mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-22 05:38:02 +01:00
Accept source ACI at /v1/messages/report
This commit is contained in:
@@ -80,6 +80,7 @@ import org.whispersystems.textsecuregcm.push.MessageSender;
|
||||
import org.whispersystems.textsecuregcm.push.ReceiptSender;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.DeletedAccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ReportMessageManager;
|
||||
@@ -94,24 +95,25 @@ class MessageControllerTest {
|
||||
private static final UUID SINGLE_DEVICE_UUID = UUID.randomUUID();
|
||||
private static final UUID SINGLE_DEVICE_PNI = UUID.randomUUID();
|
||||
|
||||
private static final String MULTI_DEVICE_RECIPIENT = "+14152222222";
|
||||
private static final UUID MULTI_DEVICE_UUID = UUID.randomUUID();
|
||||
private static final String MULTI_DEVICE_RECIPIENT = "+14152222222";
|
||||
private static final UUID MULTI_DEVICE_UUID = UUID.randomUUID();
|
||||
|
||||
private static final String INTERNATIONAL_RECIPIENT = "+61123456789";
|
||||
private static final UUID INTERNATIONAL_UUID = UUID.randomUUID();
|
||||
private static final UUID INTERNATIONAL_UUID = UUID.randomUUID();
|
||||
|
||||
private Account internationalAccount;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final RedisAdvancedClusterCommands<String, String> redisCommands = mock(RedisAdvancedClusterCommands.class);
|
||||
|
||||
private static final MessageSender messageSender = mock(MessageSender.class);
|
||||
private static final ReceiptSender receiptSender = mock(ReceiptSender.class);
|
||||
private static final AccountsManager accountsManager = mock(AccountsManager.class);
|
||||
private static final MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
private static final RateLimiters rateLimiters = mock(RateLimiters.class);
|
||||
private static final RateLimiter rateLimiter = mock(RateLimiter.class);
|
||||
private static final ApnFallbackManager apnFallbackManager = mock(ApnFallbackManager.class);
|
||||
private static final MessageSender messageSender = mock(MessageSender.class);
|
||||
private static final ReceiptSender receiptSender = mock(ReceiptSender.class);
|
||||
private static final AccountsManager accountsManager = mock(AccountsManager.class);
|
||||
private static final DeletedAccountsManager deletedAccountsManager = mock(DeletedAccountsManager.class);
|
||||
private static final MessagesManager messagesManager = mock(MessagesManager.class);
|
||||
private static final RateLimiters rateLimiters = mock(RateLimiters.class);
|
||||
private static final RateLimiter rateLimiter = mock(RateLimiter.class);
|
||||
private static final ApnFallbackManager apnFallbackManager = mock(ApnFallbackManager.class);
|
||||
private static final ReportMessageManager reportMessageManager = mock(ReportMessageManager.class);
|
||||
private static final ExecutorService multiRecipientMessageExecutor = mock(ExecutorService.class);
|
||||
|
||||
@@ -122,8 +124,9 @@ class MessageControllerTest {
|
||||
.addProvider(RateLimitExceededExceptionMapper.class)
|
||||
.addProvider(MultiDeviceMessageListProvider.class)
|
||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||
.addResource(new MessageController(rateLimiters, messageSender, receiptSender, accountsManager,
|
||||
messagesManager, apnFallbackManager, reportMessageManager, multiRecipientMessageExecutor))
|
||||
.addResource(
|
||||
new MessageController(rateLimiters, messageSender, receiptSender, accountsManager, deletedAccountsManager,
|
||||
messagesManager, apnFallbackManager, reportMessageManager, multiRecipientMessageExecutor))
|
||||
.build();
|
||||
|
||||
@BeforeEach
|
||||
@@ -486,13 +489,13 @@ class MessageControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetMessages() throws Exception {
|
||||
void testGetMessages() {
|
||||
|
||||
final long timestampOne = 313377;
|
||||
final long timestampTwo = 313388;
|
||||
|
||||
final UUID messageGuidOne = UUID.randomUUID();
|
||||
final UUID sourceUuid = UUID.randomUUID();
|
||||
final UUID sourceUuid = UUID.randomUUID();
|
||||
|
||||
List<OutgoingMessageEntity> messages = new LinkedList<>() {{
|
||||
add(new OutgoingMessageEntity(messageGuidOne, Envelope.Type.CIPHERTEXT_VALUE, timestampOne, "+14152222222", sourceUuid, 2, AuthHelper.VALID_UUID, "hi there".getBytes(), 0));
|
||||
@@ -595,12 +598,23 @@ class MessageControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportMessage() {
|
||||
void testReportMessageByE164() {
|
||||
|
||||
final String senderNumber = "+12125550001";
|
||||
final UUID messageGuid = UUID.randomUUID();
|
||||
final UUID senderAci = UUID.randomUUID();
|
||||
final UUID senderPni = UUID.randomUUID();
|
||||
UUID messageGuid = UUID.randomUUID();
|
||||
|
||||
final Response response =
|
||||
final Account account = mock(Account.class);
|
||||
when(account.getUuid()).thenReturn(senderAci);
|
||||
when(account.getNumber()).thenReturn(senderNumber);
|
||||
when(account.getPhoneNumberIdentifier()).thenReturn(senderPni);
|
||||
|
||||
when(accountsManager.getByE164(senderNumber)).thenReturn(Optional.of(account));
|
||||
when(deletedAccountsManager.findDeletedAccountAci(senderNumber)).thenReturn(Optional.of(senderAci));
|
||||
when(accountsManager.getPhoneNumberIdentifier(senderNumber)).thenReturn(senderPni);
|
||||
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/report/%s/%s", senderNumber, messageGuid))
|
||||
.request()
|
||||
@@ -609,7 +623,73 @@ class MessageControllerTest {
|
||||
|
||||
assertThat(response.getStatus(), is(equalTo(202)));
|
||||
|
||||
verify(reportMessageManager).report(senderNumber, messageGuid, AuthHelper.VALID_UUID);
|
||||
verify(reportMessageManager).report(Optional.of(senderNumber), Optional.of(senderAci), Optional.of(senderPni),
|
||||
messageGuid, AuthHelper.VALID_UUID);
|
||||
verify(deletedAccountsManager, never()).findDeletedAccountE164(any(UUID.class));
|
||||
verify(accountsManager, never()).getPhoneNumberIdentifier(anyString());
|
||||
|
||||
when(accountsManager.getByE164(senderNumber)).thenReturn(Optional.empty());
|
||||
messageGuid = UUID.randomUUID();
|
||||
|
||||
response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/report/%s/%s", senderNumber, messageGuid))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.post(null);
|
||||
|
||||
assertThat(response.getStatus(), is(equalTo(202)));
|
||||
|
||||
verify(reportMessageManager).report(Optional.of(senderNumber), Optional.of(senderAci), Optional.of(senderPni),
|
||||
messageGuid, AuthHelper.VALID_UUID);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportMessageByAci() {
|
||||
|
||||
final String senderNumber = "+12125550001";
|
||||
final UUID senderAci = UUID.randomUUID();
|
||||
final UUID senderPni = UUID.randomUUID();
|
||||
UUID messageGuid = UUID.randomUUID();
|
||||
|
||||
final Account account = mock(Account.class);
|
||||
when(account.getUuid()).thenReturn(senderAci);
|
||||
when(account.getNumber()).thenReturn(senderNumber);
|
||||
when(account.getPhoneNumberIdentifier()).thenReturn(senderPni);
|
||||
|
||||
when(accountsManager.getByAccountIdentifier(senderAci)).thenReturn(Optional.of(account));
|
||||
when(deletedAccountsManager.findDeletedAccountE164(senderAci)).thenReturn(Optional.of(senderNumber));
|
||||
when(accountsManager.getPhoneNumberIdentifier(senderNumber)).thenReturn(senderPni);
|
||||
|
||||
Response response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/report/%s/%s", senderAci, messageGuid))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.post(null);
|
||||
|
||||
assertThat(response.getStatus(), is(equalTo(202)));
|
||||
|
||||
verify(reportMessageManager).report(Optional.of(senderNumber), Optional.of(senderAci), Optional.of(senderPni),
|
||||
messageGuid, AuthHelper.VALID_UUID);
|
||||
verify(deletedAccountsManager, never()).findDeletedAccountE164(any(UUID.class));
|
||||
verify(accountsManager, never()).getPhoneNumberIdentifier(anyString());
|
||||
|
||||
when(accountsManager.getByAccountIdentifier(senderAci)).thenReturn(Optional.empty());
|
||||
|
||||
messageGuid = UUID.randomUUID();
|
||||
|
||||
response =
|
||||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/messages/report/%s/%s", senderAci, messageGuid))
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.post(null);
|
||||
|
||||
assertThat(response.getStatus(), is(equalTo(202)));
|
||||
|
||||
verify(reportMessageManager).report(Optional.of(senderNumber), Optional.of(senderAci), Optional.of(senderPni),
|
||||
messageGuid, AuthHelper.VALID_UUID);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
||||
@@ -5,6 +5,16 @@
|
||||
|
||||
package org.whispersystems.textsecuregcm.storage;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.lang.Thread.State;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
@@ -17,16 +27,6 @@ import software.amazon.awssdk.services.dynamodb.model.Projection;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ProjectionType;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
|
||||
import java.lang.Thread.State;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class DeletedAccountsManagerTest {
|
||||
|
||||
@@ -43,11 +43,26 @@ class DeletedAccountsManagerTest {
|
||||
.attributeName(DeletedAccounts.ATTR_NEEDS_CDS_RECONCILIATION)
|
||||
.attributeType(ScalarAttributeType.N)
|
||||
.build())
|
||||
.attributeDefinition(AttributeDefinition.builder()
|
||||
.attributeName(DeletedAccounts.ATTR_ACCOUNT_UUID)
|
||||
.attributeType(ScalarAttributeType.B)
|
||||
.build())
|
||||
.globalSecondaryIndex(GlobalSecondaryIndex.builder()
|
||||
.indexName(NEEDS_RECONCILIATION_INDEX_NAME)
|
||||
.keySchema(KeySchemaElement.builder().attributeName(DeletedAccounts.KEY_ACCOUNT_E164).keyType(KeyType.HASH).build(),
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.ATTR_NEEDS_CDS_RECONCILIATION).keyType(KeyType.RANGE).build())
|
||||
.projection(Projection.builder().projectionType(ProjectionType.INCLUDE).nonKeyAttributes(DeletedAccounts.ATTR_ACCOUNT_UUID).build())
|
||||
.keySchema(
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.KEY_ACCOUNT_E164).keyType(KeyType.HASH).build(),
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.ATTR_NEEDS_CDS_RECONCILIATION)
|
||||
.keyType(KeyType.RANGE).build())
|
||||
.projection(Projection.builder().projectionType(ProjectionType.INCLUDE)
|
||||
.nonKeyAttributes(DeletedAccounts.ATTR_ACCOUNT_UUID).build())
|
||||
.provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(10L).writeCapacityUnits(10L).build())
|
||||
.build())
|
||||
.globalSecondaryIndex(GlobalSecondaryIndex.builder()
|
||||
.indexName(DeletedAccounts.UUID_TO_E164_INDEX_NAME)
|
||||
.keySchema(
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.ATTR_ACCOUNT_UUID).keyType(KeyType.HASH).build()
|
||||
)
|
||||
.projection(Projection.builder().projectionType(ProjectionType.KEYS_ONLY).build())
|
||||
.provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(10L).writeCapacityUnits(10L).build())
|
||||
.build())
|
||||
.build();
|
||||
@@ -167,4 +182,5 @@ class DeletedAccountsManagerTest {
|
||||
return List.of(deletedAccounts.get(0).second());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -41,11 +41,26 @@ class DeletedAccountsTest {
|
||||
.attributeName(DeletedAccounts.ATTR_NEEDS_CDS_RECONCILIATION)
|
||||
.attributeType(ScalarAttributeType.N)
|
||||
.build())
|
||||
.attributeDefinition(AttributeDefinition.builder()
|
||||
.attributeName(DeletedAccounts.ATTR_ACCOUNT_UUID)
|
||||
.attributeType(ScalarAttributeType.B)
|
||||
.build())
|
||||
.globalSecondaryIndex(GlobalSecondaryIndex.builder()
|
||||
.indexName(NEEDS_RECONCILIATION_INDEX_NAME)
|
||||
.keySchema(KeySchemaElement.builder().attributeName(DeletedAccounts.KEY_ACCOUNT_E164).keyType(KeyType.HASH).build(),
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.ATTR_NEEDS_CDS_RECONCILIATION).keyType(KeyType.RANGE).build())
|
||||
.projection(Projection.builder().projectionType(ProjectionType.INCLUDE).nonKeyAttributes(DeletedAccounts.ATTR_ACCOUNT_UUID).build())
|
||||
.keySchema(
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.KEY_ACCOUNT_E164).keyType(KeyType.HASH).build(),
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.ATTR_NEEDS_CDS_RECONCILIATION)
|
||||
.keyType(KeyType.RANGE).build())
|
||||
.projection(Projection.builder().projectionType(ProjectionType.INCLUDE)
|
||||
.nonKeyAttributes(DeletedAccounts.ATTR_ACCOUNT_UUID).build())
|
||||
.provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(10L).writeCapacityUnits(10L).build())
|
||||
.build())
|
||||
.globalSecondaryIndex(GlobalSecondaryIndex.builder()
|
||||
.indexName(DeletedAccounts.UUID_TO_E164_INDEX_NAME)
|
||||
.keySchema(
|
||||
KeySchemaElement.builder().attributeName(DeletedAccounts.ATTR_ACCOUNT_UUID).keyType(KeyType.HASH).build()
|
||||
)
|
||||
.projection(Projection.builder().projectionType(ProjectionType.KEYS_ONLY).build())
|
||||
.provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(10L).writeCapacityUnits(10L).build())
|
||||
.build())
|
||||
.build();
|
||||
@@ -156,4 +171,30 @@ class DeletedAccountsTest {
|
||||
|
||||
assertEquals(expectedAccountsNeedingReconciliation, accountsNeedingReconciliation);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testFindE164() {
|
||||
assertEquals(Optional.empty(), deletedAccounts.findE164(UUID.randomUUID()));
|
||||
|
||||
final UUID uuid = UUID.randomUUID();
|
||||
final String e164 = "+18005551234";
|
||||
|
||||
deletedAccounts.put(uuid, e164, true);
|
||||
|
||||
assertEquals(Optional.of(e164), deletedAccounts.findE164(uuid));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testFindUUID() {
|
||||
final String e164 = "+18005551234";
|
||||
|
||||
assertEquals(Optional.empty(), deletedAccounts.findUuid(e164));
|
||||
|
||||
final UUID uuid = UUID.randomUUID();
|
||||
|
||||
deletedAccounts.put(uuid, e164, true);
|
||||
|
||||
assertEquals(Optional.of(uuid), deletedAccounts.findUuid(e164));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,16 +24,17 @@ class MessagesManagerTest {
|
||||
@Test
|
||||
void insert() {
|
||||
final String sourceNumber = "+12025551212";
|
||||
final UUID sourceAci = UUID.randomUUID();
|
||||
final Envelope message = Envelope.newBuilder()
|
||||
.setSource(sourceNumber)
|
||||
.setSourceUuid(UUID.randomUUID().toString())
|
||||
.setSourceUuid(sourceAci.toString())
|
||||
.build();
|
||||
|
||||
final UUID destinationUuid = UUID.randomUUID();
|
||||
|
||||
messagesManager.insert(destinationUuid, 1L, message);
|
||||
|
||||
verify(reportMessageManager).store(eq(sourceNumber), any(UUID.class));
|
||||
verify(reportMessageManager).store(eq(sourceNumber), eq(sourceAci.toString()), any(UUID.class));
|
||||
|
||||
final Envelope syncMessage = Envelope.newBuilder(message)
|
||||
.setSourceUuid(destinationUuid.toString())
|
||||
|
||||
@@ -6,13 +6,21 @@
|
||||
package org.whispersystems.textsecuregcm.storage;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
|
||||
import software.amazon.awssdk.services.dynamodb.model.GlobalSecondaryIndex;
|
||||
import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
|
||||
import software.amazon.awssdk.services.dynamodb.model.KeyType;
|
||||
import software.amazon.awssdk.services.dynamodb.model.Projection;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ProjectionType;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
|
||||
|
||||
class PhoneNumberIdentifiersTest {
|
||||
@@ -27,6 +35,20 @@ class PhoneNumberIdentifiersTest {
|
||||
.attributeName(PhoneNumberIdentifiers.KEY_E164)
|
||||
.attributeType(ScalarAttributeType.S)
|
||||
.build())
|
||||
.attributeDefinition(AttributeDefinition.builder()
|
||||
.attributeName(PhoneNumberIdentifiers.ATTR_PHONE_NUMBER_IDENTIFIER)
|
||||
.attributeType(ScalarAttributeType.B)
|
||||
.build())
|
||||
.globalSecondaryIndex(GlobalSecondaryIndex.builder()
|
||||
.indexName(PhoneNumberIdentifiers.INDEX_NAME)
|
||||
.projection(Projection.builder()
|
||||
.projectionType(ProjectionType.KEYS_ONLY)
|
||||
.build())
|
||||
.keySchema(KeySchemaElement.builder().keyType(KeyType.HASH)
|
||||
.attributeName(PhoneNumberIdentifiers.ATTR_PHONE_NUMBER_IDENTIFIER)
|
||||
.build())
|
||||
.provisionedThroughput(ProvisionedThroughput.builder().readCapacityUnits(10L).writeCapacityUnits(10L).build())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
private PhoneNumberIdentifiers phoneNumberIdentifiers;
|
||||
@@ -55,4 +77,14 @@ class PhoneNumberIdentifiersTest {
|
||||
assertEquals(phoneNumberIdentifiers.generatePhoneNumberIdentifierIfNotExists(number),
|
||||
phoneNumberIdentifiers.generatePhoneNumberIdentifierIfNotExists(number));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPhoneNumber() {
|
||||
final String number = "+18005551234";
|
||||
|
||||
assertFalse(phoneNumberIdentifiers.getPhoneNumber(UUID.randomUUID()).isPresent());
|
||||
|
||||
final UUID pni = phoneNumberIdentifiers.getPhoneNumberIdentifier(number);
|
||||
assertEquals(Optional.of(number), phoneNumberIdentifiers.getPhoneNumber(pni));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,13 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -23,8 +22,16 @@ import org.whispersystems.textsecuregcm.redis.RedisClusterExtension;
|
||||
class ReportMessageManagerTest {
|
||||
|
||||
private ReportMessageDynamoDb reportMessageDynamoDb;
|
||||
|
||||
private ReportMessageManager reportMessageManager;
|
||||
|
||||
private String sourceNumber;
|
||||
private UUID sourceAci;
|
||||
private UUID sourcePni;
|
||||
private Account sourceAccount;
|
||||
private UUID messageGuid;
|
||||
private UUID reporterUuid;
|
||||
|
||||
@RegisterExtension
|
||||
static RedisClusterExtension RATE_LIMIT_CLUSTER_EXTENSION = RedisClusterExtension.builder().build();
|
||||
|
||||
@@ -34,77 +41,95 @@ class ReportMessageManagerTest {
|
||||
|
||||
reportMessageManager = new ReportMessageManager(reportMessageDynamoDb,
|
||||
RATE_LIMIT_CLUSTER_EXTENSION.getRedisCluster(), Duration.ofDays(1));
|
||||
|
||||
sourceNumber = "+15105551111";
|
||||
sourceAci = UUID.randomUUID();
|
||||
sourcePni = UUID.randomUUID();
|
||||
messageGuid = UUID.randomUUID();
|
||||
reporterUuid = UUID.randomUUID();
|
||||
|
||||
sourceAccount = mock(Account.class);
|
||||
when(sourceAccount.getUuid()).thenReturn(sourceAci);
|
||||
when(sourceAccount.getNumber()).thenReturn(sourceNumber);
|
||||
when(sourceAccount.getPhoneNumberIdentifier()).thenReturn(sourcePni);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStore() {
|
||||
|
||||
final UUID messageGuid = UUID.randomUUID();
|
||||
final String number = "+15105551111";
|
||||
|
||||
assertDoesNotThrow(() -> reportMessageManager.store(null, messageGuid));
|
||||
assertDoesNotThrow(() -> reportMessageManager.store(null, null, messageGuid));
|
||||
|
||||
verifyNoInteractions(reportMessageDynamoDb);
|
||||
|
||||
reportMessageManager.store(number, messageGuid);
|
||||
reportMessageManager.store(sourceNumber, sourceAci.toString(), messageGuid);
|
||||
|
||||
verify(reportMessageDynamoDb).store(any());
|
||||
verify(reportMessageDynamoDb, times(2)).store(any());
|
||||
|
||||
doThrow(RuntimeException.class)
|
||||
.when(reportMessageDynamoDb).store(any());
|
||||
|
||||
assertDoesNotThrow(() -> reportMessageManager.store(number, messageGuid));
|
||||
assertDoesNotThrow(() -> reportMessageManager.store(sourceNumber, sourceAci.toString(), messageGuid));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReport() {
|
||||
final String sourceNumber = "+15105551111";
|
||||
final UUID messageGuid = UUID.randomUUID();
|
||||
final UUID reporterUuid = UUID.randomUUID();
|
||||
|
||||
final ReportedMessageListener listener = mock(ReportedMessageListener.class);
|
||||
reportMessageManager.addListener(listener);
|
||||
|
||||
when(reportMessageDynamoDb.remove(any())).thenReturn(false);
|
||||
reportMessageManager.report(sourceNumber, messageGuid, reporterUuid);
|
||||
reportMessageManager.report(Optional.of(sourceNumber), Optional.of(sourceAci), Optional.of(sourcePni), messageGuid,
|
||||
reporterUuid);
|
||||
|
||||
assertEquals(0, reportMessageManager.getRecentReportCount(sourceNumber));
|
||||
assertEquals(0, reportMessageManager.getRecentReportCount(sourceAccount));
|
||||
|
||||
when(reportMessageDynamoDb.remove(any())).thenReturn(true);
|
||||
reportMessageManager.report(sourceNumber, messageGuid, reporterUuid);
|
||||
reportMessageManager.report(Optional.of(sourceNumber), Optional.of(sourceAci), Optional.of(sourcePni), messageGuid,
|
||||
reporterUuid);
|
||||
|
||||
assertEquals(1, reportMessageManager.getRecentReportCount(sourceNumber));
|
||||
assertEquals(1, reportMessageManager.getRecentReportCount(sourceAccount));
|
||||
verify(listener).handleMessageReported(sourceNumber, messageGuid, reporterUuid);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportMultipleReporters() {
|
||||
final String sourceNumber = "+15105551111";
|
||||
final UUID messageGuid = UUID.randomUUID();
|
||||
|
||||
when(reportMessageDynamoDb.remove(any())).thenReturn(true);
|
||||
assertEquals(0, reportMessageManager.getRecentReportCount(sourceNumber));
|
||||
assertEquals(0, reportMessageManager.getRecentReportCount(sourceAccount));
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
reportMessageManager.report(sourceNumber, messageGuid, UUID.randomUUID());
|
||||
reportMessageManager.report(Optional.of(sourceNumber), Optional.of(sourceAci), Optional.of(sourcePni),
|
||||
messageGuid, UUID.randomUUID());
|
||||
}
|
||||
|
||||
assertTrue(reportMessageManager.getRecentReportCount(sourceNumber) > 10);
|
||||
assertTrue(reportMessageManager.getRecentReportCount(sourceAccount) > 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportSingleReporter() {
|
||||
final String sourceNumber = "+15105551111";
|
||||
final UUID messageGuid = UUID.randomUUID();
|
||||
final UUID reporterUuid = UUID.randomUUID();
|
||||
|
||||
when(reportMessageDynamoDb.remove(any())).thenReturn(true);
|
||||
assertEquals(0, reportMessageManager.getRecentReportCount(sourceNumber));
|
||||
assertEquals(0, reportMessageManager.getRecentReportCount(sourceAccount));
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
reportMessageManager.report(sourceNumber, messageGuid, reporterUuid);
|
||||
reportMessageManager.report(Optional.of(sourceNumber), Optional.of(sourceAci), Optional.of(sourcePni),
|
||||
messageGuid,
|
||||
reporterUuid);
|
||||
}
|
||||
|
||||
assertEquals(1, reportMessageManager.getRecentReportCount(sourceNumber));
|
||||
assertEquals(1, reportMessageManager.getRecentReportCount(sourceAccount));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReportMultipleReportersByPni() {
|
||||
when(reportMessageDynamoDb.remove(any())).thenReturn(true);
|
||||
assertEquals(0, reportMessageManager.getRecentReportCount(sourceAccount));
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
reportMessageManager.report(Optional.of(sourceNumber), Optional.empty(), Optional.of(sourcePni),
|
||||
messageGuid, UUID.randomUUID());
|
||||
}
|
||||
|
||||
reportMessageManager.report(Optional.empty(), Optional.of(sourceAci), Optional.empty(),
|
||||
messageGuid, UUID.randomUUID());
|
||||
|
||||
final int recentReportCount = reportMessageManager.getRecentReportCount(sourceAccount);
|
||||
assertTrue(recentReportCount > 10);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user