From 42c004bfd91cc24f61c21a6f135f311e18a613ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Gargalovi=C4=8D?= <xgargal@fi.muni.cz>
Date: Fri, 14 Apr 2023 15:18:22 +0200
Subject: [PATCH] added Question Tests

---
 .../question/QuestionController.java          |   7 +
 .../question/QuestionFacade.java              |  21 +-
 .../question/QuestionRepository.java          |  10 +
 .../question/QuestionService.java             |   7 +
 .../moduleexercise/question/QuestionTest.java | 179 +++++++++++-------
 5 files changed, 157 insertions(+), 67 deletions(-)

diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionController.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionController.java
index 1595f03f..531f6e74 100644
--- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionController.java
+++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionController.java
@@ -139,4 +139,11 @@ public class QuestionController {
         questionFacade.delete(id);
         return ResponseEntity.noContent().build();
     }
+
+    //    @TestOnly
+    @DeleteMapping("/reset")
+    public void resetTable() {
+        questionFacade.resetTable();
+    }
+
 }
\ No newline at end of file
diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionFacade.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionFacade.java
index bf6f97d1..aabf8116 100644
--- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionFacade.java
+++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionFacade.java
@@ -91,8 +91,9 @@ public class QuestionFacade {
         for (var answer : answers) {
             answer.setQuestion(createdQuestion);
         }
-
-        return questionMapper.toDto(createdQuestion);
+        var result = questionMapper.toDto(createdQuestion);
+        result.setExerciseId(exercise.getId());
+        return result;
     }
 
     /**
@@ -104,9 +105,14 @@ public class QuestionFacade {
     public QuestionDto update(long id, QuestionUpdateDto dto) {
         Question question = questionMapper.fromUpdateDto(dto);
         question.setId(id);
+        var qston = questionService.find(id);
         List<Answer> questionAnswers = answerService.findAllByQuestionId(id);
         question.setAnswers(new HashSet<>(questionAnswers));
+
+        question.setExercise(qston.getExercise());
         Question updatedQuestion = questionService.update(question);
+        var ddto = questionMapper.toDto(updatedQuestion);
+
         return questionMapper.toDto(updatedQuestion);
     }
 
@@ -122,4 +128,15 @@ public class QuestionFacade {
         }
         questionService.delete(id);
     }
+
+    //@TestOnly
+    public void reset() {
+        questionService.reset();
+        questionService.resetId();
+    }
+
+    public void resetTable() {
+        questionService.reset();
+        questionService.resetId();
+    }
 }
diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionRepository.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionRepository.java
index b5b2adc4..0c11e6ec 100644
--- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionRepository.java
+++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionRepository.java
@@ -1,11 +1,21 @@
 package org.fuseri.moduleexercise.question;
 
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * A repository interface for managing Question entities
  */
 @Repository
 public interface QuestionRepository extends JpaRepository<Question, Long> {
+
+    //@TestOnly
+    @Modifying
+    @Transactional
+    @Query( value = "ALTER TABLE Question ALTER COLUMN id RESTART WITH 1",nativeQuery = true)
+    void resetId();
+
 }
\ No newline at end of file
diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionService.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionService.java
index 2d54e3d1..58171014 100644
--- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionService.java
+++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/question/QuestionService.java
@@ -43,4 +43,11 @@ public class QuestionService extends DomainService<Question> {
         return repository.findById(id)
                 .orElseThrow(() -> new EntityNotFoundException("Question '" + id + "' not found."));
     }
+
+    //@TestOnly
+    @Transactional
+    public void resetId() {
+        repository.resetId();
+    }
+
 }
diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionTest.java
index c248a763..5155e64a 100644
--- a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionTest.java
+++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionTest.java
@@ -1,22 +1,29 @@
 package org.fuseri.moduleexercise.question;
 
-import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.fuseri.model.dto.exercise.AnswerDto;
 import org.fuseri.model.dto.exercise.AnswerInQuestionCreateDto;
 import org.fuseri.model.dto.exercise.ExerciseCreateDto;
