feat(flutter): 重做收藏与观看历史页

This commit is contained in:
Zhou Weidong committed 2026-10-20 16:31:59 +08:00
1 parent 7285a1cd4e
commit 794dc87083
14 files changed
+855 -272

No files matched your search

+27
View File
@@ -10,6 +10,7 @@ import 'package:fruitshorts/core/data/services/auth_controller.dart';
import 'package:fruitshorts/core/data/services/auth_session_store.dart';
import 'package:fruitshorts/core/data/services/favorite_controller.dart';
import 'package:fruitshorts/core/platform/haptics.dart';
import 'package:fruitshorts/core/theme/app_colors.dart';
import 'package:fruitshorts/core/widgets/empty_state.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/favorites/favorites_page.dart';
@@ -47,9 +48,35 @@ void main() {
await _pumpPage(tester, auth: auth, favorites: favorites);
expect(find.byKey(const Key('favorites-page')), findsOneWidget);
expect(find.byKey(const Key('favorites-back')), findsOneWidget);
expect(
tester.widget<Text>(find.byKey(const Key('favorites-count'))).data,
'2 favorites',
);
expect(find.text('Long press a card to remove'), findsOneWidget);
expect(find.text('Drama signal'), findsOneWidget);
expect(find.text('Drama city'), findsOneWidget);
final title = tester.widget<Text>(
find.byKey(const Key('favorite-title-signal')),
);
expect(title.style?.color, AppColors.onSurface);
expect(title.style?.fontSize, 15);
expect(
tester.getSize(find.byKey(const Key('favorite-cover-signal'))),
const Size(80, 106),
);
expect(find.byKey(const Key('favorite-remove-signal')), findsOneWidget);
expect(
tester.getSize(find.byKey(const Key('favorite-remove-signal'))),
const Size(28, 28),
);
final refresh = tester.widget<RefreshIndicator>(
find.byType(RefreshIndicator),
);
expect(refresh.color, AppColors.blue);
expect(refresh.backgroundColor, AppColors.card);
expect(refresh.strokeWidth, 2);
});
testWidgets('should_keep_card_and_show_failure_when_remove_fails', (
@@ -72,6 +72,43 @@ void main() {
expect(controller.error, isNull);
});
test('should_reuse_cached_details_when_records_are_loaded_again', () async {
final history = ControlledWatchHistory([_progress('1'), _progress('2')]);
final catalog = ScriptedWatchCatalog();
final controller = WatchRecordsController(
history: history,
catalog: catalog,
);
await controller.load();
await controller.load();
expect(catalog.calls, ['1', '2']);
expect(
controller.records.every(
(record) => !record.detailLoading && record.drama != null,
),
isTrue,
);
});
test('should_keep_existing_records_when_refresh_fails', () async {
final history = ControlledWatchHistory([_progress('1')]);
final controller = WatchRecordsController(
history: history,
catalog: ScriptedWatchCatalog(),
);
await controller.load();
history.failRecent = true;
await controller.load();
expect(controller.loading, isFalse);
expect(controller.error, 'progressError');
expect(controller.records.single.drama?.id, '1');
expect(controller.records.single.detailLoading, isFalse);
});
test('should_keep_other_records_when_one_detail_request_fails', () async {
final history = ControlledWatchHistory([_progress('1'), _progress('2')]);
final catalog = ScriptedWatchCatalog(failedIds: {'1'});
+36
View File
@@ -12,6 +12,7 @@ import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart
import 'package:fruitshorts/core/data/services/auth_controller.dart';
import 'package:fruitshorts/core/data/services/auth_session_store.dart';
import 'package:fruitshorts/core/platform/haptics.dart';
import 'package:fruitshorts/core/theme/app_colors.dart';
import 'package:fruitshorts/core/widgets/empty_state.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/watch_records/watch_records_page.dart';
@@ -47,11 +48,46 @@ void main() {
await _pumpPage(tester, auth: auth, history: history, catalog: catalog);
expect(find.byKey(const Key('watch-records-page')), findsOneWidget);
expect(find.byKey(const Key('watch-records-back')), findsOneWidget);
expect(
tester.widget<Text>(find.byKey(const Key('watch-records-count'))).data,
'1 records',
);
expect(find.text('The Signal'), findsOneWidget);
final title = tester.widget<Text>(
find.byKey(const Key('watch-record-title-the-signal-demo')),
);
expect(title.style?.color, AppColors.onSurface);
expect(title.style?.fontSize, 15);
expect(
tester.getSize(
find.byKey(const Key('watch-record-cover-the-signal-demo')),
),
const Size(72, 96),
);
expect(
tester.getSize(
find.byKey(const Key('watch-record-remove-the-signal-demo')),
),
const Size(28, 28),
);
expect(
find.byKey(const Key('watch-record-episode-the-signal-demo')),
findsOneWidget,
);
final refresh = tester.widget<RefreshIndicator>(
find.byType(RefreshIndicator),
);
expect(refresh.color, AppColors.blue);
expect(refresh.backgroundColor, AppColors.card);
expect(refresh.strokeWidth, 2);
final list = tester.widget<ListView>(
find.descendant(
of: find.byType(RefreshIndicator),
matching: find.byType(ListView),
),
);
expect(list.physics, isA<AlwaysScrollableScrollPhysics>());
});
testWidgets(