@Test public void testOnlineSend() throws Exception { MessagesManager storedMessages = mock(MessagesManager.class); OutgoingMessageSignal firstMessage = OutgoingMessageSignal.newBuilder() .setMessage(ByteString.copyFrom("first".getBytes())) .setSource("sender1") .setTimestamp(System.currentTimeMillis()) .setSourceDevice(1) .setType(OutgoingMessageSignal.Type.CIPHERTEXT_VALUE) .build(); OutgoingMessageSignal secondMessage = OutgoingMessageSignal.newBuilder() .setMessage(ByteString.copyFrom("second".getBytes())) .setSource("sender2") .setTimestamp(System.currentTimeMillis()) .setSourceDevice(2) .setType(OutgoingMessageSignal.Type.CIPHERTEXT_VALUE) .build(); List<OutgoingMessageEntity> pendingMessages = new LinkedList<>(); when(device.getId()).thenReturn(2L); when(device.getSignalingKey()).thenReturn(Base64.encodeBytes(new byte[52])); when(account.getAuthenticatedDevice()).thenReturn(Optional.of(device)); when(account.getNumber()).thenReturn("+14152222222"); final Device sender1device = mock(Device.class); Set<Device> sender1devices = new HashSet<Device>() { { add(sender1device); } }; Account sender1 = mock(Account.class); when(sender1.getDevices()).thenReturn(sender1devices); when(accountsManager.get("sender1")).thenReturn(Optional.of(sender1)); when(accountsManager.get("sender2")).thenReturn(Optional.<Account>absent()); when(storedMessages.getMessagesForDevice(account.getNumber(), device.getId())) .thenReturn(pendingMessages); final List<SettableFuture<WebSocketResponseMessage>> futures = new LinkedList<>(); final WebSocketClient client = mock(WebSocketClient.class); when(client.sendRequest(eq("PUT"), eq("/api/v1/message"), any(Optional.class))) .thenAnswer( new Answer<SettableFuture<WebSocketResponseMessage>>() { @Override public SettableFuture<WebSocketResponseMessage> answer( InvocationOnMock invocationOnMock) throws Throwable { SettableFuture<WebSocketResponseMessage> future = SettableFuture.create(); futures.add(future); return future; } }); WebsocketAddress websocketAddress = new WebsocketAddress(account.getNumber(), device.getId()); WebSocketConnection connection = new WebSocketConnection(pushSender, receiptSender, storedMessages, account, device, client); connection.onDispatchSubscribed(websocketAddress.serialize()); connection.onDispatchMessage( websocketAddress.serialize(), PubSubProtos.PubSubMessage.newBuilder() .setType(PubSubProtos.PubSubMessage.Type.DELIVER) .setContent(ByteString.copyFrom(firstMessage.toByteArray())) .build() .toByteArray()); connection.onDispatchMessage( websocketAddress.serialize(), PubSubProtos.PubSubMessage.newBuilder() .setType(PubSubProtos.PubSubMessage.Type.DELIVER) .setContent(ByteString.copyFrom(secondMessage.toByteArray())) .build() .toByteArray()); verify(client, times(2)).sendRequest(eq("PUT"), eq("/api/v1/message"), any(Optional.class)); assertEquals(futures.size(), 2); WebSocketResponseMessage response = mock(WebSocketResponseMessage.class); when(response.getStatus()).thenReturn(200); futures.get(1).set(response); futures.get(0).setException(new IOException()); verify(receiptSender, times(1)) .sendReceipt( eq(account), eq("sender2"), eq(secondMessage.getTimestamp()), eq(Optional.<String>absent())); verify(pushSender, times(1)) .sendMessage(eq(account), eq(device), any(OutgoingMessageSignal.class)); connection.onDispatchUnsubscribed(websocketAddress.serialize()); verify(client).close(anyInt(), anyString()); }
@Test public void testOpen() throws Exception { MessagesManager storedMessages = mock(MessagesManager.class); List<OutgoingMessageEntity> outgoingMessages = new LinkedList<OutgoingMessageEntity>() { { add(createMessage(1L, "sender1", 1111, false, "first")); add(createMessage(2L, "sender1", 2222, false, "second")); add(createMessage(3L, "sender2", 3333, false, "third")); } }; when(device.getId()).thenReturn(2L); when(device.getSignalingKey()).thenReturn(Base64.encodeBytes(new byte[52])); when(account.getAuthenticatedDevice()).thenReturn(Optional.of(device)); when(account.getNumber()).thenReturn("+14152222222"); final Device sender1device = mock(Device.class); Set<Device> sender1devices = new HashSet<Device>() { { add(sender1device); } }; Account sender1 = mock(Account.class); when(sender1.getDevices()).thenReturn(sender1devices); when(accountsManager.get("sender1")).thenReturn(Optional.of(sender1)); when(accountsManager.get("sender2")).thenReturn(Optional.<Account>absent()); when(storedMessages.getMessagesForDevice(account.getNumber(), device.getId())) .thenReturn(outgoingMessages); final List<SettableFuture<WebSocketResponseMessage>> futures = new LinkedList<>(); final WebSocketClient client = mock(WebSocketClient.class); when(client.sendRequest(eq("PUT"), eq("/api/v1/message"), any(Optional.class))) .thenAnswer( new Answer<SettableFuture<WebSocketResponseMessage>>() { @Override public SettableFuture<WebSocketResponseMessage> answer( InvocationOnMock invocationOnMock) throws Throwable { SettableFuture<WebSocketResponseMessage> future = SettableFuture.create(); futures.add(future); return future; } }); WebsocketAddress websocketAddress = new WebsocketAddress(account.getNumber(), device.getId()); WebSocketConnection connection = new WebSocketConnection(pushSender, receiptSender, storedMessages, account, device, client); connection.onDispatchSubscribed(websocketAddress.serialize()); verify(client, times(3)).sendRequest(eq("PUT"), eq("/api/v1/message"), any(Optional.class)); assertTrue(futures.size() == 3); WebSocketResponseMessage response = mock(WebSocketResponseMessage.class); when(response.getStatus()).thenReturn(200); futures.get(1).set(response); futures.get(0).setException(new IOException()); futures.get(2).setException(new IOException()); verify(storedMessages, times(1)).delete(eq(account.getNumber()), eq(2L)); verify(receiptSender, times(1)) .sendReceipt(eq(account), eq("sender1"), eq(2222L), eq(Optional.<String>absent())); connection.onDispatchUnsubscribed(websocketAddress.serialize()); verify(client).close(anyInt(), anyString()); }