From c557114193829aeed116a69430e76e54f490fd53 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 10:44:35 +0000 Subject: [PATCH 1/5] Update Remote Config API to support managed value types Added support for Rollouts, Experiments, and Personalization value types in the Remote Config API. - Updated `ParameterValue` to include `RolloutValue`, `PersonalizationValue`, and `ExperimentValue` subclasses. - Added factory methods `rollout`, `personalization`, and `experiment` to `ParameterValue`. - Updated `TemplateResponse` to parse `rolloutValue`, `personalizationValue`, and `experimentValue` fields from the backend response. - Added unit tests for the new value types. --- .../firebase/remoteconfig/ParameterValue.java | 275 ++++++++++++++++++ .../internal/TemplateResponse.java | 170 +++++++++++ .../remoteconfig/ParameterValueTest.java | 77 +++++ 3 files changed, 522 insertions(+) diff --git a/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java b/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java index 90bf0e5df..23aa0e286 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java +++ b/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java @@ -19,8 +19,15 @@ 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.ExperimentValueResponse; +import com.google.firebase.remoteconfig.internal.TemplateResponse.ExperimentVariantValueResponse; import com.google.firebase.remoteconfig.internal.TemplateResponse.ParameterValueResponse; +import com.google.firebase.remoteconfig.internal.TemplateResponse.PersonalizationValueResponse; +import com.google.firebase.remoteconfig.internal.TemplateResponse.RolloutValueResponse; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -47,6 +54,40 @@ public static InAppDefault inAppDefault() { return new InAppDefault(); } + /** + * Creates a new {@link ParameterValue.RolloutValue} instance. + * + * @param rolloutId The rollout ID. + * @param value The value of the rollout. + * @param percent The percentage of the rollout. + * @return A {@link ParameterValue.RolloutValue} instance. + */ + public static RolloutValue rollout(String rolloutId, String value, double percent) { + return new RolloutValue(rolloutId, value, percent); + } + + /** + * Creates a new {@link ParameterValue.PersonalizationValue} instance. + * + * @param personalizationId The personalization ID. + * @return A {@link ParameterValue.PersonalizationValue} instance. + */ + public static PersonalizationValue personalization(String personalizationId) { + return new PersonalizationValue(personalizationId); + } + + /** + * Creates a new {@link ParameterValue.ExperimentValue} instance. + * + * @param experimentId The experiment ID. + * @param variantValues The list of experiment variant values. + * @return A {@link ParameterValue.ExperimentValue} instance. + */ + public static ExperimentValue experiment(String experimentId, + List variantValues) { + return new ExperimentValue(experimentId, variantValues); + } + abstract ParameterValueResponse toParameterValueResponse(); static ParameterValue fromParameterValueResponse( @@ -55,6 +96,24 @@ static ParameterValue fromParameterValueResponse( if (parameterValueResponse.isUseInAppDefault()) { return ParameterValue.inAppDefault(); } + if (parameterValueResponse.getRolloutValue() != null) { + RolloutValueResponse rv = parameterValueResponse.getRolloutValue(); + return ParameterValue.rollout(rv.getRolloutId(), rv.getValue(), rv.getPercent()); + } + if (parameterValueResponse.getPersonalizationValue() != null) { + PersonalizationValueResponse pv = parameterValueResponse.getPersonalizationValue(); + return ParameterValue.personalization(pv.getPersonalizationId()); + } + if (parameterValueResponse.getExperimentValue() != null) { + ExperimentValueResponse ev = parameterValueResponse.getExperimentValue(); + List variantValues = new ArrayList<>(); + for (ExperimentVariantValueResponse evv : ev.getExperimentVariantValues()) { + variantValues.add( + new ExperimentVariantValue(evv.getVariantId(), evv.getValue(), + evv.getNoChange())); + } + return ParameterValue.experiment(ev.getExperimentId(), variantValues); + } return ParameterValue.of(parameterValueResponse.getValue()); } @@ -124,4 +183,220 @@ public boolean equals(Object o) { return true; } } + + /** + * Represents a Rollout value. + */ + public static final class RolloutValue extends ParameterValue { + private final String rolloutId; + private final String value; + private final double percent; + + private RolloutValue(String rolloutId, String value, double percent) { + this.rolloutId = rolloutId; + this.value = value; + this.percent = percent; + } + + public String getRolloutId() { + return rolloutId; + } + + public String getValue() { + return value; + } + + public double getPercent() { + return percent; + } + + @Override + ParameterValueResponse toParameterValueResponse() { + return new ParameterValueResponse().setRolloutValue( + new RolloutValueResponse() + .setRolloutId(this.rolloutId) + .setValue(this.value) + .setPercent(this.percent)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RolloutValue that = (RolloutValue) o; + return Double.compare(that.percent, percent) == 0 + && Objects.equals(rolloutId, that.rolloutId) + && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(rolloutId, value, percent); + } + } + + /** + * Represents a Personalization value. + */ + public static final class PersonalizationValue extends ParameterValue { + private final String personalizationId; + + private PersonalizationValue(String personalizationId) { + this.personalizationId = personalizationId; + } + + public String getPersonalizationId() { + return personalizationId; + } + + @Override + ParameterValueResponse toParameterValueResponse() { + return new ParameterValueResponse().setPersonalizationValue( + new PersonalizationValueResponse() + .setPersonalizationId(this.personalizationId)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PersonalizationValue that = (PersonalizationValue) o; + return Objects.equals(personalizationId, that.personalizationId); + } + + @Override + public int hashCode() { + return Objects.hash(personalizationId); + } + } + + /** + * Represents a specific variant within an Experiment. + */ + public static final class ExperimentVariantValue { + private final String variantId; + private final String value; + private final boolean noChange; + + ExperimentVariantValue(String variantId, String value, Boolean noChange) { + this.variantId = variantId; + this.value = value; + this.noChange = Boolean.TRUE.equals(noChange); + } + + /** + * Creates a new {@link ExperimentVariantValue} instance. + * + * @param variantId The variant ID. + * @param value The value of the variant. + * @return A {@link ExperimentVariantValue} instance. + */ + public static ExperimentVariantValue of(String variantId, String value) { + return new ExperimentVariantValue(variantId, value, false); + } + + /** + * Creates a new {@link ExperimentVariantValue} instance. + * + * @param variantId The variant ID. + * @return A {@link ExperimentVariantValue} instance. + */ + public static ExperimentVariantValue ofNoChange(String variantId) { + return new ExperimentVariantValue(variantId, null, true); + } + + public String getVariantId() { + return variantId; + } + + @Nullable + public String getValue() { + return value; + } + + public boolean isNoChange() { + return noChange; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ExperimentVariantValue that = (ExperimentVariantValue) o; + return noChange == that.noChange + && Objects.equals(variantId, that.variantId) + && Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(variantId, value, noChange); + } + } + + /** + * Represents an Experiment value. + */ + public static final class ExperimentValue extends ParameterValue { + private final String experimentId; + private final List variantValues; + + private ExperimentValue(String experimentId, List variantValues) { + this.experimentId = experimentId; + this.variantValues = variantValues; + } + + public String getExperimentId() { + return experimentId; + } + + public List getExperimentVariantValues() { + return variantValues; + } + + @Override + ParameterValueResponse toParameterValueResponse() { + List variantValueResponses = new ArrayList<>(); + for (ExperimentVariantValue variantValue : variantValues) { + variantValueResponses.add(new ExperimentVariantValueResponse() + .setVariantId(variantValue.getVariantId()) + .setValue(variantValue.getValue()) + .setNoChange(variantValue.isNoChange())); + } + return new ParameterValueResponse().setExperimentValue( + new ExperimentValueResponse() + .setExperimentId(this.experimentId) + .setExperimentVariantValues(variantValueResponses)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ExperimentValue that = (ExperimentValue) o; + return Objects.equals(experimentId, that.experimentId) + && Objects.equals(variantValues, that.variantValues); + } + + @Override + public int hashCode() { + return Objects.hash(experimentId, variantValues); + } + } } diff --git a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java index 57a066bf2..b790ac36a 100644 --- a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java +++ b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java @@ -161,6 +161,15 @@ public static final class ParameterValueResponse { @Key("useInAppDefault") private Boolean useInAppDefault; + @Key("rolloutValue") + private RolloutValueResponse rolloutValue; + + @Key("personalizationValue") + private PersonalizationValueResponse personalizationValue; + + @Key("experimentValue") + private ExperimentValueResponse experimentValue; + public String getValue() { return value; } @@ -169,6 +178,18 @@ public boolean isUseInAppDefault() { return Boolean.TRUE.equals(this.useInAppDefault); } + public RolloutValueResponse getRolloutValue() { + return rolloutValue; + } + + public PersonalizationValueResponse getPersonalizationValue() { + return personalizationValue; + } + + public ExperimentValueResponse getExperimentValue() { + return experimentValue; + } + public ParameterValueResponse setValue(String value) { this.value = value; return this; @@ -178,6 +199,155 @@ public ParameterValueResponse setUseInAppDefault(boolean useInAppDefault) { this.useInAppDefault = useInAppDefault; return this; } + + public ParameterValueResponse setRolloutValue(RolloutValueResponse rolloutValue) { + this.rolloutValue = rolloutValue; + return this; + } + + public ParameterValueResponse setPersonalizationValue( + PersonalizationValueResponse personalizationValue) { + this.personalizationValue = personalizationValue; + return this; + } + + public ParameterValueResponse setExperimentValue(ExperimentValueResponse experimentValue) { + this.experimentValue = experimentValue; + return this; + } + } + + /** + * The Data Transfer Object for parsing Remote Config Rollout value responses from the + * Remote Config service. + **/ + public static final class RolloutValueResponse { + @Key("rolloutId") + private String rolloutId; + + @Key("value") + private String value; + + @Key("percent") + private Double percent; + + public String getRolloutId() { + return rolloutId; + } + + public String getValue() { + return value; + } + + public Double getPercent() { + return percent; + } + + public RolloutValueResponse setRolloutId(String rolloutId) { + this.rolloutId = rolloutId; + return this; + } + + public RolloutValueResponse setValue(String value) { + this.value = value; + return this; + } + + public RolloutValueResponse setPercent(Double percent) { + this.percent = percent; + return this; + } + } + + /** + * The Data Transfer Object for parsing Remote Config Personalization value responses from the + * Remote Config service. + **/ + public static final class PersonalizationValueResponse { + @Key("personalizationId") + private String personalizationId; + + public String getPersonalizationId() { + return personalizationId; + } + + public PersonalizationValueResponse setPersonalizationId(String personalizationId) { + this.personalizationId = personalizationId; + return this; + } + } + + /** + * The Data Transfer Object for parsing Remote Config Experiment value responses from the + * Remote Config service. + **/ + public static final class ExperimentValueResponse { + @Key("experimentId") + private String experimentId; + + @Key("experimentVariantValues") + private List experimentVariantValues; + + public String getExperimentId() { + return experimentId; + } + + public List getExperimentVariantValues() { + return experimentVariantValues; + } + + public ExperimentValueResponse setExperimentId(String experimentId) { + this.experimentId = experimentId; + return this; + } + + public ExperimentValueResponse setExperimentVariantValues( + List experimentVariantValues) { + this.experimentVariantValues = experimentVariantValues; + return this; + } + } + + /** + * The Data Transfer Object for parsing Remote Config Experiment variant value responses from the + * Remote Config service. + **/ + public static final class ExperimentVariantValueResponse { + @Key("variantId") + private String variantId; + + @Key("value") + private String value; + + @Key("noChange") + private Boolean noChange; + + public String getVariantId() { + return variantId; + } + + public String getValue() { + return value; + } + + public Boolean getNoChange() { + return noChange; + } + + public ExperimentVariantValueResponse setVariantId(String variantId) { + this.variantId = variantId; + return this; + } + + public ExperimentVariantValueResponse setValue(String value) { + this.value = value; + return this; + } + + public ExperimentVariantValueResponse setNoChange(Boolean noChange) { + this.noChange = noChange; + return this; + } } /** diff --git a/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java b/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java index 842fd808f..5bfc02706 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java @@ -18,7 +18,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import com.google.common.collect.ImmutableList; +import com.google.firebase.remoteconfig.ParameterValue.ExperimentVariantValue; import org.junit.Test; public class ParameterValueTest { @@ -37,6 +40,44 @@ public void testCreateInAppDefault() { assertEquals(ParameterValue.InAppDefault.class, parameterValue.getClass()); } + @Test + public void testCreateRolloutValue() { + final ParameterValue.RolloutValue parameterValue = + ParameterValue.rollout("rollout_1", "value_1", 10.0); + + assertEquals("rollout_1", parameterValue.getRolloutId()); + assertEquals("value_1", parameterValue.getValue()); + assertEquals(10.0, parameterValue.getPercent(), 0.0); + } + + @Test + public void testCreatePersonalizationValue() { + final ParameterValue.PersonalizationValue parameterValue = + ParameterValue.personalization("personalization_1"); + + assertEquals("personalization_1", parameterValue.getPersonalizationId()); + } + + @Test + public void testCreateExperimentValue() { + final ParameterValue.ExperimentValue parameterValue = + ParameterValue.experiment("experiment_1", ImmutableList.of( + ExperimentVariantValue.of("variant_1", "value_1"), + ExperimentVariantValue.ofNoChange("variant_2") + )); + + assertEquals("experiment_1", parameterValue.getExperimentId()); + assertEquals(2, parameterValue.getExperimentVariantValues().size()); + ExperimentVariantValue variant1 = parameterValue.getExperimentVariantValues().get(0); + assertEquals("variant_1", variant1.getVariantId()); + assertEquals("value_1", variant1.getValue()); + assertEquals(false, variant1.isNoChange()); + ExperimentVariantValue variant2 = parameterValue.getExperimentVariantValues().get(1); + assertEquals("variant_2", variant2.getVariantId()); + assertEquals(null, variant2.getValue()); + assertEquals(true, variant2.isNoChange()); + } + @Test public void testEquality() { ParameterValue.Explicit parameterValueOne = ParameterValue.of("value"); @@ -50,5 +91,41 @@ public void testEquality() { ParameterValue.InAppDefault parameterValueFive = ParameterValue.inAppDefault(); assertEquals(parameterValueFour, parameterValueFive); + + ParameterValue.RolloutValue rolloutValueOne = + ParameterValue.rollout("rollout_1", "value_1", 10.0); + ParameterValue.RolloutValue rolloutValueTwo = + ParameterValue.rollout("rollout_1", "value_1", 10.0); + ParameterValue.RolloutValue rolloutValueThree = + ParameterValue.rollout("rollout_2", "value_1", 10.0); + + assertEquals(rolloutValueOne, rolloutValueTwo); + assertNotEquals(rolloutValueOne, rolloutValueThree); + + ParameterValue.PersonalizationValue personalizationValueOne = + ParameterValue.personalization("personalization_1"); + ParameterValue.PersonalizationValue personalizationValueTwo = + ParameterValue.personalization("personalization_1"); + ParameterValue.PersonalizationValue personalizationValueThree = + ParameterValue.personalization("personalization_2"); + + assertEquals(personalizationValueOne, personalizationValueTwo); + assertNotEquals(personalizationValueOne, personalizationValueThree); + + ParameterValue.ExperimentValue experimentValueOne = + ParameterValue.experiment("experiment_1", ImmutableList.of( + ExperimentVariantValue.of("variant_1", "value_1") + )); + ParameterValue.ExperimentValue experimentValueTwo = + ParameterValue.experiment("experiment_1", ImmutableList.of( + ExperimentVariantValue.of("variant_1", "value_1") + )); + ParameterValue.ExperimentValue experimentValueThree = + ParameterValue.experiment("experiment_2", ImmutableList.of( + ExperimentVariantValue.of("variant_1", "value_1") + )); + + assertEquals(experimentValueOne, experimentValueTwo); + assertNotEquals(experimentValueOne, experimentValueThree); } } From 4087dea25f926a7aafe1919abfcd0346685146bb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 10:18:54 +0000 Subject: [PATCH 2/5] Address PR review comments - Renamed factory methods in ParameterValue to ofRollout, ofPersonalization, and ofExperiment. - Updated JSON key for experiment variant values to variantValue in TemplateResponse. --- .../firebase/remoteconfig/ParameterValue.java | 12 +++++----- .../internal/TemplateResponse.java | 2 +- .../remoteconfig/ParameterValueTest.java | 24 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java b/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java index 23aa0e286..bc4d90d96 100644 --- a/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java +++ b/src/main/java/com/google/firebase/remoteconfig/ParameterValue.java @@ -62,7 +62,7 @@ public static InAppDefault inAppDefault() { * @param percent The percentage of the rollout. * @return A {@link ParameterValue.RolloutValue} instance. */ - public static RolloutValue rollout(String rolloutId, String value, double percent) { + public static RolloutValue ofRollout(String rolloutId, String value, double percent) { return new RolloutValue(rolloutId, value, percent); } @@ -72,7 +72,7 @@ public static RolloutValue rollout(String rolloutId, String value, double percen * @param personalizationId The personalization ID. * @return A {@link ParameterValue.PersonalizationValue} instance. */ - public static PersonalizationValue personalization(String personalizationId) { + public static PersonalizationValue ofPersonalization(String personalizationId) { return new PersonalizationValue(personalizationId); } @@ -83,7 +83,7 @@ public static PersonalizationValue personalization(String personalizationId) { * @param variantValues The list of experiment variant values. * @return A {@link ParameterValue.ExperimentValue} instance. */ - public static ExperimentValue experiment(String experimentId, + public static ExperimentValue ofExperiment(String experimentId, List variantValues) { return new ExperimentValue(experimentId, variantValues); } @@ -98,11 +98,11 @@ static ParameterValue fromParameterValueResponse( } if (parameterValueResponse.getRolloutValue() != null) { RolloutValueResponse rv = parameterValueResponse.getRolloutValue(); - return ParameterValue.rollout(rv.getRolloutId(), rv.getValue(), rv.getPercent()); + return ParameterValue.ofRollout(rv.getRolloutId(), rv.getValue(), rv.getPercent()); } if (parameterValueResponse.getPersonalizationValue() != null) { PersonalizationValueResponse pv = parameterValueResponse.getPersonalizationValue(); - return ParameterValue.personalization(pv.getPersonalizationId()); + return ParameterValue.ofPersonalization(pv.getPersonalizationId()); } if (parameterValueResponse.getExperimentValue() != null) { ExperimentValueResponse ev = parameterValueResponse.getExperimentValue(); @@ -112,7 +112,7 @@ static ParameterValue fromParameterValueResponse( new ExperimentVariantValue(evv.getVariantId(), evv.getValue(), evv.getNoChange())); } - return ParameterValue.experiment(ev.getExperimentId(), variantValues); + return ParameterValue.ofExperiment(ev.getExperimentId(), variantValues); } return ParameterValue.of(parameterValueResponse.getValue()); } diff --git a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java index b790ac36a..b92580f8c 100644 --- a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java +++ b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java @@ -285,7 +285,7 @@ public static final class ExperimentValueResponse { @Key("experimentId") private String experimentId; - @Key("experimentVariantValues") + @Key("variantValue") private List experimentVariantValues; public String getExperimentId() { diff --git a/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java b/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java index 5bfc02706..d18df7c7b 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java @@ -43,7 +43,7 @@ public void testCreateInAppDefault() { @Test public void testCreateRolloutValue() { final ParameterValue.RolloutValue parameterValue = - ParameterValue.rollout("rollout_1", "value_1", 10.0); + ParameterValue.ofRollout("rollout_1", "value_1", 10.0); assertEquals("rollout_1", parameterValue.getRolloutId()); assertEquals("value_1", parameterValue.getValue()); @@ -53,7 +53,7 @@ public void testCreateRolloutValue() { @Test public void testCreatePersonalizationValue() { final ParameterValue.PersonalizationValue parameterValue = - ParameterValue.personalization("personalization_1"); + ParameterValue.ofPersonalization("personalization_1"); assertEquals("personalization_1", parameterValue.getPersonalizationId()); } @@ -61,7 +61,7 @@ public void testCreatePersonalizationValue() { @Test public void testCreateExperimentValue() { final ParameterValue.ExperimentValue parameterValue = - ParameterValue.experiment("experiment_1", ImmutableList.of( + ParameterValue.ofExperiment("experiment_1", ImmutableList.of( ExperimentVariantValue.of("variant_1", "value_1"), ExperimentVariantValue.ofNoChange("variant_2") )); @@ -93,35 +93,35 @@ public void testEquality() { assertEquals(parameterValueFour, parameterValueFive); ParameterValue.RolloutValue rolloutValueOne = - ParameterValue.rollout("rollout_1", "value_1", 10.0); + ParameterValue.ofRollout("rollout_1", "value_1", 10.0); ParameterValue.RolloutValue rolloutValueTwo = - ParameterValue.rollout("rollout_1", "value_1", 10.0); + ParameterValue.ofRollout("rollout_1", "value_1", 10.0); ParameterValue.RolloutValue rolloutValueThree = - ParameterValue.rollout("rollout_2", "value_1", 10.0); + ParameterValue.ofRollout("rollout_2", "value_1", 10.0); assertEquals(rolloutValueOne, rolloutValueTwo); assertNotEquals(rolloutValueOne, rolloutValueThree); ParameterValue.PersonalizationValue personalizationValueOne = - ParameterValue.personalization("personalization_1"); + ParameterValue.ofPersonalization("personalization_1"); ParameterValue.PersonalizationValue personalizationValueTwo = - ParameterValue.personalization("personalization_1"); + ParameterValue.ofPersonalization("personalization_1"); ParameterValue.PersonalizationValue personalizationValueThree = - ParameterValue.personalization("personalization_2"); + ParameterValue.ofPersonalization("personalization_2"); assertEquals(personalizationValueOne, personalizationValueTwo); assertNotEquals(personalizationValueOne, personalizationValueThree); ParameterValue.ExperimentValue experimentValueOne = - ParameterValue.experiment("experiment_1", ImmutableList.of( + ParameterValue.ofExperiment("experiment_1", ImmutableList.of( ExperimentVariantValue.of("variant_1", "value_1") )); ParameterValue.ExperimentValue experimentValueTwo = - ParameterValue.experiment("experiment_1", ImmutableList.of( + ParameterValue.ofExperiment("experiment_1", ImmutableList.of( ExperimentVariantValue.of("variant_1", "value_1") )); ParameterValue.ExperimentValue experimentValueThree = - ParameterValue.experiment("experiment_2", ImmutableList.of( + ParameterValue.ofExperiment("experiment_2", ImmutableList.of( ExperimentVariantValue.of("variant_1", "value_1") )); From dad48bfb26e2eeeff15c320f17f81eb34900b5a6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 10:26:22 +0000 Subject: [PATCH 3/5] Add test case for experiment value with different variants Added a new test case to `ParameterValueTest` to verify that `ExperimentValue` objects with the same ID but different variant values are not equal. --- .../com/google/firebase/remoteconfig/ParameterValueTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java b/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java index d18df7c7b..a2ae5782a 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ParameterValueTest.java @@ -124,8 +124,13 @@ public void testEquality() { ParameterValue.ofExperiment("experiment_2", ImmutableList.of( ExperimentVariantValue.of("variant_1", "value_1") )); + ParameterValue.ExperimentValue experimentValueFour = + ParameterValue.ofExperiment("experiment_1", ImmutableList.of( + ExperimentVariantValue.of("variant_2", "value_2") + )); assertEquals(experimentValueOne, experimentValueTwo); assertNotEquals(experimentValueOne, experimentValueThree); + assertNotEquals(experimentValueOne, experimentValueFour); } } From baf8e015e39a49c063eacec8e15bd0887ac1490c Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 10:42:52 +0000 Subject: [PATCH 4/5] Add tests for managed value types in ParameterTest and FirebaseRemoteConfigTest - Added `testEqualityWithManagedValues` to `ParameterTest` to verify equality of parameters with `RolloutValue`, `PersonalizationValue`, and `ExperimentValue`. - Added `testGetTemplateWithManagedValues` to `FirebaseRemoteConfigTest` to verify that `getTemplate()` correctly parses managed values. --- .../FirebaseRemoteConfigTest.java | 28 +++++++++++++++++++ .../firebase/remoteconfig/ParameterTest.java | 18 ++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 8b416b67b..2664a21b7 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableMap; import com.google.firebase.ErrorCode; import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseOptions; @@ -149,6 +150,33 @@ public void testGetTemplate() throws FirebaseRemoteConfigException { assertEquals(TEST_ETAG, template.getETag()); } + @Test + public void testGetTemplateWithManagedValues() throws FirebaseRemoteConfigException { + Template template = new Template() + .setETag(TEST_ETAG) + .setParameters(ImmutableMap.of( + "p1", new Parameter().setDefaultValue( + ParameterValue.ofRollout("rollout_1", "value_1", 10.0)), + "p2", new Parameter().setDefaultValue( + ParameterValue.ofPersonalization("personalization_1")) + )); + MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(template); + FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); + + Template fetchedTemplate = remoteConfig.getTemplate(); + + assertEquals(TEST_ETAG, fetchedTemplate.getETag()); + ParameterValue.RolloutValue rolloutValue = + (ParameterValue.RolloutValue) fetchedTemplate.getParameters().get("p1").getDefaultValue(); + assertEquals("rollout_1", rolloutValue.getRolloutId()); + assertEquals("value_1", rolloutValue.getValue()); + assertEquals(10.0, rolloutValue.getPercent(), 0.0); + + ParameterValue.PersonalizationValue personalizationValue = + (ParameterValue.PersonalizationValue) fetchedTemplate.getParameters().get("p2").getDefaultValue(); + assertEquals("personalization_1", personalizationValue.getPersonalizationId()); + } + @Test public void testGetTemplateFailure() { MockRemoteConfigClient client = MockRemoteConfigClient.fromException(TEST_EXCEPTION); diff --git a/src/test/java/com/google/firebase/remoteconfig/ParameterTest.java b/src/test/java/com/google/firebase/remoteconfig/ParameterTest.java index 7fc6ee555..598b0008c 100644 --- a/src/test/java/com/google/firebase/remoteconfig/ParameterTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/ParameterTest.java @@ -104,4 +104,22 @@ public void testEquality() { assertNotEquals(parameterThree, parameterFive); assertNotEquals(parameterThree, parameterSeven); } + + @Test + public void testEqualityWithManagedValues() { + final Parameter parameterOne = new Parameter() + .setDefaultValue(ParameterValue.ofRollout("rollout_1", "value_1", 10.0)); + final Parameter parameterTwo = new Parameter() + .setDefaultValue(ParameterValue.ofRollout("rollout_1", "value_1", 10.0)); + + assertEquals(parameterOne, parameterTwo); + + final Parameter parameterThree = new Parameter() + .setDefaultValue(ParameterValue.ofPersonalization("personalization_1")); + final Parameter parameterFour = new Parameter() + .setDefaultValue(ParameterValue.ofPersonalization("personalization_1")); + + assertEquals(parameterThree, parameterFour); + assertNotEquals(parameterOne, parameterThree); + } } From c59db876c9c519284609d90629036df4c0299045 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 31 Dec 2025 10:49:46 +0000 Subject: [PATCH 5/5] Update managed value test to use conditional values Updated `testGetTemplateWithManagedValues` in `FirebaseRemoteConfigTest` to set managed values (Rollout, Personalization) as conditional values instead of default values, as they are not supported as default values. --- .../remoteconfig/FirebaseRemoteConfigTest.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java index 2664a21b7..7c02b3c2f 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigTest.java @@ -155,10 +155,10 @@ public void testGetTemplateWithManagedValues() throws FirebaseRemoteConfigExcept Template template = new Template() .setETag(TEST_ETAG) .setParameters(ImmutableMap.of( - "p1", new Parameter().setDefaultValue( - ParameterValue.ofRollout("rollout_1", "value_1", 10.0)), - "p2", new Parameter().setDefaultValue( - ParameterValue.ofPersonalization("personalization_1")) + "p1", new Parameter().setConditionalValues(ImmutableMap.of( + "c1", ParameterValue.ofRollout("rollout_1", "value_1", 10.0))), + "p2", new Parameter().setConditionalValues(ImmutableMap.of( + "c2", ParameterValue.ofPersonalization("personalization_1"))) )); MockRemoteConfigClient client = MockRemoteConfigClient.fromTemplate(template); FirebaseRemoteConfig remoteConfig = getRemoteConfig(client); @@ -167,13 +167,15 @@ public void testGetTemplateWithManagedValues() throws FirebaseRemoteConfigExcept assertEquals(TEST_ETAG, fetchedTemplate.getETag()); ParameterValue.RolloutValue rolloutValue = - (ParameterValue.RolloutValue) fetchedTemplate.getParameters().get("p1").getDefaultValue(); + (ParameterValue.RolloutValue) fetchedTemplate.getParameters().get("p1") + .getConditionalValues().get("c1"); assertEquals("rollout_1", rolloutValue.getRolloutId()); assertEquals("value_1", rolloutValue.getValue()); assertEquals(10.0, rolloutValue.getPercent(), 0.0); ParameterValue.PersonalizationValue personalizationValue = - (ParameterValue.PersonalizationValue) fetchedTemplate.getParameters().get("p2").getDefaultValue(); + (ParameterValue.PersonalizationValue) fetchedTemplate.getParameters().get("p2") + .getConditionalValues().get("c2"); assertEquals("personalization_1", personalizationValue.getPersonalizationId()); }