Skip to content

Commit

Permalink
Database Interop (#1865)
Browse files Browse the repository at this point in the history
* Register Database with Interop

+ Add AuthInterop dependency
+ Have Database register with Interop component container
+ Add weak dependency on Auth
~ Cleaned up imports

* Use Interop for Auth token fetching

+ Use macro to get auth component
~ Change `getTokenForcingRefresh:withCallback:` call to use Interop component version of Auth
~ Clean up imports

* Implement necessary protocols

+ Added FIRComponentRegistrant and FIRDatabaseNilProtocol to FIRDatabase

* Squash of my previous local commits for Database Interop

Register Database with Interop:

  + Add AuthInterop dependency
  + Have Database register with Interop component container
  + Add weak dependency on Auth
  ~ Cleaned up imports

Use Interop for Auth token fetching:

  + Use macro to get auth component
  ~ Change `getTokenForcingRefresh:withCallback:` call to use Interop component version of Auth
  ~ Clean up imports

Implement necessary protocols:

  + Added FIRComponentRegistrant and FIRDatabaseNilProtocol to FIRDatabase

Clean up Database tests:

  - Removed all unnecessary header files
  ~ Ran style.sh across all the tests

Cleaned Up project file:

  Some header removals were missed in the last commit.

Sorted some test files

Fix Database Fake App Tests:

  + Added container property
  + Added an Auth fake in the container
  + Added the Shared utils files to the necessary targets
  + Added a missing XCTest reference in a test that didn't compile for me

* Revert "Squash of my previous local commits for Database Interop"

This reverts commit c0d0421.

* Cleaned Up project file

Some header removals were missed in the last commit.

* Sorted some test files

* Fix Database Fake App Tests

+ Added container property
+ Added an Auth fake in the container
+ Added the Shared utils files to the necessary targets
+ Added a missing XCTest reference in a test that didn't compile for me

* PR Feedback Changes

+ Created new FIRDatabaseComponent class to encapsulate instance creation
+ Updated FAuthTokenProvider to only use an auth instance rather than an app.

* PR Feedback Follow-Up

- Removed FIRDatabase registration code

* pod deintegrate

* Move instance management

Somes tests may still be out of date.

* Fix Auth integration test

* pod deintegrate -- again

* PR Feedback

* PR Feedback

Added the FIRComponentLifecycleMaintainer protocol to FIRDatabaseComponent

* Update Firebase/Database/Api/FIRDatabaseComponent.m

Missed some small changes

* Get integration tests compiling

* Fix some tests

* Fixed more tests

Component needs to be cacheable in order to get the appWIllBeDeleted callback.

* Update target memberships

* Revert project file changes

* Add FIRAuthInteropFake for broken targets

* PR feedback

* Spacing and Style

* Moved `instances` to ivar

* Simplify FIRDatabaseDictionary

It's now keyed on the URL with the app being implied since each app will get its own `FIRDatabaseComponent`
  • Loading branch information
bstpierr authored Nov 19, 2018
1 parent e0d7975 commit 4090195
Show file tree
Hide file tree
Showing 26 changed files with 482 additions and 338 deletions.
1 change: 1 addition & 0 deletions Example/Database/Tests/Helpers/FDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

@class FIRDatabaseReference;
@class SenTest;
@class XCTest;

@interface FDevice : NSObject
- (id)initOnline;
Expand Down
2 changes: 1 addition & 1 deletion Example/Database/Tests/Helpers/FDevice.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ - (id)initOfflineWithUrl:(NSString *)firebaseUrl {
- (id)initWithUrl:(NSString *)firebaseUrl andOnline:(BOOL)online {
self = [super init];
if (self) {
config = [FIRDatabaseConfig configForName:[NSString stringWithFormat:@"device-%lu", deviceId++]];
config = [FTestHelpers configForName:[NSString stringWithFormat:@"device-%lu", deviceId++]];
config.persistenceEnabled = YES;
url = firebaseUrl;
isOnline = online;
Expand Down
2 changes: 2 additions & 0 deletions Example/Database/Tests/Helpers/FIRFakeApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#import <Foundation/Foundation.h>

@class FIRComponentContainer;
@class FIRFakeOptions;

@interface FIRFakeApp : NSObject
Expand All @@ -24,4 +25,5 @@

@property(nonatomic, readonly) FIRFakeOptions *options;
@property(nonatomic, copy, readonly) NSString *name;
@property(nonatomic, readonly) FIRComponentContainer *container;
@end
52 changes: 34 additions & 18 deletions Example/Database/Tests/Helpers/FIRFakeApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,49 @@

#import "FIRFakeApp.h"

#import "FIRAuthInteropFake.h"
#import "FIRComponentTestUtilities.h"
#import "FIRDatabaseComponent.h"

@interface FIRFakeOptions: NSObject
@property(nonatomic, readonly, copy) NSString *databaseURL;
- (instancetype) initWithURL:(NSString *)url;
- (instancetype)initWithURL:(NSString *)url;
@end

@implementation FIRFakeOptions
- (instancetype) initWithURL:(NSString *)url {
self = [super init];
if (self) {
self->_databaseURL = url;
}
return self;
- (instancetype)initWithURL:(NSString *)url {
self = [super init];
if (self) {
_databaseURL = url;
}
return self;
}
@end

@implementation FIRFakeApp
@interface FIRDatabaseComponent (Internal)
- (instancetype)initWithApp:(FIRApp *)app;
@end

- (instancetype) initWithName:(NSString *)name URL:(NSString *)url {
self = [super init];
if (self) {
self->_name = name;
self->_options = [[FIRFakeOptions alloc] initWithURL:url];
}
return self;
}
@implementation FIRFakeApp

- (void)getTokenForcingRefresh:(BOOL)forceRefresh withCallback:(void (^)(NSString *_Nullable token, NSError *_Nullable error))callback {
callback(nil, nil);
- (instancetype)initWithName:(NSString *)name URL:(NSString *)url {
self = [super init];
if (self) {
_name = name;
_options = [[FIRFakeOptions alloc] initWithURL:url];
_Nullable id (^authBlock)(FIRComponentContainer *, BOOL *) =
^(FIRComponentContainer *container, BOOL *isCacheable) {
return [[FIRAuthInteropFake alloc] initWithToken:nil userID:nil error:nil];
};
FIRComponentCreationBlock databaseBlock =
^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
return [[FIRDatabaseComponent alloc] initWithApp:container.app];
};
NSDictionary<NSString *, FIRComponentCreationBlock> *components =
@{NSStringFromProtocol(@protocol(FIRAuthInterop)) : authBlock,
NSStringFromProtocol(@protocol(FIRDatabaseProvider)) : databaseBlock};
_container = [[FIRComponentContainer alloc] initWithApp:(FIRApp *)self components:components];
}
return self;
}
@end
2 changes: 2 additions & 0 deletions Example/Database/Tests/Helpers/FTestHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#define PATH(__path) [FPath pathWithString:(__path)]

@interface FTestHelpers : XCTestCase
+ (FIRDatabaseConfig *) defaultConfig;
+ (FIRDatabaseConfig *) configForName:(NSString *)name;
+ (FIRDatabaseReference *) getRandomNode;
+ (FIRDatabaseReference *) getRandomNodeWithoutPersistence;
+ (FTupleFirebase *) getRandomNodePair;
Expand Down
181 changes: 102 additions & 79 deletions Example/Database/Tests/Helpers/FTestHelpers.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,118 +15,141 @@
*/

#import "FTestHelpers.h"
#import "FConstants.h"
#import <FirebaseCore/FIRApp.h>

#import <FirebaseAuthInterop/FIRAuthInterop.h>
#import <FirebaseCore/FIRAppInternal.h>
#import <FirebaseCore/FIRComponent.h>
#import <FirebaseCore/FIRComponentContainer.h>
#import <FirebaseCore/FIROptions.h>

#import "FConstants.h"
#import "FIRAuthInteropFake.h"
#import "FIRDatabaseConfig_Private.h"
#import "FTestAuthTokenGenerator.h"

@implementation FTestHelpers

+ (NSTimeInterval) waitUntil:(BOOL (^)())predicate timeout:(NSTimeInterval)seconds {
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:seconds];
NSTimeInterval timeoutTime = [timeoutDate timeIntervalSinceReferenceDate];
NSTimeInterval currentTime;
+ (NSTimeInterval)waitUntil:(BOOL (^)())predicate timeout:(NSTimeInterval)seconds {
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:seconds];
NSTimeInterval timeoutTime = [timeoutDate timeIntervalSinceReferenceDate];
NSTimeInterval currentTime;

for (currentTime = [NSDate timeIntervalSinceReferenceDate];
!predicate() && currentTime < timeoutTime;
currentTime = [NSDate timeIntervalSinceReferenceDate]) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}
for (currentTime = [NSDate timeIntervalSinceReferenceDate];
!predicate() && currentTime < timeoutTime;
currentTime = [NSDate timeIntervalSinceReferenceDate]) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}

NSTimeInterval finish = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval finish = [NSDate timeIntervalSinceReferenceDate];

NSAssert(currentTime <= timeoutTime, @"Timed out");
NSAssert(currentTime <= timeoutTime, @"Timed out");

return (finish - start);
return (finish - start);
}

+ (NSArray*) getRandomNodes:(int)num persistence:(BOOL)persistence {
static dispatch_once_t pred = 0;
static NSMutableArray *persistenceRefs = nil;
static NSMutableArray *noPersistenceRefs = nil;
dispatch_once(&pred, ^{
persistenceRefs = [[NSMutableArray alloc] init];
noPersistenceRefs = [[NSMutableArray alloc] init];
// Uncomment the following line to run tests against a background thread
//[Firebase setDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
});

NSMutableArray *refs = (persistence) ? persistenceRefs : noPersistenceRefs;

id<FAuthTokenProvider> authTokenProvider = [FAuthTokenProvider authTokenProviderForApp:[FIRApp defaultApp]];

while (num > refs.count) {
NSString *sessionIdentifier = [NSString stringWithFormat:@"test-config-%@persistence-%lu", (persistence) ? @"" : @"no-", refs.count];
FIRDatabaseConfig *config = [[FIRDatabaseConfig alloc] initWithSessionIdentifier:sessionIdentifier authTokenProvider:authTokenProvider];
config.persistenceEnabled = persistence;
FIRDatabaseReference * ref = [[FIRDatabaseReference alloc] initWithConfig:config];
[refs addObject:ref];
}
+ (FIRDatabaseConfig *)defaultConfig {
return [self configForName:@"default"];
}

NSMutableArray* results = [[NSMutableArray alloc] init];
NSString* name = nil;
for (int i = 0; i < num; ++i) {
FIRDatabaseReference * ref = [refs objectAtIndex:i];
if (!name) {
name = [ref childByAutoId].key;
}
[results addObject:[ref child:name]];
+ (FIRDatabaseConfig *)configForName:(NSString *)name {
id<FIRAuthInterop> auth = [[FIRAuthInteropFake alloc] initWithToken:nil userID:nil error:nil];
id<FAuthTokenProvider> authTokenProvider = [FAuthTokenProvider authTokenProviderWithAuth:auth];
return [[FIRDatabaseConfig alloc] initWithSessionIdentifier:name
authTokenProvider:authTokenProvider];
}

+ (NSArray *)getRandomNodes:(int)num persistence:(BOOL)persistence {
static dispatch_once_t pred = 0;
static NSMutableArray *persistenceRefs = nil;
static NSMutableArray *noPersistenceRefs = nil;
dispatch_once(&pred, ^{
persistenceRefs = [[NSMutableArray alloc] init];
noPersistenceRefs = [[NSMutableArray alloc] init];
// Uncomment the following line to run tests against a background thread
//[Firebase setDispatchQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
});

NSMutableArray *refs = (persistence) ? persistenceRefs : noPersistenceRefs;

id<FIRAuthInterop> auth = [[FIRAuthInteropFake alloc] initWithToken:nil userID:nil error:nil];
id<FAuthTokenProvider> authTokenProvider = [FAuthTokenProvider authTokenProviderWithAuth:auth];

while (num > refs.count) {
NSString *sessionIdentifier =
[NSString stringWithFormat:@"test-config-%@persistence-%lu", (persistence) ? @"" : @"no-",
refs.count];
FIRDatabaseConfig *config =
[[FIRDatabaseConfig alloc] initWithSessionIdentifier:sessionIdentifier
authTokenProvider:authTokenProvider];
config.persistenceEnabled = persistence;
FIRDatabaseReference *ref = [[FIRDatabaseReference alloc] initWithConfig:config];
[refs addObject:ref];
}

NSMutableArray *results = [[NSMutableArray alloc] init];
NSString *name = nil;
for (int i = 0; i < num; ++i) {
FIRDatabaseReference *ref = [refs objectAtIndex:i];
if (!name) {
name = [ref childByAutoId].key;
}
return results;
[results addObject:[ref child:name]];
}
return results;
}

// Helpers
+ (FIRDatabaseReference *) getRandomNode {
NSArray* refs = [self getRandomNodes:1 persistence:YES];
return [refs objectAtIndex:0];
+ (FIRDatabaseReference *)getRandomNode {
NSArray *refs = [self getRandomNodes:1 persistence:YES];
return [refs objectAtIndex:0];
}

+ (FIRDatabaseReference *) getRandomNodeWithoutPersistence {
NSArray* refs = [self getRandomNodes:1 persistence:NO];
return refs[0];
+ (FIRDatabaseReference *)getRandomNodeWithoutPersistence {
NSArray *refs = [self getRandomNodes:1 persistence:NO];
return refs[0];
}

+ (FTupleFirebase *) getRandomNodePair {
NSArray* refs = [self getRandomNodes:2 persistence:YES];
+ (FTupleFirebase *)getRandomNodePair {
NSArray *refs = [self getRandomNodes:2 persistence:YES];

FTupleFirebase* tuple = [[FTupleFirebase alloc] init];
tuple.one = [refs objectAtIndex:0];
tuple.two = [refs objectAtIndex:1];
FTupleFirebase *tuple = [[FTupleFirebase alloc] init];
tuple.one = [refs objectAtIndex:0];
tuple.two = [refs objectAtIndex:1];

return tuple;
return tuple;
}

+ (FTupleFirebase *) getRandomNodePairWithoutPersistence {
NSArray* refs = [self getRandomNodes:2 persistence:NO];
+ (FTupleFirebase *)getRandomNodePairWithoutPersistence {
NSArray *refs = [self getRandomNodes:2 persistence:NO];

FTupleFirebase* tuple = [[FTupleFirebase alloc] init];
tuple.one = refs[0];
tuple.two = refs[1];
FTupleFirebase *tuple = [[FTupleFirebase alloc] init];
tuple.one = refs[0];
tuple.two = refs[1];

return tuple;
return tuple;
}

+ (FTupleFirebase *) getRandomNodeTriple {
NSArray* refs = [self getRandomNodes:3 persistence:YES];
FTupleFirebase* triple = [[FTupleFirebase alloc] init];
triple.one = [refs objectAtIndex:0];
triple.two = [refs objectAtIndex:1];
triple.three = [refs objectAtIndex:2];
+ (FTupleFirebase *)getRandomNodeTriple {
NSArray *refs = [self getRandomNodes:3 persistence:YES];
FTupleFirebase *triple = [[FTupleFirebase alloc] init];
triple.one = [refs objectAtIndex:0];
triple.two = [refs objectAtIndex:1];
triple.three = [refs objectAtIndex:2];

return triple;
return triple;
}

+ (id<FNode>)leafNodeOfSize:(NSUInteger)size {
NSMutableString *string = [NSMutableString string];
NSString *pattern = @"abdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (NSUInteger i = 0; i < size - pattern.length; i = i + pattern.length) {
[string appendString:pattern];
}
NSUInteger remainingLength = size - string.length;
[string appendString:[pattern substringToIndex:remainingLength]];
return [FSnapshotUtilities nodeFrom:string];
NSMutableString *string = [NSMutableString string];
NSString *pattern = @"abdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (NSUInteger i = 0; i < size - pattern.length; i = i + pattern.length) {
[string appendString:pattern];
}
NSUInteger remainingLength = size - string.length;
[string appendString:[pattern substringToIndex:remainingLength]];
return [FSnapshotUtilities nodeFrom:string];
}

@end
2 changes: 1 addition & 1 deletion Example/Database/Tests/Integration/FData.m
Original file line number Diff line number Diff line change
Expand Up @@ -2529,7 +2529,7 @@ - (void) testUpdateAfterChildSet {

- (void) testDeltaSyncNoDataUpdatesAfterReconnect {
FIRDatabaseReference *ref = [FTestHelpers getRandomNode];
FIRDatabaseConfig *cfg = [FIRDatabaseConfig configForName:@"test-config"];
FIRDatabaseConfig *cfg = [FTestHelpers configForName:@"test-config"];
FIRDatabaseReference * ref2 = [[[FIRDatabaseReference alloc] initWithConfig:cfg] child:ref.key];
__block id data = @{ @"a": @1, @"b": @2, @"c": @{ @".priority": @3, @".value": @3}, @"d": @4 };
[self waitForCompletionOf:ref setValue:data];
Expand Down
8 changes: 4 additions & 4 deletions Example/Database/Tests/Integration/FDotInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ - (void) testCanWatchInfoConnected {
}

- (void) testInfoConnectedGoesToFalseOnDisconnect {
FIRDatabaseConfig *cfg = [FIRDatabaseConfig configForName:@"test-config"];
FIRDatabaseConfig *cfg = [FTestHelpers configForName:@"test-config"];
FIRDatabaseReference * rootRef = [[FIRDatabaseReference alloc] initWithConfig:cfg];
__block BOOL everConnected = NO;
__block NSMutableString *connectedHistory = [[NSMutableString alloc] init];
Expand All @@ -78,7 +78,7 @@ - (void) testInfoConnectedGoesToFalseOnDisconnect {
}

- (void) testInfoServerTimeOffset {
FIRDatabaseConfig *cfg = [FIRDatabaseConfig configForName:@"test-config"];
FIRDatabaseConfig *cfg = [FTestHelpers configForName:@"test-config"];
FIRDatabaseReference * ref = [[FIRDatabaseReference alloc] initWithConfig:cfg];

// make sure childByAutoId works
Expand All @@ -103,8 +103,8 @@ - (void) testInfoServerTimeOffset {
}

- (void) testManualConnectionManagement {
FIRDatabaseConfig *cfg = [FIRDatabaseConfig configForName:@"test-config"];
FIRDatabaseConfig *altCfg = [FIRDatabaseConfig configForName:@"alt-config"];
FIRDatabaseConfig *cfg = [FTestHelpers configForName:@"test-config"];
FIRDatabaseConfig *altCfg = [FTestHelpers configForName:@"alt-config"];

FIRDatabaseReference * ref = [[FIRDatabaseReference alloc] initWithConfig:cfg];
FIRDatabaseReference * refAlt = [[FIRDatabaseReference alloc] initWithConfig:altCfg];
Expand Down
Loading

0 comments on commit 4090195

Please sign in to comment.