/*
* Copyright 2014 The Netty Project
*
* The Netty Project licenses this file to you 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.netty.handler.codec.json;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.CorruptedFrameException;
import io.netty.handler.codec.TooLongFrameException;
import io.netty.util.CharsetUtil;
import org.junit.Test;
import static org.junit.Assert.*;
public class JsonObjectDecoderTest {
@Test
public void testJsonObjectOverMultipleWrites() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
String objectPart1 = "{ \"firstname\": \"John";
String objectPart2 = "\" ,\n \"surname\" :";
String objectPart3 = "\"Doe\", age:22 \n}";
// Test object
ch.writeInbound(Unpooled.copiedBuffer(" \n\n " + objectPart1, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(objectPart2, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(objectPart3 + " \n\n \n", CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(objectPart1 + objectPart2 + objectPart3, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testJsonArrayOverMultipleWrites() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
String arrayPart1 = "[{\"test";
String arrayPart2 = "case\" : \"\\\"}]Escaped dou\\\"ble quotes \\\" in JSON str\\\"ing\"";
String arrayPart3 = " }\n\n , ";
String arrayPart4 = "{\"testcase\" : \"Streaming string me";
String arrayPart5 = "ssage\"} ]";
// Test array
ch.writeInbound(Unpooled.copiedBuffer(" " + arrayPart1, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(arrayPart2, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(arrayPart3, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(arrayPart4, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(arrayPart5 + " ", CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(arrayPart1 + arrayPart2 + arrayPart3 + arrayPart4 + arrayPart5, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testSingleByteStream() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
String json = "{\"foo\" : {\"bar\" : [{},{}]}}";
for (byte c : json.getBytes(CharsetUtil.UTF_8)) {
ch.writeInbound(Unpooled.copiedBuffer(new byte[] {c}));
}
ByteBuf res = ch.readInbound();
assertEquals(json, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testBackslashInString1() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
// {"foo" : "bar\""}
String json = "{\"foo\" : \"bar\\\"\"}";
System.out.println(json);
ch.writeInbound(Unpooled.copiedBuffer(json, CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(json, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testBackslashInString2() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
// {"foo" : "bar\\"}
String json = "{\"foo\" : \"bar\\\\\"}";
System.out.println(json);
ch.writeInbound(Unpooled.copiedBuffer(json, CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(json, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testBackslashInString3() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
// {"foo" : "bar\\\""}
String json = "{\"foo\" : \"bar\\\\\\\"\"}";
System.out.println(json);
ch.writeInbound(Unpooled.copiedBuffer(json, CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(json, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testMultipleJsonObjectsInOneWrite() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
String object1 = "{\"key\" : \"value1\"}",
object2 = "{\"key\" : \"value2\"}",
object3 = "{\"key\" : \"value3\"}";
ch.writeInbound(Unpooled.copiedBuffer(object1 + object2 + object3, CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(object1, res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals(object2, res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals(object3, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test(expected = CorruptedFrameException.class)
public void testNonJsonContent1() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
try {
ch.writeInbound(Unpooled.copiedBuffer(" b [1,2,3]", CharsetUtil.UTF_8));
} finally {
assertFalse(ch.finish());
}
fail();
}
@Test(expected = CorruptedFrameException.class)
public void testNonJsonContent2() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
ch.writeInbound(Unpooled.copiedBuffer(" [1,2,3] ", CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals("[1,2,3]", res.toString(CharsetUtil.UTF_8));
res.release();
try {
ch.writeInbound(Unpooled.copiedBuffer(" a {\"key\" : 10}", CharsetUtil.UTF_8));
} finally {
assertFalse(ch.finish());
}
fail();
}
@Test (expected = TooLongFrameException.class)
public void testMaxObjectLength() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder(6));
try {
ch.writeInbound(Unpooled.copiedBuffer("[2,4,5]", CharsetUtil.UTF_8));
} finally {
assertFalse(ch.finish());
}
fail();
}
@Test
public void testOneJsonObjectPerWrite() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
String object1 = "{\"key\" : \"value1\"}",
object2 = "{\"key\" : \"value2\"}",
object3 = "{\"key\" : \"value3\"}";
ch.writeInbound(Unpooled.copiedBuffer(object1, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(object2, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(object3, CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(object1, res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals(object2, res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals(object3, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testSpecialJsonCharsInString() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
String object = "{ \"key\" : \"[]{}}\\\"}}'}\"}";
ch.writeInbound(Unpooled.copiedBuffer(object, CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals(object, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testStreamArrayElementsSimple() {
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder(Integer.MAX_VALUE, true));
String array = "[ 12, \"bla\" , 13.4 \t ,{\"key0\" : [1,2], \"key1\" : 12, \"key2\" : {}} , " +
"true, false, null, [\"bla\", {}, [1,2,3]] ]";
String object = "{\"bla\" : \"blub\"}";
ch.writeInbound(Unpooled.copiedBuffer(array, CharsetUtil.UTF_8));
ch.writeInbound(Unpooled.copiedBuffer(object, CharsetUtil.UTF_8));
ByteBuf res = ch.readInbound();
assertEquals("12", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("\"bla\"", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("13.4", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("{\"key0\" : [1,2], \"key1\" : 12, \"key2\" : {}}", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("true", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("false", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("null", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals("[\"bla\", {}, [1,2,3]]", res.toString(CharsetUtil.UTF_8));
res.release();
res = ch.readInbound();
assertEquals(object, res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
@Test
public void testCorruptedFrameException() {
final String part1 = "{\"a\":{\"b\":{\"c\":{ \"d\":\"27301\", \"med\":\"d\", \"path\":\"27310\"} }," +
" \"status\":\"OK\" } }{\"";
final String part2 = "a\":{\"b\":{\"c\":{\"ory\":[{\"competi\":[{\"event\":[{" + "\"externalI\":{\"external\"" +
":[{\"id\":\"O\"} ]";
EmbeddedChannel ch = new EmbeddedChannel(new JsonObjectDecoder());
ByteBuf res;
ch.writeInbound(Unpooled.copiedBuffer(part1, CharsetUtil.UTF_8));
res = ch.readInbound();
assertEquals("{\"a\":{\"b\":{\"c\":{ \"d\":\"27301\", \"med\":\"d\", \"path\":\"27310\"} }, " +
"\"status\":\"OK\" } }", res.toString(CharsetUtil.UTF_8));
res.release();
ch.writeInbound(Unpooled.copiedBuffer(part2, CharsetUtil.UTF_8));
res = ch.readInbound();
assertNull(res);
ch.writeInbound(Unpooled.copiedBuffer("}}]}]}]}}}}", CharsetUtil.UTF_8));
res = ch.readInbound();
assertEquals("{\"a\":{\"b\":{\"c\":{\"ory\":[{\"competi\":[{\"event\":[{" + "\"externalI\":{" +
"\"external\":[{\"id\":\"O\"} ]}}]}]}]}}}}", res.toString(CharsetUtil.UTF_8));
res.release();
assertFalse(ch.finish());
}
}