mirrored_repositories/awesome-flutter/examples/plugins/packages/image_picker/image_picker
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:image_picker/image_picker.dart';
import 'package:image_picker_platform_interface/image_picker_platform_interface.dart';
import 'package:mockito/mockito.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('$ImagePicker', () {
    const MethodChannel channel =
        MethodChannel('plugins.flutter.io/image_picker');

    final List<MethodCall> log = <MethodCall>[];

    final picker = ImagePicker();

    test('ImagePicker platform instance overrides the actual platform used',
        () {
      final ImagePickerPlatform savedPlatform = ImagePickerPlatform.instance;
      final MockPlatform mockPlatform = MockPlatform();
      ImagePickerPlatform.instance = mockPlatform;
      expect(ImagePicker.platform, mockPlatform);
      ImagePickerPlatform.instance = savedPlatform;
    });

    group('#Single image/video', () {
      setUp(() {
        channel.setMockMethodCallHandler((MethodCall methodCall) async {
          log.add(methodCall);
          return '';
        });

        log.clear();
      });

      group('#pickImage', () {
        test('passes the image source argument correctly', () async {
          await picker.getImage(source: ImageSource.camera);
          await picker.getImage(source: ImageSource.gallery);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': null,
                'maxHeight': null,
                'imageQuality': null,
                'cameraDevice': 0
              }),
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 1,
                'maxWidth': null,
                'maxHeight': null,
                'imageQuality': null,
                'cameraDevice': 0
              }),
            ],
          );
        });

        test('passes the width and height arguments correctly', () async {
          await picker.getImage(source: ImageSource.camera);
          await picker.getImage(
            source: ImageSource.camera,
            maxWidth: 10.0,
          );
          await picker.getImage(
            source: ImageSource.camera,
            maxHeight: 10.0,
          );
          await picker.getImage(
            source: ImageSource.camera,
            maxWidth: 10.0,
            maxHeight: 20.0,
          );
          await picker.getImage(
              source: ImageSource.camera, maxWidth: 10.0, imageQuality: 70);
          await picker.getImage(
              source: ImageSource.camera, maxHeight: 10.0, imageQuality: 70);
          await picker.getImage(
              source: ImageSource.camera,
              maxWidth: 10.0,
              maxHeight: 20.0,
              imageQuality: 70);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': null,
                'maxHeight': null,
                'imageQuality': null,
                'cameraDevice': 0
              }),
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': 10.0,
                'maxHeight': null,
                'imageQuality': null,
                'cameraDevice': 0
              }),
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': null,
                'maxHeight': 10.0,
                'imageQuality': null,
                'cameraDevice': 0
              }),
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': 10.0,
                'maxHeight': 20.0,
                'imageQuality': null,
                'cameraDevice': 0
              }),
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': 10.0,
                'maxHeight': null,
                'imageQuality': 70,
                'cameraDevice': 0
              }),
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': null,
                'maxHeight': 10.0,
                'imageQuality': 70,
                'cameraDevice': 0
              }),
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': 10.0,
                'maxHeight': 20.0,
                'imageQuality': 70,
                'cameraDevice': 0
              }),
            ],
          );
        });

        test('does not accept a negative width or height argument', () {
          expect(
            picker.getImage(source: ImageSource.camera, maxWidth: -1.0),
            throwsArgumentError,
          );

          expect(
            picker.getImage(source: ImageSource.camera, maxHeight: -1.0),
            throwsArgumentError,
          );
        });

        test('handles a null image path response gracefully', () async {
          channel.setMockMethodCallHandler((MethodCall methodCall) => null);

          expect(await picker.getImage(source: ImageSource.gallery), isNull);
          expect(await picker.getImage(source: ImageSource.camera), isNull);
        });

        test('camera position defaults to back', () async {
          await picker.getImage(source: ImageSource.camera);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': null,
                'maxHeight': null,
                'imageQuality': null,
                'cameraDevice': 0,
              }),
            ],
          );
        });

        test('camera position can set to front', () async {
          await picker.getImage(
              source: ImageSource.camera,
              preferredCameraDevice: CameraDevice.front);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickImage', arguments: <String, dynamic>{
                'source': 0,
                'maxWidth': null,
                'maxHeight': null,
                'imageQuality': null,
                'cameraDevice': 1,
              }),
            ],
          );
        });
      });

      group('#pickVideo', () {
        test('passes the image source argument correctly', () async {
          await picker.getVideo(source: ImageSource.camera);
          await picker.getVideo(source: ImageSource.gallery);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 0,
                'cameraDevice': 0,
                'maxDuration': null,
              }),
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 1,
                'cameraDevice': 0,
                'maxDuration': null,
              }),
            ],
          );
        });

        test('passes the duration argument correctly', () async {
          await picker.getVideo(source: ImageSource.camera);
          await picker.getVideo(
              source: ImageSource.camera,
              maxDuration: const Duration(seconds: 10));
          await picker.getVideo(
              source: ImageSource.camera,
              maxDuration: const Duration(minutes: 1));
          await picker.getVideo(
              source: ImageSource.camera,
              maxDuration: const Duration(hours: 1));
          expect(
            log,
            <Matcher>[
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 0,
                'maxDuration': null,
                'cameraDevice': 0,
              }),
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 0,
                'maxDuration': 10,
                'cameraDevice': 0,
              }),
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 0,
                'maxDuration': 60,
                'cameraDevice': 0,
              }),
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 0,
                'maxDuration': 3600,
                'cameraDevice': 0,
              }),
            ],
          );
        });

        test('handles a null video path response gracefully', () async {
          channel.setMockMethodCallHandler((MethodCall methodCall) => null);

          expect(await picker.getVideo(source: ImageSource.gallery), isNull);
          expect(await picker.getVideo(source: ImageSource.camera), isNull);
        });

        test('camera position defaults to back', () async {
          await picker.getVideo(source: ImageSource.camera);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 0,
                'cameraDevice': 0,
                'maxDuration': null,
              }),
            ],
          );
        });

        test('camera position can set to front', () async {
          await picker.getVideo(
              source: ImageSource.camera,
              preferredCameraDevice: CameraDevice.front);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickVideo', arguments: <String, dynamic>{
                'source': 0,
                'maxDuration': null,
                'cameraDevice': 1,
              }),
            ],
          );
        });
      });

      group('#retrieveLostData', () {
        test('retrieveLostData get success response', () async {
          channel.setMockMethodCallHandler((MethodCall methodCall) async {
            return <String, String>{
              'type': 'image',
              'path': '/example/path',
            };
          });
          final LostData response = await picker.getLostData();
          expect(response.type, RetrieveType.image);
          expect(response.file!.path, '/example/path');
        });

        test('retrieveLostData get error response', () async {
          channel.setMockMethodCallHandler((MethodCall methodCall) async {
            return <String, String>{
              'type': 'video',
              'errorCode': 'test_error_code',
              'errorMessage': 'test_error_message',
            };
          });
          final LostData response = await picker.getLostData();
          expect(response.type, RetrieveType.video);
          expect(response.exception!.code, 'test_error_code');
          expect(response.exception!.message, 'test_error_message');
        });

        test('retrieveLostData get null response', () async {
          channel.setMockMethodCallHandler((MethodCall methodCall) async {
            return null;
          });
          expect((await picker.getLostData()).isEmpty, true);
        });

        test('retrieveLostData get both path and error should throw', () async {
          channel.setMockMethodCallHandler((MethodCall methodCall) async {
            return <String, String>{
              'type': 'video',
              'errorCode': 'test_error_code',
              'errorMessage': 'test_error_message',
              'path': '/example/path',
            };
          });
          expect(picker.getLostData(), throwsAssertionError);
        });
      });
    });

    group('Multi images', () {
      setUp(() {
        channel.setMockMethodCallHandler((MethodCall methodCall) async {
          log.add(methodCall);
          return [];
        });
        log.clear();
      });

      group('#pickMultiImage', () {
        test('passes the width and height arguments correctly', () async {
          await picker.getMultiImage();
          await picker.getMultiImage(
            maxWidth: 10.0,
          );
          await picker.getMultiImage(
            maxHeight: 10.0,
          );
          await picker.getMultiImage(
            maxWidth: 10.0,
            maxHeight: 20.0,
          );
          await picker.getMultiImage(
            maxWidth: 10.0,
            imageQuality: 70,
          );
          await picker.getMultiImage(
            maxHeight: 10.0,
            imageQuality: 70,
          );
          await picker.getMultiImage(
              maxWidth: 10.0, maxHeight: 20.0, imageQuality: 70);

          expect(
            log,
            <Matcher>[
              isMethodCall('pickMultiImage', arguments: <String, dynamic>{
                'maxWidth': null,
                'maxHeight': null,
                'imageQuality': null,
              }),
              isMethodCall('pickMultiImage', arguments: <String, dynamic>{
                'maxWidth': 10.0,
                'maxHeight': null,
                'imageQuality': null,
              }),
              isMethodCall('pickMultiImage', arguments: <String, dynamic>{
                'maxWidth': null,
                'maxHeight': 10.0,
                'imageQuality': null,
              }),
              isMethodCall('pickMultiImage', arguments: <String, dynamic>{
                'maxWidth': 10.0,
                'maxHeight': 20.0,
                'imageQuality': null,
              }),
              isMethodCall('pickMultiImage', arguments: <String, dynamic>{
                'maxWidth': 10.0,
                'maxHeight': null,
                'imageQuality': 70,
              }),
              isMethodCall('pickMultiImage', arguments: <String, dynamic>{
                'maxWidth': null,
                'maxHeight': 10.0,
                'imageQuality': 70,
              }),
              isMethodCall('pickMultiImage', arguments: <String, dynamic>{
                'maxWidth': 10.0,
                'maxHeight': 20.0,
                'imageQuality': 70,
              }),
            ],
          );
        });

        test('does not accept a negative width or height argument', () {
          expect(
            picker.getMultiImage(maxWidth: -1.0),
            throwsArgumentError,
          );

          expect(
            picker.getMultiImage(maxHeight: -1.0),
            throwsArgumentError,
          );
        });

        test('handles a null image path response gracefully', () async {
          channel.setMockMethodCallHandler((MethodCall methodCall) => null);

          expect(await picker.getMultiImage(), isNull);
          expect(await picker.getMultiImage(), isNull);
        });
      });
    });
  });
}

class MockPlatform extends Mock
    with MockPlatformInterfaceMixin
    implements ImagePickerPlatform {}