-import org.fuseri.model.dto.exercise.ExerciseDto;
 import org.fuseri.model.dto.exercise.QuestionCreateDto;
 import org.fuseri.model.dto.exercise.QuestionDto;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.http.MediaType;
 import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
 
+import static org.hamcrest.Matchers.is;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import java.util.ArrayList;
 import java.util.List;
 
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
 
@@ -38,109 +45,151 @@ public class QuestionTest {
         }
     }
 
-    @Test
-    void testCreateQuestion() throws Exception {
-        long id = createExercise();
-        var answr = new AnswerDto("dis a logical paradox", true);
-        QuestionDto res = createQuestion(id);
-        var expected = new QuestionDto();
-        expected.setAnswers(List.of(answr));
-        expected.setExerciseId(id);
-        expected.setId(res.getId());
-        expected.setText("this statement is false");
-
-//        assert expected.equals(res);
+    private void createExercise() {
+        var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0L);
+        var postExercise2 = new ExerciseCreateDto("riddles", "simple english riddles", 2, 0L);
+        try {
+            mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON));
+            mockMvc.perform(post("/exercises").content(asJsonString(postExercise2)).contentType(MediaType.APPLICATION_JSON));
+
+        } catch (Exception e) {
+            assert (false);
+        }
     }
 
