From f0b0b7f4a0d08c22e82afb2b466093c6397f5a2c Mon Sep 17 00:00:00 2001 From: Dana Silver Date: Tue, 1 Dec 2020 13:29:53 -0800 Subject: [PATCH] Check for missing metadata when constructing ConfigContainer. --- .../internal/ConfigContainer.java | 9 ++++- .../internal/ConfigStorageClientTest.java | 33 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigContainer.java b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigContainer.java index 5e9d44e25ee..d7d7d690844 100644 --- a/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigContainer.java +++ b/firebase-config/src/main/java/com/google/firebase/remoteconfig/internal/ConfigContainer.java @@ -86,11 +86,18 @@ private ConfigContainer( *

The {@code containerJson} must not be modified. */ static ConfigContainer copyOf(JSONObject containerJson) throws JSONException { + // Personalization metadata may not have been written yet. + JSONObject personalizationMetadataJSON = + containerJson.optJSONObject(PERSONALIZATION_METADATA_KEY); + if (personalizationMetadataJSON == null) { + personalizationMetadataJSON = new JSONObject(); + } + return new ConfigContainer( containerJson.getJSONObject(CONFIGS_KEY), new Date(containerJson.getLong(FETCH_TIME_KEY)), containerJson.getJSONArray(ABT_EXPERIMENTS_KEY), - containerJson.getJSONObject(PERSONALIZATION_METADATA_KEY)); + personalizationMetadataJSON); } /** diff --git a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigStorageClientTest.java b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigStorageClientTest.java index dd29a2b99ea..07f7acdf025 100644 --- a/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigStorageClientTest.java +++ b/firebase-config/src/test/java/com/google/firebase/remoteconfig/internal/ConfigStorageClientTest.java @@ -23,8 +23,11 @@ import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.Date; +import org.json.JSONObject; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -82,6 +85,36 @@ public void read_validContainer_returnsContainer() throws Exception { assertThat(container).isEqualTo(configContainer); } + @Test + public void read_validContainerWithPersonalization_returnsContainer() throws Exception { + ConfigContainer configWithPersonalization = + ConfigContainer.newBuilder(configContainer) + .withPersonalizationMetadata( + new JSONObject(ImmutableMap.of(Personalization.ARM_KEY, "arm_value"))) + .build(); + storageClient.write(configWithPersonalization); + Preconditions.checkArgument(getFileAsString().equals(configWithPersonalization.toString())); + + ConfigContainer container = storageClient.read(); + assertThat(container).isEqualTo(configWithPersonalization); + } + + @Test + public void read_validContainerWithoutPersonalization_returnsContainer() throws Exception { + // Configs written by SDK versions <20.0.1 do not contain personalization metadata. + // Since the serialized configContainer contains personalization metadata, we manually remove it + // and write the config to disk directly to test. + JSONObject configJSON = new JSONObject(configContainer.toString()); + configJSON.remove(ConfigContainer.PERSONALIZATION_METADATA_KEY); + + try (FileOutputStream outputStream = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE)) { + outputStream.write(configJSON.toString().getBytes(StandardCharsets.UTF_8)); + } + + ConfigContainer container = storageClient.read(); + assertThat(container).isEqualTo(configContainer); + } + @Test public void read_emptyFile_returnsNull() throws Exception { ConfigContainer container = storageClient.read();