Migrate service tests to JUnit 5

This commit is contained in:
Chris Eager 2021-12-20 22:49:59 -08:00 committed by Chris Eager
parent b758737907
commit a1e84f5a88
35 changed files with 653 additions and 659 deletions

View File

@ -388,11 +388,6 @@
<version>3.3.16.RELEASE</version> <version>3.3.16.RELEASE</version>
</dependency> </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId> <artifactId>junit-jupiter-params</artifactId>

View File

@ -5,28 +5,27 @@
package org.whispersystems.textsecuregcm.auth; package org.whispersystems.textsecuregcm.auth;
import org.junit.Test; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.whispersystems.textsecuregcm.crypto.Curve; import static org.mockito.Mockito.mock;
import org.whispersystems.textsecuregcm.storage.Account; import static org.mockito.Mockito.when;
import org.whispersystems.textsecuregcm.storage.Device;
import java.io.IOException; import java.io.IOException;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.util.Base64; import java.util.Base64;
import java.util.UUID; import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.crypto.Curve;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.Device;
import static org.junit.Assert.assertTrue; class CertificateGeneratorTest {
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class CertificateGeneratorTest {
private static final String SIGNING_CERTIFICATE = "CiUIDBIhBbTz4h1My+tt+vw+TVscgUe/DeHS0W02tPWAWbTO2xc3EkD+go4bJnU0AcnFfbOLKoiBfCzouZtDYMOVi69rE7r4U9cXREEqOkUmU2WJBjykAxWPCcSTmVTYHDw7hkSp/puG"; private static final String SIGNING_CERTIFICATE = "CiUIDBIhBbTz4h1My+tt+vw+TVscgUe/DeHS0W02tPWAWbTO2xc3EkD+go4bJnU0AcnFfbOLKoiBfCzouZtDYMOVi69rE7r4U9cXREEqOkUmU2WJBjykAxWPCcSTmVTYHDw7hkSp/puG";
private static final String SIGNING_KEY = "ABOxG29xrfq4E7IrW11Eg7+HBbtba9iiS0500YoBjn4="; private static final String SIGNING_KEY = "ABOxG29xrfq4E7IrW11Eg7+HBbtba9iiS0500YoBjn4=";
private static final String IDENTITY_KEY = "BcxxDU9FGMda70E7+Uvm7pnQcEdXQ64aJCpPUeRSfcFo"; private static final String IDENTITY_KEY = "BcxxDU9FGMda70E7+Uvm7pnQcEdXQ64aJCpPUeRSfcFo";
@Test @Test
public void testCreateFor() throws IOException, InvalidKeyException { void testCreateFor() throws IOException, InvalidKeyException {
final Account account = mock(Account.class); final Account account = mock(Account.class);
final Device device = mock(Device.class); final Device device = mock(Device.class);
final CertificateGenerator certificateGenerator = new CertificateGenerator(Base64.getDecoder().decode(SIGNING_CERTIFICATE), Curve.decodePrivatePoint(Base64.getDecoder().decode(SIGNING_KEY)), 1); final CertificateGenerator certificateGenerator = new CertificateGenerator(Base64.getDecoder().decode(SIGNING_CERTIFICATE), Curve.decodePrivatePoint(Base64.getDecoder().decode(SIGNING_KEY)), 1);

View File

@ -10,13 +10,13 @@ import java.math.BigDecimal;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.entities.CurrencyConversionEntityList; import org.whispersystems.textsecuregcm.entities.CurrencyConversionEntityList;
public class CurrencyConversionManagerTest { class CurrencyConversionManagerTest {
@Test @Test
public void testCurrencyCalculations() throws IOException { void testCurrencyCalculations() throws IOException {
FixerClient fixerClient = mock(FixerClient.class); FixerClient fixerClient = mock(FixerClient.class);
FtxClient ftxClient = mock(FtxClient.class); FtxClient ftxClient = mock(FtxClient.class);
@ -43,7 +43,7 @@ public class CurrencyConversionManagerTest {
} }
@Test @Test
public void testCurrencyCalculations_noTrailingZeros() throws IOException { void testCurrencyCalculations_noTrailingZeros() throws IOException {
FixerClient fixerClient = mock(FixerClient.class); FixerClient fixerClient = mock(FixerClient.class);
FtxClient ftxClient = mock(FtxClient.class); FtxClient ftxClient = mock(FtxClient.class);
@ -72,7 +72,7 @@ public class CurrencyConversionManagerTest {
} }
@Test @Test
public void testCurrencyCalculations_accuracy() throws IOException { void testCurrencyCalculations_accuracy() throws IOException {
FixerClient fixerClient = mock(FixerClient.class); FixerClient fixerClient = mock(FixerClient.class);
FtxClient ftxClient = mock(FtxClient.class); FtxClient ftxClient = mock(FtxClient.class);
@ -100,7 +100,7 @@ public class CurrencyConversionManagerTest {
} }
@Test @Test
public void testCurrencyCalculationsTimeoutNoRun() throws IOException { void testCurrencyCalculationsTimeoutNoRun() throws IOException {
FixerClient fixerClient = mock(FixerClient.class); FixerClient fixerClient = mock(FixerClient.class);
FtxClient ftxClient = mock(FtxClient.class); FtxClient ftxClient = mock(FtxClient.class);
@ -131,7 +131,7 @@ public class CurrencyConversionManagerTest {
} }
@Test @Test
public void testCurrencyCalculationsFtxTimeoutWithRun() throws IOException { void testCurrencyCalculationsFtxTimeoutWithRun() throws IOException {
FixerClient fixerClient = mock(FixerClient.class); FixerClient fixerClient = mock(FixerClient.class);
FtxClient ftxClient = mock(FtxClient.class); FtxClient ftxClient = mock(FtxClient.class);
@ -163,7 +163,7 @@ public class CurrencyConversionManagerTest {
@Test @Test
public void testCurrencyCalculationsFixerTimeoutWithRun() throws IOException { void testCurrencyCalculationsFixerTimeoutWithRun() throws IOException {
FixerClient fixerClient = mock(FixerClient.class); FixerClient fixerClient = mock(FixerClient.class);
FtxClient ftxClient = mock(FtxClient.class); FtxClient ftxClient = mock(FtxClient.class);
@ -197,7 +197,6 @@ public class CurrencyConversionManagerTest {
assertThat(conversions.getCurrencies().get(0).getConversions().get("EUR")).isEqualTo(new BigDecimal("2.1687586")); assertThat(conversions.getCurrencies().get(0).getConversions().get("EUR")).isEqualTo(new BigDecimal("2.1687586"));
assertThat(conversions.getCurrencies().get(0).getConversions().get("FJD")).isEqualTo(new BigDecimal("4.835595")); assertThat(conversions.getCurrencies().get(0).getConversions().get("FJD")).isEqualTo(new BigDecimal("4.835595"));
assertThat(conversions.getCurrencies().get(0).getConversions().get("FKP")).isEqualTo(new BigDecimal("1.7470981")); assertThat(conversions.getCurrencies().get(0).getConversions().get("FKP")).isEqualTo(new BigDecimal("1.7470981"));
} }
} }

View File

@ -5,20 +5,6 @@
package org.whispersystems.textsecuregcm.experiment; package org.whispersystems.textsecuregcm.experiment;
import io.micrometer.core.instrument.Timer;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
@ -27,16 +13,27 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset; import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@RunWith(JUnitParamsRunner.class) import io.micrometer.core.instrument.Timer;
public class ExperimentTest { import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
class ExperimentTest {
private Timer matchTimer; private Timer matchTimer;
private Timer errorTimer; private Timer errorTimer;
private Experiment experiment; private Experiment experiment;
@Before @BeforeEach
public void setUp() { void setUp() {
matchTimer = mock(Timer.class); matchTimer = mock(Timer.class);
errorTimer = mock(Timer.class); errorTimer = mock(Timer.class);
@ -44,31 +41,31 @@ public class ExperimentTest {
} }
@Test @Test
public void compareFutureResult() { void compareFutureResult() {
experiment.compareFutureResult(12, CompletableFuture.completedFuture(12)); experiment.compareFutureResult(12, CompletableFuture.completedFuture(12));
verify(matchTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS)); verify(matchTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS));
} }
@Test @Test
public void compareFutureResultError() { void compareFutureResultError() {
experiment.compareFutureResult(12, CompletableFuture.failedFuture(new RuntimeException("OH NO"))); experiment.compareFutureResult(12, CompletableFuture.failedFuture(new RuntimeException("OH NO")));
verify(errorTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS)); verify(errorTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS));
} }
@Test @Test
public void compareSupplierResultMatch() { void compareSupplierResultMatch() {
experiment.compareSupplierResult(12, () -> 12); experiment.compareSupplierResult(12, () -> 12);
verify(matchTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS)); verify(matchTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS));
} }
@Test @Test
public void compareSupplierResultError() { void compareSupplierResultError() {
experiment.compareSupplierResult(12, () -> { throw new RuntimeException("OH NO"); }); experiment.compareSupplierResult(12, () -> { throw new RuntimeException("OH NO"); });
verify(errorTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS)); verify(errorTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS));
} }
@Test @Test
public void compareSupplierResultAsyncMatch() throws InterruptedException { void compareSupplierResultAsyncMatch() throws InterruptedException {
final ExecutorService experimentExecutor = Executors.newSingleThreadExecutor(); final ExecutorService experimentExecutor = Executors.newSingleThreadExecutor();
experiment.compareSupplierResultAsync(12, () -> 12, experimentExecutor); experiment.compareSupplierResultAsync(12, () -> 12, experimentExecutor);
@ -79,7 +76,7 @@ public class ExperimentTest {
} }
@Test @Test
public void compareSupplierResultAsyncError() throws InterruptedException { void compareSupplierResultAsyncError() throws InterruptedException {
final ExecutorService experimentExecutor = Executors.newSingleThreadExecutor(); final ExecutorService experimentExecutor = Executors.newSingleThreadExecutor();
experiment.compareSupplierResultAsync(12, () -> { throw new RuntimeException("OH NO"); }, experimentExecutor); experiment.compareSupplierResultAsync(12, () -> { throw new RuntimeException("OH NO"); }, experimentExecutor);
@ -90,7 +87,7 @@ public class ExperimentTest {
} }
@Test @Test
public void compareSupplierResultAsyncRejection() { void compareSupplierResultAsyncRejection() {
final ExecutorService executorService = mock(ExecutorService.class); final ExecutorService executorService = mock(ExecutorService.class);
doThrow(new RejectedExecutionException()).when(executorService).execute(any(Runnable.class)); doThrow(new RejectedExecutionException()).when(executorService).execute(any(Runnable.class));
@ -98,8 +95,8 @@ public class ExperimentTest {
verify(errorTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS)); verify(errorTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS));
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForTestRecordResult") @MethodSource("argumentsForTestRecordResult")
public void testRecordResult(final Object expected, final Object actual, final Experiment experiment, final Timer expectedTimer) { public void testRecordResult(final Object expected, final Object actual, final Experiment experiment, final Timer expectedTimer) {
reset(expectedTimer); reset(expectedTimer);
@ -110,7 +107,7 @@ public class ExperimentTest {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Object argumentsForTestRecordResult() { private static Object[] argumentsForTestRecordResult() {
// Hack: parameters are set before the @Before method gets called // Hack: parameters are set before the @Before method gets called
final Timer matchTimer = mock(Timer.class); final Timer matchTimer = mock(Timer.class);
final Timer errorTimer = mock(Timer.class); final Timer errorTimer = mock(Timer.class);

View File

@ -20,20 +20,18 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import junitparams.JUnitParamsRunner; import org.junit.jupiter.api.Test;
import junitparams.Parameters; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.Test; import org.junit.jupiter.params.provider.CsvSource;
import org.junit.runner.RunWith;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicRemoteDeprecationConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicRemoteDeprecationConfiguration;
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager; import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
import org.whispersystems.textsecuregcm.util.ua.ClientPlatform; import org.whispersystems.textsecuregcm.util.ua.ClientPlatform;
@RunWith(JUnitParamsRunner.class) class RemoteDeprecationFilterTest {
public class RemoteDeprecationFilterTest {
@Test @Test
public void testEmptyMap() throws IOException, ServletException { void testEmptyMap() throws IOException, ServletException {
// We're happy as long as there's no exception // We're happy as long as there's no exception
final DynamicConfigurationManager dynamicConfigurationManager = mock(DynamicConfigurationManager.class); final DynamicConfigurationManager dynamicConfigurationManager = mock(DynamicConfigurationManager.class);
final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class); final DynamicConfiguration dynamicConfiguration = mock(DynamicConfiguration.class);
@ -56,8 +54,9 @@ public class RemoteDeprecationFilterTest {
verify(servletResponse, never()).sendError(anyInt()); verify(servletResponse, never()).sendError(anyInt());
} }
@Test @ParameterizedTest
@Parameters({"Unrecognized UA | false", @CsvSource(delimiter = '|', value =
{"Unrecognized UA | false",
"Signal-Android/4.68.3 | false", "Signal-Android/4.68.3 | false",
"Signal-iOS/3.9.0 | false", "Signal-iOS/3.9.0 | false",
"Signal-Desktop/1.2.3 | false", "Signal-Desktop/1.2.3 | false",
@ -67,7 +66,7 @@ public class RemoteDeprecationFilterTest {
"Signal-Desktop/8.0.0-beta.2 | true", "Signal-Desktop/8.0.0-beta.2 | true",
"Signal-Desktop/8.0.0-beta.1 | false", "Signal-Desktop/8.0.0-beta.1 | false",
"Signal-iOS/8.0.0-beta.2 | false"}) "Signal-iOS/8.0.0-beta.2 | false"})
public void testFilter(final String userAgent, final boolean expectDeprecation) throws IOException, ServletException { void testFilter(final String userAgent, final boolean expectDeprecation) throws IOException, ServletException {
final EnumMap<ClientPlatform, Semver> minimumVersionsByPlatform = new EnumMap<>(ClientPlatform.class); final EnumMap<ClientPlatform, Semver> minimumVersionsByPlatform = new EnumMap<>(ClientPlatform.class);
minimumVersionsByPlatform.put(ClientPlatform.ANDROID, new Semver("1.0.0")); minimumVersionsByPlatform.put(ClientPlatform.ANDROID, new Semver("1.0.0"));
minimumVersionsByPlatform.put(ClientPlatform.IOS, new Semver("1.0.0")); minimumVersionsByPlatform.put(ClientPlatform.IOS, new Semver("1.0.0"));

View File

@ -5,23 +5,21 @@
package org.whispersystems.textsecuregcm.filters; package org.whispersystems.textsecuregcm.filters;
import org.glassfish.jersey.message.internal.HeaderUtils; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Test;
import org.whispersystems.textsecuregcm.util.TimestampHeaderUtil;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.core.MultivaluedHashMap;
import javax.ws.rs.core.MultivaluedMap;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
public class TimestampResponseFilterTest { import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.core.MultivaluedMap;
import org.glassfish.jersey.message.internal.HeaderUtils;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.util.TimestampHeaderUtil;
class TimestampResponseFilterTest {
@Test @Test
public void testFilter() { void testFilter() {
final ContainerRequestContext requestContext = mock(ContainerRequestContext.class); final ContainerRequestContext requestContext = mock(ContainerRequestContext.class);
final ContainerResponseContext responseContext = mock(ContainerResponseContext.class); final ContainerResponseContext responseContext = mock(ContainerResponseContext.class);

View File

@ -1,21 +1,17 @@
/* /*
* Copyright 2013-2020 Signal Messenger, LLC * Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
package org.whispersystems.textsecuregcm.metrics; package org.whispersystems.textsecuregcm.metrics;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.*; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
@RunWith(JUnitParamsRunner.class) class OperatingSystemMemoryGaugeTest {
public class OperatingSystemMemoryGaugeTest {
private static final String MEMINFO = private static final String MEMINFO =
""" """
@ -74,13 +70,13 @@ public class OperatingSystemMemoryGaugeTest {
DirectMap1G: 2097152 kB DirectMap1G: 2097152 kB
"""; """;
@Test @ParameterizedTest
@Parameters(method = "argumentsForTestGetValue") @MethodSource("argumentsForTestGetValue")
public void testGetValue(final String metricName, final long expectedValue) { public void testGetValue(final String metricName, final long expectedValue) {
assertEquals(expectedValue, new OperatingSystemMemoryGauge(metricName).getValue(MEMINFO.lines())); assertEquals(expectedValue, new OperatingSystemMemoryGauge(metricName).getValue(MEMINFO.lines()));
} }
private static Object argumentsForTestGetValue() { private static Object[] argumentsForTestGetValue() {
return new Object[] { return new Object[] {
new Object[] { "MemTotal", 16052208L }, new Object[] { "MemTotal", 16052208L },
new Object[] { "Active(anon)", 5580980L }, new Object[] { "Active(anon)", 5580980L },

View File

@ -5,23 +5,20 @@
package org.whispersystems.textsecuregcm.metrics; package org.whispersystems.textsecuregcm.metrics;
import io.micrometer.core.instrument.Tag; import static org.junit.jupiter.api.Assertions.assertEquals;
import junitparams.JUnitParamsRunner; import static org.junit.jupiter.api.Assertions.assertTrue;
import junitparams.Parameters;
import org.junit.Test;
import org.junit.runner.RunWith;
import io.micrometer.core.instrument.Tag;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.Assert.assertEquals; class UserAgentTagUtilTest {
import static org.junit.Assert.assertTrue;
@RunWith(JUnitParamsRunner.class) @ParameterizedTest
public class UserAgentTagUtilTest { @MethodSource("argumentsForTestGetUserAgentTags")
@Test
@Parameters(method = "argumentsForTestGetUserAgentTags")
public void testGetUserAgentTags(final String userAgent, final List<Tag> expectedTags) { public void testGetUserAgentTags(final String userAgent, final List<Tag> expectedTags) {
assertEquals(new HashSet<>(expectedTags), assertEquals(new HashSet<>(expectedTags),
new HashSet<>(UserAgentTagUtil.getUserAgentTags(userAgent))); new HashSet<>(UserAgentTagUtil.getUserAgentTags(userAgent)));
@ -32,7 +29,7 @@ public class UserAgentTagUtilTest {
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Object argumentsForTestGetUserAgentTags() { private static Object[] argumentsForTestGetUserAgentTags() {
return new Object[] { return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", UserAgentTagUtil.UNRECOGNIZED_TAGS }, new Object[] { "This is obviously not a reasonable User-Agent string.", UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { null, UserAgentTagUtil.UNRECOGNIZED_TAGS }, new Object[] { null, UserAgentTagUtil.UNRECOGNIZED_TAGS },
@ -52,7 +49,7 @@ public class UserAgentTagUtilTest {
} }
@Test @Test
public void testGetUserAgentTagsFlooded() { void testGetUserAgentTagsFlooded() {
for (int i = 0; i < UserAgentTagUtil.MAX_VERSIONS; i++) { for (int i = 0; i < UserAgentTagUtil.MAX_VERSIONS; i++) {
UserAgentTagUtil.getUserAgentTags(String.format("Signal-Android 4.0.%d (Android 8.1)", i)); UserAgentTagUtil.getUserAgentTags(String.format("Signal-Android 4.0.%d (Android 8.1)", i));
} }
@ -67,13 +64,13 @@ public class UserAgentTagUtilTest {
assertTrue(tags.contains(Tag.of(UserAgentTagUtil.VERSION_TAG, "4.0.0"))); assertTrue(tags.contains(Tag.of(UserAgentTagUtil.VERSION_TAG, "4.0.0")));
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForTestGetPlatformTag") @MethodSource("argumentsForTestGetPlatformTag")
public void testGetPlatformTag(final String userAgent, final Tag expectedTag) { public void testGetPlatformTag(final String userAgent, final Tag expectedTag) {
assertEquals(expectedTag, UserAgentTagUtil.getPlatformTag(userAgent)); assertEquals(expectedTag, UserAgentTagUtil.getPlatformTag(userAgent));
} }
private Object argumentsForTestGetPlatformTag() { private static Object[] argumentsForTestGetPlatformTag() {
return new Object[] { return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized") }, new Object[] { "This is obviously not a reasonable User-Agent string.", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized") },
new Object[] { null, Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized") }, new Object[] { null, Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized") },

View File

@ -5,6 +5,13 @@
package org.whispersystems.textsecuregcm.redis; package org.whispersystems.textsecuregcm.redis;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException; import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.Retry;
@ -12,25 +19,18 @@ import io.lettuce.core.RedisCommandTimeoutException;
import io.lettuce.core.RedisException; import io.lettuce.core.RedisException;
import io.lettuce.core.cluster.pubsub.StatefulRedisClusterPubSubConnection; import io.lettuce.core.cluster.pubsub.StatefulRedisClusterPubSubConnection;
import io.lettuce.core.cluster.pubsub.api.sync.RedisClusterPubSubCommands; import io.lettuce.core.cluster.pubsub.api.sync.RedisClusterPubSubCommands;
import org.junit.Before; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.BeforeEach;
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration; import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
import org.whispersystems.textsecuregcm.configuration.RetryConfiguration; import org.whispersystems.textsecuregcm.configuration.RetryConfiguration;
import static org.junit.Assert.assertEquals; class FaultTolerantPubSubConnectionTest {
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class FaultTolerantPubSubConnectionTest {
private RedisClusterPubSubCommands<String, String> pubSubCommands; private RedisClusterPubSubCommands<String, String> pubSubCommands;
private FaultTolerantPubSubConnection<String, String> faultTolerantPubSubConnection; private FaultTolerantPubSubConnection<String, String> faultTolerantPubSubConnection;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Before @BeforeEach
public void setUp() { public void setUp() {
final StatefulRedisClusterPubSubConnection<String, String> pubSubConnection = mock(StatefulRedisClusterPubSubConnection.class); final StatefulRedisClusterPubSubConnection<String, String> pubSubConnection = mock(StatefulRedisClusterPubSubConnection.class);
@ -54,7 +54,7 @@ public class FaultTolerantPubSubConnectionTest {
} }
@Test @Test
public void testBreaker() { void testBreaker() {
when(pubSubCommands.get(anyString())) when(pubSubCommands.get(anyString()))
.thenReturn("value") .thenReturn("value")
.thenThrow(new RuntimeException("Badness has ensued.")); .thenThrow(new RuntimeException("Badness has ensued."));
@ -71,7 +71,7 @@ public class FaultTolerantPubSubConnectionTest {
} }
@Test @Test
public void testRetry() { void testRetry() {
when(pubSubCommands.get(anyString())) when(pubSubCommands.get(anyString()))
.thenThrow(new RedisCommandTimeoutException()) .thenThrow(new RedisCommandTimeoutException())
.thenThrow(new RedisCommandTimeoutException()) .thenThrow(new RedisCommandTimeoutException())

View File

@ -5,6 +5,13 @@
package org.whispersystems.textsecuregcm.redis; package org.whispersystems.textsecuregcm.redis;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException; import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import io.lettuce.core.RedisCommandTimeoutException; import io.lettuce.core.RedisCommandTimeoutException;
import io.lettuce.core.RedisException; import io.lettuce.core.RedisException;
@ -14,26 +21,20 @@ import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
import io.lettuce.core.cluster.pubsub.StatefulRedisClusterPubSubConnection; import io.lettuce.core.cluster.pubsub.StatefulRedisClusterPubSubConnection;
import io.lettuce.core.event.EventBus; import io.lettuce.core.event.EventBus;
import io.lettuce.core.resource.ClientResources; import io.lettuce.core.resource.ClientResources;
import org.junit.Before; import java.time.Duration;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration; import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
import org.whispersystems.textsecuregcm.configuration.RetryConfiguration; import org.whispersystems.textsecuregcm.configuration.RetryConfiguration;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import java.time.Duration; class FaultTolerantRedisClusterTest {
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class FaultTolerantRedisClusterTest {
private RedisAdvancedClusterCommands<String, String> clusterCommands; private RedisAdvancedClusterCommands<String, String> clusterCommands;
private FaultTolerantRedisCluster faultTolerantCluster; private FaultTolerantRedisCluster faultTolerantCluster;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Before @BeforeEach
public void setUp() { public void setUp() {
final RedisClusterClient clusterClient = mock(RedisClusterClient.class); final RedisClusterClient clusterClient = mock(RedisClusterClient.class);
final StatefulRedisClusterConnection<String, String> clusterConnection = mock(StatefulRedisClusterConnection.class); final StatefulRedisClusterConnection<String, String> clusterConnection = mock(StatefulRedisClusterConnection.class);
@ -63,7 +64,7 @@ public class FaultTolerantRedisClusterTest {
} }
@Test @Test
public void testBreaker() { void testBreaker() {
when(clusterCommands.get(anyString())) when(clusterCommands.get(anyString()))
.thenReturn("value") .thenReturn("value")
.thenThrow(new RuntimeException("Badness has ensued.")); .thenThrow(new RuntimeException("Badness has ensued."));
@ -80,7 +81,7 @@ public class FaultTolerantRedisClusterTest {
} }
@Test @Test
public void testRetry() { void testRetry() {
when(clusterCommands.get(anyString())) when(clusterCommands.get(anyString()))
.thenThrow(new RedisCommandTimeoutException()) .thenThrow(new RedisCommandTimeoutException())
.thenThrow(new RedisCommandTimeoutException()) .thenThrow(new RedisCommandTimeoutException())

View File

@ -5,36 +5,32 @@
package org.whispersystems.textsecuregcm.securebackup; package org.whispersystems.textsecuregcm.securebackup;
import com.github.tomakehurst.wiremock.junit.WireMockRule; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import org.apache.commons.lang3.RandomStringUtils; import static com.github.tomakehurst.wiremock.client.WireMock.delete;
import org.junit.After; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import org.junit.AfterClass; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import org.junit.Before; import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.BeforeClass; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Rule; import static org.mockito.Mockito.mock;
import org.junit.Test; import static org.mockito.Mockito.when;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
import org.whispersystems.textsecuregcm.configuration.SecureBackupServiceConfiguration;
import java.security.Security; import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
import org.whispersystems.textsecuregcm.configuration.SecureBackupServiceConfiguration;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; class SecureBackupClientTest {
import static com.github.tomakehurst.wiremock.client.WireMock.delete;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SecureBackupClientTest {
private UUID accountUuid; private UUID accountUuid;
private ExternalServiceCredentialGenerator credentialGenerator; private ExternalServiceCredentialGenerator credentialGenerator;
@ -42,17 +38,19 @@ public class SecureBackupClientTest {
private SecureBackupClient secureStorageClient; private SecureBackupClient secureStorageClient;
@Rule @RegisterExtension
public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort().dynamicHttpsPort()); private final WireMockExtension wireMock = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort().dynamicHttpsPort())
.build();
@Before @BeforeEach
public void setUp() throws CertificateException { void setUp() throws CertificateException {
accountUuid = UUID.randomUUID(); accountUuid = UUID.randomUUID();
credentialGenerator = mock(ExternalServiceCredentialGenerator.class); credentialGenerator = mock(ExternalServiceCredentialGenerator.class);
httpExecutor = Executors.newSingleThreadExecutor(); httpExecutor = Executors.newSingleThreadExecutor();
final SecureBackupServiceConfiguration config = new SecureBackupServiceConfiguration(); final SecureBackupServiceConfiguration config = new SecureBackupServiceConfiguration();
config.setUri("http://localhost:" + wireMockRule.port()); config.setUri("http://localhost:" + wireMock.getPort());
// This is a randomly-generated, throwaway certificate that's not actually connected to anything // This is a randomly-generated, throwaway certificate that's not actually connected to anything
config.setBackupCaCertificate(""" config.setBackupCaCertificate("""
@ -76,20 +74,20 @@ public class SecureBackupClientTest {
secureStorageClient = new SecureBackupClient(credentialGenerator, httpExecutor, config); secureStorageClient = new SecureBackupClient(credentialGenerator, httpExecutor, config);
} }
@After @AfterEach
public void tearDown() throws InterruptedException { void tearDown() throws InterruptedException {
httpExecutor.shutdown(); httpExecutor.shutdown();
httpExecutor.awaitTermination(1, TimeUnit.SECONDS); httpExecutor.awaitTermination(1, TimeUnit.SECONDS);
} }
@Test @Test
public void deleteStoredData() { void deleteStoredData() {
final String username = RandomStringUtils.randomAlphabetic(16); final String username = RandomStringUtils.randomAlphabetic(16);
final String password = RandomStringUtils.randomAlphanumeric(32); final String password = RandomStringUtils.randomAlphanumeric(32);
when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password)); when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password));
wireMockRule.stubFor(delete(urlEqualTo(SecureBackupClient.DELETE_PATH)) wireMock.stubFor(delete(urlEqualTo(SecureBackupClient.DELETE_PATH))
.withBasicAuth(username, password) .withBasicAuth(username, password)
.willReturn(aResponse().withStatus(202))); .willReturn(aResponse().withStatus(202)));
@ -98,13 +96,13 @@ public class SecureBackupClientTest {
} }
@Test @Test
public void deleteStoredDataFailure() { void deleteStoredDataFailure() {
final String username = RandomStringUtils.randomAlphabetic(16); final String username = RandomStringUtils.randomAlphabetic(16);
final String password = RandomStringUtils.randomAlphanumeric(32); final String password = RandomStringUtils.randomAlphanumeric(32);
when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password)); when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password));
wireMockRule.stubFor(delete(urlEqualTo(SecureBackupClient.DELETE_PATH)) wireMock.stubFor(delete(urlEqualTo(SecureBackupClient.DELETE_PATH))
.withBasicAuth(username, password) .withBasicAuth(username, password)
.willReturn(aResponse().withStatus(400))); .willReturn(aResponse().withStatus(400)));

View File

@ -5,36 +5,32 @@
package org.whispersystems.textsecuregcm.securestorage; package org.whispersystems.textsecuregcm.securestorage;
import com.github.tomakehurst.wiremock.junit.WireMockRule; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import org.apache.commons.lang3.RandomStringUtils; import static com.github.tomakehurst.wiremock.client.WireMock.delete;
import org.junit.After; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import org.junit.AfterClass; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import org.junit.Before; import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.BeforeClass; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.Rule; import static org.mockito.Mockito.mock;
import org.junit.Test; import static org.mockito.Mockito.when;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
import org.whispersystems.textsecuregcm.configuration.SecureStorageServiceConfiguration;
import java.security.Security; import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
import org.whispersystems.textsecuregcm.configuration.SecureStorageServiceConfiguration;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; class SecureStorageClientTest {
import static com.github.tomakehurst.wiremock.client.WireMock.delete;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class SecureStorageClientTest {
private UUID accountUuid; private UUID accountUuid;
private ExternalServiceCredentialGenerator credentialGenerator; private ExternalServiceCredentialGenerator credentialGenerator;
@ -42,17 +38,19 @@ public class SecureStorageClientTest {
private SecureStorageClient secureStorageClient; private SecureStorageClient secureStorageClient;
@Rule @RegisterExtension
public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort().dynamicHttpsPort()); private final WireMockExtension wireMock = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort().dynamicHttpsPort())
.build();
@Before @BeforeEach
public void setUp() throws CertificateException { void setUp() throws CertificateException {
accountUuid = UUID.randomUUID(); accountUuid = UUID.randomUUID();
credentialGenerator = mock(ExternalServiceCredentialGenerator.class); credentialGenerator = mock(ExternalServiceCredentialGenerator.class);
httpExecutor = Executors.newSingleThreadExecutor(); httpExecutor = Executors.newSingleThreadExecutor();
final SecureStorageServiceConfiguration config = new SecureStorageServiceConfiguration(); final SecureStorageServiceConfiguration config = new SecureStorageServiceConfiguration();
config.setUri("http://localhost:" + wireMockRule.port()); config.setUri("http://localhost:" + wireMock.getPort());
// This is a randomly-generated, throwaway certificate that's not actually connected to anything // This is a randomly-generated, throwaway certificate that's not actually connected to anything
config.setStorageCaCertificate(""" config.setStorageCaCertificate("""
@ -76,20 +74,20 @@ public class SecureStorageClientTest {
secureStorageClient = new SecureStorageClient(credentialGenerator, httpExecutor, config); secureStorageClient = new SecureStorageClient(credentialGenerator, httpExecutor, config);
} }
@After @AfterEach
public void tearDown() throws InterruptedException { void tearDown() throws InterruptedException {
httpExecutor.shutdown(); httpExecutor.shutdown();
httpExecutor.awaitTermination(1, TimeUnit.SECONDS); httpExecutor.awaitTermination(1, TimeUnit.SECONDS);
} }
@Test @Test
public void deleteStoredData() { void deleteStoredData() {
final String username = RandomStringUtils.randomAlphabetic(16); final String username = RandomStringUtils.randomAlphabetic(16);
final String password = RandomStringUtils.randomAlphanumeric(32); final String password = RandomStringUtils.randomAlphanumeric(32);
when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password)); when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password));
wireMockRule.stubFor(delete(urlEqualTo(SecureStorageClient.DELETE_PATH)) wireMock.stubFor(delete(urlEqualTo(SecureStorageClient.DELETE_PATH))
.withBasicAuth(username, password) .withBasicAuth(username, password)
.willReturn(aResponse().withStatus(202))); .willReturn(aResponse().withStatus(202)));
@ -98,13 +96,13 @@ public class SecureStorageClientTest {
} }
@Test @Test
public void deleteStoredDataFailure() { void deleteStoredDataFailure() {
final String username = RandomStringUtils.randomAlphabetic(16); final String username = RandomStringUtils.randomAlphabetic(16);
final String password = RandomStringUtils.randomAlphanumeric(32); final String password = RandomStringUtils.randomAlphanumeric(32);
when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password)); when(credentialGenerator.generateFor(accountUuid.toString())).thenReturn(new ExternalServiceCredentials(username, password));
wireMockRule.stubFor(delete(urlEqualTo(SecureStorageClient.DELETE_PATH)) wireMock.stubFor(delete(urlEqualTo(SecureStorageClient.DELETE_PATH))
.withBasicAuth(username, password) .withBasicAuth(username, password)
.willReturn(aResponse().withStatus(400))); .willReturn(aResponse().withStatus(400)));

View File

@ -5,12 +5,11 @@ import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import com.github.tomakehurst.wiremock.junit.WireMockRule; import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.time.Duration; import java.time.Duration;
import java.util.Collections; import java.util.Collections;
@ -18,19 +17,17 @@ import java.util.List;
import java.util.Locale.LanguageRange; import java.util.Locale.LanguageRange;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import junitparams.JUnitParamsRunner; import org.junit.jupiter.api.BeforeEach;
import junitparams.Parameters; import org.junit.jupiter.api.Test;
import org.junit.Before; import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.Rule; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.Test; import org.junit.jupiter.params.provider.MethodSource;
import org.junit.runner.RunWith;
import org.whispersystems.textsecuregcm.configuration.TwilioConfiguration; import org.whispersystems.textsecuregcm.configuration.TwilioConfiguration;
import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient; import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
import org.whispersystems.textsecuregcm.util.ExecutorUtils; import org.whispersystems.textsecuregcm.util.ExecutorUtils;
@SuppressWarnings("OptionalGetWithoutIsPresent") @SuppressWarnings("OptionalGetWithoutIsPresent")
@RunWith(JUnitParamsRunner.class) class TwilioVerifySenderTest {
public class TwilioVerifySenderTest {
private static final String ACCOUNT_ID = "test_account_id"; private static final String ACCOUNT_ID = "test_account_id";
private static final String ACCOUNT_TOKEN = "test_account_token"; private static final String ACCOUNT_TOKEN = "test_account_token";
@ -43,13 +40,15 @@ public class TwilioVerifySenderTest {
private static final String VERIFICATION_SID = "verification"; private static final String VERIFICATION_SID = "verification";
@Rule @RegisterExtension
public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort().dynamicHttpsPort()); private final WireMockExtension wireMock = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort().dynamicHttpsPort())
.build();
private TwilioVerifySender sender; private TwilioVerifySender sender;
@Before @BeforeEach
public void setup() { void setup() {
final TwilioConfiguration twilioConfiguration = createTwilioConfiguration(); final TwilioConfiguration twilioConfiguration = createTwilioConfiguration();
final FaultTolerantHttpClient httpClient = FaultTolerantHttpClient.newBuilder() final FaultTolerantHttpClient httpClient = FaultTolerantHttpClient.newBuilder()
@ -62,7 +61,7 @@ public class TwilioVerifySenderTest {
.withName("twilio") .withName("twilio")
.build(); .build();
sender = new TwilioVerifySender("http://localhost:" + wireMockRule.port(), httpClient, twilioConfiguration); sender = new TwilioVerifySender("http://localhost:" + wireMock.getPort(), httpClient, twilioConfiguration);
} }
private TwilioConfiguration createTwilioConfiguration() { private TwilioConfiguration createTwilioConfiguration() {
@ -82,16 +81,16 @@ public class TwilioVerifySenderTest {
} }
private void setupSuccessStubForVerify() { private void setupSuccessStubForVerify() {
wireMockRule.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications")) wireMock.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withHeader("Content-Type", "application/json") .withHeader("Content-Type", "application/json")
.withBody("{\"sid\": \"" + VERIFICATION_SID + "\", \"status\": \"pending\"}"))); .withBody("{\"sid\": \"" + VERIFICATION_SID + "\", \"status\": \"pending\"}")));
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForDeliverSmsVerificationWithVerify") @MethodSource("argumentsForDeliverSmsVerificationWithVerify")
public void deliverSmsVerificationWithVerify(@Nullable final String client, @Nullable final String languageRange, void deliverSmsVerificationWithVerify(@Nullable final String client, @Nullable final String languageRange,
final boolean expectAppHash, @Nullable final String expectedLocale) throws Exception { final boolean expectAppHash, @Nullable final String expectedLocale) throws Exception {
setupSuccessStubForVerify(); setupSuccessStubForVerify();
@ -106,7 +105,7 @@ public class TwilioVerifySenderTest {
assertEquals(VERIFICATION_SID, verificationSid.get()); assertEquals(VERIFICATION_SID, verificationSid.get());
verify(1, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications")) wireMock.verify(1, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo( .withRequestBody(equalTo(
(expectedLocale == null ? "" : "Locale=" + expectedLocale + "&") (expectedLocale == null ? "" : "Locale=" + expectedLocale + "&")
@ -115,7 +114,7 @@ public class TwilioVerifySenderTest {
))); )));
} }
private static Object argumentsForDeliverSmsVerificationWithVerify() { private static Object[] argumentsForDeliverSmsVerificationWithVerify() {
return new Object[][]{ return new Object[][]{
// client, languageRange, expectAppHash, expectedLocale // client, languageRange, expectAppHash, expectedLocale
{"ios", "fr-CA, en", false, "fr"}, {"ios", "fr-CA, en", false, "fr"},
@ -124,9 +123,9 @@ public class TwilioVerifySenderTest {
}; };
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForDeliverVoxVerificationWithVerify") @MethodSource("argumentsForDeliverVoxVerificationWithVerify")
public void deliverVoxVerificationWithVerify(@Nullable final String languageRange, void deliverVoxVerificationWithVerify(@Nullable final String languageRange,
@Nullable final String expectedLocale) throws Exception { @Nullable final String expectedLocale) throws Exception {
setupSuccessStubForVerify(); setupSuccessStubForVerify();
@ -140,7 +139,7 @@ public class TwilioVerifySenderTest {
assertEquals(VERIFICATION_SID, verificationSid.get()); assertEquals(VERIFICATION_SID, verificationSid.get());
verify(1, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications")) wireMock.verify(1, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo( .withRequestBody(equalTo(
(expectedLocale == null ? "" : "Locale=" + expectedLocale + "&") (expectedLocale == null ? "" : "Locale=" + expectedLocale + "&")
@ -148,7 +147,7 @@ public class TwilioVerifySenderTest {
+ "&CustomCode=123456"))); + "&CustomCode=123456")));
} }
private static Object argumentsForDeliverVoxVerificationWithVerify() { private static Object[] argumentsForDeliverVoxVerificationWithVerify() {
return new Object[][]{ return new Object[][]{
// languageRange, expectedLocale // languageRange, expectedLocale
{"fr-CA, en", "fr"}, {"fr-CA, en", "fr"},
@ -159,8 +158,8 @@ public class TwilioVerifySenderTest {
} }
@Test @Test
public void testSmsFiveHundred() throws Exception { void testSmsFiveHundred() throws Exception {
wireMockRule.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications")) wireMock.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(500) .withStatus(500)
@ -172,15 +171,15 @@ public class TwilioVerifySenderTest {
assertThat(verificationSid).isEmpty(); assertThat(verificationSid).isEmpty();
verify(3, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications")) wireMock.verify(3, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("Channel=sms&To=%2B14153333333&CustomFriendlyName=" + SERVICE_FRIENDLY_NAME .withRequestBody(equalTo("Channel=sms&To=%2B14153333333&CustomFriendlyName=" + SERVICE_FRIENDLY_NAME
+ "&CustomCode=123456"))); + "&CustomCode=123456")));
} }
@Test @Test
public void testVoxFiveHundred() throws Exception { void testVoxFiveHundred() throws Exception {
wireMockRule.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications")) wireMock.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(500) .withStatus(500)
@ -192,16 +191,16 @@ public class TwilioVerifySenderTest {
assertThat(verificationSid).isEmpty(); assertThat(verificationSid).isEmpty();
verify(3, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications")) wireMock.verify(3, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("Channel=call&To=%2B14153333333&CustomFriendlyName=" + SERVICE_FRIENDLY_NAME .withRequestBody(equalTo("Channel=call&To=%2B14153333333&CustomFriendlyName=" + SERVICE_FRIENDLY_NAME
+ "&CustomCode=123456"))); + "&CustomCode=123456")));
} }
@Test @Test
public void reportVerificationSucceeded() throws Exception { void reportVerificationSucceeded() throws Exception {
wireMockRule.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications/" + VERIFICATION_SID)) wireMock.stubFor(post(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications/" + VERIFICATION_SID))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(200) .withStatus(200)
@ -212,7 +211,7 @@ public class TwilioVerifySenderTest {
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications/" + VERIFICATION_SID)) wireMock.verify(1, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications/" + VERIFICATION_SID))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("Status=approved"))); .withRequestBody(equalTo("Status=approved")));
} }

View File

@ -5,30 +5,26 @@
package org.whispersystems.textsecuregcm.storage; package org.whispersystems.textsecuregcm.storage;
import junitparams.JUnitParamsRunner; import static org.junit.jupiter.api.Assertions.assertEquals;
import junitparams.Parameters;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
import java.time.Duration;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@RunWith(JUnitParamsRunner.class) import java.time.Duration;
public class DeviceTest { import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
@Test class DeviceTest {
@Parameters(method = "argumentsForTestIsEnabled")
public void testIsEnabled(final boolean master, final boolean fetchesMessages, final String apnId, final String gcmId, final SignedPreKey signedPreKey, final Duration timeSinceLastSeen, final boolean expectEnabled) { @ParameterizedTest
@MethodSource("argumentsForTestIsEnabled")
void testIsEnabled(final boolean master, final boolean fetchesMessages, final String apnId, final String gcmId, final SignedPreKey signedPreKey, final Duration timeSinceLastSeen, final boolean expectEnabled) {
final long lastSeen = System.currentTimeMillis() - timeSinceLastSeen.toMillis(); final long lastSeen = System.currentTimeMillis() - timeSinceLastSeen.toMillis();
final Device device = new Device(master ? 1 : 2, "test", "auth-token", "salt", gcmId, apnId, null, fetchesMessages, 1, signedPreKey, lastSeen, lastSeen, "user-agent", 0, null); final Device device = new Device(master ? 1 : 2, "test", "auth-token", "salt", gcmId, apnId, null, fetchesMessages, 1, signedPreKey, lastSeen, lastSeen, "user-agent", 0, null);
assertEquals(expectEnabled, device.isEnabled()); assertEquals(expectEnabled, device.isEnabled());
} }
private static Object argumentsForTestIsEnabled() { private static Object[] argumentsForTestIsEnabled() {
return new Object[] { return new Object[] {
// master fetchesMessages apnId gcmId signedPreKey lastSeen expectEnabled // master fetchesMessages apnId gcmId signedPreKey lastSeen expectEnabled
new Object[] { true, false, null, null, null, Duration.ofDays(60), false }, new Object[] { true, false, null, null, null, Duration.ofDays(60), false },
@ -66,9 +62,9 @@ public class DeviceTest {
}; };
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForTestIsGroupsV2Supported") @MethodSource("argumentsForTestIsGroupsV2Supported")
public void testIsGroupsV2Supported(final boolean master, final String apnId, final boolean gv2Capability, final boolean gv2_2Capability, final boolean gv2_3Capability, final boolean expectGv2Supported) { void testIsGroupsV2Supported(final boolean master, final String apnId, final boolean gv2Capability, final boolean gv2_2Capability, final boolean gv2_3Capability, final boolean expectGv2Supported) {
final Device.DeviceCapabilities capabilities = new Device.DeviceCapabilities(gv2Capability, gv2_2Capability, gv2_3Capability, false, false, false, final Device.DeviceCapabilities capabilities = new Device.DeviceCapabilities(gv2Capability, gv2_2Capability, gv2_3Capability, false, false, false,
false, false, false); false, false, false);
final Device device = new Device(master ? 1 : 2, "test", "auth-token", "salt", final Device device = new Device(master ? 1 : 2, "test", "auth-token", "salt",
@ -77,7 +73,7 @@ public class DeviceTest {
assertEquals(expectGv2Supported, device.isGroupsV2Supported()); assertEquals(expectGv2Supported, device.isGroupsV2Supported());
} }
private static Object argumentsForTestIsGroupsV2Supported() { private static Object[] argumentsForTestIsGroupsV2Supported() {
return new Object[] { return new Object[] {
// master apnId gv2 gv2-2 gv2-3 capable // master apnId gv2 gv2-2 gv2-3 capable

View File

@ -4,8 +4,8 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
import software.amazon.awssdk.core.SdkBytes; import software.amazon.awssdk.core.SdkBytes;
@ -13,19 +13,19 @@ import software.amazon.awssdk.services.appconfig.AppConfigClient;
import software.amazon.awssdk.services.appconfig.model.GetConfigurationRequest; import software.amazon.awssdk.services.appconfig.model.GetConfigurationRequest;
import software.amazon.awssdk.services.appconfig.model.GetConfigurationResponse; import software.amazon.awssdk.services.appconfig.model.GetConfigurationResponse;
public class DynamicConfigurationManagerTest { class DynamicConfigurationManagerTest {
private DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager; private DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
private AppConfigClient appConfig; private AppConfigClient appConfig;
@Before @BeforeEach
public void setup() { void setup() {
this.appConfig = mock(AppConfigClient.class); this.appConfig = mock(AppConfigClient.class);
this.dynamicConfigurationManager = new DynamicConfigurationManager<>(appConfig, "foo", "bar", "baz", "poof", DynamicConfiguration.class); this.dynamicConfigurationManager = new DynamicConfigurationManager<>(appConfig, "foo", "bar", "baz", "poof", DynamicConfiguration.class);
} }
@Test @Test
public void testGetConfig() { void testGetConfig() {
ArgumentCaptor<GetConfigurationRequest> captor = ArgumentCaptor.forClass(GetConfigurationRequest.class); ArgumentCaptor<GetConfigurationRequest> captor = ArgumentCaptor.forClass(GetConfigurationRequest.class);
when(appConfig.getConfiguration(captor.capture())).thenReturn( when(appConfig.getConfiguration(captor.capture())).thenReturn(
GetConfigurationResponse.builder().content(SdkBytes.fromByteArray("test: true".getBytes())).configurationVersion("1").build()); GetConfigurationResponse.builder().content(SdkBytes.fromByteArray("test: true".getBytes())).configurationVersion("1").build());

View File

@ -1,108 +1,125 @@
/* /*
* Copyright 2021 Signal Messenger, LLC * Copyright 2021-2022 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
package org.whispersystems.textsecuregcm.storage; package org.whispersystems.textsecuregcm.storage;
import static org.junit.Assert.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.ClassRule; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.entities.PreKey; import org.whispersystems.textsecuregcm.entities.PreKey;
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue; import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
public class KeysTest { class KeysTest {
private Keys keys; private static final String TABLE_NAME = "Signal_Keys_Test";
@ClassRule private Keys keys;
public static KeysDynamoDbRule dynamoDbRule = new KeysDynamoDbRule();
private static final UUID ACCOUNT_UUID = UUID.randomUUID(); @RegisterExtension
private static final long DEVICE_ID = 1L; static DynamoDbExtension dynamoDbExtension = DynamoDbExtension.builder()
.tableName(TABLE_NAME)
.hashKey(Keys.KEY_ACCOUNT_UUID)
.rangeKey(Keys.KEY_DEVICE_ID_KEY_ID)
.attributeDefinition(AttributeDefinition.builder()
.attributeName(Keys.KEY_ACCOUNT_UUID)
.attributeType(ScalarAttributeType.B)
.build())
.attributeDefinition(
AttributeDefinition.builder()
.attributeName(Keys.KEY_DEVICE_ID_KEY_ID)
.attributeType(ScalarAttributeType.B)
.build())
.build();
@Before private static final UUID ACCOUNT_UUID = UUID.randomUUID();
public void setup() { private static final long DEVICE_ID = 1L;
keys = new Keys(dynamoDbRule.getDynamoDbClient(), KeysDynamoDbRule.TABLE_NAME);
}
@Test @BeforeEach
public void testStore() { void setup() {
assertEquals("Initial pre-key count for an account should be zero", keys = new Keys(dynamoDbExtension.getDynamoDbClient(), TABLE_NAME);
0, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); }
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key"))); @Test
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); void testStore() {
assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID),
"Initial pre-key count for an account should be zero");
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key"))); keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key")));
assertEquals("Repeatedly storing same key should have no effect", assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
1, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(2, "different-public-key"))); keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key")));
assertEquals("Inserting a new key should overwrite all prior keys for the given account/device", assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID),
1, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); "Repeatedly storing same key should have no effect");
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(3, "third-public-key"), new PreKey(4, "fourth-public-key"))); keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(2, "different-public-key")));
assertEquals("Inserting multiple new keys should overwrite all prior keys for the given account/device", assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID),
2, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); "Inserting a new key should overwrite all prior keys for the given account/device");
}
@Test keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(3, "third-public-key"), new PreKey(4, "fourth-public-key")));
public void testTakeAccountAndDeviceId() { assertEquals(2, keys.getCount(ACCOUNT_UUID, DEVICE_ID),
assertEquals(Optional.empty(), keys.take(ACCOUNT_UUID, DEVICE_ID)); "Inserting multiple new keys should overwrite all prior keys for the given account/device");
}
final PreKey preKey = new PreKey(1, "public-key"); @Test
void testTakeAccountAndDeviceId() {
assertEquals(Optional.empty(), keys.take(ACCOUNT_UUID, DEVICE_ID));
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(preKey, new PreKey(2, "different-pre-key"))); final PreKey preKey = new PreKey(1, "public-key");
assertEquals(Optional.of(preKey), keys.take(ACCOUNT_UUID, DEVICE_ID));
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
}
@Test keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(preKey, new PreKey(2, "different-pre-key")));
public void testGetCount() { assertEquals(Optional.of(preKey), keys.take(ACCOUNT_UUID, DEVICE_ID));
assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
}
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key"))); @Test
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); void testGetCount() {
} assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
@Test keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key")));
public void testDeleteByAccount() { assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key"), new PreKey(2, "different-public-key"))); }
keys.store(ACCOUNT_UUID, DEVICE_ID + 1, List.of(new PreKey(3, "public-key-for-different-device")));
assertEquals(2, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); @Test
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1)); void testDeleteByAccount() {
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key"), new PreKey(2, "different-public-key")));
keys.store(ACCOUNT_UUID, DEVICE_ID + 1, List.of(new PreKey(3, "public-key-for-different-device")));
keys.delete(ACCOUNT_UUID); assertEquals(2, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1));
assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); keys.delete(ACCOUNT_UUID);
assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1));
}
@Test assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
public void testDeleteByAccountAndDevice() { assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1));
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key"), new PreKey(2, "different-public-key"))); }
keys.store(ACCOUNT_UUID, DEVICE_ID + 1, List.of(new PreKey(3, "public-key-for-different-device")));
assertEquals(2, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); @Test
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1)); void testDeleteByAccountAndDevice() {
keys.store(ACCOUNT_UUID, DEVICE_ID, List.of(new PreKey(1, "public-key"), new PreKey(2, "different-public-key")));
keys.store(ACCOUNT_UUID, DEVICE_ID + 1, List.of(new PreKey(3, "public-key-for-different-device")));
keys.delete(ACCOUNT_UUID, DEVICE_ID); assertEquals(2, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1));
assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID)); keys.delete(ACCOUNT_UUID, DEVICE_ID);
assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1));
}
@Test assertEquals(0, keys.getCount(ACCOUNT_UUID, DEVICE_ID));
public void testSortKeyPrefix() { assertEquals(1, keys.getCount(ACCOUNT_UUID, DEVICE_ID + 1));
AttributeValue got = Keys.getSortKeyPrefix(123); }
assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 123}, got.b().asByteArray());
} @Test
void testSortKeyPrefix() {
AttributeValue got = Keys.getSortKeyPrefix(123);
assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 123}, got.b().asByteArray());
}
} }

View File

@ -9,22 +9,22 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import org.junit.Before; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.BeforeEach;
public class RemoteConfigsManagerTest { class RemoteConfigsManagerTest {
private RemoteConfigs remoteConfigs; private RemoteConfigs remoteConfigs;
private RemoteConfigsManager remoteConfigsManager; private RemoteConfigsManager remoteConfigsManager;
@Before @BeforeEach
public void setup() { void setup() {
this.remoteConfigs = mock(RemoteConfigs.class); this.remoteConfigs = mock(RemoteConfigs.class);
this.remoteConfigsManager = new RemoteConfigsManager(remoteConfigs); this.remoteConfigsManager = new RemoteConfigsManager(remoteConfigs);
} }
@Test @Test
public void testGetAll() { void testGetAll() {
remoteConfigsManager.getAll(); remoteConfigsManager.getAll();
remoteConfigsManager.getAll(); remoteConfigsManager.getAll();
@ -33,7 +33,7 @@ public class RemoteConfigsManagerTest {
} }
@Test @Test
public void testSet() { void testSet() {
final RemoteConfig remoteConfig = mock(RemoteConfig.class); final RemoteConfig remoteConfig = mock(RemoteConfig.class);
remoteConfigsManager.set(remoteConfig); remoteConfigsManager.set(remoteConfig);
@ -43,7 +43,7 @@ public class RemoteConfigsManagerTest {
} }
@Test @Test
public void testDelete() { void testDelete() {
final String name = "name"; final String name = "name";
remoteConfigsManager.delete(name); remoteConfigsManager.delete(name);

View File

@ -5,15 +5,15 @@
package org.whispersystems.textsecuregcm.tests.auth; package org.whispersystems.textsecuregcm.tests.auth;
import org.junit.Test;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
public class AuthenticationCredentialsTest { import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials;
class AuthenticationCredentialsTest {
@Test @Test
public void testCreating() { void testCreating() {
AuthenticationCredentials credentials = new AuthenticationCredentials("mypassword"); AuthenticationCredentials credentials = new AuthenticationCredentials("mypassword");
assertThat(credentials.getSalt()).isNotEmpty(); assertThat(credentials.getSalt()).isNotEmpty();
assertThat(credentials.getHashedAuthenticationToken()).isNotEmpty(); assertThat(credentials.getHashedAuthenticationToken()).isNotEmpty();
@ -21,7 +21,7 @@ public class AuthenticationCredentialsTest {
} }
@Test @Test
public void testMatching() { void testMatching() {
AuthenticationCredentials credentials = new AuthenticationCredentials("mypassword"); AuthenticationCredentials credentials = new AuthenticationCredentials("mypassword");
AuthenticationCredentials provided = new AuthenticationCredentials(credentials.getHashedAuthenticationToken(), credentials.getSalt()); AuthenticationCredentials provided = new AuthenticationCredentials(credentials.getHashedAuthenticationToken(), credentials.getSalt());
@ -29,12 +29,11 @@ public class AuthenticationCredentialsTest {
} }
@Test @Test
public void testMisMatching() { void testMisMatching() {
AuthenticationCredentials credentials = new AuthenticationCredentials("mypassword"); AuthenticationCredentials credentials = new AuthenticationCredentials("mypassword");
AuthenticationCredentials provided = new AuthenticationCredentials(credentials.getHashedAuthenticationToken(), credentials.getSalt()); AuthenticationCredentials provided = new AuthenticationCredentials(credentials.getHashedAuthenticationToken(), credentials.getSalt());
assertThat(provided.verify("wrong")).isFalse(); assertThat(provided.verify("wrong")).isFalse();
} }
} }

View File

@ -7,14 +7,14 @@ package org.whispersystems.textsecuregcm.tests.auth;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator;
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
public class ExternalServiceCredentialsGeneratorTest { class ExternalServiceCredentialsGeneratorTest {
@Test @Test
public void testGenerateDerivedUsername() { void testGenerateDerivedUsername() {
ExternalServiceCredentialGenerator generator = new ExternalServiceCredentialGenerator(new byte[32], new byte[32]); ExternalServiceCredentialGenerator generator = new ExternalServiceCredentialGenerator(new byte[32], new byte[32]);
ExternalServiceCredentials credentials = generator.generateFor("+14152222222"); ExternalServiceCredentials credentials = generator.generateFor("+14152222222");
@ -23,7 +23,7 @@ public class ExternalServiceCredentialsGeneratorTest {
} }
@Test @Test
public void testGenerateNoDerivedUsername() { void testGenerateNoDerivedUsername() {
ExternalServiceCredentialGenerator generator = new ExternalServiceCredentialGenerator(new byte[32], new byte[32], false); ExternalServiceCredentialGenerator generator = new ExternalServiceCredentialGenerator(new byte[32], new byte[32], false);
ExternalServiceCredentials credentials = generator.generateFor("+14152222222"); ExternalServiceCredentials credentials = generator.generateFor("+14152222222");

View File

@ -5,24 +5,23 @@
package org.whispersystems.textsecuregcm.tests.auth; package org.whispersystems.textsecuregcm.tests.auth;
import org.junit.Test; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.whispersystems.textsecuregcm.auth.Anonymous;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
import org.whispersystems.textsecuregcm.storage.Account;
import javax.ws.rs.WebApplicationException;
import java.util.Base64;
import java.util.Optional;
import static junit.framework.TestCase.assertEquals;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
public class OptionalAccessTest { import java.util.Base64;
import java.util.Optional;
import javax.ws.rs.WebApplicationException;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.auth.Anonymous;
import org.whispersystems.textsecuregcm.auth.OptionalAccess;
import org.whispersystems.textsecuregcm.storage.Account;
class OptionalAccessTest {
@Test @Test
public void testUnidentifiedMissingTarget() { void testUnidentifiedMissingTarget() {
try { try {
OptionalAccess.verify(Optional.empty(), Optional.empty(), Optional.empty()); OptionalAccess.verify(Optional.empty(), Optional.empty(), Optional.empty());
throw new AssertionError("should fail"); throw new AssertionError("should fail");
@ -32,7 +31,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testUnidentifiedMissingTargetDevice() { void testUnidentifiedMissingTargetDevice() {
Account account = mock(Account.class); Account account = mock(Account.class);
when(account.isEnabled()).thenReturn(true); when(account.isEnabled()).thenReturn(true);
when(account.getDevice(eq(10))).thenReturn(Optional.empty()); when(account.getDevice(eq(10))).thenReturn(Optional.empty());
@ -46,7 +45,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testUnidentifiedBadTargetDevice() { void testUnidentifiedBadTargetDevice() {
Account account = mock(Account.class); Account account = mock(Account.class);
when(account.isEnabled()).thenReturn(true); when(account.isEnabled()).thenReturn(true);
when(account.getDevice(eq(10))).thenReturn(Optional.empty()); when(account.getDevice(eq(10))).thenReturn(Optional.empty());
@ -61,7 +60,7 @@ public class OptionalAccessTest {
@Test @Test
public void testUnidentifiedBadCode() { void testUnidentifiedBadCode() {
Account account = mock(Account.class); Account account = mock(Account.class);
when(account.isEnabled()).thenReturn(true); when(account.isEnabled()).thenReturn(true);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes())); when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
@ -75,7 +74,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testIdentifiedMissingTarget() { void testIdentifiedMissingTarget() {
Account account = mock(Account.class); Account account = mock(Account.class);
when(account.isEnabled()).thenReturn(true); when(account.isEnabled()).thenReturn(true);
@ -88,7 +87,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testUnsolicitedBadTarget() { void testUnsolicitedBadTarget() {
Account account = mock(Account.class); Account account = mock(Account.class);
when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(false); when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(false);
when(account.isEnabled()).thenReturn(true); when(account.isEnabled()).thenReturn(true);
@ -102,7 +101,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testUnsolicitedGoodTarget() { void testUnsolicitedGoodTarget() {
Account account = mock(Account.class); Account account = mock(Account.class);
Anonymous random = mock(Anonymous.class); Anonymous random = mock(Anonymous.class);
when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(true); when(account.isUnrestrictedUnidentifiedAccess()).thenReturn(true);
@ -111,7 +110,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testUnidentifiedGoodTarget() { void testUnidentifiedGoodTarget() {
Account account = mock(Account.class); Account account = mock(Account.class);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes())); when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
when(account.isEnabled()).thenReturn(true); when(account.isEnabled()).thenReturn(true);
@ -119,7 +118,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testUnidentifiedInactive() { void testUnidentifiedInactive() {
Account account = mock(Account.class); Account account = mock(Account.class);
when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes())); when(account.getUnidentifiedAccessKey()).thenReturn(Optional.of("1234".getBytes()));
when(account.isEnabled()).thenReturn(false); when(account.isEnabled()).thenReturn(false);
@ -133,7 +132,7 @@ public class OptionalAccessTest {
} }
@Test @Test
public void testIdentifiedGoodTarget() { void testIdentifiedGoodTarget() {
Account source = mock(Account.class); Account source = mock(Account.class);
Account target = mock(Account.class); Account target = mock(Account.class);
when(target.isEnabled()).thenReturn(true); when(target.isEnabled()).thenReturn(true);

View File

@ -5,18 +5,19 @@
package org.whispersystems.textsecuregcm.tests.entities; package org.whispersystems.textsecuregcm.tests.entities;
import org.junit.Test;
import org.whispersystems.textsecuregcm.entities.PreKey;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.*; import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.asJson;
import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.jsonFixture;
public class PreKeyTest { import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.entities.PreKey;
class PreKeyTest {
@Test @Test
public void serializeToJSONV2() throws Exception { void serializeToJSONV2() throws Exception {
PreKey preKey = new PreKey(1234, "test"); PreKey preKey = new PreKey(1234, "test");
assertThat("PreKeyV2 Serialization works", assertThat("PreKeyV2 Serialization works",

View File

@ -1,18 +1,19 @@
/* /*
* Copyright 2013-2020 Signal Messenger, LLC * Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
package org.whispersystems.textsecuregcm.tests.http; package org.whispersystems.textsecuregcm.tests.http;
import com.github.tomakehurst.wiremock.junit.WireMockRule; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException; import static com.github.tomakehurst.wiremock.client.WireMock.get;
import org.junit.Rule; import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import org.junit.Test; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import org.whispersystems.textsecuregcm.configuration.RetryConfiguration; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.http.HttpClient; import java.net.http.HttpClient;
@ -20,23 +21,22 @@ import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
import org.whispersystems.textsecuregcm.configuration.RetryConfiguration;
import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; class FaultTolerantHttpClientTest {
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
public class FaultTolerantHttpClientTest { @RegisterExtension
private final WireMockExtension wireMock = WireMockExtension.newInstance()
@Rule .options(wireMockConfig().dynamicPort().dynamicHttpsPort())
public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort().dynamicHttpsPort()); .build();
@Test @Test
public void testSimpleGet() { void testSimpleGet() {
wireMockRule.stubFor(get(urlEqualTo("/ping")) wireMock.stubFor(get(urlEqualTo("/ping"))
.willReturn(aResponse() .willReturn(aResponse()
.withHeader("Content-Type", "text/plain") .withHeader("Content-Type", "text/plain")
.withBody("Pong!"))); .withBody("Pong!")));
@ -51,7 +51,7 @@ public class FaultTolerantHttpClientTest {
.build(); .build();
HttpRequest request = HttpRequest.newBuilder() HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:" + wireMockRule.port() + "/ping")) .uri(URI.create("http://localhost:" + wireMock.getPort() + "/ping"))
.GET() .GET()
.build(); .build();
@ -60,12 +60,12 @@ public class FaultTolerantHttpClientTest {
assertThat(response.statusCode()).isEqualTo(200); assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.body()).isEqualTo("Pong!"); assertThat(response.body()).isEqualTo("Pong!");
verify(1, getRequestedFor(urlEqualTo("/ping"))); wireMock.verify(1, getRequestedFor(urlEqualTo("/ping")));
} }
@Test @Test
public void testRetryGet() { void testRetryGet() {
wireMockRule.stubFor(get(urlEqualTo("/failure")) wireMock.stubFor(get(urlEqualTo("/failure"))
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(500) .withStatus(500)
.withHeader("Content-Type", "text/plain") .withHeader("Content-Type", "text/plain")
@ -80,7 +80,7 @@ public class FaultTolerantHttpClientTest {
.build(); .build();
HttpRequest request = HttpRequest.newBuilder() HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://localhost:" + wireMockRule.port() + "/failure")) .uri(URI.create("http://localhost:" + wireMock.getPort() + "/failure"))
.GET() .GET()
.build(); .build();
@ -89,11 +89,11 @@ public class FaultTolerantHttpClientTest {
assertThat(response.statusCode()).isEqualTo(500); assertThat(response.statusCode()).isEqualTo(500);
assertThat(response.body()).isEqualTo("Pong!"); assertThat(response.body()).isEqualTo("Pong!");
verify(3, getRequestedFor(urlEqualTo("/failure"))); wireMock.verify(3, getRequestedFor(urlEqualTo("/failure")));
} }
@Test @Test
public void testNetworkFailureCircuitBreaker() throws InterruptedException { void testNetworkFailureCircuitBreaker() throws InterruptedException {
CircuitBreakerConfiguration circuitBreakerConfiguration = new CircuitBreakerConfiguration(); CircuitBreakerConfiguration circuitBreakerConfiguration = new CircuitBreakerConfiguration();
circuitBreakerConfiguration.setRingBufferSizeInClosedState(2); circuitBreakerConfiguration.setRingBufferSizeInClosedState(2);
circuitBreakerConfiguration.setRingBufferSizeInHalfOpenState(1); circuitBreakerConfiguration.setRingBufferSizeInHalfOpenState(1);
@ -154,10 +154,6 @@ public class FaultTolerantHttpClientTest {
assertThat(e.getCause()).isInstanceOf(CallNotPermittedException.class); assertThat(e.getCause()).isInstanceOf(CallNotPermittedException.class);
// good // good
} }
} }
} }

View File

@ -1,27 +1,26 @@
/* /*
* Copyright 2013-2020 Signal Messenger, LLC * Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
package org.whispersystems.textsecuregcm.tests.limits; package org.whispersystems.textsecuregcm.tests.limits;
import com.fasterxml.jackson.databind.ObjectMapper; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.Test; import static org.junit.jupiter.api.Assertions.assertFalse;
import org.whispersystems.textsecuregcm.limits.LeakyBucket; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException; import java.io.IOException;
import java.time.Duration; import java.time.Duration;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.limits.LeakyBucket;
import static org.junit.Assert.assertEquals; class LeakyBucketTest {
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class LeakyBucketTest {
@Test @Test
public void testFull() { void testFull() {
LeakyBucket leakyBucket = new LeakyBucket(2, 1.0 / 2.0); LeakyBucket leakyBucket = new LeakyBucket(2, 1.0 / 2.0);
assertTrue(leakyBucket.add(1)); assertTrue(leakyBucket.add(1));
@ -36,7 +35,7 @@ public class LeakyBucketTest {
} }
@Test @Test
public void testLapseRate() throws IOException { void testLapseRate() throws IOException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
String serialized = "{\"bucketSize\":2,\"leakRatePerMillis\":8.333333333333334E-6,\"spaceRemaining\":0,\"lastUpdateTimeMillis\":" + (System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2)) + "}"; String serialized = "{\"bucketSize\":2,\"leakRatePerMillis\":8.333333333333334E-6,\"spaceRemaining\":0,\"lastUpdateTimeMillis\":" + (System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(2)) + "}";
@ -50,7 +49,7 @@ public class LeakyBucketTest {
} }
@Test @Test
public void testLapseShort() throws Exception { void testLapseShort() throws Exception {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
String serialized = "{\"bucketSize\":2,\"leakRatePerMillis\":8.333333333333334E-6,\"spaceRemaining\":0,\"lastUpdateTimeMillis\":" + (System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(1)) + "}"; String serialized = "{\"bucketSize\":2,\"leakRatePerMillis\":8.333333333333334E-6,\"spaceRemaining\":0,\"lastUpdateTimeMillis\":" + (System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(1)) + "}";
@ -59,7 +58,7 @@ public class LeakyBucketTest {
} }
@Test @Test
public void testGetTimeUntilSpaceAvailable() throws Exception { void testGetTimeUntilSpaceAvailable() throws Exception {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
{ {

View File

@ -5,6 +5,15 @@
package org.whispersystems.textsecuregcm.tests.push; package org.whispersystems.textsecuregcm.tests.push;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.eq;
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;
import com.eatthepath.pushy.apns.ApnsClient; import com.eatthepath.pushy.apns.ApnsClient;
import com.eatthepath.pushy.apns.ApnsPushNotification; import com.eatthepath.pushy.apns.ApnsPushNotification;
import com.eatthepath.pushy.apns.DeliveryPriority; import com.eatthepath.pushy.apns.DeliveryPriority;
@ -12,8 +21,13 @@ import com.eatthepath.pushy.apns.PushNotificationResponse;
import com.eatthepath.pushy.apns.util.SimpleApnsPushNotification; import com.eatthepath.pushy.apns.util.SimpleApnsPushNotification;
import com.eatthepath.pushy.apns.util.concurrent.PushNotificationFuture; import com.eatthepath.pushy.apns.util.concurrent.PushNotificationFuture;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import org.junit.Before; import java.time.Instant;
import org.junit.Test; import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import org.whispersystems.textsecuregcm.push.APNSender; import org.whispersystems.textsecuregcm.push.APNSender;
@ -27,16 +41,7 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.Device;
import org.whispersystems.textsecuregcm.tests.util.SynchronousExecutorService; import org.whispersystems.textsecuregcm.tests.util.SynchronousExecutorService;
import java.time.Instant; class APNSenderTest {
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
public class APNSenderTest {
private static final UUID DESTINATION_UUID = UUID.randomUUID(); private static final UUID DESTINATION_UUID = UUID.randomUUID();
private static final String DESTINATION_APN_ID = "foo"; private static final String DESTINATION_APN_ID = "foo";
@ -47,15 +52,15 @@ public class APNSenderTest {
private final Device destinationDevice = mock(Device.class); private final Device destinationDevice = mock(Device.class);
private final ApnFallbackManager fallbackManager = mock(ApnFallbackManager.class); private final ApnFallbackManager fallbackManager = mock(ApnFallbackManager.class);
@Before @BeforeEach
public void setup() { void setup() {
when(destinationAccount.getDevice(1)).thenReturn(Optional.of(destinationDevice)); when(destinationAccount.getDevice(1)).thenReturn(Optional.of(destinationDevice));
when(destinationDevice.getApnId()).thenReturn(DESTINATION_APN_ID); when(destinationDevice.getApnId()).thenReturn(DESTINATION_APN_ID);
when(accountsManager.getByAccountIdentifier(DESTINATION_UUID)).thenReturn(Optional.of(destinationAccount)); when(accountsManager.getByAccountIdentifier(DESTINATION_UUID)).thenReturn(Optional.of(destinationAccount));
} }
@Test @Test
public void testSendVoip() throws Exception { void testSendVoip() throws Exception {
ApnsClient apnsClient = mock(ApnsClient.class); ApnsClient apnsClient = mock(ApnsClient.class);
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class); PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
@ -89,7 +94,7 @@ public class APNSenderTest {
} }
@Test @Test
public void testSendApns() throws Exception { void testSendApns() throws Exception {
ApnsClient apnsClient = mock(ApnsClient.class); ApnsClient apnsClient = mock(ApnsClient.class);
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class); PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
@ -123,7 +128,7 @@ public class APNSenderTest {
} }
@Test @Test
public void testUnregisteredUser() throws Exception { void testUnregisteredUser() throws Exception {
ApnsClient apnsClient = mock(ApnsClient.class); ApnsClient apnsClient = mock(ApnsClient.class);
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class); PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
@ -227,7 +232,7 @@ public class APNSenderTest {
// } // }
@Test @Test
public void testRecentUnregisteredUser() throws Exception { void testRecentUnregisteredUser() throws Exception {
ApnsClient apnsClient = mock(ApnsClient.class); ApnsClient apnsClient = mock(ApnsClient.class);
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class); PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
@ -322,7 +327,7 @@ public class APNSenderTest {
// } // }
@Test @Test
public void testGenericFailure() throws Exception { void testGenericFailure() throws Exception {
ApnsClient apnsClient = mock(ApnsClient.class); ApnsClient apnsClient = mock(ApnsClient.class);
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class); PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
@ -356,7 +361,7 @@ public class APNSenderTest {
} }
@Test @Test
public void testFailure() throws Exception { void testFailure() throws Exception {
ApnsClient apnsClient = mock(ApnsClient.class); ApnsClient apnsClient = mock(ApnsClient.class);
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class); PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);

View File

@ -15,7 +15,7 @@ import static org.mockito.Mockito.when;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.whispersystems.gcm.server.Message; import org.whispersystems.gcm.server.Message;
import org.whispersystems.gcm.server.Result; import org.whispersystems.gcm.server.Result;
import org.whispersystems.gcm.server.Sender; import org.whispersystems.gcm.server.Sender;
@ -28,10 +28,10 @@ import org.whispersystems.textsecuregcm.tests.util.AccountsHelper;
import org.whispersystems.textsecuregcm.tests.util.SynchronousExecutorService; import org.whispersystems.textsecuregcm.tests.util.SynchronousExecutorService;
import org.whispersystems.textsecuregcm.util.Util; import org.whispersystems.textsecuregcm.util.Util;
public class GCMSenderTest { class GCMSenderTest {
@Test @Test
public void testSendMessage() { void testSendMessage() {
AccountsManager accountsManager = mock(AccountsManager.class); AccountsManager accountsManager = mock(AccountsManager.class);
Sender sender = mock(Sender.class ); Sender sender = mock(Sender.class );
Result successResult = mock(Result.class ); Result successResult = mock(Result.class );
@ -57,7 +57,7 @@ public class GCMSenderTest {
} }
@Test @Test
public void testSendUninstalled() { void testSendUninstalled() {
UUID destinationUuid = UUID.randomUUID(); UUID destinationUuid = UUID.randomUUID();
String gcmId = "foo"; String gcmId = "foo";
@ -96,7 +96,7 @@ public class GCMSenderTest {
} }
@Test @Test
public void testCanonicalId() { void testCanonicalId() {
UUID destinationUuid = UUID.randomUUID(); UUID destinationUuid = UUID.randomUUID();
String gcmId = "foo"; String gcmId = "foo";
String canonicalId = "bar"; String canonicalId = "bar";

View File

@ -5,25 +5,28 @@
package org.whispersystems.textsecuregcm.tests.redis; package org.whispersystems.textsecuregcm.tests.redis;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException; import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test; import static org.mockito.Mockito.mock;
import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration; import static org.mockito.Mockito.times;
import org.whispersystems.textsecuregcm.redis.ReplicatedJedisPool; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat; import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguration;
import static org.mockito.Mockito.*; import org.whispersystems.textsecuregcm.redis.ReplicatedJedisPool;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.exceptions.JedisException;
public class ReplicatedJedisPoolTest { class ReplicatedJedisPoolTest {
@Test @Test
public void testWriteCheckoutNoSlaves() { void testWriteCheckoutNoSlaves() {
JedisPool master = mock(JedisPool.class); JedisPool master = mock(JedisPool.class);
try { try {
@ -35,7 +38,7 @@ public class ReplicatedJedisPoolTest {
} }
@Test @Test
public void testWriteCheckoutWithSlaves() { void testWriteCheckoutWithSlaves() {
JedisPool master = mock(JedisPool.class); JedisPool master = mock(JedisPool.class);
JedisPool slave = mock(JedisPool.class); JedisPool slave = mock(JedisPool.class);
Jedis instance = mock(Jedis.class ); Jedis instance = mock(Jedis.class );
@ -50,7 +53,7 @@ public class ReplicatedJedisPoolTest {
} }
@Test @Test
public void testReadCheckouts() { void testReadCheckouts() {
JedisPool master = mock(JedisPool.class); JedisPool master = mock(JedisPool.class);
JedisPool slaveOne = mock(JedisPool.class); JedisPool slaveOne = mock(JedisPool.class);
JedisPool slaveTwo = mock(JedisPool.class); JedisPool slaveTwo = mock(JedisPool.class);
@ -72,7 +75,7 @@ public class ReplicatedJedisPoolTest {
} }
@Test @Test
public void testBrokenReadCheckout() { void testBrokenReadCheckout() {
JedisPool master = mock(JedisPool.class); JedisPool master = mock(JedisPool.class);
JedisPool slaveOne = mock(JedisPool.class); JedisPool slaveOne = mock(JedisPool.class);
JedisPool slaveTwo = mock(JedisPool.class); JedisPool slaveTwo = mock(JedisPool.class);
@ -91,7 +94,7 @@ public class ReplicatedJedisPoolTest {
} }
@Test @Test
public void testAllBrokenReadCheckout() { void testAllBrokenReadCheckout() {
JedisPool master = mock(JedisPool.class); JedisPool master = mock(JedisPool.class);
JedisPool slaveOne = mock(JedisPool.class); JedisPool slaveOne = mock(JedisPool.class);
JedisPool slaveTwo = mock(JedisPool.class); JedisPool slaveTwo = mock(JedisPool.class);
@ -112,7 +115,7 @@ public class ReplicatedJedisPoolTest {
} }
@Test @Test
public void testCircuitBreakerOpen() { void testCircuitBreakerOpen() {
CircuitBreakerConfiguration configuration = new CircuitBreakerConfiguration(); CircuitBreakerConfiguration configuration = new CircuitBreakerConfiguration();
configuration.setFailureRateThreshold(50); configuration.setFailureRateThreshold(50);
configuration.setRingBufferSizeInClosedState(2); configuration.setRingBufferSizeInClosedState(2);
@ -146,7 +149,7 @@ public class ReplicatedJedisPoolTest {
} }
@Test @Test
public void testCircuitBreakerHalfOpen() throws InterruptedException { void testCircuitBreakerHalfOpen() throws InterruptedException {
CircuitBreakerConfiguration configuration = new CircuitBreakerConfiguration(); CircuitBreakerConfiguration configuration = new CircuitBreakerConfiguration();
configuration.setFailureRateThreshold(50); configuration.setFailureRateThreshold(50);
configuration.setRingBufferSizeInClosedState(2); configuration.setRingBufferSizeInClosedState(2);
@ -199,8 +202,6 @@ public class ReplicatedJedisPoolTest {
} catch (CallNotPermittedException e) { } catch (CallNotPermittedException e) {
// good // good
} }
} }
} }

View File

@ -5,20 +5,18 @@
package org.whispersystems.textsecuregcm.tests.s3; package org.whispersystems.textsecuregcm.tests.s3;
import org.junit.Test; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.whispersystems.textsecuregcm.s3.PolicySigner;
import java.io.UnsupportedEncodingException;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.s3.PolicySigner;
import static org.junit.Assert.assertEquals; class PolicySignerTest {
public class PolicySignerTest {
@Test @Test
public void testSignature() throws UnsupportedEncodingException { void testSignature() {
Instant time = Instant.parse("2015-12-29T00:00:00Z"); Instant time = Instant.parse("2015-12-29T00:00:00Z");
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(time, ZoneOffset.UTC); ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(time, ZoneOffset.UTC);
String encodedPolicy = "eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJzaWd2NGV4YW1wbGVidWNrZXQifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwNCiAgICB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL3NpZ3Y0ZXhhbXBsZWJ1Y2tldC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRDb250ZW50LVR5cGUiLCAiaW1hZ2UvIl0sDQogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwNCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkeC1hbXotbWV0YS10YWciLCAiIl0sDQoNCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlPU0ZPRE5ON0VYQU1QTEUvMjAxNTEyMjkvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LA0KICAgIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwNCiAgICB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfQ0KICBdDQp9"; String encodedPolicy = "eyAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTMwVDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJzaWd2NGV4YW1wbGVidWNrZXQifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAidXNlci91c2VyMS8iXSwNCiAgICB7ImFjbCI6ICJwdWJsaWMtcmVhZCJ9LA0KICAgIHsic3VjY2Vzc19hY3Rpb25fcmVkaXJlY3QiOiAiaHR0cDovL3NpZ3Y0ZXhhbXBsZWJ1Y2tldC5zMy5hbWF6b25hd3MuY29tL3N1Y2Nlc3NmdWxfdXBsb2FkLmh0bWwifSwNCiAgICBbInN0YXJ0cy13aXRoIiwgIiRDb250ZW50LVR5cGUiLCAiaW1hZ2UvIl0sDQogICAgeyJ4LWFtei1tZXRhLXV1aWQiOiAiMTQzNjUxMjM2NTEyNzQifSwNCiAgICB7IngtYW16LXNlcnZlci1zaWRlLWVuY3J5cHRpb24iOiAiQUVTMjU2In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIkeC1hbXotbWV0YS10YWciLCAiIl0sDQoNCiAgICB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlPU0ZPRE5ON0VYQU1QTEUvMjAxNTEyMjkvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LA0KICAgIHsieC1hbXotYWxnb3JpdGhtIjogIkFXUzQtSE1BQy1TSEEyNTYifSwNCiAgICB7IngtYW16LWRhdGUiOiAiMjAxNTEyMjlUMDAwMDAwWiIgfQ0KICBdDQp9";

View File

@ -6,11 +6,11 @@ import static org.mockito.Mockito.times;
import java.util.Optional; import java.util.Optional;
import org.junit.Test; import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.sms.SmsSender; import org.whispersystems.textsecuregcm.sms.SmsSender;
import org.whispersystems.textsecuregcm.sms.TwilioSmsSender; import org.whispersystems.textsecuregcm.sms.TwilioSmsSender;
public class SmsSenderTest { class SmsSenderTest {
private static final String NON_MEXICO_NUMBER = "+12345678901"; private static final String NON_MEXICO_NUMBER = "+12345678901";
private static final String MEXICO_NON_MOBILE_NUMBER = "+52234567890"; private static final String MEXICO_NON_MOBILE_NUMBER = "+52234567890";
@ -20,21 +20,21 @@ public class SmsSenderTest {
private final SmsSender smsSender = new SmsSender(twilioSmsSender); private final SmsSender smsSender = new SmsSender(twilioSmsSender);
@Test @Test
public void testDeliverSmsVerificationNonMexico() { void testDeliverSmsVerificationNonMexico() {
smsSender.deliverSmsVerification(NON_MEXICO_NUMBER, Optional.empty(), ""); smsSender.deliverSmsVerification(NON_MEXICO_NUMBER, Optional.empty(), "");
verify(twilioSmsSender, times(1)) verify(twilioSmsSender, times(1))
.deliverSmsVerification(NON_MEXICO_NUMBER, Optional.empty(), ""); .deliverSmsVerification(NON_MEXICO_NUMBER, Optional.empty(), "");
} }
@Test @Test
public void testDeliverSmsVerificationMexicoNonMobile() { void testDeliverSmsVerificationMexicoNonMobile() {
smsSender.deliverSmsVerification(MEXICO_NON_MOBILE_NUMBER, Optional.empty(), ""); smsSender.deliverSmsVerification(MEXICO_NON_MOBILE_NUMBER, Optional.empty(), "");
verify(twilioSmsSender, times(1)) verify(twilioSmsSender, times(1))
.deliverSmsVerification("+521" + MEXICO_NON_MOBILE_NUMBER.substring("+52".length()), Optional.empty(), ""); .deliverSmsVerification("+521" + MEXICO_NON_MOBILE_NUMBER.substring("+52".length()), Optional.empty(), "");
} }
@Test @Test
public void testDeliverSmsVerificationMexicoMobile() { void testDeliverSmsVerificationMexicoMobile() {
smsSender.deliverSmsVerification(MEXICO_MOBILE_NUMBER, Optional.empty(), ""); smsSender.deliverSmsVerification(MEXICO_MOBILE_NUMBER, Optional.empty(), "");
verify(twilioSmsSender, times(1)) verify(twilioSmsSender, times(1))
.deliverSmsVerification(MEXICO_MOBILE_NUMBER, Optional.empty(), ""); .deliverSmsVerification(MEXICO_MOBILE_NUMBER, Optional.empty(), "");

View File

@ -11,21 +11,20 @@ import static com.github.tomakehurst.wiremock.client.WireMock.matching;
import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.verify; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import com.github.tomakehurst.wiremock.junit.WireMockRule; import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import java.util.List; import java.util.List;
import java.util.Locale.LanguageRange; import java.util.Locale.LanguageRange;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Rule; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.configuration.TwilioConfiguration; import org.whispersystems.textsecuregcm.configuration.TwilioConfiguration;
import org.whispersystems.textsecuregcm.configuration.TwilioVerificationTextConfiguration; import org.whispersystems.textsecuregcm.configuration.TwilioVerificationTextConfiguration;
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration; import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
@ -33,7 +32,7 @@ import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicTwilioConfi
import org.whispersystems.textsecuregcm.sms.TwilioSmsSender; import org.whispersystems.textsecuregcm.sms.TwilioSmsSender;
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager; import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
public class TwilioSmsSenderTest { class TwilioSmsSenderTest {
private static final String ACCOUNT_ID = "test_account_id"; private static final String ACCOUNT_ID = "test_account_id";
private static final String ACCOUNT_TOKEN = "test_account_token"; private static final String ACCOUNT_TOKEN = "test_account_token";
@ -42,14 +41,16 @@ public class TwilioSmsSenderTest {
private static final String VERIFY_SERVICE_SID = "verify_service_sid"; private static final String VERIFY_SERVICE_SID = "verify_service_sid";
private static final String LOCAL_DOMAIN = "test.com"; private static final String LOCAL_DOMAIN = "test.com";
@Rule @RegisterExtension
public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort().dynamicHttpsPort()); private final WireMockExtension wireMock = WireMockExtension.newInstance()
.options(wireMockConfig().dynamicPort().dynamicHttpsPort())
.build();
private DynamicConfigurationManager dynamicConfigurationManager; private DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager;
private TwilioSmsSender sender; private TwilioSmsSender sender;
@Before @BeforeEach
public void setup() { void setup() {
dynamicConfigurationManager = mock(DynamicConfigurationManager.class); dynamicConfigurationManager = mock(DynamicConfigurationManager.class);
DynamicConfiguration dynamicConfiguration = new DynamicConfiguration(); DynamicConfiguration dynamicConfiguration = new DynamicConfiguration();
@ -59,7 +60,7 @@ public class TwilioSmsSenderTest {
when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration); when(dynamicConfigurationManager.getConfiguration()).thenReturn(dynamicConfiguration);
TwilioConfiguration configuration = createTwilioConfiguration(); TwilioConfiguration configuration = createTwilioConfiguration();
sender = new TwilioSmsSender("http://localhost:" + wireMockRule.port(), "http://localhost:11111", configuration, dynamicConfigurationManager); sender = new TwilioSmsSender("http://localhost:" + wireMock.getPort(), "http://localhost:11111", configuration, dynamicConfigurationManager);
} }
@Nonnull @Nonnull
@ -95,7 +96,7 @@ public class TwilioSmsSenderTest {
} }
private void setupSuccessStubForSms() { private void setupSuccessStubForSms() {
wireMockRule.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withHeader("Content-Type", "application/json") .withHeader("Content-Type", "application/json")
@ -103,68 +104,68 @@ public class TwilioSmsSenderTest {
} }
@Test @Test
public void testSendSms() { void testSendSms() {
setupSuccessStubForSms(); setupSuccessStubForSms();
boolean success = sender.deliverSmsVerification("+14153333333", Optional.of("android-ng"), "123-456").join(); boolean success = sender.deliverSmsVerification("+14153333333", Optional.of("android-ng"), "123-456").join();
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters"))); .withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters")));
} }
@Test @Test
public void testSendSmsAndroid202001() { void testSendSmsAndroid202001() {
setupSuccessStubForSms(); setupSuccessStubForSms();
boolean success = sender.deliverSmsVerification("+14153333333", Optional.of("android-2020-01"), "123-456").join(); boolean success = sender.deliverSmsVerification("+14153333333", Optional.of("android-2020-01"), "123-456").join();
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=Verify+on+Android202001%3A+123-456%0A%0Asomelink%3A%2F%2Fverify%2F123-456%0A%0Acharacters"))); .withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=Verify+on+Android202001%3A+123-456%0A%0Asomelink%3A%2F%2Fverify%2F123-456%0A%0Acharacters")));
} }
@Test @Test
public void testSendSmsAndroid202103() { void testSendSmsAndroid202103() {
setupSuccessStubForSms(); setupSuccessStubForSms();
boolean success = sender.deliverSmsVerification("+14153333333", Optional.of("android-2021-03"), "123456").join(); boolean success = sender.deliverSmsVerification("+14153333333", Optional.of("android-2021-03"), "123456").join();
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=Verify+on+Android202103%3A+123456%0A%0Acharacters"))); .withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=Verify+on+Android202103%3A+123456%0A%0Acharacters")));
} }
@Test @Test
public void testSendSmsNanpaMessagingService() { void testSendSmsNanpaMessagingService() {
setupSuccessStubForSms(); setupSuccessStubForSms();
TwilioConfiguration configuration = createTwilioConfiguration(); TwilioConfiguration configuration = createTwilioConfiguration();
configuration.setNanpaMessagingServiceSid(NANPA_MESSAGING_SERVICE_SID); configuration.setNanpaMessagingServiceSid(NANPA_MESSAGING_SERVICE_SID);
TwilioSmsSender sender = new TwilioSmsSender("http://localhost:" + wireMockRule.port(), TwilioSmsSender sender = new TwilioSmsSender("http://localhost:" + wireMock.getPort(),
"http://localhost:11111", configuration, dynamicConfigurationManager); "http://localhost:11111", configuration, dynamicConfigurationManager);
assertThat(sender.deliverSmsVerification("+14153333333", Optional.of("ios"), "654-321").join()).isTrue(); assertThat(sender.deliverSmsVerification("+14153333333", Optional.of("ios"), "654-321").join()).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=Verify+on+iOS%3A+654-321%0A%0Asomelink%3A%2F%2Fverify%2F654-321"))); .withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=Verify+on+iOS%3A+654-321%0A%0Asomelink%3A%2F%2Fverify%2F654-321")));
wireMockRule.resetRequests(); wireMock.resetRequests();
assertThat(sender.deliverSmsVerification("+447911123456", Optional.of("ios"), "654-321").join()).isTrue(); assertThat(sender.deliverSmsVerification("+447911123456", Optional.of("ios"), "654-321").join()).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=test_messaging_services_id&To=%2B447911123456&Body=Verify+on+iOS%3A+654-321%0A%0Asomelink%3A%2F%2Fverify%2F654-321"))); .withRequestBody(equalTo("MessagingServiceSid=test_messaging_services_id&To=%2B447911123456&Body=Verify+on+iOS%3A+654-321%0A%0Asomelink%3A%2F%2Fverify%2F654-321")));
} }
@Test @Test
public void testSendVox() { void testSendVox() {
wireMockRule.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json")) wireMock.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withHeader("Content-Type", "application/json") .withHeader("Content-Type", "application/json")
@ -174,14 +175,14 @@ public class TwilioSmsSenderTest {
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(matching("To=%2B14153333333&From=%2B1415(1111111|2222222)&Url=https%3A%2F%2Ftest.com%2Fv1%2Fvoice%2Fdescription%2F123-456%3Fl%3Den-US"))); .withRequestBody(matching("To=%2B14153333333&From=%2B1415(1111111|2222222)&Url=https%3A%2F%2Ftest.com%2Fv1%2Fvoice%2Fdescription%2F123-456%3Fl%3Den-US")));
} }
@Test @Test
public void testSendVoxMultipleLocales() { void testSendVoxMultipleLocales() {
wireMockRule.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json")) wireMock.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withHeader("Content-Type", "application/json") .withHeader("Content-Type", "application/json")
@ -191,14 +192,14 @@ public class TwilioSmsSenderTest {
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(matching("To=%2B14153333333&From=%2B1415(1111111|2222222)&Url=https%3A%2F%2Ftest.com%2Fv1%2Fvoice%2Fdescription%2F123-456%3Fl%3Den-US%26l%3Dar-US%26l%3Dfa-US%26l%3Dzh-US%26l%3Dru-RU%26l%3Dzh-US"))); .withRequestBody(matching("To=%2B14153333333&From=%2B1415(1111111|2222222)&Url=https%3A%2F%2Ftest.com%2Fv1%2Fvoice%2Fdescription%2F123-456%3Fl%3Den-US%26l%3Dar-US%26l%3Dfa-US%26l%3Dzh-US%26l%3Dru-RU%26l%3Dzh-US")));
} }
@Test @Test
public void testSendSmsFiveHundred() { void testSendSmsFiveHundred() {
wireMockRule.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(500) .withStatus(500)
@ -209,14 +210,14 @@ public class TwilioSmsSenderTest {
assertThat(success).isFalse(); assertThat(success).isFalse();
verify(3, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(3, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters"))); .withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters")));
} }
@Test @Test
public void testSendVoxFiveHundred() { void testSendVoxFiveHundred() {
wireMockRule.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json")) wireMock.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(500) .withStatus(500)
@ -227,14 +228,14 @@ public class TwilioSmsSenderTest {
assertThat(success).isFalse(); assertThat(success).isFalse();
verify(3, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json")) wireMock.verify(3, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Calls.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(matching("To=%2B14153333333&From=%2B1415(1111111|2222222)&Url=https%3A%2F%2Ftest.com%2Fv1%2Fvoice%2Fdescription%2F123-456%3Fl%3Den-US"))); .withRequestBody(matching("To=%2B14153333333&From=%2B1415(1111111|2222222)&Url=https%3A%2F%2Ftest.com%2Fv1%2Fvoice%2Fdescription%2F123-456%3Fl%3Den-US")));
} }
@Test @Test
public void testSendSmsNetworkFailure() { void testSendSmsNetworkFailure() {
TwilioConfiguration configuration = createTwilioConfiguration(); TwilioConfiguration configuration = createTwilioConfiguration();
TwilioSmsSender sender = new TwilioSmsSender("http://localhost:" + 39873, "http://localhost:" + 39873, configuration, dynamicConfigurationManager); TwilioSmsSender sender = new TwilioSmsSender("http://localhost:" + 39873, "http://localhost:" + 39873, configuration, dynamicConfigurationManager);
@ -244,8 +245,8 @@ public class TwilioSmsSenderTest {
} }
@Test @Test
public void testRetrySmsOnUnreachableErrorCodeIsTriedOnlyOnceWithoutSenderId() { void testRetrySmsOnUnreachableErrorCodeIsTriedOnlyOnceWithoutSenderId() {
wireMockRule.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.stubFor(post(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN) .withBasicAuth(ACCOUNT_ID, ACCOUNT_TOKEN)
.willReturn(aResponse() .willReturn(aResponse()
.withStatus(400) .withStatus(400)
@ -256,33 +257,33 @@ public class TwilioSmsSenderTest {
assertThat(success).isFalse(); assertThat(success).isFalse();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters"))); .withRequestBody(equalTo("MessagingServiceSid=nanpa_test_messaging_service_id&To=%2B14153333333&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters")));
} }
@Test @Test
public void testSendSmsChina() { void testSendSmsChina() {
setupSuccessStubForSms(); setupSuccessStubForSms();
boolean success = sender.deliverSmsVerification("+861065529988", Optional.of("android-ng"), "123-456").join(); boolean success = sender.deliverSmsVerification("+861065529988", Optional.of("android-ng"), "123-456").join();
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=test_messaging_services_id&To=%2B861065529988&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters%E2%80%88"))); .withRequestBody(equalTo("MessagingServiceSid=test_messaging_services_id&To=%2B861065529988&Body=%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters%E2%80%88")));
} }
@Test @Test
public void testSendSmsRegionalVerificationText() { void testSendSmsRegionalVerificationText() {
setupSuccessStubForSms(); setupSuccessStubForSms();
boolean success = sender.deliverSmsVerification("+33655512673", Optional.of("android-ng"), "123-456").join(); boolean success = sender.deliverSmsVerification("+33655512673", Optional.of("android-ng"), "123-456").join();
assertThat(success).isTrue(); assertThat(success).isTrue();
verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json")) wireMock.verify(1, postRequestedFor(urlEqualTo("/2010-04-01/Accounts/" + ACCOUNT_ID + "/Messages.json"))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded")) .withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("MessagingServiceSid=test_messaging_services_id&To=%2B33655512673&Body=%5B33%5D+%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters"))); .withRequestBody(equalTo("MessagingServiceSid=test_messaging_services_id&To=%2B33655512673&Body=%5B33%5D+%3C%23%3E+Verify+on+AndroidNg%3A+123-456%0A%0Acharacters")));
} }

View File

@ -4,21 +4,6 @@
*/ */
package org.whispersystems.textsecuregcm.tests.storage; package org.whispersystems.textsecuregcm.tests.storage;
import org.junit.Before;
import org.junit.Test;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountCleaner;
import org.whispersystems.textsecuregcm.storage.AccountDatabaseCrawlerRestartException;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@ -28,7 +13,21 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
public class AccountCleanerTest { import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.AccountCleaner;
import org.whispersystems.textsecuregcm.storage.AccountDatabaseCrawlerRestartException;
import org.whispersystems.textsecuregcm.storage.AccountsManager;
import org.whispersystems.textsecuregcm.storage.Device;
class AccountCleanerTest {
private final AccountsManager accountsManager = mock(AccountsManager.class); private final AccountsManager accountsManager = mock(AccountsManager.class);
@ -41,8 +40,8 @@ public class AccountCleanerTest {
private final Device undeletedEnabledDevice = mock(Device.class ); private final Device undeletedEnabledDevice = mock(Device.class );
@Before @BeforeEach
public void setup() { void setup() {
when(deletedDisabledDevice.isEnabled()).thenReturn(false); when(deletedDisabledDevice.isEnabled()).thenReturn(false);
when(deletedDisabledDevice.getGcmId()).thenReturn(null); when(deletedDisabledDevice.getGcmId()).thenReturn(null);
when(deletedDisabledDevice.getApnId()).thenReturn(null); when(deletedDisabledDevice.getApnId()).thenReturn(null);
@ -72,7 +71,7 @@ public class AccountCleanerTest {
} }
@Test @Test
public void testAccounts() throws AccountDatabaseCrawlerRestartException, InterruptedException { void testAccounts() throws AccountDatabaseCrawlerRestartException, InterruptedException {
AccountCleaner accountCleaner = new AccountCleaner(accountsManager); AccountCleaner accountCleaner = new AccountCleaner(accountsManager);
accountCleaner.onCrawlStart(); accountCleaner.onCrawlStart();
accountCleaner.timeAndProcessCrawlChunk(Optional.empty(), Arrays.asList(deletedDisabledAccount, undeletedDisabledAccount, undeletedEnabledAccount)); accountCleaner.timeAndProcessCrawlChunk(Optional.empty(), Arrays.asList(deletedDisabledAccount, undeletedDisabledAccount, undeletedEnabledAccount));
@ -86,7 +85,7 @@ public class AccountCleanerTest {
} }
@Test @Test
public void testMaxAccountUpdates() throws AccountDatabaseCrawlerRestartException, InterruptedException { void testMaxAccountUpdates() throws AccountDatabaseCrawlerRestartException, InterruptedException {
List<Account> accounts = new LinkedList<>(); List<Account> accounts = new LinkedList<>();
accounts.add(undeletedEnabledAccount); accounts.add(undeletedEnabledAccount);

View File

@ -5,15 +5,15 @@
package org.whispersystems.textsecuregcm.tests.util; package org.whispersystems.textsecuregcm.tests.util;
import org.junit.Test;
import org.whispersystems.textsecuregcm.util.Util;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
public class NumberPrefixTest { import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.util.Util;
class NumberPrefixTest {
@Test @Test
public void testPrefixes() { void testPrefixes() {
assertThat(Util.getNumberPrefix("+14151234567")).isEqualTo("+14151"); assertThat(Util.getNumberPrefix("+14151234567")).isEqualTo("+14151");
assertThat(Util.getNumberPrefix("+22587654321")).isEqualTo("+2258765"); assertThat(Util.getNumberPrefix("+22587654321")).isEqualTo("+2258765");
assertThat(Util.getNumberPrefix("+298654321")).isEqualTo("+2986543"); assertThat(Util.getNumberPrefix("+298654321")).isEqualTo("+2986543");

View File

@ -5,18 +5,17 @@
package org.whispersystems.textsecuregcm.tests.util; package org.whispersystems.textsecuregcm.tests.util;
import com.amazonaws.HttpMethod;
import org.junit.Test;
import org.whispersystems.textsecuregcm.s3.UrlSigner;
import java.net.URL;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
public class UrlSignerTest { import com.amazonaws.HttpMethod;
import java.net.URL;
import org.junit.jupiter.api.Test;
import org.whispersystems.textsecuregcm.s3.UrlSigner;
class UrlSignerTest {
@Test @Test
public void testTransferAcceleration() { void testTransferAcceleration() {
UrlSigner signer = new UrlSigner("foo", "bar", "attachments-test"); UrlSigner signer = new UrlSigner("foo", "bar", "attachments-test");
URL url = signer.getPreSignedUrl(1234, HttpMethod.GET, false); URL url = signer.getPreSignedUrl(1234, HttpMethod.GET, false);
@ -24,7 +23,7 @@ public class UrlSignerTest {
} }
@Test @Test
public void testTransferUnaccelerated() { void testTransferUnaccelerated() {
UrlSigner signer = new UrlSigner("foo", "bar", "attachments-test"); UrlSigner signer = new UrlSigner("foo", "bar", "attachments-test");
URL url = signer.getPreSignedUrl(1234, HttpMethod.GET, true); URL url = signer.getPreSignedUrl(1234, HttpMethod.GET, true);

View File

@ -5,15 +5,15 @@
package org.whispersystems.textsecuregcm.util; package org.whispersystems.textsecuregcm.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import io.lettuce.core.cluster.SlotHash; import io.lettuce.core.cluster.SlotHash;
import org.junit.Test; import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals; class RedisClusterUtilTest {
public class RedisClusterUtilTest {
@Test @Test
public void testGetMinimalHashTag() { void testGetMinimalHashTag() {
for (int slot = 0; slot < SlotHash.SLOT_COUNT; slot++) { for (int slot = 0; slot < SlotHash.SLOT_COUNT; slot++) {
assertEquals(slot, SlotHash.getSlot(RedisClusterUtil.getMinimalHashTag(slot))); assertEquals(slot, SlotHash.getSlot(RedisClusterUtil.getMinimalHashTag(slot)));
} }

View File

@ -5,38 +5,35 @@
package org.whispersystems.textsecuregcm.util.ua; package org.whispersystems.textsecuregcm.util.ua;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.vdurmont.semver4j.Semver; import com.vdurmont.semver4j.Semver;
import junitparams.JUnitParamsRunner; import org.junit.jupiter.params.ParameterizedTest;
import junitparams.Parameters; import org.junit.jupiter.params.provider.MethodSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
import static org.junit.Assert.*; class UserAgentUtilTest {
@RunWith(JUnitParamsRunner.class) @ParameterizedTest
public class UserAgentUtilTest { @MethodSource("argumentsForTestParseUserAgentString")
void testParseUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) throws UnrecognizedUserAgentException {
@Test
@Parameters(method = "argumentsForTestParseUserAgentString")
public void testParseUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) throws UnrecognizedUserAgentException {
assertEquals(expectedUserAgent, UserAgentUtil.parseUserAgentString(userAgentString)); assertEquals(expectedUserAgent, UserAgentUtil.parseUserAgentString(userAgentString));
} }
private static Object argumentsForTestParseUserAgentString() { private static Object[] argumentsForTestParseUserAgentString() {
return new Object[] { return new Object[] {
new Object[] { "Signal-Android/4.68.3 Android/25", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25") }, new Object[] { "Signal-Android/4.68.3 Android/25", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25") },
new Object[] { "Signal-Android 4.53.7 (Android 8.1)", new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)") }, new Object[] { "Signal-Android 4.53.7 (Android 8.1)", new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)") },
}; };
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForTestParseBogusUserAgentString") @MethodSource("argumentsForTestParseBogusUserAgentString")
public void testParseBogusUserAgentString(final String userAgentString) { void testParseBogusUserAgentString(final String userAgentString) {
assertThrows(UnrecognizedUserAgentException.class, () -> UserAgentUtil.parseUserAgentString(userAgentString)); assertThrows(UnrecognizedUserAgentException.class, () -> UserAgentUtil.parseUserAgentString(userAgentString));
} }
private static Object argumentsForTestParseBogusUserAgentString() { private static Object[] argumentsForTestParseBogusUserAgentString() {
return new Object[] { return new Object[] {
null, null,
"This is obviously not a reasonable User-Agent string.", "This is obviously not a reasonable User-Agent string.",
@ -44,13 +41,13 @@ public class UserAgentUtilTest {
}; };
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForTestParseStandardUserAgentString") @MethodSource("argumentsForTestParseStandardUserAgentString")
public void testParseStandardUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) { void testParseStandardUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) {
assertEquals(expectedUserAgent, UserAgentUtil.parseStandardUserAgentString(userAgentString)); assertEquals(expectedUserAgent, UserAgentUtil.parseStandardUserAgentString(userAgentString));
} }
private static Object argumentsForTestParseStandardUserAgentString() { private static Object[] argumentsForTestParseStandardUserAgentString() {
return new Object[] { return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", null }, new Object[] { "This is obviously not a reasonable User-Agent string.", null },
new Object[] { "Signal-Android/4.68.3 Android/25", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25") }, new Object[] { "Signal-Android/4.68.3 Android/25", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25") },
@ -66,13 +63,13 @@ public class UserAgentUtilTest {
}; };
} }
@Test @ParameterizedTest
@Parameters(method = "argumentsForTestParseLegacyUserAgentString") @MethodSource("argumentsForTestParseLegacyUserAgentString")
public void testParseLegacyUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) { void testParseLegacyUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) {
assertEquals(expectedUserAgent, UserAgentUtil.parseLegacyUserAgentString(userAgentString)); assertEquals(expectedUserAgent, UserAgentUtil.parseLegacyUserAgentString(userAgentString));
} }
private static Object argumentsForTestParseLegacyUserAgentString() { private static Object[] argumentsForTestParseLegacyUserAgentString() {
return new Object[] { return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", null }, new Object[] { "This is obviously not a reasonable User-Agent string.", null },
new Object[] { "Signal-Android 4.53.7 (Android 8.1)", new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)") }, new Object[] { "Signal-Android 4.53.7 (Android 8.1)", new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)") },

View File

@ -5,9 +5,10 @@
package org.whispersystems.textsecuregcm.websocket; package org.whispersystems.textsecuregcm.websocket;
import static org.junit.Assert.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
@ -27,6 +28,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
import io.dropwizard.auth.basic.BasicCredentials; import io.dropwizard.auth.basic.BasicCredentials;
import io.lettuce.core.RedisException; import io.lettuce.core.RedisException;
import java.io.IOException; import java.io.IOException;
import java.time.Duration;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -43,8 +45,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.jetty.websocket.api.UpgradeRequest; import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.junit.Before; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.BeforeEach;
import org.mockito.ArgumentMatchers; import org.mockito.ArgumentMatchers;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
@ -66,7 +68,7 @@ import org.whispersystems.websocket.auth.WebSocketAuthenticator.AuthenticationRe
import org.whispersystems.websocket.messages.WebSocketResponseMessage; import org.whispersystems.websocket.messages.WebSocketResponseMessage;
import org.whispersystems.websocket.session.WebSocketSessionContext; import org.whispersystems.websocket.session.WebSocketSessionContext;
public class WebSocketConnectionTest { class WebSocketConnectionTest {
private static final String VALID_USER = "+14152222222"; private static final String VALID_USER = "+14152222222";
private static final String INVALID_USER = "+14151111111"; private static final String INVALID_USER = "+14151111111";
@ -84,8 +86,8 @@ public class WebSocketConnectionTest {
private ApnFallbackManager apnFallbackManager; private ApnFallbackManager apnFallbackManager;
private ScheduledExecutorService retrySchedulingExecutor; private ScheduledExecutorService retrySchedulingExecutor;
@Before @BeforeEach
public void setup() { void setup() {
accountAuthenticator = mock(AccountAuthenticator.class); accountAuthenticator = mock(AccountAuthenticator.class);
accountsManager = mock(AccountsManager.class); accountsManager = mock(AccountsManager.class);
account = mock(Account.class); account = mock(Account.class);
@ -98,7 +100,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testCredentials() throws Exception { void testCredentials() {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
WebSocketAccountAuthenticator webSocketAuthenticator = new WebSocketAccountAuthenticator(accountAuthenticator); WebSocketAccountAuthenticator webSocketAuthenticator = new WebSocketAccountAuthenticator(accountAuthenticator);
AuthenticatedConnectListener connectListener = new AuthenticatedConnectListener(receiptSender, storedMessages, AuthenticatedConnectListener connectListener = new AuthenticatedConnectListener(receiptSender, storedMessages,
@ -143,7 +145,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testOpen() throws Exception { void testOpen() throws Exception {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
UUID accountUuid = UUID.randomUUID(); UUID accountUuid = UUID.randomUUID();
@ -187,7 +189,7 @@ public class WebSocketConnectionTest {
when(client.sendRequest(eq("PUT"), eq("/api/v1/message"), ArgumentMatchers.nullable(List.class), ArgumentMatchers.<Optional<byte[]>>any())) when(client.sendRequest(eq("PUT"), eq("/api/v1/message"), ArgumentMatchers.nullable(List.class), ArgumentMatchers.<Optional<byte[]>>any()))
.thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() { .thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() {
@Override @Override
public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) throws Throwable { public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) {
CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>(); CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>();
futures.add(future); futures.add(future);
return future; return future;
@ -217,8 +219,8 @@ public class WebSocketConnectionTest {
verify(client).close(anyInt(), anyString()); verify(client).close(anyInt(), anyString());
} }
@Test(timeout = 5_000L) @Test
public void testOnlineSend() throws Exception { public void testOnlineSend() {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -250,34 +252,36 @@ public class WebSocketConnectionTest {
return CompletableFuture.completedFuture(successResponse); return CompletableFuture.completedFuture(successResponse);
}); });
// This is a little hacky and non-obvious, but because the first call to getMessagesForDevice returns empty list of assertTimeoutPreemptively(Duration.ofSeconds(5), () -> {
// messages, the call to CompletableFuture.allOf(...) in processStoredMessages will produce an instantly-succeeded // This is a little hacky and non-obvious, but because the first call to getMessagesForDevice returns empty list of
// future, and the whenComplete method will get called immediately on THIS thread, so we don't need to synchronize // messages, the call to CompletableFuture.allOf(...) in processStoredMessages will produce an instantly-succeeded
// or wait for anything. // future, and the whenComplete method will get called immediately on THIS thread, so we don't need to synchronize
connection.start(); // or wait for anything.
connection.start();
connection.handleNewMessagesAvailable(); connection.handleNewMessagesAvailable();
synchronized (sendCounter) { synchronized (sendCounter) {
while (sendCounter.get() < 1) { while (sendCounter.get() < 1) {
sendCounter.wait(); sendCounter.wait();
}
} }
}
connection.handleNewMessagesAvailable(); connection.handleNewMessagesAvailable();
synchronized (sendCounter) { synchronized (sendCounter) {
while (sendCounter.get() < 2) { while (sendCounter.get() < 2) {
sendCounter.wait(); sendCounter.wait();
}
} }
} });
verify(client, times(1)).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty())); verify(client, times(1)).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty()));
verify(client, times(2)).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), any(Optional.class)); verify(client, times(2)).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), any(Optional.class));
} }
@Test @Test
public void testPendingSend() throws Exception { void testPendingSend() throws Exception {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
final UUID senderTwoUuid = UUID.randomUUID(); final UUID senderTwoUuid = UUID.randomUUID();
@ -344,7 +348,7 @@ public class WebSocketConnectionTest {
when(client.sendRequest(eq("PUT"), eq("/api/v1/message"), ArgumentMatchers.nullable(List.class), ArgumentMatchers.<Optional<byte[]>>any())) when(client.sendRequest(eq("PUT"), eq("/api/v1/message"), ArgumentMatchers.nullable(List.class), ArgumentMatchers.<Optional<byte[]>>any()))
.thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() { .thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() {
@Override @Override
public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) throws Throwable { public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) {
CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>(); CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>();
futures.add(future); futures.add(future);
return future; return future;
@ -372,8 +376,8 @@ public class WebSocketConnectionTest {
verify(client).close(anyInt(), anyString()); verify(client).close(anyInt(), anyString());
} }
@Test(timeout = 5000L) @Test
public void testProcessStoredMessageConcurrency() throws InterruptedException { void testProcessStoredMessageConcurrency() throws InterruptedException {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -406,37 +410,40 @@ public class WebSocketConnectionTest {
final Thread[] threads = new Thread[10]; final Thread[] threads = new Thread[10];
final CountDownLatch unblockedThreadsLatch = new CountDownLatch(threads.length - 1); final CountDownLatch unblockedThreadsLatch = new CountDownLatch(threads.length - 1);
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
connection.processStoredMessages();
unblockedThreadsLatch.countDown();
});
threads[i].start(); assertTimeoutPreemptively(Duration.ofSeconds(5), () -> {
} for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
connection.processStoredMessages();
unblockedThreadsLatch.countDown();
});
unblockedThreadsLatch.await(); threads[i].start();
synchronized (threadWaiting) {
while (!threadWaiting.get()) {
threadWaiting.wait();
} }
}
synchronized (returnMessageList) { unblockedThreadsLatch.await();
returnMessageList.set(true);
returnMessageList.notifyAll();
}
for (final Thread thread : threads) { synchronized (threadWaiting) {
thread.join(); while (!threadWaiting.get()) {
} threadWaiting.wait();
}
}
synchronized (returnMessageList) {
returnMessageList.set(true);
returnMessageList.notifyAll();
}
for (final Thread thread : threads) {
thread.join();
}
});
verify(messagesManager).getMessagesForDevice(any(UUID.class), anyLong(), anyString(), eq(false)); verify(messagesManager).getMessagesForDevice(any(UUID.class), anyLong(), anyString(), eq(false));
} }
@Test(timeout = 5000L) @Test
public void testProcessStoredMessagesMultiplePages() throws InterruptedException { void testProcessStoredMessagesMultiplePages() {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -471,16 +478,18 @@ public class WebSocketConnectionTest {
return CompletableFuture.completedFuture(successResponse); return CompletableFuture.completedFuture(successResponse);
}); });
connection.processStoredMessages(); assertTimeoutPreemptively(Duration.ofSeconds(5), () -> {
connection.processStoredMessages();
sendLatch.await(); sendLatch.await();
});
verify(client, times(firstPageMessages.size() + secondPageMessages.size())).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), any(Optional.class)); verify(client, times(firstPageMessages.size() + secondPageMessages.size())).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), any(Optional.class));
verify(client).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty())); verify(client).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty()));
} }
@Test(timeout = 5000L) @Test
public void testProcessStoredMessagesContainsSenderUuid() throws InterruptedException { void testProcessStoredMessagesContainsSenderUuid() {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -508,9 +517,11 @@ public class WebSocketConnectionTest {
return CompletableFuture.completedFuture(successResponse); return CompletableFuture.completedFuture(successResponse);
}); });
connection.processStoredMessages(); assertTimeoutPreemptively(Duration.ofSeconds(5), () -> {
connection.processStoredMessages();
sendLatch.await(); sendLatch.await();
});
verify(client, times(messages.size())).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), argThat(argument -> { verify(client, times(messages.size())).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), argThat(argument -> {
if (argument.isEmpty()) { if (argument.isEmpty()) {
@ -532,7 +543,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testProcessStoredMessagesSingleEmptyCall() { void testProcessStoredMessagesSingleEmptyCall() {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -561,8 +572,8 @@ public class WebSocketConnectionTest {
verify(client, times(1)).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty())); verify(client, times(1)).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty()));
} }
@Test(timeout = 5000L) @Test
public void testRequeryOnStateMismatch() throws InterruptedException { public void testRequeryOnStateMismatch() {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -601,16 +612,18 @@ public class WebSocketConnectionTest {
return CompletableFuture.completedFuture(successResponse); return CompletableFuture.completedFuture(successResponse);
}); });
connection.processStoredMessages(); assertTimeoutPreemptively(Duration.ofSeconds(5), () -> {
connection.processStoredMessages();
sendLatch.await(); sendLatch.await();
});
verify(client, times(firstPageMessages.size() + secondPageMessages.size())).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), any(Optional.class)); verify(client, times(firstPageMessages.size() + secondPageMessages.size())).sendRequest(eq("PUT"), eq("/api/v1/message"), any(List.class), any(Optional.class));
verify(client).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty())); verify(client).sendRequest(eq("PUT"), eq("/api/v1/queue/empty"), any(List.class), eq(Optional.empty()));
} }
@Test @Test
public void testProcessCachedMessagesOnly() { void testProcessCachedMessagesOnly() {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -643,7 +656,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testProcessDatabaseMessagesAfterPersist() { void testProcessDatabaseMessagesAfterPersist() {
final MessagesManager messagesManager = mock(MessagesManager.class); final MessagesManager messagesManager = mock(MessagesManager.class);
final WebSocketClient client = mock(WebSocketClient.class); final WebSocketClient client = mock(WebSocketClient.class);
final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client, final WebSocketConnection connection = new WebSocketConnection(receiptSender, messagesManager, auth, device, client,
@ -673,7 +686,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testDiscardOversizedMessagesForDesktop() { void testDiscardOversizedMessagesForDesktop() {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
UUID accountUuid = UUID.randomUUID(); UUID accountUuid = UUID.randomUUID();
@ -718,8 +731,7 @@ public class WebSocketConnectionTest {
ArgumentMatchers.<Optional<byte[]>>any())) ArgumentMatchers.<Optional<byte[]>>any()))
.thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() { .thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() {
@Override @Override
public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) {
throws Throwable {
CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>(); CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>();
futures.add(future); futures.add(future);
return future; return future;
@ -749,7 +761,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testSendOversizedMessagesForNonDesktop() throws Exception { void testSendOversizedMessagesForNonDesktop() {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
UUID accountUuid = UUID.randomUUID(); UUID accountUuid = UUID.randomUUID();
@ -794,8 +806,7 @@ public class WebSocketConnectionTest {
ArgumentMatchers.<Optional<byte[]>>any())) ArgumentMatchers.<Optional<byte[]>>any()))
.thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() { .thenAnswer(new Answer<CompletableFuture<WebSocketResponseMessage>>() {
@Override @Override
public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) public CompletableFuture<WebSocketResponseMessage> answer(InvocationOnMock invocationOnMock) {
throws Throwable {
CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>(); CompletableFuture<WebSocketResponseMessage> future = new CompletableFuture<>();
futures.add(future); futures.add(future);
return future; return future;
@ -824,7 +835,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testRetrieveMessageException() { void testRetrieveMessageException() {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
UUID accountUuid = UUID.randomUUID(); UUID accountUuid = UUID.randomUUID();
@ -858,7 +869,7 @@ public class WebSocketConnectionTest {
} }
@Test @Test
public void testRetrieveMessageExceptionClientDisconnected() { void testRetrieveMessageExceptionClientDisconnected() {
MessagesManager storedMessages = mock(MessagesManager.class); MessagesManager storedMessages = mock(MessagesManager.class);
UUID accountUuid = UUID.randomUUID(); UUID accountUuid = UUID.randomUUID();