Skip to content

[camera] Remove OCMock from permission tests #8350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/camera/camera_avfoundation/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## NEXT
## 0.9.17+6

* Updates minimum supported SDK version to Flutter 3.22/Dart 3.4.
* Removes OCMock usage from permission tests

## 0.9.17+5

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,58 @@
#endif
@import AVFoundation;
@import XCTest;
#import <OCMock/OCMock.h>

#import "CameraTestUtils.h"

@interface CameraPermissionTests : XCTestCase
@interface MockPermissionService : NSObject <FLTPermissionServicing>
@property(nonatomic, copy) AVAuthorizationStatus (^authorizationStatusStub)(AVMediaType mediaType);
@property(nonatomic, copy) void (^requestAccessStub)(AVMediaType mediaType, void (^handler)(BOOL));
@end

@implementation MockPermissionService
- (AVAuthorizationStatus)authorizationStatusForMediaType:(AVMediaType)mediaType {
return self.authorizationStatusStub ? self.authorizationStatusStub(mediaType)
: AVAuthorizationStatusNotDetermined;
}

- (void)requestAccessForMediaType:(AVMediaType)mediaType completionHandler:(void (^)(BOOL))handler {
if (self.requestAccessStub) {
self.requestAccessStub(mediaType, handler);
}
}
@end

@implementation CameraPermissionTests
@interface FLTCameraPermissionManagerTests : XCTestCase
@property(nonatomic, strong) FLTCameraPermissionManager *permissionManager;
@property(nonatomic, strong) MockPermissionService *mockService;
@end

@implementation FLTCameraPermissionManagerTests

- (void)setUp {
[super setUp];
self.mockService = [[MockPermissionService alloc] init];
self.permissionManager =
[[FLTCameraPermissionManager alloc] initWithPermissionService:self.mockService];
}

#pragma mark - camera permissions

- (void)testRequestCameraPermission_completeWithoutErrorIfPrevoiuslyAuthorized {
- (void)testRequestCameraPermission_completeWithoutErrorIfPreviouslyAuthorized {
XCTestExpectation *expectation =
[self expectationWithDescription:
@"Must copmlete without error if camera access was previously authorized."];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusAuthorized);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeVideo);
return AVAuthorizationStatusAuthorized;
};

FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
[self.permissionManager requestCameraPermissionWithCompletionHandler:^(FlutterError *error) {
if (error == nil) {
[expectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}
- (void)testRequestCameraPermission_completeWithErrorIfPreviouslyDenied {
Expand All @@ -45,14 +72,16 @@ - (void)testRequestCameraPermission_completeWithErrorIfPreviouslyDenied {
@"Settings to enable camera access."
details:nil];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusDenied);
FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeVideo);
return AVAuthorizationStatusDenied;
};

[self.permissionManager requestCameraPermissionWithCompletionHandler:^(FlutterError *error) {
if ([error isEqual:expectedError]) {
[expectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

Expand All @@ -63,37 +92,39 @@ - (void)testRequestCameraPermission_completeWithErrorIfRestricted {
message:@"Camera access is restricted. "
details:nil];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusRestricted);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeVideo);
return AVAuthorizationStatusRestricted;
};

FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
[self.permissionManager requestCameraPermissionWithCompletionHandler:^(FlutterError *error) {
if ([error isEqual:expectedError]) {
[expectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testRequestCameraPermission_completeWithoutErrorIfUserGrantAccess {
XCTestExpectation *grantedExpectation = [self
expectationWithDescription:@"Must complete without error if user choose to grant access"];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusNotDetermined);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeVideo);
return AVAuthorizationStatusNotDetermined;
};

// Mimic user choosing "allow" in permission dialog.
OCMStub([mockDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:[OCMArg checkWithBlock:^BOOL(void (^block)(BOOL)) {
block(YES);
return YES;
}]]);
self.mockService.requestAccessStub = ^(AVMediaType mediaType, void (^handler)(BOOL)) {
XCTAssertEqualObjects(mediaType, AVMediaTypeVideo);
handler(YES);
};

FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
[self.permissionManager requestCameraPermissionWithCompletionHandler:^(FlutterError *error) {
if (error == nil) {
[grantedExpectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

Expand All @@ -105,21 +136,22 @@ - (void)testRequestCameraPermission_completeWithErrorIfUserDenyAccess {
message:@"User denied the camera access request."
details:nil];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeVideo])
.andReturn(AVAuthorizationStatusNotDetermined);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeVideo);
return AVAuthorizationStatusNotDetermined;
};

// Mimic user choosing "deny" in permission dialog.
OCMStub([mockDevice requestAccessForMediaType:AVMediaTypeVideo
completionHandler:[OCMArg checkWithBlock:^BOOL(void (^block)(BOOL)) {
block(NO);
return YES;
}]]);
FLTRequestCameraPermissionWithCompletionHandler(^(FlutterError *error) {
self.mockService.requestAccessStub = ^(AVMediaType mediaType, void (^handler)(BOOL)) {
XCTAssertEqualObjects(mediaType, AVMediaTypeVideo);
handler(NO);
};

[self.permissionManager requestCameraPermissionWithCompletionHandler:^(FlutterError *error) {
if ([error isEqual:expectedError]) {
[expectation fulfill];
}
});
}];

[self waitForExpectationsWithTimeout:1 handler:nil];
}
Expand All @@ -131,17 +163,19 @@ - (void)testRequestAudioPermission_completeWithoutErrorIfPrevoiuslyAuthorized {
[self expectationWithDescription:
@"Must copmlete without error if audio access was previously authorized."];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeAudio])
.andReturn(AVAuthorizationStatusAuthorized);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeAudio);
return AVAuthorizationStatusAuthorized;
};

