diff options
Diffstat (limited to 'Example')
-rw-r--r-- | Example/Auth/Tests/FIRUserTests.m | 172 | ||||
-rw-r--r-- | Example/Core/Tests/FIRLoggerTest.m | 10 | ||||
-rw-r--r-- | Example/Messaging/Tests/FIRMessagingPubSubTest.m | 9 | ||||
-rw-r--r-- | Example/Messaging/Tests/FIRMessagingServiceTest.m | 180 |
4 files changed, 275 insertions, 96 deletions
diff --git a/Example/Auth/Tests/FIRUserTests.m b/Example/Auth/Tests/FIRUserTests.m index 7a6c165..8bb6786 100644 --- a/Example/Auth/Tests/FIRUserTests.m +++ b/Example/Auth/Tests/FIRUserTests.m @@ -26,9 +26,11 @@ #import "FIRAuthGlobalWorkQueue.h" #import "FIRAuthOperationType.h" #import "FIRAuthTokenResult.h" +#import "FIREmailLinkSignInResponse.m" #import "FIRSecureTokenService.h" #import "FIRSecureTokenRequest.h" #import "FIRSecureTokenResponse.h" +#import "FIRSignUpNewUserResponse.h" #import "FIRGetAccountInfoRequest.h" #import "FIRGetAccountInfoResponse.h" #import "FIRSetAccountInfoRequest.h" @@ -583,6 +585,57 @@ static const NSTimeInterval kExpectationTimeout = 2; OCMVerifyAll(_mockBackend); } +/** @fn testUpdateEmailWithAuthLinkAccountSuccess + @brief Tests a successful @c updateEmail:completion: call updates provider info. + */ +- (void)testUpdateEmailWithAuthLinkAccountSuccess { + id (^mockUserInfoWithDisplayName)(NSString *) = ^(NSString *displayName) { + id mockGetAccountInfoResponseUser = OCMClassMock([FIRGetAccountInfoResponseUser class]); + OCMStub([mockGetAccountInfoResponseUser localID]).andReturn(kLocalID); + OCMStub([mockGetAccountInfoResponseUser email]).andReturn(kEmail); + OCMStub([mockGetAccountInfoResponseUser displayName]).andReturn(displayName); + OCMStub([mockGetAccountInfoResponseUser passwordHash]).andReturn(kPasswordHash); + return mockGetAccountInfoResponseUser; + }; + XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; + id userInfoResponse = mockUserInfoWithDisplayName(kGoogleDisplayName); + [self signInWithEmailLinkWithMockUserInfoResponse:userInfoResponse + completion:^(FIRUser *user) { + // Pretend that the display name on the server has been changed since last request. + [self + expectGetAccountInfoWithMockUserInfoResponse:mockUserInfoWithDisplayName(kNewDisplayName)]; + OCMExpect([_mockBackend setAccountInfo:[OCMArg any] callback:[OCMArg any]]) + .andCallBlock2(^(FIRSetAccountInfoRequest *_Nullable request, + FIRSetAccountInfoResponseCallback callback) { + XCTAssertEqualObjects(request.APIKey, kAPIKey); + XCTAssertEqualObjects(request.accessToken, kAccessToken); + XCTAssertEqualObjects(request.email, kNewEmail); + XCTAssertNil(request.localID); + XCTAssertNil(request.displayName); + XCTAssertNil(request.photoURL); + XCTAssertNil(request.password); + XCTAssertNil(request.providers); + XCTAssertNil(request.deleteAttributes); + XCTAssertNil(request.deleteProviders); + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { + id mockSetAccountInfoResponse = OCMClassMock([FIRSetAccountInfoResponse class]); + OCMStub([mockSetAccountInfoResponse email]).andReturn(kNewEmail); + OCMStub([mockSetAccountInfoResponse displayName]).andReturn(kNewDisplayName); + callback(mockSetAccountInfoResponse, nil); + }); + }); + [user updateEmail:kNewEmail completion:^(NSError *_Nullable error) { + XCTAssertNil(error); + XCTAssertEqualObjects(user.email, kNewEmail); + XCTAssertEqualObjects(user.displayName, kNewDisplayName); + XCTAssertFalse(user.isAnonymous); + [expectation fulfill]; + }]; + }]; + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; + OCMVerifyAll(_mockBackend); +} + /** @fn testUpdateEmailFailure @brief Tests the flow of a failed @c updateEmail:completion: call. */ @@ -1572,6 +1625,64 @@ static const NSTimeInterval kExpectationTimeout = 2; OCMVerifyAll(_mockBackend); } +/** @fn testLinkingAnonymousAccountsUpdatesIsAnonymous + @brief Tests the flow of a successful @c linkAndRetrieveDataWithCredential:completion: + invocation for email credential. + */ +- (void)testLinkingAnonymousAccountsUpdatesIsAnonymous { + FIRAuthCredential *linkEmailCredential = + [FIREmailAuthProvider credentialWithEmail:kEmail + link:@"https://google.com?oobCode=aCode&mode=signIn"]; + + id (^mockUserInfoWithDisplayName)(NSString *, BOOL) = ^(NSString *displayName, + BOOL hasProviders) { + NSArray *providers = hasProviders ? @[ @{ + @"providerId": FIREmailAuthProviderID, + @"email": kEmail + } ] : @[]; + FIRGetAccountInfoResponseUser *responseUser = + [[FIRGetAccountInfoResponseUser alloc] initWithDictionary:@{ + @"providerUserInfo": providers, + @"localId": kLocalID, + @"displayName": displayName, + @"email": kEmail + }]; + return responseUser; + }; + XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; + id userInfoResponse = mockUserInfoWithDisplayName(kGoogleDisplayName, NO); + + [self signInAnonymouslyWithMockGetAccountInfoResponse:userInfoResponse + completion:^(FIRUser *user) { + // Pretend that the display name and providers on the server have been updated. + // Get account info is expected to be invoked twice. + id updatedMockUser = mockUserInfoWithDisplayName(kNewDisplayName, YES); + [self expectGetAccountInfoWithMockUserInfoResponse:updatedMockUser]; + [self expectGetAccountInfoWithMockUserInfoResponse:updatedMockUser]; + OCMExpect([_mockBackend setAccountInfo:[OCMArg any] callback:[OCMArg any]]) + .andCallBlock2(^(FIRSetAccountInfoRequest *_Nullable request, + FIRSetAccountInfoResponseCallback callback) { + id mockSetAccountInfoResponse = OCMClassMock([FIRSetAccountInfoResponse class]); + OCMStub([mockSetAccountInfoResponse email]).andReturn(kNewEmail); + OCMStub([mockSetAccountInfoResponse displayName]).andReturn(kNewDisplayName); + callback(mockSetAccountInfoResponse, nil); + }); + XCTAssertTrue(user.isAnonymous); + + [user linkAndRetrieveDataWithCredential:linkEmailCredential + completion:^(FIRAuthDataResult *_Nullable linkAuthResult, + NSError *_Nullable error) { + XCTAssertTrue([NSThread isMainThread]); + XCTAssertNil(error); + XCTAssertEqualObjects(user.email, kEmail); + XCTAssertFalse(user.isAnonymous); + [expectation fulfill]; + }]; + }]; + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; + OCMVerifyAll(_mockBackend); +} + /** @fn testlinkEmailAndRetrieveDataSuccess @brief Tests the flow of a successful @c linkAndRetrieveDataWithCredential:completion: invocation for email credential. @@ -2222,6 +2333,34 @@ static const NSTimeInterval kExpectationTimeout = 2; OCMVerifyAll(_mockBackend); } +/** @fn signInAnonymouslyWithMockGetAccountInfoResponse:completion: + @brief Signs in with an anonymous account with mocked backend end calls. + @param mockUserInfoResponse A mocked FIRGetAccountInfoResponseUser object. + @param completion The completion block that takes the newly signed-in user as the only + parameter. + */ +- (void)signInAnonymouslyWithMockGetAccountInfoResponse:(id)mockUserInfoResponse + completion:(void (^)(FIRUser *user))completion { + OCMExpect([_mockBackend signUpNewUser:[OCMArg any] callback:[OCMArg any]]) + .andCallBlock2(^(FIRSignUpNewUserRequest *_Nullable request, + FIRSignupNewUserCallback callback) { + id mockSignUpResponse = OCMClassMock([FIRSignUpNewUserResponse class]); + OCMStub([mockSignUpResponse IDToken]).andReturn(kAccessToken); + OCMStub([mockSignUpResponse approximateExpirationDate]) + .andReturn([NSDate dateWithTimeIntervalSinceNow:kAccessTokenTimeToLive]); + OCMStub([mockSignUpResponse refreshToken]).andReturn(kRefreshToken); + callback(mockSignUpResponse, nil); + }); + [self expectGetAccountInfoWithMockUserInfoResponse:mockUserInfoResponse]; + [[FIRAuth auth] signOut:NULL]; + [[FIRAuth auth] signInAnonymouslyWithCompletion:^(FIRAuthDataResult *_Nullable result, + NSError *_Nullable error) { + XCTAssertNotNil(result.user); + XCTAssertNil(error); + completion(result.user); + }]; +} + /** @fn signInWithEmailPasswordWithMockGetAccountInfoResponse:completion: @brief Signs in with an email and password account with mocked backend end calls. @param mockUserInfoResponse A mocked FIRGetAccountInfoResponseUser object. @@ -2229,7 +2368,7 @@ static const NSTimeInterval kExpectationTimeout = 2; parameter. */ - (void)signInWithEmailPasswordWithMockUserInfoResponse:(id)mockUserInfoResponse - completion:(void (^)(FIRUser *user))completion { + completion:(void (^)(FIRUser *user))completion { OCMExpect([_mockBackend verifyPassword:[OCMArg any] callback:[OCMArg any]]) .andCallBlock2(^(FIRVerifyPasswordRequest *_Nullable request, FIRVerifyPasswordResponseCallback callback) { @@ -2239,7 +2378,7 @@ static const NSTimeInterval kExpectationTimeout = 2; OCMStub([mockVeriyPasswordResponse approximateExpirationDate]) .andReturn([NSDate dateWithTimeIntervalSinceNow:kAccessTokenTimeToLive]); OCMStub([mockVeriyPasswordResponse refreshToken]).andReturn(kRefreshToken); - callback(mockVeriyPasswordResponse, nil); + callback(mockVeriyPasswordResponse, nil); }); }); [self expectGetAccountInfoWithMockUserInfoResponse:mockUserInfoResponse]; @@ -2253,6 +2392,35 @@ static const NSTimeInterval kExpectationTimeout = 2; }]; } +/** @fn signInWithEmailLinkWithMockGetAccountInfoResponse:completion: + @brief Signs in with an email link auth account with mocked backend end calls. + @param mockUserInfoResponse A mocked FIRGetAccountInfoResponseUser object. + @param completion The completion block that takes the newly signed-in user as the only + parameter. + */ +- (void)signInWithEmailLinkWithMockUserInfoResponse:(id)mockUserInfoResponse + completion:(void (^)(FIRUser *user))completion { + OCMExpect([_mockBackend emailLinkSignin:[OCMArg any] callback:[OCMArg any]]) + .andCallBlock2(^(FIREmailLinkSignInRequest *_Nullable request, + FIREmailLinkSigninResponseCallback callback) { + id mockVerifyLinkResponse = OCMClassMock([FIREmailLinkSignInResponse class]); + OCMStub([mockVerifyLinkResponse IDToken]).andReturn(kAccessToken); + OCMStub([mockVerifyLinkResponse approximateExpirationDate]) + .andReturn([NSDate dateWithTimeIntervalSinceNow:kAccessTokenTimeToLive]); + OCMStub([mockVerifyLinkResponse refreshToken]).andReturn(kRefreshToken); + callback(mockVerifyLinkResponse, nil); + }); + [self expectGetAccountInfoWithMockUserInfoResponse:mockUserInfoResponse]; + [[FIRAuth auth] signOut:NULL]; + [[FIRAuth auth] signInWithEmail:kEmail + link:@"https://www.google.com?oobCode=aCode&mode=signIn" + completion:^(FIRAuthDataResult *_Nullable result, NSError *_Nullable error) { + XCTAssertNotNil(result.user); + XCTAssertNil(error); + completion(result.user); + }]; +} + /** @fn expectGetAccountInfoWithMockUserInfoResponse: @brief Expects a GetAccountInfo request on the mock backend and calls back with provided fake account data. diff --git a/Example/Core/Tests/FIRLoggerTest.m b/Example/Core/Tests/FIRLoggerTest.m index 0d6d4e2..c1ba37b 100644 --- a/Example/Core/Tests/FIRLoggerTest.m +++ b/Example/Core/Tests/FIRLoggerTest.m @@ -29,8 +29,6 @@ extern NSString *const kFIRPersistedDebugModeKey; extern const char *kFIRLoggerASLClientFacilityName; -extern const char *kFIRLoggerCustomASLMessageFormat; - extern void FIRResetLogger(void); extern aslclient getFIRLoggerClient(void); @@ -39,10 +37,6 @@ extern dispatch_queue_t getFIRClientQueue(void); extern BOOL getFIRLoggerDebugMode(void); -// Define the message format again to make sure the format doesn't accidentally change. -static NSString *const kCorrectASLMessageFormat = - @"$((Time)(J.3)) $(Sender)[$(PID)] <$((Level)(str))> $Message"; - static NSString *const kMessageCode = @"I-COR000001"; @interface FIRLoggerTest : FIRTestCase @@ -71,10 +65,6 @@ static NSString *const kMessageCode = @"I-COR000001"; // Test some stable variables to make sure they weren't accidently changed. - (void)testStableVariables { - // kFIRLoggerCustomASLMessageFormat. - XCTAssertEqualObjects(kCorrectASLMessageFormat, - [NSString stringWithUTF8String:kFIRLoggerCustomASLMessageFormat]); - // Strings of type FIRLoggerServices. XCTAssertEqualObjects(kFIRLoggerABTesting, @"[Firebase/ABTesting]"); XCTAssertEqualObjects(kFIRLoggerAdMob, @"[Firebase/AdMob]"); diff --git a/Example/Messaging/Tests/FIRMessagingPubSubTest.m b/Example/Messaging/Tests/FIRMessagingPubSubTest.m index 3af1402..e1260f5 100644 --- a/Example/Messaging/Tests/FIRMessagingPubSubTest.m +++ b/Example/Messaging/Tests/FIRMessagingPubSubTest.m @@ -78,4 +78,13 @@ static NSString *const kTopicName = @"topic-Name"; XCTAssertTrue([FIRMessagingPubSub isValidTopicWithPrefix:topic]); } +- (void)testRemoveTopicPrefix { + NSString *topic = [NSString stringWithFormat:@"/topics/%@", kTopicName]; + topic = [FIRMessagingPubSub removePrefixFromTopic:topic]; + XCTAssertEqualObjects(topic, kTopicName); + // if the topic doesn't have the prefix, should return topic itself. + topic = [FIRMessagingPubSub removePrefixFromTopic:kTopicName]; + XCTAssertEqualObjects(topic, kTopicName); +} + @end diff --git a/Example/Messaging/Tests/FIRMessagingServiceTest.m b/Example/Messaging/Tests/FIRMessagingServiceTest.m index 073adad..afbae46 100644 --- a/Example/Messaging/Tests/FIRMessagingServiceTest.m +++ b/Example/Messaging/Tests/FIRMessagingServiceTest.m @@ -26,6 +26,11 @@ #import "InternalHeaders/FIRMessagingInternalUtilities.h" #import "NSError+FIRMessaging.h" +static NSString *const kFakeToken = + @"fE1e1PZJFSQ:APA91bFAOjp1ahBWn9rTlbjArwBEm_" + @"yUTTzK6dhIvLqzqqCSabaa4TQVM0pGTmF6r7tmMHPe6VYiGMHuCwJFgj5v97xl78sUNMLwuPPhoci8z_" + @"QGlCrTbxCFGzEUfvA3fGpGgIVQU2W6"; + @interface FIRMessaging () <FIRMessagingClientDelegate> @property(nonatomic, readwrite, strong) FIRMessagingClient *client; @@ -40,22 +45,35 @@ @end - -@interface FIRMessagingServiceTest : XCTestCase +@interface FIRMessagingServiceTest : XCTestCase { + FIRMessaging *_messaging; + id _mockPubSub; +} @end @implementation FIRMessagingServiceTest +- (void)setUp { + _messaging = [FIRMessaging messaging]; + _messaging.defaultFcmToken = kFakeToken; + _mockPubSub = OCMPartialMock(_messaging.pubsub); + [super setUp]; +} + +- (void)tearDown { + [_mockPubSub stopMocking]; + [super tearDown]; +} + - (void)testSubscribe { id mockClient = OCMClassMock([FIRMessagingClient class]); - FIRMessaging *service = [FIRMessaging messaging]; - [service setClient:mockClient]; - [service.pubsub setClient:mockClient]; + [_messaging setClient:mockClient]; + [_mockPubSub setClient:mockClient]; XCTestExpectation *subscribeExpectation = [self expectationWithDescription:@"Should call subscribe on FIRMessagingClient"]; - NSString *token = @"abcdefghijklmn"; + NSString *token = kFakeToken; NSString *topic = @"/topics/some-random-topic"; [[[mockClient stub] @@ -68,12 +86,12 @@ shouldDelete:NO handler:OCMOCK_ANY]; - [service.pubsub subscribeWithToken:token - topic:topic - options:nil - handler:^(NSError *error){ - // not a nil block - }]; + [_mockPubSub subscribeWithToken:token + topic:topic + options:nil + handler:^(NSError *error){ + // not a nil block + }]; // should call updateSubscription [self waitForExpectationsWithTimeout:0.1 @@ -85,14 +103,13 @@ - (void)testUnsubscribe { id mockClient = OCMClassMock([FIRMessagingClient class]); - FIRMessaging *messaging = [FIRMessaging messaging]; - [messaging setClient:mockClient]; - [messaging.pubsub setClient:mockClient]; + [_messaging setClient:mockClient]; + [_mockPubSub setClient:mockClient]; XCTestExpectation *subscribeExpectation = [self expectationWithDescription:@"Should call unsubscribe on FIRMessagingClient"]; - NSString *token = @"abcdefghijklmn"; + NSString *token = kFakeToken; NSString *topic = @"/topics/some-random-topic"; [[[mockClient stub] andDo:^(NSInvocation *invocation) { @@ -109,12 +126,12 @@ shouldDelete:YES handler:OCMOCK_ANY]; - [messaging.pubsub unsubscribeWithToken:token - topic:topic - options:nil - handler:^(NSError *error){ + [_mockPubSub unsubscribeWithToken:token + topic:topic + options:nil + handler:^(NSError *error){ - }]; + }]; // should call updateSubscription [self waitForExpectationsWithTimeout:0.1 @@ -128,8 +145,8 @@ * Test using PubSub without explicitly starting FIRMessagingService. */ - (void)testSubscribeWithoutStart { - [[[FIRMessaging messaging] pubsub] - subscribeWithToken:@"abcdef1234" + [_mockPubSub + subscribeWithToken:kFakeToken topic:@"/topics/hello-world" options:nil handler:^(NSError *error) { @@ -141,19 +158,18 @@ // TODO(chliangGoogle) Investigate why invalid token can't throw assertion but the rest can under // release build. - (void)testSubscribeWithInvalidTopic { - FIRMessaging *messaging = [FIRMessaging messaging]; XCTestExpectation *exceptionExpectation = [self expectationWithDescription:@"Should throw exception for invalid token"]; @try { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" - [messaging.pubsub subscribeWithToken:@"abcdef1234" - topic:nil - options:nil - handler:^(NSError *error) { - XCTFail(@"Should not invoke the handler"); - }]; + [_mockPubSub subscribeWithToken:kFakeToken + topic:nil + options:nil + handler:^(NSError *error) { + XCTFail(@"Should not invoke the handler"); + }]; #pragma clang diagnostic pop } @catch (NSException *exception) { @@ -167,19 +183,17 @@ } - (void)testUnsubscribeWithInvalidTopic { - FIRMessaging *messaging = [FIRMessaging messaging]; - XCTestExpectation *exceptionExpectation = [self expectationWithDescription:@"Should throw exception for invalid token"]; @try { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wnonnull" - [messaging.pubsub unsubscribeWithToken:@"abcdef1234" - topic:nil - options:nil - handler:^(NSError *error) { - XCTFail(@"Should not invoke the handler"); - }]; + [_mockPubSub unsubscribeWithToken:kFakeToken + topic:nil + options:nil + handler:^(NSError *error) { + XCTFail(@"Should not invoke the handler"); + }]; #pragma clang diagnostic pop } @catch (NSException *exception) { @@ -193,68 +207,66 @@ } - (void)testSubscribeWithNoTopicPrefix { - FIRMessaging *messaging = [FIRMessaging messaging]; - FIRMessagingPubSub *pubSub = messaging.pubsub; - id mockPubSub = OCMClassMock([FIRMessagingPubSub class]); NSString *topicName = @"topicWithoutPrefix"; NSString *topicNameWithPrefix = [FIRMessagingPubSub addPrefixToTopic:topicName]; - messaging.pubsub = mockPubSub; - messaging.defaultFcmToken = @"fake-default-token"; - OCMExpect([messaging.pubsub subscribeToTopic:[OCMArg isEqual:topicNameWithPrefix] - handler:[OCMArg any]]); - [messaging subscribeToTopic:topicName]; - OCMVerifyAll(mockPubSub); - // Need to swap back since it's a singleton and hence will live beyond the scope of this test. - messaging.pubsub = pubSub; + OCMExpect( + [_mockPubSub subscribeToTopic:[OCMArg isEqual:topicNameWithPrefix] handler:[OCMArg any]]); + [_messaging subscribeToTopic:topicName]; + OCMVerifyAll(_mockPubSub); } - (void)testSubscribeWithTopicPrefix { - FIRMessaging *messaging = [FIRMessaging messaging]; - FIRMessagingPubSub *pubSub = messaging.pubsub; - id mockPubSub = OCMClassMock([FIRMessagingPubSub class]); - NSString *topicName = @"/topics/topicWithoutPrefix"; - messaging.pubsub = mockPubSub; - messaging.defaultFcmToken = @"fake-default-token"; - OCMExpect([messaging.pubsub subscribeToTopic:[OCMArg isEqual:topicName] handler:[OCMArg any]]); - [messaging subscribeToTopic:topicName]; - OCMVerifyAll(mockPubSub); - // Need to swap back since it's a singleton and hence will live beyond the scope of this test. - messaging.pubsub = pubSub; + OCMExpect([_mockPubSub subscribeToTopic:[OCMArg isEqual:topicName] handler:[OCMArg any]]); + [_messaging subscribeToTopic:topicName]; + OCMVerifyAll(_mockPubSub); } - (void)testUnsubscribeWithNoTopicPrefix { - FIRMessaging *messaging = [FIRMessaging messaging]; - FIRMessagingPubSub *pubSub = messaging.pubsub; - id mockPubSub = OCMClassMock([FIRMessagingPubSub class]); - NSString *topicName = @"topicWithoutPrefix"; NSString *topicNameWithPrefix = [FIRMessagingPubSub addPrefixToTopic:topicName]; - messaging.pubsub = mockPubSub; - messaging.defaultFcmToken = @"fake-default-token"; - OCMExpect([messaging.pubsub unsubscribeFromTopic:[OCMArg isEqual:topicNameWithPrefix] - handler:[OCMArg any]]); - [messaging unsubscribeFromTopic:topicName]; - OCMVerifyAll(mockPubSub); - // Need to swap back since it's a singleton and hence will live beyond the scope of this test. - messaging.pubsub = pubSub; + OCMExpect( + [_mockPubSub unsubscribeFromTopic:[OCMArg isEqual:topicNameWithPrefix] handler:[OCMArg any]]); + [_messaging unsubscribeFromTopic:topicName]; + OCMVerifyAll(_mockPubSub); } - (void)testUnsubscribeWithTopicPrefix { - FIRMessaging *messaging = [FIRMessaging messaging]; - FIRMessagingPubSub *pubSub = messaging.pubsub; - id mockPubSub = OCMClassMock([FIRMessagingPubSub class]); - NSString *topicName = @"/topics/topicWithPrefix"; - messaging.pubsub = mockPubSub; - messaging.defaultFcmToken = @"fake-default-token"; - OCMExpect([messaging.pubsub unsubscribeFromTopic:[OCMArg isEqual:topicName] - handler:[OCMArg any]]); - [messaging unsubscribeFromTopic:topicName]; - OCMVerifyAll(mockPubSub); - // Need to swap back since it's a singleton and hence will live beyond the scope of this test. - messaging.pubsub = pubSub; + OCMExpect([_mockPubSub unsubscribeFromTopic:[OCMArg isEqual:topicName] handler:[OCMArg any]]); + [_messaging unsubscribeFromTopic:topicName]; + OCMVerifyAll(_mockPubSub); +} + +- (void)testSubscriptionCompletionHandlerWithSuccess { + OCMStub([_mockPubSub subscribeToTopic:[OCMArg any] + handler:([OCMArg invokeBlockWithArgs:[NSNull null], nil])]); + XCTestExpectation *subscriptionCompletionExpectation = + [self expectationWithDescription:@"Subscription is complete"]; + [_messaging subscribeToTopic:@"news" + completion:^(NSError *error) { + XCTAssertNil(error); + [subscriptionCompletionExpectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:0.2 + handler:^(NSError *_Nullable error){ + }]; +} + +- (void)testUnsubscribeCompletionHandlerWithSuccess { + OCMStub([_mockPubSub unsubscribeFromTopic:[OCMArg any] + handler:([OCMArg invokeBlockWithArgs:[NSNull null], nil])]); + XCTestExpectation *unsubscriptionCompletionExpectation = + [self expectationWithDescription:@"Unsubscription is complete"]; + [_messaging unsubscribeFromTopic:@"news" + completion:^(NSError *_Nullable error) { + XCTAssertNil(error); + [unsubscriptionCompletionExpectation fulfill]; + }]; + [self waitForExpectationsWithTimeout:0.2 + handler:^(NSError *_Nullable error){ + }]; } - (void)testFIRMessagingSDKVersionInFIRMessagingService { |