diff --git a/FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h b/FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h index 26b82172681..9530dee817c 100644 --- a/FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h +++ b/FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h @@ -55,11 +55,6 @@ /// Custom variable (aka App context digest). This is the pending custom variables request before /// fetching. @property(nonatomic, copy) NSDictionary *customVariables; -/// Cached internal metadata from internal metadata table. It contains customized information such -/// as HTTP connection timeout, HTTP read timeout, success/failure throttling rate and time -/// interval. Client has the default value of each parameters, they are only saved in -/// internalMetadata if they have been customize by developers. -@property(nonatomic, readonly, copy) NSDictionary *internalMetadata; /// Device conditions since last successful fetch from the backend. Device conditions including /// app /// version, iOS version, device localte, language, GMP project ID and Game project ID. Used for @@ -122,9 +117,6 @@ /// Returns metadata from metadata table. - (NSDictionary *)loadConfigFromMetadataTable; -/// Updates internal content with the latest successful config response. -- (void)updateInternalContentWithResponse:(NSDictionary *)response; - /// Updates the metadata table with the current fetch status. /// @param fetchSuccess True if fetch was successful. - (void)updateMetadataWithFetchSuccessStatus:(BOOL)fetchSuccess diff --git a/FirebaseRemoteConfig/Sources/RCNConfigDBManager.h b/FirebaseRemoteConfig/Sources/RCNConfigDBManager.h index 97ca03af6e7..e22b40d3779 100644 --- a/FirebaseRemoteConfig/Sources/RCNConfigDBManager.h +++ b/FirebaseRemoteConfig/Sources/RCNConfigDBManager.h @@ -70,10 +70,6 @@ typedef void (^RCNDBLoadCompletion)(BOOL success, /// start. Config settings include success/failure fetch times, device contenxt, app context, etc. - (NSDictionary *)loadMetadataWithBundleIdentifier:(NSString *)bundleIdentifier namespace:(NSString *)namespace; -/// Load internal metadata from internal metadata table, such as customized HTTP connection/read -/// timeout, throttling time interval and number limit of throttling, etc. -/// This call needs to be blocking to ensure throttling works during apps starts. -- (NSDictionary *)loadInternalMetadataTable; /// Load experiment from experiment table. /// @param handler The callback when reading from DB is complete. - (void)loadExperimentWithCompletionHandler:(RCNDBCompletion)handler; @@ -90,10 +86,6 @@ typedef void (^RCNDBLoadCompletion)(BOOL success, - (void)insertMainTableWithValues:(NSArray *)values fromSource:(RCNDBSource)source completionHandler:(RCNDBCompletion)handler; -/// Insert a record in internal metadata table. -/// @param values Values to be inserted. -- (void)insertInternalMetadataTableWithValues:(NSArray *)values - completionHandler:(RCNDBCompletion)handler; /// Insert experiment data in experiment table. /// @param key The key of experiment data belongs to, which are defined in /// RCNConfigDefines.h. @@ -125,11 +117,10 @@ typedef void (^RCNDBLoadCompletion)(BOOL success, - (void)deleteRecordFromMainTableWithNamespace:(NSString *)namespace_p bundleIdentifier:(NSString *)bundleIdentifier fromSource:(RCNDBSource)source; -/// Remove all the records of given package name and namespace from metadata/internal metadata DB +/// Remove all the records of given package name and namespace from metadata DB /// before updating new values from response. - (void)deleteRecordWithBundleIdentifier:(NSString *)bundlerIdentifier - namespace:(NSString *)namespace - isInternalDB:(BOOL)isInternalDB; + namespace:(NSString *)namespace; /// Remove all the records from a config content table. - (void)deleteAllRecordsFromTableWithSource:(RCNDBSource)source; diff --git a/FirebaseRemoteConfig/Sources/RCNConfigDBManager.m b/FirebaseRemoteConfig/Sources/RCNConfigDBManager.m index 57ee0258515..161f678b8d6 100644 --- a/FirebaseRemoteConfig/Sources/RCNConfigDBManager.m +++ b/FirebaseRemoteConfig/Sources/RCNConfigDBManager.m @@ -28,7 +28,6 @@ #define RCNTableNameMainDefault "main_default" #define RCNTableNameMetadataDeprecated "fetch_metadata" #define RCNTableNameMetadata "fetch_metadata_v2" -#define RCNTableNameInternalMetadata "internal_metadata" #define RCNTableNameExperiment "experiment" #define RCNTableNamePersonalization "personalization" #define RCNTableNameRollout "rollout" @@ -278,10 +277,6 @@ - (BOOL)createTableSchema { "success_fetch_time BLOB, failure_fetch_time BLOB, last_fetch_status INTEGER, " "last_fetch_error INTEGER, last_apply_time INTEGER, last_set_defaults_time INTEGER)"; - static const char *createTableInternalMetadata = - "create TABLE IF NOT EXISTS " RCNTableNameInternalMetadata - " (_id INTEGER PRIMARY KEY, key TEXT, value BLOB)"; - static const char *createTableExperiment = "create TABLE IF NOT EXISTS " RCNTableNameExperiment " (_id INTEGER PRIMARY KEY, key TEXT, value BLOB)"; static const char *createTablePersonalization = @@ -293,7 +288,6 @@ - (BOOL)createTableSchema { return [self executeQuery:createTableMain] && [self executeQuery:createTableMainActive] && [self executeQuery:createTableMainDefault] && [self executeQuery:createTableMetadata] && - [self executeQuery:createTableInternalMetadata] && [self executeQuery:createTableExperiment] && [self executeQuery:createTablePersonalization] && [self executeQuery:createTableRollout]; } @@ -471,48 +465,6 @@ - (BOOL)insertMainTableWithValues:(NSArray *)values fromSource:(RCNDBSource)sour return YES; } -- (void)insertInternalMetadataTableWithValues:(NSArray *)values - completionHandler:(RCNDBCompletion)handler { - __weak RCNConfigDBManager *weakSelf = self; - dispatch_async(_databaseOperationQueue, ^{ - BOOL success = [weakSelf insertInternalMetadataWithValues:values]; - if (handler) { - dispatch_async(dispatch_get_main_queue(), ^{ - handler(success, nil); - }); - } - }); -} - -- (BOOL)insertInternalMetadataWithValues:(NSArray *)values { - RCN_MUST_NOT_BE_MAIN_THREAD(); - if (values.count != 2) { - return NO; - } - const char *SQL = - "INSERT OR REPLACE INTO " RCNTableNameInternalMetadata " (key, value) values (?, ?)"; - sqlite3_stmt *statement = [self prepareSQL:SQL]; - if (!statement) { - return NO; - } - NSString *aString = values[0]; - if (![self bindStringToStatement:statement index:1 string:aString]) { - [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; - return NO; - } - NSData *blobData = values[1]; - if (sqlite3_bind_blob(statement, 2, blobData.bytes, (int)blobData.length, NULL) != SQLITE_OK) { - [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; - return NO; - } - if (sqlite3_step(statement) != SQLITE_DONE) { - [self logErrorWithSQL:SQL finalizeStatement:statement returnValue:NO]; - return NO; - } - sqlite3_finalize(statement); - return YES; -} - - (void)insertExperimentTableWithKey:(NSString *)key value:(NSData *)serializedValue completionHandler:(RCNDBCompletion)handler { @@ -1039,34 +991,6 @@ - (NSData *)loadPersonalizationTableFromKey:(int)key { return results[0]; } -- (NSDictionary *)loadInternalMetadataTable { - __block NSMutableDictionary *internalMetadataTableResult; - __weak RCNConfigDBManager *weakSelf = self; - dispatch_sync(_databaseOperationQueue, ^{ - internalMetadataTableResult = [weakSelf loadInternalMetadataTableInternal]; - }); - return internalMetadataTableResult; -} - -- (NSMutableDictionary *)loadInternalMetadataTableInternal { - NSMutableDictionary *internalMetadata = [[NSMutableDictionary alloc] init]; - const char *SQL = "SELECT key, value FROM " RCNTableNameInternalMetadata; - sqlite3_stmt *statement = [self prepareSQL:SQL]; - if (!statement) { - return nil; - } - - while (sqlite3_step(statement) == SQLITE_ROW) { - NSString *key = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(statement, 0)]; - - NSData *dataValue = [NSData dataWithBytes:(char *)sqlite3_column_blob(statement, 1) - length:sqlite3_column_bytes(statement, 1)]; - internalMetadata[key] = dataValue; - } - sqlite3_finalize(statement); - return internalMetadata; -} - /// This method is only meant to be called at init time. The underlying logic will need to be /// reevaluated if the assumption changes at a later time. - (void)loadMainWithBundleIdentifier:(NSString *)bundleIdentifier @@ -1178,20 +1102,16 @@ - (void)deleteRecordFromMainTableWithNamespace:(NSString *)namespace_p } - (void)deleteRecordWithBundleIdentifier:(NSString *)bundleIdentifier - namespace:(NSString *)namespace - isInternalDB:(BOOL)isInternalDB { + namespace:(NSString *)namespace { __weak RCNConfigDBManager *weakSelf = self; dispatch_async(_databaseOperationQueue, ^{ RCNConfigDBManager *strongSelf = weakSelf; if (!strongSelf) { return; } - const char *SQL = "DELETE FROM " RCNTableNameInternalMetadata " WHERE key LIKE ?"; - NSArray *params = @[ bundleIdentifier ]; - if (!isInternalDB) { - SQL = "DELETE FROM " RCNTableNameMetadata " WHERE bundle_identifier = ? and namespace = ?"; - params = @[ bundleIdentifier, namespace ]; - } + const char *SQL = + "DELETE FROM " RCNTableNameMetadata " WHERE bundle_identifier = ? and namespace = ?"; + NSArray *params = @[ bundleIdentifier, namespace ]; [strongSelf executeQuery:SQL withParams:params]; }); } diff --git a/FirebaseRemoteConfig/Sources/RCNConfigSettings.m b/FirebaseRemoteConfig/Sources/RCNConfigSettings.m index 48e414e2f83..69848f872f7 100644 --- a/FirebaseRemoteConfig/Sources/RCNConfigSettings.m +++ b/FirebaseRemoteConfig/Sources/RCNConfigSettings.m @@ -45,11 +45,6 @@ @interface RCNConfigSettings () { /// Custom variables (aka App context digest). This is the pending custom variables request before /// fetching. NSMutableDictionary *_customVariables; - /// Cached internal metadata from internal metadata table. It contains customized information such - /// as HTTP connection timeout, HTTP read timeout, success/failure throttling rate and time - /// interval. Client has the default value of each parameters, they are only saved in - /// internalMetadata if they have been customize by developers. - NSMutableDictionary *_internalMetadata; /// Last fetch status. FIRRemoteConfigFetchStatus _lastFetchStatus; /// Last fetch Error. @@ -66,8 +61,6 @@ @interface RCNConfigSettings () { NSString *_googleAppID; /// The user defaults manager scoped to this RC instance of FIRApp and namespace. RCNUserDefaultsManager *_userDefaultsManager; - /// The timestamp of last eTag update. - NSTimeInterval _lastETagUpdateTime; } @end @@ -93,11 +86,6 @@ - (instancetype)initWithDatabaseManager:(RCNConfigDBManager *)manager _successFetchTimes = [[NSMutableArray alloc] init]; _failureFetchTimes = [[NSMutableArray alloc] init]; _DBManager = manager; - - _internalMetadata = [[_DBManager loadInternalMetadataTable] mutableCopy]; - if (!_internalMetadata) { - _internalMetadata = [[NSMutableDictionary alloc] init]; - } _userDefaultsManager = [[RCNUserDefaultsManager alloc] initWithAppName:appName bundleID:_bundleIdentifier namespace:_FIRNamespace]; @@ -184,32 +172,6 @@ - (NSDictionary *)loadConfigFromMetadataTable { } #pragma mark - update DB/cached - -// Update internal metadata content to cache and DB. -- (void)updateInternalContentWithResponse:(NSDictionary *)response { - // Remove all the keys with current package name. - [_DBManager deleteRecordWithBundleIdentifier:_bundleIdentifier - namespace:_FIRNamespace - isInternalDB:YES]; - - for (NSString *key in _internalMetadata.allKeys) { - if ([key hasPrefix:_bundleIdentifier]) { - [_internalMetadata removeObjectForKey:key]; - } - } - - for (NSString *entry in response) { - NSData *val = [response[entry] dataUsingEncoding:NSUTF8StringEncoding]; - NSArray *values = @[ entry, val ]; - _internalMetadata[entry] = response[entry]; - [self updateInternalMetadataTableWithValues:values]; - } -} - -- (void)updateInternalMetadataTableWithValues:(NSArray *)values { - [_DBManager insertInternalMetadataTableWithValues:values completionHandler:nil]; -} - /// If the last fetch was not successful, update the (exponential backoff) period that we wait until /// fetching again. Any subsequent fetch requests will be checked and allowed only if past this /// throttle end time. @@ -310,9 +272,7 @@ - (void)updateFetchTimeWithSuccessFetch:(BOOL)isSuccessfulFetch { } - (void)updateMetadataTable { - [_DBManager deleteRecordWithBundleIdentifier:_bundleIdentifier - namespace:_FIRNamespace - isInternalDB:NO]; + [_DBManager deleteRecordWithBundleIdentifier:_bundleIdentifier namespace:_FIRNamespace]; NSError *error; // Objects to be serialized cannot be invalid. if (!_bundleIdentifier) { @@ -472,10 +432,6 @@ - (NSDictionary *)customVariables { return [_customVariables copy]; } -- (NSDictionary *)internalMetadata { - return [_internalMetadata copy]; -} - - (NSDictionary *)deviceContext { return [_deviceContext copy]; } diff --git a/FirebaseRemoteConfig/Tests/Unit/RCNConfigDBManagerTest.m b/FirebaseRemoteConfig/Tests/Unit/RCNConfigDBManagerTest.m index 773af690935..09c577346bb 100644 --- a/FirebaseRemoteConfig/Tests/Unit/RCNConfigDBManagerTest.m +++ b/FirebaseRemoteConfig/Tests/Unit/RCNConfigDBManagerTest.m @@ -155,39 +155,6 @@ - (void)testWriteAndLoadMainTableResult { }]; } -- (void)testWriteAndLoadInternalMetadataResult { - XCTestExpectation *loadConfigContentExpectation = [self - expectationWithDescription:@"Write and read internal metadata in database successfully"]; - __block int count = 0; - for (int i = 0; i <= 100; ++i) { - // check DB write correctly - RCNDBCompletion insertCompletion = ^void(BOOL success, NSDictionary *result) { - count++; - XCTAssertTrue(success); - if (count == 100) { - // check DB read correctly - NSDictionary *result = [self->_DBManager loadInternalMetadataTable]; - NSString *stringValue = [[NSString alloc] initWithData:result[@"key100"] - encoding:NSUTF8StringEncoding]; - XCTAssertEqualObjects(stringValue, @"value100"); - if (success) { - [loadConfigContentExpectation fulfill]; - } - } - }; - NSString *value = [NSString stringWithFormat:@"value%d", i]; - NSString *key = [NSString stringWithFormat:@"key%d", i]; - - NSArray *values = @[ key, [value dataUsingEncoding:NSUTF8StringEncoding] ]; - [_DBManager insertInternalMetadataTableWithValues:values completionHandler:insertCompletion]; - } - - [self waitForExpectationsWithTimeout:_expectionTimeout - handler:^(NSError *error) { - XCTAssertNil(error); - }]; -} - - (void)testWriteAndLoadMetadataResult { XCTestExpectation *writeAndLoadMetadataExpectation = [self expectationWithDescription:@"Write and load metadata in database successfully"]; diff --git a/FirebaseRemoteConfig/Tests/Unit/RCNConfigSettingsTest.m b/FirebaseRemoteConfig/Tests/Unit/RCNConfigSettingsTest.m index a5ed22a8bb6..045e0cdf247 100644 --- a/FirebaseRemoteConfig/Tests/Unit/RCNConfigSettingsTest.m +++ b/FirebaseRemoteConfig/Tests/Unit/RCNConfigSettingsTest.m @@ -25,7 +25,6 @@ @interface RCNConfigSettings (ExposedTestCase) - (RCNConfigFetchRequest *)nextRequestWithUserProperties:(NSDictionary *)userProperties fetchedConfig:(NSDictionary *)fetchedConfig; -- (void)updateInternalContentWithResponse:(RCNConfigFetchResponse *)response; - (void)updateConfigContentWithResponse:(RCNConfigFetchResponse *)response; - (void)updateFetchTimeWithSuccessFetch:(BOOL)isSuccessfulFetch; - (BOOL)hasCachedData; @@ -54,170 +53,6 @@ - (void)testCrashShouldNotHappenWithoutMainBundleID { } #ifdef FIX_OR_DELETE -- (void)testUpdateInternalMetadata { - RCNConfigFetchResponse *response = [[RCNConfigFetchResponse alloc] init]; - // Mock internal metadata array with all_packages prefix key - response.internalMetadataArray = [RCNTestUtilities entryArrayWithKeyValuePair:@{ - [NSString stringWithFormat:@"%@:%@", RCNInternalMetadataAllPackagesPrefix, - RCNHTTPConnectionTimeoutInMillisecondsKey] : @"50", - [NSString stringWithFormat:@"%@:%@", RCNInternalMetadataAllPackagesPrefix, - RCNHTTPReadTimeoutInMillisecondsKey] : @"2000000", - [NSString stringWithFormat:@"%@:%@", RCNInternalMetadataAllPackagesPrefix, - RCNThrottledSuccessFetchTimeIntervalInSecondsKey] : @"300", - [NSString stringWithFormat:@"%@:%@", RCNInternalMetadataAllPackagesPrefix, - RCNThrottledSuccessFetchCountKey] : @"-6", - [NSString stringWithFormat:@"%@:%@", RCNInternalMetadataAllPackagesPrefix, - RCNThrottledFailureFetchTimeIntervalInSecondsKey] : @"10000000", - [NSString stringWithFormat:@"%@:%@", RCNInternalMetadataAllPackagesPrefix, - RCNThrottledFailureFetchCountKey] : @"21", - - }]; - [_mockSettings updateInternalContentWithResponse:response]; - XCTAssertEqual( - [_mockSettings internalMetadataValueForKey:RCNHTTPConnectionTimeoutInMillisecondsKey - minValue:RCNHTTPConnectionTimeoutInMillisecondsMin - maxValue:RCNHTTPConnectionTimeoutInMillisecondsMax - defaultValue:RCNHTTPConnectionTimeoutInMillisecondsDefault], - RCNHTTPConnectionTimeoutInMillisecondsMin, - @"HTTP Connection Timeout must be within the range."); - XCTAssertEqual( - [_mockSettings internalMetadataValueForKey:RCNHTTPReadTimeoutInMillisecondsKey - minValue:RCNHTTPReadTimeoutInMillisecondsMin - maxValue:RCNHTTPReadTimeoutInMillisecondsMax - defaultValue:RCNHTTPReadTimeoutInMillisecondsDefault], - RCNHTTPReadTimeoutInMillisecondsMax, @"HTTP Read Timeout must be within the range"); - XCTAssertEqual( - [_mockSettings - internalMetadataValueForKey:RCNThrottledSuccessFetchTimeIntervalInSecondsKey - minValue:RCNThrottledSuccessFetchTimeIntervalInSecondsMin - maxValue:RCNThrottledSuccessFetchTimeIntervalInSecondsMax - defaultValue:RCNThrottledSuccessFetchTimeIntervalInSecondsDefault], - RCNThrottledSuccessFetchTimeIntervalInSecondsMin, - @"Throttling success internal must be within the range"); - XCTAssertEqual([_mockSettings internalMetadataValueForKey:RCNThrottledSuccessFetchCountKey - minValue:RCNThrottledSuccessFetchCountMin - maxValue:RCNThrottledSuccessFetchCountMax - defaultValue:RCNThrottledSuccessFetchCountDefault], - RCNThrottledSuccessFetchCountMin); - XCTAssertEqual( - [_mockSettings - internalMetadataValueForKey:RCNThrottledFailureFetchTimeIntervalInSecondsKey - minValue:RCNThrottledFailureFetchTimeIntervalInSecondsMin - maxValue:RCNThrottledFailureFetchTimeIntervalInSecondsMax - defaultValue:RCNThrottledFailureFetchTimeIntervalInSecondsDefault], - RCNThrottledFailureFetchTimeIntervalInSecondsMax); - XCTAssertEqual([_mockSettings internalMetadataValueForKey:RCNThrottledFailureFetchCountKey - minValue:RCNThrottledFailureFetchCountMin - maxValue:RCNThrottledFailureFetchCountMax - defaultValue:RCNThrottledFailureFetchCountDefault], - RCNThrottledFailureFetchCountMax); - - // Mock internal metadata array with bundle_identifier prefix key. - // bundle_identifier prefixed key should override all_packages prefix key - NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier]; - response.internalMetadataArray = [RCNTestUtilities entryArrayWithKeyValuePair:@{ - [NSString stringWithFormat:@"%@:%@", bundleIdentifier, - RCNHTTPConnectionTimeoutInMillisecondsKey] : @"70000", - [NSString stringWithFormat:@"%@:%@", bundleIdentifier, RCNHTTPReadTimeoutInMillisecondsKey] : - @"70000", - [NSString stringWithFormat:@"%@:%@", bundleIdentifier, - RCNThrottledSuccessFetchTimeIntervalInSecondsKey] : @"1800", - [NSString stringWithFormat:@"%@:%@", bundleIdentifier, RCNThrottledSuccessFetchCountKey] : - @"100", - [NSString stringWithFormat:@"%@:%@", bundleIdentifier, - RCNThrottledFailureFetchTimeIntervalInSecondsKey] : @"1800", - [NSString stringWithFormat:@"%@:%@", bundleIdentifier, RCNThrottledFailureFetchCountKey] : @"0", - }]; - [_mockSettings updateInternalContentWithResponse:response]; - - XCTAssertEqual( - [_mockSettings internalMetadataValueForKey:RCNHTTPConnectionTimeoutInMillisecondsKey - minValue:RCNHTTPConnectionTimeoutInMillisecondsMin - maxValue:RCNHTTPConnectionTimeoutInMillisecondsMax - defaultValue:RCNHTTPConnectionTimeoutInMillisecondsDefault], - 70000); - XCTAssertEqual( - [_mockSettings internalMetadataValueForKey:RCNHTTPReadTimeoutInMillisecondsKey - minValue:RCNHTTPReadTimeoutInMillisecondsMin - maxValue:RCNHTTPReadTimeoutInMillisecondsMax - defaultValue:RCNHTTPReadTimeoutInMillisecondsDefault], - 70000); - XCTAssertEqual( - [_mockSettings - internalMetadataValueForKey:RCNThrottledSuccessFetchTimeIntervalInSecondsKey - minValue:RCNThrottledSuccessFetchTimeIntervalInSecondsMin - maxValue:RCNThrottledSuccessFetchTimeIntervalInSecondsMax - defaultValue:RCNThrottledSuccessFetchTimeIntervalInSecondsDefault], - 1800); - XCTAssertEqual([_mockSettings internalMetadataValueForKey:RCNThrottledSuccessFetchCountKey - minValue:RCNThrottledSuccessFetchCountMin - maxValue:RCNThrottledSuccessFetchCountMax - defaultValue:RCNThrottledSuccessFetchCountDefault], - 20); - - XCTAssertEqual( - [_mockSettings - internalMetadataValueForKey:RCNThrottledFailureFetchTimeIntervalInSecondsKey - minValue:RCNThrottledFailureFetchTimeIntervalInSecondsMin - maxValue:RCNThrottledFailureFetchTimeIntervalInSecondsMax - defaultValue:RCNThrottledFailureFetchTimeIntervalInSecondsDefault], - 1800); - XCTAssertEqual([_mockSettings internalMetadataValueForKey:RCNThrottledFailureFetchCountKey - minValue:RCNThrottledFailureFetchCountMin - maxValue:RCNThrottledFailureFetchCountMax - defaultValue:RCNThrottledFailureFetchCountDefault], - 1); -} - -- (void)testInternalMetadataOverride { - // Mock response after fetching. - RCNConfigFetchResponse *response = [[RCNConfigFetchResponse alloc] init]; - NSString *onePackageKey = - [NSString stringWithFormat:@"%@:%@", [[NSBundle mainBundle] bundleIdentifier], - RCNThrottledSuccessFetchCountKey]; - NSString *allPackageKey = - [NSString stringWithFormat:@"%@:%@", RCNInternalMetadataAllPackagesPrefix, - RCNThrottledSuccessFetchCountKey]; - - [_mockSettings updateInternalContentWithResponse:response]; - XCTAssertEqual([_mockSettings internalMetadataValueForKey:RCNThrottledSuccessFetchCountKey - minValue:RCNThrottledSuccessFetchCountMin - maxValue:RCNThrottledSuccessFetchCountMax - defaultValue:RCNThrottledSuccessFetchCountDefault], - RCNThrottledSuccessFetchCountDefault, - @"Fetch with no internal metadata, must return default value."); - - response.internalMetadataArray = - [RCNTestUtilities entryArrayWithKeyValuePair:@{onePackageKey : @"8", allPackageKey : @"9"}]; - [_mockSettings updateInternalContentWithResponse:response]; - XCTAssertEqual([_mockSettings internalMetadataValueForKey:RCNThrottledSuccessFetchCountKey - minValue:RCNThrottledSuccessFetchCountMin - maxValue:RCNThrottledSuccessFetchCountMax - defaultValue:RCNThrottledSuccessFetchCountDefault], - 8, @"Fetch with both keys, must return the one with package key."); - - [response.internalMetadataArray removeAllObjects]; - [_mockSettings updateInternalContentWithResponse:response]; - XCTAssertEqual( - [_mockSettings internalMetadataValueForKey:RCNThrottledSuccessFetchCountKey - minValue:RCNThrottledSuccessFetchCountMin - maxValue:RCNThrottledSuccessFetchCountMax - defaultValue:RCNThrottledSuccessFetchCountDefault], - 9, @"Fetch with no internal metadata, must return the one with previous all_packages key."); - - [response.internalMetadataArray removeAllObjects]; - response.internalMetadataArray = [RCNTestUtilities entryArrayWithKeyValuePair:@{ - onePackageKey : @"6", - }]; - - [_mockSettings updateInternalContentWithResponse:response]; - XCTAssertEqual([_mockSettings internalMetadataValueForKey:RCNThrottledSuccessFetchCountKey - minValue:RCNThrottledSuccessFetchCountMin - maxValue:RCNThrottledSuccessFetchCountMax - defaultValue:RCNThrottledSuccessFetchCountDefault], - 6, @"Fetch with one package key, must return the one with package key."); -} - - (void)testThrottlingFresh { NSTimeInterval endTimestamp = [_mockSettings cachedDataThrottledEndTimestamp]; NSTimeInterval now = [[NSDate date] timeIntervalSince1970];