| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001 |
- // 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 "FirebaseCore/Tests/Unit/FIRTestCase.h"
- #import "FirebaseCore/Tests/Unit/FIRTestComponents.h"
- #import <GoogleUtilities/GULAppEnvironmentUtil.h>
- #import "FirebaseCore/Sources/FIRAnalyticsConfiguration.h"
- #import "FirebaseCore/Sources/Private/FIRAppInternal.h"
- #import "FirebaseCore/Sources/Private/FIRComponentType.h"
- #import "FirebaseCore/Sources/Private/FIRCoreDiagnosticsConnector.h"
- #import "FirebaseCore/Sources/Private/FIROptionsInternal.h"
- #import "SharedTestUtilities/FIROptionsMock.h"
- NSString *const kFIRTestAppName1 = @"test_app_name_1";
- NSString *const kFIRTestAppName2 = @"test-app-name-2";
- @interface FIRApp (TestInternal)
- + (void)resetApps;
- - (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options;
- - (BOOL)configureCore;
- + (NSError *)errorForInvalidAppID;
- - (BOOL)isAppIDValid;
- + (NSString *)actualBundleID;
- + (NSNumber *)mapFromServiceStringToTypeEnum:(NSString *)serviceString;
- + (NSString *)deviceModel;
- + (NSString *)installString;
- + (NSURL *)filePathURLWithName:(NSString *)fileName;
- + (NSString *)stringAtURL:(NSURL *)filePathURL;
- + (BOOL)writeString:(NSString *)string toURL:(NSURL *)filePathURL;
- + (void)logAppInfo:(NSNotification *)notification;
- + (BOOL)validateAppID:(NSString *)appID;
- + (BOOL)validateAppIDFormat:(NSString *)appID withVersion:(NSString *)version;
- + (BOOL)validateAppIDFingerprint:(NSString *)appID withVersion:(NSString *)version;
- + (nullable NSNumber *)readDataCollectionSwitchFromPlist;
- + (nullable NSNumber *)readDataCollectionSwitchFromUserDefaultsForApp:(FIRApp *)app;
- @end
- @interface FIRAppTest : FIRTestCase
- @property(nonatomic) id appClassMock;
- @property(nonatomic) id mockCoreDiagnosticsConnector;
- @property(nonatomic) NSNotificationCenter *notificationCenter;
- /// If `YES` then throws when `logCoreTelemetryWithOptions:` method is called.
- @property(nonatomic) BOOL assertNoLogCoreTelemetry;
- @end
- @implementation FIRAppTest
- - (void)setUp {
- [super setUp];
- [FIROptions resetDefaultOptions];
- [FIRApp resetApps];
- // TODO: Don't mock the class we are testing.
- _appClassMock = OCMClassMock([FIRApp class]);
- _mockCoreDiagnosticsConnector = OCMClassMock([FIRCoreDiagnosticsConnector class]);
- [FIROptionsMock mockFIROptions];
- self.assertNoLogCoreTelemetry = NO;
- OCMStub(ClassMethod([self.mockCoreDiagnosticsConnector logCoreTelemetryWithOptions:[OCMArg any]]))
- .andDo(^(NSInvocation *invocation) {
- if (self.assertNoLogCoreTelemetry) {
- XCTFail(@"Method `-[mockCoreDiagnosticsConnector logCoreTelemetryWithOptions:]` must not "
- @"be called");
- }
- });
- // TODO: Remove all usages of defaultCenter in Core, then we can instantiate an instance here to
- // inject instead of using defaultCenter.
- _notificationCenter = [NSNotificationCenter defaultCenter];
- }
- - (void)tearDown {
- // Wait for background operations to complete.
- NSDate *waitUntilDate = [NSDate dateWithTimeIntervalSinceNow:0.5];
- while ([[NSDate date] compare:waitUntilDate] == NSOrderedAscending) {
- [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
- }
- [_appClassMock stopMocking];
- _appClassMock = nil;
- _notificationCenter = nil;
- _mockCoreDiagnosticsConnector = nil;
- [super tearDown];
- }
- - (void)testConfigure {
- [self registerLibrariesWithClasses:@[
- [FIRTestClassCached class], [FIRTestClassEagerCached class]
- ]];
- NSDictionary *expectedUserInfo = [self expectedUserInfoWithAppName:kFIRDefaultAppName
- isDefaultApp:YES];
- XCTestExpectation *notificationExpectation =
- [self expectNotificationNamed:kFIRAppReadyToConfigureSDKNotification
- object:[FIRApp class]
- userInfo:expectedUserInfo];
- XCTAssertNoThrow([FIRApp configure]);
- [self waitForExpectations:@[ notificationExpectation ] timeout:0.1];
- FIRApp *app = [FIRApp defaultApp];
- XCTAssertNotNil(app);
- XCTAssertEqualObjects(app.name, kFIRDefaultAppName);
- XCTAssertEqualObjects(app.options.clientID, kClientID);
- XCTAssertTrue([FIRApp allApps].count == 1);
- // Check the registered libraries instances available.
- XCTAssertNotNil(FIR_COMPONENT(FIRTestProtocolCached, app.container));
- XCTAssertNotNil(FIR_COMPONENT(FIRTestProtocolEagerCached, app.container));
- XCTAssertNil(FIR_COMPONENT(FIRTestProtocol, app.container));
- }
- - (void)testConfigureWithNoDefaultOptions {
- id optionsClassMock = OCMClassMock([FIROptions class]);
- OCMStub([optionsClassMock defaultOptions]).andReturn(nil);
- XCTAssertThrows([FIRApp configure]);
- }
- - (void)testConfigureWithOptions {
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wnonnull"
- // Test `nil` options.
- XCTAssertThrows([FIRApp configureWithOptions:nil]);
- #pragma clang diagnostic pop
- XCTAssertTrue([FIRApp allApps].count == 0);
- NSDictionary *expectedUserInfo = [self expectedUserInfoWithAppName:kFIRDefaultAppName
- isDefaultApp:YES];
- XCTestExpectation *notificationExpectation =
- [self expectNotificationNamed:kFIRAppReadyToConfigureSDKNotification
- object:[FIRApp class]
- userInfo:expectedUserInfo];
- // Use a valid instance of options.
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- options.clientID = kClientID;
- XCTAssertNoThrow([FIRApp configureWithOptions:options]);
- [self waitForExpectations:@[ notificationExpectation ] timeout:0.1];
- // Verify the default app instance is created.
- FIRApp *app = [FIRApp defaultApp];
- XCTAssertNotNil(app);
- XCTAssertEqualObjects(app.name, kFIRDefaultAppName);
- XCTAssertEqualObjects(app.options.googleAppID, kGoogleAppID);
- XCTAssertEqualObjects(app.options.GCMSenderID, kGCMSenderID);
- XCTAssertEqualObjects(app.options.clientID, kClientID);
- XCTAssertTrue([FIRApp allApps].count == 1);
- }
- - (void)testConfigureWithNameAndOptions {
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- options.clientID = kClientID;
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wnonnull"
- XCTAssertThrows([FIRApp configureWithName:nil options:options]);
- XCTAssertThrows([FIRApp configureWithName:kFIRTestAppName1 options:nil]);
- #pragma clang diagnostic pop
- XCTAssertThrows([FIRApp configureWithName:@"" options:options]);
- XCTAssertTrue([FIRApp allApps].count == 0);
- NSDictionary *expectedUserInfo = [self expectedUserInfoWithAppName:kFIRTestAppName1
- isDefaultApp:NO];
- XCTestExpectation *notificationExpectation =
- [self expectNotificationNamed:kFIRAppReadyToConfigureSDKNotification
- object:[FIRApp class]
- userInfo:expectedUserInfo];
- XCTAssertNoThrow([FIRApp configureWithName:kFIRTestAppName1 options:options]);
- [self waitForExpectations:@[ notificationExpectation ] timeout:0.1];
- XCTAssertTrue([FIRApp allApps].count == 1);
- FIRApp *app = [FIRApp appNamed:kFIRTestAppName1];
- XCTAssertNotNil(app);
- XCTAssertEqualObjects(app.name, kFIRTestAppName1);
- XCTAssertEqualObjects(app.options.clientID, kClientID);
- // Configure the same app again should throw an exception.
- XCTAssertThrows([FIRApp configureWithName:kFIRTestAppName1 options:options]);
- }
- - (void)testConfigureWithMultipleApps {
- FIROptions *options1 = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- options1.deepLinkURLScheme = kDeepLinkURLScheme;
- NSDictionary *expectedUserInfo1 = [self expectedUserInfoWithAppName:kFIRTestAppName1
- isDefaultApp:NO];
- XCTestExpectation *configExpectation1 =
- [self expectNotificationNamed:kFIRAppReadyToConfigureSDKNotification
- object:[FIRApp class]
- userInfo:expectedUserInfo1];
- XCTAssertNoThrow([FIRApp configureWithName:kFIRTestAppName1 options:options1]);
- XCTAssertTrue([FIRApp allApps].count == 1);
- // Configure a different app with valid customized options.
- FIROptions *options2 = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- options2.bundleID = kBundleID;
- options2.APIKey = kCustomizedAPIKey;
- NSDictionary *expectedUserInfo2 = [self expectedUserInfoWithAppName:kFIRTestAppName2
- isDefaultApp:NO];
- XCTestExpectation *configExpectation2 =
- [self expectNotificationNamed:kFIRAppReadyToConfigureSDKNotification
- object:[FIRApp class]
- userInfo:expectedUserInfo2];
- XCTAssertNoThrow([FIRApp configureWithName:kFIRTestAppName2 options:options2]);
- [self waitForExpectations:@[ configExpectation1, configExpectation2 ]
- timeout:0.1
- enforceOrder:YES];
- XCTAssertTrue([FIRApp allApps].count == 2);
- FIRApp *app = [FIRApp appNamed:kFIRTestAppName2];
- XCTAssertNotNil(app);
- XCTAssertEqualObjects(app.name, kFIRTestAppName2);
- XCTAssertEqualObjects(app.options.googleAppID, kGoogleAppID);
- XCTAssertEqualObjects(app.options.APIKey, kCustomizedAPIKey);
- }
- - (void)testConfigureThrowsAfterConfigured {
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- [FIRApp configureWithOptions:options];
- XCTAssertNotNil([FIRApp defaultApp]);
- // A second configure call should throw, since Firebase is already configured.
- XCTAssertThrows([FIRApp configureWithOptions:options]);
- // Test the same with a custom named app.
- [FIRApp configureWithName:kFIRTestAppName1 options:options];
- XCTAssertNotNil([FIRApp appNamed:kFIRTestAppName1]);
- // A second configure call should throw, since Firebase is already configured.
- XCTAssertThrows([FIRApp configureWithName:kFIRTestAppName1 options:options]);
- }
- - (void)testConfigureDefaultAppInExtension {
- id environmentMock = OCMClassMock([GULAppEnvironmentUtil class]);
- OCMStub([environmentMock isAppExtension]).andReturn(YES);
- // Set up the default app like a standard app.
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- [FIRApp configureWithOptions:options];
- XCTAssertNotNil([FIRApp defaultApp]);
- XCTAssertEqual([FIRApp allApps].count, 1);
- // Configuring with the same set of options shouldn't throw.
- XCTAssertNoThrow([FIRApp configureWithOptions:options]);
- // Only 1 app should have been configured still, the default app.
- XCTAssertNotNil([FIRApp defaultApp]);
- XCTAssertEqual([FIRApp allApps].count, 1);
- // Use a set of a different options to call configure again, which should throw.
- FIROptions *differentOptions = [[FIROptions alloc] initWithGoogleAppID:@"1:789:ios:789XYZ"
- GCMSenderID:kGCMSenderID];
- XCTAssertThrows([FIRApp configureWithOptions:differentOptions]);
- XCTAssertEqual([FIRApp allApps].count, 1);
- // Explicily stop the environmentMock.
- [environmentMock stopMocking];
- environmentMock = nil;
- }
- - (void)testConfigureCustomAppInExtension {
- id environmentMock = OCMClassMock([GULAppEnvironmentUtil class]);
- OCMStub([environmentMock isAppExtension]).andReturn(YES);
- // Set up a custom named app like a standard app.
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- [FIRApp configureWithName:kFIRTestAppName1 options:options];
- XCTAssertNotNil([FIRApp appNamed:kFIRTestAppName1]);
- XCTAssertEqual([FIRApp allApps].count, 1);
- // Configuring with the same set of options shouldn't throw.
- XCTAssertNoThrow([FIRApp configureWithName:kFIRTestAppName1 options:options]);
- // Only 1 app should have been configured still.
- XCTAssertNotNil([FIRApp appNamed:kFIRTestAppName1]);
- XCTAssertEqual([FIRApp allApps].count, 1);
- // Use a set of a different options to call configure again, which should throw.
- FIROptions *differentOptions = [[FIROptions alloc] initWithGoogleAppID:@"1:789:ios:789XYZ"
- GCMSenderID:kGCMSenderID];
- XCTAssertThrows([FIRApp configureWithName:kFIRTestAppName1 options:differentOptions]);
- XCTAssertEqual([FIRApp allApps].count, 1);
- // Explicily stop the environmentMock.
- [environmentMock stopMocking];
- environmentMock = nil;
- }
- - (void)testValidName {
- XCTAssertNoThrow([FIRApp configureWithName:@"aA1_" options:[FIROptions defaultOptions]]);
- XCTAssertNoThrow([FIRApp configureWithName:@"aA1-" options:[FIROptions defaultOptions]]);
- XCTAssertNoThrow([FIRApp configureWithName:@"aAē1_" options:[FIROptions defaultOptions]]);
- XCTAssertThrows([FIRApp configureWithName:@"aA1%" options:[FIROptions defaultOptions]]);
- XCTAssertThrows([FIRApp configureWithName:@"aA1?" options:[FIROptions defaultOptions]]);
- XCTAssertThrows([FIRApp configureWithName:@"aA1!" options:[FIROptions defaultOptions]]);
- }
- - (void)testDefaultApp {
- FIRApp *app = [FIRApp defaultApp];
- XCTAssertNil(app);
- [FIRApp configure];
- app = [FIRApp defaultApp];
- XCTAssertEqualObjects(app.name, kFIRDefaultAppName);
- XCTAssertEqualObjects(app.options.clientID, kClientID);
- }
- - (void)testAppNamed {
- FIRApp *app = [FIRApp appNamed:kFIRTestAppName1];
- XCTAssertNil(app);
- [FIRApp configureWithName:kFIRTestAppName1 options:[FIROptions defaultOptions]];
- app = [FIRApp appNamed:kFIRTestAppName1];
- XCTAssertEqualObjects(app.name, kFIRTestAppName1);
- XCTAssertEqualObjects(app.options.clientID, kClientID);
- }
- - (void)testDeleteApp {
- [self registerLibrariesWithClasses:@[
- [FIRTestClassCached class], [FIRTestClassEagerCached class]
- ]];
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- [FIRApp configureWithName:name options:options];
- FIRApp *app = [FIRApp appNamed:name];
- XCTAssertNotNil(app);
- XCTAssertTrue([FIRApp allApps].count == 1);
- // Check the registered libraries instances available.
- XCTAssertNotNil(FIR_COMPONENT(FIRTestProtocolCached, app.container));
- XCTAssertNotNil(FIR_COMPONENT(FIRTestProtocolEagerCached, app.container));
- XCTAssertNil(FIR_COMPONENT(FIRTestProtocol, app.container));
- XCTestExpectation *notificationExpectation =
- [self expectationForNotification:kFIRAppDeleteNotification
- object:[FIRApp class]
- notificationCenter:self.notificationCenter
- handler:nil];
- XCTestExpectation *deleteExpectation =
- [self expectationWithDescription:@"Deleting the app should succeed."];
- [app deleteApp:^(BOOL success) {
- XCTAssertTrue(success);
- [deleteExpectation fulfill];
- }];
- [self waitForExpectations:@[ notificationExpectation, deleteExpectation ] timeout:1];
- XCTAssertTrue([FIRApp allApps].count == 0);
- // Check no new library instances created after the app delete.
- XCTAssertNil(FIR_COMPONENT(FIRTestProtocolCached, app.container));
- XCTAssertNil(FIR_COMPONENT(FIRTestProtocolEagerCached, app.container));
- }
- - (void)testOptionsLocking {
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- options.projectID = kProjectID;
- options.databaseURL = kDatabaseURL;
- // Options should not be locked before they are used to configure a `FIRApp`.
- XCTAssertFalse(options.isEditingLocked);
- // The options returned should be locked after configuring `FIRApp`.
- NSString *name = NSStringFromSelector(_cmd);
- [FIRApp configureWithName:name options:options];
- FIROptions *optionsCopy = [[FIRApp appNamed:name] options];
- XCTAssertTrue(optionsCopy.isEditingLocked);
- }
- #pragma mark - App ID v1
- - (void)testAppIDV1 {
- // Missing separator between platform:fingerprint.
- XCTAssertFalse([FIRApp validateAppID:@"1:1337:iosdeadbeef"]);
- // Wrong platform "android".
- XCTAssertFalse([FIRApp validateAppID:@"1:1337:android:deadbeef"]);
- // The fingerprint, aka 4th field, should only contain hex characters.
- XCTAssertFalse([FIRApp validateAppID:@"1:1337:ios:123abcxyz"]);
- // The fingerprint, aka 4th field, is not tested in V1, so a bad value shouldn't cause a failure.
- XCTAssertTrue([FIRApp validateAppID:@"1:1337:ios:deadbeef"]);
- }
- #pragma mark - App ID v2
- - (void)testAppIDV2 {
- // Missing separator between platform:fingerprint.
- XCTAssertTrue([FIRApp validateAppID:@"2:1337:ios5e18052ab54fbfec"]);
- // Unknown versions may contain anything.
- XCTAssertTrue([FIRApp validateAppID:@"2:1337:ios:123abcxyz"]);
- XCTAssertTrue([FIRApp validateAppID:@"2:thisdoesn'teven_m:a:t:t:e:r_"]);
- // Known good fingerprint.
- XCTAssertTrue([FIRApp validateAppID:@"2:1337:ios:5e18052ab54fbfec"]);
- // Unknown fingerprint, not tested so shouldn't cause a failure.
- XCTAssertTrue([FIRApp validateAppID:@"2:1337:ios:deadbeef"]);
- }
- #pragma mark - App ID other
- - (void)testAppIDV3 {
- // Currently there is no specification for v3, so we would not expect it to fail.
- XCTAssertTrue([FIRApp validateAppID:@"3:1337:ios:deadbeef"]);
- }
- - (void)testAppIDEmpty {
- XCTAssertFalse([FIRApp validateAppID:@""]);
- }
- - (void)testAppIDValidationTrue {
- // Ensure that isAppIDValid matches validateAppID.
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:@"" GCMSenderID:@""];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:NSStringFromSelector(_cmd) options:options];
- OCMStub([self.appClassMock validateAppID:[OCMArg any]]).andReturn(YES);
- XCTAssertTrue([app isAppIDValid]);
- }
- - (void)testAppIDValidationFalse {
- // Ensure that isAppIDValid matches validateAppID.
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:@"" GCMSenderID:@""];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:NSStringFromSelector(_cmd) options:options];
- OCMStub([self.appClassMock validateAppID:[OCMArg any]]).andReturn(NO);
- XCTAssertFalse([app isAppIDValid]);
- }
- - (void)testAppIDPrefix {
- // Unknown numeric-character prefixes should pass.
- XCTAssertTrue([FIRApp validateAppID:@"0:"]);
- XCTAssertTrue([FIRApp validateAppID:@"01:"]);
- XCTAssertTrue([FIRApp validateAppID:@"10:"]);
- XCTAssertTrue([FIRApp validateAppID:@"010:"]);
- XCTAssertTrue([FIRApp validateAppID:@"3:"]);
- XCTAssertTrue([FIRApp validateAppID:@"123:"]);
- XCTAssertTrue([FIRApp validateAppID:@"999999999:"]);
- // Non-numeric prefixes should not pass.
- XCTAssertFalse([FIRApp validateAppID:@"a:"]);
- XCTAssertFalse([FIRApp validateAppID:@"abcsdf0:"]);
- XCTAssertFalse([FIRApp validateAppID:@"0aaaa:"]);
- XCTAssertFalse([FIRApp validateAppID:@"0aaaa0450:"]);
- XCTAssertFalse([FIRApp validateAppID:@"-1:"]);
- XCTAssertFalse([FIRApp validateAppID:@"abcsdf:"]);
- XCTAssertFalse([FIRApp validateAppID:@"ABDCF:"]);
- XCTAssertFalse([FIRApp validateAppID:@" :"]);
- XCTAssertFalse([FIRApp validateAppID:@"1 :"]);
- XCTAssertFalse([FIRApp validateAppID:@" 1:"]);
- XCTAssertFalse([FIRApp validateAppID:@" 123 :"]);
- XCTAssertFalse([FIRApp validateAppID:@"1 23:"]);
- XCTAssertFalse([FIRApp validateAppID:@"&($*&%(*$&:"]);
- XCTAssertFalse([FIRApp validateAppID:@"abCDSF$%%df:"]);
- // Known version prefixes should never pass without the rest of the app ID string present.
- XCTAssertFalse([FIRApp validateAppID:@"1:"]);
- // Version must include ":".
- XCTAssertFalse([FIRApp validateAppID:@"0"]);
- XCTAssertFalse([FIRApp validateAppID:@"01"]);
- XCTAssertFalse([FIRApp validateAppID:@"10"]);
- XCTAssertFalse([FIRApp validateAppID:@"010"]);
- XCTAssertFalse([FIRApp validateAppID:@"3"]);
- XCTAssertFalse([FIRApp validateAppID:@"123"]);
- XCTAssertFalse([FIRApp validateAppID:@"999999999"]);
- XCTAssertFalse([FIRApp validateAppID:@"com.google.bundleID"]);
- }
- - (void)testAppIDFormatInvalid {
- OCMStub([self.appClassMock actualBundleID]).andReturn(@"com.google.bundleID");
- // Some direct tests of the validateAppIDFormat:withVersion: method.
- // Sanity checks first.
- NSString *const kGoodAppIDV1 = @"1:1337:ios:deadbeef";
- NSString *const kGoodVersionV1 = @"1";
- XCTAssertTrue([FIRApp validateAppIDFormat:kGoodAppIDV1 withVersion:kGoodVersionV1]);
- NSString *const kGoodAppIDV2 = @"2:1337:ios:5e18052ab54fbfec";
- NSString *const kGoodVersionV2 = @"2";
- XCTAssertTrue([FIRApp validateAppIDFormat:kGoodAppIDV2 withVersion:kGoodVersionV2]);
- // Version mismatch.
- XCTAssertFalse([FIRApp validateAppIDFormat:kGoodAppIDV2 withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:kGoodAppIDV1 withVersion:kGoodVersionV2]);
- XCTAssertFalse([FIRApp validateAppIDFormat:kGoodAppIDV1 withVersion:@"999:"]);
- // Nil or empty strings.
- XCTAssertFalse([FIRApp validateAppIDFormat:kGoodAppIDV1 withVersion:nil]);
- XCTAssertFalse([FIRApp validateAppIDFormat:kGoodAppIDV1 withVersion:@""]);
- XCTAssertFalse([FIRApp validateAppIDFormat:nil withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:nil withVersion:nil]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"" withVersion:@""]);
- // App ID contains only the version prefix.
- XCTAssertFalse([FIRApp validateAppIDFormat:kGoodVersionV1 withVersion:kGoodVersionV1]);
- // The version is the entire app ID.
- XCTAssertFalse([FIRApp validateAppIDFormat:kGoodAppIDV1 withVersion:kGoodAppIDV1]);
- // Versions digits that may make a partial match.
- XCTAssertFalse([FIRApp validateAppIDFormat:@"01:1337:ios:deadbeef" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"10:1337:ios:deadbeef" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"11:1337:ios:deadbeef" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"21:1337:ios:5e18052ab54fbfec"
- withVersion:kGoodVersionV2]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"22:1337:ios:5e18052ab54fbfec"
- withVersion:kGoodVersionV2]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"02:1337:ios:5e18052ab54fbfec"
- withVersion:kGoodVersionV2]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"20:1337:ios:5e18052ab54fbfec"
- withVersion:kGoodVersionV2]);
- // Extra fields.
- XCTAssertFalse([FIRApp validateAppIDFormat:@"ab:1:1337:ios:deadbeef" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"1:ab:1337:ios:deadbeef" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"1:1337:ab:ios:deadbeef" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"1:1337:ios:ab:deadbeef" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFormat:@"1:1337:ios:deadbeef:ab" withVersion:kGoodVersionV1]);
- }
- - (void)testAppIDFingerprintInvalid {
- OCMStub([self.appClassMock actualBundleID]).andReturn(@"com.google.bundleID");
- // Some direct tests of the validateAppIDFingerprint:withVersion: method.
- // Sanity checks first.
- NSString *const kGoodAppIDV1 = @"1:1337:ios:deadbeef";
- NSString *const kGoodVersionV1 = @"1";
- XCTAssertTrue([FIRApp validateAppIDFingerprint:kGoodAppIDV1 withVersion:kGoodVersionV1]);
- NSString *const kGoodAppIDV2 = @"2:1337:ios:5e18052ab54fbfec";
- NSString *const kGoodVersionV2 = @"2";
- XCTAssertTrue([FIRApp validateAppIDFormat:kGoodAppIDV2 withVersion:kGoodVersionV2]);
- // Nil or empty strings.
- XCTAssertFalse([FIRApp validateAppIDFingerprint:kGoodAppIDV1 withVersion:nil]);
- XCTAssertFalse([FIRApp validateAppIDFingerprint:kGoodAppIDV1 withVersion:@""]);
- XCTAssertFalse([FIRApp validateAppIDFingerprint:nil withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFingerprint:@"" withVersion:kGoodVersionV1]);
- XCTAssertFalse([FIRApp validateAppIDFingerprint:nil withVersion:nil]);
- XCTAssertFalse([FIRApp validateAppIDFingerprint:@"" withVersion:@""]);
- // App ID contains only the version prefix.
- XCTAssertFalse([FIRApp validateAppIDFingerprint:kGoodVersionV1 withVersion:kGoodVersionV1]);
- // The version is the entire app ID.
- XCTAssertFalse([FIRApp validateAppIDFingerprint:kGoodAppIDV1 withVersion:kGoodAppIDV1]);
- }
- // Uncomment if you need to measure performance of [FIRApp validateAppID:].
- // It is commented because measures are heavily dependent on a build agent configuration,
- // so it cannot produce reliable resault on CI
- //- (void)testAppIDFingerprintPerfomance {
- // [self measureBlock:^{
- // for (NSInteger i = 0; i < 100; ++i) {
- // [self testAppIDPrefix];
- // }
- // }];
- //}
- #pragma mark - Automatic Data Collection Tests
- - (void)testGlobalDataCollectionNoFlags {
- // Test: No flags set.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];
- OCMStub([self.appClassMock readDataCollectionSwitchFromPlist]).andReturn(nil);
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(nil);
- XCTAssertTrue(app.isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionPlistSetEnabled {
- // Test: Plist set to enabled, no override.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];
- OCMStub([self.appClassMock readDataCollectionSwitchFromPlist]).andReturn(@YES);
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(nil);
- XCTAssertTrue(app.isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionPlistSetDisabled {
- // Test: Plist set to disabled, no override.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];
- OCMStub([self.appClassMock readDataCollectionSwitchFromPlist]).andReturn(@NO);
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(nil);
- XCTAssertFalse(app.isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionUserSpecifiedEnabled {
- // Test: User specified as enabled, no plist value.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];
- OCMStub([self.appClassMock readDataCollectionSwitchFromPlist]).andReturn(nil);
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(@YES);
- XCTAssertTrue(app.isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionUserSpecifiedDisabled {
- // Test: User specified as disabled, no plist value.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];
- OCMStub([self.appClassMock readDataCollectionSwitchFromPlist]).andReturn(nil);
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(@NO);
- XCTAssertFalse(app.isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionUserOverriddenEnabled {
- // Test: User specified as enabled, with plist set as disabled.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];
- OCMStub([self.appClassMock readDataCollectionSwitchFromPlist]).andReturn(@NO);
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(@YES);
- XCTAssertTrue(app.isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionUserOverriddenDisabled {
- // Test: User specified as disabled, with plist set as enabled.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options];
- OCMStub([self.appClassMock readDataCollectionSwitchFromPlist]).andReturn(@YES);
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(@NO);
- XCTAssertFalse(app.isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionWriteToDefaults {
- id defaultsMock = OCMPartialMock([NSUserDefaults standardUserDefaults]);
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- [FIRApp configureWithName:name options:options];
- FIRApp *app = [FIRApp appNamed:name];
- app.dataCollectionDefaultEnabled = YES;
- NSString *key =
- [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, app.name];
- OCMVerify([defaultsMock setObject:@YES forKey:key]);
- app.dataCollectionDefaultEnabled = NO;
- OCMVerify([defaultsMock setObject:@NO forKey:key]);
- [defaultsMock stopMocking];
- }
- - (void)testGlobalDataCollectionClearedAfterDelete {
- // Configure and disable data collection for the default FIRApp.
- NSString *name = NSStringFromSelector(_cmd);
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- [FIRApp configureWithName:name options:options];
- FIRApp *app = [FIRApp appNamed:name];
- app.dataCollectionDefaultEnabled = NO;
- XCTAssertFalse(app.isDataCollectionDefaultEnabled);
- // Delete the app, and verify that the switch was reset.
- XCTestExpectation *deleteFinished =
- [self expectationWithDescription:@"The app should successfully delete."];
- [app deleteApp:^(BOOL success) {
- XCTAssertTrue(success);
- [deleteFinished fulfill];
- }];
- // Wait for the delete to complete.
- [self waitForExpectations:@[ deleteFinished ] timeout:1];
- // Set up an app with the same name again, and check the data collection flag.
- [FIRApp configureWithName:name options:options];
- XCTAssertTrue([FIRApp appNamed:name].isDataCollectionDefaultEnabled);
- }
- - (void)testGlobalDataCollectionNoDiagnosticsSent {
- FIROptions *options = [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID
- GCMSenderID:kGCMSenderID];
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:NSStringFromSelector(_cmd) options:options];
- app.dataCollectionDefaultEnabled = NO;
- // Stub out reading from user defaults since stubbing out the BOOL has issues. If the data
- // collection switch is disabled, the `sendLogs` call should return immediately and not fire a
- // notification.
- OCMStub([self.appClassMock readDataCollectionSwitchFromUserDefaultsForApp:OCMOCK_ANY])
- .andReturn(@NO);
- // Don't expect the diagnostics data to be sent.
- self.assertNoLogCoreTelemetry = YES;
- // The diagnostics data is expected to be sent on `UIApplicationDidBecomeActiveNotification` when
- // data collection is enabled.
- [FIRApp configure];
- [self.notificationCenter postNotificationName:[self appDidBecomeActiveNotificationName]
- object:nil];
- // Wait for some time because diagnostics is logged asynchronously.
- OCMVerifyAllWithDelay(self.mockCoreDiagnosticsConnector, 1);
- }
- #pragma mark - Analytics Flag Tests
- - (void)testAnalyticsSetByGlobalDataCollectionSwitch {
- // Test that the global data collection switch triggers setting Analytics when no explicit flag is
- // set.
- id optionsMock = OCMClassMock([FIROptions class]);
- OCMStub([optionsMock isAnalyticsCollectionExplicitlySet]).andReturn(NO);
- // We need to use the default app name since Analytics only associates with the default app.
- FIRApp *defaultApp = [[FIRApp alloc] initInstanceWithName:kFIRDefaultAppName options:optionsMock];
- id configurationMock = OCMClassMock([FIRAnalyticsConfiguration class]);
- OCMStub([configurationMock sharedInstance]).andReturn(configurationMock);
- // Ensure Analytics is set after the global flag is set. It needs to
- [defaultApp setDataCollectionDefaultEnabled:YES];
- OCMVerify([configurationMock setAnalyticsCollectionEnabled:YES persistSetting:NO]);
- [defaultApp setDataCollectionDefaultEnabled:NO];
- OCMVerify([configurationMock setAnalyticsCollectionEnabled:NO persistSetting:NO]);
- }
- - (void)testAnalyticsNotSetByGlobalDataCollectionSwitch {
- // Test that the global data collection switch doesn't override an explicitly set Analytics flag.
- id optionsMock = OCMClassMock([FIROptions class]);
- OCMStub([optionsMock isAnalyticsCollectionExplicitlySet]).andReturn(YES);
- FIRApp *app = [[FIRApp alloc] initInstanceWithName:@"testAnalyticsNotSet" options:optionsMock];
- id configurationMock = OCMClassMock([FIRAnalyticsConfiguration class]);
- OCMStub([configurationMock sharedInstance]).andReturn(configurationMock);
- // Reject any changes to Analytics when the data collection changes.
- OCMReject([configurationMock setAnalyticsCollectionEnabled:YES persistSetting:YES]);
- OCMReject([configurationMock setAnalyticsCollectionEnabled:YES persistSetting:NO]);
- [app setDataCollectionDefaultEnabled:YES];
- OCMReject([configurationMock setAnalyticsCollectionEnabled:NO persistSetting:YES]);
- OCMReject([configurationMock setAnalyticsCollectionEnabled:NO persistSetting:NO]);
- [app setDataCollectionDefaultEnabled:NO];
- }
- #pragma mark - Internal Methods
- - (void)testIsDefaultAppConfigured {
- // Ensure it's false before anything is configured.
- XCTAssertFalse([FIRApp isDefaultAppConfigured]);
- // Configure it and ensure it's configured.
- [FIRApp configure];
- XCTAssertTrue([FIRApp isDefaultAppConfigured]);
- // Reset the apps and ensure it's not configured anymore.
- [FIRApp resetApps];
- XCTAssertFalse([FIRApp isDefaultAppConfigured]);
- }
- - (void)testRegisterLibrary_InvalidLibraryName {
- NSString *originalFirebaseUserAgent = [FIRApp firebaseUserAgent];
- [FIRApp registerLibrary:@"Oops>" withVersion:@"1.0.0"];
- XCTAssertTrue([[FIRApp firebaseUserAgent] isEqualToString:originalFirebaseUserAgent]);
- }
- - (void)testRegisterLibrary_InvalidLibraryVersion {
- NSString *originalFirebaseUserAgent = [FIRApp firebaseUserAgent];
- [FIRApp registerLibrary:@"ValidName" withVersion:@"1.0.0+"];
- XCTAssertTrue([[FIRApp firebaseUserAgent] isEqualToString:originalFirebaseUserAgent]);
- }
- - (void)testRegisterLibrary_SingleLibrary {
- [FIRApp registerLibrary:@"ValidName" withVersion:@"1.0.0"];
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"ValidName/1.0.0"]);
- }
- - (void)testRegisterLibrary_MultipleLibraries {
- [FIRApp registerLibrary:@"ValidName" withVersion:@"1.0.0"];
- [FIRApp registerLibrary:@"ValidName2" withVersion:@"2.0.0"];
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"ValidName/1.0.0 ValidName2/2.0.0"]);
- }
- - (void)testRegisterLibrary_RegisteringConformingLibrary {
- Class testClass = [FIRTestClass class];
- [FIRApp registerInternalLibrary:testClass withName:@"ValidName" withVersion:@"1.0.0"];
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"ValidName/1.0.0"]);
- }
- - (void)testRegisterLibrary_RegisteringNonConformingLibrary {
- XCTAssertThrows([FIRApp registerInternalLibrary:[NSString class]
- withName:@"InvalidLibrary"
- withVersion:@"1.0.0"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"InvalidLibrary`/1.0.0"]);
- }
- - (void)testFirebaseUserAgent_SwiftFlagWithNoSwift {
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"swift/false"]);
- }
- - (void)testFirebaseUserAgent_ApplePlatformFlag {
- // When a Catalyst app is run on macOS then both `TARGET_OS_MACCATALYST` and `TARGET_OS_IOS` are
- // `true`.
- #if TARGET_OS_MACCATALYST
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/ios"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/tvos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/macos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/watchos"]);
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"apple-platform/maccatalyst"]);
- #elif TARGET_OS_IOS
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"apple-platform/ios"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/tvos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/macos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/watchos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/maccatalyst"]);
- #endif // TARGET_OS_MACCATALYST
- #if TARGET_OS_TV
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/ios"]);
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"apple-platform/tvos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/macos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/watchos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/maccatalyst"]);
- #endif // TARGET_OS_TV
- #if TARGET_OS_OSX
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/ios"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/tvos"]);
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"apple-platform/macos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/watchos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/maccatalyst"]);
- #endif // TARGET_OS_OSX
- #if TARGET_OS_WATCH
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/ios"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/tvos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/macos"]);
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:@"apple-platform/watchos"]);
- XCTAssertFalse([[FIRApp firebaseUserAgent] containsString:@"apple-platform/maccatalyst"]);
- #endif // TARGET_OS_WATCH
- }
- - (void)testFirebaseUserAgent_DeploymentType {
- #if SWIFT_PACKAGE
- NSString *deploymentType = @"swiftpm";
- #elif FIREBASE_BUILD_CARTHAGE
- NSString *deploymentType = @"carthage";
- #elif FIREBASE_BUILD_ZIP_FILE
- NSString *deploymentType = @"zip";
- #else
- NSString *deploymentType = @"cocoapods";
- #endif
- NSString *expectedComponent = [NSString stringWithFormat:@"deploy/%@", deploymentType];
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:expectedComponent]);
- }
- - (void)testFirebaseUserAgent_DeviceModel {
- NSString *expectedComponent =
- [NSString stringWithFormat:@"device/%@", [GULAppEnvironmentUtil deviceModel]];
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:expectedComponent]);
- }
- - (void)testFirebaseUserAgent_OSVersion {
- NSString *expectedComponent =
- [NSString stringWithFormat:@"os-version/%@", [GULAppEnvironmentUtil systemVersion]];
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:expectedComponent]);
- }
- - (void)testFirebaseUserAgent_IsFromAppStore {
- NSString *appStoreValue = [GULAppEnvironmentUtil isFromAppStore] ? @"true" : @"false";
- NSString *expectedComponent = [NSString stringWithFormat:@"appstore/%@", appStoreValue];
- XCTAssertTrue([[FIRApp firebaseUserAgent] containsString:expectedComponent]);
- }
- #pragma mark - Core Diagnostics
- - (void)testCoreDiagnosticsLoggedWhenAppDidBecomeActive {
- FIRApp *app = [self createConfiguredAppWithName:NSStringFromSelector(_cmd)];
- [self expectCoreDiagnosticsDataLogWithOptions:app.options];
- [self.notificationCenter postNotificationName:[self appDidBecomeActiveNotificationName]
- object:nil];
- OCMVerifyAllWithDelay(self.mockCoreDiagnosticsConnector, 0.5);
- }
- #pragma mark - private
- - (XCTestExpectation *)expectNotificationNamed:(NSNotificationName)name
- object:(nullable id)object
- userInfo:(NSDictionary *)userInfo {
- XCTestExpectation *notificationExpectation =
- [self expectationForNotification:name
- object:object
- notificationCenter:self.notificationCenter
- handler:^BOOL(NSNotification *_Nonnull notification) {
- return [userInfo isEqualToDictionary:notification.userInfo];
- }];
- return notificationExpectation;
- }
- - (NSDictionary<NSString *, NSObject *> *)expectedUserInfoWithAppName:(NSString *)name
- isDefaultApp:(BOOL)isDefaultApp {
- return @{
- kFIRAppNameKey : name,
- kFIRAppIsDefaultAppKey : [NSNumber numberWithBool:isDefaultApp],
- kFIRGoogleAppIDKey : kGoogleAppID
- };
- }
- - (void)expectCoreDiagnosticsDataLogWithOptions:(nullable FIROptions *)expectedOptions {
- [self.mockCoreDiagnosticsConnector stopMocking];
- self.mockCoreDiagnosticsConnector = nil;
- self.mockCoreDiagnosticsConnector = OCMClassMock([FIRCoreDiagnosticsConnector class]);
- OCMExpect(ClassMethod([self.mockCoreDiagnosticsConnector
- logCoreTelemetryWithOptions:[OCMArg checkWithBlock:^BOOL(FIROptions *options) {
- if (!expectedOptions) {
- return YES;
- }
- return [options.googleAppID isEqualToString:expectedOptions.googleAppID] &&
- [options.GCMSenderID isEqualToString:expectedOptions.GCMSenderID];
- }]]));
- }
- - (NSNotificationName)appDidBecomeActiveNotificationName {
- #if TARGET_OS_IOS || TARGET_OS_TV
- return UIApplicationDidBecomeActiveNotification;
- #endif
- #if TARGET_OS_OSX
- return NSApplicationDidBecomeActiveNotification;
- #endif
- }
- - (FIRApp *)createConfiguredAppWithName:(NSString *)name {
- FIROptions *options = [self appOptions];
- [FIRApp configureWithName:name options:options];
- return [FIRApp appNamed:name];
- }
- - (FIROptions *)appOptions {
- return [[FIROptions alloc] initWithGoogleAppID:kGoogleAppID GCMSenderID:kGCMSenderID];
- }
- - (void)registerLibrariesWithClasses:(NSArray<Class> *)classes {
- for (Class klass in classes) {
- [FIRApp registerInternalLibrary:klass withName:NSStringFromClass(klass) withVersion:@"1.0"];
- }
- }
- @end
|