blob: 5f3287400c5e93c8578d2615c21e5b14407c254c [file] [log] [blame]
// 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 "ImagePickerTestImages.h"
@import image_picker;
@import image_picker.Test;
@import XCTest;
#import <OCMock/OCMock.h>
@interface MockViewController : UIViewController
@property(nonatomic, retain) UIViewController *mockPresented;
@end
@implementation MockViewController
@synthesize mockPresented;
- (UIViewController *)presentedViewController {
return mockPresented;
}
@end
@interface ImagePickerPluginTests : XCTestCase
@end
@implementation ImagePickerPluginTests
- (void)testPluginPickImageDeviceBack {
id mockUIImagePicker = OCMClassMock([UIImagePickerController class]);
id mockAVCaptureDevice = OCMClassMock([AVCaptureDevice class]);
// UIImagePickerControllerSourceTypeCamera is supported
OCMStub(ClassMethod(
[mockUIImagePicker isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]))
.andReturn(YES);
// UIImagePickerControllerCameraDeviceRear is supported
OCMStub(ClassMethod(
[mockUIImagePicker isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]))
.andReturn(YES);
// AVAuthorizationStatusAuthorized is supported
OCMStub([mockAVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusAuthorized);
// Run test
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
FlutterMethodCall *call =
[FlutterMethodCall methodCallWithMethodName:@"pickImage"
arguments:@{@"source" : @(0), @"cameraDevice" : @(0)}];
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
[plugin setImagePickerControllerOverrides:@[ controller ]];
[plugin handleMethodCall:call
result:^(id _Nullable r){
}];
XCTAssertEqual(controller.cameraDevice, UIImagePickerControllerCameraDeviceRear);
}
- (void)testPluginPickImageDeviceFront {
id mockUIImagePicker = OCMClassMock([UIImagePickerController class]);
id mockAVCaptureDevice = OCMClassMock([AVCaptureDevice class]);
// UIImagePickerControllerSourceTypeCamera is supported
OCMStub(ClassMethod(
[mockUIImagePicker isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]))
.andReturn(YES);
// UIImagePickerControllerCameraDeviceFront is supported
OCMStub(ClassMethod(
[mockUIImagePicker isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]))
.andReturn(YES);
// AVAuthorizationStatusAuthorized is supported
OCMStub([mockAVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusAuthorized);
// Run test
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
FlutterMethodCall *call =
[FlutterMethodCall methodCallWithMethodName:@"pickImage"
arguments:@{@"source" : @(0), @"cameraDevice" : @(1)}];
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
[plugin setImagePickerControllerOverrides:@[ controller ]];
[plugin handleMethodCall:call
result:^(id _Nullable r){
}];
XCTAssertEqual(controller.cameraDevice, UIImagePickerControllerCameraDeviceFront);
}
- (void)testPluginPickVideoDeviceBack {
id mockUIImagePicker = OCMClassMock([UIImagePickerController class]);
id mockAVCaptureDevice = OCMClassMock([AVCaptureDevice class]);
// UIImagePickerControllerSourceTypeCamera is supported
OCMStub(ClassMethod(
[mockUIImagePicker isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]))
.andReturn(YES);
// UIImagePickerControllerCameraDeviceRear is supported
OCMStub(ClassMethod(
[mockUIImagePicker isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear]))
.andReturn(YES);
// AVAuthorizationStatusAuthorized is supported
OCMStub([mockAVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusAuthorized);
// Run test
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
FlutterMethodCall *call =
[FlutterMethodCall methodCallWithMethodName:@"pickVideo"
arguments:@{@"source" : @(0), @"cameraDevice" : @(0)}];
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
[plugin setImagePickerControllerOverrides:@[ controller ]];
[plugin handleMethodCall:call
result:^(id _Nullable r){
}];
XCTAssertEqual(controller.cameraDevice, UIImagePickerControllerCameraDeviceRear);
}
- (void)testPluginPickVideoDeviceFront {
id mockUIImagePicker = OCMClassMock([UIImagePickerController class]);
id mockAVCaptureDevice = OCMClassMock([AVCaptureDevice class]);
// UIImagePickerControllerSourceTypeCamera is supported
OCMStub(ClassMethod(
[mockUIImagePicker isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]))
.andReturn(YES);
// UIImagePickerControllerCameraDeviceFront is supported
OCMStub(ClassMethod(
[mockUIImagePicker isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]))
.andReturn(YES);
// AVAuthorizationStatusAuthorized is supported
OCMStub([mockAVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusAuthorized);
// Run test
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
FlutterMethodCall *call =
[FlutterMethodCall methodCallWithMethodName:@"pickVideo"
arguments:@{@"source" : @(0), @"cameraDevice" : @(1)}];
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
[plugin setImagePickerControllerOverrides:@[ controller ]];
[plugin handleMethodCall:call
result:^(id _Nullable r){
}];
XCTAssertEqual(controller.cameraDevice, UIImagePickerControllerCameraDeviceFront);
}
- (void)testPickMultiImageShouldUseUIImagePickerControllerOnPreiOS14 {
if (@available(iOS 14, *)) {
return;
}
id mockUIImagePicker = OCMClassMock([UIImagePickerController class]);
id photoLibrary = OCMClassMock([PHPhotoLibrary class]);
OCMStub(ClassMethod([photoLibrary authorizationStatus]))
.andReturn(PHAuthorizationStatusAuthorized);
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
[plugin setImagePickerControllerOverrides:@[ mockUIImagePicker ]];
FlutterMethodCall *call = [FlutterMethodCall methodCallWithMethodName:@"pickMultiImage"
arguments:@{
@"maxWidth" : @(100),
@"maxHeight" : @(200),
@"imageQuality" : @(50),
}];
[plugin handleMethodCall:call
result:^(id _Nullable r){
}];
OCMVerify(times(1),
[mockUIImagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]);
}
#pragma mark - Test camera devices, no op on simulators
- (void)testPluginPickImageDeviceCancelClickMultipleTimes {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
return;
}
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
FlutterMethodCall *call =
[FlutterMethodCall methodCallWithMethodName:@"pickImage"
arguments:@{@"source" : @(0), @"cameraDevice" : @(1)}];
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
plugin.imagePickerControllerOverrides = @[ controller ];
[plugin handleMethodCall:call
result:^(id _Nullable r){
}];
plugin.result = ^(id result) {
};
// To ensure the flow does not crash by multiple cancel call
[plugin imagePickerControllerDidCancel:controller];
[plugin imagePickerControllerDidCancel:controller];
}
#pragma mark - Test video duration
- (void)testPickingVideoWithDuration {
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
FlutterMethodCall *call = [FlutterMethodCall
methodCallWithMethodName:@"pickVideo"
arguments:@{@"source" : @(0), @"cameraDevice" : @(0), @"maxDuration" : @95}];
UIImagePickerController *controller = [[UIImagePickerController alloc] init];
[plugin setImagePickerControllerOverrides:@[ controller ]];
[plugin handleMethodCall:call
result:^(id _Nullable r){
}];
XCTAssertEqual(controller.videoMaximumDuration, 95);
}
- (void)testViewController {
UIWindow *window = [UIWindow new];
MockViewController *vc1 = [MockViewController new];
window.rootViewController = vc1;
UIViewController *vc2 = [UIViewController new];
vc1.mockPresented = vc2;
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
XCTAssertEqual([plugin viewControllerWithWindow:window], vc2);
}
- (void)testPluginMultiImagePathIsNil {
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
dispatch_semaphore_t resultSemaphore = dispatch_semaphore_create(0);
__block FlutterError *pickImageResult = nil;
plugin.result = ^(id _Nullable r) {
pickImageResult = r;
dispatch_semaphore_signal(resultSemaphore);
};
[plugin handleSavedPathList:nil];
dispatch_semaphore_wait(resultSemaphore, DISPATCH_TIME_FOREVER);
XCTAssertEqualObjects(pickImageResult.code, @"create_error");
}
- (void)testPluginMultiImagePathHasNullItem {
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
NSMutableArray *pathList = [NSMutableArray new];
[pathList addObject:[NSNull null]];
dispatch_semaphore_t resultSemaphore = dispatch_semaphore_create(0);
__block FlutterError *pickImageResult = nil;
plugin.result = ^(id _Nullable r) {
pickImageResult = r;
dispatch_semaphore_signal(resultSemaphore);
};
[plugin handleSavedPathList:pathList];
dispatch_semaphore_wait(resultSemaphore, DISPATCH_TIME_FOREVER);
XCTAssertEqualObjects(pickImageResult.code, @"create_error");
}
- (void)testPluginMultiImagePathHasItem {
FLTImagePickerPlugin *plugin = [FLTImagePickerPlugin new];
NSString *savedPath = @"test";
NSMutableArray *pathList = [NSMutableArray new];
[pathList addObject:savedPath];
dispatch_semaphore_t resultSemaphore = dispatch_semaphore_create(0);
__block id pickImageResult = nil;
plugin.result = ^(id _Nullable r) {
pickImageResult = r;
dispatch_semaphore_signal(resultSemaphore);
};
[plugin handleSavedPathList:pathList];
dispatch_semaphore_wait(resultSemaphore, DISPATCH_TIME_FOREVER);
XCTAssertEqual(pickImageResult, pathList);
}
@end