Files
firebase-ios-sdk/Example/Auth/Tests/FIRAuthNotificationManagerTests.m
T

288 lines
10 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 <OCMock/OCMock.h>
#import "FIRAuthAppCredential.h"
#import "FIRAuthAppCredentialManager.h"
#import "FIRAuthNotificationManager.h"
NS_ASSUME_NONNULL_BEGIN
/** @var kReceipt
@brief A fake receipt used for testing.
*/
static NSString *const kReceipt = @"FAKE_RECEIPT";
/** @var kSecret
@brief A fake secret used for testing.
*/
static NSString *const kSecret = @"FAKE_SECRET";
/** @class FIRAuthFakeForwardingDelegate
@brief The base class for a fake UIApplicationDelegate that forwards remote notifications.
*/
@interface FIRAuthFakeForwardingDelegate : NSObject <UIApplicationDelegate>
/** @property notificationManager
@brief The notification manager to forward.
*/
@property(nonatomic, strong) FIRAuthNotificationManager *notificationManager;
/** @property forwardsNotification
@brief Whether notifications are being forwarded.
*/
@property(nonatomic, assign) BOOL forwardsNotification;
/** @property notificationReceived
@brief Whether a notification has been received.
*/
@property(nonatomic, assign) BOOL notificationReceived;
/** @property notificationhandled
@brief Whether a notification has been handled.
*/
@property(nonatomic, assign) BOOL notificationhandled;
@end
@implementation FIRAuthFakeForwardingDelegate
@end
/** @class FIRAuthFakeForwardingDelegate
@brief A fake UIApplicationDelegate that implements the modern deegate method to receive
notification.
*/
@interface FIRAuthModernForwardingDelegate : FIRAuthFakeForwardingDelegate
@end
@implementation FIRAuthModernForwardingDelegate
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
self.notificationReceived = YES;
if (self.forwardsNotification) {
self.notificationhandled = [self.notificationManager canHandleNotification:userInfo];
}
}
@end
/** @class FIRAuthLegacyForwardingDelegate
@brief A fake UIApplicationDelegate that implements the legacy deegate method to receive
notification.
*/
@interface FIRAuthLegacyForwardingDelegate : FIRAuthFakeForwardingDelegate
@end
@implementation FIRAuthLegacyForwardingDelegate
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
self.notificationReceived = YES;
if (self.forwardsNotification) {
self.notificationhandled = [self.notificationManager canHandleNotification:userInfo];
}
}
@end
/** @class FIRAuthNotificationManagerTests
@brief Unit tests for @c FIRAuthNotificationManager .
*/
@interface FIRAuthNotificationManagerTests : XCTestCase
@end
@implementation FIRAuthNotificationManagerTests {
/** @var _mockApplication
@brief The mock UIApplication for testing.
*/
id _mockApplication;
/** @var _mockAppCredentialManager
@brief The mock FIRAuthAppCredentialManager for testing.
*/
id _mockAppCredentialManager;
/** @var _notificationManager
@brief The FIRAuthNotificationManager to be tested.
*/
FIRAuthNotificationManager *_notificationManager;
/** @var _modernDelegate
@brief The modern fake UIApplicationDelegate for testing.
*/
FIRAuthModernForwardingDelegate *_modernDelegate;
/** @var _legacyDelegate
@brief The legacy fake UIApplicationDelegate for testing.
*/
FIRAuthLegacyForwardingDelegate *_legacyDelegate;
}
- (void)setUp {
_mockApplication = OCMClassMock([UIApplication class]);
_mockAppCredentialManager = OCMClassMock([FIRAuthAppCredentialManager class]);
_notificationManager =
[[FIRAuthNotificationManager alloc] initWithApplication:_mockApplication
appCredentialManager:_mockAppCredentialManager];
_modernDelegate = [[FIRAuthModernForwardingDelegate alloc] init];
_modernDelegate.notificationManager = _notificationManager;
_legacyDelegate = [[FIRAuthLegacyForwardingDelegate alloc] init];
_legacyDelegate.notificationManager = _notificationManager;
}
/** @fn testForwardingModernDelegate
@brief Tests checking notification forwarding on modern fake delegate.
*/
- (void)testForwardingModernDelegate {
[self verifyForwarding:YES delegate:_modernDelegate];
}
/** @fn testForwardingLegacyDelegate
@brief Tests checking notification forwarding on legacy fake delegate.
*/
- (void)testForwardingLegacyDelegate {
[self verifyForwarding:YES delegate:_legacyDelegate];
}
/** @fn testNotForwardingModernDelegate
@brief Tests checking notification not forwarding on modern fake delegate.
*/
- (void)testNotForwardingModernDelegate {
[self verifyForwarding:NO delegate:_modernDelegate];
}
/** @fn testNotForwardingLegacyDelegate
@brief Tests checking notification not forwarding on legacy fake delegate.
*/
- (void)testNotForwardingLegacyDelegate {
[self verifyForwarding:NO delegate:_legacyDelegate];
}
/** @fn verifyForwarding:delegate:
@brief Tests checking notification forwarding on a particular delegate.
@param forwarding Whether the notification is being forwarded or not.
@param delegate The fake UIApplicationDelegate used for testing.
*/
- (void)verifyForwarding:(BOOL)forwarding delegate:(FIRAuthFakeForwardingDelegate *)delegate {
delegate.forwardsNotification = forwarding;
OCMStub([_mockApplication delegate]).andReturn(delegate);
XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
[_notificationManager
checkNotificationForwardingWithCallback:^(BOOL isNotificationBeingForwarded) {
XCTAssertEqual(isNotificationBeingForwarded, forwarding);
[expectation fulfill];
}];
XCTAssertFalse(delegate.notificationReceived);
NSTimeInterval timeout = _notificationManager.timeout * (1.5 - forwarding);
[self waitForExpectationsWithTimeout:timeout handler:nil];
XCTAssertTrue(delegate.notificationReceived);
XCTAssertEqual(delegate.notificationhandled, forwarding);
}
/** @fn testCachedResult
@brief Test notification forwarding is only checked once.
*/
- (void)testCachedResult {
FIRAuthFakeForwardingDelegate *delegate = _modernDelegate;
[self verifyForwarding:NO delegate:delegate];
delegate.notificationReceived = NO;
__block BOOL calledBack = NO;
[_notificationManager
checkNotificationForwardingWithCallback:^(BOOL isNotificationBeingForwarded) {
XCTAssertFalse(isNotificationBeingForwarded);
calledBack = YES;
}];
XCTAssertTrue(calledBack);
XCTAssertFalse(delegate.notificationReceived);
}
/** @fn testMultipleCallbacks
@brief Test multiple callbacks are handled correctly.
*/
- (void)testMultipleCallbacks {
FIRAuthFakeForwardingDelegate *delegate = _legacyDelegate;
delegate.forwardsNotification = YES;
OCMStub([_mockApplication delegate]).andReturn(delegate);
XCTestExpectation *expectation1 = [self expectationWithDescription:@"callback1"];
[_notificationManager
checkNotificationForwardingWithCallback:^(BOOL isNotificationBeingForwarded) {
XCTAssertTrue(isNotificationBeingForwarded);
[expectation1 fulfill];
}];
XCTestExpectation *expectation2 = [self expectationWithDescription:@"callback2"];
[_notificationManager
checkNotificationForwardingWithCallback:^(BOOL isNotificationBeingForwarded) {
XCTAssertTrue(isNotificationBeingForwarded);
[expectation2 fulfill];
}];
XCTAssertFalse(delegate.notificationReceived);
[self waitForExpectationsWithTimeout:_notificationManager.timeout * .5 handler:nil];
XCTAssertTrue(delegate.notificationReceived);
XCTAssertTrue(delegate.notificationhandled);
}
/** @fn testPassingToCredentialManager
@brief Test notification with the right structure is passed to credential manager.
*/
- (void)testPassingToCredentialManager {
NSDictionary *payload = @{@"receipt" : kReceipt, @"secret" : kSecret};
NSDictionary *notification = @{@"com.google.firebase.auth" : payload};
OCMExpect([_mockAppCredentialManager canFinishVerificationWithReceipt:kReceipt secret:kSecret])
.andReturn(YES);
XCTAssertTrue([_notificationManager canHandleNotification:notification]);
OCMVerifyAll(_mockAppCredentialManager);
// JSON string form
NSData *data = [NSJSONSerialization dataWithJSONObject:payload options:0 error:NULL];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
notification = @{@"com.google.firebase.auth" : string};
OCMExpect([_mockAppCredentialManager canFinishVerificationWithReceipt:kReceipt secret:kSecret])
.andReturn(YES);
XCTAssertTrue([_notificationManager canHandleNotification:notification]);
OCMVerifyAll(_mockAppCredentialManager);
}
/** @fn testNotHandling
@brief Test unrecognized notifications are not handled.
*/
- (void)testNotHandling {
XCTAssertFalse([_notificationManager canHandleNotification:@{@"random" : @"string"}]);
XCTAssertFalse([_notificationManager
canHandleNotification:@{@"com.google.firebase.auth" : @"something wrong"}]);
XCTAssertFalse([_notificationManager canHandleNotification:@{
@"com.google.firebase.auth" : @{
@"receipt" : kReceipt
// missing secret
}
}]);
XCTAssertFalse([_notificationManager canHandleNotification:@{
@"com.google.firebase.auth" : @{
// missing receipt
@"secret" : kSecret
}
}]);
XCTAssertFalse([_notificationManager canHandleNotification:@{
@"com.google.firebase.auth" : @{
// probing notification does not belong to this instance
@"warning" : @"asdf"
}
}]);
}
@end
NS_ASSUME_NONNULL_END