package io.katharsis.jackson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import io.katharsis.queryParams.DefaultQueryParamsParser;
import io.katharsis.queryParams.QueryParams;
import io.katharsis.queryParams.QueryParamsBuilder;
import io.katharsis.request.path.JsonPath;
import io.katharsis.request.path.PathBuilder;
import io.katharsis.request.path.ResourcePath;
import io.katharsis.resource.mock.models.Project;
import io.katharsis.resource.mock.models.Task;
import io.katharsis.resource.mock.models.User;
import io.katharsis.resource.registry.RegistryEntry;
import io.katharsis.response.BaseResponseContext;
import io.katharsis.response.CollectionResponseContext;
import io.katharsis.response.Container;
import io.katharsis.response.JsonApiResponse;
import io.katharsis.response.LinkageContainer;
import io.katharsis.response.LinksInformation;
import io.katharsis.response.MetaInformation;
import io.katharsis.response.ResourceResponseContext;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
public class BaseResponseSerializerTest extends BaseSerializerTest {
private static final QueryParams REQUEST_PARAMS = new QueryParams();
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void onSingleResponseWithOneIncludedResourceShouldReturnIncludedResource() throws Exception {
// GIVEN
Project project = new Project();
project.setId(2L);
project.setName("Sample project");
Task task = new Task();
task.setId(1L);
task.setName("Sample task");
task.setProject(project);
// WHEN
String result = sut
.writeValueAsString(new ResourceResponseContext(buildResponse(task), new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("data").isPresent();
assertThatJson(result).node("data.id").isEqualTo("\"1\"");
assertThatJson(result).node("included").isArray().ofLength(1);
assertThatJson(result).node("included[0].id").isEqualTo("\"2\"");
}
@Test
public void onNestedNonAnnotatedResourcesShouldReturnNestedId() throws JsonProcessingException {
// GIVEN
Task task = new Task();
task.setId(1L);
Task otherTask = new Task();
otherTask.setId(2L);
otherTask.setName("other task");
task.setOtherTasks(Collections.singletonList(otherTask));
QueryParamsBuilder queryParamsBuilder = new QueryParamsBuilder(new DefaultQueryParamsParser());
QueryParams queryParams = queryParamsBuilder.buildQueryParams(Collections.<String, Set<String>>emptyMap());
JsonPath jsonPath = new PathBuilder(resourceRegistry).buildPath("/tasks");
// WHEN
String result = sut.writeValueAsString(new Container(task, new ResourceResponseContext(null, jsonPath, queryParams)));
// THEN
assertThatJson(result).node("id").isEqualTo("\"1\"");
assertThatJson(result).node("attributes.otherTasks").isArray().ofLength(1);
assertThatJson(result).node("attributes.otherTasks[0].name").isEqualTo("other task");
assertThatJson(result).node("attributes.otherTasks[0].id").isEqualTo(2);
}
@Test
public void onSingleResponseWithOneIncludedResourcesShouldReturnIncludedResources() throws Exception {
// GIVEN
Project project1 = new Project();
project1.setId(1L);
project1.setName("Sample project");
Project project2 = new Project();
project2.setId(2L);
project2.setName("Sample project");
User user = new User();
user.setId(1L);
user.setAssignedProjects(Arrays.asList(project1, project2));
// WHEN
String result = sut
.writeValueAsString(new ResourceResponseContext(buildResponse(user), new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("data").isPresent();
assertThatJson(result).node("data.id").isEqualTo("\"1\"");
assertThatJson(result).node("included").isArray().ofLength(2);
}
@Test
public void onSingleResponseWithManyResourcesShouldReturnArrayOfResources() throws Exception {
// GIVEN
Task task1 = new Task();
task1.setId(1L);
task1.setName("Sample task");
Task task2 = new Task();
task2.setId(2L);
task2.setName("Sample task");
// WHEN
String result = sut.writeValueAsString(new CollectionResponseContext(buildResponse(Arrays.asList(task1, task2)),
new ResourcePath("tasks"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("data").isArray().ofLength(2);
}
@Test
public void onSingleResponseWithManyLinkagesShouldReturnArrayOfLinks() throws Exception {
// GIVEN
RegistryEntry entry = resourceRegistry.getEntry(Task.class);
LinkageContainer linkageContainer1 = new LinkageContainer(new Task().setId(1L), Task.class, entry);
LinkageContainer linkageContainer2 = new LinkageContainer(new Task().setId(2L), Task.class, entry);
// WHEN
JsonApiResponse response = buildResponse(Arrays.asList(linkageContainer1, linkageContainer2));
String result = sut.writeValueAsString(new CollectionResponseContext(response, new ResourcePath("tasks"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("data").isArray().ofLength(2);
assertThatJson(result).node("data[0].type").isEqualTo("tasks");
}
@Test
public void onSingleResponseWithOneLinkagesShouldReturnOneLink() throws Exception {
// GIVEN
RegistryEntry entry = resourceRegistry.getEntry(Task.class);
LinkageContainer linkageContainer1 = new LinkageContainer(new Task().setId(1L), Task.class, entry);
// WHEN
String result = sut.writeValueAsString(new ResourceResponseContext(buildResponse(linkageContainer1),
new ResourcePath("tasks"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("data.id").isStringEqualTo("1");
assertThatJson(result).node("data.type").isEqualTo("tasks");
}
@Test
public void onSingleResponseWithNoResourcesShouldReturnEmptyArray() throws Exception {
// WHEN
String result = sut
.writeValueAsString(new CollectionResponseContext(new JsonApiResponse(), new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("data").isArray().ofLength(0);
}
@Test
public void onSingleResponseWithNoResourceShouldReturnNull() throws Exception {
// WHEN
String result = sut
.writeValueAsString(new ResourceResponseContext(new JsonApiResponse(), new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("data").isEqualTo(null);
}
@Test
public void onMetaInformationShouldReturnMetaObject() throws Exception {
// GIVEN
JsonApiResponse response = new JsonApiResponse()
.setMetaInformation(new MetaData("Humpty Dumpty"));
// WHEN
String result = sut.writeValueAsString(
new ResourceResponseContext(response, new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("meta.author").isEqualTo("Humpty Dumpty");
}
@Test
public void onLinksInformationShouldReturnLinksObject() throws Exception {
// GIVEN
JsonApiResponse response = new JsonApiResponse()
.setLinksInformation(new LinksData("/sth/123"));
// WHEN
String result = sut.writeValueAsString(
new ResourceResponseContext(response, new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("links.self").isEqualTo("/sth/123");
}
@Test
public void onNoMetaInformationShouldReturnNoMetaObject() throws Exception {
// WHEN
String result = sut.writeValueAsString(
new ResourceResponseContext(new JsonApiResponse(), new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("meta").isAbsent();
}
@Test
public void onNoLinksInformationShouldReturnNoLinksObject() throws Exception {
// WHEN
String result = sut.writeValueAsString(
new ResourceResponseContext(new JsonApiResponse(), new ResourcePath("projects"), REQUEST_PARAMS));
// THEN
assertThatJson(result).node("links").isAbsent();
}
@Test
public void onCustomResponseShouldThrowException() throws Exception {
// THEN
expectedException.expect(JsonMappingException.class);
// WHEN
sut.writeValueAsString(new BaseResponseContext() {
@Override
public int getHttpStatus() {
return 0;
}
@Override
public JsonApiResponse getResponse() {
return null;
}
@Override
public JsonPath getJsonPath() {
return null;
}
@Override
public QueryParams getQueryParams() {
return null;
}
});
}
@Test
public void onDoubledIncludedResourcesShouldReturnUniqueValues() throws Exception {
// GIVEN
Project project = new Project();
project.setId(2L);
project.setName("Sample project");
Task task = new Task();
task.setId(1L);
task.setName("Sample task");
task.setProject(project);
task.setProjects(Collections.singletonList(project));
QueryParamsBuilder queryParamsBuilder = new QueryParamsBuilder(new DefaultQueryParamsParser());
QueryParams queryParams = queryParamsBuilder.buildQueryParams(
Collections.singletonMap("include[tasks]", Collections.singleton("projects")));
// WHEN
String result = sut
.writeValueAsString(new ResourceResponseContext(buildResponse(task), new ResourcePath("projects"), queryParams));
// THEN
assertThatJson(result).node("data").isPresent();
assertThatJson(result).node("data.id").isEqualTo("\"1\"");
assertThatJson(result).node("included").isArray().ofLength(1);
assertThatJson(result).node("included[0].id").isEqualTo("\"2\"");
}
public static class MetaData implements MetaInformation {
private String author;
public MetaData(String author) {
this.author = author;
}
public String getAuthor() {
return author;
}
}
public static class LinksData implements LinksInformation {
private String self;
public LinksData(String self) {
this.self = self;
}
public String getSelf() {
return self;
}
}
}