Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
squash! unit tests: SPiDTokenStorageTests, SPiDTokenStorageUserDefaul…
Browse files Browse the repository at this point in the history
…tsBackendTests
  • Loading branch information
danielschibsted committed Mar 9, 2017
1 parent fcff1a6 commit 76d9b39
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 5 deletions.
18 changes: 18 additions & 0 deletions SPiDSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
0893185B1E6EFD52002CD789 /* SPiDTokenStorageUserDefaultsBackend.m in Sources */ = {isa = PBXBuildFile; fileRef = 089318591E6EFD52002CD789 /* SPiDTokenStorageUserDefaultsBackend.m */; };
0893185E1E6EFEA9002CD789 /* SPiDTokenStorageKeychainBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 0893185C1E6EFEA9002CD789 /* SPiDTokenStorageKeychainBackend.h */; };
0893185F1E6EFEA9002CD789 /* SPiDTokenStorageKeychainBackend.m in Sources */ = {isa = PBXBuildFile; fileRef = 0893185D1E6EFEA9002CD789 /* SPiDTokenStorageKeychainBackend.m */; };
089318611E716AE6002CD789 /* SPiDTokenStorageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 089318601E716AE6002CD789 /* SPiDTokenStorageTests.m */; };
089318621E717174002CD789 /* SPiDTokenStorageUserDefaultsBackend.m in Sources */ = {isa = PBXBuildFile; fileRef = 089318591E6EFD52002CD789 /* SPiDTokenStorageUserDefaultsBackend.m */; };
089318641E7176DD002CD789 /* SPiDTokenStorageUserDefaultsBackendTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 089318631E7176DD002CD789 /* SPiDTokenStorageUserDefaultsBackendTests.m */; };
089318651E717AB9002CD789 /* SPiDTokenStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 089318551E6EFAD6002CD789 /* SPiDTokenStorage.m */; };
089318661E717AE6002CD789 /* SPiDTokenStorageKeychainBackend.m in Sources */ = {isa = PBXBuildFile; fileRef = 0893185D1E6EFEA9002CD789 /* SPiDTokenStorageKeychainBackend.m */; };
089318671E717AF4002CD789 /* SPiDKeychainWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = E304E86B163571BA2FDCE5BD /* SPiDKeychainWrapper.m */; };
089318681E717B44002CD789 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E304ECEC953C2E9C143FD9E2 /* Security.framework */; };
5306208B16C12440001B2A08 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E304ECEC953C2E9C143FD9E2 /* Security.framework */; };
5306209716C1375D001B2A08 /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5306209616C1375D001B2A08 /* Social.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
5306209B16C1376F001B2A08 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5306209A16C1376F001B2A08 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
Expand Down Expand Up @@ -165,6 +172,8 @@
089318591E6EFD52002CD789 /* SPiDTokenStorageUserDefaultsBackend.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPiDTokenStorageUserDefaultsBackend.m; sourceTree = "<group>"; };
0893185C1E6EFEA9002CD789 /* SPiDTokenStorageKeychainBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPiDTokenStorageKeychainBackend.h; sourceTree = "<group>"; };
0893185D1E6EFEA9002CD789 /* SPiDTokenStorageKeychainBackend.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPiDTokenStorageKeychainBackend.m; sourceTree = "<group>"; };
089318601E716AE6002CD789 /* SPiDTokenStorageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPiDTokenStorageTests.m; sourceTree = "<group>"; };
089318631E7176DD002CD789 /* SPiDTokenStorageUserDefaultsBackendTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPiDTokenStorageUserDefaultsBackendTests.m; sourceTree = "<group>"; };
5306208716C082B8001B2A08 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = "<group>"; };
5306209616C1375D001B2A08 /* Social.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Social.framework; path = System/Library/Frameworks/Social.framework; sourceTree = SDKROOT; };
5306209816C13764001B2A08 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -354,6 +363,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
089318681E717B44002CD789 /* Security.framework in Frameworks */,
537D220515FF224C000ABCA6 /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -546,6 +556,8 @@
9698149C1E54942600439631 /* SPiDAccessTokenTests.m */,
969814A11E54972700439631 /* NSDictionary+Test.h */,
969814A21E54972700439631 /* NSDictionary+Test.m */,
089318601E716AE6002CD789 /* SPiDTokenStorageTests.m */,
089318631E7176DD002CD789 /* SPiDTokenStorageUserDefaultsBackendTests.m */,
);
path = SPiDSDKTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -973,13 +985,19 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
089318661E717AE6002CD789 /* SPiDTokenStorageKeychainBackend.m in Sources */,
DAF1DE3D1CDC706D007B15B3 /* NSCharacterSet+SPiD.m in Sources */,
537D221115FF224C000ABCA6 /* SPiDSDKTests.m in Sources */,
9665D1F91E092DCE00759F60 /* SPiDAgreements.m in Sources */,
089318651E717AB9002CD789 /* SPiDTokenStorage.m in Sources */,
089318671E717AF4002CD789 /* SPiDKeychainWrapper.m in Sources */,
969814A31E54972700439631 /* NSDictionary+Test.m in Sources */,
9665D1F81E092C0000759F60 /* SPiDAgreementsTests.m in Sources */,
089318621E717174002CD789 /* SPiDTokenStorageUserDefaultsBackend.m in Sources */,
089318641E7176DD002CD789 /* SPiDTokenStorageUserDefaultsBackendTests.m in Sources */,
DAF1DE3C1CDC6F35007B15B3 /* SPiDUtils.m in Sources */,
9698149D1E54942600439631 /* SPiDAccessTokenTests.m in Sources */,
089318611E716AE6002CD789 /* SPiDTokenStorageTests.m in Sources */,
969814A41E549AEE00439631 /* SPiDAccessToken.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
4 changes: 4 additions & 0 deletions SPiDSDK/SPiDTokenStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ typedef NS_ENUM(NSUInteger, SPiDTokenStorageBackendType) {
- (instancetype)initWithReadBackendTypes:(NSArray<NSNumber *> *)readBackendTypes
writeBackendTypes:(NSArray<NSNumber *> *)writeBackendTypes;

- (instancetype)initWithReadBackendTypes:(NSArray<NSNumber *> *)readBackendTypes
writeBackendTypes:(NSArray<NSNumber *> *)writeBackendTypes
backends:(NSDictionary<NSNumber *, id<SPiDTokenStorageBackend>> *)backends;

- (SPiDAccessToken *)loadAccessTokenAndReplicate;
- (BOOL)storeAccessTokenWithValue:(SPiDAccessToken *)accessToken;
- (BOOL)updateAccessTokenWithValue:(SPiDAccessToken *)accessToken;
Expand Down
12 changes: 9 additions & 3 deletions SPiDSDK/SPiDTokenStorage.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ @implementation SPiDTokenStorage
case SPiDTokenStorageBackendTypeKeychain:
return [SPiDTokenStorageKeychainBackend new];
case SPiDTokenStorageBackendTypeUserDefaults:
return [SPiDTokenStorageUserDefaultsBackend new];
return [[SPiDTokenStorageUserDefaultsBackend alloc] initWithUserDefaults:[NSUserDefaults standardUserDefaults]];
default:
NSAssert(NO, @"Unknown SPiDTokenStorageBackendType %d", type);
}
Expand All @@ -47,6 +47,7 @@ static BOOL haveCommonElementsInArrays(NSArray *array1, NSArray *array2)

- (instancetype)initWithReadBackendTypes:(NSArray<NSNumber *> *)readBackendTypes
writeBackendTypes:(NSArray<NSNumber *> *)writeBackendTypes
backends:(NSDictionary<NSNumber *, id<SPiDTokenStorageBackend>> *)backends
{
__unused BOOL haveCommonReadAndWriteBackends = haveCommonElementsInArrays(readBackendTypes, writeBackendTypes);
NSAssert(haveCommonReadAndWriteBackends, @"At least one backend should be used for both reading and writing.");
Expand All @@ -55,15 +56,20 @@ - (instancetype)initWithReadBackendTypes:(NSArray<NSNumber *> *)readBackendTypes
if (self == nil) return nil;
_readBackendTypes = readBackendTypes;
_writeBackendTypes = writeBackendTypes;
_backends = backends;
return self;
}

- (instancetype)initWithReadBackendTypes:(NSArray<NSNumber *> *)readBackendTypes
writeBackendTypes:(NSArray<NSNumber *> *)writeBackendTypes
{
NSSet<NSNumber *> *allBackendTypes = [[NSSet setWithArray:readBackendTypes] setByAddingObjectsFromArray:writeBackendTypes];
NSMutableDictionary<NSNumber *, id<SPiDTokenStorageBackend>> *backends = [NSMutableDictionary new];
for (NSNumber *type in allBackendTypes) {
backends[type] = [SPiDTokenStorage createBackendOfType:[type unsignedIntegerValue]];
}
_backends = backends;

return self;
return [self initWithReadBackendTypes:readBackendTypes writeBackendTypes:writeBackendTypes backends:backends];
}

- (NSString *)identifier
Expand Down
2 changes: 2 additions & 0 deletions SPiDSDK/SPiDTokenStorageUserDefaultsBackend.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@

@interface SPiDTokenStorageUserDefaultsBackend : NSObject <SPiDTokenStorageBackend>

- (instancetype)initWithUserDefaults:(NSUserDefaults *)defaults;

@end
4 changes: 2 additions & 2 deletions SPiDSDK/SPiDTokenStorageUserDefaultsBackend.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ @implementation SPiDTokenStorageUserDefaultsBackend
NSUserDefaults *_defaults;
}

- (instancetype)init
- (instancetype)initWithUserDefaults:(NSUserDefaults *)defaults
{
self = [super init];
if (self == nil) return nil;
_defaults = [NSUserDefaults standardUserDefaults];
_defaults = defaults;
return self;
}

Expand Down
171 changes: 171 additions & 0 deletions SPiDSDKTests/SPiDTokenStorageTests.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
//
// SPiDTokenStorageTests.m
// SPiDSDK
//
// Created by Daniel Lazarenko on 09/03/2017.
//

#import <XCTest/XCTest.h>
#import "SPiDTokenStorageUserDefaultsBackend.h"
#import "SPiDAccessToken.h"
#import "SPiDTokenStorage.h"

@interface SPiDTokenStorageTests : XCTestCase
{
NSUserDefaults *_defaults1;
id<SPiDTokenStorageBackend> _backend1;
NSUserDefaults *_defaults2;
id<SPiDTokenStorageBackend> _backend2;
NSDictionary<NSNumber *, id<SPiDTokenStorageBackend>> *_backends;
}

@property (readonly) NSDate *expectedExpiresAt;
@property (readonly) NSString *tokenIdentifier;

@end

@implementation SPiDTokenStorageTests

NSUserDefaults *SPiDSDKTestsCreateFreshUserDefaults();

- (void)setUp
{
[super setUp];
_defaults1 = SPiDSDKTestsCreateFreshUserDefaults(@"xctest1");
_backend1 = [[SPiDTokenStorageUserDefaultsBackend alloc] initWithUserDefaults:_defaults1];
_defaults2 = SPiDSDKTestsCreateFreshUserDefaults(@"xctest2");
_backend2 = [[SPiDTokenStorageUserDefaultsBackend alloc] initWithUserDefaults:_defaults2];
_backends = @{
@(SPiDTokenStorageBackendTypeKeychain): _backend1,
@(SPiDTokenStorageBackendTypeUserDefaults): _backend2,
};
}

- (SPiDAccessToken *)createExpectedToken
{
return [[SPiDAccessToken alloc] initWithUserID:@"uid123" accessToken:@"at234"
expiresAt:[NSDate dateWithTimeIntervalSinceReferenceDate:555]
refreshToken:@"rt345"];
}

- (NSString *)tokenIdentifier
{
return @"AccessToken";
}

- (void)testBackendsAreCleanAfterSetUp
{
XCTAssertNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);
}

- (void)testLoadsSomeTokenAfterStoring
{
SPiDTokenStorage *storage = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
backends:_backends];
[storage storeAccessTokenWithValue:[self createExpectedToken]];
SPiDAccessToken *token = [storage loadAccessTokenAndReplicate];
XCTAssertNotNil(token);
}

- (void)testStoreToOnlyOneWriteBackend
{
SPiDTokenStorage *storage = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
backends:_backends];
[storage storeAccessTokenWithValue:[self createExpectedToken]];
XCTAssertNotNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);
}

- (void)testWriteToBothBackends
{
SPiDTokenStorage *storage = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain), @(SPiDTokenStorageBackendTypeUserDefaults) ]
backends:_backends];
[storage storeAccessTokenWithValue:[self createExpectedToken]];
XCTAssertNotNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNotNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);
SPiDAccessToken *token = [storage loadAccessTokenAndReplicate];
XCTAssertNotNil(token);
}

- (void)testReplicateAfterReading
{
SPiDTokenStorage *storageOnly1 = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
backends:_backends];
[storageOnly1 storeAccessTokenWithValue:[self createExpectedToken]];
[storageOnly1 loadAccessTokenAndReplicate];
XCTAssertNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);

SPiDTokenStorage *storageWriteBoth = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain), @(SPiDTokenStorageBackendTypeUserDefaults) ]
backends:_backends];
SPiDAccessToken *token = [storageWriteBoth loadAccessTokenAndReplicate];
XCTAssertNotNil(token);
XCTAssertNotNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNotNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);
}

- (void)testCleanupAfterReadingBackup
{
SPiDTokenStorage *storageOnlyBackup = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeUserDefaults) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeUserDefaults) ]
backends:_backends];
[storageOnlyBackup storeAccessTokenWithValue:[self createExpectedToken]];
XCTAssertNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNotNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);

SPiDTokenStorage *storageReadBackup = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain), @(SPiDTokenStorageBackendTypeUserDefaults) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
backends:_backends];
SPiDAccessToken *token = [storageReadBackup loadAccessTokenAndReplicate];
XCTAssertNotNil(token);
XCTAssertNotNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);
}

- (void)testRemovalFromAllBackends
{
SPiDTokenStorage *storage = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain), @(SPiDTokenStorageBackendTypeUserDefaults) ]
backends:_backends];
[storage storeAccessTokenWithValue:[self createExpectedToken]];
[storage removeAccessToken];
XCTAssertNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);
SPiDAccessToken *token = [storage loadAccessTokenAndReplicate];
XCTAssertNil(token);
}

- (void)testFullMigrationScenario
{
// logged in app state
SPiDTokenStorage *storageOnly1 = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
backends:@{ @(SPiDTokenStorageBackendTypeKeychain): _backend1 }];
[storageOnly1 storeAccessTokenWithValue:[self createExpectedToken]];

// update 1: replicate to backup
SPiDTokenStorage *storageWriteBoth = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain), @(SPiDTokenStorageBackendTypeUserDefaults) ]
backends:_backends];
[storageWriteBoth loadAccessTokenAndReplicate];

// update 2: move to the new account
[storageOnly1 removeAccessToken];
SPiDTokenStorage *storageReadBackup = [[SPiDTokenStorage alloc] initWithReadBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain), @(SPiDTokenStorageBackendTypeUserDefaults) ]
writeBackendTypes:@[ @(SPiDTokenStorageBackendTypeKeychain) ]
backends:_backends];
[storageReadBackup loadAccessTokenAndReplicate];

// update 3: back to keychain only
XCTAssertNotNil([_backend1 accessTokenForIdentifier:self.tokenIdentifier]);
XCTAssertNil([_backend2 accessTokenForIdentifier:self.tokenIdentifier]);
SPiDAccessToken *token = [storageOnly1 loadAccessTokenAndReplicate];
XCTAssertNotNil(token);
}

@end
Loading

0 comments on commit 76d9b39

Please sign in to comment.