WebSocketFrameEncoder extends ChannelOutboundHandlerAdapter { @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { if (msg instanceof ByteBuf) { writeContinuationFrame(ctx, (ByteBuf) msg, promise); } else { super.write(ctx, msg, promise); } } WebSocketFrameEncoder(int maxFramePayloadLength); @Override void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise);  }
@Test public void testWriteNonByteBuf() throws Exception { Object msg = "Not a ByteBuf"; spy.write(ctx, msg, promise); verify(spy).write(ctx, msg, promise); verify(ctx).write(msg, promise); verifyNoMoreInteractions(spy, ctx); verifyZeroInteractions(promise); }
@Test public void testWriteReleaseBuffer() throws Exception { String content = "Buffer should be released"; int utf8Bytes = ByteBufUtil.utf8Bytes(content); ByteBuf msg = Unpooled.directBuffer(utf8Bytes); ByteBufUtil.reserveAndWriteUtf8(msg, content, utf8Bytes); ArgumentCaptor<WebSocketFrame> frameCaptor = ArgumentCaptor.forClass(WebSocketFrame.class); spy.write(ctx, msg, promise); assertEquals(0, msg.refCnt()); assertEquals(0, msg.readableBytes()); verify(ctx).writeAndFlush(frameCaptor.capture(), eq(promise)); WebSocketFrame frame = frameCaptor.getValue(); assertTrue(frame instanceof BinaryWebSocketFrame); assertTrue(frame.isFinalFragment()); assertEquals(content, frame.content().toString(StandardCharsets.UTF_8)); }
@Test public void testWriteSingleFrame() throws Exception { String content = "Content MSG length less than max frame payload length: " + maxFramePayloadLength; ByteBuf msg = Unpooled.copiedBuffer(content, StandardCharsets.UTF_8); ArgumentCaptor<WebSocketFrame> frameCaptor = ArgumentCaptor.forClass(WebSocketFrame.class); spy.write(ctx, msg, promise); assertEquals(0, msg.readableBytes()); verify(ctx).writeAndFlush(frameCaptor.capture(), eq(promise)); WebSocketFrame frame = frameCaptor.getValue(); assertTrue(frame instanceof BinaryWebSocketFrame); assertTrue(frame.isFinalFragment()); assertEquals(content, frame.content().toString(StandardCharsets.UTF_8)); }
@Test public void testWriteContinuationFrames() throws Exception { String contentPart = "Content MSG Length @ "; StringBuilder contentBuilder = new StringBuilder(3 * maxFramePayloadLength); while (contentBuilder.length() < 2 * maxFramePayloadLength) { contentBuilder.append(contentPart); contentBuilder.append(contentBuilder.length()); contentBuilder.append('\n'); } String content = contentBuilder.toString(); int length = content.length(); assertTrue(length > 2 * maxFramePayloadLength); ByteBuf msg = Unpooled.copiedBuffer(content, StandardCharsets.UTF_8); ArgumentCaptor<WebSocketFrame> frameCaptor = ArgumentCaptor.forClass(WebSocketFrame.class); spy.write(ctx, msg, promise); assertEquals(0, msg.readableBytes()); verify(spy).write(ctx, msg, promise); verify(ctx, times(3)).writeAndFlush(frameCaptor.capture(), eq(promise)); List<WebSocketFrame> frames = frameCaptor.getAllValues(); assertEquals(3, frames.size()); int offset = 0; WebSocketFrame first = frames.get(0); assertTrue(first instanceof BinaryWebSocketFrame); assertFalse(first.isFinalFragment()); assertEquals(content.substring(offset, offset + maxFramePayloadLength), first.content().toString(StandardCharsets.UTF_8)); offset += maxFramePayloadLength; WebSocketFrame second = frames.get(1); assertTrue(second instanceof ContinuationWebSocketFrame); assertFalse(second.isFinalFragment()); assertEquals(content.substring(offset, offset + maxFramePayloadLength), second.content().toString(StandardCharsets.UTF_8)); offset += maxFramePayloadLength; WebSocketFrame last = frames.get(2); assertTrue(last instanceof ContinuationWebSocketFrame); assertTrue(last.isFinalFragment()); assertEquals(content.substring(offset), last.content().toString(StandardCharsets.UTF_8)); verifyNoMoreInteractions(spy, ctx); verifyZeroInteractions(promise); }