mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
275 lines
9.0 KiB
Objective-C
275 lines
9.0 KiB
Objective-C
/*
|
|
* 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 = 2;
|
|
|
|
/** @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;
|
|
|
|
/** @var _error
|
|
@brief The fake error used for testing.
|
|
*/
|
|
NSError *_error;
|
|
}
|
|
|
|
- (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, NSError *_Nullable error) {
|
|
XCTAssertEqualObjects(token.data, self->_data);
|
|
XCTAssertEqual(token.type, FIRAuthAPNSTokenTypeSandbox);
|
|
XCTAssertNil(error);
|
|
firstCallbackCalled = YES;
|
|
}];
|
|
XCTAssertFalse(firstCallbackCalled);
|
|
|
|
// Add second callback, which is yet to be called either.
|
|
__block BOOL secondCallbackCalled = NO;
|
|
[_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token, NSError *_Nullable error) {
|
|
XCTAssertEqualObjects(token.data, self->_data);
|
|
XCTAssertEqual(token.type, FIRAuthAPNSTokenTypeSandbox);
|
|
XCTAssertNil(error);
|
|
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, NSError *_Nullable error) {
|
|
XCTAssertEqualObjects(token.data, self->_data);
|
|
XCTAssertEqual(token.type, FIRAuthAPNSTokenTypeSandbox);
|
|
XCTAssertNil(error);
|
|
thirdCallbackCalled = YES;
|
|
}];
|
|
XCTAssertTrue(thirdCallbackCalled);
|
|
|
|
// Verify the mock in the main thread.
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"verify mock"];
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
OCMVerifyAll(self->_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, NSError *_Nullable error) {
|
|
XCTAssertNil(token);
|
|
XCTAssertNil(error);
|
|
[expectation fulfill];
|
|
}];
|
|
|
|
// Time out.
|
|
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
|
|
OCMVerifyAll(_mockApplication);
|
|
|
|
// Calling cancel afterwards should have no effect.
|
|
[_manager cancelWithError:_error];
|
|
}
|
|
|
|
/** @fn testCancel
|
|
@brief Tests cancelling the pending callbacks.
|
|
*/
|
|
- (void)testCancel {
|
|
// Set up timeout.
|
|
XCTAssertGreaterThan(_manager.timeout, 0);
|
|
_manager.timeout = kRegistrationTimeout;
|
|
|
|
// Add callback to cancel.
|
|
OCMExpect([_mockApplication registerForRemoteNotifications]);
|
|
__block BOOL callbackCalled = NO;
|
|
[_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token, NSError *_Nullable error) {
|
|
XCTAssertNil(token);
|
|
XCTAssertEqualObjects(error, self->_error);
|
|
XCTAssertFalse(callbackCalled); // verify callback is not called twice
|
|
callbackCalled = YES;
|
|
}];
|
|
XCTAssertFalse(callbackCalled);
|
|
|
|
// Call cancel.
|
|
[_manager cancelWithError:_error];
|
|
XCTAssertTrue(callbackCalled);
|
|
|
|
// Add callback to timeout.
|
|
XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
|
|
[_manager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token, NSError *_Nullable error) {
|
|
XCTAssertNil(token);
|
|
XCTAssertNil(error);
|
|
[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, NSError *_Nullable error) {
|
|
XCTAssertEqualObjects(token.data, self->_data);
|
|
XCTAssertNotEqual(token.type, FIRAuthAPNSTokenTypeUnknown);
|
|
XCTAssertNil(error);
|
|
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(self->_mockApplication);
|
|
[expectation fulfill];
|
|
});
|
|
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|