182 lines
5.5 KiB
Dart
182 lines
5.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:plezy/i18n/strings.g.dart';
|
|
import 'package:plezy/media/ids.dart';
|
|
import 'package:plezy/media/library_query.dart';
|
|
import 'package:plezy/media/media_backend.dart';
|
|
import 'package:plezy/media/media_hub.dart';
|
|
import 'package:plezy/media/media_item.dart';
|
|
import 'package:plezy/media/media_kind.dart';
|
|
import 'package:plezy/media/media_server_client.dart';
|
|
import 'package:plezy/media/server_capabilities.dart';
|
|
import 'package:plezy/providers/multi_server_provider.dart';
|
|
import 'package:plezy/screens/hub_detail_screen.dart';
|
|
import 'package:plezy/services/data_aggregation_service.dart';
|
|
import 'package:plezy/services/multi_server_manager.dart';
|
|
import 'package:plezy/services/settings_service.dart';
|
|
import 'package:plezy/theme/mono_theme.dart';
|
|
import 'package:plezy/utils/media_server_http_client.dart';
|
|
import 'package:provider/provider.dart';
|
|
|
|
import '../test_helpers/prefs.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
setUp(() {
|
|
resetSharedPreferencesForTest();
|
|
SettingsService.resetForTesting();
|
|
LocaleSettings.setLocaleSync(AppLocale.en);
|
|
});
|
|
|
|
testWidgets('Jellyfin hub advances by raw page size after screen filtering', (tester) async {
|
|
final items = List.generate(
|
|
205,
|
|
(index) => _item(index, libraryId: index.isEven ? '7' : '8', backend: MediaBackend.jellyfin),
|
|
);
|
|
final harness = await _createHarness(items, backend: MediaBackend.jellyfin);
|
|
|
|
await tester.pumpWidget(
|
|
harness.wrap(
|
|
HubDetailScreen(
|
|
hub: MediaHub(
|
|
id: 'home.recent',
|
|
title: 'Recent',
|
|
type: 'movie',
|
|
items: items.take(5).toList(),
|
|
size: items.length,
|
|
more: true,
|
|
libraryId: '7',
|
|
serverId: 'server_1',
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(harness.client.requestedStarts, [0, 200]);
|
|
expect(harness.client.fullHubRequests, 0);
|
|
expect(find.text(t.common.retry), findsNothing);
|
|
|
|
await tester.drag(find.byType(CustomScrollView), const Offset(0, -30000));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('Item 204'), findsOneWidget);
|
|
expect(find.text('Item 203'), findsNothing);
|
|
});
|
|
|
|
testWidgets('Plex hub replaces its preview with the full-hub response', (tester) async {
|
|
final items = List.generate(205, (index) => _item(index, backend: MediaBackend.plex));
|
|
final harness = await _createHarness(items, backend: MediaBackend.plex);
|
|
|
|
await tester.pumpWidget(
|
|
harness.wrap(
|
|
HubDetailScreen(
|
|
hub: MediaHub(
|
|
id: '/hubs/home/recentlyAdded',
|
|
title: 'Recently Added',
|
|
type: 'movie',
|
|
items: items.take(5).toList(),
|
|
size: items.length,
|
|
more: true,
|
|
serverId: 'server_1',
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(harness.client.requestedStarts, [0]);
|
|
expect(harness.client.fullHubRequests, 1);
|
|
expect(find.text(t.common.retry), findsNothing);
|
|
|
|
await tester.drag(find.byType(CustomScrollView), const Offset(0, -30000));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('Item 204'), findsOneWidget);
|
|
});
|
|
}
|
|
|
|
MediaItem _item(int index, {required MediaBackend backend, String? libraryId}) => MediaItem(
|
|
id: 'item_$index',
|
|
backend: backend,
|
|
kind: MediaKind.movie,
|
|
title: 'Item $index',
|
|
libraryId: libraryId,
|
|
serverId: 'server_1',
|
|
serverName: 'Server',
|
|
);
|
|
|
|
Future<_HubHarness> _createHarness(List<MediaItem> items, {required MediaBackend backend}) async {
|
|
await SettingsService.getInstance();
|
|
final client = _PagedHubClient(items, backend: backend);
|
|
final manager = MultiServerManager()..debugRegisterClientForTesting(client);
|
|
final provider = MultiServerProvider(manager, DataAggregationService(manager));
|
|
addTearDown(provider.dispose);
|
|
return _HubHarness(client: client, provider: provider);
|
|
}
|
|
|
|
class _HubHarness {
|
|
const _HubHarness({required this.client, required this.provider});
|
|
|
|
final _PagedHubClient client;
|
|
final MultiServerProvider provider;
|
|
|
|
Widget wrap(Widget child) => TranslationProvider(
|
|
child: ChangeNotifierProvider<MultiServerProvider>.value(
|
|
value: provider,
|
|
child: MaterialApp(
|
|
theme: monoTheme(dark: true),
|
|
home: SizedBox(width: 1280, height: 720, child: child),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
class _PagedHubClient implements MediaServerClient {
|
|
_PagedHubClient(this.items, {required this.backend});
|
|
|
|
final List<MediaItem> items;
|
|
final List<int?> requestedStarts = [];
|
|
int fullHubRequests = 0;
|
|
|
|
@override
|
|
final MediaBackend backend;
|
|
|
|
@override
|
|
ServerId get serverId => ServerId('server_1');
|
|
|
|
@override
|
|
String? get serverName => 'Server';
|
|
|
|
@override
|
|
ServerCapabilities get capabilities =>
|
|
backend == MediaBackend.plex ? ServerCapabilities.plex : ServerCapabilities.jellyfin;
|
|
|
|
@override
|
|
Future<LibraryPage<MediaItem>> fetchMoreHubItemsPage(
|
|
String hubId, {
|
|
int? start,
|
|
int? size,
|
|
AbortController? abort,
|
|
}) async {
|
|
requestedStarts.add(start);
|
|
final offset = start ?? 0;
|
|
return LibraryPage(
|
|
items: items.skip(offset).take(size ?? items.length).toList(growable: false),
|
|
totalCount: items.length,
|
|
offset: offset,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Future<List<MediaItem>> fetchMoreHubItems(String hubId, {int? limit}) async {
|
|
fullHubRequests++;
|
|
return List.unmodifiable(items);
|
|
}
|
|
|
|
@override
|
|
void close() {}
|
|
|
|
@override
|
|
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
|
}
|