mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-10 22:45:59 +05:45
* FIS - use shared user defaults if `accessGroup` is set. * Use `FIROptions.appGroupID` to set keychain `accessGroup` * ./scripts/style.sh
247 lines
9.1 KiB
Objective-C
247 lines
9.1 KiB
Objective-C
/*
|
|
* Copyright 2019 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 <GoogleUtilities/GULUserDefaults.h>
|
|
#import "FBLPromise+Testing.h"
|
|
#import "FIRInstallationsErrorUtil.h"
|
|
#import "FIRInstallationsItem+Tests.h"
|
|
#import "FIRInstallationsItem.h"
|
|
#import "FIRInstallationsStore.h"
|
|
#import "FIRInstallationsStoredItem.h"
|
|
#import "FIRSecureStorage.h"
|
|
|
|
@interface FIRInstallationsStoreTests : XCTestCase
|
|
@property(nonatomic) NSString *accessGroup;
|
|
@property(nonatomic) FIRInstallationsStore *store;
|
|
@property(nonatomic) id mockSecureStorage;
|
|
@property(nonatomic) GULUserDefaults *userDefaults;
|
|
@end
|
|
|
|
@implementation FIRInstallationsStoreTests
|
|
|
|
- (void)setUp {
|
|
self.accessGroup = @"accessGroup";
|
|
self.mockSecureStorage = OCMClassMock([FIRSecureStorage class]);
|
|
self.store = [[FIRInstallationsStore alloc] initWithSecureStorage:self.mockSecureStorage
|
|
accessGroup:self.accessGroup];
|
|
|
|
// TODO: Replace real user defaults by an injected mock or a test specific user defaults instance
|
|
// with a specific suite name.
|
|
self.userDefaults = [[GULUserDefaults alloc] initWithSuiteName:self.accessGroup];
|
|
}
|
|
|
|
- (void)tearDown {
|
|
self.userDefaults = nil;
|
|
self.store = nil;
|
|
self.mockSecureStorage = nil;
|
|
[self.mockSecureStorage stopMocking];
|
|
}
|
|
|
|
- (void)testInstallationID_WhenNoUserDefaultsItem_ThenNotFound {
|
|
NSString *appID = @"123";
|
|
NSString *appName = @"name";
|
|
NSString *itemID = [self itemIDWithAppID:appID appName:appName];
|
|
|
|
[self.userDefaults removeObjectForKey:itemID];
|
|
|
|
// Check with empty keychain.
|
|
OCMReject([self.mockSecureStorage getObjectForKey:[OCMArg any]
|
|
objectClass:[OCMArg any]
|
|
accessGroup:[OCMArg any]]);
|
|
|
|
[self assertInstallationIDNotFoundForAppID:appID appName:appName];
|
|
OCMVerifyAll(self.mockSecureStorage);
|
|
}
|
|
|
|
- (void)testInstallationID_WhenThereIsUserDefaultsAndKeychain_ThenReturnsItem {
|
|
NSString *appID = @"123";
|
|
NSString *appName = @"name";
|
|
NSString *itemID = [self itemIDWithAppID:appID appName:appName];
|
|
|
|
[self.userDefaults setObject:@(YES) forKey:itemID];
|
|
|
|
FIRInstallationsStoredItem *storedItem = [self createValidStoredItem];
|
|
|
|
OCMExpect([self.mockSecureStorage getObjectForKey:itemID
|
|
objectClass:[FIRInstallationsStoredItem class]
|
|
accessGroup:self.accessGroup])
|
|
.andReturn([FBLPromise resolvedWith:storedItem]);
|
|
|
|
FBLPromise<FIRInstallationsItem *> *itemPromise = [self.store installationForAppID:appID
|
|
appName:appName];
|
|
XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
|
|
|
|
XCTAssertTrue(itemPromise.isFulfilled);
|
|
XCTAssertNil(itemPromise.error);
|
|
XCTAssertNotNil(itemPromise.value);
|
|
|
|
FIRInstallationsItem *item = itemPromise.value;
|
|
XCTAssertEqualObjects(item.appID, appID);
|
|
XCTAssertEqualObjects(item.firebaseAppName, appName);
|
|
[self assertStoredItem:storedItem correspondsToItem:item];
|
|
|
|
OCMVerifyAll(self.mockSecureStorage);
|
|
}
|
|
|
|
- (void)testInstallationID_WhenThereIsUserDefaultsAndNoKeychain_ThenNotFound {
|
|
NSString *appID = @"123";
|
|
NSString *appName = @"name";
|
|
NSString *itemID = [self itemIDWithAppID:appID appName:appName];
|
|
|
|
[self.userDefaults setObject:@(YES) forKey:itemID];
|
|
|
|
OCMExpect([self.mockSecureStorage getObjectForKey:itemID
|
|
objectClass:[FIRInstallationsStoredItem class]
|
|
accessGroup:self.accessGroup])
|
|
.andReturn([FBLPromise resolvedWith:nil]);
|
|
|
|
FBLPromise<FIRInstallationsItem *> *itemPromise = [self.store installationForAppID:appID
|
|
appName:appName];
|
|
XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
|
|
|
|
XCTAssertNotNil(itemPromise.error);
|
|
XCTAssertEqualObjects(itemPromise.error,
|
|
[FIRInstallationsErrorUtil installationItemNotFoundForAppID:appID
|
|
appName:appName]);
|
|
XCTAssertNil(itemPromise.value);
|
|
|
|
OCMVerifyAll(self.mockSecureStorage);
|
|
}
|
|
|
|
- (void)testSaveInstallationWhenKeychainSucceds {
|
|
FIRInstallationsItem *item = [FIRInstallationsItem createUnregisteredInstallationItem];
|
|
NSString *itemID = [item identifier];
|
|
// Reset user defaults key.
|
|
[self.userDefaults removeObjectForKey:itemID];
|
|
|
|
id storedItemArg = [OCMArg checkWithBlock:^BOOL(FIRInstallationsStoredItem *obj) {
|
|
XCTAssertEqualObjects([obj class], [FIRInstallationsStoredItem class]);
|
|
[self assertStoredItem:obj correspondsToItem:item];
|
|
return YES;
|
|
}];
|
|
OCMExpect([self.mockSecureStorage setObject:storedItemArg
|
|
forKey:itemID
|
|
accessGroup:self.accessGroup])
|
|
.andReturn([FBLPromise resolvedWith:[NSNull null]]);
|
|
|
|
FBLPromise<NSNull *> *promise = [self.store saveInstallation:item];
|
|
XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
|
|
|
|
XCTAssertNil(promise.error);
|
|
XCTAssertTrue(promise.isFulfilled);
|
|
|
|
OCMVerifyAll(self.mockSecureStorage);
|
|
|
|
// Check the user defaults key updated.
|
|
XCTAssertNotNil([self.userDefaults objectForKey:itemID]);
|
|
}
|
|
|
|
- (void)testSaveInstallationWhenKeychainFails {
|
|
FIRInstallationsItem *item = [FIRInstallationsItem createUnregisteredInstallationItem];
|
|
NSString *itemID = [item identifier];
|
|
// Reset user defaults key.
|
|
[self.userDefaults removeObjectForKey:itemID];
|
|
|
|
NSError *keychainError = [FIRInstallationsErrorUtil keychainErrorWithFunction:@"Get" status:-1];
|
|
FBLPromise *rejectedPromise = [FBLPromise pendingPromise];
|
|
[rejectedPromise reject:keychainError];
|
|
|
|
id storedItemArg = [OCMArg checkWithBlock:^BOOL(FIRInstallationsStoredItem *obj) {
|
|
XCTAssertEqualObjects([obj class], [FIRInstallationsStoredItem class]);
|
|
[self assertStoredItem:obj correspondsToItem:item];
|
|
return YES;
|
|
}];
|
|
OCMExpect([self.mockSecureStorage setObject:storedItemArg
|
|
forKey:itemID
|
|
accessGroup:self.accessGroup])
|
|
.andReturn(rejectedPromise);
|
|
|
|
FBLPromise<NSNull *> *promise = [self.store saveInstallation:item];
|
|
XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
|
|
|
|
XCTAssertTrue(promise.isRejected);
|
|
XCTAssertEqualObjects(promise.error, keychainError);
|
|
|
|
OCMVerifyAll(self.mockSecureStorage);
|
|
|
|
// Check the user defaults key wasn't updated.
|
|
XCTAssertNil([self.userDefaults objectForKey:itemID]);
|
|
}
|
|
|
|
- (void)testRemoveInstallation {
|
|
NSString *appID = @"123";
|
|
NSString *appName = @"name";
|
|
NSString *itemID = [self itemIDWithAppID:appID appName:appName];
|
|
|
|
[self.userDefaults setObject:@(YES) forKey:itemID];
|
|
|
|
OCMExpect([self.mockSecureStorage removeObjectForKey:itemID accessGroup:self.accessGroup])
|
|
.andReturn([FBLPromise resolvedWith:[NSNull null]]);
|
|
|
|
FBLPromise<NSNull *> *promise = [self.store removeInstallationForAppID:appID appName:appName];
|
|
XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
|
|
|
|
XCTAssertTrue(promise.isFulfilled);
|
|
XCTAssertNil(promise.error);
|
|
|
|
OCMVerifyAll(self.mockSecureStorage);
|
|
|
|
XCTAssertNil([self.userDefaults objectForKey:itemID]);
|
|
}
|
|
|
|
#pragma mark - Common
|
|
|
|
- (void)assertInstallationIDNotFoundForAppID:(NSString *)appID appName:(NSString *)appName {
|
|
FBLPromise<FIRInstallationsItem *> *itemPromise = [self.store installationForAppID:appID
|
|
appName:appName];
|
|
|
|
XCTAssert(FBLWaitForPromisesWithTimeout(0.5));
|
|
|
|
XCTAssertTrue(itemPromise.isRejected, @"%@", self.name);
|
|
XCTAssertEqualObjects(itemPromise.error,
|
|
[FIRInstallationsErrorUtil installationItemNotFoundForAppID:appID
|
|
appName:appName],
|
|
@"%@", self.name);
|
|
}
|
|
|
|
#pragma mark - Helpers
|
|
|
|
- (NSString *)itemIDWithAppID:(NSString *)appID appName:(NSString *)appName {
|
|
return [FIRInstallationsItem identifierWithAppID:appID appName:appName];
|
|
}
|
|
|
|
- (FIRInstallationsStoredItem *)createValidStoredItem {
|
|
FIRInstallationsStoredItem *storedItem = [[FIRInstallationsStoredItem alloc] init];
|
|
|
|
storedItem.firebaseInstallationID = @"firebaseInstallationID";
|
|
storedItem.refreshToken = @"refreshToken";
|
|
|
|
return storedItem;
|
|
}
|
|
|
|
- (void)assertStoredItem:(FIRInstallationsStoredItem *)storedItem
|
|
correspondsToItem:(FIRInstallationsItem *)item {
|
|
XCTAssertEqualObjects(item.refreshToken, storedItem.refreshToken);
|
|
XCTAssertEqualObjects(item.firebaseInstallationID, storedItem.firebaseInstallationID);
|
|
XCTAssertEqual(item.registrationStatus, storedItem.registrationStatus);
|
|
}
|
|
|
|
@end
|