package io.katharsis.dispatcher.controller.resource; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import io.katharsis.dispatcher.controller.BaseControllerTest; import io.katharsis.queryParams.QueryParams; import io.katharsis.request.dto.DataBody; import io.katharsis.request.dto.LinkageData; import io.katharsis.request.dto.RequestBody; import io.katharsis.request.dto.ResourceRelationships; import io.katharsis.request.path.JsonPath; import io.katharsis.request.path.ResourcePath; import io.katharsis.resource.exception.ResourceNotFoundException; import io.katharsis.resource.mock.models.Memorandum; import io.katharsis.resource.mock.models.OtherPojo; import io.katharsis.resource.mock.models.Pojo; import io.katharsis.resource.mock.models.Project; import io.katharsis.resource.mock.models.ProjectData; import io.katharsis.resource.mock.models.Task; import io.katharsis.resource.mock.models.User; import io.katharsis.resource.mock.repository.TaskRepository; import io.katharsis.response.HttpStatus; import io.katharsis.response.ResourceResponseContext; import org.junit.Assert; import org.junit.Test; import java.util.Collections; import static org.assertj.core.api.Assertions.assertThat; public class ResourcePostTest extends BaseControllerTest { private static final String REQUEST_TYPE = "POST"; @Test public void onGivenRequestCollectionGetShouldDenyIt() { // GIVEN JsonPath jsonPath = pathBuilder.buildPath("/tasks/1"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // WHEN boolean result = sut.isAcceptable(jsonPath, REQUEST_TYPE); // THEN Assert.assertEquals(result, false); } @Test public void onGivenRequestResourceGetShouldAcceptIt() { // GIVEN JsonPath jsonPath = pathBuilder.buildPath("/tasks/"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // WHEN boolean result = sut.isAcceptable(jsonPath, REQUEST_TYPE); // THEN Assert.assertEquals(result, true); } @Test public void onInconsistentResourceTypesShouldThrowException() throws Exception { // GIVEN RequestBody newProjectBody = new RequestBody(); DataBody data = new DataBody(); newProjectBody.setData(data); data.setType("projects"); data.setAttributes(objectMapper.createObjectNode().put("name", "sample task")); JsonPath projectPath = pathBuilder.buildPath("/tasks"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // THEN expectedException.expect(RuntimeException.class); // WHEN sut.handle(projectPath, new QueryParams(), null, newProjectBody); } @Test public void onNonExistentResourceShouldThrowException() throws Exception { // GIVEN RequestBody newProjectBody = new RequestBody(); DataBody data = new DataBody(); newProjectBody.setData(data); data.setType("fridges"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // THEN expectedException.expect(ResourceNotFoundException.class); // WHEN sut.handle(new ResourcePath("fridges"), new QueryParams(), null, newProjectBody); } @Test public void onNoBodyResourceShouldThrowException() throws Exception { // GIVEN ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // THEN expectedException.expect(RuntimeException.class); // WHEN sut.handle(new ResourcePath("fridges"), new QueryParams(), null, null); } @Test public void onNewResourcesAndRelationshipShouldPersistThoseData() throws Exception { // GIVEN RequestBody newProjectBody = new RequestBody(); DataBody data = new DataBody(); newProjectBody.setData(data); data.setType("projects"); ObjectNode attributes = objectMapper.createObjectNode() .put("name", "sample project"); attributes.putObject("data") .put("data", "asd"); data.setAttributes(attributes); JsonPath projectPath = pathBuilder.buildPath("/projects"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // WHEN ResourceResponseContext projectResponse = sut.handle(projectPath, new QueryParams(), null, newProjectBody); // THEN assertThat(projectResponse.getHttpStatus()).isEqualTo(HttpStatus.CREATED_201); assertThat(projectResponse.getResponse().getEntity()).isExactlyInstanceOf(Project.class); Project persistedProject = (Project) (projectResponse.getResponse().getEntity()); assertThat(persistedProject.getId()).isNotNull(); assertThat(persistedProject.getName()).isEqualTo("sample project"); assertThat(persistedProject.getData()).isEqualToComparingFieldByField(new ProjectData().setData("asd")); Long projectId = ((Project) (projectResponse.getResponse().getEntity())).getId(); /* ------- */ // GIVEN RequestBody newTaskBody = new RequestBody(); data = new DataBody(); newTaskBody.setData(data); data.setType("tasks"); data.setAttributes(objectMapper.createObjectNode().put("name", "sample task")); data.setRelationships(new ResourceRelationships()); data.getRelationships().setAdditionalProperty("project", new LinkageData("projects", projectId.toString())); JsonPath taskPath = pathBuilder.buildPath("/tasks"); // WHEN ResourceResponseContext taskResponse = sut.handle(taskPath, new QueryParams(), null, newTaskBody); // THEN assertThat(taskResponse.getHttpStatus()).isEqualTo(HttpStatus.CREATED_201); assertThat(taskResponse.getResponse().getEntity()).isExactlyInstanceOf(Task.class); Long taskId = ((Task) (taskResponse.getResponse().getEntity())).getId(); assertThat(taskId).isNotNull(); assertThat(((Task) (taskResponse.getResponse().getEntity())).getName()).isEqualTo("sample task"); TaskRepository taskRepository = new TaskRepository(); Task persistedTask = taskRepository.findOne(taskId, null); assertThat(persistedTask.getProject().getId()).isEqualTo(projectId); } @Test public void onNewResourcesAndRelationshipsShouldPersistThoseData() throws Exception { // GIVEN RequestBody newProjectBody = new RequestBody(); DataBody data = new DataBody(); newProjectBody.setData(data); data.setType("projects"); data.setAttributes(objectMapper.createObjectNode().put("name", "sample project")); JsonPath projectPath = pathBuilder.buildPath("/projects"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // WHEN ResourceResponseContext projectResponse = sut.handle(projectPath, new QueryParams(), null, newProjectBody); // THEN assertThat(projectResponse.getResponse().getEntity()).isExactlyInstanceOf(Project.class); assertThat(((Project) (projectResponse.getResponse().getEntity())).getId()).isNotNull(); assertThat(((Project) (projectResponse.getResponse().getEntity())).getName()).isEqualTo("sample project"); Long projectId = ((Project) (projectResponse.getResponse().getEntity())).getId(); /* ------- */ // GIVEN RequestBody newUserBody = new RequestBody(); data = new DataBody(); newUserBody.setData(data); data.setType("users"); data.setAttributes(objectMapper.createObjectNode().put("name", "some user")); data.setRelationships(new ResourceRelationships()); data.getRelationships().setAdditionalProperty("assignedProjects", Collections.singletonList(new LinkageData("projects", projectId.toString()))); JsonPath taskPath = pathBuilder.buildPath("/users"); // WHEN ResourceResponseContext taskResponse = sut.handle(taskPath, new QueryParams(), null, newUserBody); // THEN assertThat(taskResponse.getResponse().getEntity()).isExactlyInstanceOf(User.class); Long userId = ((User) (taskResponse.getResponse().getEntity())).getId(); assertThat(userId).isNotNull(); assertThat(((User) (taskResponse.getResponse().getEntity())).getName()).isEqualTo("some user"); assertThat(((User) (taskResponse.getResponse().getEntity())).getAssignedProjects()).hasSize(1); assertThat(((User) (taskResponse.getResponse().getEntity())).getAssignedProjects().get(0).getId()).isEqualTo(projectId); } @Test public void onNewInheritedResourceShouldPersistThisResource() throws Exception { // GIVEN RequestBody newMemorandumBody = new RequestBody(); DataBody data = new DataBody(); newMemorandumBody.setData(data); data.setType("memoranda"); ObjectNode attributes = objectMapper.createObjectNode() .put("title", "sample title") .put("body", "sample body"); data.setAttributes(attributes); JsonPath projectPath = pathBuilder.buildPath("/documents"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // WHEN ResourceResponseContext memorandumResponse = sut.handle(projectPath, new QueryParams(), null, newMemorandumBody); // THEN assertThat(memorandumResponse.getResponse().getEntity()).isExactlyInstanceOf(Memorandum.class); Memorandum persistedMemorandum = (Memorandum) (memorandumResponse.getResponse().getEntity()); assertThat(persistedMemorandum.getId()).isNotNull(); assertThat(persistedMemorandum.getTitle()).isEqualTo("sample title"); assertThat(persistedMemorandum.getBody()).isEqualTo("sample body"); } @Test public void onResourceWithCustomNamesShouldSaveParametersCorrectly() throws Exception { // GIVEN - creating sample project id RequestBody newProjectBody = new RequestBody(); DataBody data = new DataBody(); newProjectBody.setData(data); data.setType("projects"); data.setAttributes(objectMapper.createObjectNode().put("name", "sample project")); JsonPath projectPath = pathBuilder.buildPath("/projects"); ResourcePost sut = new ResourcePost(resourceRegistry, typeParser, objectMapper); // WHEN ResourceResponseContext projectResponse = sut.handle(projectPath, new QueryParams(), null, newProjectBody); // THEN assertThat(projectResponse.getResponse().getEntity()).isExactlyInstanceOf(Project.class); assertThat(((Project) (projectResponse.getResponse().getEntity())).getId()).isNotNull(); assertThat(((Project) (projectResponse.getResponse().getEntity())).getName()).isEqualTo("sample project"); Long projectId = ((Project) (projectResponse.getResponse().getEntity())).getId(); /* ------- */ // GIVEN RequestBody pojoBody = new RequestBody(); DataBody pojoData = new DataBody(); pojoBody.setData(pojoData); pojoData.setType("pojo"); JsonNode put = objectMapper.createObjectNode().put("value", "hello"); JsonNode attributes = objectMapper.createObjectNode() .set("other-pojo", put); pojoData.setAttributes(attributes); ResourceRelationships relationships = new ResourceRelationships(); relationships.setAdditionalProperty("some-project", new LinkageData("projects", Long.toString(projectId))); relationships.setAdditionalProperty("some-projects", Collections.singletonList(new LinkageData("projects", Long.toString(projectId)))); pojoData.setRelationships(relationships); JsonPath pojoPath = pathBuilder.buildPath("/pojo"); // WHEN ResourceResponseContext pojoResponse = sut.handle(pojoPath, new QueryParams(), null, pojoBody); // THEN assertThat(pojoResponse.getResponse().getEntity()).isExactlyInstanceOf(Pojo.class); Pojo persistedPojo = (Pojo) (pojoResponse.getResponse().getEntity()); assertThat(persistedPojo.getId()).isNotNull(); assertThat(persistedPojo.getOtherPojo()).isEqualTo(new OtherPojo().setValue("hello")); assertThat(persistedPojo.getProject()).isNotNull(); assertThat(persistedPojo.getProject().getId()).isEqualTo(projectId); assertThat(persistedPojo.getProjects()).hasSize(1); assertThat(persistedPojo.getProjects().get(0).getId()).isEqualTo(projectId); } }