/* * Copyright 2015 Netflix, Inc. * * 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 io.reactivex.netty.protocol.http.sse.client; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.logging.LoggingHandler; import io.reactivex.netty.protocol.http.sse.ServerSentEvent; import io.reactivex.netty.protocol.http.sse.ServerSentEvent.Type; import org.junit.Test; import java.util.ArrayList; import java.util.List; import static io.reactivex.netty.protocol.http.sse.SseTestUtil.*; import static org.junit.Assert.*; public class ServerSentEventDecoderTest { private final ServerSentEventDecoder decoder = new ServerSentEventDecoder(); private final ChannelHandlerContext ch = new EmbeddedChannel(new LoggingHandler()).pipeline().firstContext(); @Test(timeout = 60000) public void testOneDataLineDecode() throws Exception { String eventType = "add"; String eventId = "1"; String data = "data line"; ServerSentEvent expected = newServerSentEvent(eventType, eventId, data); doTest(newSseProtocolString(eventType, eventId, data), expected); } @Test(timeout = 60000) public void testMultipleDataLineDecode() throws Exception { String eventType = "add"; String eventId = "1"; String data1 = "data line"; String data2 = "data line"; ServerSentEvent expected1 = newServerSentEvent(eventType, eventId, data1); ServerSentEvent expected2 = newServerSentEvent(eventType, eventId, data2); doTest(newSseProtocolString(eventType, eventId, data1, data2), expected1, expected2); } @Test(timeout = 60000) public void testEventWithNoIdDecode() throws Exception { String eventType = "add"; String data = "data line"; ServerSentEvent expected = newServerSentEvent(eventType, null, data); doTest(newSseProtocolString(eventType, null, data), expected); } @Test(timeout = 60000) public void testEventWithNoEventTypeDecode() throws Exception { String eventId = "1"; String data = "data line"; ServerSentEvent expected = newServerSentEvent(null, eventId, data); doTest(newSseProtocolString(null, eventId, data), expected); } @Test(timeout = 60000) public void testEventWithDataOnlyDecode() throws Exception { String data = "data line"; ServerSentEvent expected = newServerSentEvent(null, null, data); doTest(newSseProtocolString(null, null, data), expected); } @Test(timeout = 60000) public void testResetEventType() throws Exception { String eventType = "add"; String eventId = "1"; String data1 = "data line"; String data2 = "data line"; ServerSentEvent expected1 = newServerSentEvent(eventType, eventId, data1); ServerSentEvent expected2 = newServerSentEvent(null, eventId, data2); doTest(newSseProtocolString(eventType, eventId, data1) + newSseProtocolString("", null, data2), expected1, expected2); } @Test(timeout = 60000) public void testResetEventId() throws Exception { String eventType = "add"; String eventId = "1"; String data1 = "data line"; String data2 = "data line"; ServerSentEvent expected1 = newServerSentEvent(eventType, eventId, data1); ServerSentEvent expected2 = newServerSentEvent(eventType, null, data2); doTest(newSseProtocolString(eventType, eventId, data1) + newSseProtocolString(null, "", data2), expected1, expected2); } @Test(timeout = 60000) public void testIncompleteEventId() throws Exception { List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("id: 111"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); ServerSentEvent expected = newServerSentEvent(null, "1111", "data line"); doTest("1\ndata: data line\n", expected); } @Test(timeout = 60000) public void testIncompleteEventType() throws Exception { List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("event: ad"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); ServerSentEvent expected = newServerSentEvent("add", null, "data line"); doTest("d\ndata: data line\n", expected); } @Test(timeout = 60000) public void testIncompleteEventData() throws Exception { ServerSentEvent expected = newServerSentEvent("add", null, "data line"); List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("event: add\n"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); decoder.decode(ch, toHttpContent("data: d"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); doTest("ata line\n", expected); } @Test(timeout = 60000) public void testIncompleteFieldName() throws Exception { ServerSentEvent expected = newServerSentEvent("add", null, "data line"); List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("ev"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); decoder.decode(ch, toHttpContent("ent: add\n d"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); doTest("ata: data line\n", expected); } @Test(timeout = 60000) public void testInvalidFieldNameAndNextEvent() throws Exception { ArrayList<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("event: event type\n"), out); assertTrue("Output list not empty.", out.isEmpty()); decoder.decode(ch, toHttpContent("data: dumb \n"), out); assertFalse("Event not emitted after invalid field name.", out.isEmpty()); assertEquals("Unexpected event count after invalid field name.", 1, out.size()); } @Test(timeout = 60000) public void testInvalidFieldName() throws Throwable { ArrayList<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("event: dumb \n"), out); assertTrue("Event emitted for invalid field name.", out.isEmpty()); } @Test(timeout = 60000) public void testFieldNameWithSpace() throws Throwable { ArrayList<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("eve nt: dumb \n"), new ArrayList<>()); assertTrue("Event emitted for invalid field name.", out.isEmpty()); } @Test(timeout = 60000) public void testDataInMultipleChunks() throws Exception { ServerSentEvent expected = newServerSentEvent(null, null, "data line"); List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("da"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); decoder.decode(ch, toHttpContent("ta: d"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); decoder.decode(ch, toHttpContent("ata"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); decoder.decode(ch, toHttpContent(" "), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); decoder.decode(ch, toHttpContent("li"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); decoder.decode(ch, toHttpContent("ne"), out); assertEquals("Unexpected number of decoded messages.", 0, out.size()); doTest("\n", expected); } @Test(timeout = 10000) public void testLeadingNewLineInFieldName() throws Exception { List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent("\n data: ad\n"), out); assertEquals("Unexpected number of decoded messages.", 1, out.size()); } @Test(timeout = 10000) public void testLeadingSpaceInFieldName() throws Exception { List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent(" data: ad\n"), out); assertEquals("Unexpected number of decoded messages.", 1, out.size()); ServerSentEvent event = (ServerSentEvent) out.get(0); assertEquals("Unexpected event type.", Type.Data, event.getType()); assertEquals("Unexpected event type.", "ad", event.contentAsString()); } private void doTest(String eventText, ServerSentEvent... expected) throws Exception { List<Object> out = new ArrayList<>(); decoder.decode(ch, toHttpContent(eventText), out); assertEquals(expected.length, out.size()); for (int i = 0; i < out.size(); i++) { ServerSentEvent event = (ServerSentEvent) out.get(i); assertContentEquals("Unexpected SSE data", expected[i].content(), event.content()); assertContentEquals("Unexpected SSE event type", expected[i].getEventType(), event.getEventType()); assertContentEquals("Unexpected SSE event id", expected[i].getEventId(), event.getEventId()); } } }