From bef0bf5cd69ca72648ec883ef89ce3ee50347531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20Arteiro?= Date: Wed, 4 Oct 2023 21:21:54 +0100 Subject: [PATCH] fix: Image picking tests fix. #275 --- pubspec.lock | 2 +- pubspec.yaml | 2 + test/integration_test.dart | 81 +++++++++++++++++++++++++++-- test/unit/image_callbacks_test.dart | 6 +-- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 66bb96ab..1f3746fa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -624,7 +624,7 @@ packages: source: hosted version: "0.2.1+1" image_picker_platform_interface: - dependency: transitive + dependency: "direct dev" description: name: image_picker_platform_interface sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 diff --git a/pubspec.yaml b/pubspec.yaml index bdc7701c..0a597563 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,9 +50,11 @@ dev_dependencies: cross_file: ^0.3.3+5 path_provider_platform_interface: ^2.1.1 + image_picker_platform_interface: ^2.9.1 flutter: uses-material-design: true assets: - assets/icon/ + - assets/ diff --git a/test/integration_test.dart b/test/integration_test.dart index d306dabc..66667f1a 100644 --- a/test/integration_test.dart +++ b/test/integration_test.dart @@ -3,11 +3,49 @@ import 'package:dwyl_app/presentation/views/views.dart'; import 'package:dwyl_app/presentation/widgets/editor/emoji_picker.dart'; import 'package:dwyl_app/presentation/widgets/widgets.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_quill/flutter_quill.dart' hide Text; import 'package:flutter_quill/flutter_quill_test.dart'; import 'package:flutter_quill_extensions/embeds/toolbar/image_button.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:dwyl_app/main.dart'; +import 'package:image_picker_platform_interface/image_picker_platform_interface.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:universal_io/io.dart'; + +class FakeImagePicker extends ImagePickerPlatform { + @override + Future getImageFromSource({ + required ImageSource source, + ImagePickerOptions options = const ImagePickerOptions(), + }) async { + final data = await rootBundle.load('assets/sample.jpeg'); + final bytes = data.buffer.asUint8List(); + final tempDir = await getTemporaryDirectory(); + final file = await File( + '${tempDir.path}/doc.png', + ).writeAsBytes(bytes); + + return XFile(file.path); + } + + @override + Future> getMultiImageWithOptions({ + MultiImagePickerOptions options = const MultiImagePickerOptions(), + }) async { + final data = await rootBundle.load('assets/sample.jpeg'); + final bytes = data.buffer.asUint8List(); + final tempDir = await getTemporaryDirectory(); + final file = await File( + '${tempDir.path}/sample.png', + ).writeAsBytes(bytes); + return [ + XFile( + file.path, + ), + ]; + } +} void main() { /// Bootstraps a sample main application, whether it [isWeb] or not. @@ -21,8 +59,10 @@ void main() { ); } + // See https://stackoverflow.com/questions/76586920/mocking-imagepicker-in-flutter-integration-tests-not-working for context. setUpAll(() { TestWidgetsFlutterBinding.ensureInitialized(); + ImagePickerPlatform.instance = FakeImagePicker(); }); group('Normal build', () { @@ -403,9 +443,6 @@ void main() { group('Image picker', () { testWidgets('should show and select image', (WidgetTester tester) async { - // Mock image - // mockImagePicker(tester); - // Build our app and trigger a frame. final app = initializeMainApp(isWeb: false); await tester.pumpWidget(app); @@ -426,12 +463,46 @@ void main() { await tester.pump(const Duration(minutes: 1)); // Press image button + // Because of the override, should embed image. + final imageButton = find.byType(ImageButton); + await tester.tap(imageButton); + await tester.pumpAndSettle(); + + // Image correctly added, editor should be visible again. + expect(editor.hitTestable(), findsOneWidget); + }); + + + // TODO does not work because inside ImageButton, there is a `kIsWeb`. + // This can't be mockable, unless we use a custom button to recreate this behaviour. + testWidgets('should show and select image (on the web - uploads image to the web)', (WidgetTester tester) async { + // Build our app and trigger a frame. + final app = initializeMainApp(isWeb: true); + await tester.pumpWidget(app); + await tester.pumpAndSettle(); + + // Tap textfield to open new page to create item + await tester.tap(find.byKey(textfieldKey)); + await tester.pumpAndSettle(const Duration(seconds: 2)); + + // Should show editor and toolbar + final editor = find.byType(QuillEditor); + final toolbar = find.byType(QuillToolbar); + expect(editor.hitTestable(), findsOneWidget); + expect(toolbar.hitTestable(), findsOneWidget); + + // Drag toolbar to the right + await tester.drag(toolbar, const Offset(-500, 0)); + await tester.pump(const Duration(minutes: 1)); + + // Press image button + // Because of the override, should embed image. final imageButton = find.byType(ImageButton); await tester.tap(imageButton); await tester.pumpAndSettle(); - // TODO can't choose image. - // Check https://github.com/singerdmx/flutter-quill/issues/1389. + // Image correctly added, editor should be visible again. + expect(editor.hitTestable(), findsOneWidget); }); }); diff --git a/test/unit/image_callbacks_test.dart b/test/unit/image_callbacks_test.dart index bbe71f92..fea41cb9 100644 --- a/test/unit/image_callbacks_test.dart +++ b/test/unit/image_callbacks_test.dart @@ -17,7 +17,7 @@ class FakePathProviderPlatform extends PathProviderPlatform implements Fake { @override Future getApplicationDocumentsPath() async { // Make sure is the same folder used in the tests. - return 'test'; + return 'assets'; } } @@ -45,11 +45,11 @@ void main() { }); test('`onImagePickCallback` should return path of a given file.', () async { - final file = File('test/sample.jpeg'); + final file = File('assets/sample.jpeg'); final path = await onImagePickCallback(file); // Some time must have passed - expect(path == 'test/sample.jpeg', true); + expect(path == 'assets/sample.jpeg', true); }); testWidgets('`webImagePickImpl` should return the URL of the uploaded image on success (200).', (WidgetTester tester) async {