/// 照片管理占位页 widget 测试(P3 计划 Task 4)。 /// /// 覆盖:Task 9 占位横幅、基础列表(可见性/处理状态标签、时区时间)、 /// 游标加载更多。完整交互由 Task 9 替换。 library; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:photo_live/core/api_client.dart'; import 'package:photo_live/features/albums/models.dart'; import 'package:photo_live/l10n/app_localizations.dart'; import 'package:photo_live/pages/album_photos_page.dart'; import '../helpers/fakes.dart'; void main() { late FakeSessionStore store; setUp(() { store = FakeSessionStore(); }); ApiClient clientOf(FakeAdapter adapter) => ApiClient( sessionStore: store, dio: Dio(BaseOptions(baseUrl: 'http://test.local')) ..httpClientAdapter = adapter, ); Future pumpPhotos(WidgetTester tester, ApiClient client) async { await tester.pumpWidget( ProviderScope( overrides: [apiClientProvider.overrideWith((ref) => client)], child: MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, home: AlbumPhotosPage(album: Album.fromJson(albumJson())), ), ), ); await tester.pumpAndSettle(); } testWidgets('占位横幅 + 列表标签 + 游标加载第二页', (tester) async { final page1 = List>.generate( 20, (i) => adminPhotoJson( photoId: 'ph-${(i + 1).toString().padLeft(8, '0')}', visibility: i % 2 == 0 ? 'published' : 'unpublished', processingState: i % 2 == 0 ? 'ready' : 'processing', ), ); final page2 = >[ // 区分度高的 ID:第二页条目渲染后可按标题前缀断言。 adminPhotoJson(photoId: 'page2item'), ]; final adapter = FakeAdapter((o) { if (o.path != '/v1/albums/alb-1/photos') { throw StateError('unexpected ${o.method} ${o.path}'); } final cursor = o.uri.queryParameters['cursor']; if (cursor == null) { return (200, cursorPageBody(page1, nextCursor: 'pc1')); } if (cursor == 'pc1') return (200, cursorPageBody(page2)); throw StateError('unexpected cursor $cursor'); }); await pumpPhotos(tester, clientOf(adapter)); // Task 9 占位横幅。 expect( find.textContaining('the full experience ships in Task 9'), findsOneWidget, ); // 标签与条目(ListView 懒构建,只断言在渲染的可见条目)。 expect(find.text('Published'), findsWidgets); expect(find.text('Unpublished'), findsWidgets); expect(find.text('Ready'), findsWidgets); expect(find.text('Processing'), findsWidgets); expect(find.text('2026/9/18 15:00'), findsWidgets, reason: '相册时区展示'); // 滚动加载第二页。 await tester.drag(find.byType(ListView), const Offset(0, -4000)); await tester.pumpAndSettle(); expect( adapter.requests.last.uri.queryParameters['cursor'], 'pc1', ); // 第二页条目渲染(标题展示 photoId 前 8 位)。 expect(find.textContaining('page2ite'), findsOneWidget); }); }