FLTRequestAudioPermissionWithCompletionHandler(^(FlutterError *error) {
[self.permissionManager requestAudioPermissionWithCompletionHandler:^(FlutterError *error) {
if (error == nil) {
[expectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testRequestAudioPermission_completeWithErrorIfPreviouslyDenied {
XCTestExpectation *expectation =
[self expectationWithDescription:
Expand All @@ -152,14 +186,16 @@ - (void)testRequestAudioPermission_completeWithErrorIfPreviouslyDenied {
@"Settings to enable audio access."
details:nil];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeAudio])
.andReturn(AVAuthorizationStatusDenied);
FLTRequestAudioPermissionWithCompletionHandler(^(FlutterError *error) {
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeAudio);
return AVAuthorizationStatusDenied;
};

[self.permissionManager requestAudioPermissionWithCompletionHandler:^(FlutterError *error) {
if ([error isEqual:expectedError]) {
[expectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

Expand All @@ -170,37 +206,39 @@ - (void)testRequestAudioPermission_completeWithErrorIfRestricted {
message:@"Audio access is restricted. "
details:nil];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeAudio])
.andReturn(AVAuthorizationStatusRestricted);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeAudio);
return AVAuthorizationStatusRestricted;
};

FLTRequestAudioPermissionWithCompletionHandler(^(FlutterError *error) {
[self.permissionManager requestAudioPermissionWithCompletionHandler:^(FlutterError *error) {
if ([error isEqual:expectedError]) {
[expectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

- (void)testRequestAudioPermission_completeWithoutErrorIfUserGrantAccess {
XCTestExpectation *grantedExpectation = [self
expectationWithDescription:@"Must complete without error if user choose to grant access"];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeAudio])
.andReturn(AVAuthorizationStatusNotDetermined);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeAudio);
return AVAuthorizationStatusNotDetermined;
};

// Mimic user choosing "allow" in permission dialog.
OCMStub([mockDevice requestAccessForMediaType:AVMediaTypeAudio
completionHandler:[OCMArg checkWithBlock:^BOOL(void (^block)(BOOL)) {
block(YES);
return YES;
}]]);
self.mockService.requestAccessStub = ^(AVMediaType mediaType, void (^handler)(BOOL)) {
XCTAssertEqualObjects(mediaType, AVMediaTypeAudio);
handler(YES);
};

FLTRequestAudioPermissionWithCompletionHandler(^(FlutterError *error) {
[self.permissionManager requestAudioPermissionWithCompletionHandler:^(FlutterError *error) {
if (error == nil) {
[grantedExpectation fulfill];
}
});
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

Expand All @@ -211,22 +249,22 @@ - (void)testRequestAudioPermission_completeWithErrorIfUserDenyAccess {
message:@"User denied the audio access request."
details:nil];

id mockDevice = OCMClassMock([AVCaptureDevice class]);
OCMStub([mockDevice authorizationStatusForMediaType:AVMediaTypeAudio])
.andReturn(AVAuthorizationStatusNotDetermined);
self.mockService.authorizationStatusStub = ^AVAuthorizationStatus(AVMediaType mediaType) {
XCTAssertEqualObjects(mediaType, AVMediaTypeAudio);
return AVAuthorizationStatusNotDetermined;
};

// Mimic user choosing "deny" in permission dialog.
OCMStub([mockDevice requestAccessForMediaType:AVMediaTypeAudio
completionHandler:[OCMArg checkWithBlock:^BOOL(void (^block)(BOOL)) {
block(NO);
return YES;
}]]);
FLTRequestAudioPermissionWithCompletionHandler(^(FlutterError *error) {
self.mockService.requestAccessStub = ^(AVMediaType mediaType, void (^handler)(BOOL)) {
XCTAssertEqualObjects(mediaType, AVMediaTypeAudio);
handler(NO);
};

[self.permissionManager requestAudioPermissionWithCompletionHandler:^(FlutterError *error) {
if ([error isEqual:expectedError]) {
[expectation fulfill];
}
});

}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}

Expand Down
Loading
Loading