/* * Copyright 2012 Jason Miller * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jj.http.server.websocket; import static org.hamcrest.Matchers.is; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import jj.engine.HostEvent; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame; import io.netty.handler.codec.http.websocketx.PingWebSocketFrame; import io.netty.handler.codec.http.websocketx.PongWebSocketFrame; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; /** * @author jason * */ @RunWith(MockitoJUnitRunner.class) public class WebSocketFrameHandlerTest { @Mock WebSocketServerHandshaker handshaker; @Mock WebSocketConnection connection; @Mock WebSocketConnectionHost webSocketConnectionHost; @Mock WebSocketConnectionTracker connectionTracker; @Mock ConnectionEventExecutor executor; @InjectMocks WebSocketFrameHandler wsfh; // don't mock things you don't own! // unless, as in this case, the things you don't // own won't work without talking to an actual resource @Mock(answer=Answers.RETURNS_DEEP_STUBS) ChannelHandlerContext ctx; @Captor ArgumentCaptor<GenericFutureListener<Future<Void>>> futureListenerCaptor; ChannelFuture future; ByteBuf byteBuf; @Captor ArgumentCaptor<TextWebSocketFrame> textFrameCaptor; @Captor ArgumentCaptor<PongWebSocketFrame> pongFrameCaptor; @Before public void before() { byteBuf = Unpooled.buffer(0); willReturn(webSocketConnectionHost).given(connection).webSocketConnectionHost(); } @Test public void testHandlerAdded() throws Exception { wsfh.handlerAdded(ctx); verify(connectionTracker).addConnection(connection); verify(webSocketConnectionHost).connected(connection); verify(executor).submit(connection, HostEvent.clientConnected.toString(), connection); verify(ctx.channel().closeFuture()).addListener(futureListenerCaptor.capture()); futureListenerCaptor.getValue().operationComplete(future); verify(connectionTracker).removeConnection(connection); verify(webSocketConnectionHost).disconnected(connection); verify(executor).submit(connection, HostEvent.clientDisconnected.toString(), connection); } @Test public void testTextFrame() throws Exception { String text = "text"; TextWebSocketFrame textFrame = new TextWebSocketFrame(text); wsfh.channelRead0(ctx, textFrame); verify(connection).markActivity(); verify(webSocketConnectionHost).message(connection, text); } @Test public void testHeartbeatTextFrame() throws Exception { TextWebSocketFrame textFrame = new TextWebSocketFrame("jj-hi"); wsfh.channelRead0(ctx, textFrame); verify(connection).markActivity(); verifyZeroInteractions(executor); verify(ctx).writeAndFlush(textFrameCaptor.capture()); assertThat(textFrameCaptor.getValue().text(), is("jj-yo")); } @Test public void testPingFrame() throws Exception { PingWebSocketFrame pingFrame = new PingWebSocketFrame(byteBuf); wsfh.channelRead0(ctx, pingFrame); verify(connection).markActivity(); verify(ctx).writeAndFlush(pongFrameCaptor.capture()); PongWebSocketFrame pongFrame2 = pongFrameCaptor.getValue().retain(); assertThat(pongFrame2.content(), is(byteBuf)); } @Test public void testPongFrame() throws Exception { PongWebSocketFrame pongFrame = new PongWebSocketFrame(byteBuf); wsfh.channelRead0(ctx, pongFrame); verify(connection).markActivity(); //verify(handler).ponged(connection, byteBuf); } @Test public void testBinaryFrame() throws Exception { BinaryWebSocketFrame binaryFrame = new BinaryWebSocketFrame(byteBuf); wsfh.channelRead0(ctx, binaryFrame); verify(connection).markActivity(); //verify(handler).messageReceived(connection, byteBuf); } @Test public void testCloseFrame() throws Exception { CloseWebSocketFrame closeFrame = new CloseWebSocketFrame(1000, ""); wsfh.channelRead0(ctx, closeFrame); verify(handshaker).close(ctx.channel(), closeFrame); } }