@@ -268,16 +268,16 @@ - (void)testObtainingOAuthProvider {
268268 @brief Tests a successful invocation of @c getCredentialWithUIDelegte:completion:
269269 */
270270- (void )testGetCredentialWithUIDelegateWithClientID {
271- OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
272- _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
273-
274271 id mockBundle = OCMClassMock ([NSBundle class ]);
275272 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
276273 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
277274 @{@" CFBundleURLSchemes" : @[ kFakeReverseClientID ]}
278275 ]);
279276 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
280277
278+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
279+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
280+
281281 OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
282282 .andCallBlock2 (
283283 ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
@@ -371,16 +371,16 @@ - (void)testGetCredentialWithUIDelegateWithClientID {
371371 cancelation.
372372 */
373373- (void )testGetCredentialWithUIDelegateUserCancellationWithClientID {
374- OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
375- _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
376-
377374 id mockBundle = OCMClassMock ([NSBundle class ]);
378375 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
379376 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
380377 @{@" CFBundleURLSchemes" : @[ kFakeReverseClientID ]}
381378 ]);
382379 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
383380
381+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
382+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
383+
384384 OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
385385 .andCallBlock2 (
386386 ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
@@ -471,16 +471,16 @@ - (void)testGetCredentialWithUIDelegateUserCancellationWithClientID {
471471 failed network request within the web context.
472472 */
473473- (void )testGetCredentialWithUIDelegateNetworkRequestFailedWithClientID {
474- OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
475- _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
476-
477474 id mockBundle = OCMClassMock ([NSBundle class ]);
478475 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
479476 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
480477 @{@" CFBundleURLSchemes" : @[ kFakeReverseClientID ]}
481478 ]);
482479 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
483480
481+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
482+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
483+
484484 OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
485485 .andCallBlock2 (
486486 ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
@@ -569,16 +569,16 @@ - (void)testGetCredentialWithUIDelegateNetworkRequestFailedWithClientID {
569569 internal error within the web context.
570570 */
571571- (void )testGetCredentialWithUIDelegateInternalErrorWithClientID {
572- OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
573- _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
574-
575572 id mockBundle = OCMClassMock ([NSBundle class ]);
576573 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
577574 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
578575 @{@" CFBundleURLSchemes" : @[ kFakeReverseClientID ]}
579576 ]);
580577 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
581578
579+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
580+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
581+
582582 OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
583583 .andCallBlock2 (
584584 ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
@@ -668,16 +668,16 @@ - (void)testGetCredentialWithUIDelegateInternalErrorWithClientID {
668668 use of an invalid client ID.
669669 */
670670- (void )testGetCredentialWithUIDelegateInvalidClientID {
671- OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
672- _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
673-
674671 id mockBundle = OCMClassMock ([NSBundle class ]);
675672 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
676673 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
677674 @{@" CFBundleURLSchemes" : @[ kFakeReverseClientID ]}
678675 ]);
679676 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
680677
678+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
679+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
680+
681681 OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
682682 .andCallBlock2 (
683683 ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
@@ -767,16 +767,16 @@ - (void)testGetCredentialWithUIDelegateInvalidClientID {
767767 unknown error.
768768 */
769769- (void )testGetCredentialWithUIDelegateUnknownErrorWithClientID {
770- OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
771- _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
772-
773770 id mockBundle = OCMClassMock ([NSBundle class ]);
774771 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
775772 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
776773 @{@" CFBundleURLSchemes" : @[ kFakeReverseClientID ]}
777774 ]);
778775 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
779776
777+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
778+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
779+
780780 OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
781781 .andCallBlock2 (
782782 ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
@@ -866,15 +866,119 @@ - (void)testGetCredentialWithUIDelegateUnknownErrorWithClientID {
866866 @brief Tests a successful invocation of @c getCredentialWithUIDelegte:completion:
867867 */
868868- (void )testGetCredentialWithUIDelegateWithFirebaseAppID {
869+ id mockBundle = OCMClassMock ([NSBundle class ]);
870+ OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
871+ OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
872+ @{@" CFBundleURLSchemes" : @[ kFakeEncodedFirebaseAppID ]}
873+ ]);
874+ OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
875+
869876 _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
870877
878+ OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
879+ .andCallBlock2 (
880+ ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
881+ XCTAssertNotNil (request);
882+ dispatch_async (FIRAuthGlobalWorkQueue (), ^() {
883+ id mockGetProjectConfigResponse = OCMClassMock ([FIRGetProjectConfigResponse class ]);
884+ OCMStub ([mockGetProjectConfigResponse authorizedDomains ]).andReturn (@[
885+ kFakeAuthorizedDomain
886+ ]);
887+ callback (mockGetProjectConfigResponse, nil );
888+ });
889+ });
890+
891+ id mockUIDelegate = OCMProtocolMock (@protocol (FIRAuthUIDelegate));
892+
893+ // Expect view controller presentation by UIDelegate.
894+ OCMExpect ([_mockURLPresenter presentURL: OCMOCK_ANY
895+ UIDelegate: mockUIDelegate
896+ callbackMatcher: OCMOCK_ANY
897+ completion: OCMOCK_ANY])
898+ .andDo (^(NSInvocation *invocation) {
899+ __unsafe_unretained id unretainedArgument;
900+ // Indices 0 and 1 indicate the hidden arguments self and _cmd.
901+ // `presentURL` is at index 2.
902+ [invocation getArgument: &unretainedArgument atIndex: 2 ];
903+ NSURL *presentURL = unretainedArgument;
904+ XCTAssertEqualObjects (presentURL.scheme , @" https" );
905+ XCTAssertEqualObjects (presentURL.host , kFakeAuthorizedDomain );
906+ XCTAssertEqualObjects (presentURL.path , @" /__/auth/handler" );
907+ NSDictionary *params = [FIRAuthWebUtils dictionaryWithHttpArgumentsString: presentURL.query];
908+ XCTAssertEqualObjects (params[@" ibi" ], kFakeBundleID );
909+ XCTAssertEqualObjects (params[@" appId" ], kFakeFirebaseAppID );
910+ XCTAssertEqualObjects (params[@" apiKey" ], kFakeAPIKey );
911+ XCTAssertEqualObjects (params[@" authType" ], @" signInWithRedirect" );
912+ XCTAssertNotNil (params[@" v" ]);
913+ // `callbackMatcher` is at index 4
914+ [invocation getArgument: &unretainedArgument atIndex: 4 ];
915+ FIRAuthURLCallbackMatcher callbackMatcher = unretainedArgument;
916+ NSMutableString *redirectURL = [NSMutableString
917+ stringWithString: [kFakeEncodedFirebaseAppID
918+ stringByAppendingString: kFakeRedirectURLResponseURL ]];
919+ // Add fake OAuthResponse to callback.
920+ [redirectURL appendString: kFakeOAuthResponseURL ];
921+ // Verify that the URL is rejected by the callback matcher without the event ID.
922+ XCTAssertFalse (callbackMatcher ([NSURL URLWithString: redirectURL]));
923+ [redirectURL appendString: @" %26e ventId%3D " ];
924+ [redirectURL appendString: params[@" eventId" ]];
925+ NSURLComponents *originalComponents = [[NSURLComponents alloc ] initWithString: redirectURL];
926+ // Verify that the URL is accepted by the callback matcher with the matching event ID.
927+ XCTAssertTrue (callbackMatcher ([originalComponents URL ]));
928+ NSURLComponents *components = [originalComponents copy ];
929+ components.query = @" https" ;
930+ XCTAssertFalse (callbackMatcher ([components URL ]));
931+ components = [originalComponents copy ];
932+ components.host = @" badhost" ;
933+ XCTAssertFalse (callbackMatcher ([components URL ]));
934+ components = [originalComponents copy ];
935+ components.path = @" badpath" ;
936+ XCTAssertFalse (callbackMatcher ([components URL ]));
937+ components = [originalComponents copy ];
938+ components.query = @" badquery" ;
939+ XCTAssertFalse (callbackMatcher ([components URL ]));
940+
941+ // `completion` is at index 5
942+ [invocation getArgument: &unretainedArgument atIndex: 5 ];
943+ FIRAuthURLPresentationCompletion completion = unretainedArgument;
944+ dispatch_async (FIRAuthGlobalWorkQueue (), ^() {
945+ completion (originalComponents.URL , nil );
946+ });
947+ });
948+
949+ XCTestExpectation *expectation = [self expectationWithDescription: @" callback" ];
950+ [_provider
951+ getCredentialWithUIDelegate: mockUIDelegate
952+ completion: ^(FIRAuthCredential *_Nullable credential,
953+ NSError *_Nullable error) {
954+ XCTAssertTrue ([NSThread isMainThread ]);
955+ XCTAssertNil (error);
956+ XCTAssertTrue ([credential isKindOfClass: [FIROAuthCredential class ]]);
957+ FIROAuthCredential *OAuthCredential = (FIROAuthCredential *)credential;
958+ XCTAssertEqualObjects (kFakeOAuthResponseURL ,
959+ OAuthCredential.OAuthResponseURLString );
960+ [expectation fulfill ];
961+ }];
962+ [self waitForExpectationsWithTimeout: kExpectationTimeout handler: nil ];
963+ OCMVerifyAll (_mockBackend);
964+ }
965+
966+ /* * @fn testGetCredentialWithUIDelegateWithFirebaseAppIDWhileClientIdPresent
967+ @brief Tests a successful invocation of @c getCredentialWithUIDelegte:completion: when the
968+ client ID is present in the plist file, but the encoded app ID is the registered custom URL
969+ scheme.
970+ */
971+ - (void )testGetCredentialWithUIDelegateWithFirebaseAppIDWhileClientIdPresent {
871972 id mockBundle = OCMClassMock ([NSBundle class ]);
872973 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
873974 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
874975 @{@" CFBundleURLSchemes" : @[ kFakeEncodedFirebaseAppID ]}
875976 ]);
876977 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
877978
979+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
980+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
981+
878982 OCMExpect ([_mockBackend getProjectConfig: [OCMArg any ] callback: [OCMArg any ]])
879983 .andCallBlock2 (
880984 ^(FIRGetProjectConfigRequest *request, FIRGetProjectConfigResponseCallback callback) {
@@ -968,19 +1072,19 @@ - (void)testGetCredentialWithUIDelegateWithFirebaseAppID {
9681072 emulator.
9691073 */
9701074- (void )testGetCredentialWithUIDelegateUseEmulator {
971- OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
972- NSString *emulatorHostAndPort =
973- [NSString stringWithFormat: @" %@ :%@ " , kFakeEmulatorHost , kFakeEmulatorPort ];
974- OCMStub ([_mockRequestConfiguration emulatorHostAndPort ]).andReturn (emulatorHostAndPort);
975- _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
976-
9771075 id mockBundle = OCMClassMock ([NSBundle class ]);
9781076 OCMStub (ClassMethod ([mockBundle mainBundle ])).andReturn (mockBundle);
9791077 OCMStub ([mockBundle objectForInfoDictionaryKey: @" CFBundleURLTypes" ]).andReturn (@[
9801078 @{@" CFBundleURLSchemes" : @[ kFakeReverseClientID ]}
9811079 ]);
9821080 OCMStub ([mockBundle bundleIdentifier ]).andReturn (kFakeBundleID );
9831081
1082+ OCMStub ([_mockOptions clientID ]).andReturn (kFakeClientID );
1083+ NSString *emulatorHostAndPort =
1084+ [NSString stringWithFormat: @" %@ :%@ " , kFakeEmulatorHost , kFakeEmulatorPort ];
1085+ OCMStub ([_mockRequestConfiguration emulatorHostAndPort ]).andReturn (emulatorHostAndPort);
1086+ _provider = [FIROAuthProvider providerWithProviderID: kFakeProviderID auth: _mockAuth];
1087+
9841088 id mockUIDelegate = OCMProtocolMock (@protocol (FIRAuthUIDelegate));
9851089
9861090 // Expect view controller presentation by UIDelegate.
0 commit comments