/******************************************************************************* * Copyright (c) 2012-2016 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.everrest.core.impl.provider; import com.google.common.collect.ImmutableMap; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; import org.everrest.core.impl.MultivaluedMapImpl; import org.everrest.core.impl.provider.json.DoubleValue; import org.everrest.core.impl.provider.json.JsonTransient; import org.everrest.core.impl.provider.json.JsonValue; import org.everrest.core.impl.provider.json.LongValue; import org.everrest.core.impl.provider.json.ObjectValue; import org.everrest.core.impl.provider.json.StringValue; import org.everrest.core.impl.provider.json.tst.Book; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import javax.activation.DataSource; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.StreamingOutput; import javax.xml.bind.JAXBElement; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.stream.StreamSource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; import java.lang.reflect.Type; import java.util.List; import java.util.Map; import static com.google.common.collect.Lists.newArrayList; import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; import static org.everrest.core.impl.provider.json.tst.Book.createJunitBook; import static org.everrest.core.util.ParameterizedTypeImpl.newParameterizedType; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @SuppressWarnings({"unchecked"}) @RunWith(DataProviderRunner.class) public class JsonEntityProviderTest { private JsonEntityProvider jsonEntityProvider; @Before public void setUp() throws Exception { jsonEntityProvider = new JsonEntityProvider(); } @Test public void isReadableForAnyType() throws Exception { assertTrue(jsonEntityProvider.isReadable(Object.class, null, null, null)); } @Test public void isWriteableForAnyType() throws Exception { assertTrue(jsonEntityProvider.isWriteable(Object.class, null, null, null)); } @DataProvider public static Object[][] ignoresTypesData() { return new Object[][]{ {byte[].class}, {char[].class}, {DataSource.class}, {DOMSource.class}, {File.class}, {InputStream.class}, {OutputStream.class}, {JAXBElement.class}, {MultivaluedMap.class}, {Reader.class}, {Writer.class}, {SAXSource.class}, {StreamingOutput.class}, {StreamSource.class}, {String.class}, {JsonTransientAnnotated.class} }; } @JsonTransient public static class JsonTransientAnnotated { } @UseDataProvider("ignoresTypesData") @Test public void isNotReadableForTypesSupportedByOtherProviders(Class<?> aClass) throws Exception { assertFalse(jsonEntityProvider.isReadable(aClass, null, null, null)); } @UseDataProvider("ignoresTypesData") @Test public void isNotWriteableForTypesSupportedByOtherProviders(Class<?> aClass) throws Exception { assertFalse(jsonEntityProvider.isWriteable(aClass, null, null, null)); } @Test public void readsContentOfEntityStreamAsJsonValue() throws Exception { String content = "{\"title\": \"JUnit in Action\", \"pages\": 386, \"isdn\": 93011099534534, \"price\": 19.37, \"author\": \"Vincent Massol\"}"; JsonValue result = (JsonValue)jsonEntityProvider.readFrom(JsonValue.class, null, null, APPLICATION_JSON_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(content.getBytes())); assertEquals("Vincent Massol", result.getElement("author").getStringValue()); assertEquals("JUnit in Action", result.getElement("title").getStringValue()); assertEquals(386, result.getElement("pages").getIntValue()); assertEquals(19.37, result.getElement("price").getNumberValue()); assertEquals(93011099534534L, result.getElement("isdn").getLongValue()); } @Test public void readsContentOfEntityStreamAsObject() throws Exception { String content = "{\"title\": \"JUnit in Action\", \"pages\": 386, \"isdn\": 93011099534534, \"price\": 19.37, \"author\": \"Vincent Massol\"}"; Book result = (Book)jsonEntityProvider.readFrom(Book.class, null, null, APPLICATION_JSON_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(content.getBytes())); assertEquals("Vincent Massol", result.getAuthor()); assertEquals("JUnit in Action", result.getTitle()); assertEquals(386, result.getPages()); assertEquals(19.37, result.getPrice(), 0.01); assertEquals(93011099534534L, result.getIsdn()); } @Test public void readsContentOfEntityStreamAsMapStringToObject() throws Exception { String content = "{\"book\": {\"title\": \"JUnit in Action\", \"pages\": 386, \"isdn\": 93011099534534, \"price\": 19.37, \"author\": \"Vincent Massol\"}}"; Class aClass = Map.class; Type genericType = newParameterizedType(aClass, String.class, Book.class); Map<String, Book> result = (Map<String, Book>)jsonEntityProvider.readFrom(aClass, genericType, null, APPLICATION_JSON_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(content.getBytes())); assertEquals(1, result.size()); assertNotNull(result.get("book")); Book book = result.get("book"); assertEquals("Vincent Massol", book.getAuthor()); assertEquals("JUnit in Action", book.getTitle()); assertEquals(386, book.getPages()); assertEquals(19.37, book.getPrice(), 0.01); assertEquals(93011099534534L, book.getIsdn()); } @Test public void readsContentOfEntityStreamAsCollectionOfObjects() throws Exception { String content = "[{\"title\": \"JUnit in Action\", \"pages\": 386, \"isdn\": 93011099534534, \"price\": 19.37, \"author\": \"Vincent Massol\"}]"; Class aClass = List.class; Type genericType = newParameterizedType(aClass, Book.class); List<Book> result = (List<Book>)jsonEntityProvider.readFrom(aClass, genericType, null, APPLICATION_JSON_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(content.getBytes())); assertEquals(1, result.size()); Book book = result.get(0); assertEquals("Vincent Massol", book.getAuthor()); assertEquals("JUnit in Action", book.getTitle()); assertEquals(386, book.getPages()); assertEquals(19.37, book.getPrice(), 0.01); assertEquals(93011099534534L, book.getIsdn()); } @Test public void readsContentOfEntityStreamAsArrayOfObjects() throws Exception { String content = "[{\"title\": \"JUnit in Action\", \"pages\": 386, \"isdn\": 93011099534534, \"price\": 19.37, \"author\": \"Vincent Massol\"}]"; Class aClass = Book[].class; Book[] result = (Book[])jsonEntityProvider.readFrom(aClass, null, null, APPLICATION_JSON_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(content.getBytes())); assertEquals(1, result.length); Book book = result[0]; assertEquals("Vincent Massol", book.getAuthor()); assertEquals("JUnit in Action", book.getTitle()); assertEquals(386, book.getPages()); assertEquals(19.37, book.getPrice(), 0.01); assertEquals(93011099534534L, book.getIsdn()); } @Test(expected = IOException.class) public void throwsIOExceptionWhenParsingFailed() throws Exception { String invalidContent = "\"title\": \"JUnit in Action\"}"; jsonEntityProvider.readFrom(Book.class, null, null, APPLICATION_JSON_TYPE, new MultivaluedMapImpl(), new ByteArrayInputStream(invalidContent.getBytes())); } @Test public void writesJsonValueToOutputStream() throws Exception { ObjectValue jsonBook = createJsonBook(createJunitBook()); ByteArrayOutputStream out = new ByteArrayOutputStream(); jsonEntityProvider.writeTo(jsonBook, Book.class, null, null, APPLICATION_JSON_TYPE, new MultivaluedHashMap<>(), out); assertEquals("{\"author\":\"Vincent Massol\",\"title\":\"JUnit in Action\",\"pages\":386,\"price\":19.37,\"isdn\":93011099534534}", out.toString()); } @Test public void writesObjectToOutputStream() throws Exception { Book book = createJunitBook(); ByteArrayOutputStream out = new ByteArrayOutputStream(); jsonEntityProvider.writeTo(book, Book.class, null, null, APPLICATION_JSON_TYPE, new MultivaluedHashMap<>(), out); String outputAsString = out.toString(); assertTrue(outputAsString.contains("\"author\":\"Vincent Massol\"")); assertTrue(outputAsString.contains("\"title\":\"JUnit in Action\"")); assertTrue(outputAsString.contains("\"pages\":386")); assertTrue(outputAsString.contains("\"price\":19.37")); assertTrue(outputAsString.contains("\"isdn\":93011099534534")); } @Test public void writesArrayOfObjectsToOutputStream() throws Exception { Book[] books = new Book[]{createJunitBook()}; ByteArrayOutputStream out = new ByteArrayOutputStream(); jsonEntityProvider.writeTo(books, Book[].class, null, null, APPLICATION_JSON_TYPE, new MultivaluedHashMap<>(), out); String outputAsString = out.toString(); assertTrue(outputAsString.startsWith("[")); assertTrue(outputAsString.endsWith("]")); assertTrue(outputAsString.contains("\"author\":\"Vincent Massol\"")); assertTrue(outputAsString.contains("\"title\":\"JUnit in Action\"")); assertTrue(outputAsString.contains("\"pages\":386")); assertTrue(outputAsString.contains("\"price\":19.37")); assertTrue(outputAsString.contains("\"isdn\":93011099534534")); } @Test public void writesCollectionOfObjectsToOutputStream() throws Exception { List<Book> books = newArrayList(createJunitBook()); ByteArrayOutputStream out = new ByteArrayOutputStream(); jsonEntityProvider.writeTo(books, List.class, newParameterizedType(List.class, Book.class), null, APPLICATION_JSON_TYPE, new MultivaluedHashMap<>(), out); String outputAsString = out.toString(); assertTrue(outputAsString.startsWith("[")); assertTrue(outputAsString.endsWith("]")); assertTrue(outputAsString.contains("\"author\":\"Vincent Massol\"")); assertTrue(outputAsString.contains("\"title\":\"JUnit in Action\"")); assertTrue(outputAsString.contains("\"pages\":386")); assertTrue(outputAsString.contains("\"price\":19.37")); assertTrue(outputAsString.contains("\"isdn\":93011099534534")); } @Test public void writesMapStringToObjectToOutputStream() throws Exception { Map<String, Book> books = ImmutableMap.of("1", createJunitBook()); ByteArrayOutputStream out = new ByteArrayOutputStream(); jsonEntityProvider.writeTo(books, Map.class, newParameterizedType(Map.class, String.class, Book.class), null, APPLICATION_JSON_TYPE, new MultivaluedHashMap<>(), out); String outputAsString = out.toString(); assertTrue(outputAsString.startsWith("{\"1\":{")); assertTrue(outputAsString.endsWith("}")); assertTrue(outputAsString.contains("\"author\":\"Vincent Massol\"")); assertTrue(outputAsString.contains("\"title\":\"JUnit in Action\"")); assertTrue(outputAsString.contains("\"pages\":386")); assertTrue(outputAsString.contains("\"price\":19.37")); assertTrue(outputAsString.contains("\"isdn\":93011099534534")); } private ObjectValue createJsonBook(Book book) { ObjectValue objectValue = new ObjectValue(); objectValue.addElement("author", new StringValue(book.getAuthor())); objectValue.addElement("title", new StringValue(book.getTitle())); objectValue.addElement("pages", new LongValue(book.getPages())); objectValue.addElement("price", new DoubleValue(book.getPrice())); objectValue.addElement("isdn", new LongValue(book.getIsdn())); return objectValue; } }