@@ -9,6 +9,7 @@ import 'package:plezy/focus/input_mode_tracker.dart';
|
||||
import 'package:plezy/profiles/profile.dart';
|
||||
import 'package:plezy/screens/settings/add_jellyfin_screen.dart';
|
||||
import 'package:plezy/services/jellyfin_auth_service.dart';
|
||||
import 'package:plezy/services/jellyfin_lan_discovery_service.dart';
|
||||
import 'package:plezy/utils/platform_detector.dart';
|
||||
|
||||
Profile _profile(String id) =>
|
||||
@@ -35,6 +36,32 @@ JellyfinConnectionAuthService _jellyfinAuthService({bool quickConnectEnabled = f
|
||||
);
|
||||
}
|
||||
|
||||
JellyfinConnectionAuthService _jellyfinAuthServiceForBareHost() {
|
||||
return JellyfinConnectionAuthService(
|
||||
clientName: 'Plezy',
|
||||
clientVersion: 'test',
|
||||
deviceName: 'TestDevice',
|
||||
testHttpClientFactory: () => MockClient((request) async {
|
||||
switch (request.url.path) {
|
||||
case '/System/Info/Public':
|
||||
if (request.url.scheme == 'http' && request.url.host == 'jf.example.com' && request.url.port == 8096) {
|
||||
return http.Response(
|
||||
jsonEncode({'Id': 'srv-1', 'ServerName': 'Home', 'Version': '10.9.0'}),
|
||||
200,
|
||||
headers: {'content-type': 'application/json'},
|
||||
);
|
||||
}
|
||||
throw Exception('offline');
|
||||
case '/QuickConnect/Enabled':
|
||||
return http.Response(jsonEncode(false), 200, headers: {'content-type': 'application/json'});
|
||||
}
|
||||
return http.Response('', 404);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<DiscoveredJellyfinServer>> _noLocalServers() async => const [];
|
||||
|
||||
void main() {
|
||||
tearDown(() {
|
||||
TvDetectionService.debugSetAppleTVOverride(null);
|
||||
@@ -42,7 +69,7 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('autofocuses the server URL field', (tester) async {
|
||||
await tester.pumpWidget(const MaterialApp(home: AddJellyfinScreen()));
|
||||
await tester.pumpWidget(MaterialApp(home: AddJellyfinScreen(localDiscoveryFactory: _noLocalServers)));
|
||||
await tester.pump();
|
||||
|
||||
final field = tester.widget<TextField>(find.byType(TextField));
|
||||
@@ -53,7 +80,11 @@ void main() {
|
||||
testWidgets('TV initial focus opens the server URL keyboard', (tester) async {
|
||||
TvDetectionService.debugSetAppleTVOverride(true);
|
||||
|
||||
await tester.pumpWidget(const InputModeTracker(child: MaterialApp(home: AddJellyfinScreen())));
|
||||
await tester.pumpWidget(
|
||||
InputModeTracker(
|
||||
child: MaterialApp(home: AddJellyfinScreen(localDiscoveryFactory: _noLocalServers)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(FocusManager.instance.primaryFocus?.debugLabel, 'TvVirtualKeyboard');
|
||||
@@ -65,7 +96,11 @@ void main() {
|
||||
await TvDetectionService.getInstance(forceTv: true);
|
||||
TvDetectionService.setForceTVSync(true);
|
||||
|
||||
await tester.pumpWidget(const InputModeTracker(child: MaterialApp(home: AddJellyfinScreen())));
|
||||
await tester.pumpWidget(
|
||||
InputModeTracker(
|
||||
child: MaterialApp(home: AddJellyfinScreen(localDiscoveryFactory: _noLocalServers)),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(FocusManager.instance.primaryFocus?.debugLabel, 'TvVirtualKeyboard');
|
||||
@@ -83,7 +118,14 @@ void main() {
|
||||
});
|
||||
|
||||
testWidgets('D-pad moves from URL to credentials after server is found', (tester) async {
|
||||
await tester.pumpWidget(MaterialApp(home: AddJellyfinScreen(authServiceFactory: () => _jellyfinAuthService())));
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: AddJellyfinScreen(
|
||||
authServiceFactory: () => _jellyfinAuthService(),
|
||||
localDiscoveryFactory: _noLocalServers,
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
await tester.enterText(find.byType(TextField).first, 'https://jf.example.com');
|
||||
@@ -106,6 +148,49 @@ void main() {
|
||||
expect(FocusManager.instance.primaryFocus?.debugLabel, 'AddJellyfin:Url');
|
||||
});
|
||||
|
||||
testWidgets('accepts a bare Jellyfin host and expands it before probing', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: AddJellyfinScreen(
|
||||
authServiceFactory: () => _jellyfinAuthServiceForBareHost(),
|
||||
localDiscoveryFactory: _noLocalServers,
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
await tester.enterText(find.byType(TextField).first, 'jf.example.com');
|
||||
await tester.testTextInput.receiveAction(TextInputAction.go);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final field = tester.widget<TextField>(find.byType(TextField).first);
|
||||
expect(field.controller?.text, 'http://jf.example.com:8096');
|
||||
expect(find.text('Home'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('selecting a discovered Jellyfin server probes that address', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: AddJellyfinScreen(
|
||||
authServiceFactory: () => _jellyfinAuthService(),
|
||||
localDiscoveryFactory: () async => [
|
||||
DiscoveredJellyfinServer(address: 'http://192.168.1.20:8096', id: 'srv-1', name: 'Home'),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Home'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Home'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final field = tester.widget<TextField>(find.byType(TextField).first);
|
||||
expect(field.controller?.text, contains('http://192.168.1.20:8096'));
|
||||
expect(find.text('Jellyfin 10.9.0'), findsOneWidget);
|
||||
});
|
||||
|
||||
group('Jellyfin profile binding decisions', () {
|
||||
test('creates a local profile only on true first-run with no profiles', () {
|
||||
expect(shouldCreateLocalJellyfinProfile(targetProfile: null, activeProfile: null, hasProfiles: false), isTrue);
|
||||
|
||||
Reference in New Issue
Block a user