@@ -558,6 +558,129 @@ - (void)testFetchConfigsFailed {
558558 }];
559559}
560560
561+ // TODO(mandard): Break up test with helper methods.
562+ - (void )testFetchConfigsFailedErrorNoNetwork {
563+ // Override the setup values to return back an error status.
564+ RCNConfigContent *configContent = [[RCNConfigContent alloc ] initWithDBManager: _DBManager];
565+ // Populate the default, second app, second namespace instances.
566+ for (int i = 0 ; i < RCNTestRCNumTotalInstances; i++) {
567+ NSString *currentAppName = nil ;
568+ FIROptions *currentOptions = nil ;
569+ NSString *currentNamespace = nil ;
570+ switch (i) {
571+ case RCNTestRCInstanceSecondNamespace:
572+ currentAppName = RCNTestsDefaultFIRAppName;
573+ currentOptions = [self firstAppOptions ];
574+ currentNamespace = RCNTestsPerfNamespace;
575+ break ;
576+ case RCNTestRCInstanceSecondApp:
577+ currentAppName = RCNTestsSecondFIRAppName;
578+ currentOptions = [self secondAppOptions ];
579+ currentNamespace = FIRNamespaceGoogleMobilePlatform;
580+ break ;
581+ case RCNTestRCInstanceDefault:
582+ default :
583+ currentAppName = RCNTestsDefaultFIRAppName;
584+ currentOptions = [self firstAppOptions ];
585+ currentNamespace = RCNTestsFIRNamespace;
586+ break ;
587+ }
588+ NSString *fullyQualifiedNamespace =
589+ [NSString stringWithFormat: @" %@ :%@ " , currentNamespace, currentAppName];
590+ RCNUserDefaultsManager *userDefaultsManager =
591+ [[RCNUserDefaultsManager alloc ] initWithAppName: currentAppName
592+ bundleID: [NSBundle mainBundle ].bundleIdentifier
593+ namespace: fullyQualifiedNamespace];
594+ userDefaultsManager.lastFetchTime = 0 ;
595+
596+ FIRRemoteConfig *config =
597+ OCMPartialMock ([[FIRRemoteConfig alloc ] initWithAppName: currentAppName
598+ FIROptions: currentOptions
599+ namespace: currentNamespace
600+ DBManager: _DBManager
601+ configContent: configContent
602+ analytics: nil ]);
603+
604+ _configInstances[i] = config;
605+ RCNConfigSettings *settings =
606+ [[RCNConfigSettings alloc ] initWithDatabaseManager: _DBManager
607+ namespace: fullyQualifiedNamespace
608+ firebaseAppName: currentAppName
609+ googleAppID: currentOptions.googleAppID];
610+ dispatch_queue_t queue = dispatch_queue_create (
611+ [[NSString stringWithFormat: @" testqueue: %d " , i] cStringUsingEncoding: NSUTF8StringEncoding],
612+ DISPATCH_QUEUE_SERIAL);
613+ _configFetch[i] = OCMPartialMock ([[RCNConfigFetch alloc ] initWithContent: configContent
614+ DBManager: _DBManager
615+ settings: settings
616+ analytics: nil
617+ experiment: nil
618+ queue: queue
619+ namespace: fullyQualifiedNamespace
620+ options: currentOptions]);
621+
622+ OCMStub ([_configFetch[i] fetchConfigWithExpirationDuration: 43200 completionHandler: OCMOCK_ANY])
623+ .andDo (^(NSInvocation *invocation) {
624+ void (^handler)(FIRRemoteConfigFetchStatus status, NSError *_Nullable error) = nil ;
625+ // void (^handler)(FIRRemoteConfigFetchCompletion);
626+ [invocation getArgument: &handler atIndex: 3 ];
627+ [_configFetch[i] fetchWithUserProperties: [[NSDictionary alloc ] init ]
628+ completionHandler: handler];
629+ });
630+
631+ _response[i] = @{};
632+
633+ _responseData[i] = [NSJSONSerialization dataWithJSONObject: _response[i] options: 0 error: nil ];
634+
635+ // A no network error is accompanied with an HTTP status code of 0.
636+ _URLResponse[i] =
637+ [[NSHTTPURLResponse alloc ] initWithURL: [NSURL URLWithString: @" https://firebase.com" ]
638+ statusCode: 0
639+ HTTPVersion: nil
640+ headerFields: @{@" etag" : @" etag1" }];
641+
642+ id completionBlock =
643+ [OCMArg invokeBlockWithArgs: _responseData[i], _URLResponse[i], [NSNull null ], nil ];
644+
645+ OCMExpect ([_configFetch[i] URLSessionDataTaskWithContent: [OCMArg any ]
646+ completionHandler: completionBlock])
647+ .andReturn (nil );
648+ [_configInstances[i] updateWithNewInstancesForConfigFetch: _configFetch[i]
649+ configContent: configContent
650+ configSettings: settings
651+ configExperiment: nil ];
652+ }
653+ #pragma clang diagnostic push
654+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
655+ // Make the fetch calls for all instances.
656+ NSMutableArray <XCTestExpectation *> *expectations =
657+ [[NSMutableArray alloc ] initWithCapacity: RCNTestRCNumTotalInstances];
658+
659+ for (int i = 0 ; i < RCNTestRCNumTotalInstances; i++) {
660+ expectations[i] = [self
661+ expectationWithDescription:
662+ [NSString stringWithFormat: @" Test enumerating configs successfully - instance %d " , i]];
663+ XCTAssertEqual (_configInstances[i].lastFetchStatus , FIRRemoteConfigFetchStatusNoFetchYet);
664+ FIRRemoteConfigFetchCompletion fetchCompletion =
665+ ^void (FIRRemoteConfigFetchStatus status, NSError *error) {
666+ XCTAssertEqual (_configInstances[i].lastFetchStatus , FIRRemoteConfigFetchStatusFailure);
667+ XCTAssertFalse ([_configInstances[i] activateFetched ]);
668+ XCTAssertNotNil (error);
669+ // No such key, still return a static value.
670+ FIRRemoteConfigValue *value = _configInstances[RCNTestRCInstanceDefault][@" key1" ];
671+ XCTAssertEqual ((int )value.source , (int )FIRRemoteConfigSourceStatic);
672+ XCTAssertEqualObjects (value.stringValue , @" " );
673+ XCTAssertEqual (value.boolValue , NO );
674+ [expectations[i] fulfill ];
675+ };
676+ [_configInstances[i] fetchWithExpirationDuration: 43200 completionHandler: fetchCompletion];
677+ }
678+ [self waitForExpectationsWithTimeout: _expectationTimeout
679+ handler: ^(NSError *error) {
680+ XCTAssertNil (error);
681+ }];
682+ }
683+
561684// Activate should return false if a fetch response returns 200 with NO_CHANGE as the response body.
562685- (void )testActivateOnFetchNoChangeStatus {
563686 // Override the setup values to return back an error status.
0 commit comments