-    private QuestionDto createQuestion(long id) throws Exception {
+    @BeforeEach
+    void init() {
+        createExercise();
+        long id = 2;
+
         var question = new QuestionCreateDto("this statement is false", id, List.of(new AnswerInQuestionCreateDto("dis a logical paradox", true)));
+        var question2 = new QuestionCreateDto("What month of the year has 28 days?", id, List.of(new AnswerInQuestionCreateDto("February", false), new AnswerInQuestionCreateDto("All of them", true)));
+        ResultActions posted = null;
+        try {
+            posted = mockMvc.perform(post("/questions").content(asJsonString(question)).contentType(MediaType.APPLICATION_JSON));
+            posted = mockMvc.perform(post("/questions").content(asJsonString(question2)).contentType(MediaType.APPLICATION_JSON));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 
+    @AfterEach
+    void cleanup() {
+        try {
+            mockMvc.perform(delete("/questions/reset"));
+            mockMvc.perform(delete("/exercises/reset"));
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
 
+    @Test
+    void testCreateQuestion() throws Exception {
+        var exerciseId = 1L;
+        var question = new QuestionCreateDto("what is the meaning of: costs an arm and leg", exerciseId, List.of(new AnswerInQuestionCreateDto("dis very expencive", true), new AnswerInQuestionCreateDto("FMA refference", false)));
         var posted = mockMvc.perform(post("/questions").content(asJsonString(question)).contentType(MediaType.APPLICATION_JSON));
 
-
-        var cont = posted.andReturn().getResponse().getContentAsString();
-        var res = objectMapper.readValue(cont, QuestionDto.class);
-        return res;
+        posted.andExpect(status().isCreated())
+                .andExpect(jsonPath("$.text", is("what is the meaning of: costs an arm and leg")))
+                .andExpect(jsonPath("$.exerciseId", is(exerciseId)))
+                .andExpect(jsonPath("$.answers[0].text", is("dis very expencive")));
     }
 
-    private long createExercise() {
-        var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0L);
-
-        long id = 0L;
-
-        try {
-            var dis = mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON));
-            var ok = dis.andReturn().getResponse().getContentAsString();
+    @Test
+    void testCreateQuestionEmptyQuestions() throws Exception {
+        var prompt = """
+                {
+                "text": "this is a question without exercise Id",
+                "exerciseId": 1,
+                "answers": []
+                }
+                """;
 
-            var ll = objectMapper.readValue(ok, ExerciseDto.class);
+        var posted = mockMvc.perform(post("/questions").content(prompt).contentType(MediaType.APPLICATION_JSON));
 
-            id = ll.getId();
-        } catch (Exception e) {
-            assert (false);
-        }
-        return id;
+        posted.andExpect(status().isCreated());
     }
 
 
     @Test
-    void getQuestion() throws Exception {
-
+    void testCreateQuestionEmptyField() throws Exception {
+        var exerciseId = 1L;
+        var question = new QuestionCreateDto("", exerciseId, List.of(new AnswerInQuestionCreateDto("dis very expencive", true), new AnswerInQuestionCreateDto("FMA refference", false)));
+        var posted = mockMvc.perform(post("/questions").content(asJsonString(question)).contentType(MediaType.APPLICATION_JSON));
 
-        long exerciseId = createExercise();
-        var question = createQuestion(exerciseId);
+        posted.andExpect(status().is4xxClientError());
+    }
 
-        var theId = String.format("/questions/%s", question.getId());
+    @Test
+    void testCreateQuestionMissingField() throws Exception {
+        var prompt = """
+                {
+                "text": "this is a question without exercise Id,
+                "answers" : []
+                }
+                """;
 
+        var posted = mockMvc.perform(post("/questions").content(prompt).contentType(MediaType.APPLICATION_JSON));
 
-        var gets = mockMvc.perform(get(theId));
+        posted.andExpect(status().is4xxClientError());
+    }
 
-        var content = gets.andReturn().getResponse().getContentAsString();
-        var res = objectMapper.readValue(content, QuestionDto.class);
+    private QuestionDto createQuestion(long id) throws Exception {
+        var question = new QuestionCreateDto("this statement is false", id, List.of(new AnswerInQuestionCreateDto("dis a logical paradox", true)));
+        var posted = mockMvc.perform(post("/questions").content(asJsonString(question)).contentType(MediaType.APPLICATION_JSON));
+        var cont = posted.andReturn().getResponse().getContentAsString();
+        var res = objectMapper.readValue(cont, QuestionDto.class);
+        return res;
+    }
 
-        assert res.equals(question);
 
+    @Test
+    void getQuestion() throws Exception {
+        var gets = mockMvc.perform(get("/questions/1"));
+        gets.andExpect(status().isOk()).andExpect(jsonPath("$.text", is("this statement is false")));
     }
 
     @Test
-    void getAnswer() throws Exception {
-        var exerciseId = createExercise();
-        var question = createQuestion(exerciseId);
-
-        var gets = mockMvc.perform(get(String.format("/questions/%s/answers", question.getId())));
+    void getQuestionNotFound() throws Exception {
+        var gets = mockMvc.perform(get("/questions/9999"));
+        gets.andExpect(status().isNotFound());
+    }
 
-        var content2 = gets.andReturn().getResponse().getContentAsString();
 
-        var res = objectMapper.readValue(content2, new TypeReference<List<AnswerDto>>() {
-        });
+    @Test
+    void getAnswer() throws Exception {
+        var gets = mockMvc.perform(get("/questions/2/answers"));
+        gets.andExpect(status().isOk())
+                .andExpect(jsonPath("$[0].text", is("February")))
+                .andExpect(jsonPath("$[1].text", is("All of them")));
 
-        assert (res.equals(question.getAnswers()));
 
     }
 
     @Test
     void TestUpdate() throws Exception {
-        long id = createExercise();
-        var question = createQuestion(id);
+        long id = 1;
 
         var updated = """
                 {
                   "text": "wat a paradox?",
-                  "exerciseId": "%s"
+                  "exerciseId": "1"
                 }
                 """;
 
-        updated = String.format(updated, id);
-//
-//        var smth = mockMvc.perform(put(String.format("/questions/%s", question.getId())).content(updated).contentType(MediaType.APPLICATION_JSON));
-//
-//        var content = smth.andReturn().getResponse().getContentAsString();
-
-//        var res = objectMapper.readValue(content, QuestionDto.class);
+        var gets = mockMvc.perform(put("/questions/1").content(updated).contentType(MediaType.APPLICATION_JSON));
 
-//        question.setText("wat a paradox?");
-
-//        assert (question.equals(res));
+        gets.andExpect(status().isOk())
+                .andExpect(jsonPath("$.text", is("wat a paradox?")));
+    }
 
+@Test
+    void deleteExisting() {
+    try {
+        mockMvc.perform(delete("/questions/1")).andExpect(status().isNoContent());
+    } catch (Exception e) {
+        throw new RuntimeException(e);
     }
 }
+
+}
-- 
GitLab