From 74200cc2100c976032fdc744830d34c93247242f Mon Sep 17 00:00:00 2001 From: Dominika Zemanovicova <xzemanov@fi.muni.cz> Date: Sun, 16 Apr 2023 20:19:23 +0200 Subject: [PATCH] Add back create to AnswerController --- .../answer/AnswerController.java | 23 +++++++ .../moduleexercise/answer/AnswerFacade.java | 12 +++- .../answer/AnswerControllerTest.java | 69 ++++++++++++++++++- 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerController.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerController.java index 696c3703..b3829f98 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerController.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerController.java @@ -9,9 +9,11 @@ import jakarta.validation.constraints.NotNull; import org.fuseri.model.dto.exercise.AnswerCreateDto; import org.fuseri.model.dto.exercise.AnswerDto; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -33,6 +35,27 @@ public class AnswerController { this.facade = facade; } + /** + * Create a new answer for the given question ID + * + * @param dto the AnswerCreateDto object containing information about the answer to create + * @return a ResponseEntity containing an AnswerDto object representing the newly created answer, or a 404 Not Found response + * if the question with the specified ID in dto was not found + */ + @Operation(summary = "Create new answer for question", description = "Creates new answer for question.") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "Answers created successfully."), + @ApiResponse(responseCode = "400", description = "Invalid input.") + }) + @PostMapping + public ResponseEntity<AnswerDto> create(@Valid @RequestBody AnswerCreateDto dto) { + try { + return ResponseEntity.status(HttpStatus.CREATED).body(facade.create(dto)); + } catch (EntityNotFoundException e) { + return ResponseEntity.notFound().build(); + } + } + /** * Update an answer * diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerFacade.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerFacade.java index 5f885b00..693c8322 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerFacade.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerFacade.java @@ -5,6 +5,7 @@ import org.fuseri.model.dto.exercise.AnswerCreateDto; import org.fuseri.model.dto.exercise.AnswerDto; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestBody; /** * Represent facade for managing answers @@ -16,7 +17,6 @@ public class AnswerFacade { private final AnswerService answerService; private final AnswerMapper mapper; - /** * Constructor for AnswerFacade * @@ -29,6 +29,16 @@ public class AnswerFacade { this.mapper = mapper; } + /** + * Create a new answer for the given question ID + * + * @param dto the AnswerCreateDto object containing information about the answer to create + * @return an AnswerDto object representing the newly created answer + */ + public AnswerDto create(@RequestBody AnswerCreateDto dto) { + return mapper.toDto(answerService.create(mapper.fromCreateDto(dto))); + } + /** * Update answer * diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerControllerTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerControllerTest.java index 7516ea80..66eaea5a 100644 --- a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerControllerTest.java +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerControllerTest.java @@ -5,6 +5,7 @@ import jakarta.persistence.EntityNotFoundException; import org.fuseri.model.dto.exercise.AnswerCreateDto; import org.fuseri.model.dto.exercise.AnswerDto; import org.fuseri.model.dto.exercise.AnswerInQuestionCreateDto; +import org.fuseri.model.dto.exercise.AnswersCreateDto; import org.fuseri.model.dto.exercise.ExerciseCreateDto; import org.fuseri.model.dto.exercise.QuestionCreateDto; import org.junit.jupiter.api.BeforeEach; @@ -21,8 +22,7 @@ import java.util.List; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.when; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -61,6 +61,71 @@ public class AnswerControllerTest { new AnswerInQuestionCreateDto("All of them", true))); } + @Test + void testCreateAnswer() throws Exception { + var answerCreateDto = new AnswerCreateDto("BA", true, 1); + var answerDto = new AnswerDto("BA", true); + when(answerFacade.create(ArgumentMatchers.isA(AnswerCreateDto.class))).thenReturn(answerDto); + + mockMvc.perform(post("/answers") + .content(asJsonString(answerCreateDto)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.text", is("BA"))) + .andExpect(jsonPath("$.correct", is(true))); + } + + @Test + void testCreateAnswerEmptyText() throws Exception { + var incorrect1 = new AnswerInQuestionCreateDto("", false); + var createAnswer = new AnswersCreateDto(1, List.of(incorrect1)); + + mockMvc.perform(post("/answers") + .content(asJsonString(createAnswer)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); + } + + @Test + void testCreateAnswerMissingText() throws Exception { + var prompt = """ + { + "questionId": 1, + "answers": [ + { + "text": "something", + "correct": false + } + ] + } + """; + + mockMvc.perform(post("/answers") + .content(prompt) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); + } + + @Test + void testCreateAnswerMissingCorrect() throws Exception { + + var prompt = """ + { + "questionId": 1, + "answers": [ + { + "text": "something" + } + ] + } + """; + + mockMvc.perform(post("/answers") + .content(prompt) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); + } + @Test void testUpdate() throws Exception { long id = 1L; -- GitLab