import 'package:flutter/material.dart'; import 'package:flutter_image_test_utils/image_test/image_test_io.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fotodocumentation/controller/customer_controller.dart'; import 'package:fotodocumentation/dto/customer_dto.dart' show CustomerDto, CustomerListDto; import 'package:fotodocumentation/dto/picture_dto.dart'; import 'package:fotodocumentation/pages/customer/picture_fullscreen_dialog.dart'; import 'package:fotodocumentation/utils/di_container.dart'; import 'package:fotodocumentation/utils/global_router.dart'; import 'package:fotodocumentation/utils/login_credentials.dart'; import 'package:mockito/mockito.dart'; import '../testing/test_utils.dart'; import '../testing/test_utils.mocks.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); DiContainer.instance.initState(); DiContainer.instance.put(LoginCredentials, getDefaultLoginCredentials()); late CustomerDto customerDto; late PictureDto pictureDto1; late PictureDto pictureDto2; late PictureDto pictureDto3; late MockCustomerController mockCustomerController; setUp(() { pictureDto1 = PictureDto( id: 1, comment: 'First picture comment', category: 'category1', pictureDate: DateTime(2024, 1, 15), username: 'user1', evaluation: 1, imageUrl: "", normalSizeUrl: "", thumbnailSizeUrl: "", ); pictureDto2 = PictureDto( id: 2, comment: 'Second picture comment', category: 'category2', pictureDate: DateTime(2024, 2, 20), username: 'user2', evaluation: 1, imageUrl: "", normalSizeUrl: "", thumbnailSizeUrl: "", ); pictureDto3 = PictureDto( id: 3, comment: null, category: 'category3', pictureDate: DateTime(2024, 3, 25), username: 'user3', evaluation: 1, imageUrl: "", normalSizeUrl: "", thumbnailSizeUrl: "", ); customerDto = CustomerDto( id: 1, name: 'Test Apotheke', customerNumber: 'CUST001', pictures: [pictureDto1, pictureDto2, pictureDto3], ); mockCustomerController = MockCustomerController(); DiContainer.instance.put(CustomerController, mockCustomerController); }); group('PictureWidget', () { testWidgets('displays customer information correctly', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Verify customer name is displayed expect(find.text('Test Apotheke'), findsOneWidget); // Verify customer number is displayed expect(find.text('CUST001'), findsOneWidget); // Verify labels are displayed expect(find.text('KUNDENNUMMER'), findsOneWidget); expect(find.text('KOMMENTAR'), findsOneWidget); }); }); testWidgets('displays picture comment', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Verify the comment is displayed expect(find.text('First picture comment'), findsOneWidget); }); }); testWidgets('displays empty string when comment is null', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // The comment field should be empty but the label should exist expect(find.text('KOMMENTAR'), findsOneWidget); }); }); testWidgets('shows both navigation buttons at bottom', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Both navigation buttons should always be visible at the bottom expect(find.byKey(Key("navigate_left")), findsOneWidget); expect(find.byKey(Key("navigate_right")), findsOneWidget); }); }); testWidgets('shows both navigation buttons when on middle picture', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Both navigation buttons should be visible expect(find.byKey(Key("navigate_left")), findsOneWidget); expect(find.byKey(Key("navigate_right")), findsOneWidget); }); }); testWidgets('shows both navigation buttons on last picture', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Both navigation buttons should be visible (right one is disabled) expect(find.byKey(Key("navigate_left")), findsOneWidget); expect(find.byKey(Key("navigate_right")), findsOneWidget); }); }); testWidgets('navigates to next picture when right button is tapped', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Verify first picture comment is shown expect(find.text('First picture comment'), findsOneWidget); // Tap right navigation button await tester.tap(find.byKey(Key("navigate_right"))); await tester.pumpAndSettle(); // Verify second picture comment is now shown expect(find.text('Second picture comment'), findsOneWidget); expect(find.text('First picture comment'), findsNothing); }); }); testWidgets('navigates to previous picture when left button is tapped', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/2"); await tester.pumpAndSettle(); // Verify second picture comment is shown expect(find.text('Second picture comment'), findsOneWidget); // Tap left navigation button await tester.tap(find.byKey(Key("navigate_left"))); await tester.pumpAndSettle(); // Verify first picture comment is now shown expect(find.text('First picture comment'), findsOneWidget); expect(find.text('Second picture comment'), findsNothing); }); }); testWidgets('shows disabled navigation buttons when only one picture', (WidgetTester tester) async { setScreenSize(tester, 1024, 1024); final singlePictureCustomer = CustomerDto( id: 1, name: 'Test Apotheke', customerNumber: 'CUST001', pictures: [pictureDto1], ); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => singlePictureCustomer); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Both navigation buttons should be shown but disabled expect(find.byKey(Key("navigate_left")), findsOneWidget); expect(find.byKey(Key("navigate_right")), findsOneWidget); }); }); testWidgets('opens fullscreen dialog when image is tapped', (WidgetTester tester) async { setScreenSize(tester, 2048, 2048); when(mockCustomerController.get(id: 1)).thenAnswer((_) async => customerDto); when(mockCustomerController.getAll("", "")).thenAnswer((_) async => _list); provideMockedNetworkImages(() async { await pumpAppConfig(tester, "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/1${GlobalRouter.pathPicture}/1"); await tester.pumpAndSettle(); // Find the GestureDetector with the image key final imageFinder = find.byKey(const Key("image")); expect(imageFinder, findsOneWidget); // Ensure the widget is visible first await tester.ensureVisible(imageFinder); await tester.pumpAndSettle(); // Tap the image - use warnIfMissed: false since the Image.memory may have // rendering issues in test environment but the GestureDetector should still work await tester.tap(imageFinder, warnIfMissed: false); await tester.pumpAndSettle(); // Verify fullscreen dialog is shown expect(find.byType(PictureFullscreenDialog), findsOneWidget); }); }); }); } List _list = [CustomerListDto(id: 1, customerNumber: "CODE1", name: "Customer 1"), CustomerListDto(id: 2, customerNumber: "CODE2", name: "Customer 2")];