diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/RemoteConfigController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/RemoteConfigController.java index 97ef203d1..564fef311 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/RemoteConfigController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/RemoteConfigController.java @@ -2,6 +2,7 @@ package org.whispersystems.textsecuregcm.controllers; import com.codahale.metrics.annotation.Timed; import com.google.common.annotations.VisibleForTesting; +import io.dropwizard.auth.Auth; import org.whispersystems.textsecuregcm.entities.UserRemoteConfig; import org.whispersystems.textsecuregcm.entities.UserRemoteConfigList; import org.whispersystems.textsecuregcm.storage.Account; @@ -29,8 +30,6 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -import io.dropwizard.auth.Auth; - @Path("/v1/config") public class RemoteConfigController { @@ -50,12 +49,10 @@ public class RemoteConfigController { try { MessageDigest digest = MessageDigest.getInstance("SHA1"); - return new UserRemoteConfigList(remoteConfigsManager.getAll().stream().map(config -> new UserRemoteConfig(config.getName(), - isInBucket(digest, account.getUuid(), - config.getName().getBytes(), - config.getPercentage(), - config.getUuids()))) - .collect(Collectors.toList())); + return new UserRemoteConfigList(remoteConfigsManager.getAll().stream().map(config -> { + boolean inBucket = isInBucket(digest, account.getUuid(), config.getName().getBytes(), config.getPercentage(), config.getUuids()); + return new UserRemoteConfig(config.getName(), inBucket, inBucket ? config.getValue() : config.getDefaultValue()); + }).collect(Collectors.toList())); } catch (NoSuchAlgorithmException e) { throw new AssertionError(e); } @@ -104,5 +101,4 @@ public class RemoteConfigController { private boolean isAuthorized(String configToken) { return configToken != null && configAuthTokens.stream().anyMatch(authorized -> MessageDigest.isEqual(authorized.getBytes(), configToken.getBytes())); } - } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/entities/UserRemoteConfig.java b/service/src/main/java/org/whispersystems/textsecuregcm/entities/UserRemoteConfig.java index f8e01fa60..c3670d82d 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/entities/UserRemoteConfig.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/entities/UserRemoteConfig.java @@ -5,16 +5,20 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class UserRemoteConfig { @JsonProperty - private String name; + private String name; @JsonProperty private boolean enabled; + @JsonProperty + private String value; + public UserRemoteConfig() {} - public UserRemoteConfig(String name, boolean enabled) { + public UserRemoteConfig(String name, boolean enabled, String value) { this.name = name; this.enabled = enabled; + this.value = value; } public String getName() { @@ -24,4 +28,8 @@ public class UserRemoteConfig { public boolean isEnabled() { return enabled; } + + public String getValue() { + return value; + } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfig.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfig.java index facedbcec..9f4d5daaf 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfig.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfig.java @@ -7,8 +7,6 @@ import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Set; import java.util.UUID; @@ -28,12 +26,20 @@ public class RemoteConfig { @NotNull private Set uuids = new HashSet<>(); + @JsonProperty + private String defaultValue; + + @JsonProperty + private String value; + public RemoteConfig() {} - public RemoteConfig(String name, int percentage, Set uuids) { - this.name = name; - this.percentage = percentage; - this.uuids = uuids; + public RemoteConfig(String name, int percentage, Set uuids, String defaultValue, String value) { + this.name = name; + this.percentage = percentage; + this.uuids = uuids; + this.defaultValue = defaultValue; + this.value = value; } public int getPercentage() { @@ -47,4 +53,12 @@ public class RemoteConfig { public Set getUuids() { return uuids; } + + public String getDefaultValue() { + return defaultValue; + } + + public String getValue() { + return value; + } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigs.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigs.java index fe692b5ad..637622fa9 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigs.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigs.java @@ -3,27 +3,22 @@ package org.whispersystems.textsecuregcm.storage; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.SharedMetricRegistries; import com.codahale.metrics.Timer; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.jdbi.v3.core.transaction.TransactionIsolationLevel; -import org.whispersystems.textsecuregcm.storage.mappers.AccountRowMapper; import org.whispersystems.textsecuregcm.storage.mappers.RemoteConfigRowMapper; import org.whispersystems.textsecuregcm.util.Constants; -import org.whispersystems.textsecuregcm.util.SystemMapper; -import java.util.LinkedList; import java.util.List; -import java.util.Optional; import java.util.UUID; import static com.codahale.metrics.MetricRegistry.name; public class RemoteConfigs { - public static final String ID = "id"; - public static final String NAME = "name"; - public static final String PERCENTAGE = "percentage"; - public static final String UUIDS = "uuids"; + public static final String ID = "id"; + public static final String NAME = "name"; + public static final String PERCENTAGE = "percentage"; + public static final String UUIDS = "uuids"; + public static final String DEFAULT_VALUE = "default_value"; + public static final String VALUE = "value"; private final MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME); private final Timer setTimer = metricRegistry.timer(name(Accounts.class, "set" )); @@ -41,11 +36,13 @@ public class RemoteConfigs { public void set(RemoteConfig remoteConfig) { database.use(jdbi -> jdbi.useHandle(handle -> { try (Timer.Context ignored = setTimer.time()) { - handle.createUpdate("INSERT INTO remote_config (" + NAME + ", " + PERCENTAGE + ", " + UUIDS + ") VALUES (:name, :percentage, :uuids) ON CONFLICT(" + NAME + ") DO UPDATE SET " + PERCENTAGE + " = EXCLUDED." + PERCENTAGE + ", " + UUIDS + " = EXCLUDED." + UUIDS) - .bind("name", remoteConfig.getName()) - .bind("percentage", remoteConfig.getPercentage()) - .bind("uuids", remoteConfig.getUuids().toArray(new UUID[0])) - .execute(); + handle.createUpdate("INSERT INTO remote_config (" + NAME + ", " + PERCENTAGE + ", " + UUIDS + ", " + DEFAULT_VALUE + ", " + VALUE + ") VALUES (:name, :percentage, :uuids, :default_value, :value) ON CONFLICT(" + NAME + ") DO UPDATE SET " + PERCENTAGE + " = EXCLUDED." + PERCENTAGE + ", " + UUIDS + " = EXCLUDED." + UUIDS + ", " + DEFAULT_VALUE + " = EXCLUDED." + DEFAULT_VALUE + ", " + VALUE + " = EXCLUDED." + VALUE) + .bind("name", remoteConfig.getName()) + .bind("percentage", remoteConfig.getPercentage()) + .bind("uuids", remoteConfig.getUuids().toArray(new UUID[0])) + .bind("default_value", remoteConfig.getDefaultValue()) + .bind("value", remoteConfig.getValue()) + .execute(); } })); } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigsManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigsManager.java index 4a775302c..d955274b4 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigsManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/RemoteConfigsManager.java @@ -1,6 +1,7 @@ package org.whispersystems.textsecuregcm.storage; import com.google.common.annotations.VisibleForTesting; +import io.dropwizard.lifecycle.Managed; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.util.Util; @@ -10,8 +11,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; -import io.dropwizard.lifecycle.Managed; - public class RemoteConfigsManager implements Managed { private final Logger logger = LoggerFactory.getLogger(RemoteConfigsManager.class); @@ -19,7 +18,7 @@ public class RemoteConfigsManager implements Managed { private final RemoteConfigs remoteConfigs; private final long sleepInterval; - private AtomicReference> cachedConfigs = new AtomicReference<>(new LinkedList<>()); + private final AtomicReference> cachedConfigs = new AtomicReference<>(new LinkedList<>()); public RemoteConfigsManager(RemoteConfigs remoteConfigs) { this(remoteConfigs, TimeUnit.SECONDS.toMillis(10)); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/mappers/RemoteConfigRowMapper.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/mappers/RemoteConfigRowMapper.java index 46b8d5428..bacc6a4a7 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/mappers/RemoteConfigRowMapper.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/mappers/RemoteConfigRowMapper.java @@ -16,6 +16,10 @@ public class RemoteConfigRowMapper implements RowMapper { @Override public RemoteConfig map(ResultSet rs, StatementContext ctx) throws SQLException { - return new RemoteConfig(rs.getString(RemoteConfigs.NAME), rs.getInt(RemoteConfigs.PERCENTAGE), new HashSet<>(Arrays.asList((UUID[])rs.getArray(RemoteConfigs.UUIDS).getArray()))); + return new RemoteConfig(rs.getString(RemoteConfigs.NAME), + rs.getInt(RemoteConfigs.PERCENTAGE), + new HashSet<>(Arrays.asList((UUID[])rs.getArray(RemoteConfigs.UUIDS).getArray())), + rs.getString(RemoteConfigs.DEFAULT_VALUE), + rs.getString(RemoteConfigs.VALUE)); } } diff --git a/service/src/main/resources/accountsdb.xml b/service/src/main/resources/accountsdb.xml index 7bb8995dd..1de061d16 100644 --- a/service/src/main/resources/accountsdb.xml +++ b/service/src/main/resources/accountsdb.xml @@ -310,5 +310,12 @@ + + + + + + + diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/RemoteConfigControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/RemoteConfigControllerTest.java index d117cfe22..d1b3856dd 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/RemoteConfigControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/RemoteConfigControllerTest.java @@ -1,6 +1,8 @@ package org.whispersystems.textsecuregcm.tests.controllers; import com.google.common.collect.ImmutableSet; +import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; +import io.dropwizard.testing.junit.ResourceTestRule; import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.junit.Before; import org.junit.Rule; @@ -20,26 +22,25 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; -import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider; -import io.dropwizard.testing.junit.ResourceTestRule; -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; public class RemoteConfigControllerTest { - private RemoteConfigsManager remoteConfigsManager = mock(RemoteConfigsManager.class); - private List remoteConfigsAuth = new LinkedList<>() {{ - add("foo"); - add("bar"); - }}; + private final RemoteConfigsManager remoteConfigsManager = mock(RemoteConfigsManager.class); + private final List remoteConfigsAuth = List.of("foo", "bar"); @Rule public final ResourceTestRule resources = ResourceTestRule.builder() @@ -52,24 +53,15 @@ public class RemoteConfigControllerTest { @Before - public void setup() throws Exception { + public void setup() { when(remoteConfigsManager.getAll()).thenReturn(new LinkedList<>() {{ - add(new RemoteConfig("android.stickers", 25, new HashSet<>() {{ - add(AuthHelper.DISABLED_UUID); - add(AuthHelper.INVALID_UUID); - }})); - - add(new RemoteConfig("ios.stickers", 50, new HashSet<>() {{ - - }})); - - add(new RemoteConfig("always.true", 100, new HashSet<>() {{ - - }})); - - add(new RemoteConfig("only.special", 0, new HashSet<>() {{ - add(AuthHelper.VALID_UUID); - }})); + add(new RemoteConfig("android.stickers", 25, Set.of(AuthHelper.DISABLED_UUID, AuthHelper.INVALID_UUID), null, null)); + add(new RemoteConfig("ios.stickers", 50, Set.of(), null, null)); + add(new RemoteConfig("always.true", 100, Set.of(), null, null)); + add(new RemoteConfig("only.special", 0, Set.of(AuthHelper.VALID_UUID), null, null)); + add(new RemoteConfig("value.always.true", 100, Set.of(), "foo", "bar")); + add(new RemoteConfig("value.only.special", 0, Set.of(AuthHelper.VALID_UUID), "abc", "xyz")); + add(new RemoteConfig("value.always.false", 0, Set.of(), "red", "green")); }}); } @@ -83,12 +75,24 @@ public class RemoteConfigControllerTest { verify(remoteConfigsManager, times(1)).getAll(); - assertThat(configuration.getConfig().size()).isEqualTo(4); + assertThat(configuration.getConfig().size()).isEqualTo(7); assertThat(configuration.getConfig().get(0).getName()).isEqualTo("android.stickers"); assertThat(configuration.getConfig().get(1).getName()).isEqualTo("ios.stickers"); assertThat(configuration.getConfig().get(2).getName()).isEqualTo("always.true"); assertThat(configuration.getConfig().get(2).isEnabled()).isEqualTo(true); + assertThat(configuration.getConfig().get(2).getValue()).isNull(); + assertThat(configuration.getConfig().get(3).getName()).isEqualTo("only.special"); assertThat(configuration.getConfig().get(3).isEnabled()).isEqualTo(true); + assertThat(configuration.getConfig().get(2).getValue()).isNull(); + assertThat(configuration.getConfig().get(4).getName()).isEqualTo("value.always.true"); + assertThat(configuration.getConfig().get(4).isEnabled()).isEqualTo(true); + assertThat(configuration.getConfig().get(4).getValue()).isEqualTo("bar"); + assertThat(configuration.getConfig().get(5).getName()).isEqualTo("value.only.special"); + assertThat(configuration.getConfig().get(5).isEnabled()).isEqualTo(true); + assertThat(configuration.getConfig().get(5).getValue()).isEqualTo("xyz"); + assertThat(configuration.getConfig().get(6).getName()).isEqualTo("value.always.false"); + assertThat(configuration.getConfig().get(6).isEnabled()).isEqualTo(false); + assertThat(configuration.getConfig().get(6).getValue()).isEqualTo("red"); } @Test @@ -101,12 +105,24 @@ public class RemoteConfigControllerTest { verify(remoteConfigsManager, times(1)).getAll(); - assertThat(configuration.getConfig().size()).isEqualTo(4); + assertThat(configuration.getConfig().size()).isEqualTo(7); assertThat(configuration.getConfig().get(0).getName()).isEqualTo("android.stickers"); assertThat(configuration.getConfig().get(1).getName()).isEqualTo("ios.stickers"); assertThat(configuration.getConfig().get(2).getName()).isEqualTo("always.true"); assertThat(configuration.getConfig().get(2).isEnabled()).isEqualTo(true); + assertThat(configuration.getConfig().get(2).getValue()).isNull(); + assertThat(configuration.getConfig().get(3).getName()).isEqualTo("only.special"); assertThat(configuration.getConfig().get(3).isEnabled()).isEqualTo(false); + assertThat(configuration.getConfig().get(2).getValue()).isNull(); + assertThat(configuration.getConfig().get(4).getName()).isEqualTo("value.always.true"); + assertThat(configuration.getConfig().get(4).isEnabled()).isEqualTo(true); + assertThat(configuration.getConfig().get(4).getValue()).isEqualTo("bar"); + assertThat(configuration.getConfig().get(5).getName()).isEqualTo("value.only.special"); + assertThat(configuration.getConfig().get(5).isEnabled()).isEqualTo(false); + assertThat(configuration.getConfig().get(5).getValue()).isEqualTo("abc"); + assertThat(configuration.getConfig().get(6).getName()).isEqualTo("value.always.false"); + assertThat(configuration.getConfig().get(6).isEnabled()).isEqualTo(false); + assertThat(configuration.getConfig().get(6).getValue()).isEqualTo("red"); } @@ -130,7 +146,7 @@ public class RemoteConfigControllerTest { .target("/v1/config") .request() .header("Config-Token", "foo") - .put(Entity.entity(new RemoteConfig("android.stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE)); + .put(Entity.entity(new RemoteConfig("android.stickers", 88, Set.of(), "FALSE", "TRUE"), MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(204); @@ -143,13 +159,32 @@ public class RemoteConfigControllerTest { assertThat(captor.getValue().getUuids()).isEmpty(); } + @Test + public void testSetConfigValued() { + Response response = resources.getJerseyTest() + .target("/v1/config") + .request() + .header("Config-Token", "foo") + .put(Entity.entity(new RemoteConfig("value.sometimes", 50, Set.of(), "a", "b"), MediaType.APPLICATION_JSON_TYPE)); + + assertThat(response.getStatus()).isEqualTo(204); + + ArgumentCaptor captor = ArgumentCaptor.forClass(RemoteConfig.class); + + verify(remoteConfigsManager, times(1)).set(captor.capture()); + + assertThat(captor.getValue().getName()).isEqualTo("value.sometimes"); + assertThat(captor.getValue().getPercentage()).isEqualTo(50); + assertThat(captor.getValue().getUuids()).isEmpty(); + } + @Test public void testSetConfigUnauthorized() { Response response = resources.getJerseyTest() .target("/v1/config") .request() .header("Config-Token", "baz") - .put(Entity.entity(new RemoteConfig("android.stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE)); + .put(Entity.entity(new RemoteConfig("android.stickers", 88, Set.of(), "FALSE", "TRUE"), MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(401); @@ -161,7 +196,7 @@ public class RemoteConfigControllerTest { Response response = resources.getJerseyTest() .target("/v1/config") .request() - .put(Entity.entity(new RemoteConfig("android.stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE)); + .put(Entity.entity(new RemoteConfig("android.stickers", 88, Set.of(), "FALSE", "TRUE"), MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(401); @@ -174,7 +209,7 @@ public class RemoteConfigControllerTest { .target("/v1/config") .request() .header("Config-Token", "foo") - .put(Entity.entity(new RemoteConfig("android-stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE)); + .put(Entity.entity(new RemoteConfig("android-stickers", 88, Set.of(), "FALSE", "TRUE"), MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(422); @@ -187,7 +222,7 @@ public class RemoteConfigControllerTest { .target("/v1/config") .request() .header("Config-Token", "foo") - .put(Entity.entity(new RemoteConfig("", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE)); + .put(Entity.entity(new RemoteConfig("", 88, Set.of(), "FALSE", "TRUE"), MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(422); @@ -232,7 +267,6 @@ public class RemoteConfigControllerTest { for (int i=0;i())) { count++; diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsManagerTest.java index 9bd87540e..6ff42948b 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsManagerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsManagerTest.java @@ -14,11 +14,10 @@ import org.whispersystems.textsecuregcm.storage.RemoteConfigs; import org.whispersystems.textsecuregcm.storage.RemoteConfigsManager; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; -import java.util.HashSet; import java.util.List; +import java.util.Set; -import io.dropwizard.auth.Auth; -import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class RemoteConfigsManagerTest { @@ -36,17 +35,18 @@ public class RemoteConfigsManagerTest { @Test public void testUpdate() throws InterruptedException { - remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>() {{ - add(AuthHelper.VALID_UUID); - }})); - remoteConfigs.set(new RemoteConfig("ios.stickers", 50, new HashSet<>())); - remoteConfigs.set(new RemoteConfig("ios.stickers", 75, new HashSet<>())); + remoteConfigs.set(new RemoteConfig("android.stickers", 50, Set.of(AuthHelper.VALID_UUID), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("value.sometimes", 50, Set.of(), "bar", "baz")); + remoteConfigs.set(new RemoteConfig("ios.stickers", 50, Set.of(), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("ios.stickers", 75, Set.of(), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("value.sometimes", 25, Set.of(AuthHelper.VALID_UUID), "abc", "def")); Thread.sleep(501); List results = remoteConfigs.getAll(); - assertThat(results.size()).isEqualTo(2); + assertThat(results.size()).isEqualTo(3); + assertThat(results.get(0).getName()).isEqualTo("android.stickers"); assertThat(results.get(0).getPercentage()).isEqualTo(50); assertThat(results.get(0).getUuids().size()).isEqualTo(1); @@ -56,6 +56,13 @@ public class RemoteConfigsManagerTest { assertThat(results.get(1).getPercentage()).isEqualTo(75); assertThat(results.get(1).getUuids()).isEmpty(); + assertThat(results.get(2).getName()).isEqualTo("value.sometimes"); + assertThat(results.get(2).getUuids()).hasSize(1); + assertThat(results.get(2).getUuids()).contains(AuthHelper.VALID_UUID); + assertThat(results.get(2).getPercentage()).isEqualTo(25); + assertThat(results.get(2).getDefaultValue()).isEqualTo("abc"); + assertThat(results.get(2).getValue()).isEqualTo("def"); + } } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsTest.java index b639384ac..3ba6a3496 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/RemoteConfigsTest.java @@ -13,12 +13,10 @@ import org.whispersystems.textsecuregcm.storage.RemoteConfig; import org.whispersystems.textsecuregcm.storage.RemoteConfigs; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; -import java.sql.SQLException; -import java.util.HashSet; import java.util.List; +import java.util.Set; -import io.dropwizard.auth.Auth; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.Assertions.assertThat; public class RemoteConfigsTest { @@ -33,60 +31,84 @@ public class RemoteConfigsTest { } @Test - public void testStore() throws SQLException { - remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>() {{ - add(AuthHelper.VALID_UUID); - add(AuthHelper.VALID_UUID_TWO); - }})); + public void testStore() { + remoteConfigs.set(new RemoteConfig("android.stickers", 50, Set.of(AuthHelper.VALID_UUID, AuthHelper.VALID_UUID_TWO), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("value.sometimes", 25, Set.of(AuthHelper.VALID_UUID_TWO), "default", "custom")); List configs = remoteConfigs.getAll(); - assertThat(configs.size()).isEqualTo(1); + assertThat(configs).hasSize(2); + assertThat(configs.get(0).getName()).isEqualTo("android.stickers"); + assertThat(configs.get(0).getValue()).isEqualTo("TRUE"); + assertThat(configs.get(0).getDefaultValue()).isEqualTo("FALSE"); assertThat(configs.get(0).getPercentage()).isEqualTo(50); - assertThat(configs.get(0).getUuids().size()).isEqualTo(2); - assertThat(configs.get(0).getUuids().contains(AuthHelper.VALID_UUID)).isTrue(); - assertThat(configs.get(0).getUuids().contains(AuthHelper.VALID_UUID_TWO)).isTrue(); - assertThat(configs.get(0).getUuids().contains(AuthHelper.INVALID_UUID)).isFalse(); + assertThat(configs.get(0).getUuids()).hasSize(2); + assertThat(configs.get(0).getUuids()).contains(AuthHelper.VALID_UUID); + assertThat(configs.get(0).getUuids()).contains(AuthHelper.VALID_UUID_TWO); + assertThat(configs.get(0).getUuids()).doesNotContain(AuthHelper.INVALID_UUID); + + assertThat(configs.get(1).getName()).isEqualTo("value.sometimes"); + assertThat(configs.get(1).getValue()).isEqualTo("custom"); + assertThat(configs.get(1).getDefaultValue()).isEqualTo("default"); + assertThat(configs.get(1).getPercentage()).isEqualTo(25); + assertThat(configs.get(1).getUuids()).hasSize(1); + assertThat(configs.get(1).getUuids()).contains(AuthHelper.VALID_UUID_TWO); + assertThat(configs.get(1).getUuids()).doesNotContain(AuthHelper.VALID_UUID); + assertThat(configs.get(1).getUuids()).doesNotContain(AuthHelper.INVALID_UUID); } @Test - public void testUpdate() throws SQLException { - remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>())); - - remoteConfigs.set(new RemoteConfig("ios.stickers", 50, new HashSet<>() {{ - add(AuthHelper.DISABLED_UUID); - }})); - - remoteConfigs.set(new RemoteConfig("ios.stickers", 75, new HashSet<>())); + public void testUpdate() { + remoteConfigs.set(new RemoteConfig("android.stickers", 50, Set.of(), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("value.sometimes", 22, Set.of(), "def", "!")); + remoteConfigs.set(new RemoteConfig("ios.stickers", 50, Set.of(AuthHelper.DISABLED_UUID), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("ios.stickers", 75, Set.of(), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("value.sometimes", 77, Set.of(), "hey", "wut")); List configs = remoteConfigs.getAll(); - assertThat(configs.size()).isEqualTo(2); + assertThat(configs).hasSize(3); + assertThat(configs.get(0).getName()).isEqualTo("android.stickers"); assertThat(configs.get(0).getPercentage()).isEqualTo(50); - assertThat(configs.get(0).getUuids().size()).isEqualTo(0); + assertThat(configs.get(0).getUuids()).isEmpty(); + assertThat(configs.get(0).getDefaultValue()).isEqualTo("FALSE"); + assertThat(configs.get(0).getValue()).isEqualTo("TRUE"); assertThat(configs.get(1).getName()).isEqualTo("ios.stickers"); assertThat(configs.get(1).getPercentage()).isEqualTo(75); - assertThat(configs.get(1).getUuids().size()).isEqualTo(0); + assertThat(configs.get(1).getUuids()).isEmpty(); + assertThat(configs.get(1).getDefaultValue()).isEqualTo("FALSE"); + assertThat(configs.get(1).getValue()).isEqualTo("TRUE"); + + assertThat(configs.get(2).getName()).isEqualTo("value.sometimes"); + assertThat(configs.get(2).getPercentage()).isEqualTo(77); + assertThat(configs.get(2).getUuids()).isEmpty(); + assertThat(configs.get(2).getDefaultValue()).isEqualTo("hey"); + assertThat(configs.get(2).getValue()).isEqualTo("wut"); } @Test public void testDelete() { - remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>() {{ - add(AuthHelper.VALID_UUID); - }})); - remoteConfigs.set(new RemoteConfig("ios.stickers", 50, new HashSet<>())); - remoteConfigs.set(new RemoteConfig("ios.stickers", 75, new HashSet<>())); + remoteConfigs.set(new RemoteConfig("android.stickers", 50, Set.of(AuthHelper.VALID_UUID), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("ios.stickers", 50, Set.of(), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("ios.stickers", 75, Set.of(), "FALSE", "TRUE")); + remoteConfigs.set(new RemoteConfig("value.always", 100, Set.of(), "never", "always")); remoteConfigs.delete("android.stickers"); List configs = remoteConfigs.getAll(); - assertThat(configs.size()).isEqualTo(1); + assertThat(configs).hasSize(2); + assertThat(configs.get(0).getName()).isEqualTo("ios.stickers"); assertThat(configs.get(0).getPercentage()).isEqualTo(75); + assertThat(configs.get(0).getDefaultValue()).isEqualTo("FALSE"); + assertThat(configs.get(0).getValue()).isEqualTo("TRUE"); + + assertThat(configs.get(1).getName()).isEqualTo("value.always"); + assertThat(configs.get(1).getPercentage()).isEqualTo(100); + assertThat(configs.get(1).getValue()).isEqualTo("always"); + assertThat(configs.get(1).getDefaultValue()).isEqualTo("never"); } - - }