Files
reelbox/test/api_selector_ui_test.dart
T

202 lines
7.6 KiB
Dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:reelbox/app.dart';
import 'package:reelbox/data/api_service.dart';
import 'package:reelbox/data/models.dart';
import 'package:reelbox/state/app_state.dart';
import 'package:reelbox/ui/catalog.dart';
import 'package:reelbox/ui/library.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'api_service_test.dart' as fixtures;
import 'api_selector_test.dart' show iranBase;
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() => SharedPreferences.setMockInitialValues({}));
fixtures.StubAdapter adapter() => fixtures.StubAdapter(
(r) => r.uri.path.contains('/first/')
? fixtures.jsonBody({'posters': []})
: fixtures.jsonBody([]),
);
for (final locale in ['en', 'fa']) {
testWidgets(
'settings hides connection details and preserves migrated library in $locale',
(tester) async {
final network = adapter();
final state = AppState(
api: ApiService(dio: Dio()..httpClientAdapter = network),
);
addTearDown(state.dispose);
await state.initialize(discover: false);
await state.updateSettings(state.prefs.copyWith(locale: locale));
const title = TitleRecord(id: 9, title: 'Saved title');
await state.toggleSaved(title);
await state.recordWatch(
title,
sourceUrl: 'https://media.example/film.mp4?token=exact',
positionSeconds: 12,
);
await state.createCollection('Keep collection');
final storedLibrary = (await SharedPreferences.getInstance()).getString(
AppState.storageKey,
);
var notifications = 0;
state.addListener(() => notifications++);
await tester.pumpWidget(
AppScope(
state: state,
child: const MaterialApp(home: SettingsPage()),
),
);
await tester.drag(find.byType(ListView), const Offset(0, -10000));
await tester.pumpAndSettle();
expect(state.api.baseUrl, iranBase);
expect(find.text(iranBase), findsNothing);
expect(find.byKey(const Key('catalog-api-endpoint')), findsNothing);
expect(
find.text(locale == 'en' ? 'Iran Catalogue' : 'فهرست ایران'),
findsNothing,
);
expect(find.byKey(const Key('catalog-api-selector')), findsNothing);
expect(find.text('Original API'), findsNothing);
expect(find.text('API اصلی'), findsNothing);
expect(find.text('Refresh API server'), findsNothing);
expect(notifications, 0);
expect(
network.requests,
isEmpty,
reason: 'Endpoint information must not probe or offer fallback',
);
expect(
(await SharedPreferences.getInstance()).getString(
AppState.storageKey,
),
storedLibrary,
);
final preferences = await SharedPreferences.getInstance();
await preferences.setString(
'reelbox.api-selection.v1',
'https://ninwinios.info/api/',
);
await preferences.setString(
'reelbox.trusted-api.v1',
'https://ninwinios.info/api/',
);
final restarted = AppState(
api: ApiService(dio: Dio()..httpClientAdapter = adapter()),
);
addTearDown(restarted.dispose);
await restarted.initialize(discover: false);
expect(preferences.getString(AppState.storageKey), storedLibrary);
expect(restarted.api.baseUrl, iranBase);
expect(restarted.saved.single.title, 'Saved title');
expect(
restarted.history.single.sourceUrl,
'https://media.example/film.mp4?token=exact',
);
expect(restarted.collections.single.name, 'Keep collection');
expect(restarted.locale, locale);
},
);
}
testWidgets(
'Iran-only catalogue normalizes a legacy views browse on first mount',
(tester) async {
final network = adapter();
final state = AppState(
api: ApiService(dio: Dio()..httpClientAdapter = network),
);
addTearDown(state.dispose);
await state.initialize(discover: false);
await tester.pumpWidget(
AppScope(
state: state,
child: const MaterialApp(home: BrowsePage(initialOrder: 'views')),
),
);
await tester.pumpAndSettle();
expect(find.text('Most viewed'), findsNothing);
expect(find.text('Recently added'), findsOneWidget);
final iranRequests = network.requests.where(
(r) => r.uri.host == 'reelbox.dartty.top',
);
expect(iranRequests.any((r) => r.uri.path.contains('/created/')), isTrue);
expect(iranRequests.any((r) => r.uri.path.contains('/views/')), isFalse);
await tester.tap(find.byTooltip('Sort titles'));
await tester.pumpAndSettle();
expect(find.text('Most viewed'), findsNothing);
await tester.tap(find.text('Release year'));
await tester.pumpAndSettle();
await tester.pumpWidget(
AppScope(
state: state,
child: const MaterialApp(home: DiscoveryDirectoryPage()),
),
);
await tester.pumpAndSettle();
final list = tester.widget<ListView>(find.byType(ListView));
final children =
(list.childrenDelegate as SliverChildListDelegate).children;
final titles = children
.whereType<ListTile>()
.map((tile) => (tile.title as Text).data)
.toList();
expect(titles, isNot(contains('Most-viewed movies')));
expect(titles, isNot(contains('Most-viewed series')));
},
);
testWidgets(
'catalogue tabs survive simplified settings without changing local library',
(tester) async {
final network = adapter();
final state = AppState(
api: ApiService(dio: Dio()..httpClientAdapter = network),
);
addTearDown(state.dispose);
await state.initialize(discover: false);
await state.updateSettings(state.prefs.copyWith(introCompleted: true));
await state.toggleSaved(const TitleRecord(id: 9, title: 'Saved title'));
await tester.pumpWidget(MyApp(state: state));
await tester.pumpAndSettle();
for (final tab in ['Browse', 'Search', 'Library', 'More']) {
await tester.tap(find.widgetWithText(NavigationDestination, tab));
await tester.pumpAndSettle();
}
await tester.tap(find.text('Settings'));
await tester.pumpAndSettle();
await tester.drag(find.byType(ListView), const Offset(0, -10000));
await tester.pumpAndSettle();
expect(find.text(iranBase), findsNothing);
expect(find.byKey(const Key('catalog-api-endpoint')), findsNothing);
expect(find.byKey(const Key('catalog-api-selector')), findsNothing);
await tester.pageBack();
await tester.pumpAndSettle();
final iranRequests = network.requests
.where((r) => r.uri.origin == 'https://reelbox.dartty.top')
.toList();
expect(iranRequests.any((r) => r.uri.path.contains('/first/')), isTrue);
expect(
iranRequests.any((r) => r.uri.path.contains('/movie/by/filtres/')),
isTrue,
);
expect(
iranRequests.any(
(r) => r.uri.queryParameters['action'] == 'search-trand',
),
isTrue,
);
expect(state.saved.single.title, 'Saved title');
await tester.tap(find.widgetWithText(NavigationDestination, 'Library'));
await tester.pumpAndSettle();
expect(find.text('Watchlist (1)'), findsOneWidget);
expect(tester.takeException(), isNull);
},
);
}