feat(following): 新增追剧三栏与双列网格
This commit is contained in:
1 parent
73380ee090
commit
97e3f4fc47
15 files changed
+1001
-12
No files matched your search
@@ -0,0 +1,210 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fruitshorts/app.dart';
|
||||
import 'package:fruitshorts/core/data/models/drama.dart';
|
||||
import 'package:fruitshorts/core/data/models/watch_progress.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/favorite_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
||||
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
||||
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
||||
|
||||
import '../support/fake_catalog.dart';
|
||||
import '../support/fake_category.dart';
|
||||
import '../support/fake_interaction_repositories.dart';
|
||||
import '../support/widget_player.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('should_render_following_tabs_grid_and_edit_actions', (
|
||||
tester,
|
||||
) async {
|
||||
_signIn();
|
||||
final catalog = FakeCatalogRepository();
|
||||
await tester.pumpWidget(
|
||||
_app(
|
||||
catalog: catalog,
|
||||
favorites: InMemoryFavoriteRepository(
|
||||
cards: catalog.dramas.take(1).toList(),
|
||||
saved: {catalog.dramas.first.id},
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('following-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('following-tab-favorites')), findsOneWidget);
|
||||
expect(find.byKey(const Key('following-tab-history')), findsOneWidget);
|
||||
expect(find.byKey(const Key('following-tab-reserve')), findsOneWidget);
|
||||
expect(find.byKey(const Key('following-favorites-grid')), findsOneWidget);
|
||||
expect(find.byType(CustomScrollView), findsWidgets);
|
||||
|
||||
await tester.tap(find.byKey(const Key('following-edit')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(
|
||||
find.byKey(const Key('following-remove-the-signal-demo')),
|
||||
findsOneWidget,
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(const Key('following-remove-the-signal-demo')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(AlertDialog), findsOneWidget);
|
||||
await tester.tap(
|
||||
find.descendant(
|
||||
of: find.byType(AlertDialog),
|
||||
matching: find.byType(FilledButton),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
find.byKey(const Key('following-remove-the-signal-demo')),
|
||||
findsNothing,
|
||||
);
|
||||
expect(find.byIcon(Icons.edit_outlined), findsOneWidget);
|
||||
expect(
|
||||
find.byKey(const Key('following-card-the-signal-demo')),
|
||||
findsNothing,
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(const Key('following-tab-history')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('following-history-empty')), findsOneWidget);
|
||||
await tester.tap(find.byKey(const Key('following-tab-reserve')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('following-reserve-empty')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_show_auth_gate_when_signed_out', (tester) async {
|
||||
SharedPreferencesAsyncPlatform.instance =
|
||||
InMemorySharedPreferencesAsync.empty();
|
||||
await tester.pumpWidget(_app(catalog: FakeCatalogRepository()));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('auth-gate-panel')), findsOneWidget);
|
||||
expect(find.byKey(const Key('following-favorites-grid')), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('should_show_empty_favorites_and_history', (tester) async {
|
||||
_signIn();
|
||||
await tester.pumpWidget(_app(catalog: FakeCatalogRepository()));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('following-favorites-empty')), findsOneWidget);
|
||||
await tester.tap(find.byKey(const Key('following-tab-history')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('following-history-empty')), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('should_render_history_metadata_without_detail_fetch', (
|
||||
tester,
|
||||
) async {
|
||||
_signIn();
|
||||
final catalog = _CountingCatalogRepository();
|
||||
await tester.pumpWidget(
|
||||
_app(
|
||||
catalog: catalog,
|
||||
history: InMemoryWatchHistoryRepository(
|
||||
seed: [
|
||||
WatchProgress(
|
||||
dramaId: 'the-signal-demo',
|
||||
episodeId: 'the-signal-demo-3',
|
||||
dramaTitle: 'Server title',
|
||||
dramaCover: '/files/server-cover.jpg',
|
||||
episodeNumber: 3,
|
||||
totalEpisodes: 8,
|
||||
position: const Duration(seconds: 25),
|
||||
duration: const Duration(seconds: 100),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('following-tab-history')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Server title'), findsOneWidget);
|
||||
expect(find.text('Watched to Episode 3'), findsOneWidget);
|
||||
expect(
|
||||
find.byKey(const Key('following-progress-the-signal-demo')),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(catalog.detailFetches, 0);
|
||||
});
|
||||
|
||||
testWidgets('should_reset_edit_state_when_switching_tabs', (tester) async {
|
||||
_signIn();
|
||||
final catalog = FakeCatalogRepository();
|
||||
await tester.pumpWidget(
|
||||
_app(
|
||||
catalog: catalog,
|
||||
favorites: InMemoryFavoriteRepository(
|
||||
cards: catalog.dramas,
|
||||
saved: catalog.dramas.map((drama) => drama.id).toSet(),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('following-edit')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.byKey(const Key('following-tab-history')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byKey(const Key('following-tab-favorites')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(
|
||||
find.byKey(const Key('following-card-the-signal-demo')),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(find.byIcon(Icons.edit_outlined), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
void _signIn() {
|
||||
SharedPreferencesAsyncPlatform.instance =
|
||||
InMemorySharedPreferencesAsync.withData({
|
||||
'auth.accessToken': 'access',
|
||||
'auth.refreshToken': 'refresh',
|
||||
'auth.user': '{"uid":"9","nickname":"Viewer","avatarUrl":""}',
|
||||
});
|
||||
}
|
||||
|
||||
Widget _app({
|
||||
required FakeCatalogRepository catalog,
|
||||
FavoriteRepository? favorites,
|
||||
WatchHistoryRepository? history,
|
||||
}) {
|
||||
return LumaDramaApp(
|
||||
playerFactory: createWidgetPlayer,
|
||||
catalogRepository: catalog,
|
||||
categoryRepository: FakeCategoryRepository(catalog: catalog),
|
||||
watchHistoryRepository: history ?? InMemoryWatchHistoryRepository(),
|
||||
favoriteRepository: favorites ?? InMemoryFavoriteRepository(),
|
||||
playbackRepository: FakePlaybackRepository(),
|
||||
commentRepository: FakeCommentRepository(),
|
||||
interactionRepository: FakeInteractionRepository(),
|
||||
);
|
||||
}
|
||||
|
||||
class _CountingCatalogRepository extends FakeCatalogRepository {
|
||||
int detailFetches = 0;
|
||||
|
||||
@override
|
||||
Future<Drama> fetchDrama(String dramaId) {
|
||||
detailFetches += 1;
|
||||
return super.fetchDrama(dramaId);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import 'package:fruitshorts/core/data/repositories/playback_repository.dart';
|
||||
import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart';
|
||||
import 'package:fruitshorts/core/theme/app_colors.dart';
|
||||
import 'package:fruitshorts/core/widgets/app_bottom_nav.dart';
|
||||
import 'package:fruitshorts/pages/favorites/favorites_page.dart';
|
||||
import 'package:fruitshorts/pages/following/following_page.dart';
|
||||
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
|
||||
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
|
||||
|
||||
@@ -217,10 +217,9 @@ void main() {
|
||||
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
final favorites = find.byType(FavoritesContent);
|
||||
final favorites = find.byType(FollowingPage);
|
||||
expect(favorites, findsOneWidget);
|
||||
expect(find.byKey(const Key('favorites-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('favorites-back')), findsNothing);
|
||||
expect(find.byKey(const Key('following-page')), findsOneWidget);
|
||||
expect(find.byType(AppBottomNav), findsOneWidget);
|
||||
expect(
|
||||
find.descendant(of: favorites, matching: find.byType(Scaffold)),
|
||||
|
||||
@@ -36,8 +36,7 @@ void main() {
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byKey(const Key('favorites-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('favorites-back')), findsNothing);
|
||||
expect(find.byKey(const Key('following-page')), findsOneWidget);
|
||||
expect(find.byType(AppBottomNav), findsOneWidget);
|
||||
});
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ void main() {
|
||||
|
||||
await tester.tap(find.byKey(const Key('tab-follow')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('favorites-page')), findsOneWidget);
|
||||
expect(find.byKey(const Key('following-page')), findsOneWidget);
|
||||
await tester.tap(find.byKey(const Key('tab-mine')));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byKey(const Key('mine-menu')), findsOneWidget);
|
||||
|
||||
Reference in new issue
Block a user