diff options
Diffstat (limited to 'Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m')
-rw-r--r-- | Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m b/Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m new file mode 100644 index 0000000..37d95a6 --- /dev/null +++ b/Example/Auth/Tests/FIRAuthAPNSTokenManagerTests.m @@ -0,0 +1,225 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import <XCTest/XCTest.h> + +#import "FIRAuthAPNSToken.h" +#import "FIRAuthAPNSTokenManager.h" +#import <OCMock/OCMock.h> + +NS_ASSUME_NONNULL_BEGIN + +/** @var kRegistrationTimeout + @brief The registration timeout used for testing. + */ +static const NSTimeInterval kRegistrationTimeout = .5; + +/** @var kExpectationTimeout + @brief The test expectation timeout. + @remarks This must be considerably greater than @c kVerificationTimeout . + */ +static const NSTimeInterval kExpectationTimeout = 1; + +/** @class FIRAuthLegacyUIApplication + @brief A fake legacy (< iOS 7) UIApplication class. + @remarks A custom class is needed because `respondsToSelector:` itself cannot be mocked. + */ +@interface FIRAuthLegacyUIApplication : NSObject + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types; +#pragma clang diagnostic pop + +@end +@implementation FIRAuthLegacyUIApplication + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +- (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types { +} +#pragma clang diagnostic pop + +@end + +/** @class FIRAuthAPNSTokenManagerTests + @brief Unit tests for @c FIRAuthAPNSTokenManager . + */ +@interface FIRAuthAPNSTokenManagerTests : XCTestCase +@end +@implementation FIRAuthAPNSTokenManagerTests { + /** @var _mockApplication + @brief The mock application for testing. + */ + id _mockApplication; + + /** @var _manager + @brief The @c FIRAuthAPNSTokenManager instance under tests. + */ + FIRAuthAPNSTokenManager *_manager; + + /** @var _data + @brief One piece of data used for testing. + */ + NSData *_data; + + /** @var _otherData + @brief Another piece of data used for testing. + */ + NSData *_otherData; +} + +- (void)setUp { + _mockApplication = OCMClassMock([UIApplication class]); + _manager = [[FIRAuthAPNSTokenManager alloc] initWithApplication:_mockApplication]; + _data = [@"qwerty" dataUsingEncoding:NSUTF8StringEncoding]; + _otherData = [@"!@#$" dataUsingEncoding:NSUTF8StringEncoding]; +} + +/** @fn testSetToken + @brief Tests setting and getting the `token` property. + */ +- (void)testSetToken { + XCTAssertNil(_manager.token); + _manager.token = [[FIRAuthAPNSToken alloc] initWithData:_data type:FIRAuthAPNSTokenTypeProd]; + XCTAssertEqualObjects(_manager.token.data, _data); + XCTAssertEqual(_manager.token.type, FIRAuthAPNSTokenTypeProd); + _manager.token = nil; + XCTAssertNil(_manager.token); +} + +/** @fn testDetectTokenType + @brief Tests automatic detection of token type. + */ +- (void)testDetectTokenType { + XCTAssertNil(_manager.token); + _manager.token = [[FIRAuthAPNSToken alloc] initWithData:_data type:FIRAuthAPNSTokenTypeUnknown]; + XCTAssertEqualObjects(_manager.token.data, _data); + XCTAssertNotEqual(_manager.token.type, FIRAuthAPNSTokenTypeUnknown); +} + +/** @fn testCallback + @brief Tests callbacks are called. + */ +- (void)testCallback { + // Add first callback, which is yet to be called. + OCMExpect([_mockApplication registerForRemoteNotifications]); + __block BOOL firstCallbackCalled = NO; + [_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token) { + XCTAssertEqualObjects(token.data, _data); + XCTAssertEqual(token.type, FIRAuthAPNSTokenTypeSandbox); + firstCallbackCalled = YES; + }]; + XCTAssertFalse(firstCallbackCalled); + + // Add second callback, which is yet to be called either. + __block BOOL secondCallbackCalled = NO; + [_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token) { + XCTAssertEqualObjects(token.data, _data); + XCTAssertEqual(token.type, FIRAuthAPNSTokenTypeSandbox); + secondCallbackCalled = YES; + }]; + XCTAssertFalse(secondCallbackCalled); + + // Setting nil token shouldn't trigger either callbacks. + _manager.token = nil; + XCTAssertFalse(firstCallbackCalled); + XCTAssertFalse(secondCallbackCalled); + XCTAssertNil(_manager.token); + + // Setting a real token should trigger both callbacks. + _manager.token = [[FIRAuthAPNSToken alloc] initWithData:_data type:FIRAuthAPNSTokenTypeSandbox]; + XCTAssertTrue(firstCallbackCalled); + XCTAssertTrue(secondCallbackCalled); + XCTAssertEqualObjects(_manager.token.data, _data); + XCTAssertEqual(_manager.token.type, FIRAuthAPNSTokenTypeSandbox); + + // Add third callback, which should be called back immediately. + __block BOOL thirdCallbackCalled = NO; + [_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token) { + XCTAssertEqualObjects(token.data, _data); + XCTAssertEqual(token.type, FIRAuthAPNSTokenTypeSandbox); + thirdCallbackCalled = YES; + }]; + XCTAssertTrue(thirdCallbackCalled); + + // Verify the mock in the main thread. + XCTestExpectation *expectation = [self expectationWithDescription:@"verify mock"]; + dispatch_async(dispatch_get_main_queue(), ^{ + OCMVerifyAll(_mockApplication); + [expectation fulfill]; + }); + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; +} + +/** @fn testTimeout + @brief Tests callbacks can be timed out. + */ +- (void)testTimeout { + // Set up timeout. + XCTAssertGreaterThan(_manager.timeout, 0); + _manager.timeout = kRegistrationTimeout; + + // Add callback to time out. + OCMExpect([_mockApplication registerForRemoteNotifications]); + XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; + [_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token) { + XCTAssertNil(token); + [expectation fulfill]; + }]; + + // Time out. + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; + OCMVerifyAll(_mockApplication); +} + +/** @fn testLegacyRegistration + @brief Tests remote notification registration on legacy systems. + */ +- (void)testLegacyRegistration { + // Use a custom class for `respondsToSelector:` to work. + _mockApplication = OCMClassMock([FIRAuthLegacyUIApplication class]); + _manager = [[FIRAuthAPNSTokenManager alloc] initWithApplication:_mockApplication]; + + // Add callback. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [[[_mockApplication expect] ignoringNonObjectArgs] registerForRemoteNotificationTypes:0]; +#pragma clang diagnostic pop + __block BOOL callbackCalled = NO; + [_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token) { + XCTAssertEqualObjects(token.data, _data); + XCTAssertNotEqual(token.type, FIRAuthAPNSTokenTypeUnknown); + callbackCalled = YES; + }]; + XCTAssertFalse(callbackCalled); + + // Set the token. + _manager.token = [[FIRAuthAPNSToken alloc] initWithData:_data type:FIRAuthAPNSTokenTypeUnknown]; + XCTAssertTrue(callbackCalled); + + // Verify the mock in the main thread. + XCTestExpectation *expectation = [self expectationWithDescription:@"verify mock"]; + dispatch_async(dispatch_get_main_queue(), ^{ + OCMVerifyAll(_mockApplication); + [expectation fulfill]; + }); + [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil]; +} + +@end + +NS_ASSUME_NONNULL_END |