mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-10 22:45:59 +05:45
543 lines
22 KiB
Objective-C
543 lines
22 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 "FirebaseCore/Extension/FirebaseCoreInternal.h"
|
|
|
|
#import "FirebaseDatabase/Sources/Api/Private/FIRDatabaseReference_Private.h"
|
|
#import "FirebaseDatabase/Sources/FIRDatabaseConfig_Private.h"
|
|
#import "FirebaseDatabase/Sources/Public/FirebaseDatabase/FIRDatabase.h"
|
|
#import "FirebaseDatabase/Sources/Public/FirebaseDatabase/FIRDatabaseReference.h"
|
|
#import "FirebaseDatabase/Tests/Helpers/FIRFakeApp.h"
|
|
#import "FirebaseDatabase/Tests/Helpers/FMockStorageEngine.h"
|
|
#import "FirebaseDatabase/Tests/Helpers/FTestBase.h"
|
|
#import "FirebaseDatabase/Tests/Helpers/FTestHelpers.h"
|
|
|
|
@interface FIRDatabaseTests : FTestBase
|
|
|
|
@end
|
|
|
|
static const NSInteger kFErrorCodeWriteCanceled = 3;
|
|
static NSString *kFirebaseTestAltNamespace = @"https://foobar.firebaseio.com";
|
|
|
|
@implementation FIRDatabaseTests
|
|
|
|
- (void)testFIRDatabaseForNilApp {
|
|
XCTAssertThrowsSpecificNamed([FIRDatabase databaseForApp:(FIRApp *_Nonnull)nil], NSException,
|
|
@"InvalidFIRApp");
|
|
}
|
|
|
|
- (void)testDatabaseForApp {
|
|
FIRDatabase *database = [self databaseForURL:self.databaseURL];
|
|
XCTAssertEqualObjects(self.databaseURL, [database reference].URL);
|
|
}
|
|
|
|
- (void)testDatabaseForAppWithInvalidURLs {
|
|
XCTAssertThrows([self databaseForURL:@"not-a-url"]);
|
|
XCTAssertThrows([self databaseForURL:@"http://x.example.com/paths/are/bad"]);
|
|
}
|
|
|
|
- (void)testDatabaseForAppWithURL {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testDatabaseForAppWithURL"
|
|
URL:kFirebaseTestAltNamespace];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app URL:@"http://foo.bar.com"];
|
|
XCTAssertEqualObjects(@"https://foo.bar.com", [database reference].URL);
|
|
}
|
|
|
|
- (void)testDatabaseForAppWithURLAndPort {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testDatabaseForAppWithURLAndPort"
|
|
URL:kFirebaseTestAltNamespace];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app URL:@"http://foo.bar.com:80"];
|
|
XCTAssertEqualObjects(@"http://foo.bar.com:80", [database reference].URL);
|
|
}
|
|
|
|
- (void)testDatabaseForAppWithHttpsURL {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testDatabaseForAppWithHttpsURL"
|
|
URL:kFirebaseTestAltNamespace];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app URL:@"https://foo.bar.com"];
|
|
XCTAssertEqualObjects(@"https://foo.bar.com", [database reference].URL);
|
|
}
|
|
|
|
- (void)testDatabaseForAppWithProjectId {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testDatabaseForAppWithURL" URL:nil];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app];
|
|
XCTAssertEqualObjects(@"https://fake-project-id-default-rtdb.firebaseio.com",
|
|
[database reference].URL);
|
|
}
|
|
|
|
- (void)testDifferentInstanceForAppWithURL {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testDifferentInstanceForAppWithURL"
|
|
URL:kFirebaseTestAltNamespace];
|
|
FIRDatabase *database1 = [FIRDatabase databaseForApp:app URL:@"https://foo1.bar.com"];
|
|
FIRDatabase *database2 = [FIRDatabase databaseForApp:app URL:@"https://foo1.bar.com/"];
|
|
FIRDatabase *database3 = [FIRDatabase databaseForApp:app URL:@"https://foo2.bar.com"];
|
|
XCTAssertEqual(database1, database2);
|
|
XCTAssertNotEqual(database1, database3);
|
|
}
|
|
|
|
- (void)testDatabaseForAppWithInvalidCustomURLs {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testDatabaseForAppWithInvalidCustomURLs"
|
|
URL:kFirebaseTestAltNamespace];
|
|
XCTAssertThrows([FIRDatabase databaseForApp:app URL:(NSString *_Nonnull)nil]);
|
|
XCTAssertThrows([FIRDatabase databaseForApp:app URL:@"not-a-url"]);
|
|
XCTAssertThrows([FIRDatabase databaseForApp:app URL:@"http://x.fblocal.com:9000/paths/are/bad"]);
|
|
}
|
|
|
|
- (void)testDeleteDatabase {
|
|
// Set up a custom FIRApp with a custom database based on it.
|
|
FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:@"1:123:ios:123abc"
|
|
GCMSenderID:@"gcm_sender_id"];
|
|
options.databaseURL = self.databaseURL;
|
|
NSString *customAppName = @"MyCustomApp";
|
|
[FIRApp configureWithName:customAppName options:options];
|
|
FIRApp *customApp = [FIRApp appNamed:customAppName];
|
|
FIRDatabase *customDatabase = [FIRDatabase databaseForApp:customApp];
|
|
XCTAssertNotNil(customDatabase);
|
|
|
|
// Delete the custom app and wait for it to be done.
|
|
XCTestExpectation *customAppDeletedExpectation =
|
|
[self expectationWithDescription:@"Deleting the custom app should be successful."];
|
|
[customApp deleteApp:^(BOOL success) {
|
|
// The app shouldn't exist anymore, ensure that the databaseForApp throws.
|
|
XCTAssertThrows([FIRDatabase databaseForApp:[FIRApp appNamed:customAppName]]);
|
|
|
|
[customAppDeletedExpectation fulfill];
|
|
}];
|
|
|
|
// Wait for the custom app to be deleted.
|
|
[self waitForExpectations:@[ customAppDeletedExpectation ] timeout:2];
|
|
|
|
// Configure the app again, then grab a reference to the database. Assert it's different.
|
|
[FIRApp configureWithName:customAppName options:options];
|
|
FIRApp *secondCustomApp = [FIRApp appNamed:customAppName];
|
|
FIRDatabase *secondCustomDatabase = [FIRDatabase databaseForApp:secondCustomApp];
|
|
XCTAssertNotNil(secondCustomDatabase);
|
|
XCTAssertNotEqualObjects(customDatabase, secondCustomDatabase);
|
|
}
|
|
|
|
- (void)testReferenceWithPath {
|
|
FIRDatabase *db = [self defaultDatabase];
|
|
NSString *expectedURL = [NSString stringWithFormat:@"%@/foo", self.databaseURL];
|
|
XCTAssertEqualObjects(expectedURL, [db referenceWithPath:@"foo"].URL);
|
|
}
|
|
|
|
- (void)testReferenceFromURLWithEmptyPath {
|
|
FIRDatabaseReference *ref = [[self defaultDatabase] referenceFromURL:self.databaseURL];
|
|
XCTAssertEqualObjects(self.databaseURL, ref.URL);
|
|
}
|
|
|
|
- (void)testReferenceFromURLWithPath {
|
|
NSString *url = [NSString stringWithFormat:@"%@/foo/bar", self.databaseURL];
|
|
FIRDatabaseReference *ref = [[self defaultDatabase] referenceFromURL:url];
|
|
XCTAssertEqualObjects(url, ref.URL);
|
|
}
|
|
|
|
- (void)testReferenceFromURLWithWrongURL {
|
|
NSString *url = [NSString stringWithFormat:@"%@/foo/bar", @"https://foobar.firebaseio.com"];
|
|
XCTAssertThrows([[self defaultDatabase] referenceFromURL:url]);
|
|
}
|
|
|
|
- (void)testReferenceEqualityForFIRDatabase {
|
|
FIRDatabase *db1 = [self databaseForURL:self.databaseURL name:@"db1"];
|
|
FIRDatabase *db2 = [self databaseForURL:self.databaseURL name:@"db2"];
|
|
FIRDatabase *altDb = [self databaseForURL:self.databaseURL name:@"altDb"];
|
|
FIRDatabase *wrongHostDb = [self databaseForURL:@"http://tests.example.com"];
|
|
|
|
FIRDatabaseReference *testRef1 = [db1 reference];
|
|
FIRDatabaseReference *testRef2 = [db1 referenceWithPath:@"foo"];
|
|
FIRDatabaseReference *testRef3 = [altDb reference];
|
|
FIRDatabaseReference *testRef4 = [wrongHostDb reference];
|
|
FIRDatabaseReference *testRef5 = [db2 reference];
|
|
FIRDatabaseReference *testRef6 = [db2 reference];
|
|
|
|
// Referential equality
|
|
XCTAssertTrue(testRef1.database == testRef2.database);
|
|
XCTAssertFalse(testRef1.database == testRef3.database);
|
|
XCTAssertFalse(testRef1.database == testRef4.database);
|
|
XCTAssertFalse(testRef1.database == testRef5.database);
|
|
XCTAssertFalse(testRef1.database == testRef6.database);
|
|
|
|
// references from same FIRDatabase same identical .database references.
|
|
XCTAssertTrue(testRef5.database == testRef6.database);
|
|
|
|
[db1 goOffline];
|
|
[db2 goOffline];
|
|
[altDb goOffline];
|
|
[wrongHostDb goOffline];
|
|
}
|
|
|
|
- (FIRDatabaseReference *)rootRefWithEngine:(id<FStorageEngine>)engine name:(NSString *)name {
|
|
FIRDatabaseConfig *config = [FTestHelpers configForName:name];
|
|
config.persistenceEnabled = YES;
|
|
config.forceStorageEngine = engine;
|
|
return [[FTestHelpers databaseForConfig:config] reference];
|
|
}
|
|
|
|
- (void)testPurgeWritesPurgesAllWrites {
|
|
FMockStorageEngine *engine = [[FMockStorageEngine alloc] init];
|
|
FIRDatabaseReference *ref = [self rootRefWithEngine:engine name:@"purgeWritesPurgesAllWrites"];
|
|
FIRDatabase *database = ref.database;
|
|
|
|
[database goOffline];
|
|
|
|
[[ref childByAutoId] setValue:@"test-value-1"];
|
|
[[ref childByAutoId] setValue:@"test-value-2"];
|
|
[[ref childByAutoId] setValue:@"test-value-3"];
|
|
[[ref childByAutoId] setValue:@"test-value-4"];
|
|
|
|
[self waitForEvents:ref];
|
|
|
|
XCTAssertEqual(engine.userWrites.count, (NSUInteger)4);
|
|
|
|
[database purgeOutstandingWrites];
|
|
[self waitForEvents:ref];
|
|
XCTAssertEqual(engine.userWrites.count, (NSUInteger)0);
|
|
|
|
[database goOnline];
|
|
}
|
|
|
|
- (void)testPurgeWritesAreCanceledInOrder {
|
|
FMockStorageEngine *engine = [[FMockStorageEngine alloc] init];
|
|
FIRDatabaseReference *ref = [self rootRefWithEngine:engine name:@"purgeWritesAndCanceledInOrder"];
|
|
FIRDatabase *database = ref.database;
|
|
|
|
[database goOffline];
|
|
|
|
NSMutableArray *order = [NSMutableArray array];
|
|
|
|
[[ref childByAutoId] setValue:@"test-value-1"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[order addObject:@"1"];
|
|
}];
|
|
[[ref childByAutoId] setValue:@"test-value-2"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[order addObject:@"2"];
|
|
}];
|
|
[[ref childByAutoId] setValue:@"test-value-3"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[order addObject:@"3"];
|
|
}];
|
|
[[ref childByAutoId] setValue:@"test-value-4"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[order addObject:@"4"];
|
|
}];
|
|
|
|
[self waitForEvents:ref];
|
|
|
|
XCTAssertEqual(engine.userWrites.count, (NSUInteger)4);
|
|
|
|
[database purgeOutstandingWrites];
|
|
[self waitForEvents:ref];
|
|
XCTAssertEqual(engine.userWrites.count, (NSUInteger)0);
|
|
XCTAssertEqualObjects(order, (@[ @"1", @"2", @"3", @"4" ]));
|
|
|
|
[database goOnline];
|
|
}
|
|
|
|
- (void)testPurgeWritesCancelsOnDisconnects {
|
|
FMockStorageEngine *engine = [[FMockStorageEngine alloc] init];
|
|
FIRDatabaseReference *ref = [self rootRefWithEngine:engine
|
|
name:@"purgeWritesCancelsOnDisconnects"];
|
|
FIRDatabase *database = ref.database;
|
|
|
|
[database goOffline];
|
|
|
|
NSMutableArray *events = [NSMutableArray array];
|
|
|
|
[[ref childByAutoId] onDisconnectSetValue:@"test-value-1"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[events addObject:@"1"];
|
|
}];
|
|
|
|
[[ref childByAutoId] onDisconnectSetValue:@"test-value-2"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[events addObject:@"2"];
|
|
}];
|
|
|
|
[self waitForEvents:ref];
|
|
|
|
[database purgeOutstandingWrites];
|
|
|
|
[self waitForEvents:ref];
|
|
|
|
XCTAssertEqualObjects(events, (@[ @"1", @"2" ]));
|
|
}
|
|
|
|
- (void)testPurgeWritesReraisesEvents {
|
|
FMockStorageEngine *engine = [[FMockStorageEngine alloc] init];
|
|
FIRDatabaseReference *ref = [[self rootRefWithEngine:engine
|
|
name:@"purgeWritesReraiseEvents"] childByAutoId];
|
|
FIRDatabase *database = ref.database;
|
|
|
|
[self waitForCompletionOf:ref
|
|
setValue:@{@"foo" : @"foo-value", @"bar" : @{@"qux" : @"qux-value"}}];
|
|
|
|
NSMutableArray *fooValues = [NSMutableArray array];
|
|
NSMutableArray *barQuuValues = [NSMutableArray array];
|
|
NSMutableArray *barQuxValues = [NSMutableArray array];
|
|
NSMutableArray *cancelOrder = [NSMutableArray array];
|
|
|
|
[[ref child:@"foo"] observeEventType:FIRDataEventTypeValue
|
|
withBlock:^(FIRDataSnapshot *snapshot) {
|
|
[fooValues addObject:snapshot.value];
|
|
}];
|
|
[[ref child:@"bar/quu"] observeEventType:FIRDataEventTypeValue
|
|
withBlock:^(FIRDataSnapshot *snapshot) {
|
|
[barQuuValues addObject:snapshot.value];
|
|
}];
|
|
[[ref child:@"bar/qux"] observeEventType:FIRDataEventTypeValue
|
|
withBlock:^(FIRDataSnapshot *snapshot) {
|
|
[barQuxValues addObject:snapshot.value];
|
|
}];
|
|
|
|
[database goOffline];
|
|
|
|
[[ref child:@"foo"] setValue:@"new-foo-value"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
// This should be after we raised events
|
|
XCTAssertEqualObjects(fooValues.lastObject, @"foo-value");
|
|
[cancelOrder addObject:@"foo-1"];
|
|
}];
|
|
|
|
[[ref child:@"bar"] updateChildValues:@{@"quu" : @"quu-value", @"qux" : @"new-qux-value"}
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
// This should be after we raised events
|
|
XCTAssertEqualObjects(barQuxValues.lastObject, @"qux-value");
|
|
XCTAssertEqualObjects(barQuuValues.lastObject, [NSNull null]);
|
|
[cancelOrder addObject:@"bar"];
|
|
}];
|
|
|
|
[[ref child:@"foo"] setValue:@"newest-foo-value"
|
|
withCompletionBlock:^(NSError *error, FIRDatabaseReference *ref) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
// This should be after we raised events
|
|
XCTAssertEqualObjects(fooValues.lastObject, @"foo-value");
|
|
[cancelOrder addObject:@"foo-2"];
|
|
}];
|
|
|
|
[database purgeOutstandingWrites];
|
|
|
|
[self waitForEvents:ref];
|
|
|
|
XCTAssertEqualObjects(cancelOrder, (@[ @"foo-1", @"bar", @"foo-2" ]));
|
|
XCTAssertEqualObjects(fooValues,
|
|
(@[ @"foo-value", @"new-foo-value", @"newest-foo-value", @"foo-value" ]));
|
|
XCTAssertEqualObjects(barQuuValues, (@[ [NSNull null], @"quu-value", [NSNull null] ]));
|
|
XCTAssertEqualObjects(barQuxValues, (@[ @"qux-value", @"new-qux-value", @"qux-value" ]));
|
|
|
|
[database goOnline];
|
|
// Make sure we're back online and reconnected again
|
|
[self waitForRoundTrip:ref];
|
|
|
|
// No events should be reraised
|
|
XCTAssertEqualObjects(cancelOrder, (@[ @"foo-1", @"bar", @"foo-2" ]));
|
|
XCTAssertEqualObjects(fooValues,
|
|
(@[ @"foo-value", @"new-foo-value", @"newest-foo-value", @"foo-value" ]));
|
|
XCTAssertEqualObjects(barQuuValues, (@[ [NSNull null], @"quu-value", [NSNull null] ]));
|
|
XCTAssertEqualObjects(barQuxValues, (@[ @"qux-value", @"new-qux-value", @"qux-value" ]));
|
|
}
|
|
|
|
- (void)testPurgeWritesCancelsTransactions {
|
|
FMockStorageEngine *engine = [[FMockStorageEngine alloc] init];
|
|
FIRDatabaseReference *ref =
|
|
[[self rootRefWithEngine:engine name:@"purgeWritesCancelsTransactions"] childByAutoId];
|
|
FIRDatabase *database = ref.database;
|
|
|
|
NSMutableArray *events = [NSMutableArray array];
|
|
|
|
[ref observeEventType:FIRDataEventTypeValue
|
|
withBlock:^(FIRDataSnapshot *snapshot) {
|
|
[events addObject:[NSString stringWithFormat:@"value-%@", snapshot.value]];
|
|
}];
|
|
|
|
// Make sure the first value event is fired
|
|
[self waitForRoundTrip:ref];
|
|
|
|
[database goOffline];
|
|
|
|
[ref
|
|
runTransactionBlock:^FIRTransactionResult *(FIRMutableData *currentData) {
|
|
[currentData setValue:@"1"];
|
|
return [FIRTransactionResult successWithValue:currentData];
|
|
}
|
|
andCompletionBlock:^(NSError *error, BOOL committed, FIRDataSnapshot *snapshot) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[events addObject:@"cancel-1"];
|
|
}];
|
|
|
|
[ref
|
|
runTransactionBlock:^FIRTransactionResult *(FIRMutableData *currentData) {
|
|
[currentData setValue:@"2"];
|
|
return [FIRTransactionResult successWithValue:currentData];
|
|
}
|
|
andCompletionBlock:^(NSError *error, BOOL committed, FIRDataSnapshot *snapshot) {
|
|
XCTAssertEqual(error.code, kFErrorCodeWriteCanceled);
|
|
[events addObject:@"cancel-2"];
|
|
}];
|
|
|
|
[database purgeOutstandingWrites];
|
|
|
|
[self waitForEvents:ref];
|
|
|
|
// The order should really be cancel-1 then cancel-2, but meh, to difficult to implement
|
|
// currently...
|
|
XCTAssertEqualObjects(
|
|
events,
|
|
(@[ @"value-<null>", @"value-1", @"value-2", @"value-<null>", @"cancel-2", @"cancel-1" ]));
|
|
}
|
|
|
|
- (void)testPersistenceEnabled {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testPersistenceEnabled" URL:self.databaseURL];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app];
|
|
database.persistenceEnabled = YES;
|
|
XCTAssertTrue(database.persistenceEnabled);
|
|
|
|
// Just do a dummy observe that should get null added to the persistent cache.
|
|
FIRDatabaseReference *ref = [[database reference] childByAutoId];
|
|
[self waitForValueOf:ref toBe:[NSNull null]];
|
|
|
|
// Now go offline and since null is cached offline, our observer should still complete.
|
|
[database goOffline];
|
|
[self waitForValueOf:ref toBe:[NSNull null]];
|
|
}
|
|
|
|
- (void)testPersistenceCacheSizeBytes {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testPersistenceCacheSizeBytes" URL:self.databaseURL];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app];
|
|
database.persistenceEnabled = YES;
|
|
|
|
int oneMegabyte = 1 * 1024 * 1024;
|
|
|
|
XCTAssertThrows([database setPersistenceCacheSizeBytes:1], @"Cache must be a least 1 MB.");
|
|
XCTAssertThrows([database setPersistenceCacheSizeBytes:101 * oneMegabyte],
|
|
@"Cache must be less than 100 MB.");
|
|
database.persistenceCacheSizeBytes = 2 * oneMegabyte;
|
|
XCTAssertEqual(2 * oneMegabyte, database.persistenceCacheSizeBytes);
|
|
|
|
[database reference]; // Initialize database.
|
|
|
|
XCTAssertThrows([database setPersistenceCacheSizeBytes:3 * oneMegabyte],
|
|
@"Persistence can't be changed after initialization.");
|
|
XCTAssertEqual(2 * oneMegabyte, database.persistenceCacheSizeBytes);
|
|
}
|
|
|
|
- (void)testCallbackQueue {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testCallbackQueue" URL:self.databaseURL];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app];
|
|
dispatch_queue_t callbackQueue = dispatch_queue_create("testCallbackQueue", NULL);
|
|
database.callbackQueue = callbackQueue;
|
|
XCTAssertEqual(callbackQueue, database.callbackQueue);
|
|
|
|
__block BOOL done = NO;
|
|
[database.reference.childByAutoId observeSingleEventOfType:FIRDataEventTypeValue
|
|
withBlock:^(FIRDataSnapshot *snapshot) {
|
|
dispatch_assert_queue(callbackQueue);
|
|
done = YES;
|
|
}];
|
|
WAIT_FOR(done);
|
|
[database goOffline];
|
|
}
|
|
|
|
- (void)testSetEmulatorSettingsCreatesEmulatedReferences {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testSetEmulatorSettingsCreatesEmulatedReferences"
|
|
URL:self.databaseURL];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app];
|
|
|
|
[database useEmulatorWithHost:@"localhost" port:1111];
|
|
NSString *concatenatedHost = @"localhost:1111";
|
|
|
|
FIRDatabaseReference *reference = [database reference];
|
|
|
|
NSString *referenceURLString = reference.URL;
|
|
|
|
XCTAssert([referenceURLString containsString:concatenatedHost]);
|
|
}
|
|
|
|
- (void)testSetEmulatorSettingsThrowsAfterRepoInit {
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testSetEmulatorSettingsThrowsAfterRepoInit"
|
|
URL:self.databaseURL];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app];
|
|
|
|
[database reference]; // initialize database repo
|
|
|
|
// Emulator can't be set after initialization of the database's repo.
|
|
XCTAssertThrows([database useEmulatorWithHost:@"a" port:1]);
|
|
}
|
|
|
|
- (void)testEmulatedDatabaseValidatesOnlyNonCustomURLs {
|
|
// Set a non-custom databaseURL
|
|
NSString *databaseURL = @"https://test.example.com";
|
|
id app = [[FIRFakeApp alloc] initWithName:@"testEmulatedDatabaseValidatesNonCustomURLs0"
|
|
URL:databaseURL];
|
|
FIRDatabase *database = [FIRDatabase databaseForApp:app];
|
|
|
|
// Reference should be retrievable without an exception being raised
|
|
NSString *referenceURLString = [databaseURL stringByAppendingString:@"/path"];
|
|
FIRDatabaseReference *reference = [database referenceFromURL:referenceURLString];
|
|
XCTAssertNotNil(reference);
|
|
|
|
app = [[FIRFakeApp alloc] initWithName:@"testEmulatedDatabaseValidatesNonCustomURLs1"
|
|
URL:databaseURL];
|
|
database = [FIRDatabase databaseForApp:app];
|
|
[database useEmulatorWithHost:@"localhost" port:1111];
|
|
|
|
// Expect production url creates a valid (emulated) reference.
|
|
reference = [database referenceFromURL:referenceURLString];
|
|
XCTAssertNotNil(reference);
|
|
XCTAssert([reference.URL containsString:@"localhost:1111"]);
|
|
|
|
// Test emulated url
|
|
referenceURLString = @"http://localhost:1111/path";
|
|
reference = [database referenceFromURL:referenceURLString];
|
|
XCTAssertNotNil(reference);
|
|
XCTAssert([reference.URL containsString:@"localhost:1111"]);
|
|
|
|
// Test non-custom url with different host throws exception
|
|
referenceURLString = @"https://test.firebaseio.com/path";
|
|
XCTAssertThrows([database referenceFromURL:referenceURLString]);
|
|
}
|
|
|
|
- (FIRDatabase *)defaultDatabase {
|
|
return [self databaseForURL:self.databaseURL];
|
|
}
|
|
|
|
- (FIRDatabase *)databaseForURL:(NSString *)url {
|
|
NSString *name = [NSString stringWithFormat:@"url:%@", url];
|
|
return [self databaseForURL:url name:name];
|
|
}
|
|
|
|
- (FIRDatabase *)databaseForURL:(NSString *)url name:(NSString *)name {
|
|
NSString *defaultDatabaseURL = [NSString stringWithFormat:@"url:%@", self.databaseURL];
|
|
if ([url isEqualToString:self.databaseURL] && [name isEqualToString:defaultDatabaseURL]) {
|
|
// Use the default app for the default URL to avoid getting out of sync with FRepoManager
|
|
// when calling ensureRepo during tests that don't create their own FIRFakeApp.
|
|
return [FTestHelpers defaultDatabase];
|
|
} else {
|
|
id app = [[FIRFakeApp alloc] initWithName:name URL:url];
|
|
return [FIRDatabase databaseForApp:app];
|
|
}
|
|
}
|
|
@end
|