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