8
8
#endif
9
9
@import AVFoundation;
10
10
@import XCTest;
11
- # import < OCMock/OCMock.h >
11
+
12
12
#import " CameraTestUtils.h"
13
13
14
- @interface CameraPermissionTests : XCTestCase
14
+ @interface MockPermissionService : NSObject <FLTPermissionServicing>
15
+ @property (nonatomic , copy ) AVAuthorizationStatus (^authorizationStatusStub)(AVMediaType mediaType);
16
+ @property (nonatomic , copy ) void (^requestAccessStub)(AVMediaType mediaType, void (^handler)(BOOL ));
17
+ @end
15
18
19
+ @implementation MockPermissionService
20
+ - (AVAuthorizationStatus)authorizationStatusForMediaType : (AVMediaType)mediaType {
21
+ return self.authorizationStatusStub ? self.authorizationStatusStub (mediaType)
22
+ : AVAuthorizationStatusNotDetermined;
23
+ }
24
+
25
+ - (void )requestAccessForMediaType : (AVMediaType)mediaType completionHandler : (void (^)(BOOL ))handler {
26
+ if (self.requestAccessStub ) {
27
+ self.requestAccessStub (mediaType, handler);
28
+ }
29
+ }
16
30
@end
17
31
18
- @implementation CameraPermissionTests
32
+ @interface FLTCameraPermissionManagerTests : XCTestCase
33
+ @property (nonatomic , strong ) FLTCameraPermissionManager *permissionManager;
34
+ @property (nonatomic , strong ) MockPermissionService *mockService;
35
+ @end
36
+
37
+ @implementation FLTCameraPermissionManagerTests
38
+
39
+ - (void )setUp {
40
+ [super setUp ];
41
+ self.mockService = [[MockPermissionService alloc ] init ];
42
+ self.permissionManager =
43
+ [[FLTCameraPermissionManager alloc ] initWithPermissionService: self .mockService];
44
+ }
19
45
20
46
#pragma mark - camera permissions
21
47
22
- - (void )testRequestCameraPermission_completeWithoutErrorIfPrevoiuslyAuthorized {
48
+ - (void )testRequestCameraPermission_completeWithoutErrorIfPreviouslyAuthorized {
23
49
XCTestExpectation *expectation =
24
50
[self expectationWithDescription:
25
51
@" Must copmlete without error if camera access was previously authorized." ];
26
52
27
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
28
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeVideo])
29
- .andReturn (AVAuthorizationStatusAuthorized);
53
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
54
+ XCTAssertEqualObjects (mediaType, AVMediaTypeVideo);
55
+ return AVAuthorizationStatusAuthorized;
56
+ };
30
57
31
- FLTRequestCameraPermissionWithCompletionHandler ( ^(FlutterError *error) {
58
+ [ self .permissionManager requestCameraPermissionWithCompletionHandler: ^(FlutterError *error) {
32
59
if (error == nil ) {
33
60
[expectation fulfill ];
34
61
}
35
- }) ;
62
+ }] ;
36
63
[self waitForExpectationsWithTimeout: 1 handler: nil ];
37
64
}
38
65
- (void )testRequestCameraPermission_completeWithErrorIfPreviouslyDenied {
@@ -45,14 +72,16 @@ - (void)testRequestCameraPermission_completeWithErrorIfPreviouslyDenied {
45
72
@" Settings to enable camera access."
46
73
details: nil ];
47
74
48
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
49
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeVideo])
50
- .andReturn (AVAuthorizationStatusDenied);
51
- FLTRequestCameraPermissionWithCompletionHandler (^(FlutterError *error) {
75
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
76
+ XCTAssertEqualObjects (mediaType, AVMediaTypeVideo);
77
+ return AVAuthorizationStatusDenied;
78
+ };
79
+
80
+ [self .permissionManager requestCameraPermissionWithCompletionHandler: ^(FlutterError *error) {
52
81
if ([error isEqual: expectedError]) {
53
82
[expectation fulfill ];
54
83
}
55
- }) ;
84
+ }] ;
56
85
[self waitForExpectationsWithTimeout: 1 handler: nil ];
57
86
}
58
87
@@ -63,37 +92,39 @@ - (void)testRequestCameraPermission_completeWithErrorIfRestricted {
63
92
message: @" Camera access is restricted. "
64
93
details: nil ];
65
94
66
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
67
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeVideo])
68
- .andReturn (AVAuthorizationStatusRestricted);
95
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
96
+ XCTAssertEqualObjects (mediaType, AVMediaTypeVideo);
97
+ return AVAuthorizationStatusRestricted;
98
+ };
69
99
70
- FLTRequestCameraPermissionWithCompletionHandler ( ^(FlutterError *error) {
100
+ [ self .permissionManager requestCameraPermissionWithCompletionHandler: ^(FlutterError *error) {
71
101
if ([error isEqual: expectedError]) {
72
102
[expectation fulfill ];
73
103
}
74
- }) ;
104
+ }] ;
75
105
[self waitForExpectationsWithTimeout: 1 handler: nil ];
76
106
}
77
107
78
108
- (void )testRequestCameraPermission_completeWithoutErrorIfUserGrantAccess {
79
109
XCTestExpectation *grantedExpectation = [self
80
110
expectationWithDescription: @" Must complete without error if user choose to grant access" ];
81
111
82
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
83
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeVideo])
84
- .andReturn (AVAuthorizationStatusNotDetermined);
112
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
113
+ XCTAssertEqualObjects (mediaType, AVMediaTypeVideo);
114
+ return AVAuthorizationStatusNotDetermined;
115
+ };
116
+
85
117
// Mimic user choosing "allow" in permission dialog.
86
- OCMStub ([mockDevice requestAccessForMediaType: AVMediaTypeVideo
87
- completionHandler: [OCMArg checkWithBlock: ^BOOL (void (^block)(BOOL )) {
88
- block (YES );
89
- return YES ;
90
- }]]);
118
+ self.mockService .requestAccessStub = ^(AVMediaType mediaType, void (^handler)(BOOL )) {
119
+ XCTAssertEqualObjects (mediaType, AVMediaTypeVideo);
120
+ handler (YES );
121
+ };
91
122
92
- FLTRequestCameraPermissionWithCompletionHandler ( ^(FlutterError *error) {
123
+ [ self .permissionManager requestCameraPermissionWithCompletionHandler: ^(FlutterError *error) {
93
124
if (error == nil ) {
94
125
[grantedExpectation fulfill ];
95
126
}
96
- }) ;
127
+ }] ;
97
128
[self waitForExpectationsWithTimeout: 1 handler: nil ];
98
129
}
99
130
@@ -105,21 +136,22 @@ - (void)testRequestCameraPermission_completeWithErrorIfUserDenyAccess {
105
136
message: @" User denied the camera access request."
106
137
details: nil ];
107
138
108
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
109
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeVideo])
110
- .andReturn (AVAuthorizationStatusNotDetermined);
139
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
140
+ XCTAssertEqualObjects (mediaType, AVMediaTypeVideo);
141
+ return AVAuthorizationStatusNotDetermined;
142
+ };
111
143
112
144
// Mimic user choosing "deny" in permission dialog.
113
- OCMStub ([mockDevice requestAccessForMediaType: AVMediaTypeVideo
114
- completionHandler: [OCMArg checkWithBlock: ^ BOOL ( void (^block)( BOOL )) {
115
- block (NO );
116
- return YES ;
117
- }]]);
118
- FLTRequestCameraPermissionWithCompletionHandler ( ^(FlutterError *error) {
145
+ self. mockService . requestAccessStub = ^(AVMediaType mediaType, void (^handler)( BOOL )) {
146
+ XCTAssertEqualObjects (mediaType, AVMediaTypeVideo);
147
+ handler (NO );
148
+ } ;
149
+
150
+ [ self .permissionManager requestCameraPermissionWithCompletionHandler: ^(FlutterError *error) {
119
151
if ([error isEqual: expectedError]) {
120
152
[expectation fulfill ];
121
153
}
122
- }) ;
154
+ }] ;
123
155
124
156
[self waitForExpectationsWithTimeout: 1 handler: nil ];
125
157
}
@@ -131,17 +163,19 @@ - (void)testRequestAudioPermission_completeWithoutErrorIfPrevoiuslyAuthorized {
131
163
[self expectationWithDescription:
132
164
@" Must copmlete without error if audio access was previously authorized." ];
133
165
134
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
135
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeAudio])
136
- .andReturn (AVAuthorizationStatusAuthorized);
166
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
167
+ XCTAssertEqualObjects (mediaType, AVMediaTypeAudio);
168
+ return AVAuthorizationStatusAuthorized;
169
+ };
137
170
138
- FLTRequestAudioPermissionWithCompletionHandler ( ^(FlutterError *error) {
171
+ [ self .permissionManager requestAudioPermissionWithCompletionHandler: ^(FlutterError *error) {
139
172
if (error == nil ) {
140
173
[expectation fulfill ];
141
174
}
142
- }) ;
175
+ }] ;
143
176
[self waitForExpectationsWithTimeout: 1 handler: nil ];
144
177
}
178
+
145
179
- (void )testRequestAudioPermission_completeWithErrorIfPreviouslyDenied {
146
180
XCTestExpectation *expectation =
147
181
[self expectationWithDescription:
@@ -152,14 +186,16 @@ - (void)testRequestAudioPermission_completeWithErrorIfPreviouslyDenied {
152
186
@" Settings to enable audio access."
153
187
details: nil ];
154
188
155
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
156
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeAudio])
157
- .andReturn (AVAuthorizationStatusDenied);
158
- FLTRequestAudioPermissionWithCompletionHandler (^(FlutterError *error) {
189
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
190
+ XCTAssertEqualObjects (mediaType, AVMediaTypeAudio);
191
+ return AVAuthorizationStatusDenied;
192
+ };
193
+
194
+ [self .permissionManager requestAudioPermissionWithCompletionHandler: ^(FlutterError *error) {
159
195
if ([error isEqual: expectedError]) {
160
196
[expectation fulfill ];
161
197
}
162
- }) ;
198
+ }] ;
163
199
[self waitForExpectationsWithTimeout: 1 handler: nil ];
164
200
}
165
201
@@ -170,37 +206,39 @@ - (void)testRequestAudioPermission_completeWithErrorIfRestricted {
170
206
message: @" Audio access is restricted. "
171
207
details: nil ];
172
208
173
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
174
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeAudio])
175
- .andReturn (AVAuthorizationStatusRestricted);
209
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
210
+ XCTAssertEqualObjects (mediaType, AVMediaTypeAudio);
211
+ return AVAuthorizationStatusRestricted;
212
+ };
176
213
177
- FLTRequestAudioPermissionWithCompletionHandler ( ^(FlutterError *error) {
214
+ [ self .permissionManager requestAudioPermissionWithCompletionHandler: ^(FlutterError *error) {
178
215
if ([error isEqual: expectedError]) {
179
216
[expectation fulfill ];
180
217
}
181
- }) ;
218
+ }] ;
182
219
[self waitForExpectationsWithTimeout: 1 handler: nil ];
183
220
}
184
221
185
222
- (void )testRequestAudioPermission_completeWithoutErrorIfUserGrantAccess {
186
223
XCTestExpectation *grantedExpectation = [self
187
224
expectationWithDescription: @" Must complete without error if user choose to grant access" ];
188
225
189
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
190
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeAudio])
191
- .andReturn (AVAuthorizationStatusNotDetermined);
226
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
227
+ XCTAssertEqualObjects (mediaType, AVMediaTypeAudio);
228
+ return AVAuthorizationStatusNotDetermined;
229
+ };
230
+
192
231
// Mimic user choosing "allow" in permission dialog.
193
- OCMStub ([mockDevice requestAccessForMediaType: AVMediaTypeAudio
194
- completionHandler: [OCMArg checkWithBlock: ^BOOL (void (^block)(BOOL )) {
195
- block (YES );
196
- return YES ;
197
- }]]);
232
+ self.mockService .requestAccessStub = ^(AVMediaType mediaType, void (^handler)(BOOL )) {
233
+ XCTAssertEqualObjects (mediaType, AVMediaTypeAudio);
234
+ handler (YES );
235
+ };
198
236
199
- FLTRequestAudioPermissionWithCompletionHandler ( ^(FlutterError *error) {
237
+ [ self .permissionManager requestAudioPermissionWithCompletionHandler: ^(FlutterError *error) {
200
238
if (error == nil ) {
201
239
[grantedExpectation fulfill ];
202
240
}
203
- }) ;
241
+ }] ;
204
242
[self waitForExpectationsWithTimeout: 1 handler: nil ];
205
243
}
206
244
@@ -211,22 +249,22 @@ - (void)testRequestAudioPermission_completeWithErrorIfUserDenyAccess {
211
249
message: @" User denied the audio access request."
212
250
details: nil ];
213
251
214
- id mockDevice = OCMClassMock ([AVCaptureDevice class ]);
215
- OCMStub ([mockDevice authorizationStatusForMediaType: AVMediaTypeAudio])
216
- .andReturn (AVAuthorizationStatusNotDetermined);
252
+ self.mockService .authorizationStatusStub = ^AVAuthorizationStatus (AVMediaType mediaType) {
253
+ XCTAssertEqualObjects (mediaType, AVMediaTypeAudio);
254
+ return AVAuthorizationStatusNotDetermined;
255
+ };
217
256
218
257
// Mimic user choosing "deny" in permission dialog.
219
- OCMStub ([mockDevice requestAccessForMediaType: AVMediaTypeAudio
220
- completionHandler: [OCMArg checkWithBlock: ^ BOOL ( void (^block)( BOOL )) {
221
- block (NO );
222
- return YES ;
223
- }]]);
224
- FLTRequestAudioPermissionWithCompletionHandler ( ^(FlutterError *error) {
258
+ self. mockService . requestAccessStub = ^(AVMediaType mediaType, void (^handler)( BOOL )) {
259
+ XCTAssertEqualObjects (mediaType, AVMediaTypeAudio);
260
+ handler (NO );
261
+ } ;
262
+
263
+ [ self .permissionManager requestAudioPermissionWithCompletionHandler: ^(FlutterError *error) {
225
264
if ([error isEqual: expectedError]) {
226
265
[expectation fulfill ];
227
266
}
228
- });
229
-
267
+ }];
230
268
[self waitForExpectationsWithTimeout: 1 handler: nil ];
231
269
}
232
270
0 commit comments