From 5123e8f44e7a1d869dd37a9f86bc8249c76a7dc1 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 2 Nov 2020 17:34:42 -0500 Subject: [PATCH 1/4] Add Version information to RC template --- .../firebase/remoteconfig/Template.java | 51 ++--- .../google/firebase/remoteconfig/User.java | 70 +++++++ .../google/firebase/remoteconfig/Version.java | 181 ++++++++++++++++++ .../internal/TemplateResponse.java | 106 ++++++++++ .../FirebaseRemoteConfigClientImplTest.java | 32 +++- .../firebase/remoteconfig/TemplateTest.java | 74 ------- .../firebase/remoteconfig/UserTest.java | 27 +++ .../firebase/remoteconfig/VersionTest.java | 59 ++++++ src/test/resources/getRemoteConfig.json | 7 +- 9 files changed, 500 insertions(+), 107 deletions(-) create mode 100644 src/main/java/com/google/firebase/remoteconfig/User.java create mode 100644 src/main/java/com/google/firebase/remoteconfig/Version.java create mode 100644 src/test/java/com/google/firebase/remoteconfig/UserTest.java create mode 100644 src/test/java/com/google/firebase/remoteconfig/VersionTest.java diff --git a/src/main/java/com/google/firebase/remoteconfig/Template.java b/src/main/java/com/google/firebase/remoteconfig/Template.java index f54cc801f..34ded9a6b 100644 --- a/src/main/java/com/google/firebase/remoteconfig/Template.java +++ b/src/main/java/com/google/firebase/remoteconfig/Template.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; /** * Represents a Remote Config template. @@ -36,6 +35,7 @@ public final class Template { private Map parameters; private List conditions; private Map parameterGroups; + private Version version; /** * Creates a new {@link Template}. @@ -69,6 +69,9 @@ public Template() { this.parameterGroups.put(entry.getKey(), new ParameterGroup(entry.getValue())); } } + if (templateResponse.getVersion() != null) { + this.version = new Version(templateResponse.getVersion()); + } } /** @@ -111,6 +114,15 @@ public Map getParameterGroups() { return parameterGroups; } + /** + * Gets the version information of the template. + * + * @return The version information of the template. + */ + public Version getVersion() { + return version; + } + /** * Sets the map of parameters of the template. * @@ -152,6 +164,18 @@ public Template setParameterGroups( return this; } + /** + * Sets the version information of the template. + * Only the version's description field can be specified here. + * + * @param version A {@link Version} instance. + * @return This {@link Template} instance. + */ + public Template setVersion(Version version) { + this.version = version; + return this; + } + Template setETag(String etag) { this.etag = etag; return this; @@ -170,29 +194,12 @@ TemplateResponse toTemplateResponse() { for (Map.Entry entry : this.parameterGroups.entrySet()) { parameterGroupResponse.put(entry.getKey(), entry.getValue().toParameterGroupResponse()); } + TemplateResponse.VersionResponse versionResponse = (this.version == null) ? null + : this.version.toVersionResponse(); return new TemplateResponse() .setParameters(parameterResponses) .setConditions(conditionResponses) - .setParameterGroups(parameterGroupResponse); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Template template = (Template) o; - return Objects.equals(etag, template.etag) - && Objects.equals(parameters, template.parameters) - && Objects.equals(conditions, template.conditions) - && Objects.equals(parameterGroups, template.parameterGroups); - } - - @Override - public int hashCode() { - return Objects.hash(etag, parameters, conditions, parameterGroups); + .setParameterGroups(parameterGroupResponse) + .setVersion(versionResponse); } } diff --git a/src/main/java/com/google/firebase/remoteconfig/User.java b/src/main/java/com/google/firebase/remoteconfig/User.java new file mode 100644 index 000000000..a026f09c5 --- /dev/null +++ b/src/main/java/com/google/firebase/remoteconfig/User.java @@ -0,0 +1,70 @@ +/* + * 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.UserResponse; + +/** + * Represents a Remote Config user. Output only. + */ +public final class User { + + private String email; + private String name; + private String imageUrl; + + User(@NonNull UserResponse userResponse) { + checkNotNull(userResponse); + this.email = userResponse.getEmail(); + this.name = userResponse.getName(); + this.imageUrl = userResponse.getImageUrl(); + } + + /** + * Gets the email of the user. + * + * @return The email of the user or null. + */ + @Nullable + public String getEmail() { + return email; + } + + /** + * Gets the name of the user. + * + * @return The name of the user or null. + */ + @Nullable + public String getName() { + return name; + } + + /** + * Gets the image URL of the user. + * + * @return The image URL of the user or null. + */ + @Nullable + public String getImageUrl() { + return imageUrl; + } +} diff --git a/src/main/java/com/google/firebase/remoteconfig/Version.java b/src/main/java/com/google/firebase/remoteconfig/Version.java new file mode 100644 index 000000000..b75009086 --- /dev/null +++ b/src/main/java/com/google/firebase/remoteconfig/Version.java @@ -0,0 +1,181 @@ +/* + * 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.common.base.Strings; +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.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +/** + * Represents a 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 Version { + + private String versionNumber; + private long updateTime; + private String updateOrigin; + private String updateType; + private User updateUser; + private String description; + private String rollbackSource; + private boolean legacy; + + /** + * Creates a new {@link Version} with a description. + */ + public static Version withDescription(String description) { + return new Version().setDescription(description); + } + + Version() { + } + + Version(@NonNull VersionResponse versionResponse) { + checkNotNull(versionResponse); + this.versionNumber = versionResponse.getVersionNumber(); + if (!Strings.isNullOrEmpty(versionResponse.getUpdateTime())) { + SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + try { + this.updateTime = dateFormat.parse(versionResponse.getUpdateTime()).getTime(); + } catch (ParseException e) { + this.updateTime = 0; + } + } + 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(); + } + + /** + * 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 long 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 version number of the Remote Config template that has become the current version + * due to a rollback. Only present if this version 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 version history was + * supported. + * + * @return true if the template was published before version 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 Version}. + */ + public Version setDescription(String description) { + this.description = description; + return this; + } + + VersionResponse toVersionResponse() { + return new VersionResponse() + .setDescription(this.description); + } +} 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 199536250..469d58413 100644 --- a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java +++ b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java @@ -36,6 +36,9 @@ public final class TemplateResponse { @Key("parameterGroups") private Map parameterGroups; + @Key("version") + private VersionResponse version; + public Map getParameters() { return parameters; } @@ -48,6 +51,10 @@ public Map getParameterGroups() { return parameterGroups; } + public VersionResponse getVersion() { + return version; + } + public TemplateResponse setParameters( Map parameters) { this.parameters = parameters; @@ -66,6 +73,11 @@ public TemplateResponse setParameterGroups( return this; } + public TemplateResponse setVersion(VersionResponse version) { + this.version = version; + return this; + } + /** * The Data Transfer Object for parsing Remote Config parameter responses from the * Remote Config service. @@ -216,4 +228,98 @@ public ParameterGroupResponse setDescription(String description) { return this; } } + + /** + * The Data Transfer Object for parsing Remote Config version responses from the + * Remote Config service. + **/ + public static final class VersionResponse { + @Key("versionNumber") + private String versionNumber; + + @Key("updateTime") + private String updateTime; + + @Key("updateOrigin") + private String updateOrigin; + + @Key("updateType") + private String updateType; + + @Key("updateUser") + private UserResponse updateUser; + + @Key("description") + private String description; + + @Key("rollbackSource") + private String rollbackSource; + + @Key("legacy") + private Boolean legacy; + + public String getVersionNumber() { + return versionNumber; + } + + public String getUpdateTime() { + return updateTime; + } + + public String getUpdateOrigin() { + return updateOrigin; + } + + public String getUpdateType() { + return updateType; + } + + public UserResponse getUpdateUser() { + return updateUser; + } + + public String getDescription() { + return description; + } + + public String getRollbackSource() { + return rollbackSource; + } + + public boolean isLegacy() { + return Boolean.TRUE.equals(this.legacy); + } + + public VersionResponse setDescription(String description) { + this.description = description; + return this; + } + } + + /** + * The Data Transfer Object for parsing Remote Config user responses from the + * Remote Config service. + **/ + public static final class UserResponse { + @Key("email") + private String email; + + @Key("name") + private String name; + + @Key("imageUrl") + private String imageUrl; + + public String getEmail() { + return email; + } + + public String getName() { + return name; + } + + public String getImageUrl() { + return imageUrl; + } + } } diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index 910cc0416..1e307a3c3 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -45,8 +45,11 @@ import com.google.firebase.testing.TestUtils; import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.List; import java.util.Map; +import java.util.TimeZone; import org.junit.Before; import org.junit.Test; @@ -85,7 +88,7 @@ public void testGetTemplate() throws Exception { response.setContent(MOCK_TEMPLATE_RESPONSE); Template receivedTemplate = client.getTemplate(); - Map expectedParameters = ImmutableMap.of( + final Map expectedParameters = ImmutableMap.of( "welcome_message_text", new Parameter() .setDefaultValue(ParameterValue.of("welcome to app")) .setConditionalValues(ImmutableMap.of( @@ -95,7 +98,7 @@ public void testGetTemplate() throws Exception { "header_text", new Parameter() .setDefaultValue(ParameterValue.inAppDefault()) ); - Map expectedParameterGroups = ImmutableMap.of( + final Map expectedParameterGroups = ImmutableMap.of( "new menu", new ParameterGroup() .setDescription("New Menu") .setParameters(ImmutableMap.of( @@ -105,21 +108,32 @@ public void testGetTemplate() throws Exception { ) ) ); - List expectedConditions = ImmutableList.of( + final List expectedConditions = 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']") .setTagColor(TagColor.UNSPECIFIED) ); - Template expectedTemplate = new Template() - .setParameters(expectedParameters) - .setParameterGroups(expectedParameterGroups) - .setConditions(expectedConditions) - .setETag(TEST_ETAG); assertEquals(TEST_ETAG, receivedTemplate.getETag()); - assertEquals(expectedTemplate, receivedTemplate); + assertEquals(expectedParameters, receivedTemplate.getParameters()); + assertEquals(expectedParameterGroups, receivedTemplate.getParameterGroups()); + assertEquals(expectedConditions, receivedTemplate.getConditions()); + + final Version receivedVersion = receivedTemplate.getVersion(); + SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + final String updateTime = dateFormat.format(new Date(receivedVersion.getUpdateTime())); + + assertEquals("17", receivedVersion.getVersionNumber()); + assertEquals("ADMIN_SDK_NODE", receivedVersion.getUpdateOrigin()); + assertEquals("INCREMENTAL_UPDATE", receivedVersion.getUpdateType()); + assertEquals("firebase-user@account.com", receivedVersion.getUpdateUser().getEmail()); + assertEquals("dev-admin", receivedVersion.getUpdateUser().getName()); + assertEquals("http://image.jpg", receivedVersion.getUpdateUser().getImageUrl()); + assertEquals("Wed, 30 Sep 2020 17:56:07 GMT", updateTime); + assertEquals("promo config", receivedVersion.getDescription()); checkGetRequestHeader(interceptor.getLastRequest()); } diff --git a/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java b/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java index ce272301d..d719e1c56 100644 --- a/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java @@ -16,18 +16,10 @@ package com.google.firebase.remoteconfig; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; - -import java.util.List; -import java.util.Map; - import org.junit.Test; public class TemplateTest { @@ -67,70 +59,4 @@ public void testSetNullParameterGroups() { Template template = new Template(); template.setParameterGroups(null); } - - @Test - public void testEquality() { - final Template templateOne = new Template(); - final Template templateTwo = new Template(); - - assertEquals(templateOne, templateTwo); - - final List conditions = ImmutableList.of( - new Condition("ios_en", "exp ios") - .setTagColor(TagColor.INDIGO), - new Condition("android_en", "exp android") - ); - final Map conditionalValues = ImmutableMap.of( - "ios", ParameterValue.of("hello ios"), - "android", ParameterValue.of("hello android"), - "promo", ParameterValue.inAppDefault() - ); - final Map parameters = ImmutableMap.of( - "greeting_header", new Parameter() - .setDefaultValue(ParameterValue.inAppDefault()) - .setDescription("greeting header text") - .setConditionalValues(conditionalValues), - "greeting_text", new Parameter() - .setDefaultValue(ParameterValue.inAppDefault()) - .setDescription("greeting text") - .setConditionalValues(conditionalValues) - ); - final Template templateThree = new Template() - .setConditions(conditions) - .setParameters(parameters); - final Template templateFour = new Template() - .setConditions(conditions) - .setParameters(parameters); - - assertEquals(templateThree, templateFour); - - final Map parameterGroups = ImmutableMap.of( - "greetings_group", new ParameterGroup() - .setDescription("description") - .setParameters(parameters) - ); - final Template templateFive = new Template() - .setConditions(conditions) - .setParameters(parameters) - .setParameterGroups(parameterGroups); - final Template templateSix = new Template() - .setConditions(conditions) - .setParameters(parameters) - .setParameterGroups(parameterGroups); - - assertEquals(templateFive, templateSix); - - final Template templateSeven = new Template() - .setETag("etag-123456789097-20"); - final Template templateEight = new Template() - .setETag("etag-123456789097-20"); - - assertEquals(templateSeven, templateEight); - assertNotEquals(templateOne, templateThree); - assertNotEquals(templateOne, templateFive); - assertNotEquals(templateOne, templateSeven); - assertNotEquals(templateThree, templateFive); - assertNotEquals(templateThree, templateSeven); - assertNotEquals(templateFive, templateSeven); - } } diff --git a/src/test/java/com/google/firebase/remoteconfig/UserTest.java b/src/test/java/com/google/firebase/remoteconfig/UserTest.java new file mode 100644 index 000000000..c46a0f14e --- /dev/null +++ b/src/test/java/com/google/firebase/remoteconfig/UserTest.java @@ -0,0 +1,27 @@ +/* + * 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 org.junit.Test; + +public class UserTest { + + @Test(expected = NullPointerException.class) + public void testConstructorWithNullVersionResponse() { + new User(null); + } +} diff --git a/src/test/java/com/google/firebase/remoteconfig/VersionTest.java b/src/test/java/com/google/firebase/remoteconfig/VersionTest.java new file mode 100644 index 000000000..fde6109b2 --- /dev/null +++ b/src/test/java/com/google/firebase/remoteconfig/VersionTest.java @@ -0,0 +1,59 @@ +/* + * 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.assertNull; + +import org.junit.Test; + +public class VersionTest { + + @Test + public void testConstructor() { + final Version version = new Version(); + + assertNull(version.getVersionNumber()); + assertEquals(0, version.getUpdateTime()); + assertNull(version.getUpdateOrigin()); + assertNull(version.getUpdateType()); + assertNull(version.getUpdateUser()); + assertNull(version.getDescription()); + assertNull(version.getRollbackSource()); + assertFalse(version.isLegacy()); + } + + @Test(expected = NullPointerException.class) + public void testConstructorWithNullVersionResponse() { + new Version(null); + } + + @Test + public void testWithDescription() { + final Version version = Version.withDescription("version description text"); + + assertEquals("version description text", version.getDescription()); + assertNull(version.getVersionNumber()); + assertEquals(0, version.getUpdateTime()); + assertNull(version.getUpdateOrigin()); + assertNull(version.getUpdateType()); + assertNull(version.getUpdateUser()); + assertNull(version.getRollbackSource()); + assertFalse(version.isLegacy()); + } +} diff --git a/src/test/resources/getRemoteConfig.json b/src/test/resources/getRemoteConfig.json index 8b0f66479..807866db4 100644 --- a/src/test/resources/getRemoteConfig.json +++ b/src/test/resources/getRemoteConfig.json @@ -46,8 +46,11 @@ "updateOrigin": "ADMIN_SDK_NODE", "updateType": "INCREMENTAL_UPDATE", "updateUser": { - "email": "firebase-user@account.com" + "email": "firebase-user@account.com", + "name": "dev-admin", + "imageUrl": "http://image.jpg" }, - "updateTime": "Wed, 30 Sep 2020 17:56:07 GMT" + "updateTime": "Wed, 30 Sep 2020 17:56:07 GMT", + "description": "promo config" } } From 0de7c09c643e498b050da378276a0c20b38fe8d8 Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Wed, 4 Nov 2020 15:20:15 -0500 Subject: [PATCH 2/4] PR fixes --- .../firebase/remoteconfig/Template.java | 22 +++++ .../google/firebase/remoteconfig/User.java | 29 +++++- .../google/firebase/remoteconfig/Version.java | 88 +++++++++++++++---- .../internal/TemplateResponse.java | 50 +++++++++++ .../FirebaseRemoteConfigClientImplTest.java | 38 ++++---- .../firebase/remoteconfig/TemplateTest.java | 81 +++++++++++++++++ .../firebase/remoteconfig/UserTest.java | 35 ++++++++ .../firebase/remoteconfig/VersionTest.java | 60 ++++++++++--- src/test/resources/getRemoteConfig.json | 2 +- 9 files changed, 351 insertions(+), 54 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/Template.java b/src/main/java/com/google/firebase/remoteconfig/Template.java index 34ded9a6b..c6ffcb49a 100644 --- a/src/main/java/com/google/firebase/remoteconfig/Template.java +++ b/src/main/java/com/google/firebase/remoteconfig/Template.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; /** * Represents a Remote Config template. @@ -202,4 +203,25 @@ TemplateResponse toTemplateResponse() { .setParameterGroups(parameterGroupResponse) .setVersion(versionResponse); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Template template = (Template) o; + return Objects.equals(etag, template.etag) + && Objects.equals(parameters, template.parameters) + && Objects.equals(conditions, template.conditions) + && Objects.equals(parameterGroups, template.parameterGroups) + && Objects.equals(version, template.version); + } + + @Override + public int hashCode() { + return Objects.hash(etag, parameters, conditions, parameterGroups, version); + } } diff --git a/src/main/java/com/google/firebase/remoteconfig/User.java b/src/main/java/com/google/firebase/remoteconfig/User.java index a026f09c5..ae21328b0 100644 --- a/src/main/java/com/google/firebase/remoteconfig/User.java +++ b/src/main/java/com/google/firebase/remoteconfig/User.java @@ -22,14 +22,16 @@ import com.google.firebase.internal.Nullable; import com.google.firebase.remoteconfig.internal.TemplateResponse.UserResponse; +import java.util.Objects; + /** * Represents a Remote Config user. Output only. */ -public final class User { +public class User { - private String email; - private String name; - private String imageUrl; + private final String email; + private final String name; + private final String imageUrl; User(@NonNull UserResponse userResponse) { checkNotNull(userResponse); @@ -67,4 +69,23 @@ public String getName() { public String getImageUrl() { return imageUrl; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + User user = (User) o; + return Objects.equals(email, user.email) + && Objects.equals(name, user.name) + && Objects.equals(imageUrl, user.imageUrl); + } + + @Override + public int hashCode() { + return Objects.hash(email, name, imageUrl); + } } diff --git a/src/main/java/com/google/firebase/remoteconfig/Version.java b/src/main/java/com/google/firebase/remoteconfig/Version.java index b75009086..76220bbcb 100644 --- a/src/main/java/com/google/firebase/remoteconfig/Version.java +++ b/src/main/java/com/google/firebase/remoteconfig/Version.java @@ -26,7 +26,10 @@ import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Objects; import java.util.TimeZone; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Represents a Remote Config template version. @@ -37,37 +40,53 @@ */ public final class Version { - private String versionNumber; - private long updateTime; - private String updateOrigin; - private String updateType; - private User updateUser; - private String description; - private String rollbackSource; - private boolean legacy; + private static final Pattern ZULU_TIME_NO_NANOSECONDS_PATTERN = Pattern + .compile("^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})"); - /** - * Creates a new {@link Version} with a description. - */ - public static Version withDescription(String description) { - return new Version().setDescription(description); - } + private final String versionNumber; + private final long updateTime; + private final String updateOrigin; + private final String updateType; + private final User updateUser; + private final String rollbackSource; + private final boolean legacy; + private String description; - Version() { + private Version() { + this.versionNumber = null; + this.updateTime = 0L; + this.updateOrigin = null; + this.updateType = null; + this.updateUser = null; + this.rollbackSource = null; + this.legacy = false; } Version(@NonNull VersionResponse versionResponse) { checkNotNull(versionResponse); this.versionNumber = versionResponse.getVersionNumber(); + if (!Strings.isNullOrEmpty(versionResponse.getUpdateTime())) { - SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); + // Update Time is a timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. + // example: "2014-10-02T15:01:23.045123456Z" + // SimpleDateFormat cannot handle nanoseconds, therefore we drop nanoseconds from the string. + Matcher errorMatcher = ZULU_TIME_NO_NANOSECONDS_PATTERN + .matcher(versionResponse.getUpdateTime()); + String updateTimeWithoutNanoseconds = ""; + if (errorMatcher.find()) { + updateTimeWithoutNanoseconds = errorMatcher.group(1); + } + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { - this.updateTime = dateFormat.parse(versionResponse.getUpdateTime()).getTime(); + this.updateTime = dateFormat.parse(updateTimeWithoutNanoseconds).getTime(); } catch (ParseException e) { - this.updateTime = 0; + throw new IllegalStateException(); } + } else { + this.updateTime = 0L; } + this.updateOrigin = versionResponse.getUpdateOrigin(); this.updateType = versionResponse.getUpdateType(); TemplateResponse.UserResponse userResponse = versionResponse.getUpdateUser(); @@ -77,6 +96,13 @@ public static Version withDescription(String description) { this.legacy = versionResponse.isLegacy(); } + /** + * Creates a new {@link Version} with a description. + */ + public static Version withDescription(String description) { + return new Version().setDescription(description); + } + /** * Gets the version number of the template. * @@ -178,4 +204,30 @@ VersionResponse toVersionResponse() { return new VersionResponse() .setDescription(this.description); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Version version = (Version) o; + return updateTime == version.updateTime + && legacy == version.legacy + && Objects.equals(versionNumber, version.versionNumber) + && Objects.equals(updateOrigin, version.updateOrigin) + && Objects.equals(updateType, version.updateType) + && Objects.equals(updateUser, version.updateUser) + && Objects.equals(description, version.description) + && Objects.equals(rollbackSource, version.rollbackSource); + } + + @Override + public int hashCode() { + return Objects + .hash(versionNumber, updateTime, updateOrigin, updateType, updateUser, description, + rollbackSource, legacy); + } } 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 469d58413..9a209a274 100644 --- a/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java +++ b/src/main/java/com/google/firebase/remoteconfig/internal/TemplateResponse.java @@ -294,6 +294,41 @@ public VersionResponse setDescription(String description) { this.description = description; return this; } + + public VersionResponse setVersionNumber(String versionNumber) { + this.versionNumber = versionNumber; + return this; + } + + public VersionResponse setUpdateTime(String updateTime) { + this.updateTime = updateTime; + return this; + } + + public VersionResponse setUpdateOrigin(String updateOrigin) { + this.updateOrigin = updateOrigin; + return this; + } + + public VersionResponse setUpdateType(String updateType) { + this.updateType = updateType; + return this; + } + + public VersionResponse setUpdateUser(UserResponse updateUser) { + this.updateUser = updateUser; + return this; + } + + public VersionResponse setRollbackSource(String rollbackSource) { + this.rollbackSource = rollbackSource; + return this; + } + + public VersionResponse setLegacy(Boolean legacy) { + this.legacy = legacy; + return this; + } } /** @@ -321,5 +356,20 @@ public String getName() { public String getImageUrl() { return imageUrl; } + + public UserResponse setEmail(String email) { + this.email = email; + return this; + } + + public UserResponse setName(String name) { + this.name = name; + return this; + } + + public UserResponse setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + return this; + } } } diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index 1e307a3c3..abf3865fa 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -41,6 +41,7 @@ import com.google.firebase.OutgoingHttpRequest; import com.google.firebase.auth.MockGoogleCredentials; import com.google.firebase.internal.SdkUtils; +import com.google.firebase.remoteconfig.internal.TemplateResponse; import com.google.firebase.testing.TestResponseInterceptor; import com.google.firebase.testing.TestUtils; @@ -115,25 +116,28 @@ public void testGetTemplate() throws Exception { "device.os == 'android' && device.country in ['us', 'uk']") .setTagColor(TagColor.UNSPECIFIED) ); + final Version expectedVersion = 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-03T20:24:15.203Z") + .setDescription("promo config") + ); + + Template expectedTemplate = new Template() + .setETag(TEST_ETAG) + .setParameters(expectedParameters) + .setConditions(expectedConditions) + .setParameterGroups(expectedParameterGroups) + .setVersion(expectedVersion); assertEquals(TEST_ETAG, receivedTemplate.getETag()); - assertEquals(expectedParameters, receivedTemplate.getParameters()); - assertEquals(expectedParameterGroups, receivedTemplate.getParameterGroups()); - assertEquals(expectedConditions, receivedTemplate.getConditions()); - - final Version receivedVersion = receivedTemplate.getVersion(); - SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z"); - dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); - final String updateTime = dateFormat.format(new Date(receivedVersion.getUpdateTime())); - - assertEquals("17", receivedVersion.getVersionNumber()); - assertEquals("ADMIN_SDK_NODE", receivedVersion.getUpdateOrigin()); - assertEquals("INCREMENTAL_UPDATE", receivedVersion.getUpdateType()); - assertEquals("firebase-user@account.com", receivedVersion.getUpdateUser().getEmail()); - assertEquals("dev-admin", receivedVersion.getUpdateUser().getName()); - assertEquals("http://image.jpg", receivedVersion.getUpdateUser().getImageUrl()); - assertEquals("Wed, 30 Sep 2020 17:56:07 GMT", updateTime); - assertEquals("promo config", receivedVersion.getDescription()); + assertEquals(expectedTemplate, receivedTemplate); + assertEquals(1604435055000L, receivedTemplate.getVersion().getUpdateTime()); checkGetRequestHeader(interceptor.getLastRequest()); } diff --git a/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java b/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java index d719e1c56..e00270663 100644 --- a/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java @@ -16,10 +16,18 @@ package com.google.firebase.remoteconfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; + +import java.util.List; +import java.util.Map; + import org.junit.Test; public class TemplateTest { @@ -59,4 +67,77 @@ public void testSetNullParameterGroups() { Template template = new Template(); template.setParameterGroups(null); } + + @Test + public void testEquality() { + final Template templateOne = new Template(); + final Template templateTwo = new Template(); + + assertEquals(templateOne, templateTwo); + + final List conditions = ImmutableList.of( + new Condition("ios_en", "exp ios") + .setTagColor(TagColor.INDIGO), + new Condition("android_en", "exp android") + ); + final Map conditionalValues = ImmutableMap.of( + "ios", ParameterValue.of("hello ios"), + "android", ParameterValue.of("hello android"), + "promo", ParameterValue.inAppDefault() + ); + final Map parameters = ImmutableMap.of( + "greeting_header", new Parameter() + .setDefaultValue(ParameterValue.inAppDefault()) + .setDescription("greeting header text") + .setConditionalValues(conditionalValues), + "greeting_text", new Parameter() + .setDefaultValue(ParameterValue.inAppDefault()) + .setDescription("greeting text") + .setConditionalValues(conditionalValues) + ); + final Template templateThree = new Template() + .setConditions(conditions) + .setParameters(parameters); + final Template templateFour = new Template() + .setConditions(conditions) + .setParameters(parameters); + + assertEquals(templateThree, templateFour); + + final Map parameterGroups = ImmutableMap.of( + "greetings_group", new ParameterGroup() + .setDescription("description") + .setParameters(parameters) + ); + final Template templateFive = new Template() + .setConditions(conditions) + .setParameters(parameters) + .setParameterGroups(parameterGroups); + final Template templateSix = new Template() + .setConditions(conditions) + .setParameters(parameters) + .setParameterGroups(parameterGroups); + + assertEquals(templateFive, templateSix); + + final Template templateSeven = new Template() + .setETag("etag-123456789097-20"); + final Template templateEight = new Template() + .setETag("etag-123456789097-20"); + + assertEquals(templateSeven, templateEight); + assertNotEquals(templateOne, templateThree); + assertNotEquals(templateOne, templateFive); + assertNotEquals(templateOne, templateSeven); + assertNotEquals(templateThree, templateFive); + assertNotEquals(templateThree, templateSeven); + assertNotEquals(templateFive, templateSeven); + + final Template templateNine = new Template() + .setVersion(Version.withDescription("promo version")); + final Template templateTen = new Template() + .setVersion(Version.withDescription("promo version")); + assertEquals(templateNine, templateTen); + assertNotEquals(templateOne, templateNine); + } } diff --git a/src/test/java/com/google/firebase/remoteconfig/UserTest.java b/src/test/java/com/google/firebase/remoteconfig/UserTest.java index c46a0f14e..866b30eed 100644 --- a/src/test/java/com/google/firebase/remoteconfig/UserTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/UserTest.java @@ -16,6 +16,10 @@ package com.google.firebase.remoteconfig; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import com.google.firebase.remoteconfig.internal.TemplateResponse; import org.junit.Test; public class UserTest { @@ -24,4 +28,35 @@ public class UserTest { public void testConstructorWithNullVersionResponse() { new User(null); } + + @Test + public void testEquality() { + final User userOne = new User(new TemplateResponse.UserResponse()); + final User userTwo = new User(new TemplateResponse.UserResponse()); + + assertEquals(userOne, userTwo); + + final User userThree = new User(new TemplateResponse.UserResponse() + .setName("admin-user") + .setEmail("admin@email.com") + .setImageUrl("http://admin.jpg")); + final User userFour = new User(new TemplateResponse.UserResponse() + .setName("admin-user") + .setEmail("admin@email.com") + .setImageUrl("http://admin.jpg")); + + assertEquals(userThree, userFour); + + final User userFive = new User(new TemplateResponse.UserResponse() + .setName("admin-user") + .setEmail("admin@email.com")); + final User userSix = new User(new TemplateResponse.UserResponse() + .setName("admin-user") + .setEmail("admin@email.com")); + + assertEquals(userFive, userSix); + assertNotEquals(userOne, userThree); + assertNotEquals(userOne, userFive); + assertNotEquals(userThree, userFive); + } } diff --git a/src/test/java/com/google/firebase/remoteconfig/VersionTest.java b/src/test/java/com/google/firebase/remoteconfig/VersionTest.java index fde6109b2..c0a600445 100644 --- a/src/test/java/com/google/firebase/remoteconfig/VersionTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/VersionTest.java @@ -18,31 +18,26 @@ 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 VersionTest { - @Test - public void testConstructor() { - final Version version = new Version(); - - assertNull(version.getVersionNumber()); - assertEquals(0, version.getUpdateTime()); - assertNull(version.getUpdateOrigin()); - assertNull(version.getUpdateType()); - assertNull(version.getUpdateUser()); - assertNull(version.getDescription()); - assertNull(version.getRollbackSource()); - assertFalse(version.isLegacy()); - } - @Test(expected = NullPointerException.class) public void testConstructorWithNullVersionResponse() { new Version(null); } + @Test(expected = IllegalStateException.class) + public void testConstructorWithInvalidUpdateTime() { + new Version(new VersionResponse() + .setUpdateTime("sunday,26th")); + } + @Test public void testWithDescription() { final Version version = Version.withDescription("version description text"); @@ -56,4 +51,41 @@ public void testWithDescription() { assertNull(version.getRollbackSource()); assertFalse(version.isLegacy()); } + + @Test + public void testEquality() { + final Version versionOne = new Version(new VersionResponse()); + final Version versionTwo = new Version(new VersionResponse()); + + assertEquals(versionOne, versionTwo); + + final Version versionThree = Version.withDescription("abcd"); + final Version versionFour = Version.withDescription("abcd"); + final Version versionFive = new Version(new VersionResponse()).setDescription("abcd"); + + assertEquals(versionThree, versionFour); + assertEquals(versionThree, versionFive); + + final Version versionSix = Version.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 Version versionSeven = new Version(versionResponse); + final Version versionEight = new Version(versionResponse); + + assertEquals(versionSeven, versionEight); + assertNotEquals(versionOne, versionSeven); + assertNotEquals(versionThree, versionSeven); + assertNotEquals(versionSix, versionSeven); + } } diff --git a/src/test/resources/getRemoteConfig.json b/src/test/resources/getRemoteConfig.json index 807866db4..e64d549ca 100644 --- a/src/test/resources/getRemoteConfig.json +++ b/src/test/resources/getRemoteConfig.json @@ -50,7 +50,7 @@ "name": "dev-admin", "imageUrl": "http://image.jpg" }, - "updateTime": "Wed, 30 Sep 2020 17:56:07 GMT", + "updateTime": "2020-11-03T20:24:15.203Z", "description": "promo config" } } From a71dcd231bc4bb3f5d9ed0892017c2bd46ce192e Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Thu, 5 Nov 2020 16:25:17 -0500 Subject: [PATCH 3/4] PR fixes --- .../google/firebase/remoteconfig/Version.java | 16 +++++----------- .../FirebaseRemoteConfigClientImplTest.java | 2 +- src/test/resources/getRemoteConfig.json | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/Version.java b/src/main/java/com/google/firebase/remoteconfig/Version.java index 76220bbcb..2fcfcf9ca 100644 --- a/src/main/java/com/google/firebase/remoteconfig/Version.java +++ b/src/main/java/com/google/firebase/remoteconfig/Version.java @@ -40,9 +40,6 @@ */ public final class Version { - private static final Pattern ZULU_TIME_NO_NANOSECONDS_PATTERN = Pattern - .compile("^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})"); - private final String versionNumber; private final long updateTime; private final String updateOrigin; @@ -69,19 +66,16 @@ private Version() { if (!Strings.isNullOrEmpty(versionResponse.getUpdateTime())) { // Update Time is a timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds. // example: "2014-10-02T15:01:23.045123456Z" - // SimpleDateFormat cannot handle nanoseconds, therefore we drop nanoseconds from the string. - Matcher errorMatcher = ZULU_TIME_NO_NANOSECONDS_PATTERN - .matcher(versionResponse.getUpdateTime()); - String updateTimeWithoutNanoseconds = ""; - if (errorMatcher.find()) { - updateTimeWithoutNanoseconds = errorMatcher.group(1); - } + // SimpleDateFormat cannot handle nanoseconds, therefore we strip nanoseconds from the string. + String updateTime = versionResponse.getUpdateTime(); + int indexOfPeriod = !updateTime.contains(".") ? 0 : updateTime.indexOf("."); + String updateTimeWithoutNanoseconds = updateTime.substring(0, indexOfPeriod); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { this.updateTime = dateFormat.parse(updateTimeWithoutNanoseconds).getTime(); } catch (ParseException e) { - throw new IllegalStateException(); + throw new IllegalStateException("Unable to parse update time.", e); } } else { this.updateTime = 0L; diff --git a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java index abf3865fa..4c1bac0eb 100644 --- a/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/FirebaseRemoteConfigClientImplTest.java @@ -124,7 +124,7 @@ public void testGetTemplate() throws Exception { .setEmail("firebase-user@account.com") .setName("dev-admin") .setImageUrl("http://image.jpg")) - .setUpdateTime("2020-11-03T20:24:15.203Z") + .setUpdateTime("2020-11-03T20:24:15.045123456Z") .setDescription("promo config") ); diff --git a/src/test/resources/getRemoteConfig.json b/src/test/resources/getRemoteConfig.json index e64d549ca..cefc58746 100644 --- a/src/test/resources/getRemoteConfig.json +++ b/src/test/resources/getRemoteConfig.json @@ -50,7 +50,7 @@ "name": "dev-admin", "imageUrl": "http://image.jpg" }, - "updateTime": "2020-11-03T20:24:15.203Z", + "updateTime": "2020-11-03T20:24:15.045123456ZZ", "description": "promo config" } } From a95ba9a9fb6d8d44d106f11393fe7296eca52d8e Mon Sep 17 00:00:00 2001 From: Lahiru Maramba Date: Mon, 9 Nov 2020 18:26:57 -0500 Subject: [PATCH 4/4] Clean up template unit tests --- .../google/firebase/remoteconfig/Version.java | 8 +- .../firebase/remoteconfig/TemplateTest.java | 131 ++++++++++-------- 2 files changed, 77 insertions(+), 62 deletions(-) diff --git a/src/main/java/com/google/firebase/remoteconfig/Version.java b/src/main/java/com/google/firebase/remoteconfig/Version.java index 2fcfcf9ca..e3c182457 100644 --- a/src/main/java/com/google/firebase/remoteconfig/Version.java +++ b/src/main/java/com/google/firebase/remoteconfig/Version.java @@ -68,12 +68,14 @@ private Version() { // example: "2014-10-02T15:01:23.045123456Z" // SimpleDateFormat cannot handle nanoseconds, therefore we strip nanoseconds from the string. String updateTime = versionResponse.getUpdateTime(); - int indexOfPeriod = !updateTime.contains(".") ? 0 : updateTime.indexOf("."); - String updateTimeWithoutNanoseconds = updateTime.substring(0, indexOfPeriod); + int indexOfPeriod = updateTime.indexOf("."); + if (indexOfPeriod != -1) { + updateTime = updateTime.substring(0, indexOfPeriod); + } SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); try { - this.updateTime = dateFormat.parse(updateTimeWithoutNanoseconds).getTime(); + this.updateTime = dateFormat.parse(updateTime).getTime(); } catch (ParseException e) { throw new IllegalStateException("Unable to parse update time.", e); } diff --git a/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java b/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java index e00270663..57f5a2116 100644 --- a/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java +++ b/src/test/java/com/google/firebase/remoteconfig/TemplateTest.java @@ -32,6 +32,52 @@ public class TemplateTest { + private static final List CONDITIONS = ImmutableList.of( + new Condition("ios_en", "exp ios") + .setTagColor(TagColor.INDIGO), + new Condition("android_en", "exp android") + ); + + private static final Map CONDITIONAL_VALUES = ImmutableMap.of( + "ios", ParameterValue.of("hello ios"), + "android", ParameterValue.of("hello android"), + "promo", ParameterValue.inAppDefault() + ); + + private static final Map PARAMETERS = ImmutableMap.of( + "greeting_header", new Parameter() + .setDefaultValue(ParameterValue.inAppDefault()) + .setDescription("greeting header text") + .setConditionalValues(CONDITIONAL_VALUES), + "greeting_text", new Parameter() + .setDefaultValue(ParameterValue.inAppDefault()) + .setDescription("greeting text") + .setConditionalValues(CONDITIONAL_VALUES) + ); + + private static final Map PARAMETER_GROUPS = ImmutableMap.of( + "greetings_group", new ParameterGroup() + .setDescription("description") + .setParameters(PARAMETERS) + ); + + private static final Template EMPTY_TEMPLATE = new Template(); + + private static final Template TEMPLATE_WITH_CONDITIONS_PARAMETERS = new Template() + .setConditions(CONDITIONS) + .setParameters(PARAMETERS); + + private static final Template TEMPLATE_WITH_CONDITIONS_PARAMETERS_GROUPS = new Template() + .setConditions(CONDITIONS) + .setParameters(PARAMETERS) + .setParameterGroups(PARAMETER_GROUPS); + + private static final Template TEMPLATE_WITH_ETAG = new Template() + .setETag("etag-123456789097-20"); + + private static final Template TEMPLATE_WITH_VERSION = new Template() + .setVersion(Version.withDescription("promo version")); + @Test public void testConstructor() { Template template = new Template(); @@ -71,73 +117,40 @@ public void testSetNullParameterGroups() { @Test public void testEquality() { final Template templateOne = new Template(); - final Template templateTwo = new Template(); - - assertEquals(templateOne, templateTwo); - - final List conditions = ImmutableList.of( - new Condition("ios_en", "exp ios") - .setTagColor(TagColor.INDIGO), - new Condition("android_en", "exp android") - ); - final Map conditionalValues = ImmutableMap.of( - "ios", ParameterValue.of("hello ios"), - "android", ParameterValue.of("hello android"), - "promo", ParameterValue.inAppDefault() - ); - final Map parameters = ImmutableMap.of( - "greeting_header", new Parameter() - .setDefaultValue(ParameterValue.inAppDefault()) - .setDescription("greeting header text") - .setConditionalValues(conditionalValues), - "greeting_text", new Parameter() - .setDefaultValue(ParameterValue.inAppDefault()) - .setDescription("greeting text") - .setConditionalValues(conditionalValues) - ); - final Template templateThree = new Template() - .setConditions(conditions) - .setParameters(parameters); - final Template templateFour = new Template() - .setConditions(conditions) - .setParameters(parameters); - assertEquals(templateThree, templateFour); + assertEquals(EMPTY_TEMPLATE, templateOne); - final Map parameterGroups = ImmutableMap.of( - "greetings_group", new ParameterGroup() - .setDescription("description") - .setParameters(parameters) - ); - final Template templateFive = new Template() - .setConditions(conditions) - .setParameters(parameters) - .setParameterGroups(parameterGroups); - final Template templateSix = new Template() - .setConditions(conditions) - .setParameters(parameters) - .setParameterGroups(parameterGroups); + final Template templateTwo = new Template() + .setConditions(CONDITIONS) + .setParameters(PARAMETERS); - assertEquals(templateFive, templateSix); + assertEquals(TEMPLATE_WITH_CONDITIONS_PARAMETERS, templateTwo); - final Template templateSeven = new Template() - .setETag("etag-123456789097-20"); - final Template templateEight = new Template() + final Template templateThree = new Template() + .setConditions(CONDITIONS) + .setParameters(PARAMETERS) + .setParameterGroups(PARAMETER_GROUPS); + + assertEquals(TEMPLATE_WITH_CONDITIONS_PARAMETERS_GROUPS, templateThree); + + final Template templateFour = new Template() .setETag("etag-123456789097-20"); - assertEquals(templateSeven, templateEight); + assertEquals(TEMPLATE_WITH_ETAG, templateFour); + + final Template templateFive = new Template() + .setVersion(Version.withDescription("promo version")); + + assertEquals(TEMPLATE_WITH_VERSION, templateFive); + assertNotEquals(templateOne, templateTwo); assertNotEquals(templateOne, templateThree); + assertNotEquals(templateOne, templateFour); assertNotEquals(templateOne, templateFive); - assertNotEquals(templateOne, templateSeven); + assertNotEquals(templateTwo, templateThree); + assertNotEquals(templateTwo, templateFour); + assertNotEquals(templateTwo, templateFive); + assertNotEquals(templateThree, templateFour); assertNotEquals(templateThree, templateFive); - assertNotEquals(templateThree, templateSeven); - assertNotEquals(templateFive, templateSeven); - - final Template templateNine = new Template() - .setVersion(Version.withDescription("promo version")); - final Template templateTen = new Template() - .setVersion(Version.withDescription("promo version")); - assertEquals(templateNine, templateTen); - assertNotEquals(templateOne, templateNine); + assertNotEquals(templateFour, templateFive); } }