Explorar o código

Only update experiments for firebase namespace (#7604)

* Only update experiments for firebase namespace

* Update tests

* Add changelog
karenyz %!s(int64=5) %!d(string=hai) anos
pai
achega
a67da04b64

+ 1 - 0
FirebaseRemoteConfig/CHANGELOG.md

@@ -1,5 +1,6 @@
 # Unreleased
 - [fixed] Store fetch metadata per namespace to address activation issues. (#7179)
+- [fixed] Only update experiment data for `firebase` namespace fetch requests to ensure correct experiment exposures. (#7604)
 
 # v7.7.0
 - [added] Added community support for watchOS. (#7481)

+ 7 - 3
FirebaseRemoteConfig/Sources/RCNConfigFetch.m

@@ -480,9 +480,13 @@ static const NSInteger sFIRErrorCodeConfigFailed = -114;
         // Update config content to cache and DB.
         [strongSelf->_content updateConfigContentWithResponse:fetchedConfig
                                                  forNamespace:strongSelf->_FIRNamespace];
-        // Update experiments.
-        [strongSelf->_experiment
-            updateExperimentsWithResponse:fetchedConfig[RCNFetchResponseKeyExperimentDescriptions]];
+        // Update experiments only for 3p namespace
+        NSString *namespace = [strongSelf->_FIRNamespace
+            substringToIndex:[strongSelf->_FIRNamespace rangeOfString:@":"].location];
+        if ([namespace isEqualToString:FIRNamespaceGoogleMobilePlatform]) {
+          [strongSelf->_experiment updateExperimentsWithResponse:
+                                       fetchedConfig[RCNFetchResponseKeyExperimentDescriptions]];
+        }
       } else {
         FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000063",
                     @"Empty response with no fetched config.");

+ 55 - 5
FirebaseRemoteConfig/Tests/Unit/RCNRemoteConfigTest.m

@@ -81,9 +81,9 @@
 
 typedef NS_ENUM(NSInteger, RCNTestRCInstance) {
   RCNTestRCInstanceDefault,
-  RCNTestRCNumTotalInstances,  // TODO(mandard): Remove once OCMock issue is resolved (#4877).
   RCNTestRCInstanceSecondNamespace,
   RCNTestRCInstanceSecondApp,
+  RCNTestRCNumTotalInstances
 };
 
 @interface RCNRemoteConfigTest : XCTestCase {
@@ -463,6 +463,54 @@ typedef NS_ENUM(NSInteger, RCNTestRCInstance) {
                                }];
 }
 
+- (void)testFetch3pNamespaceUpdatesExperiments {
+  [[_experimentMock expect] updateExperimentsWithResponse:[OCMArg any]];
+
+  XCTestExpectation *expectation = [self
+      expectationWithDescription:
+          [NSString
+              stringWithFormat:@"Fetch call for 'firebase' namespace updates experiment data"]];
+  XCTAssertEqual(_configInstances[RCNTestRCInstanceDefault].lastFetchStatus,
+                 FIRRemoteConfigFetchStatusNoFetchYet);
+  FIRRemoteConfigFetchCompletion fetchCompletion =
+      ^void(FIRRemoteConfigFetchStatus status, NSError *error) {
+        XCTAssertEqual(self->_configInstances[RCNTestRCInstanceDefault].lastFetchStatus,
+                       FIRRemoteConfigFetchStatusSuccess);
+        XCTAssertNil(error);
+        [expectation fulfill];
+      };
+  [_configInstances[RCNTestRCInstanceDefault] fetchWithExpirationDuration:43200
+                                                        completionHandler:fetchCompletion];
+  [self waitForExpectationsWithTimeout:_expectationTimeout
+                               handler:^(NSError *error) {
+                                 XCTAssertNil(error);
+                               }];
+}
+
+- (void)testFetchOtherNamespaceDoesntUpdateExperiments {
+  [[_experimentMock reject] updateExperimentsWithResponse:[OCMArg any]];
+
+  XCTestExpectation *expectation =
+      [self expectationWithDescription:
+                [NSString stringWithFormat:@"Fetch call for namespace other than 'firebase' "
+                                           @"doesn't update experiment data"]];
+  XCTAssertEqual(_configInstances[RCNTestRCInstanceSecondNamespace].lastFetchStatus,
+                 FIRRemoteConfigFetchStatusNoFetchYet);
+  FIRRemoteConfigFetchCompletion fetchCompletion =
+      ^void(FIRRemoteConfigFetchStatus status, NSError *error) {
+        XCTAssertEqual(self->_configInstances[RCNTestRCInstanceSecondNamespace].lastFetchStatus,
+                       FIRRemoteConfigFetchStatusSuccess);
+        XCTAssertNil(error);
+        [expectation fulfill];
+      };
+  [_configInstances[RCNTestRCInstanceSecondNamespace] fetchWithExpirationDuration:43200
+                                                                completionHandler:fetchCompletion];
+  [self waitForExpectationsWithTimeout:_expectationTimeout
+                               handler:^(NSError *error) {
+                                 XCTAssertNil(error);
+                               }];
+}
+
 - (void)testFetchConfigsFailed {
   // Override the setup values to return back an error status.
   RCNConfigContent *configContent = [[RCNConfigContent alloc] initWithDBManager:_DBManager];
@@ -1323,10 +1371,12 @@ static NSString *UTCToLocal(NSString *utcTime) {
 }
 
 - (FIROptions *)secondAppOptions {
-  FIROptions *options =
-      [[FIROptions alloc] initWithContentsOfFile:[[NSBundle bundleForClass:[self class]]
-                                                     pathForResource:@"SecondApp-GoogleService-Info"
-                                                              ofType:@"plist"]];
+  NSBundle *bundle = [NSBundle bundleForClass:[self class]];
+#if SWIFT_PACKAGE
+  bundle = Firebase_RemoteConfigUnit_SWIFTPM_MODULE_BUNDLE();
+#endif
+  NSString *plistPath = [bundle pathForResource:@"SecondApp-GoogleService-Info" ofType:@"plist"];
+  FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:plistPath];
   XCTAssertNotNil(options);
   return options;
 }