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