From 486e84138b6d79e686627c1076226bb1cf58bfaa Mon Sep 17 00:00:00 2001 From: Athira M Date: Thu, 7 Aug 2025 22:48:22 +0530 Subject: [PATCH 01/21] Handle empty context --- .../remoteconfig/ServerTemplateImpl.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java index c85fa160..6d3d675d 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java @@ -20,6 +20,7 @@ import com.google.api.core.ApiFutures; import com.google.common.collect.ImmutableMap; import com.google.firebase.ErrorCode; +import com.google.firebase.internal.Nullable; import com.google.firebase.remoteconfig.internal.TemplateResponse.ParameterValueResponse; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -78,10 +79,11 @@ private ServerTemplateImpl(Builder builder) { } @Override - public ServerConfig evaluate(KeysAndValues context) throws FirebaseRemoteConfigException { + public ServerConfig evaluate(@Nullable KeysAndValues context) + throws FirebaseRemoteConfigException { if (this.cache == null) { throw new FirebaseRemoteConfigException(ErrorCode.FAILED_PRECONDITION, - "No Remote Config Server template in cache. Call load() before calling evaluate()."); + "No Remote Config Server template in cache. Call load() before calling evaluate()."); } Map configValues = new HashMap<>(); @@ -93,8 +95,11 @@ public ServerConfig evaluate(KeysAndValues context) throws FirebaseRemoteConfigE } ConditionEvaluator conditionEvaluator = new ConditionEvaluator(); - ImmutableMap evaluatedCondition = ImmutableMap.copyOf( - conditionEvaluator.evaluateConditions(cache.getServerConditions(), context)); + ImmutableMap evaluatedCondition = + context != null && !cache.getServerConditions().isEmpty() + ? ImmutableMap.copyOf( + conditionEvaluator.evaluateConditions(cache.getServerConditions(), context)) + : ImmutableMap.of(); ImmutableMap parameters = ImmutableMap.copyOf(cache.getParameters()); mergeDerivedConfigValues(evaluatedCondition, parameters, configValues); @@ -103,8 +108,7 @@ public ServerConfig evaluate(KeysAndValues context) throws FirebaseRemoteConfigE @Override public ServerConfig evaluate() throws FirebaseRemoteConfigException { - KeysAndValues context = new KeysAndValues.Builder().build(); - return evaluate(context); + return evaluate(null); } @Override From 91acd60ca8fb06316b53e1270fa4af0467967994 Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Fri, 8 Aug 2025 17:19:09 +0530 Subject: [PATCH 02/21] fix issue related to update time --- .../firebase/remoteconfig/ServerVersion.java | 212 ++++++++++++++++++ .../remoteconfig/ServerVersionTest.java | 99 ++++++++ 2 files changed, 311 insertions(+) create mode 100644 src/main/java/com/google/firebase/remoteconfig/ServerVersion.java create mode 100644 src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java b/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java new file mode 100644 index 00000000..9db70a75 --- /dev/null +++ b/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java @@ -0,0 +1,212 @@ +/* + * Copyright 2020 Google LLC + * + * 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. + */ + +package com.google.firebase.remoteconfig; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.firebase.internal.NonNull; +import com.google.firebase.internal.Nullable; +import com.google.firebase.remoteconfig.internal.TemplateResponse; +import com.google.firebase.remoteconfig.internal.TemplateResponse.VersionResponse; + +import java.util.Objects; + +/** + * Represents a Server Remote Config template version. + * Output only, except for the version description. Contains metadata about a particular + * version of the Remote Config template. All fields are set at the time the specified Remote + * Config template is published. A version's description field may be specified when + * publishing a template. + */ +public final class ServerVersion { + + private final String versionNumber; + private final String updateTime; + private final String updateOrigin; + private final String updateType; + private final User updateUser; + private final String rollbackSource; + private final boolean legacy; + private String description; + + private ServerVersion() { + this.versionNumber = null; + this.updateTime = null; + this.updateOrigin = null; + this.updateType = null; + this.updateUser = null; + this.rollbackSource = null; + this.legacy = false; + } + + ServerVersion(@NonNull VersionResponse versionResponse) { + checkNotNull(versionResponse); + this.versionNumber = versionResponse.getVersionNumber(); + this.updateTime = versionResponse.getUpdateTime(); + this.updateOrigin = versionResponse.getUpdateOrigin(); + this.updateType = versionResponse.getUpdateType(); + TemplateResponse.UserResponse userResponse = versionResponse.getUpdateUser(); + this.updateUser = (userResponse != null) ? new User(userResponse) : null; + this.description = versionResponse.getDescription(); + this.rollbackSource = versionResponse.getRollbackSource(); + this.legacy = versionResponse.isLegacy(); + } + + /** + * Creates a new {@link Version} with a description. + */ + public static ServerVersion withDescription(String description) { + return new ServerVersion().setDescription(description); + } + + /** + * Gets the version number of the template. + * + * @return The version number or null. + */ + @Nullable + public String getVersionNumber() { + return versionNumber; + } + + /** + * Gets the update time of the version. The timestamp of when this version of the Remote Config + * template was written to the Remote Config backend. + * + * @return The update time of the version or null. + */ + @Nullable + public String getUpdateTime() { + return updateTime; + } + + /** + * Gets the origin of the template update action. + * + * @return The origin of the template update action or null. + */ + @Nullable + public String getUpdateOrigin() { + return updateOrigin; + } + + /** + * Gets the type of the template update action. + * + * @return The type of the template update action or null. + */ + @Nullable + public String getUpdateType() { + return updateType; + } + + /** + * Gets the update user of the template. + * An aggregation of all metadata fields about the account that performed the update. + * + * @return The update user of the template or null. + */ + @Nullable + public User getUpdateUser() { + return updateUser; + } + + /** + * Gets the user-provided description of the corresponding Remote Config template. + * + * @return The description of the template or null. + */ + @Nullable + public String getDescription() { + return description; + } + + /** + * Gets the rollback source of the template. + * + *

The serverVersion number of the Remote Config template that has become the current serverVersion + * due to a rollback. Only present if this serverVersion is the result of a rollback. + * + * @return The rollback source of the template or null. + */ + @Nullable + public String getRollbackSource() { + return rollbackSource; + } + + /** + * Indicates whether this Remote Config template was published before serverVersion history was + * supported. + * + * @return true if the template was published before serverVersion history was supported, + * and false otherwise. + */ + public boolean isLegacy() { + return legacy; + } + + /** + * Sets the user-provided description of the template. + * + * @param description The description of the template. + * @return This {@link ServerVersion}. + */ + public ServerVersion setDescription(String description) { + this.description = description; + return this; + } + + VersionResponse toVersionResponse(boolean includeAll) { + VersionResponse versionResponse = new VersionResponse().setDescription(this.description); + if (includeAll) { + versionResponse.setUpdateTime(this.updateTime) + .setLegacy(this.legacy) + .setRollbackSource(this.rollbackSource) + .setUpdateOrigin(this.updateOrigin) + .setUpdateType(this.updateType) + .setUpdateUser((this.updateUser == null) ? null : this.updateUser.toUserResponse()) + .setVersionNumber(this.versionNumber); + } + return versionResponse; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ServerVersion serverVersion = (ServerVersion) o; + return updateTime == serverVersion.updateTime + && legacy == serverVersion.legacy + && Objects.equals(versionNumber, serverVersion.versionNumber) + && Objects.equals(updateOrigin, serverVersion.updateOrigin) + && Objects.equals(updateType, serverVersion.updateType) + && Objects.equals(updateUser, serverVersion.updateUser) + && Objects.equals(description, serverVersion.description) + && Objects.equals(rollbackSource, serverVersion.rollbackSource); + } + + @Override + public int hashCode() { + return Objects + .hash(versionNumber, updateTime, updateOrigin, updateType, updateUser, description, + rollbackSource, legacy); + } +} diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java new file mode 100644 index 00000000..a1ddd0a7 --- /dev/null +++ b/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java @@ -0,0 +1,99 @@ +/* + * Copyright 2020 Google LLC + * + * 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. + */ + +package com.google.firebase.remoteconfig; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; + +import com.google.firebase.remoteconfig.internal.TemplateResponse; +import com.google.firebase.remoteconfig.internal.TemplateResponse.VersionResponse; +import org.junit.Test; + +public class ServerVersionTest { + + @Test(expected = NullPointerException.class) + public void testConstructorWithNullServerVersionResponse() { + new ServerVersion(null); + } + + @Test + public void testConstructorWithValidZuluUpdateTime() { + ServerVersion serverVersion = new ServerVersion(new VersionResponse() + .setUpdateTime("2020-12-08T15:49:51.887878Z")); + assertEquals("2020-12-08T15:49:51.887878Z", serverVersion.getUpdateTime()); + } + + @Test + public void testConstructorWithValidUTCUpdateTime() { + ServerVersion serverVersion = new ServerVersion(new VersionResponse() + .setUpdateTime("Tue, 08 Dec 2020 15:49:51 GMT")); + assertEquals("Tue, 08 Dec 2020 15:49:51 GMT", serverVersion.getUpdateTime()); + } + + @Test + public void testWithDescription() { + final ServerVersion serverVersion = ServerVersion.withDescription("version description text"); + + assertEquals("version description text", serverVersion.getDescription()); + assertNull(serverVersion.getVersionNumber()); + assertEquals(null, serverVersion.getUpdateTime()); + assertNull(serverVersion.getUpdateOrigin()); + assertNull(serverVersion.getUpdateType()); + assertNull(serverVersion.getUpdateUser()); + assertNull(serverVersion.getRollbackSource()); + assertFalse(serverVersion.isLegacy()); + } + + @Test + public void testEquality() { + final ServerVersion versionOne = new ServerVersion(new VersionResponse()); + final ServerVersion versionTwo = new ServerVersion(new VersionResponse()); + + assertEquals(versionOne, versionTwo); + + final ServerVersion versionThree = ServerVersion.withDescription("abcd"); + final ServerVersion versionFour = ServerVersion.withDescription("abcd"); + final ServerVersion versionFive = new ServerVersion(new VersionResponse()).setDescription("abcd"); + + assertEquals(versionThree, versionFour); + assertEquals(versionThree, versionFive); + + final ServerVersion versionSix = ServerVersion.withDescription("efgh"); + + assertNotEquals(versionThree, versionSix); + assertNotEquals(versionOne, versionSix); + + final VersionResponse versionResponse = new VersionResponse() + .setVersionNumber("23") + .setUpdateTime("2014-10-02T15:01:23.045123456Z") + .setUpdateOrigin("ADMIN_SDK") + .setUpdateUser(new TemplateResponse.UserResponse() + .setEmail("user@email.com") + .setName("user-1234") + .setImageUrl("http://user.jpg")) + .setUpdateType("INCREMENTAL_UPDATE"); + final ServerVersion versionSeven = new ServerVersion(versionResponse); + final ServerVersion versionEight = new ServerVersion(versionResponse); + + assertEquals(versionSeven, versionEight); + assertNotEquals(versionOne, versionSeven); + assertNotEquals(versionThree, versionSeven); + assertNotEquals(versionSix, versionSeven); + } +} From 422d227cf51072129817217201167fc667d6ca54 Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Fri, 8 Aug 2025 17:55:05 +0530 Subject: [PATCH 03/21] fix string equality --- .../java/com/google/firebase/remoteconfig/ServerVersion.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java b/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java index 9db70a75..5475c2f9 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java @@ -193,8 +193,8 @@ public boolean equals(Object o) { return false; } ServerVersion serverVersion = (ServerVersion) o; - return updateTime == serverVersion.updateTime - && legacy == serverVersion.legacy + return legacy == serverVersion.legacy + && Objects.equals(updateTime, serverVersion.updateTime) && Objects.equals(versionNumber, serverVersion.versionNumber) && Objects.equals(updateOrigin, serverVersion.updateOrigin) && Objects.equals(updateType, serverVersion.updateType) From 38f658dd4fe70af12a91488e50415a397fc7fb7b Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Fri, 8 Aug 2025 18:57:51 +0530 Subject: [PATCH 04/21] fix textcase --- .../remoteconfig/ServerTemplateData.java | 18 +++++++++--------- .../FirebaseRemoteConfigClientImplTest.java | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java index 59d51b51..4572bf21 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java @@ -40,7 +40,7 @@ final class ServerTemplateData { private Map parameters; private List serverConditions; private Map parameterGroups; - private Version version; + private ServerVersion serverVersion; ServerTemplateData(String etag) { @@ -78,7 +78,7 @@ final class ServerTemplateData { } } if (serverTemplateResponse.getVersion() != null) { - this.version = new Version(serverTemplateResponse.getVersion()); + this.serverVersion = new ServerVersion(serverTemplateResponse.getVersion()); } this.etag = serverTemplateResponse.getEtag(); } @@ -120,8 +120,8 @@ Map getParameterGroups() { return parameterGroups; } - Version getVersion() { - return version; + ServerVersion getVersion() { + return serverVersion; } ServerTemplateData setParameters(@NonNull Map parameters) { @@ -144,8 +144,8 @@ ServerTemplateData setParameterGroups( return this; } - ServerTemplateData setVersion(Version version) { - this.version = version; + ServerTemplateData setVersion(ServerVersion serverVersion) { + this.serverVersion = serverVersion; return this; } @@ -178,7 +178,7 @@ ServerTemplateResponse toServerTemplateResponse(boolean includeAll) { parameterGroupResponse.put(entry.getKey(), entry.getValue().toParameterGroupResponse()); } TemplateResponse.VersionResponse versionResponse = - (this.version == null) ? null : this.version.toVersionResponse(includeAll); + (this.serverVersion == null) ? null : this.serverVersion.toVersionResponse(includeAll); ServerTemplateResponse serverTemplateResponse = new ServerTemplateResponse() .setParameters(parameterResponses) @@ -204,12 +204,12 @@ public boolean equals(Object o) { && Objects.equals(parameters, template.parameters) && Objects.equals(serverConditions, template.serverConditions) && Objects.equals(parameterGroups, template.parameterGroups) - && Objects.equals(version, template.version); + && Objects.equals(serverVersion, template.serverVersion); } @Override public int hashCode() { - return Objects.hash(etag, parameters, serverConditions, parameterGroups, version); + return Objects.hash(etag, parameters, serverConditions, parameterGroups, serverVersion); } } diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index d820dda7..c0d2118f 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -1446,7 +1446,7 @@ public void testGetServerTemplate() throws Exception { assertEquals( convertObjectToString(EXPECTED_SERVER_CONDITIONS), convertObjectToString(serverTemplateData.getServerConditions())); - assertEquals(1605423446000L, serverTemplateData.getVersion().getUpdateTime()); + assertEquals("2020-11-15T06:57:26.342763941Z", serverTemplateData.getVersion().getUpdateTime()); checkGetRequestHeaderForServer(interceptor.getLastRequest()); } @@ -1473,7 +1473,7 @@ public void testGetServerTemplateWithTimestampUpToNanosecondPrecision() throws E assertEquals(TEST_ETAG, serverTemplateData.getETag()); assertEquals("17", serverTemplateData.getVersion().getVersionNumber()); - assertEquals(1605423446000L, serverTemplateData.getVersion().getUpdateTime()); + assertEquals(timestamp, serverTemplateData.getVersion().getUpdateTime()); checkGetRequestHeaderForServer(interceptor.getLastRequest()); } } From ee44298d467ae8736ee5a7b87e29aebb3b030c1c Mon Sep 17 00:00:00 2001 From: Athira M Date: Mon, 11 Aug 2025 22:39:25 +0530 Subject: [PATCH 05/21] Fix lint errors --- .../java/com/google/firebase/remoteconfig/ServerVersion.java | 5 +++-- .../com/google/firebase/remoteconfig/ServerVersionTest.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java b/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java index 5475c2f9..2685fbfe 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java @@ -138,8 +138,9 @@ public String getDescription() { /** * Gets the rollback source of the template. * - *

The serverVersion number of the Remote Config template that has become the current serverVersion - * due to a rollback. Only present if this serverVersion is the result of a rollback. + *

The serverVersion number of the Remote Config template that has become the current + * serverVersion due to a rollback. Only present if this serverVersion is the result of a + * rollback. * * @return The rollback source of the template or null. */ diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java index a1ddd0a7..0e9c3c5d 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java @@ -69,7 +69,8 @@ public void testEquality() { final ServerVersion versionThree = ServerVersion.withDescription("abcd"); final ServerVersion versionFour = ServerVersion.withDescription("abcd"); - final ServerVersion versionFive = new ServerVersion(new VersionResponse()).setDescription("abcd"); + final ServerVersion versionFive = new ServerVersion(new VersionResponse()) + .setDescription("abcd"); assertEquals(versionThree, versionFour); assertEquals(versionThree, versionFive); From 23b1b959d31f17e80a7d0cf12b715907e072c0f5 Mon Sep 17 00:00:00 2001 From: Athira M Date: Tue, 12 Aug 2025 12:35:11 +0530 Subject: [PATCH 06/21] Add unit tests --- .../remoteconfig/ServerTemplateImplTest.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java index ae70d236..54403e39 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java @@ -63,6 +63,21 @@ public void testServerTemplateWithoutCacheValueThrowsException() assertEquals("JSON String must not be null or empty.", error.getMessage()); } + @Test + public void testEvaluateWithoutContextReturnsDefaultValue() + throws FirebaseRemoteConfigException { + KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); + + ServerConfig evaluatedConfig = template.evaluate(); + + assertEquals("Default value", evaluatedConfig.getString("Custom")); + } + @Test public void testEvaluateCustomSignalReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); From 7a28b893da1dc3e5d9d0a88a2f639cf8e76a6e90 Mon Sep 17 00:00:00 2001 From: varun rathore <35365856+rathovarun1032@users.noreply.github.com> Date: Wed, 13 Aug 2025 17:42:05 +0530 Subject: [PATCH 07/21] fix for [438426692](getDouble() logs a malformed warning on type conversion failure) Using getDouble on a string parameter value, returns the appropriate default static value but logs a warning which looks incorrect ("%s" in the warning message?). --- src/main/java/com/google/firebase/remoteconfig/Value.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/Value.java b/src/main/java/com/google/firebase/remoteconfig/Value.java index 7f04aefe..486e6556 100644 --- a/src/main/java/com/google/firebase/remoteconfig/Value.java +++ b/src/main/java/com/google/firebase/remoteconfig/Value.java @@ -100,7 +100,7 @@ long asLong() { try { return Long.parseLong(value); } catch (NumberFormatException e) { - logger.warn("Unable to convert %s to long type.", value); + logger.warn("Unable to convert {} to long type.", value); return DEFAULT_VALUE_FOR_LONG; } } @@ -118,7 +118,7 @@ long asLong() { try { return Double.parseDouble(this.value); } catch (NumberFormatException e) { - logger.warn("Unable to convert %s to double type.", value); + logger.warn("Unable to convert {} to double type.", value); return DEFAULT_VALUE_FOR_DOUBLE; } } From ce4caeaf23fe1ca886dd5df56f7fa0513077913a Mon Sep 17 00:00:00 2001 From: varun rathore <35365856+rathovarun1032@users.noreply.github.com> Date: Thu, 14 Aug 2025 09:36:00 +0530 Subject: [PATCH 08/21] Update ServerTemplateResponse.java to fix b/438607881 In the server template builder flow using cached template, evaluation using custom signals is not working as intended. --- .../remoteconfig/internal/ServerTemplateResponse.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java b/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java index 87f624a7..b8ea9274 100644 --- a/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java +++ b/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java @@ -32,7 +32,7 @@ public final class ServerTemplateResponse { @Key("parameters") private Map parameters; - @Key("conditions") + @Key("serverConditions") private List serverConditions; @Key("parameterGroups") @@ -102,7 +102,7 @@ public static final class ServerConditionResponse { @Key("name") private String name; - @Key("condition") + @Key("serverCondition") private OneOfConditionResponse condition; public String getName() { @@ -248,7 +248,7 @@ public static final class PercentConditionResponse { @Key("microPercentRange") private MicroPercentRangeResponse microPercentRange; - @Key("percentOperator") + @Key("percentConditionOperator") private String percentOperator; @Key("seed") From 61356805eef7b6a0002c2a615d124b231af8d994 Mon Sep 17 00:00:00 2001 From: varun rathore <35365856+rathovarun1032@users.noreply.github.com> Date: Thu, 14 Aug 2025 09:37:39 +0530 Subject: [PATCH 09/21] Update getServerRemoteConfig.json to fix b/438607881 --- src/test/resources/getServerRemoteConfig.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/resources/getServerRemoteConfig.json b/src/test/resources/getServerRemoteConfig.json index 2e3c3556..565a3b82 100644 --- a/src/test/resources/getServerRemoteConfig.json +++ b/src/test/resources/getServerRemoteConfig.json @@ -1,8 +1,8 @@ { - "conditions": [ + "serverConditions": [ { "name": "custom_signal", - "condition": { + "serverCondition": { "orCondition": { "conditions": [ { @@ -26,7 +26,7 @@ }, { "name": "percent", - "condition": { + "serverCondition": { "orCondition": { "conditions": [ { @@ -51,7 +51,7 @@ }, { "name": "chained_conditions", - "condition": { + "serverCondition": { "orCondition": { "conditions": [ { From 28166e012669ef30c3a5175685033f7e064a1cee Mon Sep 17 00:00:00 2001 From: varun rathore <35365856+rathovarun1032@users.noreply.github.com> Date: Thu, 14 Aug 2025 09:38:18 +0530 Subject: [PATCH 10/21] Update getServerTemplateData.json to fix b/438607881 --- src/test/resources/getServerTemplateData.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/resources/getServerTemplateData.json b/src/test/resources/getServerTemplateData.json index 27e3507d..2359718f 100644 --- a/src/test/resources/getServerTemplateData.json +++ b/src/test/resources/getServerTemplateData.json @@ -1,8 +1,8 @@ { - "conditions": [ + "serverConditions": [ { "name": "custom_signal", - "condition": { + "serverCondition": { "orCondition": { "conditions": [ { @@ -26,7 +26,7 @@ }, { "name": "percent", - "condition": { + "serverCondition": { "orCondition": { "conditions": [ { @@ -51,7 +51,7 @@ }, { "name": "chained_conditions", - "condition": { + "serverCondition": { "orCondition": { "conditions": [ { From 8932e7ee824bd9be437dadd181d8b25a94902288 Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Thu, 14 Aug 2025 09:48:30 +0530 Subject: [PATCH 11/21] fix for bugs --- .../remoteconfig/FirebaseRemoteConfigClientImplTest.java | 2 +- src/test/resources/getServerRemoteConfig.json | 4 ++-- src/test/resources/getServerTemplateData.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index c0d2118f..00b12279 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -1432,7 +1432,7 @@ private void checkExceptionFromHttpResponse( } // Get server template tests - + @Test public void testGetServerTemplate() throws Exception { response.addHeader("etag", TEST_ETAG); diff --git a/src/test/resources/getServerRemoteConfig.json b/src/test/resources/getServerRemoteConfig.json index 565a3b82..8a73ae8f 100644 --- a/src/test/resources/getServerRemoteConfig.json +++ b/src/test/resources/getServerRemoteConfig.json @@ -34,7 +34,7 @@ "conditions": [ { "percent": { - "percentOperator": "BETWEEN", + "percentConditionOperator": "BETWEEN", "seed": "3maarirs9xzs", "microPercentRange": { "microPercentLowerBound": 12000000, @@ -77,7 +77,7 @@ }, { "percent": { - "percentOperator": "BETWEEN", + "percentConditionOperator": "BETWEEN", "seed": "cla24qoibb61", "microPercentRange": { "microPercentLowerBound": 25000000, diff --git a/src/test/resources/getServerTemplateData.json b/src/test/resources/getServerTemplateData.json index 2359718f..ddd66241 100644 --- a/src/test/resources/getServerTemplateData.json +++ b/src/test/resources/getServerTemplateData.json @@ -34,7 +34,7 @@ "conditions": [ { "percent": { - "percentOperator": "BETWEEN", + "percentConditionOperator": "BETWEEN", "seed": "3maarirs9xzs", "microPercentRange": { "microPercentLowerBound": 12000000, @@ -75,7 +75,7 @@ ] }, "percent": { - "percentOperator": "BETWEEN", + "percentConditionOperator": "BETWEEN", "seed": "cla24qoibb61", "microPercentRange": { "microPercentLowerBound": 25000000, From dfecfc68f3813ea12cf29541435efff66b5368cb Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 21:02:32 +0530 Subject: [PATCH 12/21] Resolve comment related to revert of ServerVersion Class --- .../remoteconfig/ServerTemplateData.java | 18 ++--- .../remoteconfig/ServerTemplateImpl.java | 5 +- .../FirebaseRemoteConfigClientImplTest.java | 5 +- .../FirebaseRemoteConfigTest.java | 29 ++++--- .../remoteconfig/ServerTemplateImplTest.java | 76 ++++++++++++++----- src/test/resources/getServerTemplateData.json | 12 ++- 6 files changed, 91 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java index 4572bf21..17b26851 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java @@ -40,7 +40,7 @@ final class ServerTemplateData { private Map parameters; private List serverConditions; private Map parameterGroups; - private ServerVersion serverVersion; + private Version version; ServerTemplateData(String etag) { @@ -78,7 +78,7 @@ final class ServerTemplateData { } } if (serverTemplateResponse.getVersion() != null) { - this.serverVersion = new ServerVersion(serverTemplateResponse.getVersion()); + this.version = new Version(serverTemplateResponse.getVersion()); } this.etag = serverTemplateResponse.getEtag(); } @@ -120,8 +120,8 @@ Map getParameterGroups() { return parameterGroups; } - ServerVersion getVersion() { - return serverVersion; + Version getVersion() { + return version; } ServerTemplateData setParameters(@NonNull Map parameters) { @@ -144,8 +144,8 @@ ServerTemplateData setParameterGroups( return this; } - ServerTemplateData setVersion(ServerVersion serverVersion) { - this.serverVersion = serverVersion; + ServerTemplateData setVersion(Version serverVersion) { + this.version = serverVersion; return this; } @@ -178,7 +178,7 @@ ServerTemplateResponse toServerTemplateResponse(boolean includeAll) { parameterGroupResponse.put(entry.getKey(), entry.getValue().toParameterGroupResponse()); } TemplateResponse.VersionResponse versionResponse = - (this.serverVersion == null) ? null : this.serverVersion.toVersionResponse(includeAll); + (this.version == null) ? null : this.version.toVersionResponse(includeAll); ServerTemplateResponse serverTemplateResponse = new ServerTemplateResponse() .setParameters(parameterResponses) @@ -204,12 +204,12 @@ public boolean equals(Object o) { && Objects.equals(parameters, template.parameters) && Objects.equals(serverConditions, template.serverConditions) && Objects.equals(parameterGroups, template.parameterGroups) - && Objects.equals(serverVersion, template.serverVersion); + && Objects.equals(version, template.version); } @Override public int hashCode() { - return Objects.hash(etag, parameters, serverConditions, parameterGroups, serverVersion); + return Objects.hash(etag, parameters, serverConditions, parameterGroups, version); } } diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java index 6d3d675d..27a5ae22 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java @@ -22,8 +22,6 @@ import com.google.firebase.ErrorCode; import com.google.firebase.internal.Nullable; import com.google.firebase.remoteconfig.internal.TemplateResponse.ParameterValueResponse; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import java.util.HashMap; import java.util.Map; @@ -130,8 +128,7 @@ public String getCachedTemplate() { @Override public String toJson() { - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - return gson.toJson(this.cache); + return this.cache.toJSON(); } private void mergeDerivedConfigValues(ImmutableMap evaluatedCondition, diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index 00b12279..9969ac40 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -1446,7 +1446,7 @@ public void testGetServerTemplate() throws Exception { assertEquals( convertObjectToString(EXPECTED_SERVER_CONDITIONS), convertObjectToString(serverTemplateData.getServerConditions())); - assertEquals("2020-11-15T06:57:26.342763941Z", serverTemplateData.getVersion().getUpdateTime()); + assertEquals(1605423446000L, serverTemplateData.getVersion().getUpdateTime()); checkGetRequestHeaderForServer(interceptor.getLastRequest()); } @@ -1470,10 +1470,9 @@ public void testGetServerTemplateWithTimestampUpToNanosecondPrecision() throws E String receivedTemplate = client.getServerTemplate(); ServerTemplateData serverTemplateData = ServerTemplateData.fromJSON(receivedTemplate); - assertEquals(TEST_ETAG, serverTemplateData.getETag()); assertEquals("17", serverTemplateData.getVersion().getVersionNumber()); - assertEquals(timestamp, serverTemplateData.getVersion().getUpdateTime()); + assertEquals(1605423446000L, serverTemplateData.getVersion().getUpdateTime()); checkGetRequestHeaderForServer(interceptor.getLastRequest()); } } diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index f34035f5..ab71e5e5 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -28,6 +28,8 @@ import com.google.firebase.TestOnlyImplFirebaseTrampolines; import com.google.firebase.auth.MockGoogleCredentials; import com.google.firebase.remoteconfig.internal.TemplateResponse; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; import java.util.concurrent.ExecutionException; import org.junit.After; import org.junit.Test; @@ -42,13 +44,6 @@ public class FirebaseRemoteConfigTest { .setCredentials(new MockGoogleCredentials("test-token")) .setProjectId("test-project") .build(); - private static final String TEST_SERVER_TEMPLATE = - "{\n" - + " \"etag\": \"etag-123456789012-1\",\n" - + " \"parameters\": {},\n" - + " \"serverConditions\": [],\n" - + " \"parameterGroups\": {}\n" - + "}"; private static final FirebaseRemoteConfigException TEST_EXCEPTION = new FirebaseRemoteConfigException(ErrorCode.INTERNAL, "Test error message"); @@ -629,14 +624,16 @@ private FirebaseRemoteConfig getRemoteConfig(FirebaseRemoteConfigClient client) @Test public void testGetServerTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplate(); String templateData = template.toJson(); - assertEquals(TEST_SERVER_TEMPLATE, templateData); + JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement actualJson = JsonParser.parseString(templateData); + + assertEquals(expectedJson, actualJson); } @Test @@ -653,14 +650,16 @@ public void testGetServerTemplateFailure() { @Test public void testGetServerTemplateAsync() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplateAsync().get(); String templateData = template.toJson(); - assertEquals(TEST_SERVER_TEMPLATE, templateData); + JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement actualJson = JsonParser.parseString(templateData); + + assertEquals(expectedJson, actualJson); } @Test diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java index 54403e39..54f021a2 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java @@ -26,6 +26,8 @@ import com.google.firebase.testing.TestUtils; import org.junit.BeforeClass; import org.junit.Test; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; /** * Tests for {@link ServerTemplateImpl}. @@ -37,13 +39,6 @@ public class ServerTemplateImplTest { .setCredentials(new MockGoogleCredentials("test-token")) .setProjectId("test-project") .build(); - private static final String TEST_SERVER_TEMPLATE = - "{\n" - + " \"etag\": \"etag-123456789012-1\",\n" - + " \"parameters\": {},\n" - + " \"serverConditions\": [],\n" - + " \"parameterGroups\": {}\n" - + "}"; private static String cacheTemplate; @@ -354,27 +349,66 @@ private FirebaseRemoteConfig getRemoteConfig(FirebaseRemoteConfigClient client) return new FirebaseRemoteConfig(app, client); } - @Test - public void testLoad() throws Exception { - KeysAndValues defaultConfig = - new KeysAndValues.Builder().put("Unset default config", "abc").build(); +@Test +public void testLoad() throws Exception { + // 1. Define the template data that the mock client will return. + // This is the EXPECTED state after `load()` is called. + final String expectedTemplateJsonAfterLoad = new ServerTemplateData().setETag(TEST_ETAG).toJSON(); - // Mock the HTTP client to return a predefined response + // 2. Mock the HTTP client to return the predefined response. MockRemoteConfigClient client = - MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient.fromServerTemplate(expectedTemplateJsonAfterLoad); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ServerTemplate template1 = + + // 3. Build the template instance. + // It's initialized with a complex `cacheTemplate` to ensure `load()` properly overwrites it. + KeysAndValues defaultConfig = + new KeysAndValues.Builder().put("Unset default config", "abc").build(); + ServerTemplate template = remoteConfig .serverTemplateBuilder() .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) // This is the initial state before `load()` + .build(); + + // 4. Call the load method, which fetches the new template from the mock client. + ApiFuture loadFuture = template.load(); + loadFuture.get(); // Wait for the async operation to complete. + + // 5. Get the ACTUAL state of the template after `load()` has executed. + String actualJsonAfterLoad = template.toJson(); + + // 6. Assert that the template's state has been updated to match what the mock client returned. + // Parsing to JsonElement performs a deep, order-insensitive comparison. + JsonElement expectedJson = JsonParser.parseString(expectedTemplateJsonAfterLoad); + JsonElement actualJson = JsonParser.parseString(actualJsonAfterLoad); + + assertEquals(expectedJson, actualJson); +} + +@Test +public void testBuilderParsesCachedTemplateCorrectly() throws FirebaseRemoteConfigException { + // Arrange: + // 1. Create a canonical JSON string by parsing the input file and then + // re-serializing it. This gives us the precise expected output format, + // accounting for any formatting or default value differences. + ServerTemplateData canonicalData = ServerTemplateData.fromJSON(cacheTemplate); + String expectedJsonString = canonicalData.toJSON(); + + // Act: + // 2. Build a ServerTemplate instance from the original cached JSON string, + // which triggers the parsing logic we want to test. + ServerTemplate template = new ServerTemplateImpl.Builder(null) .cachedTemplate(cacheTemplate) .build(); - // Call the load method - ApiFuture loadFuture = template1.load(); - loadFuture.get(); - String cachedTemplate = template1.toJson(); - assertEquals(TEST_SERVER_TEMPLATE, cachedTemplate); - } + // Assert: + // 3. Compare the JSON from the newly built template against the canonical version. + // This verifies that the internal state was parsed and stored correctly. + // Using JsonElement ensures the comparison is not affected by key order. + JsonElement expectedJsonTree = JsonParser.parseString(expectedJsonString); + JsonElement actualJsonTree = JsonParser.parseString(template.toJson()); + + assertEquals(expectedJsonTree, actualJsonTree); +} } diff --git a/src/test/resources/getServerTemplateData.json b/src/test/resources/getServerTemplateData.json index ddd66241..81da133f 100644 --- a/src/test/resources/getServerTemplateData.json +++ b/src/test/resources/getServerTemplateData.json @@ -167,7 +167,15 @@ } }, "version": { - "versionNumber": "27", - "isLegacy": true + "versionNumber": "17", + "updateOrigin": "ADMIN_SDK_NODE", + "updateType": "INCREMENTAL_UPDATE", + "updateUser": { + "email": "firebase-user@account.com", + "name": "dev-admin", + "imageUrl": "http://image.jpg" + }, + "updateTime": "2020-11-15T06:57:26.342763941Z", + "description": "promo config" } } From a0b71bd2c72a48f92eca7b4a486cef8fef04adc4 Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 21:05:02 +0530 Subject: [PATCH 13/21] remove serverVersion --- .../remoteconfig/ServerTemplateData.java | 4 +- .../firebase/remoteconfig/ServerVersion.java | 213 ------------------ .../remoteconfig/ServerVersionTest.java | 100 -------- 3 files changed, 2 insertions(+), 315 deletions(-) delete mode 100644 src/main/java/com/google/firebase/remoteconfig/ServerVersion.java delete mode 100644 src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java index 17b26851..59d51b51 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateData.java @@ -144,8 +144,8 @@ ServerTemplateData setParameterGroups( return this; } - ServerTemplateData setVersion(Version serverVersion) { - this.version = serverVersion; + ServerTemplateData setVersion(Version version) { + this.version = version; return this; } diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java b/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java deleted file mode 100644 index 2685fbfe..00000000 --- a/src/main/java/com/google/firebase/remoteconfig/ServerVersion.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright 2020 Google LLC - * - * 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. - */ - -package com.google.firebase.remoteconfig; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.firebase.internal.NonNull; -import com.google.firebase.internal.Nullable; -import com.google.firebase.remoteconfig.internal.TemplateResponse; -import com.google.firebase.remoteconfig.internal.TemplateResponse.VersionResponse; - -import java.util.Objects; - -/** - * Represents a Server Remote Config template version. - * Output only, except for the version description. Contains metadata about a particular - * version of the Remote Config template. All fields are set at the time the specified Remote - * Config template is published. A version's description field may be specified when - * publishing a template. - */ -public final class ServerVersion { - - private final String versionNumber; - private final String updateTime; - private final String updateOrigin; - private final String updateType; - private final User updateUser; - private final String rollbackSource; - private final boolean legacy; - private String description; - - private ServerVersion() { - this.versionNumber = null; - this.updateTime = null; - this.updateOrigin = null; - this.updateType = null; - this.updateUser = null; - this.rollbackSource = null; - this.legacy = false; - } - - ServerVersion(@NonNull VersionResponse versionResponse) { - checkNotNull(versionResponse); - this.versionNumber = versionResponse.getVersionNumber(); - this.updateTime = versionResponse.getUpdateTime(); - this.updateOrigin = versionResponse.getUpdateOrigin(); - this.updateType = versionResponse.getUpdateType(); - TemplateResponse.UserResponse userResponse = versionResponse.getUpdateUser(); - this.updateUser = (userResponse != null) ? new User(userResponse) : null; - this.description = versionResponse.getDescription(); - this.rollbackSource = versionResponse.getRollbackSource(); - this.legacy = versionResponse.isLegacy(); - } - - /** - * Creates a new {@link Version} with a description. - */ - public static ServerVersion withDescription(String description) { - return new ServerVersion().setDescription(description); - } - - /** - * Gets the version number of the template. - * - * @return The version number or null. - */ - @Nullable - public String getVersionNumber() { - return versionNumber; - } - - /** - * Gets the update time of the version. The timestamp of when this version of the Remote Config - * template was written to the Remote Config backend. - * - * @return The update time of the version or null. - */ - @Nullable - public String getUpdateTime() { - return updateTime; - } - - /** - * Gets the origin of the template update action. - * - * @return The origin of the template update action or null. - */ - @Nullable - public String getUpdateOrigin() { - return updateOrigin; - } - - /** - * Gets the type of the template update action. - * - * @return The type of the template update action or null. - */ - @Nullable - public String getUpdateType() { - return updateType; - } - - /** - * Gets the update user of the template. - * An aggregation of all metadata fields about the account that performed the update. - * - * @return The update user of the template or null. - */ - @Nullable - public User getUpdateUser() { - return updateUser; - } - - /** - * Gets the user-provided description of the corresponding Remote Config template. - * - * @return The description of the template or null. - */ - @Nullable - public String getDescription() { - return description; - } - - /** - * Gets the rollback source of the template. - * - *

The serverVersion number of the Remote Config template that has become the current - * serverVersion due to a rollback. Only present if this serverVersion is the result of a - * rollback. - * - * @return The rollback source of the template or null. - */ - @Nullable - public String getRollbackSource() { - return rollbackSource; - } - - /** - * Indicates whether this Remote Config template was published before serverVersion history was - * supported. - * - * @return true if the template was published before serverVersion history was supported, - * and false otherwise. - */ - public boolean isLegacy() { - return legacy; - } - - /** - * Sets the user-provided description of the template. - * - * @param description The description of the template. - * @return This {@link ServerVersion}. - */ - public ServerVersion setDescription(String description) { - this.description = description; - return this; - } - - VersionResponse toVersionResponse(boolean includeAll) { - VersionResponse versionResponse = new VersionResponse().setDescription(this.description); - if (includeAll) { - versionResponse.setUpdateTime(this.updateTime) - .setLegacy(this.legacy) - .setRollbackSource(this.rollbackSource) - .setUpdateOrigin(this.updateOrigin) - .setUpdateType(this.updateType) - .setUpdateUser((this.updateUser == null) ? null : this.updateUser.toUserResponse()) - .setVersionNumber(this.versionNumber); - } - return versionResponse; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ServerVersion serverVersion = (ServerVersion) o; - return legacy == serverVersion.legacy - && Objects.equals(updateTime, serverVersion.updateTime) - && Objects.equals(versionNumber, serverVersion.versionNumber) - && Objects.equals(updateOrigin, serverVersion.updateOrigin) - && Objects.equals(updateType, serverVersion.updateType) - && Objects.equals(updateUser, serverVersion.updateUser) - && Objects.equals(description, serverVersion.description) - && Objects.equals(rollbackSource, serverVersion.rollbackSource); - } - - @Override - public int hashCode() { - return Objects - .hash(versionNumber, updateTime, updateOrigin, updateType, updateUser, description, - rollbackSource, legacy); - } -} diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java deleted file mode 100644 index 0e9c3c5d..00000000 --- a/src/test/java/com/google/firebase/remoteconfig/ServerVersionTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2020 Google LLC - * - * 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. - */ - -package com.google.firebase.remoteconfig; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; - -import com.google.firebase.remoteconfig.internal.TemplateResponse; -import com.google.firebase.remoteconfig.internal.TemplateResponse.VersionResponse; -import org.junit.Test; - -public class ServerVersionTest { - - @Test(expected = NullPointerException.class) - public void testConstructorWithNullServerVersionResponse() { - new ServerVersion(null); - } - - @Test - public void testConstructorWithValidZuluUpdateTime() { - ServerVersion serverVersion = new ServerVersion(new VersionResponse() - .setUpdateTime("2020-12-08T15:49:51.887878Z")); - assertEquals("2020-12-08T15:49:51.887878Z", serverVersion.getUpdateTime()); - } - - @Test - public void testConstructorWithValidUTCUpdateTime() { - ServerVersion serverVersion = new ServerVersion(new VersionResponse() - .setUpdateTime("Tue, 08 Dec 2020 15:49:51 GMT")); - assertEquals("Tue, 08 Dec 2020 15:49:51 GMT", serverVersion.getUpdateTime()); - } - - @Test - public void testWithDescription() { - final ServerVersion serverVersion = ServerVersion.withDescription("version description text"); - - assertEquals("version description text", serverVersion.getDescription()); - assertNull(serverVersion.getVersionNumber()); - assertEquals(null, serverVersion.getUpdateTime()); - assertNull(serverVersion.getUpdateOrigin()); - assertNull(serverVersion.getUpdateType()); - assertNull(serverVersion.getUpdateUser()); - assertNull(serverVersion.getRollbackSource()); - assertFalse(serverVersion.isLegacy()); - } - - @Test - public void testEquality() { - final ServerVersion versionOne = new ServerVersion(new VersionResponse()); - final ServerVersion versionTwo = new ServerVersion(new VersionResponse()); - - assertEquals(versionOne, versionTwo); - - final ServerVersion versionThree = ServerVersion.withDescription("abcd"); - final ServerVersion versionFour = ServerVersion.withDescription("abcd"); - final ServerVersion versionFive = new ServerVersion(new VersionResponse()) - .setDescription("abcd"); - - assertEquals(versionThree, versionFour); - assertEquals(versionThree, versionFive); - - final ServerVersion versionSix = ServerVersion.withDescription("efgh"); - - assertNotEquals(versionThree, versionSix); - assertNotEquals(versionOne, versionSix); - - final VersionResponse versionResponse = new VersionResponse() - .setVersionNumber("23") - .setUpdateTime("2014-10-02T15:01:23.045123456Z") - .setUpdateOrigin("ADMIN_SDK") - .setUpdateUser(new TemplateResponse.UserResponse() - .setEmail("user@email.com") - .setName("user-1234") - .setImageUrl("http://user.jpg")) - .setUpdateType("INCREMENTAL_UPDATE"); - final ServerVersion versionSeven = new ServerVersion(versionResponse); - final ServerVersion versionEight = new ServerVersion(versionResponse); - - assertEquals(versionSeven, versionEight); - assertNotEquals(versionOne, versionSeven); - assertNotEquals(versionThree, versionSeven); - assertNotEquals(versionSix, versionSeven); - } -} From 8fc3cb7baf15152abe656f8e057d2a3373369271 Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 21:20:21 +0530 Subject: [PATCH 14/21] Resolve comments related to Evaluator --- .../google/firebase/remoteconfig/ConditionEvaluator.java | 6 +++++- .../google/firebase/remoteconfig/ServerTemplateImpl.java | 7 ++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java index 2bd828e2..b18ca032 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java +++ b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.firebase.internal.NonNull; import com.google.firebase.internal.Nullable; @@ -57,12 +58,15 @@ Map evaluateConditions( @Nullable KeysAndValues context) { checkNotNull(conditions, "List of conditions must not be null."); checkArgument(!conditions.isEmpty(), "List of conditions must not be empty."); + if(context == null || conditions.isEmpty()){ + return ImmutableMap.of(); + } KeysAndValues evaluationContext = context != null ? context : new KeysAndValues.Builder().build(); Map evaluatedConditions = conditions.stream() - .collect(Collectors.toMap( + .collect(ImmutableMap.toImmutableMap( ServerCondition::getName, condition -> evaluateCondition(condition.getCondition(), evaluationContext, /* nestingLevel= */0) diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java index 27a5ae22..d9a62dbd 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java @@ -93,11 +93,8 @@ public ServerConfig evaluate(@Nullable KeysAndValues context) } ConditionEvaluator conditionEvaluator = new ConditionEvaluator(); - ImmutableMap evaluatedCondition = - context != null && !cache.getServerConditions().isEmpty() - ? ImmutableMap.copyOf( - conditionEvaluator.evaluateConditions(cache.getServerConditions(), context)) - : ImmutableMap.of(); + ImmutableMap evaluatedCondition = ImmutableMap.copyOf( + conditionEvaluator.evaluateConditions(cache.getServerConditions(), context)); ImmutableMap parameters = ImmutableMap.copyOf(cache.getParameters()); mergeDerivedConfigValues(evaluatedCondition, parameters, configValues); From 95910ad5ad4e4999ee08b7613c0d12fc523546fe Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 22:40:04 +0530 Subject: [PATCH 15/21] fix indentation --- .../google/firebase/remoteconfig/ServerTemplateImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java index d9a62dbd..d38ac51c 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java +++ b/src/main/java/com/google/firebase/remoteconfig/ServerTemplateImpl.java @@ -42,7 +42,7 @@ public static class Builder implements ServerTemplate.Builder { private KeysAndValues defaultConfig; private String cachedTemplate; private FirebaseRemoteConfigClient client; - + Builder(FirebaseRemoteConfigClient remoteConfigClient) { this.client = remoteConfigClient; } @@ -77,11 +77,11 @@ private ServerTemplateImpl(Builder builder) { } @Override - public ServerConfig evaluate(@Nullable KeysAndValues context) + public ServerConfig evaluate(@Nullable KeysAndValues context) throws FirebaseRemoteConfigException { if (this.cache == null) { throw new FirebaseRemoteConfigException(ErrorCode.FAILED_PRECONDITION, - "No Remote Config Server template in cache. Call load() before calling evaluate()."); + "No Remote Config Server template in cache. Call load() before calling evaluate()."); } Map configValues = new HashMap<>(); @@ -94,7 +94,7 @@ public ServerConfig evaluate(@Nullable KeysAndValues context) ConditionEvaluator conditionEvaluator = new ConditionEvaluator(); ImmutableMap evaluatedCondition = ImmutableMap.copyOf( - conditionEvaluator.evaluateConditions(cache.getServerConditions(), context)); + conditionEvaluator.evaluateConditions(cache.getServerConditions(), context)); ImmutableMap parameters = ImmutableMap.copyOf(cache.getParameters()); mergeDerivedConfigValues(evaluatedCondition, parameters, configValues); From 3257dc5f42ee66034a542dcf08cc62798cf56c51 Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 22:46:56 +0530 Subject: [PATCH 16/21] fix indentation --- .../remoteconfig/ConditionEvaluator.java | 34 +- .../google/firebase/remoteconfig/Value.java | 1 - .../internal/ServerTemplateResponse.java | 11 +- .../FirebaseRemoteConfigClientImplTest.java | 381 ++++++++---------- .../FirebaseRemoteConfigTest.java | 94 ++--- .../remoteconfig/ServerTemplateImplTest.java | 239 +++++------ src/test/resources/getServerRemoteConfig.json | 2 +- src/test/resources/getServerTemplateData.json | 4 +- 8 files changed, 349 insertions(+), 417 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java index b18ca032..436a3e37 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java +++ b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java @@ -39,7 +39,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - + final class ConditionEvaluator { private static final int MAX_CONDITION_RECURSION_DEPTH = 10; private static final Logger logger = LoggerFactory.getLogger(ConditionEvaluator.class); @@ -49,7 +49,7 @@ final class ConditionEvaluator { * Evaluates server conditions and assigns a boolean value to each condition. * * @param conditions List of conditions which are to be evaluated. - * @param context A map with additional metadata used during evaluation. + * @param context A map with additional metadata used during evaluation. * @return A map of condition to evaluated value. */ @NonNull @@ -58,19 +58,17 @@ Map evaluateConditions( @Nullable KeysAndValues context) { checkNotNull(conditions, "List of conditions must not be null."); checkArgument(!conditions.isEmpty(), "List of conditions must not be empty."); - if(context == null || conditions.isEmpty()){ + if (context == null || conditions.isEmpty()) { return ImmutableMap.of(); } - KeysAndValues evaluationContext = context != null - ? context + KeysAndValues evaluationContext = context != null + ? context : new KeysAndValues.Builder().build(); Map evaluatedConditions = conditions.stream() .collect(ImmutableMap.toImmutableMap( ServerCondition::getName, - condition -> - evaluateCondition(condition.getCondition(), evaluationContext, /* nestingLevel= */0) - )); + condition -> evaluateCondition(condition.getCondition(), evaluationContext, /* nestingLevel= */0))); return evaluatedConditions; } @@ -99,7 +97,6 @@ private boolean evaluateCondition(OneOfCondition condition, KeysAndValues contex return false; } - private boolean evaluateOrCondition(OrCondition condition, KeysAndValues context, int nestingLevel) { return condition.getConditions().stream() @@ -251,9 +248,8 @@ private BigInteger hashSeededRandomizationId(String seededRandomizationId) { } private boolean compareStrings(ImmutableList targetValues, String customSignal, - BiPredicate compareFunction) { - return targetValues.stream().anyMatch(targetValue -> - compareFunction.test(customSignal, targetValue)); + BiPredicate compareFunction) { + return targetValues.stream().anyMatch(targetValue -> compareFunction.test(customSignal, targetValue)); } private boolean compareStringRegex(String customSignal, String targetSignal) { @@ -265,7 +261,7 @@ private boolean compareStringRegex(String customSignal, String targetSignal) { } private boolean compareNumbers(ImmutableList targetValues, String customSignal, - IntPredicate compareFunction) { + IntPredicate compareFunction) { if (targetValues.size() != 1) { logger.warn(String.format( "Target values must contain 1 element for numeric operations. Target Value: %s", @@ -286,8 +282,8 @@ private boolean compareNumbers(ImmutableList targetValues, String custom } private boolean compareSemanticVersions(ImmutableList targetValues, - String customSignal, - IntPredicate compareFunction) { + String customSignal, + IntPredicate compareFunction) { if (targetValues.size() != 1) { logger.warn(String.format("Target values must contain 1 element for semantic operation.")); return false; @@ -320,8 +316,8 @@ private int compareSemanticVersions(List version1, List versio for (int i = 0; i < maxLength; i++) { // Default to 0 if segment is missing - int v1 = i < version1Size ? version1.get(i) : 0; - int v2 = i < version2Size ? version2.get(i) : 0; + int v1 = i < version1Size ? version1.get(i) : 0; + int v2 = i < version2Size ? version2.get(i) : 0; int comparison = Integer.compare(v1, v2); if (comparison != 0) { @@ -334,8 +330,8 @@ private int compareSemanticVersions(List version1, List versio private List parseSemanticVersion(String versionString) { return Arrays.stream(versionString.split("\\.")) - .map(Integer::parseInt) - .collect(Collectors.toList()); + .map(Integer::parseInt) + .collect(Collectors.toList()); } private boolean validateSemanticVersion(String version) { diff --git a/src/main/java/com/google/firebase/remoteconfig/Value.java b/src/main/java/com/google/firebase/remoteconfig/Value.java index 486e6556..7935e849 100644 --- a/src/main/java/com/google/firebase/remoteconfig/Value.java +++ b/src/main/java/com/google/firebase/remoteconfig/Value.java @@ -133,4 +133,3 @@ ValueSource getSource() { return source; } } - diff --git a/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java b/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java index b8ea9274..c58faa94 100644 --- a/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java +++ b/src/main/java/com/google/firebase/remoteconfig/internal/ServerTemplateResponse.java @@ -25,7 +25,8 @@ import java.util.Map; /** - * The Data Transfer Object for parsing Remote Config template responses from the Remote Config + * The Data Transfer Object for parsing Remote Config template responses from + * the Remote Config * service. */ public final class ServerTemplateResponse { @@ -94,7 +95,8 @@ public ServerTemplateResponse setEtag(String etag) { } /** - * The Data Transfer Object for parsing Remote Config condition responses from the Remote Config + * The Data Transfer Object for parsing Remote Config condition responses from + * the Remote Config * service. */ public static final class ServerConditionResponse { @@ -164,7 +166,7 @@ public OneOfConditionResponse setAndCondition(AndConditionResponse andCondition) } public OneOfConditionResponse setCustomSignalCondition( - CustomSignalConditionResponse customSignalCondition) { + CustomSignalConditionResponse customSignalCondition) { this.customSignalCondition = customSignalCondition; return this; } @@ -276,7 +278,7 @@ public PercentConditionResponse setMicroPercent(int microPercent) { } public PercentConditionResponse setMicroPercentRange( - MicroPercentRangeResponse microPercentRange) { + MicroPercentRangeResponse microPercentRange) { this.microPercentRange = microPercentRange; return this; } @@ -318,4 +320,3 @@ public MicroPercentRangeResponse setMicroPercentUpperBound(int microPercentUpper } } } - diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index 9969ac40..4ccf906d 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -61,156 +61,144 @@ public class FirebaseRemoteConfigClientImplTest { - private static final String TEST_REMOTE_CONFIG_URL = - "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; - private static final String TEST_SERVER_REMOTE_CONFIG_URL = - "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; + private static final String TEST_REMOTE_CONFIG_URL = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; + private static final String TEST_SERVER_REMOTE_CONFIG_URL = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; private static final List HTTP_STATUS_CODES = ImmutableList.of(401, 404, 500); private static final Map HTTP_STATUS_TO_ERROR_CODE = ImmutableMap.of( - 401, ErrorCode.UNAUTHENTICATED, - 404, ErrorCode.NOT_FOUND, - 500, ErrorCode.INTERNAL); + 401, ErrorCode.UNAUTHENTICATED, + 404, ErrorCode.NOT_FOUND, + 500, ErrorCode.INTERNAL); private static final String MOCK_TEMPLATE_RESPONSE = TestUtils - .loadResource("getRemoteConfig.json"); - + .loadResource("getRemoteConfig.json"); + private static final String MOCK_SERVER_TEMPLATE_RESPONSE = TestUtils - .loadResource("getServerRemoteConfig.json"); + .loadResource("getServerRemoteConfig.json"); private static final String MOCK_LIST_VERSIONS_RESPONSE = TestUtils - .loadResource("listRemoteConfigVersions.json"); + .loadResource("listRemoteConfigVersions.json"); private static final String TEST_ETAG = "etag-123456789012-1"; - private static final Map EXPECTED_PARAMETERS = - ImmutableMap.of( - "welcome_message_text", - new Parameter() - .setDefaultValue(ParameterValue.of("welcome to app")) - .setConditionalValues( - ImmutableMap.of( - "ios_en", ParameterValue.of("welcome to app en"))) - .setDescription("text for welcome message!") - .setValueType(ParameterValueType.STRING), - "header_text", - new Parameter() - .setDefaultValue(ParameterValue.inAppDefault()) - .setValueType(ParameterValueType.STRING)); - - private static final Map EXPECTED_PARAMETER_GROUPS = - ImmutableMap.of( - "new menu", - new ParameterGroup() - .setDescription("New Menu") - .setParameters( - ImmutableMap.of( - "pumpkin_spice_season", - new Parameter() - .setDefaultValue(ParameterValue.of("true")) - .setDescription("Whether it's currently pumpkin spice season.") - .setValueType(ParameterValueType.BOOLEAN)))); - - private static final List EXPECTED_CONDITIONS = - ImmutableList.of( - new Condition("ios_en", "device.os == 'ios' && device.country in ['us', 'uk']") - .setTagColor(TagColor.INDIGO), - new Condition("android_en", "device.os == 'android' && device.country in ['us', 'uk']")); - - private static final List EXPECTED_SERVER_CONDITIONS = - ImmutableList.of( - new ServerCondition("custom_signal", null) - .setServerCondition( - new OneOfCondition() - .setOrCondition( - new OrCondition( - ImmutableList.of( - new OneOfCondition() - .setAndCondition( - new AndCondition( - ImmutableList.of( - new OneOfCondition() - .setCustomSignal( - new CustomSignalCondition( - "users", - CustomSignalOperator - .NUMERIC_LESS_THAN, - new ArrayList<>( - ImmutableList.of("100"))))))))))), - new ServerCondition("percent", null) - .setServerCondition( - new OneOfCondition() - .setOrCondition( - new OrCondition( - ImmutableList.of( - new OneOfCondition() - .setAndCondition( - new AndCondition( - ImmutableList.of( - new OneOfCondition() - .setPercent( - new PercentCondition( - new MicroPercentRange( - 12000000, 100000000), - PercentConditionOperator.BETWEEN, - "3maarirs9xzs"))))))))), - new ServerCondition("chained_conditions", null) - .setServerCondition( - new OneOfCondition() - .setOrCondition( - new OrCondition( - ImmutableList.of( - new OneOfCondition() - .setAndCondition( - new AndCondition( - ImmutableList.of( - new OneOfCondition() - .setCustomSignal( - new CustomSignalCondition( - "users", - CustomSignalOperator - .NUMERIC_LESS_THAN, + private static final Map EXPECTED_PARAMETERS = ImmutableMap.of( + "welcome_message_text", + new Parameter() + .setDefaultValue(ParameterValue.of("welcome to app")) + .setConditionalValues( + ImmutableMap.of( + "ios_en", ParameterValue.of("welcome to app en"))) + .setDescription("text for welcome message!") + .setValueType(ParameterValueType.STRING), + "header_text", + new Parameter() + .setDefaultValue(ParameterValue.inAppDefault()) + .setValueType(ParameterValueType.STRING)); + + private static final Map EXPECTED_PARAMETER_GROUPS = ImmutableMap.of( + "new menu", + new ParameterGroup() + .setDescription("New Menu") + .setParameters( + ImmutableMap.of( + "pumpkin_spice_season", + new Parameter() + .setDefaultValue(ParameterValue.of("true")) + .setDescription("Whether it's currently pumpkin spice season.") + .setValueType(ParameterValueType.BOOLEAN)))); + + private static final List EXPECTED_CONDITIONS = ImmutableList.of( + new Condition("ios_en", "device.os == 'ios' && device.country in ['us', 'uk']") + .setTagColor(TagColor.INDIGO), + new Condition("android_en", "device.os == 'android' && device.country in ['us', 'uk']")); + + private static final List EXPECTED_SERVER_CONDITIONS = ImmutableList.of( + new ServerCondition("custom_signal", null) + .setServerCondition( + new OneOfCondition() + .setOrCondition( + new OrCondition( + ImmutableList.of( + new OneOfCondition() + .setAndCondition( + new AndCondition( + ImmutableList.of( + new OneOfCondition() + .setCustomSignal( + new CustomSignalCondition( + "users", + CustomSignalOperator.NUMERIC_LESS_THAN, + new ArrayList<>( + ImmutableList.of("100"))))))))))), + new ServerCondition("percent", null) + .setServerCondition( + new OneOfCondition() + .setOrCondition( + new OrCondition( + ImmutableList.of( + new OneOfCondition() + .setAndCondition( + new AndCondition( + ImmutableList.of( + new OneOfCondition() + .setPercent( + new PercentCondition( + new MicroPercentRange( + 12000000, 100000000), + PercentConditionOperator.BETWEEN, + "3maarirs9xzs"))))))))), + new ServerCondition("chained_conditions", null) + .setServerCondition( + new OneOfCondition() + .setOrCondition( + new OrCondition( + ImmutableList.of( + new OneOfCondition() + .setAndCondition( + new AndCondition( + ImmutableList.of( + new OneOfCondition() + .setCustomSignal( + new CustomSignalCondition( + "users", + CustomSignalOperator.NUMERIC_LESS_THAN, new ArrayList<>( - ImmutableList.of("100")))), - new OneOfCondition() - .setCustomSignal( - new CustomSignalCondition( + ImmutableList.of("100")))), + new OneOfCondition() + .setCustomSignal( + new CustomSignalCondition( "premium users", - CustomSignalOperator - .NUMERIC_GREATER_THAN, + CustomSignalOperator.NUMERIC_GREATER_THAN, new ArrayList<>( ImmutableList.of("20")))), - new OneOfCondition() - .setPercent( + new OneOfCondition() + .setPercent( new PercentCondition( new MicroPercentRange( 25000000, 100000000), PercentConditionOperator.BETWEEN, - "cla24qoibb61")) - )))))))); - - private static final Version EXPECTED_VERSION = - new Version( - new TemplateResponse.VersionResponse() - .setVersionNumber("17") - .setUpdateOrigin("ADMIN_SDK_NODE") - .setUpdateType("INCREMENTAL_UPDATE") - .setUpdateUser( - new TemplateResponse.UserResponse() - .setEmail("firebase-user@account.com") - .setName("dev-admin") - .setImageUrl("http://image.jpg")) - .setUpdateTime("2020-11-15T06:57:26.342763941Z") - .setDescription("promo config")); - - private static final Template EXPECTED_TEMPLATE = - new Template() - .setETag(TEST_ETAG) - .setParameters(EXPECTED_PARAMETERS) - .setConditions(EXPECTED_CONDITIONS) - .setParameterGroups(EXPECTED_PARAMETER_GROUPS) - .setVersion(EXPECTED_VERSION); + "cla24qoibb61")))))))))); + + private static final Version EXPECTED_VERSION = new Version( + new TemplateResponse.VersionResponse() + .setVersionNumber("17") + .setUpdateOrigin("ADMIN_SDK_NODE") + .setUpdateType("INCREMENTAL_UPDATE") + .setUpdateUser( + new TemplateResponse.UserResponse() + .setEmail("firebase-user@account.com") + .setName("dev-admin") + .setImageUrl("http://image.jpg")) + .setUpdateTime("2020-11-15T06:57:26.342763941Z") + .setDescription("promo config")); + + private static final Template EXPECTED_TEMPLATE = new Template() + .setETag(TEST_ETAG) + .setParameters(EXPECTED_PARAMETERS) + .setConditions(EXPECTED_CONDITIONS) + .setParameterGroups(EXPECTED_PARAMETER_GROUPS) + .setVersion(EXPECTED_VERSION); private MockLowLevelHttpResponse response; private TestResponseInterceptor interceptor; @@ -240,20 +228,18 @@ public void testGetTemplate() throws Exception { @Test public void testGetTemplateWithTimestampUpToNanosecondPrecision() throws Exception { - List timestamps = - ImmutableList.of( - "2020-11-15T06:57:26.342Z", - "2020-11-15T06:57:26.342763Z", - "2020-11-15T06:57:26.342763941Z"); + List timestamps = ImmutableList.of( + "2020-11-15T06:57:26.342Z", + "2020-11-15T06:57:26.342763Z", + "2020-11-15T06:57:26.342763941Z"); for (String timestamp : timestamps) { response.addHeader("etag", TEST_ETAG); - String templateResponse = - "{\"version\": {" - + " \"versionNumber\": \"17\"," - + " \"updateTime\": \"" - + timestamp - + "\"" - + " }}"; + String templateResponse = "{\"version\": {" + + " \"versionNumber\": \"17\"," + + " \"updateTime\": \"" + + timestamp + + "\"" + + " }}"; response.setContent(templateResponse); Template receivedTemplate = client.getTemplate(); @@ -395,14 +381,14 @@ public void testGetTemplateErrorWithMalformedResponse() { public void testGetTemplateErrorWithDetails() { for (int code : HTTP_STATUS_CODES) { response.setStatusCode(code).setContent( - "{\"error\": {\"status\": \"INVALID_ARGUMENT\", \"message\": \"test error\"}}"); + "{\"error\": {\"status\": \"INVALID_ARGUMENT\", \"message\": \"test error\"}}"); try { client.getTemplate(); fail("No error thrown for HTTP error"); } catch (FirebaseRemoteConfigException error) { checkExceptionFromHttpResponse(error, ErrorCode.INVALID_ARGUMENT, null, "test error", - HttpMethods.GET); + HttpMethods.GET); } checkGetRequestHeader(interceptor.getLastRequest()); } @@ -412,16 +398,16 @@ public void testGetTemplateErrorWithDetails() { public void testGetTemplateErrorWithRcError() { for (int code : HTTP_STATUS_CODES) { response.setStatusCode(code).setContent( - "{\"error\": {\"status\": \"INVALID_ARGUMENT\", " - + "\"message\": \"[INVALID_ARGUMENT]: test error\"}}"); + "{\"error\": {\"status\": \"INVALID_ARGUMENT\", " + + "\"message\": \"[INVALID_ARGUMENT]: test error\"}}"); try { client.getTemplate(); fail("No error thrown for HTTP error"); } catch (FirebaseRemoteConfigException error) { checkExceptionFromHttpResponse(error, ErrorCode.INVALID_ARGUMENT, - RemoteConfigErrorCode.INVALID_ARGUMENT, "[INVALID_ARGUMENT]: test error", - HttpMethods.GET); + RemoteConfigErrorCode.INVALID_ARGUMENT, "[INVALID_ARGUMENT]: test error", + HttpMethods.GET); } checkGetRequestHeader(interceptor.getLastRequest()); } @@ -436,9 +422,8 @@ public void testGetTemplateAtVersionWithNullString() throws Exception { @Test public void testGetTemplateAtVersionWithInvalidString() throws Exception { - List invalidVersionStrings = - ImmutableList.of( - "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); + List invalidVersionStrings = ImmutableList.of( + "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); for (String version : invalidVersionStrings) { try { @@ -670,17 +655,17 @@ public void testPublishTemplateWithValidTemplateAndForceTrue() throws Exception public void testPublishTemplateWithValidTemplateAndValidateOnlyTrue() throws Exception { response.addHeader("etag", TEST_ETAG); response.setContent(MOCK_TEMPLATE_RESPONSE); - Template expectedTemplate = - new Template() - .setETag("etag-123456789012-45") - .setParameters(EXPECTED_PARAMETERS) - .setConditions(EXPECTED_CONDITIONS) - .setParameterGroups(EXPECTED_PARAMETER_GROUPS) - .setVersion(EXPECTED_VERSION); + Template expectedTemplate = new Template() + .setETag("etag-123456789012-45") + .setParameters(EXPECTED_PARAMETERS) + .setConditions(EXPECTED_CONDITIONS) + .setParameterGroups(EXPECTED_PARAMETER_GROUPS) + .setVersion(EXPECTED_VERSION); Template validatedTemplate = client.publishTemplate(expectedTemplate, true, false); - // check if the etag matches the input template's etag and not the etag from the server response + // check if the etag matches the input template's etag and not the etag from the + // server response assertNotEquals(TEST_ETAG, validatedTemplate.getETag()); assertEquals("etag-123456789012-45", validatedTemplate.getETag()); assertEquals(expectedTemplate, validatedTemplate); @@ -866,9 +851,8 @@ public void testRollbackWithNullString() throws Exception { @Test public void testRollbackWithInvalidString() throws Exception { - List invalidVersionStrings = - ImmutableList.of( - "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); + List invalidVersionStrings = ImmutableList.of( + "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); for (String version : invalidVersionStrings) { try { @@ -1097,28 +1081,26 @@ public void testListVersionsWithNullOptions() throws Exception { public void testListVersionsWithOptions() throws Exception { response.setContent(MOCK_LIST_VERSIONS_RESPONSE); - TemplateResponse.ListVersionsResponse versionsList = - client.listVersions( - ListVersionsOptions.builder() - .setPageSize(10) - .setPageToken("token") - .setStartTimeMillis(1605219122000L) - .setEndTimeMillis(1606245035000L) - .setEndVersionNumber("29") - .build()); + TemplateResponse.ListVersionsResponse versionsList = client.listVersions( + ListVersionsOptions.builder() + .setPageSize(10) + .setPageToken("token") + .setStartTimeMillis(1605219122000L) + .setEndTimeMillis(1606245035000L) + .setEndVersionNumber("29") + .build()); assertTrue(versionsList.hasVersions()); HttpRequest request = interceptor.getLastRequest(); - String urlWithoutParameters = - request.getUrl().toString().substring(0, request.getUrl().toString().lastIndexOf('?')); - final Map expectedQuery = - ImmutableMap.of( - "endVersionNumber", "29", - "pageSize", "10", - "pageToken", "token", - "startTime", "2020-11-12T22:12:02.000000000Z", - "endTime", "2020-11-24T19:10:35.000000000Z"); + String urlWithoutParameters = request.getUrl().toString().substring(0, + request.getUrl().toString().lastIndexOf('?')); + final Map expectedQuery = ImmutableMap.of( + "endVersionNumber", "29", + "pageSize", "10", + "pageToken", "token", + "startTime", "2020-11-12T22:12:02.000000000Z", + "endTime", "2020-11-24T19:10:35.000000000Z"); Map actualQuery = new HashMap<>(); String query = request.getUrl().toURI().getQuery(); String[] pairs = query.split("&"); @@ -1305,11 +1287,10 @@ public void testBuilderNullRequestFactory() { @Test public void testFromApp() throws IOException { - FirebaseOptions options = - FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); + FirebaseOptions options = FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); FirebaseApp app = FirebaseApp.initializeApp(options); try { @@ -1318,8 +1299,7 @@ public void testFromApp() throws IOException { assertEquals(TEST_REMOTE_CONFIG_URL, client.getRemoteConfigUrl()); assertSame(options.getJsonFactory(), client.getJsonFactory()); - HttpRequest request = - client.getRequestFactory().buildGetRequest(new GenericUrl("https://example.com")); + HttpRequest request = client.getRequestFactory().buildGetRequest(new GenericUrl("https://example.com")); assertEquals("Bearer test-token", request.getHeaders().getAuthorization()); } finally { app.delete(); @@ -1328,8 +1308,7 @@ public void testFromApp() throws IOException { private FirebaseRemoteConfigClientImpl initRemoteConfigClient( MockLowLevelHttpResponse mockResponse, HttpResponseInterceptor interceptor) { - MockHttpTransport transport = - new MockHttpTransport.Builder().setLowLevelHttpResponse(mockResponse).build(); + MockHttpTransport transport = new MockHttpTransport.Builder().setLowLevelHttpResponse(mockResponse).build(); return FirebaseRemoteConfigClientImpl.builder() .setProjectId("test-project") @@ -1432,7 +1411,7 @@ private void checkExceptionFromHttpResponse( } // Get server template tests - + @Test public void testGetServerTemplate() throws Exception { response.addHeader("etag", TEST_ETAG); @@ -1452,20 +1431,18 @@ public void testGetServerTemplate() throws Exception { @Test public void testGetServerTemplateWithTimestampUpToNanosecondPrecision() throws Exception { - List timestamps = - ImmutableList.of( - "2020-11-15T06:57:26.342Z", - "2020-11-15T06:57:26.342763Z", - "2020-11-15T06:57:26.342763941Z"); + List timestamps = ImmutableList.of( + "2020-11-15T06:57:26.342Z", + "2020-11-15T06:57:26.342763Z", + "2020-11-15T06:57:26.342763941Z"); for (String timestamp : timestamps) { response.addHeader("etag", TEST_ETAG); - String templateResponse = - "{\"version\": {" - + " \"versionNumber\": \"17\"," - + " \"updateTime\": \"" - + timestamp - + "\"" - + " }}"; + String templateResponse = "{\"version\": {" + + " \"versionNumber\": \"17\"," + + " \"updateTime\": \"" + + timestamp + + "\"" + + " }}"; response.setContent(templateResponse); String receivedTemplate = client.getServerTemplate(); diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index ab71e5e5..e10ffe2a 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -34,18 +34,18 @@ import org.junit.After; import org.junit.Test; -/** Unit tests -* for {@link FirebaseRemoteConfig}. -* */ +/** + * Unit tests + * for {@link FirebaseRemoteConfig}. + */ public class FirebaseRemoteConfigTest { - private static final FirebaseOptions TEST_OPTIONS = - FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); - private static final FirebaseRemoteConfigException TEST_EXCEPTION = - new FirebaseRemoteConfigException(ErrorCode.INTERNAL, "Test error message"); + private static final FirebaseOptions TEST_OPTIONS = FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); + private static final FirebaseRemoteConfigException TEST_EXCEPTION = new FirebaseRemoteConfigException( + ErrorCode.INTERNAL, "Test error message"); @After public void tearDown() { @@ -79,8 +79,7 @@ public void testDefaultRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = - "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; + String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getRemoteConfigUrl()); } @@ -93,8 +92,7 @@ public void testDefaultServerRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = - "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; + String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getServerRemoteConfigUrl()); } @@ -116,19 +114,17 @@ public void testAppDelete() { @Test public void testRemoteConfigClientWithoutProjectId() { - FirebaseOptions options = - FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); + FirebaseOptions options = FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); FirebaseApp.initializeApp(options); try { FirebaseRemoteConfig.getInstance(); fail("No error thrown for missing project ID"); } catch (IllegalArgumentException expected) { - String message = - "Project ID is required to access Remote Config service. Use a service " - + "account credential or set the project ID explicitly via FirebaseOptions. " - + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " - + "environment variable."; + String message = "Project ID is required to access Remote Config service. Use a service " + + "account credential or set the project ID explicitly via FirebaseOptions. " + + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " + + "environment variable."; assertEquals(message, expected.getMessage()); } } @@ -139,8 +135,7 @@ public void testRemoteConfigClientWithoutProjectId() { @Test public void testGetTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplate(); @@ -162,8 +157,7 @@ public void testGetTemplateFailure() { @Test public void testGetTemplateAsync() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAsync().get(); @@ -187,8 +181,7 @@ public void testGetTemplateAsyncFailure() throws InterruptedException { @Test public void testGetTemplateAtVersionWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion("64"); @@ -210,8 +203,7 @@ public void testGetTemplateAtVersionWithStringValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync("55").get(); @@ -233,8 +225,7 @@ public void testGetTemplateAtVersionAsyncWithStringValueFailure() throws Interru @Test public void testGetTemplateAtVersionWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion(64L); @@ -256,8 +247,7 @@ public void testGetTemplateAtVersionWithLongValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync(55L).get(); @@ -425,8 +415,7 @@ public void testForcePublishTemplateAsyncFailure() throws InterruptedException { @Test public void testRollbackWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback("64"); @@ -448,8 +437,7 @@ public void testRollbackWithStringValueFailure() { @Test public void testRollbackAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync("55").get(); @@ -471,8 +459,7 @@ public void testRollbackAsyncWithStringValueFailure() throws InterruptedExceptio @Test public void testRollbackWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback(64L); @@ -494,8 +481,7 @@ public void testRollbackWithLongValueFailure() { @Test public void testRollbackAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync(55L).get(); @@ -519,9 +505,8 @@ public void testRollbackAsyncWithLongValueFailure() throws InterruptedException @Test public void testListVersionsWithNoOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersions(); @@ -543,9 +528,8 @@ public void testListVersionsWithNoOptionsFailure() { @Test public void testListVersionsAsyncWithNoOptions() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync().get(); @@ -567,13 +551,11 @@ public void testListVersionsAsyncWithNoOptionsFailure() throws InterruptedExcept @Test public void testListVersionsWithOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = - remoteConfig.listVersions(ListVersionsOptions.builder().build()); + ListVersionsPage listVersionsPage = remoteConfig.listVersions(ListVersionsOptions.builder().build()); assertEquals("token", listVersionsPage.getNextPageToken()); } @@ -592,13 +574,11 @@ public void testListVersionsWithOptionsFailure() { @Test public void testListVersionsAsyncWithOptions() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = - remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); + ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); assertEquals("token", listVersionsPage.getNextPageToken()); } diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java index 54f021a2..e49de56c 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java @@ -30,15 +30,14 @@ import com.google.gson.JsonParser; /** -* Tests for {@link ServerTemplateImpl}. -*/ + * Tests for {@link ServerTemplateImpl}. + */ public class ServerTemplateImplTest { - private static final FirebaseOptions TEST_OPTIONS = - FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); + private static final FirebaseOptions TEST_OPTIONS = FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); private static String cacheTemplate; @@ -52,8 +51,8 @@ public void testServerTemplateWithoutCacheValueThrowsException() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); - IllegalArgumentException error = assertThrows(IllegalArgumentException.class, - () -> new ServerTemplateImpl.Builder(null).defaultConfig(defaultConfig).build()); + IllegalArgumentException error = assertThrows(IllegalArgumentException.class, + () -> new ServerTemplateImpl.Builder(null).defaultConfig(defaultConfig).build()); assertEquals("JSON String must not be null or empty.", error.getMessage()); } @@ -62,11 +61,10 @@ public void testServerTemplateWithoutCacheValueThrowsException() public void testEvaluateWithoutContextReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(); @@ -77,11 +75,10 @@ public void testEvaluateWithoutContextReturnsDefaultValue() public void testEvaluateCustomSignalReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "100").build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -93,11 +90,10 @@ public void testEvaluateCustomSignalReturnsConditionalValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "99").build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -109,11 +105,10 @@ public void testEvaluateCustomSignalWithoutContextReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -125,11 +120,10 @@ public void testEvaluateCustomSignalWithInvalidContextReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "abc").build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -141,11 +135,10 @@ public void testEvaluatePercentWithoutRandomizationIdReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -156,11 +149,10 @@ public void testEvaluatePercentWithoutRandomizationIdReturnsDefaultValue() public void testEvaluatePercentReturnsConditionalValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("randomizationId", "user").build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -172,11 +164,10 @@ public void testEvaluateWithoutDefaultValueReturnsEmptyString() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -189,11 +180,10 @@ public void testEvaluateWithInvalidCacheValueThrowsException() KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); String invalidJsonString = "abc"; - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(invalidJsonString) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(invalidJsonString) + .build(); FirebaseRemoteConfigException error = assertThrows(FirebaseRemoteConfigException.class, () -> template.evaluate(context)); @@ -206,11 +196,10 @@ public void testEvaluateWithInvalidCacheValueThrowsException() public void testEvaluateWithInAppDefaultReturnsEmptyString() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -221,11 +210,10 @@ public void testEvaluateWithInAppDefaultReturnsEmptyString() throws Exception { public void testEvaluateWithDerivedInAppDefaultReturnsDefaultValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -236,11 +224,10 @@ public void testEvaluateWithDerivedInAppDefaultReturnsDefaultValue() throws Exce public void testEvaluateWithMultipleConditionReturnsConditionalValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "99").build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -251,14 +238,13 @@ public void testEvaluateWithMultipleConditionReturnsConditionalValue() throws Ex public void testEvaluateWithChainedAndConditionReturnsDefaultValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "100") - .put("premium users", 20) - .put("randomizationId", "user") - .build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + .put("premium users", 20) + .put("randomizationId", "user") + .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -268,13 +254,11 @@ public void testEvaluateWithChainedAndConditionReturnsDefaultValue() throws Exce @Test public void testEvaluateWithChainedAndConditionReturnsConditionalValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); - KeysAndValues context = - new KeysAndValues.Builder().put("users", "99").put("premium users", "30").build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + KeysAndValues context = new KeysAndValues.Builder().put("users", "99").put("premium users", "30").build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -285,11 +269,10 @@ public void testEvaluateWithChainedAndConditionReturnsConditionalValue() throws public void testGetEvaluateConfigOnInvalidTypeReturnsDefaultValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("randomizationId", "user").build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -300,11 +283,10 @@ public void testGetEvaluateConfigOnInvalidTypeReturnsDefaultValue() throws Excep public void testGetEvaluateConfigInvalidKeyReturnsStaticValueSource() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -315,11 +297,10 @@ public void testGetEvaluateConfigInvalidKeyReturnsStaticValueSource() throws Exc public void testGetEvaluateConfigInAppDefaultConfigReturnsDefaultValueSource() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().put("In-app default", "abc").build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -328,14 +309,12 @@ public void testGetEvaluateConfigInAppDefaultConfigReturnsDefaultValueSource() t @Test public void testGetEvaluateConfigUnsetDefaultConfigReturnsDefaultValueSource() throws Exception { - KeysAndValues defaultConfig = - new KeysAndValues.Builder().put("Unset default config", "abc").build(); + KeysAndValues defaultConfig = new KeysAndValues.Builder().put("Unset default config", "abc").build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = - new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -349,27 +328,25 @@ private FirebaseRemoteConfig getRemoteConfig(FirebaseRemoteConfigClient client) return new FirebaseRemoteConfig(app, client); } -@Test -public void testLoad() throws Exception { + @Test + public void testLoad() throws Exception { // 1. Define the template data that the mock client will return. // This is the EXPECTED state after `load()` is called. final String expectedTemplateJsonAfterLoad = new ServerTemplateData().setETag(TEST_ETAG).toJSON(); // 2. Mock the HTTP client to return the predefined response. - MockRemoteConfigClient client = - MockRemoteConfigClient.fromServerTemplate(expectedTemplateJsonAfterLoad); + MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate(expectedTemplateJsonAfterLoad); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); // 3. Build the template instance. - // It's initialized with a complex `cacheTemplate` to ensure `load()` properly overwrites it. - KeysAndValues defaultConfig = - new KeysAndValues.Builder().put("Unset default config", "abc").build(); - ServerTemplate template = - remoteConfig - .serverTemplateBuilder() - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) // This is the initial state before `load()` - .build(); + // It's initialized with a complex `cacheTemplate` to ensure `load()` properly + // overwrites it. + KeysAndValues defaultConfig = new KeysAndValues.Builder().put("Unset default config", "abc").build(); + ServerTemplate template = remoteConfig + .serverTemplateBuilder() + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) // This is the initial state before `load()` + .build(); // 4. Call the load method, which fetches the new template from the mock client. ApiFuture loadFuture = template.load(); @@ -378,37 +355,39 @@ public void testLoad() throws Exception { // 5. Get the ACTUAL state of the template after `load()` has executed. String actualJsonAfterLoad = template.toJson(); - // 6. Assert that the template's state has been updated to match what the mock client returned. + // 6. Assert that the template's state has been updated to match what the mock + // client returned. // Parsing to JsonElement performs a deep, order-insensitive comparison. JsonElement expectedJson = JsonParser.parseString(expectedTemplateJsonAfterLoad); JsonElement actualJson = JsonParser.parseString(actualJsonAfterLoad); assertEquals(expectedJson, actualJson); -} + } -@Test -public void testBuilderParsesCachedTemplateCorrectly() throws FirebaseRemoteConfigException { - // Arrange: + @Test + public void testBuilderParsesCachedTemplateCorrectly() throws FirebaseRemoteConfigException { + // Arrange: // 1. Create a canonical JSON string by parsing the input file and then // re-serializing it. This gives us the precise expected output format, // accounting for any formatting or default value differences. ServerTemplateData canonicalData = ServerTemplateData.fromJSON(cacheTemplate); String expectedJsonString = canonicalData.toJSON(); - // Act: + // Act: // 2. Build a ServerTemplate instance from the original cached JSON string, // which triggers the parsing logic we want to test. ServerTemplate template = new ServerTemplateImpl.Builder(null) - .cachedTemplate(cacheTemplate) - .build(); + .cachedTemplate(cacheTemplate) + .build(); - // Assert: - // 3. Compare the JSON from the newly built template against the canonical version. + // Assert: + // 3. Compare the JSON from the newly built template against the canonical + // version. // This verifies that the internal state was parsed and stored correctly. // Using JsonElement ensures the comparison is not affected by key order. JsonElement expectedJsonTree = JsonParser.parseString(expectedJsonString); JsonElement actualJsonTree = JsonParser.parseString(template.toJson()); assertEquals(expectedJsonTree, actualJsonTree); -} + } } diff --git a/src/test/resources/getServerRemoteConfig.json b/src/test/resources/getServerRemoteConfig.json index 8a73ae8f..19967e95 100644 --- a/src/test/resources/getServerRemoteConfig.json +++ b/src/test/resources/getServerRemoteConfig.json @@ -139,4 +139,4 @@ "updateTime": "2020-11-15T06:57:26.342763941Z", "description": "promo config" } -} +} \ No newline at end of file diff --git a/src/test/resources/getServerTemplateData.json b/src/test/resources/getServerTemplateData.json index 81da133f..91e3971e 100644 --- a/src/test/resources/getServerTemplateData.json +++ b/src/test/resources/getServerTemplateData.json @@ -132,7 +132,7 @@ } } }, - "Derived in-app default": { + "Derived in-app default": { "defaultValue": { "value": "Default value" }, @@ -178,4 +178,4 @@ "updateTime": "2020-11-15T06:57:26.342763941Z", "description": "promo config" } -} +} \ No newline at end of file From d75cfb25b66f4c158f2a6f59db2a6e825387dd08 Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 22:56:36 +0530 Subject: [PATCH 17/21] fix indentations --- .../remoteconfig/ConditionEvaluator.java | 162 +++---- .../FirebaseRemoteConfigClientImplTest.java | 411 ++++++++++-------- .../FirebaseRemoteConfigTest.java | 108 +++-- .../remoteconfig/ServerTemplateImplTest.java | 242 ++++++----- 4 files changed, 503 insertions(+), 420 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java index 436a3e37..ae6bf5e9 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java +++ b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java @@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableMap; import com.google.firebase.internal.NonNull; import com.google.firebase.internal.Nullable; - import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; @@ -36,7 +35,6 @@ import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import java.util.stream.Collectors; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,34 +45,36 @@ final class ConditionEvaluator { /** * Evaluates server conditions and assigns a boolean value to each condition. - * + * * @param conditions List of conditions which are to be evaluated. - * @param context A map with additional metadata used during evaluation. + * @param context A map with additional metadata used during evaluation. * @return A map of condition to evaluated value. */ @NonNull Map evaluateConditions( - @NonNull List conditions, - @Nullable KeysAndValues context) { + @NonNull List conditions, @Nullable KeysAndValues context) { checkNotNull(conditions, "List of conditions must not be null."); checkArgument(!conditions.isEmpty(), "List of conditions must not be empty."); if (context == null || conditions.isEmpty()) { return ImmutableMap.of(); } - KeysAndValues evaluationContext = context != null - ? context - : new KeysAndValues.Builder().build(); - - Map evaluatedConditions = conditions.stream() - .collect(ImmutableMap.toImmutableMap( - ServerCondition::getName, - condition -> evaluateCondition(condition.getCondition(), evaluationContext, /* nestingLevel= */0))); + KeysAndValues evaluationContext = + context != null ? context : new KeysAndValues.Builder().build(); + + Map evaluatedConditions = + conditions.stream() + .collect( + ImmutableMap.toImmutableMap( + ServerCondition::getName, + condition -> + evaluateCondition( + condition.getCondition(), evaluationContext, /* nestingLevel= */ 0))); return evaluatedConditions; } - private boolean evaluateCondition(OneOfCondition condition, KeysAndValues context, - int nestingLevel) { + private boolean evaluateCondition( + OneOfCondition condition, KeysAndValues context, int nestingLevel) { if (nestingLevel > MAX_CONDITION_RECURSION_DEPTH) { logger.warn("Maximum condition recursion depth exceeded."); return false; @@ -97,29 +97,30 @@ private boolean evaluateCondition(OneOfCondition condition, KeysAndValues contex return false; } - private boolean evaluateOrCondition(OrCondition condition, KeysAndValues context, - int nestingLevel) { + private boolean evaluateOrCondition( + OrCondition condition, KeysAndValues context, int nestingLevel) { return condition.getConditions().stream() .anyMatch(subCondition -> evaluateCondition(subCondition, context, nestingLevel + 1)); } - private boolean evaluateAndCondition(AndCondition condition, KeysAndValues context, - int nestingLevel) { + private boolean evaluateAndCondition( + AndCondition condition, KeysAndValues context, int nestingLevel) { return condition.getConditions().stream() .allMatch(subCondition -> evaluateCondition(subCondition, context, nestingLevel + 1)); } - private boolean evaluateCustomSignalCondition(CustomSignalCondition condition, - KeysAndValues context) { + private boolean evaluateCustomSignalCondition( + CustomSignalCondition condition, KeysAndValues context) { CustomSignalOperator customSignalOperator = condition.getCustomSignalOperator(); String customSignalKey = condition.getCustomSignalKey(); - ImmutableList targetCustomSignalValues = ImmutableList.copyOf( - condition.getTargetCustomSignalValues()); + ImmutableList targetCustomSignalValues = + ImmutableList.copyOf(condition.getTargetCustomSignalValues()); if (targetCustomSignalValues.isEmpty()) { - logger.warn(String.format( - "Values must be assigned to all custom signal fields. Operator:%s, Key:%s, Values:%s", - customSignalOperator, customSignalKey, targetCustomSignalValues)); + logger.warn( + String.format( + "Values must be assigned to all custom signal fields. Operator:%s, Key:%s, Values:%s", + customSignalOperator, customSignalKey, targetCustomSignalValues)); return false; } @@ -131,64 +132,65 @@ private boolean evaluateCustomSignalCondition(CustomSignalCondition condition, switch (customSignalOperator) { // String operations. case STRING_CONTAINS: - return compareStrings(targetCustomSignalValues, customSignalValue, + return compareStrings( + targetCustomSignalValues, + customSignalValue, (customSignal, targetSignal) -> customSignal.contains(targetSignal)); case STRING_DOES_NOT_CONTAIN: - return !compareStrings(targetCustomSignalValues, customSignalValue, + return !compareStrings( + targetCustomSignalValues, + customSignalValue, (customSignal, targetSignal) -> customSignal.contains(targetSignal)); case STRING_EXACTLY_MATCHES: - return compareStrings(targetCustomSignalValues, customSignalValue, + return compareStrings( + targetCustomSignalValues, + customSignalValue, (customSignal, targetSignal) -> customSignal.equals(targetSignal)); case STRING_CONTAINS_REGEX: - return compareStrings(targetCustomSignalValues, customSignalValue, + return compareStrings( + targetCustomSignalValues, + customSignalValue, (customSignal, targetSignal) -> compareStringRegex(customSignal, targetSignal)); // Numeric operations. case NUMERIC_LESS_THAN: - return compareNumbers(targetCustomSignalValues, customSignalValue, - (result) -> result < 0); + return compareNumbers(targetCustomSignalValues, customSignalValue, (result) -> result < 0); case NUMERIC_LESS_EQUAL: - return compareNumbers(targetCustomSignalValues, customSignalValue, - (result) -> result <= 0); + return compareNumbers(targetCustomSignalValues, customSignalValue, (result) -> result <= 0); case NUMERIC_EQUAL: - return compareNumbers(targetCustomSignalValues, customSignalValue, - (result) -> result == 0); + return compareNumbers(targetCustomSignalValues, customSignalValue, (result) -> result == 0); case NUMERIC_NOT_EQUAL: - return compareNumbers(targetCustomSignalValues, customSignalValue, - (result) -> result != 0); + return compareNumbers(targetCustomSignalValues, customSignalValue, (result) -> result != 0); case NUMERIC_GREATER_THAN: - return compareNumbers(targetCustomSignalValues, customSignalValue, - (result) -> result > 0); + return compareNumbers(targetCustomSignalValues, customSignalValue, (result) -> result > 0); case NUMERIC_GREATER_EQUAL: - return compareNumbers(targetCustomSignalValues, customSignalValue, - (result) -> result >= 0); + return compareNumbers(targetCustomSignalValues, customSignalValue, (result) -> result >= 0); // Semantic operations. case SEMANTIC_VERSION_EQUAL: - return compareSemanticVersions(targetCustomSignalValues, customSignalValue, - (result) -> result == 0); + return compareSemanticVersions( + targetCustomSignalValues, customSignalValue, (result) -> result == 0); case SEMANTIC_VERSION_GREATER_EQUAL: - return compareSemanticVersions(targetCustomSignalValues, customSignalValue, - (result) -> result >= 0); + return compareSemanticVersions( + targetCustomSignalValues, customSignalValue, (result) -> result >= 0); case SEMANTIC_VERSION_GREATER_THAN: - return compareSemanticVersions(targetCustomSignalValues, customSignalValue, - (result) -> result > 0); + return compareSemanticVersions( + targetCustomSignalValues, customSignalValue, (result) -> result > 0); case SEMANTIC_VERSION_LESS_EQUAL: - return compareSemanticVersions(targetCustomSignalValues, customSignalValue, - (result) -> result <= 0); + return compareSemanticVersions( + targetCustomSignalValues, customSignalValue, (result) -> result <= 0); case SEMANTIC_VERSION_LESS_THAN: - return compareSemanticVersions(targetCustomSignalValues, customSignalValue, - (result) -> result < 0); + return compareSemanticVersions( + targetCustomSignalValues, customSignalValue, (result) -> result < 0); case SEMANTIC_VERSION_NOT_EQUAL: - return compareSemanticVersions(targetCustomSignalValues, customSignalValue, - (result) -> result != 0); + return compareSemanticVersions( + targetCustomSignalValues, customSignalValue, (result) -> result != 0); default: return false; } } - private boolean evaluatePercentCondition(PercentCondition condition, - KeysAndValues context) { + private boolean evaluatePercentCondition(PercentCondition condition, KeysAndValues context) { if (!context.containsKey("randomizationId")) { logger.warn("Percentage operation must not be performed without randomizationId"); return false; @@ -198,18 +200,16 @@ private boolean evaluatePercentCondition(PercentCondition condition, // The micro-percent interval to be used with the BETWEEN operator. MicroPercentRange microPercentRange = condition.getMicroPercentRange(); - int microPercentUpperBound = microPercentRange != null - ? microPercentRange.getMicroPercentUpperBound() - : 0; - int microPercentLowerBound = microPercentRange != null - ? microPercentRange.getMicroPercentLowerBound() - : 0; + int microPercentUpperBound = + microPercentRange != null ? microPercentRange.getMicroPercentUpperBound() : 0; + int microPercentLowerBound = + microPercentRange != null ? microPercentRange.getMicroPercentLowerBound() : 0; // The limit of percentiles to target in micro-percents when using the // LESS_OR_EQUAL and GREATER_THAN operators. The value must be in the range [0 // and 100000000]. int microPercent = condition.getMicroPercent(); - BigInteger microPercentile = getMicroPercentile(condition.getSeed(), - context.get("randomizationId")); + BigInteger microPercentile = + getMicroPercentile(condition.getSeed(), context.get("randomizationId")); switch (operator) { case LESS_OR_EQUAL: return microPercentile.compareTo(BigInteger.valueOf(microPercent)) <= 0; @@ -247,9 +247,12 @@ private BigInteger hashSeededRandomizationId(String seededRandomizationId) { } } - private boolean compareStrings(ImmutableList targetValues, String customSignal, + private boolean compareStrings( + ImmutableList targetValues, + String customSignal, BiPredicate compareFunction) { - return targetValues.stream().anyMatch(targetValue -> compareFunction.test(customSignal, targetValue)); + return targetValues.stream() + .anyMatch(targetValue -> compareFunction.test(customSignal, targetValue)); } private boolean compareStringRegex(String customSignal, String targetSignal) { @@ -260,12 +263,13 @@ private boolean compareStringRegex(String customSignal, String targetSignal) { } } - private boolean compareNumbers(ImmutableList targetValues, String customSignal, - IntPredicate compareFunction) { + private boolean compareNumbers( + ImmutableList targetValues, String customSignal, IntPredicate compareFunction) { if (targetValues.size() != 1) { - logger.warn(String.format( - "Target values must contain 1 element for numeric operations. Target Value: %s", - targetValues)); + logger.warn( + String.format( + "Target values must contain 1 element for numeric operations. Target Value: %s", + targetValues)); return false; } @@ -275,23 +279,22 @@ private boolean compareNumbers(ImmutableList targetValues, String custom int comparisonResult = Double.compare(customSignalDouble, targetValue); return compareFunction.test(comparisonResult); } catch (NumberFormatException e) { - logger.warn("Error parsing numeric values: customSignal=%s, targetValue=%s", + logger.warn( + "Error parsing numeric values: customSignal=%s, targetValue=%s", customSignal, targetValues.get(0), e); return false; } } - private boolean compareSemanticVersions(ImmutableList targetValues, - String customSignal, - IntPredicate compareFunction) { + private boolean compareSemanticVersions( + ImmutableList targetValues, String customSignal, IntPredicate compareFunction) { if (targetValues.size() != 1) { logger.warn(String.format("Target values must contain 1 element for semantic operation.")); return false; } String targetValueString = targetValues.get(0); - if (!validateSemanticVersion(targetValueString) - || !validateSemanticVersion(customSignal)) { + if (!validateSemanticVersion(targetValueString) || !validateSemanticVersion(customSignal)) { return false; } @@ -300,7 +303,8 @@ private boolean compareSemanticVersions(ImmutableList targetValues, int maxLength = 5; if (targetVersion.size() > maxLength || customSignalVersion.size() > maxLength) { - logger.warn("Semantic version max length(%s) exceeded. Target: %s, Custom Signal: %s", + logger.warn( + "Semantic version max length(%s) exceeded. Target: %s, Custom Signal: %s", maxLength, targetValueString, customSignal); return false; } diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index 4ccf906d..78a5c276 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -61,144 +61,156 @@ public class FirebaseRemoteConfigClientImplTest { - private static final String TEST_REMOTE_CONFIG_URL = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; - private static final String TEST_SERVER_REMOTE_CONFIG_URL = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; + private static final String TEST_REMOTE_CONFIG_URL = + "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; + private static final String TEST_SERVER_REMOTE_CONFIG_URL = + "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; private static final List HTTP_STATUS_CODES = ImmutableList.of(401, 404, 500); - private static final Map HTTP_STATUS_TO_ERROR_CODE = ImmutableMap.of( - 401, ErrorCode.UNAUTHENTICATED, - 404, ErrorCode.NOT_FOUND, - 500, ErrorCode.INTERNAL); + private static final Map HTTP_STATUS_TO_ERROR_CODE = + ImmutableMap.of( + 401, ErrorCode.UNAUTHENTICATED, + 404, ErrorCode.NOT_FOUND, + 500, ErrorCode.INTERNAL); - private static final String MOCK_TEMPLATE_RESPONSE = TestUtils - .loadResource("getRemoteConfig.json"); + private static final String MOCK_TEMPLATE_RESPONSE = + TestUtils.loadResource("getRemoteConfig.json"); - private static final String MOCK_SERVER_TEMPLATE_RESPONSE = TestUtils - .loadResource("getServerRemoteConfig.json"); + private static final String MOCK_SERVER_TEMPLATE_RESPONSE = + TestUtils.loadResource("getServerRemoteConfig.json"); - private static final String MOCK_LIST_VERSIONS_RESPONSE = TestUtils - .loadResource("listRemoteConfigVersions.json"); + private static final String MOCK_LIST_VERSIONS_RESPONSE = + TestUtils.loadResource("listRemoteConfigVersions.json"); private static final String TEST_ETAG = "etag-123456789012-1"; - private static final Map EXPECTED_PARAMETERS = ImmutableMap.of( - "welcome_message_text", - new Parameter() - .setDefaultValue(ParameterValue.of("welcome to app")) - .setConditionalValues( - ImmutableMap.of( - "ios_en", ParameterValue.of("welcome to app en"))) - .setDescription("text for welcome message!") - .setValueType(ParameterValueType.STRING), - "header_text", - new Parameter() - .setDefaultValue(ParameterValue.inAppDefault()) - .setValueType(ParameterValueType.STRING)); - - private static final Map EXPECTED_PARAMETER_GROUPS = ImmutableMap.of( - "new menu", - new ParameterGroup() - .setDescription("New Menu") - .setParameters( - ImmutableMap.of( - "pumpkin_spice_season", - new Parameter() - .setDefaultValue(ParameterValue.of("true")) - .setDescription("Whether it's currently pumpkin spice season.") - .setValueType(ParameterValueType.BOOLEAN)))); - - private static final List EXPECTED_CONDITIONS = ImmutableList.of( - new Condition("ios_en", "device.os == 'ios' && device.country in ['us', 'uk']") - .setTagColor(TagColor.INDIGO), - new Condition("android_en", "device.os == 'android' && device.country in ['us', 'uk']")); - - private static final List EXPECTED_SERVER_CONDITIONS = ImmutableList.of( - new ServerCondition("custom_signal", null) - .setServerCondition( - new OneOfCondition() - .setOrCondition( - new OrCondition( - ImmutableList.of( - new OneOfCondition() - .setAndCondition( - new AndCondition( - ImmutableList.of( - new OneOfCondition() - .setCustomSignal( - new CustomSignalCondition( - "users", - CustomSignalOperator.NUMERIC_LESS_THAN, - new ArrayList<>( - ImmutableList.of("100"))))))))))), - new ServerCondition("percent", null) - .setServerCondition( - new OneOfCondition() - .setOrCondition( - new OrCondition( - ImmutableList.of( - new OneOfCondition() - .setAndCondition( - new AndCondition( - ImmutableList.of( - new OneOfCondition() - .setPercent( - new PercentCondition( - new MicroPercentRange( - 12000000, 100000000), - PercentConditionOperator.BETWEEN, - "3maarirs9xzs"))))))))), - new ServerCondition("chained_conditions", null) - .setServerCondition( - new OneOfCondition() - .setOrCondition( - new OrCondition( - ImmutableList.of( - new OneOfCondition() - .setAndCondition( - new AndCondition( - ImmutableList.of( - new OneOfCondition() - .setCustomSignal( - new CustomSignalCondition( - "users", - CustomSignalOperator.NUMERIC_LESS_THAN, - new ArrayList<>( - ImmutableList.of("100")))), - new OneOfCondition() - .setCustomSignal( - new CustomSignalCondition( - "premium users", - CustomSignalOperator.NUMERIC_GREATER_THAN, - new ArrayList<>( - ImmutableList.of("20")))), - new OneOfCondition() - .setPercent( - new PercentCondition( - new MicroPercentRange( - 25000000, 100000000), - PercentConditionOperator.BETWEEN, - "cla24qoibb61")))))))))); - - private static final Version EXPECTED_VERSION = new Version( - new TemplateResponse.VersionResponse() - .setVersionNumber("17") - .setUpdateOrigin("ADMIN_SDK_NODE") - .setUpdateType("INCREMENTAL_UPDATE") - .setUpdateUser( - new TemplateResponse.UserResponse() - .setEmail("firebase-user@account.com") - .setName("dev-admin") - .setImageUrl("http://image.jpg")) - .setUpdateTime("2020-11-15T06:57:26.342763941Z") - .setDescription("promo config")); - - private static final Template EXPECTED_TEMPLATE = new Template() - .setETag(TEST_ETAG) - .setParameters(EXPECTED_PARAMETERS) - .setConditions(EXPECTED_CONDITIONS) - .setParameterGroups(EXPECTED_PARAMETER_GROUPS) - .setVersion(EXPECTED_VERSION); + private static final Map EXPECTED_PARAMETERS = + ImmutableMap.of( + "welcome_message_text", + new Parameter() + .setDefaultValue(ParameterValue.of("welcome to app")) + .setConditionalValues( + ImmutableMap.of( + "ios_en", ParameterValue.of("welcome to app en"))) + .setDescription("text for welcome message!") + .setValueType(ParameterValueType.STRING), + "header_text", + new Parameter() + .setDefaultValue(ParameterValue.inAppDefault()) + .setValueType(ParameterValueType.STRING)); + + private static final Map EXPECTED_PARAMETER_GROUPS = + ImmutableMap.of( + "new menu", + new ParameterGroup() + .setDescription("New Menu") + .setParameters( + ImmutableMap.of( + "pumpkin_spice_season", + new Parameter() + .setDefaultValue(ParameterValue.of("true")) + .setDescription("Whether it's currently pumpkin spice season.") + .setValueType(ParameterValueType.BOOLEAN)))); + + private static final List EXPECTED_CONDITIONS = + ImmutableList.of( + new Condition("ios_en", "device.os == 'ios' && device.country in ['us', 'uk']") + .setTagColor(TagColor.INDIGO), + new Condition("android_en", "device.os == 'android' && device.country in ['us', 'uk']")); + + private static final List EXPECTED_SERVER_CONDITIONS = + ImmutableList.of( + new ServerCondition("custom_signal", null) + .setServerCondition( + new OneOfCondition() + .setOrCondition( + new OrCondition( + ImmutableList.of( + new OneOfCondition() + .setAndCondition( + new AndCondition( + ImmutableList.of( + new OneOfCondition() + .setCustomSignal( + new CustomSignalCondition( + "users", + CustomSignalOperator + .NUMERIC_LESS_THAN, + new ArrayList<>( + ImmutableList.of("100"))))))))))), + new ServerCondition("percent", null) + .setServerCondition( + new OneOfCondition() + .setOrCondition( + new OrCondition( + ImmutableList.of( + new OneOfCondition() + .setAndCondition( + new AndCondition( + ImmutableList.of( + new OneOfCondition() + .setPercent( + new PercentCondition( + new MicroPercentRange( + 12000000, 100000000), + PercentConditionOperator.BETWEEN, + "3maarirs9xzs"))))))))), + new ServerCondition("chained_conditions", null) + .setServerCondition( + new OneOfCondition() + .setOrCondition( + new OrCondition( + ImmutableList.of( + new OneOfCondition() + .setAndCondition( + new AndCondition( + ImmutableList.of( + new OneOfCondition() + .setCustomSignal( + new CustomSignalCondition( + "users", + CustomSignalOperator + .NUMERIC_LESS_THAN, + new ArrayList<>( + ImmutableList.of("100")))), + new OneOfCondition() + .setCustomSignal( + new CustomSignalCondition( + "premium users", + CustomSignalOperator + .NUMERIC_GREATER_THAN, + new ArrayList<>( + ImmutableList.of("20")))), + new OneOfCondition() + .setPercent( + new PercentCondition( + new MicroPercentRange( + 25000000, 100000000), + PercentConditionOperator.BETWEEN, + "cla24qoibb61")))))))))); + + private static final Version EXPECTED_VERSION = + new Version( + new TemplateResponse.VersionResponse() + .setVersionNumber("17") + .setUpdateOrigin("ADMIN_SDK_NODE") + .setUpdateType("INCREMENTAL_UPDATE") + .setUpdateUser( + new TemplateResponse.UserResponse() + .setEmail("firebase-user@account.com") + .setName("dev-admin") + .setImageUrl("http://image.jpg")) + .setUpdateTime("2020-11-15T06:57:26.342763941Z") + .setDescription("promo config")); + + private static final Template EXPECTED_TEMPLATE = + new Template() + .setETag(TEST_ETAG) + .setParameters(EXPECTED_PARAMETERS) + .setConditions(EXPECTED_CONDITIONS) + .setParameterGroups(EXPECTED_PARAMETER_GROUPS) + .setVersion(EXPECTED_VERSION); private MockLowLevelHttpResponse response; private TestResponseInterceptor interceptor; @@ -228,18 +240,20 @@ public void testGetTemplate() throws Exception { @Test public void testGetTemplateWithTimestampUpToNanosecondPrecision() throws Exception { - List timestamps = ImmutableList.of( - "2020-11-15T06:57:26.342Z", - "2020-11-15T06:57:26.342763Z", - "2020-11-15T06:57:26.342763941Z"); + List timestamps = + ImmutableList.of( + "2020-11-15T06:57:26.342Z", + "2020-11-15T06:57:26.342763Z", + "2020-11-15T06:57:26.342763941Z"); for (String timestamp : timestamps) { response.addHeader("etag", TEST_ETAG); - String templateResponse = "{\"version\": {" - + " \"versionNumber\": \"17\"," - + " \"updateTime\": \"" - + timestamp - + "\"" - + " }}"; + String templateResponse = + "{\"version\": {" + + " \"versionNumber\": \"17\"," + + " \"updateTime\": \"" + + timestamp + + "\"" + + " }}"; response.setContent(templateResponse); Template receivedTemplate = client.getTemplate(); @@ -380,15 +394,17 @@ public void testGetTemplateErrorWithMalformedResponse() { @Test public void testGetTemplateErrorWithDetails() { for (int code : HTTP_STATUS_CODES) { - response.setStatusCode(code).setContent( - "{\"error\": {\"status\": \"INVALID_ARGUMENT\", \"message\": \"test error\"}}"); + response + .setStatusCode(code) + .setContent( + "{\"error\": {\"status\": \"INVALID_ARGUMENT\", \"message\": \"test error\"}}"); try { client.getTemplate(); fail("No error thrown for HTTP error"); } catch (FirebaseRemoteConfigException error) { - checkExceptionFromHttpResponse(error, ErrorCode.INVALID_ARGUMENT, null, "test error", - HttpMethods.GET); + checkExceptionFromHttpResponse( + error, ErrorCode.INVALID_ARGUMENT, null, "test error", HttpMethods.GET); } checkGetRequestHeader(interceptor.getLastRequest()); } @@ -397,16 +413,21 @@ public void testGetTemplateErrorWithDetails() { @Test public void testGetTemplateErrorWithRcError() { for (int code : HTTP_STATUS_CODES) { - response.setStatusCode(code).setContent( - "{\"error\": {\"status\": \"INVALID_ARGUMENT\", " - + "\"message\": \"[INVALID_ARGUMENT]: test error\"}}"); + response + .setStatusCode(code) + .setContent( + "{\"error\": {\"status\": \"INVALID_ARGUMENT\", " + + "\"message\": \"[INVALID_ARGUMENT]: test error\"}}"); try { client.getTemplate(); fail("No error thrown for HTTP error"); } catch (FirebaseRemoteConfigException error) { - checkExceptionFromHttpResponse(error, ErrorCode.INVALID_ARGUMENT, - RemoteConfigErrorCode.INVALID_ARGUMENT, "[INVALID_ARGUMENT]: test error", + checkExceptionFromHttpResponse( + error, + ErrorCode.INVALID_ARGUMENT, + RemoteConfigErrorCode.INVALID_ARGUMENT, + "[INVALID_ARGUMENT]: test error", HttpMethods.GET); } checkGetRequestHeader(interceptor.getLastRequest()); @@ -422,8 +443,9 @@ public void testGetTemplateAtVersionWithNullString() throws Exception { @Test public void testGetTemplateAtVersionWithInvalidString() throws Exception { - List invalidVersionStrings = ImmutableList.of( - "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); + List invalidVersionStrings = + ImmutableList.of( + "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); for (String version : invalidVersionStrings) { try { @@ -655,12 +677,13 @@ public void testPublishTemplateWithValidTemplateAndForceTrue() throws Exception public void testPublishTemplateWithValidTemplateAndValidateOnlyTrue() throws Exception { response.addHeader("etag", TEST_ETAG); response.setContent(MOCK_TEMPLATE_RESPONSE); - Template expectedTemplate = new Template() - .setETag("etag-123456789012-45") - .setParameters(EXPECTED_PARAMETERS) - .setConditions(EXPECTED_CONDITIONS) - .setParameterGroups(EXPECTED_PARAMETER_GROUPS) - .setVersion(EXPECTED_VERSION); + Template expectedTemplate = + new Template() + .setETag("etag-123456789012-45") + .setParameters(EXPECTED_PARAMETERS) + .setConditions(EXPECTED_CONDITIONS) + .setParameterGroups(EXPECTED_PARAMETER_GROUPS) + .setVersion(EXPECTED_VERSION); Template validatedTemplate = client.publishTemplate(expectedTemplate, true, false); @@ -851,8 +874,9 @@ public void testRollbackWithNullString() throws Exception { @Test public void testRollbackWithInvalidString() throws Exception { - List invalidVersionStrings = ImmutableList.of( - "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); + List invalidVersionStrings = + ImmutableList.of( + "", " ", "abc", "t123", "123t", "t123t", "12t3", "#$*&^", "-123", "+123", "123.4"); for (String version : invalidVersionStrings) { try { @@ -1081,26 +1105,28 @@ public void testListVersionsWithNullOptions() throws Exception { public void testListVersionsWithOptions() throws Exception { response.setContent(MOCK_LIST_VERSIONS_RESPONSE); - TemplateResponse.ListVersionsResponse versionsList = client.listVersions( - ListVersionsOptions.builder() - .setPageSize(10) - .setPageToken("token") - .setStartTimeMillis(1605219122000L) - .setEndTimeMillis(1606245035000L) - .setEndVersionNumber("29") - .build()); + TemplateResponse.ListVersionsResponse versionsList = + client.listVersions( + ListVersionsOptions.builder() + .setPageSize(10) + .setPageToken("token") + .setStartTimeMillis(1605219122000L) + .setEndTimeMillis(1606245035000L) + .setEndVersionNumber("29") + .build()); assertTrue(versionsList.hasVersions()); HttpRequest request = interceptor.getLastRequest(); - String urlWithoutParameters = request.getUrl().toString().substring(0, - request.getUrl().toString().lastIndexOf('?')); - final Map expectedQuery = ImmutableMap.of( - "endVersionNumber", "29", - "pageSize", "10", - "pageToken", "token", - "startTime", "2020-11-12T22:12:02.000000000Z", - "endTime", "2020-11-24T19:10:35.000000000Z"); + String urlWithoutParameters = + request.getUrl().toString().substring(0, request.getUrl().toString().lastIndexOf('?')); + final Map expectedQuery = + ImmutableMap.of( + "endVersionNumber", "29", + "pageSize", "10", + "pageToken", "token", + "startTime", "2020-11-12T22:12:02.000000000Z", + "endTime", "2020-11-24T19:10:35.000000000Z"); Map actualQuery = new HashMap<>(); String query = request.getUrl().toURI().getQuery(); String[] pairs = query.split("&"); @@ -1287,10 +1313,11 @@ public void testBuilderNullRequestFactory() { @Test public void testFromApp() throws IOException { - FirebaseOptions options = FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); + FirebaseOptions options = + FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); FirebaseApp app = FirebaseApp.initializeApp(options); try { @@ -1299,7 +1326,8 @@ public void testFromApp() throws IOException { assertEquals(TEST_REMOTE_CONFIG_URL, client.getRemoteConfigUrl()); assertSame(options.getJsonFactory(), client.getJsonFactory()); - HttpRequest request = client.getRequestFactory().buildGetRequest(new GenericUrl("https://example.com")); + HttpRequest request = + client.getRequestFactory().buildGetRequest(new GenericUrl("https://example.com")); assertEquals("Bearer test-token", request.getHeaders().getAuthorization()); } finally { app.delete(); @@ -1308,7 +1336,8 @@ public void testFromApp() throws IOException { private FirebaseRemoteConfigClientImpl initRemoteConfigClient( MockLowLevelHttpResponse mockResponse, HttpResponseInterceptor interceptor) { - MockHttpTransport transport = new MockHttpTransport.Builder().setLowLevelHttpResponse(mockResponse).build(); + MockHttpTransport transport = + new MockHttpTransport.Builder().setLowLevelHttpResponse(mockResponse).build(); return FirebaseRemoteConfigClientImpl.builder() .setProjectId("test-project") @@ -1431,18 +1460,20 @@ public void testGetServerTemplate() throws Exception { @Test public void testGetServerTemplateWithTimestampUpToNanosecondPrecision() throws Exception { - List timestamps = ImmutableList.of( - "2020-11-15T06:57:26.342Z", - "2020-11-15T06:57:26.342763Z", - "2020-11-15T06:57:26.342763941Z"); + List timestamps = + ImmutableList.of( + "2020-11-15T06:57:26.342Z", + "2020-11-15T06:57:26.342763Z", + "2020-11-15T06:57:26.342763941Z"); for (String timestamp : timestamps) { response.addHeader("etag", TEST_ETAG); - String templateResponse = "{\"version\": {" - + " \"versionNumber\": \"17\"," - + " \"updateTime\": \"" - + timestamp - + "\"" - + " }}"; + String templateResponse = + "{\"version\": {" + + " \"versionNumber\": \"17\"," + + " \"updateTime\": \"" + + timestamp + + "\"" + + " }}"; response.setContent(templateResponse); String receivedTemplate = client.getServerTemplate(); diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index e10ffe2a..81124f38 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -34,18 +34,16 @@ import org.junit.After; import org.junit.Test; -/** - * Unit tests - * for {@link FirebaseRemoteConfig}. - */ +/** Unit tests for {@link FirebaseRemoteConfig}. */ public class FirebaseRemoteConfigTest { - private static final FirebaseOptions TEST_OPTIONS = FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); - private static final FirebaseRemoteConfigException TEST_EXCEPTION = new FirebaseRemoteConfigException( - ErrorCode.INTERNAL, "Test error message"); + private static final FirebaseOptions TEST_OPTIONS = + FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); + private static final FirebaseRemoteConfigException TEST_EXCEPTION = + new FirebaseRemoteConfigException(ErrorCode.INTERNAL, "Test error message"); @After public void tearDown() { @@ -79,7 +77,8 @@ public void testDefaultRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; + String expectedUrl = + "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getRemoteConfigUrl()); } @@ -92,7 +91,8 @@ public void testDefaultServerRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; + String expectedUrl = + "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getServerRemoteConfigUrl()); } @@ -114,17 +114,19 @@ public void testAppDelete() { @Test public void testRemoteConfigClientWithoutProjectId() { - FirebaseOptions options = FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); + FirebaseOptions options = + FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); FirebaseApp.initializeApp(options); try { FirebaseRemoteConfig.getInstance(); fail("No error thrown for missing project ID"); } catch (IllegalArgumentException expected) { - String message = "Project ID is required to access Remote Config service. Use a service " - + "account credential or set the project ID explicitly via FirebaseOptions. " - + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " - + "environment variable."; + String message = + "Project ID is required to access Remote Config service. Use a service " + + "account credential or set the project ID explicitly via FirebaseOptions. " + + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " + + "environment variable."; assertEquals(message, expected.getMessage()); } } @@ -135,7 +137,8 @@ public void testRemoteConfigClientWithoutProjectId() { @Test public void testGetTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplate(); @@ -157,7 +160,8 @@ public void testGetTemplateFailure() { @Test public void testGetTemplateAsync() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAsync().get(); @@ -181,7 +185,8 @@ public void testGetTemplateAsyncFailure() throws InterruptedException { @Test public void testGetTemplateAtVersionWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion("64"); @@ -203,7 +208,8 @@ public void testGetTemplateAtVersionWithStringValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync("55").get(); @@ -225,7 +231,8 @@ public void testGetTemplateAtVersionAsyncWithStringValueFailure() throws Interru @Test public void testGetTemplateAtVersionWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion(64L); @@ -247,7 +254,8 @@ public void testGetTemplateAtVersionWithLongValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync(55L).get(); @@ -415,7 +423,8 @@ public void testForcePublishTemplateAsyncFailure() throws InterruptedException { @Test public void testRollbackWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback("64"); @@ -437,7 +446,8 @@ public void testRollbackWithStringValueFailure() { @Test public void testRollbackAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync("55").get(); @@ -459,7 +469,8 @@ public void testRollbackAsyncWithStringValueFailure() throws InterruptedExceptio @Test public void testRollbackWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback(64L); @@ -481,7 +492,8 @@ public void testRollbackWithLongValueFailure() { @Test public void testRollbackAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync(55L).get(); @@ -505,8 +517,9 @@ public void testRollbackAsyncWithLongValueFailure() throws InterruptedException @Test public void testListVersionsWithNoOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersions(); @@ -528,8 +541,9 @@ public void testListVersionsWithNoOptionsFailure() { @Test public void testListVersionsAsyncWithNoOptions() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync().get(); @@ -551,11 +565,13 @@ public void testListVersionsAsyncWithNoOptionsFailure() throws InterruptedExcept @Test public void testListVersionsWithOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = remoteConfig.listVersions(ListVersionsOptions.builder().build()); + ListVersionsPage listVersionsPage = + remoteConfig.listVersions(ListVersionsOptions.builder().build()); assertEquals("token", listVersionsPage.getNextPageToken()); } @@ -574,11 +590,13 @@ public void testListVersionsWithOptionsFailure() { @Test public void testListVersionsAsyncWithOptions() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); + ListVersionsPage listVersionsPage = + remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); assertEquals("token", listVersionsPage.getNextPageToken()); } @@ -604,13 +622,15 @@ private FirebaseRemoteConfig getRemoteConfig(FirebaseRemoteConfigClient client) @Test public void testGetServerTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplate(); String templateData = template.toJson(); - JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement expectedJson = + JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); JsonElement actualJson = JsonParser.parseString(templateData); assertEquals(expectedJson, actualJson); @@ -630,13 +650,15 @@ public void testGetServerTemplateFailure() { @Test public void testGetServerTemplateAsync() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplateAsync().get(); String templateData = template.toJson(); - JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement expectedJson = + JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); JsonElement actualJson = JsonParser.parseString(templateData); assertEquals(expectedJson, actualJson); diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java index e49de56c..82da1073 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java @@ -24,20 +24,19 @@ import com.google.firebase.FirebaseOptions; import com.google.firebase.auth.MockGoogleCredentials; import com.google.firebase.testing.TestUtils; -import org.junit.BeforeClass; -import org.junit.Test; import com.google.gson.JsonElement; import com.google.gson.JsonParser; +import org.junit.BeforeClass; +import org.junit.Test; -/** - * Tests for {@link ServerTemplateImpl}. - */ +/** Tests for {@link ServerTemplateImpl}. */ public class ServerTemplateImplTest { - private static final FirebaseOptions TEST_OPTIONS = FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); + private static final FirebaseOptions TEST_OPTIONS = + FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); private static String cacheTemplate; @@ -51,20 +50,22 @@ public void testServerTemplateWithoutCacheValueThrowsException() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); - IllegalArgumentException error = assertThrows(IllegalArgumentException.class, - () -> new ServerTemplateImpl.Builder(null).defaultConfig(defaultConfig).build()); + IllegalArgumentException error = + assertThrows( + IllegalArgumentException.class, + () -> new ServerTemplateImpl.Builder(null).defaultConfig(defaultConfig).build()); assertEquals("JSON String must not be null or empty.", error.getMessage()); } @Test - public void testEvaluateWithoutContextReturnsDefaultValue() - throws FirebaseRemoteConfigException { + public void testEvaluateWithoutContextReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(); @@ -75,10 +76,11 @@ public void testEvaluateWithoutContextReturnsDefaultValue() public void testEvaluateCustomSignalReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "100").build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -90,10 +92,11 @@ public void testEvaluateCustomSignalReturnsConditionalValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "99").build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -105,10 +108,11 @@ public void testEvaluateCustomSignalWithoutContextReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -120,10 +124,11 @@ public void testEvaluateCustomSignalWithInvalidContextReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "abc").build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -135,10 +140,11 @@ public void testEvaluatePercentWithoutRandomizationIdReturnsDefaultValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -149,10 +155,11 @@ public void testEvaluatePercentWithoutRandomizationIdReturnsDefaultValue() public void testEvaluatePercentReturnsConditionalValue() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("randomizationId", "user").build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -164,10 +171,11 @@ public void testEvaluateWithoutDefaultValueReturnsEmptyString() throws FirebaseRemoteConfigException { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -180,26 +188,29 @@ public void testEvaluateWithInvalidCacheValueThrowsException() KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); String invalidJsonString = "abc"; - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(invalidJsonString) - .build(); - - FirebaseRemoteConfigException error = assertThrows(FirebaseRemoteConfigException.class, - () -> template.evaluate(context)); - - assertEquals("No Remote Config Server template in cache. Call load() before " - + "calling evaluate().", error.getMessage()); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(invalidJsonString) + .build(); + + FirebaseRemoteConfigException error = + assertThrows(FirebaseRemoteConfigException.class, () -> template.evaluate(context)); + + assertEquals( + "No Remote Config Server template in cache. Call load() before " + "calling evaluate().", + error.getMessage()); } @Test public void testEvaluateWithInAppDefaultReturnsEmptyString() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -210,10 +221,11 @@ public void testEvaluateWithInAppDefaultReturnsEmptyString() throws Exception { public void testEvaluateWithDerivedInAppDefaultReturnsDefaultValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -224,10 +236,11 @@ public void testEvaluateWithDerivedInAppDefaultReturnsDefaultValue() throws Exce public void testEvaluateWithMultipleConditionReturnsConditionalValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("users", "99").build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -237,14 +250,17 @@ public void testEvaluateWithMultipleConditionReturnsConditionalValue() throws Ex @Test public void testEvaluateWithChainedAndConditionReturnsDefaultValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); - KeysAndValues context = new KeysAndValues.Builder().put("users", "100") - .put("premium users", 20) - .put("randomizationId", "user") - .build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + KeysAndValues context = + new KeysAndValues.Builder() + .put("users", "100") + .put("premium users", 20) + .put("randomizationId", "user") + .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -254,11 +270,13 @@ public void testEvaluateWithChainedAndConditionReturnsDefaultValue() throws Exce @Test public void testEvaluateWithChainedAndConditionReturnsConditionalValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); - KeysAndValues context = new KeysAndValues.Builder().put("users", "99").put("premium users", "30").build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + KeysAndValues context = + new KeysAndValues.Builder().put("users", "99").put("premium users", "30").build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -269,10 +287,11 @@ public void testEvaluateWithChainedAndConditionReturnsConditionalValue() throws public void testGetEvaluateConfigOnInvalidTypeReturnsDefaultValue() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().put("randomizationId", "user").build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -283,10 +302,11 @@ public void testGetEvaluateConfigOnInvalidTypeReturnsDefaultValue() throws Excep public void testGetEvaluateConfigInvalidKeyReturnsStaticValueSource() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -297,10 +317,11 @@ public void testGetEvaluateConfigInvalidKeyReturnsStaticValueSource() throws Exc public void testGetEvaluateConfigInAppDefaultConfigReturnsDefaultValueSource() throws Exception { KeysAndValues defaultConfig = new KeysAndValues.Builder().put("In-app default", "abc").build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -309,12 +330,14 @@ public void testGetEvaluateConfigInAppDefaultConfigReturnsDefaultValueSource() t @Test public void testGetEvaluateConfigUnsetDefaultConfigReturnsDefaultValueSource() throws Exception { - KeysAndValues defaultConfig = new KeysAndValues.Builder().put("Unset default config", "abc").build(); + KeysAndValues defaultConfig = + new KeysAndValues.Builder().put("Unset default config", "abc").build(); KeysAndValues context = new KeysAndValues.Builder().build(); - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null) + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) + .build(); ServerConfig evaluatedConfig = template.evaluate(context); @@ -332,21 +355,25 @@ private FirebaseRemoteConfig getRemoteConfig(FirebaseRemoteConfigClient client) public void testLoad() throws Exception { // 1. Define the template data that the mock client will return. // This is the EXPECTED state after `load()` is called. - final String expectedTemplateJsonAfterLoad = new ServerTemplateData().setETag(TEST_ETAG).toJSON(); + final String expectedTemplateJsonAfterLoad = + new ServerTemplateData().setETag(TEST_ETAG).toJSON(); // 2. Mock the HTTP client to return the predefined response. - MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate(expectedTemplateJsonAfterLoad); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromServerTemplate(expectedTemplateJsonAfterLoad); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); // 3. Build the template instance. // It's initialized with a complex `cacheTemplate` to ensure `load()` properly // overwrites it. - KeysAndValues defaultConfig = new KeysAndValues.Builder().put("Unset default config", "abc").build(); - ServerTemplate template = remoteConfig - .serverTemplateBuilder() - .defaultConfig(defaultConfig) - .cachedTemplate(cacheTemplate) // This is the initial state before `load()` - .build(); + KeysAndValues defaultConfig = + new KeysAndValues.Builder().put("Unset default config", "abc").build(); + ServerTemplate template = + remoteConfig + .serverTemplateBuilder() + .defaultConfig(defaultConfig) + .cachedTemplate(cacheTemplate) // This is the initial state before `load()` + .build(); // 4. Call the load method, which fetches the new template from the mock client. ApiFuture loadFuture = template.load(); @@ -376,9 +403,8 @@ public void testBuilderParsesCachedTemplateCorrectly() throws FirebaseRemoteConf // Act: // 2. Build a ServerTemplate instance from the original cached JSON string, // which triggers the parsing logic we want to test. - ServerTemplate template = new ServerTemplateImpl.Builder(null) - .cachedTemplate(cacheTemplate) - .build(); + ServerTemplate template = + new ServerTemplateImpl.Builder(null).cachedTemplate(cacheTemplate).build(); // Assert: // 3. Compare the JSON from the newly built template against the canonical From 9fabd60b58f80c7f136d3c89f376aa74a77e790a Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 23:02:51 +0530 Subject: [PATCH 18/21] fix multi line indent --- .../FirebaseRemoteConfigTest.java | 108 +++++++----------- .../remoteconfig/ServerTemplateImplTest.java | 4 +- 2 files changed, 46 insertions(+), 66 deletions(-) diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 81124f38..5c1f133f 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -34,16 +34,18 @@ import org.junit.After; import org.junit.Test; -/** Unit tests for {@link FirebaseRemoteConfig}. */ + +/** Tests +* for {@link FirebaseRemoteConfig}. +* */ public class FirebaseRemoteConfigTest { - private static final FirebaseOptions TEST_OPTIONS = - FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); - private static final FirebaseRemoteConfigException TEST_EXCEPTION = - new FirebaseRemoteConfigException(ErrorCode.INTERNAL, "Test error message"); + private static final FirebaseOptions TEST_OPTIONS = FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); + private static final FirebaseRemoteConfigException TEST_EXCEPTION = new FirebaseRemoteConfigException( + ErrorCode.INTERNAL, "Test error message"); @After public void tearDown() { @@ -77,8 +79,7 @@ public void testDefaultRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = - "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; + String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getRemoteConfigUrl()); } @@ -91,8 +92,7 @@ public void testDefaultServerRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = - "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; + String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getServerRemoteConfigUrl()); } @@ -114,19 +114,17 @@ public void testAppDelete() { @Test public void testRemoteConfigClientWithoutProjectId() { - FirebaseOptions options = - FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); + FirebaseOptions options = FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); FirebaseApp.initializeApp(options); try { FirebaseRemoteConfig.getInstance(); fail("No error thrown for missing project ID"); } catch (IllegalArgumentException expected) { - String message = - "Project ID is required to access Remote Config service. Use a service " - + "account credential or set the project ID explicitly via FirebaseOptions. " - + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " - + "environment variable."; + String message = "Project ID is required to access Remote Config service. Use a service " + + "account credential or set the project ID explicitly via FirebaseOptions. " + + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " + + "environment variable."; assertEquals(message, expected.getMessage()); } } @@ -137,8 +135,7 @@ public void testRemoteConfigClientWithoutProjectId() { @Test public void testGetTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplate(); @@ -160,8 +157,7 @@ public void testGetTemplateFailure() { @Test public void testGetTemplateAsync() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAsync().get(); @@ -185,8 +181,7 @@ public void testGetTemplateAsyncFailure() throws InterruptedException { @Test public void testGetTemplateAtVersionWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion("64"); @@ -208,8 +203,7 @@ public void testGetTemplateAtVersionWithStringValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync("55").get(); @@ -231,8 +225,7 @@ public void testGetTemplateAtVersionAsyncWithStringValueFailure() throws Interru @Test public void testGetTemplateAtVersionWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion(64L); @@ -254,8 +247,7 @@ public void testGetTemplateAtVersionWithLongValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync(55L).get(); @@ -423,8 +415,7 @@ public void testForcePublishTemplateAsyncFailure() throws InterruptedException { @Test public void testRollbackWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback("64"); @@ -446,8 +437,7 @@ public void testRollbackWithStringValueFailure() { @Test public void testRollbackAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync("55").get(); @@ -469,8 +459,7 @@ public void testRollbackAsyncWithStringValueFailure() throws InterruptedExceptio @Test public void testRollbackWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback(64L); @@ -492,8 +481,7 @@ public void testRollbackWithLongValueFailure() { @Test public void testRollbackAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync(55L).get(); @@ -517,9 +505,8 @@ public void testRollbackAsyncWithLongValueFailure() throws InterruptedException @Test public void testListVersionsWithNoOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersions(); @@ -541,9 +528,8 @@ public void testListVersionsWithNoOptionsFailure() { @Test public void testListVersionsAsyncWithNoOptions() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync().get(); @@ -565,13 +551,11 @@ public void testListVersionsAsyncWithNoOptionsFailure() throws InterruptedExcept @Test public void testListVersionsWithOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = - remoteConfig.listVersions(ListVersionsOptions.builder().build()); + ListVersionsPage listVersionsPage = remoteConfig.listVersions(ListVersionsOptions.builder().build()); assertEquals("token", listVersionsPage.getNextPageToken()); } @@ -590,13 +574,11 @@ public void testListVersionsWithOptionsFailure() { @Test public void testListVersionsAsyncWithOptions() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = - remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); + ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); assertEquals("token", listVersionsPage.getNextPageToken()); } @@ -622,15 +604,13 @@ private FirebaseRemoteConfig getRemoteConfig(FirebaseRemoteConfigClient client) @Test public void testGetServerTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplate(); String templateData = template.toJson(); - JsonElement expectedJson = - JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); JsonElement actualJson = JsonParser.parseString(templateData); assertEquals(expectedJson, actualJson); @@ -650,15 +630,13 @@ public void testGetServerTemplateFailure() { @Test public void testGetServerTemplateAsync() throws Exception { - MockRemoteConfigClient client = - MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplateAsync().get(); String templateData = template.toJson(); - JsonElement expectedJson = - JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); JsonElement actualJson = JsonParser.parseString(templateData); assertEquals(expectedJson, actualJson); diff --git a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java index 82da1073..bafe8433 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ServerTemplateImplTest.java @@ -29,7 +29,9 @@ import org.junit.BeforeClass; import org.junit.Test; -/** Tests for {@link ServerTemplateImpl}. */ +/** Tests +* for {@link ServerTemplateImpl}. +* */ public class ServerTemplateImplTest { private static final FirebaseOptions TEST_OPTIONS = From db3fc82e0da1b23289aa74d71faaba6c8b596bce Mon Sep 17 00:00:00 2001 From: Varun Rathore Date: Mon, 18 Aug 2025 23:07:41 +0530 Subject: [PATCH 19/21] fix multi line indents --- .../FirebaseRemoteConfigTest.java | 103 +++++++++++------- 1 file changed, 64 insertions(+), 39 deletions(-) diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 5c1f133f..8b416b67 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -40,12 +40,13 @@ * */ public class FirebaseRemoteConfigTest { - private static final FirebaseOptions TEST_OPTIONS = FirebaseOptions.builder() - .setCredentials(new MockGoogleCredentials("test-token")) - .setProjectId("test-project") - .build(); - private static final FirebaseRemoteConfigException TEST_EXCEPTION = new FirebaseRemoteConfigException( - ErrorCode.INTERNAL, "Test error message"); + private static final FirebaseOptions TEST_OPTIONS = + FirebaseOptions.builder() + .setCredentials(new MockGoogleCredentials("test-token")) + .setProjectId("test-project") + .build(); + private static final FirebaseRemoteConfigException TEST_EXCEPTION = + new FirebaseRemoteConfigException(ErrorCode.INTERNAL, "Test error message"); @After public void tearDown() { @@ -79,7 +80,8 @@ public void testDefaultRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; + String expectedUrl = + "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/remoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getRemoteConfigUrl()); } @@ -92,7 +94,8 @@ public void testDefaultServerRemoteConfigClient() { assertTrue(client instanceof FirebaseRemoteConfigClientImpl); assertSame(client, remoteConfig.getRemoteConfigClient()); - String expectedUrl = "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; + String expectedUrl = + "https://firebaseremoteconfig.googleapis.com/v1/projects/test-project/namespaces/firebase-server/serverRemoteConfig"; assertEquals(expectedUrl, ((FirebaseRemoteConfigClientImpl) client).getServerRemoteConfigUrl()); } @@ -114,17 +117,19 @@ public void testAppDelete() { @Test public void testRemoteConfigClientWithoutProjectId() { - FirebaseOptions options = FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); + FirebaseOptions options = + FirebaseOptions.builder().setCredentials(new MockGoogleCredentials("test-token")).build(); FirebaseApp.initializeApp(options); try { FirebaseRemoteConfig.getInstance(); fail("No error thrown for missing project ID"); } catch (IllegalArgumentException expected) { - String message = "Project ID is required to access Remote Config service. Use a service " - + "account credential or set the project ID explicitly via FirebaseOptions. " - + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " - + "environment variable."; + String message = + "Project ID is required to access Remote Config service. Use a service " + + "account credential or set the project ID explicitly via FirebaseOptions. " + + "Alternatively you can also set the project ID via the GOOGLE_CLOUD_PROJECT " + + "environment variable."; assertEquals(message, expected.getMessage()); } } @@ -135,7 +140,8 @@ public void testRemoteConfigClientWithoutProjectId() { @Test public void testGetTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplate(); @@ -157,7 +163,8 @@ public void testGetTemplateFailure() { @Test public void testGetTemplateAsync() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAsync().get(); @@ -181,7 +188,8 @@ public void testGetTemplateAsyncFailure() throws InterruptedException { @Test public void testGetTemplateAtVersionWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion("64"); @@ -203,7 +211,8 @@ public void testGetTemplateAtVersionWithStringValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync("55").get(); @@ -225,7 +234,8 @@ public void testGetTemplateAtVersionAsyncWithStringValueFailure() throws Interru @Test public void testGetTemplateAtVersionWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersion(64L); @@ -247,7 +257,8 @@ public void testGetTemplateAtVersionWithLongValueFailure() { @Test public void testGetTemplateAtVersionAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.getTemplateAtVersionAsync(55L).get(); @@ -415,7 +426,8 @@ public void testForcePublishTemplateAsyncFailure() throws InterruptedException { @Test public void testRollbackWithStringValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback("64"); @@ -437,7 +449,8 @@ public void testRollbackWithStringValueFailure() { @Test public void testRollbackAsyncWithStringValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync("55").get(); @@ -459,7 +472,8 @@ public void testRollbackAsyncWithStringValueFailure() throws InterruptedExceptio @Test public void testRollbackWithLongValue() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollback(64L); @@ -481,7 +495,8 @@ public void testRollbackWithLongValueFailure() { @Test public void testRollbackAsyncWithLongValue() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromTemplate(new Template().setETag(TEST_ETAG)); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); Template template = remoteConfig.rollbackAsync(55L).get(); @@ -505,8 +520,9 @@ public void testRollbackAsyncWithLongValueFailure() throws InterruptedException @Test public void testListVersionsWithNoOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersions(); @@ -528,8 +544,9 @@ public void testListVersionsWithNoOptionsFailure() { @Test public void testListVersionsAsyncWithNoOptions() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync().get(); @@ -551,11 +568,13 @@ public void testListVersionsAsyncWithNoOptionsFailure() throws InterruptedExcept @Test public void testListVersionsWithOptions() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = remoteConfig.listVersions(ListVersionsOptions.builder().build()); + ListVersionsPage listVersionsPage = + remoteConfig.listVersions(ListVersionsOptions.builder().build()); assertEquals("token", listVersionsPage.getNextPageToken()); } @@ -574,11 +593,13 @@ public void testListVersionsWithOptionsFailure() { @Test public void testListVersionsAsyncWithOptions() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromListVersionsResponse( - new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromListVersionsResponse( + new TemplateResponse.ListVersionsResponse().setNextPageToken("token")); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); - ListVersionsPage listVersionsPage = remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); + ListVersionsPage listVersionsPage = + remoteConfig.listVersionsAsync(ListVersionsOptions.builder().build()).get(); assertEquals("token", listVersionsPage.getNextPageToken()); } @@ -604,13 +625,15 @@ private FirebaseRemoteConfig getRemoteConfig(FirebaseRemoteConfigClient client) @Test public void testGetServerTemplate() throws FirebaseRemoteConfigException { - MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplate(); String templateData = template.toJson(); - JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement expectedJson = + JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); JsonElement actualJson = JsonParser.parseString(templateData); assertEquals(expectedJson, actualJson); @@ -630,13 +653,15 @@ public void testGetServerTemplateFailure() { @Test public void testGetServerTemplateAsync() throws Exception { - MockRemoteConfigClient client = MockRemoteConfigClient.fromServerTemplate( - new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + MockRemoteConfigClient client = + MockRemoteConfigClient.fromServerTemplate( + new ServerTemplateData().setETag(TEST_ETAG).toJSON()); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); ServerTemplate template = remoteConfig.getServerTemplateAsync().get(); String templateData = template.toJson(); - JsonElement expectedJson = JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); + JsonElement expectedJson = + JsonParser.parseString(new ServerTemplateData().setETag(TEST_ETAG).toJSON()); JsonElement actualJson = JsonParser.parseString(templateData); assertEquals(expectedJson, actualJson); From 4dd8b1df235aff6793e33c82c6f9f927bcf74382 Mon Sep 17 00:00:00 2001 From: varun rathore <35365856+rathovarun1032@users.noreply.github.com> Date: Fri, 22 Aug 2025 15:12:30 +0530 Subject: [PATCH 20/21] Update ConditionEvaluator.java --- .../com/google/firebase/remoteconfig/ConditionEvaluator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java index ae6bf5e9..a819c983 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java +++ b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import static com.google.common.collect.ImmutableMap.toImmutableMap; import com.google.firebase.internal.NonNull; import com.google.firebase.internal.Nullable; import java.math.BigInteger; @@ -64,7 +65,7 @@ Map evaluateConditions( Map evaluatedConditions = conditions.stream() .collect( - ImmutableMap.toImmutableMap( + toImmutableMap( ServerCondition::getName, condition -> evaluateCondition( From 1a8006b4dc97f974aa926aac618a67ec2393a4c9 Mon Sep 17 00:00:00 2001 From: varun rathore <35365856+rathovarun1032@users.noreply.github.com> Date: Fri, 22 Aug 2025 15:16:31 +0530 Subject: [PATCH 21/21] Update ConditionEvaluator.java --- .../com/google/firebase/remoteconfig/ConditionEvaluator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java index a819c983..8361a143 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java +++ b/src/main/java/com/google/firebase/remoteconfig/ConditionEvaluator.java @@ -18,10 +18,10 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableMap.toImmutableMap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import static com.google.common.collect.ImmutableMap.toImmutableMap; import com.google.firebase.internal.NonNull; import com.google.firebase.internal.Nullable; import java.math.BigInteger;