package io.mangoo.managers;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketClient;
import org.eclipse.jetty.websocket.WebSocketClientFactory;
import org.junit.Test;
import org.mockito.Mockito;
import io.mangoo.configuration.Config;
import io.mangoo.core.Application;
import io.undertow.websockets.core.WebSocketChannel;
import io.undertow.websockets.core.WebSockets;
/**
*
* @author svenkubiak
*
*/
public class WebSocketManagerTest {
private static String eventData;
private static final String COOKIE_NAME = "TEST-AUTH";
private static final String VALID_COOKIE_VALUE = "3372c6783fa8d223c700e9903b4e8037db710b4b60ee2ca129465fa0a12e0a0b1860019962ae04e4b329e4da03ce09eb347c97b5598085cc8530213b9b82f91f|2999-11-11T11:11:11.111|0#mangooio";
private static final String INVALID_COOKIE_VALUE = "3372c6783fa8d223c700e9903b4e8037db710b4b60ee2ca129465fa0a12e0a0b1860019962ae04e4b329e4da03ce09eb347c97b5598085cc8530213b9b82f91f|2999-11-11T11:11:11.111|0#mangooiO";
@Test
public void testAddChannel() {
//given
final WebSocketManager webSocketManager = Application.getInstance(WebSocketManager.class);
final WebSocketChannel channel = Mockito.mock(WebSocketChannel.class);
when(channel.getUrl()).thenReturn("/websocket");
//when
webSocketManager.removeChannels("/websocket");
webSocketManager.addChannel(channel);
//then
assertThat(webSocketManager.getChannels("/websocket"), not(nullValue()));
assertThat(webSocketManager.getChannels("/websocket").size(), equalTo(1));
}
@Test
public void testRemoveChannel() {
//given
final WebSocketManager webSocketManager = Application.getInstance(WebSocketManager.class);
final WebSocketChannel channel = Mockito.mock(WebSocketChannel.class);
when(channel.getUrl()).thenReturn("/websocket");
//when
webSocketManager.addChannel(channel);
webSocketManager.removeChannels("/websocket");
//then
assertThat(webSocketManager.getChannels("/websocket"), not(nullValue()));
assertThat(webSocketManager.getChannels("/websocket").size(), equalTo(0));
}
@Test
public void testCloseChannel() throws Exception {
//given
final Config config = Application.getInstance(Config.class);
final WebSocketManager webSocketManager = Application.getInstance(WebSocketManager.class);
webSocketManager.removeChannels("/websocket");
final WebSocketClientFactory factory = new WebSocketClientFactory();
factory.start();
final String url = "ws://" + config.getConnectorHttpHost() + ":" + config.getConnectorHttpPort() + "/websocket";
//when
final WebSocketClient client = new WebSocketClient(factory);
client.open(new URI(url), new WebSocket.OnTextMessage() {
@Override
public void onOpen(Connection connection) {
// intentionally left blank
}
@Override
public void onClose(int closeCode, String message) {
// intentionally left blank
}
@Override
public void onMessage(String data) {
// intentionally left blank
}
}).get(5, TimeUnit.SECONDS);
webSocketManager.close("/websocket");
//then
assertThat(webSocketManager.getChannels("/websocket"), not(nullValue()));
assertThat(webSocketManager.getChannels("/websocket").size(), equalTo(0));
}
@Test
public void testSendData() throws Exception {
//given
final Config config = Application.getInstance(Config.class);
final WebSocketManager webSocketManager = Application.getInstance(WebSocketManager.class);
webSocketManager.removeChannels("/websocket");
final WebSocketClientFactory factory = new WebSocketClientFactory();
factory.start();
final String url = "ws://" + config.getConnectorHttpHost() + ":" + config.getConnectorHttpPort() + "/websocket";
final String data = "Server sent data FTW!";
eventData = null;
//when
new WebSocketClient(factory).open(new URI(url), new WebSocket.OnTextMessage() {
@Override
public void onOpen(Connection connection) {
// intentionally left blank
}
@Override
public void onClose(int closeCode, String message) {
// intentionally left blank
}
@Override
public void onMessage(String data) {
eventData = data;
}
}).get(5, TimeUnit.SECONDS);
Thread.sleep(500);
webSocketManager.getChannels("/websocket").forEach(channel -> {
try {
if (channel.isOpen()) {
WebSockets.sendTextBlocking(data, channel);
}
} catch (final IOException e) {
e.printStackTrace();
}
});
Thread.sleep(500);
//then
assertThat(eventData, not(nullValue()));
assertThat(eventData, equalTo(data));
}
@Test
public void testSendDataWithValidAuthentication() throws Exception {
//given
final WebSocketManager webSocketManager = Application.getInstance(WebSocketManager.class);
final Config config = Application.getInstance(Config.class);
webSocketManager.removeChannels("/websocketauth");
final WebSocketClientFactory factory = new WebSocketClientFactory();
factory.start();
final String url = "ws://" + config.getConnectorHttpHost() + ":" + config.getConnectorHttpPort() + "/websocketauth";
final String data = "Server sent data with authentication FTW!";
eventData = null;
//when
final WebSocketClient client = new WebSocketClient(factory);
client.getCookies().put(COOKIE_NAME, VALID_COOKIE_VALUE);
client.open(new URI(url), new WebSocket.OnTextMessage() {
@Override
public void onOpen(Connection connection) {
// intentionally left blank
}
@Override
public void onClose(int closeCode, String message) {
// intentionally left blank
}
@Override
public void onMessage(String data) {
if (StringUtils.isBlank(eventData)) {
eventData = data;
}
}
}).get(5, TimeUnit.SECONDS);
Thread.sleep(500);
webSocketManager.getChannels("/websocketauth").forEach(channel -> {
try {
if (channel.isOpen()) {
WebSockets.sendTextBlocking(data, channel);
}
} catch (final IOException e) {
e.printStackTrace();
}
});
Thread.sleep(500);
//then
assertThat(eventData, not(nullValue()));
assertThat(eventData, equalTo(data));
}
@Test
public void testSendDataWithInvalidAuthentication() throws Exception {
//given
final WebSocketManager webSocketManager = Application.getInstance(WebSocketManager.class);
final Config config = Application.getInstance(Config.class);
webSocketManager.removeChannels("/websocketauth");
final WebSocketClientFactory factory = new WebSocketClientFactory();
factory.start();
final String url = "ws://" + config.getConnectorHttpHost() + ":" + config.getConnectorHttpPort() + "/websocketauth";
final String data = "Server sent data with authentication FTW!";
eventData = null;
//when
final WebSocketClient client = new WebSocketClient(factory);
client.getCookies().put(COOKIE_NAME, INVALID_COOKIE_VALUE);
client.open(new URI(url), new WebSocket.OnTextMessage() {
@Override
public void onOpen(Connection connection) {
// intentionally left blank
}
@Override
public void onClose(int closeCode, String message) {
// intentionally left blank
}
@Override
public void onMessage(String data) {
if (StringUtils.isBlank(eventData)) {
eventData = data;
}
}
}).get(5, TimeUnit.SECONDS);
Thread.sleep(500);
webSocketManager.getChannels(url).forEach(channel -> {
try {
if (channel.isOpen()) {
WebSockets.sendTextBlocking(data, channel);
}
} catch (final IOException e) {
e.printStackTrace();
}
});
Thread.sleep(500);
//then
assertThat(eventData, nullValue());
assertThat(eventData, not(equalTo(data)));
}
}