openEventsPlatformApp/plugins/cordova-plugin-camera/tests/ios/CDVCameraTest/CDVCameraLibTests/CameraTest.m
plugins/cordova-plugin-camera/tests/ios/CDVCameraTest/CDVCameraLibTests/CameraTest.mRaw
1/*
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18 */
19
20#import <UIKit/UIKit.h>
21#import <XCTest/XCTest.h>
22#import "CDVCamera.h"
23#import "UIImage+CropScaleOrientation.h"
24#import <MobileCoreServices/UTCoreTypes.h>
25
26
27@interface CameraTest : XCTestCase
28
29@property (nonatomic, strong) CDVCamera* plugin;
30
31@end
32
33@interface CDVCamera ()
34
35// expose private interface
36- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options;
37- (UIImage*)retrieveImage:(NSDictionary*)info options:(CDVPictureOptions*)options;
38- (CDVPluginResult*)resultForImage:(CDVPictureOptions*)options info:(NSDictionary*)info;
39- (CDVPluginResult*)resultForVideo:(NSDictionary*)info;
40
41@end
42
43@implementation CameraTest
44
45- (void)setUp {
46 [super setUp];
47 // Put setup code here. This method is called before the invocation of each test method in the class.
48
49 self.plugin = [[CDVCamera alloc] init];
50}
51
52- (void)tearDown {
53 // Put teardown code here. This method is called after the invocation of each test method in the class.
54 [super tearDown];
55}
56
57- (void) testPictureOptionsCreate
58{
59 NSArray* args;
60 CDVPictureOptions* options;
61 NSDictionary* popoverOptions;
62
63 // No arguments, check whether the defaults are set
64 args = @[];
65 CDVInvokedUrlCommand* command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
66
67 options = [CDVPictureOptions createFromTakePictureArguments:command];
68
69 XCTAssertEqual([options.quality intValue], 50);
70 XCTAssertEqual(options.destinationType, (int)DestinationTypeFileUri);
71 XCTAssertEqual(options.sourceType, (int)UIImagePickerControllerSourceTypeCamera);
72 XCTAssertEqual(options.targetSize.width, 0);
73 XCTAssertEqual(options.targetSize.height, 0);
74 XCTAssertEqual(options.encodingType, (int)EncodingTypeJPEG);
75 XCTAssertEqual(options.mediaType, (int)MediaTypePicture);
76 XCTAssertEqual(options.allowsEditing, NO);
77 XCTAssertEqual(options.correctOrientation, NO);
78 XCTAssertEqual(options.saveToPhotoAlbum, NO);
79 XCTAssertEqualObjects(options.popoverOptions, nil);
80 XCTAssertEqual(options.cameraDirection, (int)UIImagePickerControllerCameraDeviceRear);
81 XCTAssertEqual(options.popoverSupported, NO);
82 XCTAssertEqual(options.usesGeolocation, NO);
83
84 // Set each argument, check whether they are set. different from defaults
85 popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4 };
86
87 args = @[
88 @(49),
89 @(DestinationTypeDataUrl),
90 @(UIImagePickerControllerSourceTypePhotoLibrary),
91 @(120),
92 @(240),
93 @(EncodingTypePNG),
94 @(MediaTypeVideo),
95 @YES,
96 @YES,
97 @YES,
98 popoverOptions,
99 @(UIImagePickerControllerCameraDeviceFront),
100 ];
101
102 command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
103 options = [CDVPictureOptions createFromTakePictureArguments:command];
104
105 XCTAssertEqual([options.quality intValue], 49);
106 XCTAssertEqual(options.destinationType, (int)DestinationTypeDataUrl);
107 XCTAssertEqual(options.sourceType, (int)UIImagePickerControllerSourceTypePhotoLibrary);
108 XCTAssertEqual(options.targetSize.width, 120);
109 XCTAssertEqual(options.targetSize.height, 240);
110 XCTAssertEqual(options.encodingType, (int)EncodingTypePNG);
111 XCTAssertEqual(options.mediaType, (int)MediaTypeVideo);
112 XCTAssertEqual(options.allowsEditing, YES);
113 XCTAssertEqual(options.correctOrientation, YES);
114 XCTAssertEqual(options.saveToPhotoAlbum, YES);
115 XCTAssertEqualObjects(options.popoverOptions, popoverOptions);
116 XCTAssertEqual(options.cameraDirection, (int)UIImagePickerControllerCameraDeviceFront);
117 XCTAssertEqual(options.popoverSupported, NO);
118 XCTAssertEqual(options.usesGeolocation, NO);
119}
120
121- (void) testCameraPickerCreate
122{
123 NSDictionary* popoverOptions;
124 NSArray* args;
125 CDVPictureOptions* pictureOptions;
126 CDVCameraPicker* picker;
127
128 // Souce is Camera, and image type
129
130 popoverOptions = @{ @"x" : @1, @"y" : @2, @"width" : @3, @"height" : @4 };
131 args = @[
132 @(49),
133 @(DestinationTypeDataUrl),
134 @(UIImagePickerControllerSourceTypeCamera),
135 @(120),
136 @(240),
137 @(EncodingTypePNG),
138 @(MediaTypeAll),
139 @YES,
140 @YES,
141 @YES,
142 popoverOptions,
143 @(UIImagePickerControllerCameraDeviceFront),
144 ];
145
146 CDVInvokedUrlCommand* command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
147 pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
148
149 if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
150 picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
151
152 XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
153
154 XCTAssertEqual(picker.sourceType, pictureOptions.sourceType);
155 XCTAssertEqual(picker.allowsEditing, pictureOptions.allowsEditing);
156 XCTAssertEqualObjects(picker.mediaTypes, @[(NSString*)kUTTypeImage]);
157 XCTAssertEqual(picker.cameraDevice, pictureOptions.cameraDirection);
158 }
159
160 // Souce is not Camera, and all media types
161
162 args = @[
163 @(49),
164 @(DestinationTypeDataUrl),
165 @(UIImagePickerControllerSourceTypePhotoLibrary),
166 @(120),
167 @(240),
168 @(EncodingTypePNG),
169 @(MediaTypeAll),
170 @YES,
171 @YES,
172 @YES,
173 popoverOptions,
174 @(UIImagePickerControllerCameraDeviceFront),
175 ];
176
177 command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
178 pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
179
180 if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
181 picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
182
183 XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
184
185 XCTAssertEqual(picker.sourceType, pictureOptions.sourceType);
186 XCTAssertEqual(picker.allowsEditing, pictureOptions.allowsEditing);
187 XCTAssertEqualObjects(picker.mediaTypes, [UIImagePickerController availableMediaTypesForSourceType:picker.sourceType]);
188 }
189
190 // Souce is not Camera, and either Image or Movie media type
191
192 args = @[
193 @(49),
194 @(DestinationTypeDataUrl),
195 @(UIImagePickerControllerSourceTypePhotoLibrary),
196 @(120),
197 @(240),
198 @(EncodingTypePNG),
199 @(MediaTypeVideo),
200 @YES,
201 @YES,
202 @YES,
203 popoverOptions,
204 @(UIImagePickerControllerCameraDeviceFront),
205 ];
206
207 command = [[CDVInvokedUrlCommand alloc] initWithArguments:args callbackId:@"dummy" className:@"myclassname" methodName:@"mymethodname"];
208 pictureOptions = [CDVPictureOptions createFromTakePictureArguments:command];
209
210 if ([UIImagePickerController isSourceTypeAvailable:pictureOptions.sourceType]) {
211 picker = [CDVCameraPicker createFromPictureOptions:pictureOptions];
212
213 XCTAssertEqualObjects(picker.pictureOptions, pictureOptions);
214
215 XCTAssertEqual(picker.sourceType, pictureOptions.sourceType);
216 XCTAssertEqual(picker.allowsEditing, pictureOptions.allowsEditing);
217 XCTAssertEqualObjects(picker.mediaTypes, @[(NSString*)kUTTypeMovie]);
218 }
219}
220
221- (UIImage*) createImage:(CGRect)rect orientation:(UIImageOrientation)imageOrientation {
222 UIGraphicsBeginImageContext(rect.size);
223 CGContextRef context = UIGraphicsGetCurrentContext();
224
225 CGContextSetFillColorWithColor(context, [[UIColor greenColor] CGColor]);
226 CGContextFillRect(context, rect);
227
228 CGImageRef result = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());
229 UIImage* image = [UIImage imageWithCGImage:result scale:1.0f orientation:imageOrientation];
230
231 UIGraphicsEndImageContext();
232
233 return image;
234}
235
236- (void) testImageScaleCropForSize {
237
238 UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
239 CGSize targetSize = CGSizeZero;
240
241 sourceImagePortrait = [self createImage:CGRectMake(0, 0, 2448, 3264) orientation:UIImageOrientationUp];
242 sourceImageLandscape = [self createImage:CGRectMake(0, 0, 3264, 2448) orientation:UIImageOrientationUp];
243
244 // test 640x480
245
246 targetSize = CGSizeMake(640, 480);
247
248 targetImage = [sourceImagePortrait imageByScalingAndCroppingForSize:targetSize];
249 XCTAssertEqual(targetImage.size.width, targetSize.width);
250 XCTAssertEqual(targetImage.size.height, targetSize.height);
251
252 targetImage = [sourceImageLandscape imageByScalingAndCroppingForSize:targetSize];
253 XCTAssertEqual(targetImage.size.width, targetSize.width);
254 XCTAssertEqual(targetImage.size.height, targetSize.height);
255
256
257 // test 800x600
258
259 targetSize = CGSizeMake(800, 600);
260
261 targetImage = [sourceImagePortrait imageByScalingAndCroppingForSize:targetSize];
262 XCTAssertEqual(targetImage.size.width, targetSize.width);
263 XCTAssertEqual(targetImage.size.height, targetSize.height);
264
265 targetImage = [sourceImageLandscape imageByScalingAndCroppingForSize:targetSize];
266 XCTAssertEqual(targetImage.size.width, targetSize.width);
267 XCTAssertEqual(targetImage.size.height, targetSize.height);
268
269 // test 1024x768
270
271 targetSize = CGSizeMake(1024, 768);
272
273 targetImage = [sourceImagePortrait imageByScalingAndCroppingForSize:targetSize];
274 XCTAssertEqual(targetImage.size.width, targetSize.width);
275 XCTAssertEqual(targetImage.size.height, targetSize.height);
276
277 targetImage = [sourceImageLandscape imageByScalingAndCroppingForSize:targetSize];
278 XCTAssertEqual(targetImage.size.width, targetSize.width);
279 XCTAssertEqual(targetImage.size.height, targetSize.height);
280}
281
282- (void) testImageScaleNoCropForSize {
283 UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
284 CGSize targetSize = CGSizeZero;
285
286 sourceImagePortrait = [self createImage:CGRectMake(0, 0, 2448, 3264) orientation:UIImageOrientationUp];
287 sourceImageLandscape = [self createImage:CGRectMake(0, 0, 3264, 2448) orientation:UIImageOrientationUp];
288
289 // test 640x480
290
291 targetSize = CGSizeMake(480, 640);
292
293 targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
294 XCTAssertEqual(targetImage.size.width, targetSize.width);
295 XCTAssertEqual(targetImage.size.height, targetSize.height);
296
297 targetSize = CGSizeMake(640, 480);
298
299 targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
300 XCTAssertEqual(targetImage.size.width, targetSize.width);
301 XCTAssertEqual(targetImage.size.height, targetSize.height);
302
303
304 // test 800x600
305
306 targetSize = CGSizeMake(600, 800);
307
308 targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
309 XCTAssertEqual(targetImage.size.width, targetSize.width);
310 XCTAssertEqual(targetImage.size.height, targetSize.height);
311
312 targetSize = CGSizeMake(800, 600);
313
314 targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
315 XCTAssertEqual(targetImage.size.width, targetSize.width);
316 XCTAssertEqual(targetImage.size.height, targetSize.height);
317
318 // test 1024x768
319
320 targetSize = CGSizeMake(768, 1024);
321
322 targetImage = [sourceImagePortrait imageByScalingNotCroppingForSize:targetSize];
323 XCTAssertEqual(targetImage.size.width, targetSize.width);
324 XCTAssertEqual(targetImage.size.height, targetSize.height);
325
326 targetSize = CGSizeMake(1024, 768);
327
328 targetImage = [sourceImageLandscape imageByScalingNotCroppingForSize:targetSize];
329 XCTAssertEqual(targetImage.size.width, targetSize.width);
330 XCTAssertEqual(targetImage.size.height, targetSize.height);
331}
332
333- (void) testImageCorrectedForOrientation {
334 UIImage *sourceImagePortrait, *sourceImageLandscape, *targetImage;
335 CGSize targetSize = CGSizeZero;
336
337 sourceImagePortrait = [self createImage:CGRectMake(0, 0, 2448, 3264) orientation:UIImageOrientationDown];
338 sourceImageLandscape = [self createImage:CGRectMake(0, 0, 3264, 2448) orientation:UIImageOrientationDown];
339
340 // PORTRAIT - image size should be unchanged
341
342 targetSize = CGSizeMake(2448, 3264);
343
344 targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationUp];
345 XCTAssertEqual(targetImage.size.width, targetSize.width);
346 XCTAssertEqual(targetImage.size.height, targetSize.height);
347 XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
348
349 targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationDown];
350 XCTAssertEqual(targetImage.size.width, targetSize.width);
351 XCTAssertEqual(targetImage.size.height, targetSize.height);
352 XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
353
354 targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationRight];
355 XCTAssertEqual(targetImage.size.width, targetSize.width);
356 XCTAssertEqual(targetImage.size.height, targetSize.height);
357 XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
358
359 targetImage = [sourceImagePortrait imageCorrectedForCaptureOrientation:UIImageOrientationLeft];
360 XCTAssertEqual(targetImage.size.width, targetSize.width);
361 XCTAssertEqual(targetImage.size.height, targetSize.height);
362 XCTAssertEqual(targetImage.imageOrientation, UIImageOrientationUp);
363
364 // LANDSCAPE - image size should be unchanged
365
366 targetSize = CGSizeMake(3264, 2448);
367
368 targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationUp];
369 XCTAssertEqual(targetImage.size.width, targetSize.width);
370 XCTAssertEqual(targetImage.size.height, targetSize.height);
371
372 targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationDown];
373 XCTAssertEqual(targetImage.size.width, targetSize.width);
374 XCTAssertEqual(targetImage.size.height, targetSize.height);
375
376 targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationRight];
377 XCTAssertEqual(targetImage.size.width, targetSize.width);
378 XCTAssertEqual(targetImage.size.height, targetSize.height);
379
380 targetImage = [sourceImageLandscape imageCorrectedForCaptureOrientation:UIImageOrientationLeft];
381 XCTAssertEqual(targetImage.size.width, targetSize.width);
382 XCTAssertEqual(targetImage.size.height, targetSize.height);
383}
384
385
386- (void) testRetrieveImage
387{
388 CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
389 NSDictionary *infoDict1, *infoDict2;
390 UIImage* resultImage;
391
392 UIImage* originalImage = [self createImage:CGRectMake(0, 0, 1024, 768) orientation:UIImageOrientationDown];
393 UIImage* originalCorrectedForOrientation = [originalImage imageCorrectedForCaptureOrientation];
394
395 UIImage* editedImage = [self createImage:CGRectMake(0, 0, 800, 600) orientation:UIImageOrientationDown];
396 UIImage* scaledImageWithCrop = [originalImage imageByScalingAndCroppingForSize:CGSizeMake(640, 480)];
397 UIImage* scaledImageNoCrop = [originalImage imageByScalingNotCroppingForSize:CGSizeMake(640, 480)];
398
399 infoDict1 = @{
400 UIImagePickerControllerOriginalImage : originalImage
401 };
402
403 infoDict2 = @{
404 UIImagePickerControllerOriginalImage : originalImage,
405 UIImagePickerControllerEditedImage : editedImage
406 };
407
408 // Original with no options
409
410 pictureOptions.allowsEditing = YES;
411 pictureOptions.targetSize = CGSizeZero;
412 pictureOptions.cropToSize = NO;
413 pictureOptions.correctOrientation = NO;
414
415 resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
416 XCTAssertEqualObjects(resultImage, originalImage);
417
418 // Original with no options
419
420 pictureOptions.allowsEditing = YES;
421 pictureOptions.targetSize = CGSizeZero;
422 pictureOptions.cropToSize = NO;
423 pictureOptions.correctOrientation = NO;
424
425 resultImage = [self.plugin retrieveImage:infoDict2 options:pictureOptions];
426 XCTAssertEqualObjects(resultImage, editedImage);
427
428 // Original with corrected orientation
429
430 pictureOptions.allowsEditing = YES;
431 pictureOptions.targetSize = CGSizeZero;
432 pictureOptions.cropToSize = NO;
433 pictureOptions.correctOrientation = YES;
434
435 resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
436 XCTAssertNotEqual(resultImage.imageOrientation, originalImage.imageOrientation);
437 XCTAssertEqual(resultImage.imageOrientation, originalCorrectedForOrientation.imageOrientation);
438 XCTAssertEqual(resultImage.size.width, originalCorrectedForOrientation.size.width);
439 XCTAssertEqual(resultImage.size.height, originalCorrectedForOrientation.size.height);
440
441 // Original with targetSize, no crop
442
443 pictureOptions.allowsEditing = YES;
444 pictureOptions.targetSize = CGSizeMake(640, 480);
445 pictureOptions.cropToSize = NO;
446 pictureOptions.correctOrientation = NO;
447
448 resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
449 XCTAssertEqual(resultImage.size.width, scaledImageNoCrop.size.width);
450 XCTAssertEqual(resultImage.size.height, scaledImageNoCrop.size.height);
451
452 // Original with targetSize, plus crop
453
454 pictureOptions.allowsEditing = YES;
455 pictureOptions.targetSize = CGSizeMake(640, 480);
456 pictureOptions.cropToSize = YES;
457 pictureOptions.correctOrientation = NO;
458
459 resultImage = [self.plugin retrieveImage:infoDict1 options:pictureOptions];
460 XCTAssertEqual(resultImage.size.width, scaledImageWithCrop.size.width);
461 XCTAssertEqual(resultImage.size.height, scaledImageWithCrop.size.height);
462}
463
464- (void) testProcessImage
465{
466 CDVPictureOptions* pictureOptions = [[CDVPictureOptions alloc] init];
467 NSData* resultData;
468
469 UIImage* originalImage = [self createImage:CGRectMake(0, 0, 1024, 768) orientation:UIImageOrientationDown];
470 NSData* originalImageDataPNG = UIImagePNGRepresentation(originalImage);
471 NSData* originalImageDataJPEG = UIImageJPEGRepresentation(originalImage, 1.0);
472
473 // Original, PNG
474
475 pictureOptions.allowsEditing = YES;
476 pictureOptions.targetSize = CGSizeZero;
477 pictureOptions.cropToSize = NO;
478 pictureOptions.correctOrientation = NO;
479 pictureOptions.encodingType = EncodingTypePNG;
480
481 resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
482 XCTAssertEqualObjects([resultData base64EncodedStringWithOptions:0], [originalImageDataPNG base64EncodedStringWithOptions:0]);
483
484 // Original, JPEG, full quality
485
486 pictureOptions.allowsEditing = NO;
487 pictureOptions.targetSize = CGSizeZero;
488 pictureOptions.cropToSize = NO;
489 pictureOptions.correctOrientation = NO;
490 pictureOptions.encodingType = EncodingTypeJPEG;
491
492 resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
493 XCTAssertEqualObjects([resultData base64EncodedStringWithOptions:0], [originalImageDataJPEG base64EncodedStringWithOptions:0]);
494
495 // Original, JPEG, with quality value
496
497 pictureOptions.allowsEditing = YES;
498 pictureOptions.targetSize = CGSizeZero;
499 pictureOptions.cropToSize = NO;
500 pictureOptions.correctOrientation = NO;
501 pictureOptions.encodingType = EncodingTypeJPEG;
502 pictureOptions.quality = @(57);
503
504 NSData* originalImageDataJPEGWithQuality = UIImageJPEGRepresentation(originalImage, [pictureOptions.quality floatValue]/ 100.f);
505 resultData = [self.plugin processImage:originalImage info:@{} options:pictureOptions];
506 XCTAssertEqualObjects([resultData base64EncodedStringWithOptions:0], [originalImageDataJPEGWithQuality base64EncodedStringWithOptions:0]);
507
508 // TODO: usesGeolocation is not tested
509}
510
511@end