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 1/6] 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 From 44a1247a03facd8280022538f6488d6fb56a7cee 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:45 +0200 Subject: [PATCH 2/6] added Exercise Tests --- .../moduleexercise/common/DomainService.java | 5 + .../exercise/ExerciseController.java | 6 + .../exercise/ExerciseFacade.java | 5 + .../exercise/ExerciseRepository.java | 14 + .../exercise/ExerciseService.java | 5 + .../moduleexercise/exercise/ExerciseTest.java | 244 +++++++++++++++--- 6 files changed, 242 insertions(+), 37 deletions(-) diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/common/DomainService.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/common/DomainService.java index ec9d9681..1ce61dc3 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/common/DomainService.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/common/DomainService.java @@ -52,4 +52,9 @@ public abstract class DomainService<T extends DomainObject> { public void delete(long id) { getRepository().deleteById(id); } + + public void reset() { + getRepository().deleteAll(); +// getRepository().id/ + } } \ No newline at end of file diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseController.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseController.java index f8d6926a..962d1556 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseController.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseController.java @@ -173,4 +173,10 @@ public class ExerciseController { return ResponseEntity.noContent().build(); } +// @TestOnly + @DeleteMapping("/reset") + public void resetTable() { + facade.resetTable(); + } + } diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseFacade.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseFacade.java index 8d9174a5..ef50a6d1 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseFacade.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseFacade.java @@ -119,4 +119,9 @@ public class ExerciseFacade { public void delete(long id) { exerciseService.delete(id); } + + public void resetTable() { + exerciseService.reset(); + exerciseService.resetId(); + } } diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java index abdc8f01..cd0eba8d 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java @@ -5,9 +5,11 @@ import org.fuseri.moduleexercise.question.Question; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; /** * A repository interface for managing Exercise entities @@ -30,4 +32,16 @@ public interface ExerciseRepository extends JpaRepository<Exercise, Long> { @Query("SELECT q FROM Exercise e JOIN e.questions q WHERE e.id = :exerciseId") Page<Question> getQuestions(PageRequest pageRequest, @Param("exerciseId") Long exerciseId); + + @Modifying + @Transactional + @Query(value = "TRUNCATE Table exercise",nativeQuery = true) + void resetTable(); + + @Modifying + @Transactional + @Query( value = "ALTER TABLE Exercise ALTER COLUMN id RESTART WITH 1",nativeQuery = true) + void resetId(); + + } diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseService.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseService.java index 6d819b68..4aeed17d 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseService.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseService.java @@ -85,4 +85,9 @@ public class ExerciseService extends DomainService<Exercise> { PageRequest.of(page, DomainService.DEFAULT_PAGE_SIZE), exerciseId); } + + @Transactional + public void resetId() { + repository.resetId(); + } } diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java index 92481d50..796b225e 100644 --- a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java @@ -5,20 +5,20 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.fuseri.model.dto.common.Result; import org.fuseri.model.dto.exercise.ExerciseCreateDto; import org.fuseri.model.dto.exercise.ExerciseDto; +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 java.util.Map; - +import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; @@ -38,59 +38,122 @@ public class ExerciseTest { } } + private ExerciseCreateDto exercise1; + private ExerciseCreateDto exercise2; + private ExerciseCreateDto exercise3; - @Test - void getExercise() { - var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0L); - - long id = 0L; + @BeforeEach + void init() { + exercise1 = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0); + exercise2 = new ExerciseCreateDto("idioms1", "exercise on intermediate idioms", 2, 0); + exercise3 = new ExerciseCreateDto("idioms2", "exercise on basic idioms", 1, 0L); try { - var dis = mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON)); - var ok = dis.andReturn().getResponse().getContentAsString(); - - var ll = objectMapper.readValue(ok, ExerciseDto.class); - - id = ll.getId(); + mockMvc.perform(post("/exercises").content(asJsonString(exercise1)).contentType(MediaType.APPLICATION_JSON)); + mockMvc.perform(post("/exercises").content(asJsonString(exercise2)).contentType(MediaType.APPLICATION_JSON)); + mockMvc.perform(post("/exercises").content(asJsonString(exercise3)).contentType(MediaType.APPLICATION_JSON)); } catch (Exception e) { assert (false); } + } + @AfterEach + void cleanup() { + + try { + mockMvc.perform(delete("/exercises/reset")); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + @Test + void getExercise() { + long id = 1L; try { var theId = String.format("/exercises/%s", id); var smth = mockMvc.perform(get(theId)); + smth.andExpect(status().isOk()) + .andExpect(jsonPath("$.name", is(exercise1.getName()))) + .andExpect(jsonPath("$.description", is(exercise1.getDescription()))) + .andExpect(jsonPath("$.courseId", is((int) exercise1.getCourseId()))) + .andExpect(jsonPath("$.difficulty", is(exercise1.getDifficulty()))); + } catch (Exception e) { + //do absolutely nothing + } + } + @Test + void deleteExercise() { + long id = 1L; + try { + var theId = String.format("/exercises/%s", id); + var smth = mockMvc.perform(delete(theId)); + smth.andExpect(status().isNoContent()); } catch (Exception e) { //do absolutely nothing } } @Test - void getFiltered() { + void deleteExercise_notFound() { + long id = 999999L; + try { + var theId = String.format("/exercises/%s", id); + var smth = mockMvc.perform(delete(theId)); + smth.andExpect(status().isNoContent()); + } catch (Exception e) { + //do absolutely nothing + } + } - var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 0, 0L); - var postExercise1 = new ExerciseCreateDto("idioms1", "exercise on basic idioms", 0, 0L); - var postExercise2 = new ExerciseCreateDto("idioms2", "exercise on basic idioms", 1, 0L); + @Test + void getExercise_notFound() { + long id = 999999L; + try { + var theId = String.format("/exercises/%s", id); + var smth = mockMvc.perform(get(theId)); + smth.andExpect(status().isNotFound()); + } catch (Exception e) { + //do absolutely nothing + } + } + + @Test + void FindAll() { try { - var exercise1 = mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON)); + var dis = mockMvc.perform(get("/exercises").param("page", "0")); + + dis.andExpect(status().isOk()) + .andExpect(jsonPath("$.total", is(3))) + .andExpect(jsonPath("$.items[0].name", is(exercise1.getName()))) + .andExpect(jsonPath("$.items[0].description", is(exercise1.getDescription()))) + .andExpect(jsonPath("$.items[0].difficulty", is(exercise1.getDifficulty()))) + .andExpect(jsonPath("$.items[0].courseId", is((int) exercise1.getCourseId()))) + .andExpect(jsonPath("$.items[1].name", is(exercise2.getName()))) + .andExpect(jsonPath("$.items[1].description", is(exercise2.getDescription()))) + .andExpect(jsonPath("$.items[1].difficulty", is(exercise2.getDifficulty()))) + .andExpect(jsonPath("$.items[1].courseId", is((int) exercise2.getCourseId()))) + .andExpect(jsonPath("$.items[2].name", is(exercise3.getName()))) + .andExpect(jsonPath("$.items[2].description", is(exercise3.getDescription()))) + .andExpect(jsonPath("$.items[2].difficulty", is(exercise3.getDifficulty()))) + .andExpect(jsonPath("$.items[2].courseId", is((int) exercise3.getCourseId()))); - var exercise2 = mockMvc.perform(post("/exercises").content(asJsonString(postExercise1)).contentType(MediaType.APPLICATION_JSON)); - var exercise3 = mockMvc.perform(post("/exercises").content(asJsonString(postExercise2)).contentType(MediaType.APPLICATION_JSON)); } catch (Exception e) { - //do absolutly nothing + throw new RuntimeException(e); } - Map<String, String> params; + } - try { - var filtered = mockMvc.perform(get("/exercises/filter").param("page", "0").param("courseId", "0").param("difficulty", "0")); + @Test + void getFiltered() { + try { + var filtered = mockMvc.perform(get("/exercises/filter").param("page", "0").param("courseId", "0").param("difficulty", "2")); var content = filtered.andReturn().getResponse().getContentAsString(); - var res = objectMapper.readValue(content, new TypeReference<Result<ExerciseDto>>() { }); @@ -102,11 +165,7 @@ public class ExerciseTest { // @Test // void getByExercise() throws Exception { -// -// var exerciseId = createExercise(); -// var question = createQuestion(exerciseId); -// -// var theId = String.format("/questions/exercise/%s", exerciseId); +// var theId = String.format("/questions/exercise/%s", 9); // // var smth = mockMvc.perform(get(theId).param("page", "0")); // @@ -115,24 +174,94 @@ public class ExerciseTest { // var res = objectMapper.readValue(content, new TypeReference<Result<QuestionDto>>() { // }); // -// Map<String, String> params; // -// assert (res.getItems().get(0).equals(question)); +// +//// assert (res.getItems().get(0).equals(question)); // } @Test void testCreateExercise() throws Exception { - var expectedResponse = new ExerciseDto(); var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0L); - mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isCreated()).andExpect(jsonPath("$.name").value("idioms")).andExpect(jsonPath("$.description").value("exercise on basic idioms")).andExpect(jsonPath("$.difficulty").value(2)).andExpect(jsonPath("$.courseId").value("0")).andReturn().getResponse().getContentAsString(); + mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.name").value("idioms")) + .andExpect(jsonPath("$.description").value("exercise on basic idioms")) + .andExpect(jsonPath("$.difficulty").value(2)) + .andExpect(jsonPath("$.courseId").value("0")).andReturn().getResponse().getContentAsString(); } + @Test + void testCreateExerciseEmptyBody() throws Exception { + var postExercise = ""; + + mockMvc.perform(post("/exercises").content((postExercise)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()).andReturn().getResponse().getContentAsString(); + } + + + @Test + void testCreateExerciseMissingDesc() throws Exception { + var postExercise = """ + { + "name": "idioms", + "difficulty": 2, + "courseId": 0, + } + """; + + mockMvc.perform(post("/exercises").content((postExercise)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()).andReturn().getResponse().getContentAsString(); + } + + @Test + void testCreateExerciseMissingName() throws Exception { + var postExercise = """ + { + "description: "exercise on basic idioms", + "difficulty": 2, + "courseId": 0, + } + """; + + mockMvc.perform(post("/exercises").content((postExercise)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()).andReturn().getResponse().getContentAsString(); + } + + @Test + void testCreateExerciseMissingDifficulty() throws Exception { + var postExercise = """ + { + "name": "idioms" + "description: "exercise on basic idioms", + "courseId": 0 + } + """; + + mockMvc.perform(post("/exercises").content((postExercise)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()).andReturn().getResponse().getContentAsString(); + } + + @Test + void testCreateExerciseMissingCourseId() throws Exception { + var postExercise = """ + { + "name": "idioms" + "description: "exercise on basic idioms", + "difficulty": 0 + } + """; + + mockMvc.perform(post("/exercises").content((postExercise)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()).andReturn().getResponse().getContentAsString(); + } + + @Test void testUpdate() { var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0L); - long id = 0L; + long id = 1L; try { var dis = mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON)); @@ -178,4 +307,45 @@ public class ExerciseTest { } + @Test + void testUpdateNotFound() { + long id = 999999L; + var content = """ + { + "name": "idioms", + "description": "exercise on basic idioms", + "difficulty": 2, + "courseId": 0 + } + """; + try { + var theId = String.format("/exercises/%d", id); + mockMvc.perform(put(theId).content(content).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + void testUpdateIncorrectBody() { + long id = 1L; + var content = """ + { + "description": "exercise on basic idioms", + "difficulty": 2, + "courseId": 0 + } + """; + try { + var theId = String.format("/exercises/%d", id); + mockMvc.perform(put(theId).content(content).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } -- GitLab From bcd260180a0374c6decc26f8dde7223f6d0c0cd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gargalovi=C4=8D?= <xgargal@fi.muni.cz> Date: Fri, 14 Apr 2023 23:02:22 +0200 Subject: [PATCH 3/6] Created a test Only method and fixed update() method --- .../moduleexercise/answer/AnswerController.java | 7 +++++++ .../moduleexercise/answer/AnswerFacade.java | 16 ++++++---------- .../moduleexercise/answer/AnswerRepository.java | 8 ++++++++ .../moduleexercise/answer/AnswerService.java | 4 ++++ 4 files changed, 25 insertions(+), 10 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 ebdc9cd6..f17cd187 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 @@ -96,4 +96,11 @@ public class AnswerController { return ResponseEntity.notFound().build(); } } + +// @TestOnly + @DeleteMapping("/reset") + public void resetTable() { + facade.resetTable(); + } + } 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 370eed4b..da731cdb 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 @@ -70,17 +70,8 @@ public class AnswerFacade { public AnswerDto update(long id, AnswerCreateDto dto) { var updatedAnswer = mapper.fromCreateDto(dto); updatedAnswer.setId(id); + questionService.find(dto.getQuestionId()); answerService.update(updatedAnswer); - - Question question; - question = questionService.find(dto.getQuestionId()); - - var questionAnswers = question.getAnswers(); - questionAnswers.removeIf(a -> a.getId() == id); - questionAnswers.add(updatedAnswer); - question.setAnswers(questionAnswers); - questionService.update(question); - return mapper.toDto(updatedAnswer); } @@ -101,4 +92,9 @@ public class AnswerFacade { answerService.delete(id); } + + public void resetTable() { + answerService.reset(); + answerService.resetId(); + } } diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerRepository.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerRepository.java index 8d0844a8..f7221651 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerRepository.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerRepository.java @@ -1,8 +1,11 @@ package org.fuseri.moduleexercise.answer; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -19,4 +22,9 @@ public interface AnswerRepository extends JpaRepository<Answer, Long> { * @return a list of all answers to the specified question */ List<Answer> findByQuestionId(@Param("questionId") long questionId); + + @Transactional + @Modifying + @Query( value = "ALTER TABLE Answer ALTER COLUMN id RESTART WITH 1",nativeQuery = true) + void reserId(); } \ No newline at end of file diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerService.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerService.java index f5346fc5..f7883456 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerService.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/answer/AnswerService.java @@ -58,4 +58,8 @@ public class AnswerService extends DomainService<Answer> { return repository.findById(id) .orElseThrow(() -> new EntityNotFoundException("Answer '" + id + "' not found.")); } + + public void resetId() { + repository.reserId(); + } } -- GitLab From 0ae68b088f31ff4cb7a174983734590cd0a161f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gargalovi=C4=8D?= <xgargal@fi.muni.cz> Date: Fri, 14 Apr 2023 23:02:41 +0200 Subject: [PATCH 4/6] added some more tests --- .../moduleexercise/answer/AnswerTest.java | 203 ++++++++++++------ 1 file changed, 138 insertions(+), 65 deletions(-) diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerTest.java index 46f2097e..86634c70 100644 --- a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerTest.java +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerTest.java @@ -1,14 +1,14 @@ package org.fuseri.moduleexercise.answer; -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.AnswerCreateDto; 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.ExerciseDto; import org.fuseri.model.dto.exercise.QuestionCreateDto; -import org.fuseri.model.dto.exercise.QuestionDto; +import static org.hamcrest.Matchers.is; +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; @@ -16,8 +16,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import java.util.List; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; 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; @SpringBootTest @AutoConfigureMockMvc @@ -28,6 +31,7 @@ public class AnswerTest { @Autowired private MockMvc mockMvc; + public static String asJsonString(final Object obj) { try { return new ObjectMapper().writeValueAsString(obj); @@ -36,120 +40,189 @@ public class AnswerTest { } } - private QuestionDto createQuestion(long id) throws Exception { - var question = new QuestionCreateDto("this statement is false", id, + @BeforeEach + void init() { + createExercise(); + int exerciseId = 1; + + var question = new QuestionCreateDto("this statement is false", exerciseId, List.of(new AnswerInQuestionCreateDto("dis a logical paradox", true))); + var question2 = new QuestionCreateDto("What month of the year has 28 days?", exerciseId, List.of(new AnswerInQuestionCreateDto("February", false), new AnswerInQuestionCreateDto("All of them", true))); + try { + mockMvc.perform(post("/questions") + .content(asJsonString(question)) + .contentType(MediaType.APPLICATION_JSON)); + mockMvc.perform(post("/questions") + .content(asJsonString(question2)) + .contentType(MediaType.APPLICATION_JSON)); - var posted = mockMvc.perform(post("/questions") - .content(asJsonString(question)) - .contentType(MediaType.APPLICATION_JSON)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @AfterEach + public void cleanup() { + try { + mockMvc.perform(delete("/answers/reset")); + mockMvc.perform(delete("/questions/reset")); + mockMvc.perform(delete("/exercises/reset")); + } catch (Exception ex) { + throw new RuntimeException(ex); - var cont = posted.andReturn().getResponse().getContentAsString(); - var res = objectMapper.readValue(cont, QuestionDto.class); - return res; + } } - private long createExercise() { - var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0); - long id = 0L; + private void createExercise() { + var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, 0); try { - var dis = mockMvc.perform(post("/exercises") + mockMvc.perform(post("/exercises") .content(asJsonString(postExercise)) .contentType(MediaType.APPLICATION_JSON)); - var ok = dis.andReturn().getResponse().getContentAsString(); - - var ll = objectMapper.readValue(ok, ExerciseDto.class); - - id = ll.getId(); } catch (Exception e) { - assert (false); + throw new RuntimeException(e); } - return id; } @Test void testCreateAnswer() throws Exception { - List<AnswerDto> res = createAnswer(); + var incorrect1 = new AnswerInQuestionCreateDto("True", false); + var incorrect2 = new AnswerInQuestionCreateDto("False", false); - var expected1 = new AnswerDto("True", false); - var expected2 = new AnswerDto("False", false); + var createAnswer = new AnswersCreateDto(1, List.of(incorrect1, incorrect2)); - assert (res.get(0).equals(expected1)); - assert (res.get(1).equals(expected2)); + var posted = mockMvc.perform(post("/answers") + .content(asJsonString(createAnswer)) + .contentType(MediaType.APPLICATION_JSON)); + posted.andExpect(status().isCreated()) + .andExpect(jsonPath("$[0].text",is("True"))) + .andExpect(jsonPath("$[0].correct", is(false))) + .andExpect(jsonPath("$[1].text",is("False"))) + .andExpect(jsonPath("$[1].correct",is(false))); } - private List<AnswerDto> createAnswer() throws Exception { - var exerciseId = createExercise(); - var question = createQuestion(exerciseId); - var incorrect1 = new AnswerInQuestionCreateDto("True", false); - var incorrect2 = new AnswerInQuestionCreateDto("False", false); + @Test + void testCreateAnswerEmptyText() throws Exception { - var createAnswer = new AnswersCreateDto(question.getId(), List.of(incorrect1, incorrect2)); + var incorrect1 = new AnswerInQuestionCreateDto("", false); + + var createAnswer = new AnswersCreateDto(1, List.of(incorrect1)); var posted = mockMvc.perform(post("/answers") .content(asJsonString(createAnswer)) .contentType(MediaType.APPLICATION_JSON)); - var asStr = posted.andReturn().getResponse().getContentAsString(); - - var res = objectMapper.readValue(asStr, new TypeReference<List<AnswerDto>>() { - }); - return res; + posted.andExpect(status().is4xxClientError()); } @Test - void testUpdate() throws Exception { + void testCreateAnswerMissingText() throws Exception { - var exerciseId = createExercise(); - var question = createQuestion(exerciseId); + var prompt = """ + { + "questionId": 1, + "answers": [ + { + "text": "something", + "correct": false + } + ] + } + """; - var incorrect1 = new AnswerInQuestionCreateDto("True", false); - var incorrect2 = new AnswerInQuestionCreateDto("False", false); + var posted = mockMvc.perform(post("/answers") + .content(prompt) + .contentType(MediaType.APPLICATION_JSON)); + posted.andExpect(status().isCreated()); + } - var createAnswer = new AnswersCreateDto(question.getId(), List.of(incorrect1, incorrect2)); + @Test + void testCreateAnswerMissingCorrect() throws Exception { + var prompt = """ + { + "questionId": 1, + "answers": [ + { + "text": "something" + } + ] + } + """; var posted = mockMvc.perform(post("/answers") - .content(asJsonString(createAnswer)) + .content(prompt) .contentType(MediaType.APPLICATION_JSON)); - var asStr = posted.andReturn().getResponse().getContentAsString(); + posted.andExpect(status().isCreated()); + } - var res = objectMapper.readValue(asStr, new TypeReference<List<AnswerDto>>() { - }); + @Test + void testUpdate() throws Exception { + var updated = new AnswerCreateDto("dis true",false,1); + mockMvc.perform(put("/answers/1") + .content(asJsonString(updated)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.text",is("dis true"))) + .andExpect(jsonPath("$.correct",is(false))); + } + @Test + void testUpdateNotFoundAnswer() throws Exception { + var updated = new AnswerCreateDto("dis true",false,1); + mockMvc.perform(put("/answers/9999") + .content(asJsonString(updated)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isNotFound()); + } + @Test + void testUpdateEmptyText() throws Exception { + var updated = new AnswerCreateDto("",false,1); + mockMvc.perform(put("/answers/1") + .content(asJsonString(updated)).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); + } + + @Test + void testUpdateMissingField() throws Exception { var updated = """ { - "text": "dis true", - "correct": false, - "questionId": "%s" + "correct": false, + "questionId": 1 } """; + mockMvc.perform(put("/answers/1") + .content(updated).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is4xxClientError()); + } -// updated = String.format(updated, question.getId()); -// -// var puts = mockMvc.perform(put(String.format("/answers/%s", res.get(0).getId())) -// .content(updated).contentType(MediaType.APPLICATION_JSON)); -// -// var content = puts.andReturn().getResponse().getContentAsString(); -// -// var res2 = objectMapper.readValue(content, AnswerDto.class); -// -// var expected = new AnswerDto("dis true", false); -// -// assert res2.equals(expected); - + @Test + void testDeleteExisting() { + try { + mockMvc.perform(delete("/answers/1")) + .andExpect(status().isNoContent()); + } catch (Exception e) { + assert(false); + } } + @Test + void testDeleteNotFound() { + try { + mockMvc.perform(delete("/answers/9999")) + .andExpect(status().isNotFound()); + } catch (Exception e) { + assert(false); + } + } } -- GitLab From bbdcb555faad742b78e8989bab649a57ba4e1f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gargalovi=C4=8D?= <xgargal@fi.muni.cz> Date: Fri, 14 Apr 2023 23:27:58 +0200 Subject: [PATCH 5/6] fixed exercise and question tests --- .../fuseri/moduleexercise/question/QuestionFacade.java | 2 +- .../fuseri/moduleexercise/exercise/ExerciseTest.java | 2 ++ .../fuseri/moduleexercise/question/QuestionTest.java | 10 ++++------ 3 files changed, 7 insertions(+), 7 deletions(-) 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 aabf8116..7e99230d 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 @@ -111,7 +111,7 @@ public class QuestionFacade { question.setExercise(qston.getExercise()); Question updatedQuestion = questionService.update(question); - var ddto = questionMapper.toDto(updatedQuestion); + return questionMapper.toDto(updatedQuestion); } diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java index 796b225e..30a025a3 100644 --- a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java @@ -61,7 +61,9 @@ public class ExerciseTest { void cleanup() { try { + mockMvc.perform(delete("/questions/reset")); mockMvc.perform(delete("/exercises/reset")); + mockMvc.perform(delete("/answers/reset")); } catch (Exception ex) { throw new RuntimeException(ex); } 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 5155e64a..2a97bb21 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 @@ -20,7 +20,6 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder 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; @@ -66,8 +65,8 @@ public class QuestionTest { 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)); + mockMvc.perform(post("/questions").content(asJsonString(question)).contentType(MediaType.APPLICATION_JSON)); + mockMvc.perform(post("/questions").content(asJsonString(question2)).contentType(MediaType.APPLICATION_JSON)); } catch (Exception e) { throw new RuntimeException(e); } @@ -78,6 +77,7 @@ public class QuestionTest { try { mockMvc.perform(delete("/questions/reset")); mockMvc.perform(delete("/exercises/reset")); + mockMvc.perform(delete("/answers/reset")); } catch (Exception ex) { throw new RuntimeException(ex); } @@ -91,7 +91,7 @@ public class QuestionTest { 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("$.exerciseId", is((int)exerciseId))) .andExpect(jsonPath("$.answers[0].text", is("dis very expencive"))); } @@ -168,8 +168,6 @@ public class QuestionTest { @Test void TestUpdate() throws Exception { - long id = 1; - var updated = """ { "text": "wat a paradox?", -- GitLab From 3e061fb0761a83188dcc62b3026000d4368a3153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gargalovi=C4=8D?= <xgargal@fi.muni.cz> Date: Sun, 16 Apr 2023 14:31:12 +0200 Subject: [PATCH 6/6] added some more tests --- .../model/dto/exercise/ExerciseCreateDto.java | 1 - application/module-exercise/pom.xml | 6 + .../exercise/ExerciseMapper.java | 11 ++ .../exercise/ExerciseRepository.java | 4 - .../answer/AnswerFacadeTest.java | 91 ++++++++++++++ .../answer/AnswerRepositoryTest.java | 101 +++++++++++++++ .../answer/AnswerServiceTest.java | 82 +++++++++++++ .../exercise/ExerciseFacadeTest.java | 106 ++++++++++++++++ .../exercise/ExerciseRepositoryTest.java | 106 ++++++++++++++++ .../exercise/ExerciseServiceTest.java | 115 ++++++++++++++++++ .../question/QuestionFacadeTest.java | 112 +++++++++++++++++ .../question/QuestionRepositoryTest.java | 88 ++++++++++++++ .../question/QuestionServiceTest.java | 66 ++++++++++ 13 files changed, 884 insertions(+), 5 deletions(-) create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerFacadeTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerRepositoryTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerServiceTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseFacadeTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseRepositoryTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseServiceTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionFacadeTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionRepositoryTest.java create mode 100644 application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionServiceTest.java diff --git a/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseCreateDto.java b/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseCreateDto.java index 21e7ee33..6d1cb1a7 100644 --- a/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseCreateDto.java +++ b/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseCreateDto.java @@ -9,7 +9,6 @@ import lombok.Getter; @AllArgsConstructor @Getter public class ExerciseCreateDto { - @NotBlank private String name; diff --git a/application/module-exercise/pom.xml b/application/module-exercise/pom.xml index d42b3eae..0623aed0 100644 --- a/application/module-exercise/pom.xml +++ b/application/module-exercise/pom.xml @@ -44,6 +44,12 @@ <version>0.0.1-SNAPSHOT</version> <scope>compile</scope> </dependency> + <dependency> + <groupId>org.fuseri</groupId> + <artifactId>sprachschulsystem</artifactId> + <version>0.0.1-SNAPSHOT</version> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseMapper.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseMapper.java index 3c211aaa..3b44db86 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseMapper.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseMapper.java @@ -1,9 +1,14 @@ package org.fuseri.moduleexercise.exercise; +import org.fuseri.model.dto.course.CourseDto; import org.fuseri.model.dto.exercise.ExerciseCreateDto; import org.fuseri.model.dto.exercise.ExerciseDto; import org.fuseri.moduleexercise.common.DomainMapper; import org.mapstruct.Mapper; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; + +import java.util.List; /** * Mapper between Exercises and their corresponding DTOs @@ -18,4 +23,10 @@ public interface ExerciseMapper extends DomainMapper<Exercise, ExerciseDto> { * @return corresponding Exercise entity created from DTO */ Exercise fromCreateDto(ExerciseCreateDto dto); + + List<ExerciseDto> mapToList(List<Exercise> persons); + + default Page<ExerciseDto> mapToPageDto(Page<Exercise> courses) { + return new PageImpl<>(mapToList(courses.getContent()), courses.getPageable(), courses.getTotalPages()); + } } diff --git a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java index cd0eba8d..6a4df023 100644 --- a/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java +++ b/application/module-exercise/src/main/java/org/fuseri/moduleexercise/exercise/ExerciseRepository.java @@ -33,10 +33,6 @@ public interface ExerciseRepository extends JpaRepository<Exercise, Long> { @Query("SELECT q FROM Exercise e JOIN e.questions q WHERE e.id = :exerciseId") Page<Question> getQuestions(PageRequest pageRequest, @Param("exerciseId") Long exerciseId); - @Modifying - @Transactional - @Query(value = "TRUNCATE Table exercise",nativeQuery = true) - void resetTable(); @Modifying @Transactional diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerFacadeTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerFacadeTest.java new file mode 100644 index 00000000..af06853f --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerFacadeTest.java @@ -0,0 +1,91 @@ +package org.fuseri.moduleexercise.answer; + +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.QuestionUpdateDto; +import org.fuseri.moduleexercise.exercise.Exercise; +import org.fuseri.moduleexercise.question.Question; +import org.fuseri.moduleexercise.question.QuestionService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import java.util.HashSet; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest +public class AnswerFacadeTest { + + private final Exercise exercise = new Exercise(); + private final Question question = new Question("text",new HashSet<>(),exercise); + + + private final AnswerDto answerDto = new AnswerDto("name",true); + + private final AnswerCreateDto answerCreateDto = new AnswerCreateDto("name",true,1L); + private final AnswerInQuestionCreateDto inQuestionCreateDto = new AnswerInQuestionCreateDto("name",true); + private final AnswersCreateDto answersCreateDto = new AnswersCreateDto(1L, List.of(inQuestionCreateDto)); + + private final QuestionUpdateDto questionUpdateDto = QuestionUpdateDto.builder().build(); + + private final Answer answer = new Answer("name",true,question); + + @MockBean + AnswerRepository repository; + @Autowired + AnswerFacade facade; + + @MockBean + AnswerService service; + + @MockBean + QuestionService questionService; + + @MockBean + AnswerMapper mapper; + @Test + void create() { + long id = 1; + when(service.find(id)).thenReturn(answer); + when(mapper.fromCreateDto(inQuestionCreateDto)).thenReturn(answer); + when(service.create(answer)).thenReturn(answer); + when(mapper.toDto(answer)).thenReturn(answerDto); + when(questionService.find(id)).thenReturn(question); + when(mapper.toDtoList(List.of(answer))).thenReturn(List.of(answerDto)); + + var actualDto = facade.createMultiple(answersCreateDto); + + assertEquals(List.of(answerDto), actualDto); + + } + + @Test + void update() { + Long id = 1L; + when(repository.existsById(id)).thenReturn(true); + when(service.find(id)).thenReturn(answer); + when(mapper.fromCreateDto(answerCreateDto)).thenReturn(answer); + when(service.update(answer)).thenReturn(answer); + when(mapper.toDto(answer)).thenReturn(answerDto); + AnswerDto actualDto = facade.update(id,answerCreateDto); + + + assertEquals(answerDto, actualDto); + } + @Test + void testDelete() { + Long id = 1L; + when(service.find(id)).thenReturn(answer); + when(questionService.find(answer.getId())).thenReturn(question); + facade.delete(id); + verify(service).delete(id); + } + +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerRepositoryTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerRepositoryTest.java new file mode 100644 index 00000000..9a4179ea --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerRepositoryTest.java @@ -0,0 +1,101 @@ +package org.fuseri.moduleexercise.answer; + +import org.fuseri.moduleexercise.exercise.Exercise; +import org.fuseri.moduleexercise.exercise.ExerciseRepository; +import org.fuseri.moduleexercise.question.Question; +import org.fuseri.moduleexercise.question.QuestionRepository; +import org.junit.jupiter.api.Assertions; +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.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; + +@DataJpaTest +public class AnswerRepositoryTest { + + @Autowired + AnswerRepository repository; + + @Autowired + QuestionRepository questionRepository; + + @Autowired + ExerciseRepository exerciseRepository; + + @Autowired + TestEntityManager entityManager; + + +// Question question = new Question("name","desc",2,1L,new HashSet<>()); + + Exercise exercise = new Exercise("name","desc",2,1L,new HashSet<>()); + + Question question = new Question("text",new HashSet<>(),exercise); + + Answer answer = new Answer("text",false,question); + Answer answer2 = new Answer("text2",true,question); + + @BeforeEach + void init() { + exerciseRepository.save(exercise); + questionRepository.save(question); + } + + @Test + void saveQuestion() { + Question saved = questionRepository.save(question); + + Assertions.assertNotNull(saved); + Assertions.assertEquals(question, saved); + } + + @Test + void findById() { + entityManager.persist(answer); + entityManager.flush(); + + Answer found = repository.findById(answer.getId()).orElse(null); +// Question found = questionRepository.findById(question.getId()).orElse(null); + + Assertions.assertNotNull(found); + Assertions.assertEquals(found, answer); + } + + + @Test + void testFindAllQuestions() { + entityManager.persist(answer); + entityManager.persist(answer2); + + Page<Answer> coursePage = repository.findAll(PageRequest.of(0, 42)); + + Assertions.assertEquals(2, coursePage.getTotalElements()); + Assertions.assertEquals(coursePage.getContent(), Arrays.asList(answer, answer2)); + } + + + @Test + void testFindAllQuestionsEmpty() { + Page<Answer> coursePage = repository.findAll(PageRequest.of(0, 42)); + + Assertions.assertEquals(0, coursePage.getTotalElements()); + Assertions.assertEquals(coursePage.getContent(), new ArrayList<>()); + } + + @Test + void testDeleteQuestion() { + Long id = entityManager.persist(answer).getId(); + entityManager.flush(); + + questionRepository.deleteById(id); + + Assertions.assertTrue(questionRepository.findById(id).isEmpty()); + } +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerServiceTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerServiceTest.java new file mode 100644 index 00000000..2c67bdc3 --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerServiceTest.java @@ -0,0 +1,82 @@ +package org.fuseri.moduleexercise.answer; + +import jakarta.persistence.EntityNotFoundException; +import org.fuseri.moduleexercise.exercise.Exercise; +import org.fuseri.moduleexercise.question.Question; +import org.fuseri.moduleexercise.question.QuestionRepository; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest +public class AnswerServiceTest { + @MockBean + AnswerRepository repository; + + @MockBean + QuestionRepository questionRepository; + + @Autowired + AnswerService service; + + Answer answer; + Question question; + Exercise exercise; + + @BeforeEach + void setup() { + exercise = new Exercise("idioms", "exercise on basic idioms", 2, 1L, new HashSet<Question>()); + question = new Question("text", new HashSet<>(), exercise); + answer = new Answer("text", false, question); + } + + + @Test + void create() { + when(repository.save(answer)).thenReturn(answer); + Answer result = service.create(answer); + Assertions.assertEquals(answer, result); + verify(repository).save(answer); + } + + @Test + void notFound() { + when(repository.findById(anyLong())).thenReturn(Optional.empty()); + + Assertions.assertThrows(EntityNotFoundException.class, () -> service.find(anyLong())); + } + + @Test + void find() { + when(repository.findById(anyLong())).thenReturn(Optional.of(answer)); + + Answer result = service.find(anyLong()); + + Assertions.assertEquals(answer, result); + verify(repository).findById(anyLong()); + } + + @Test + void findByQuestionId() { + long id = 1; + List<Answer> list = Collections.emptyList(); + + when(repository.existsById(id)).thenReturn(true); + when(repository.findByQuestionId(id)).thenReturn(list); + List<Answer> result = service.findAllByQuestionId(1L); + + Assertions.assertEquals(list, result); + verify(repository).findByQuestionId(id); + } +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseFacadeTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseFacadeTest.java new file mode 100644 index 00000000..d53519ac --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseFacadeTest.java @@ -0,0 +1,106 @@ +package org.fuseri.moduleexercise.exercise; + +import org.fuseri.model.dto.common.Result; +import org.fuseri.model.dto.exercise.ExerciseDto; +import org.fuseri.model.dto.exercise.ExerciseCreateDto; +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.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest +@AutoConfigureMockMvc +public class ExerciseFacadeTest { + + private final ExerciseDto exerciseDto = new ExerciseDto(); + + private final ExerciseCreateDto exerciseCreateDto = new ExerciseCreateDto("name","desc",2,1); + + private final Exercise exercise = new Exercise(); + + @Autowired + ExerciseFacade facade; + + @MockBean + ExerciseService service; + + @MockBean + ExerciseMapper mapper; + + + + @Test + void create() { + + when(mapper.fromCreateDto(exerciseCreateDto)).thenReturn(exercise); + when(service.create(exercise)).thenReturn(exercise); + when(mapper.toDto(exercise)).thenReturn(exerciseDto); + + ExerciseDto actualDto = facade.create(exerciseCreateDto); + + assertEquals(exerciseDto, actualDto); + + } + + @Test + void testFindById() { + Long id = 0L; + + when(service.find(id)).thenReturn(exercise); + when(mapper.toDto(exercise)).thenReturn(exerciseDto); + + ExerciseDto actualDto = facade.find(id); + + assertNotNull(actualDto); + assertEquals(exerciseDto, actualDto); + } + + + @Test + void testFindAll() { + int page = 0; + Pageable pageable = PageRequest.of(0, 10); + Page<Exercise> exercisePage = new PageImpl<>(List.of(exercise), pageable, 0); + Result<ExerciseDto> expectedPageDto = new Result<>(); + + + when(service.findAll(page)).thenReturn(exercisePage); + when(mapper.toResult(exercisePage)).thenReturn(expectedPageDto); + + Result<ExerciseDto> actualPageDto = facade.findAll(page); + + assertEquals(expectedPageDto, actualPageDto); + } + + @Test + void update() { + Long id = 1L; + when(mapper.fromCreateDto(exerciseCreateDto)).thenReturn(exercise); + when(service.update(exercise)).thenReturn(exercise); + when(mapper.toDto(exercise)).thenReturn(exerciseDto); + + ExerciseDto actualDto = facade.update(id, exerciseCreateDto); + + assertEquals(exerciseDto, actualDto); + } + + @Test + void testDelete() { + Long id = 1L; + facade.delete(id); + verify(service).delete(id); + } + +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseRepositoryTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseRepositoryTest.java new file mode 100644 index 00000000..6d9187ed --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseRepositoryTest.java @@ -0,0 +1,106 @@ +package org.fuseri.moduleexercise.exercise; + +import org.fuseri.moduleexercise.question.Question; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + + +@DataJpaTest +class ExerciseRepositoryTest { + + @Autowired + ExerciseRepository repository; + + @Autowired + TestEntityManager entityManager; + + + Exercise exercise = new Exercise("name", "desc", 2, 1L, new HashSet<>()); + + Question question = new Question("text", new HashSet<>(), exercise); + + @Test + void saveExercise() { + Exercise saved = repository.save(exercise); + + Assertions.assertNotNull(saved); + Assertions.assertEquals(exercise, saved); + } + + @Test + void findById() { + entityManager.persist(exercise); + entityManager.flush(); + + Exercise found = repository.findById(exercise.getId()).orElse(null); + + Assertions.assertNotNull(found); + Assertions.assertEquals(found, exercise); + } + + + @Test + void filterPerDiffPerCourse() { + entityManager.persist(exercise); + entityManager.flush(); + + Page<Exercise> found = repository.filterPerDifficultyPerCourse(PageRequest.of(0, 10), 1L, 2); + + Assertions.assertEquals(1, found.getTotalElements()); + Assertions.assertEquals(found.getContent().get(0), exercise); + } + + @Test + void testFindAllExercises() { + Exercise exercise1 = new Exercise(); + + entityManager.persist(exercise); + entityManager.persist(exercise1); + + Page<Exercise> coursePage = repository.findAll(PageRequest.of(0, 42)); + + Assertions.assertEquals(2, coursePage.getTotalElements()); + Assertions.assertEquals(coursePage.getContent(), Arrays.asList(exercise, exercise1)); + } + + @Test + void getQuestionsEmptyQuestions() { + entityManager.persist(exercise); + + var result = repository.getQuestions(PageRequest.of(0, 10), 1L); + + Assertions.assertEquals(0, result.getTotalElements()); + } + + @Test + void getQuestions() { + exercise.setQuestions(Set.of(question)); + entityManager.persist(exercise); + + var result = repository.getQuestions(PageRequest.of(0, 10), 1L); + + Assertions.assertEquals(1, result.getTotalElements()); + Assertions.assertEquals(result.getContent().get(0), question); + } + + @Test + void testDeleteExercise() { + Long id = entityManager.persist(exercise).getId(); + entityManager.flush(); + + repository.deleteById(id); + + Assertions.assertTrue(repository.findById(id).isEmpty()); + } + + +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseServiceTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseServiceTest.java new file mode 100644 index 00000000..4624d554 --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseServiceTest.java @@ -0,0 +1,115 @@ +package org.fuseri.moduleexercise.exercise; + +import jakarta.persistence.EntityNotFoundException; +import org.fuseri.model.dto.exercise.ExerciseCreateDto; +//import org.fuseri.modulelanguageschool.common.ResourceNotFoundException; + +import org.fuseri.model.dto.exercise.ExerciseDto; +import org.fuseri.moduleexercise.question.Question; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +@SpringBootTest +public class ExerciseServiceTest { + + @MockBean + ExerciseRepository repository; + + @Autowired + ExerciseService service; + + Exercise exercise; + ExerciseCreateDto exercise2; + ExerciseCreateDto exercise3; + + @BeforeEach + void setup() { + exercise = new Exercise("idioms", "exercise on basic idioms",2,1L,new HashSet<Question>()); + exercise2 = new ExerciseCreateDto("idioms1", "exercise on intermediate idioms", 2, 0); + exercise3 = new ExerciseCreateDto("idioms2", "exercise on basic idioms", 1, 0L); + } + + + @Test + void create() { + when(repository.save(exercise)).thenReturn(exercise); + Exercise result = service.create(exercise); + Assertions.assertEquals(exercise, result); + verify(repository).save(exercise); + } + + @Test + void notFound() { + when(repository.findById(anyLong())).thenReturn(Optional.empty()); + + Assertions.assertThrows(EntityNotFoundException.class, () -> service.find(anyLong())); + } + + @Test + void find() { + when(repository.findById(anyLong())).thenReturn(Optional.of(exercise)); + + Exercise result = service.find(anyLong()); + + Assertions.assertEquals(exercise, result); + verify(repository).findById(anyLong()); + } + + @Test + void findAll() { + Pageable pageable = PageRequest.of(0, 10); + Page<Exercise> page = new PageImpl<>(Collections.emptyList(), pageable, 0); + + when(repository.findAll(pageable)).thenReturn(page); + Page<Exercise> result = service.findAll(0); + + Assertions.assertEquals(page, result); + verify(repository).findAll(pageable); + } + + @Test + void findPerDiffPerCourse() { + PageRequest pageable = PageRequest.of(0, 10); + Page<Exercise> page = new PageImpl<>(Collections.emptyList(), pageable, 0); + + when(repository.filterPerDifficultyPerCourse(pageable,1L,2)).thenReturn(page); + + Page<Exercise> result = service.findPerDifficultyPerCourse(0,1L,2); + + Assertions.assertEquals(page, result); + verify(repository).filterPerDifficultyPerCourse(pageable,1L,2); + } + + + @Test + void getQuestions() { + PageRequest pageable = PageRequest.of(0, 10); + Page<Question> page = new PageImpl<>(Collections.emptyList(), pageable, 0); + + when(repository.getQuestions(pageable,1L)).thenReturn(page); + when(repository.existsById(1L)).thenReturn(true); + + + Page<Question> result = service.getQuestions(1L,0); + + Assertions.assertEquals(page, result); + verify(repository).getQuestions(pageable,1L); + } +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionFacadeTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionFacadeTest.java new file mode 100644 index 00000000..bf9cb27e --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionFacadeTest.java @@ -0,0 +1,112 @@ +package org.fuseri.moduleexercise.question; + + +import org.fuseri.model.dto.exercise.QuestionCreateDto; +import org.fuseri.model.dto.exercise.QuestionDto; +import org.fuseri.model.dto.exercise.QuestionUpdateDto; +import org.fuseri.moduleexercise.answer.AnswerService; +import org.fuseri.moduleexercise.exercise.Exercise; +import org.fuseri.moduleexercise.exercise.ExerciseService; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest +public class QuestionFacadeTest { + private final QuestionDto questionDto = new QuestionDto(); + + private final QuestionCreateDto questionCreateDto = new QuestionCreateDto("name",1L,new ArrayList<>()); + + private final QuestionUpdateDto questionUpdateDto = QuestionUpdateDto.builder().build(); + + private final Exercise exercise = new Exercise(); + private final Question question = new Question("text",new HashSet<>(),exercise); + + @MockBean + QuestionRepository repository; + @Autowired + QuestionFacade facade; + + @MockBean + QuestionService service; + + @MockBean + AnswerService answerService; + + @MockBean + QuestionMapper mapper; + + + @MockBean + ExerciseService exerciseService; +// +// @MockBean +// QuestionMapper mapper; + + @Test + void create() { + long id = 1; + when(exerciseService.find(id)).thenReturn(exercise); + when(mapper.fromCreateDto(questionCreateDto)).thenReturn(question); + when(service.create(question)).thenReturn(question); + when(mapper.toDto(question)).thenReturn(questionDto); + + QuestionDto actualDto = facade.create(questionCreateDto); + + assertEquals(questionDto, actualDto); + + } + + @Test + void testFindById() { + Long id = 0L; + + when(service.find(id)).thenReturn(question); + when(mapper.toDto(question)).thenReturn(questionDto); + + QuestionDto actualDto = facade.find(id); + + assertNotNull(actualDto); + assertEquals(questionDto, actualDto); + } + + + + + @Test + void update() { + Long id = 1L; + when(repository.existsById(id)).thenReturn(true); +// when(repository.find) + when(service.find(id)).thenReturn(question); + when(mapper.fromCreateDto(questionCreateDto)).thenReturn(question); + when(service.update(question)).thenReturn(question); + when(mapper.toDto(question)).thenReturn(questionDto); + when(mapper.fromUpdateDto(questionUpdateDto)).thenReturn(question); + when(answerService.findAllByQuestionId(id)).thenReturn(Collections.emptyList()); + QuestionDto actualDto = facade.update(id,questionUpdateDto); + + + assertEquals(questionDto, actualDto); + } + + @Test + void testDelete() { + Long id = 1L; + when(service.find(id)).thenReturn(question); + + facade.delete(id); + verify(service).delete(id); + } + +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionRepositoryTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionRepositoryTest.java new file mode 100644 index 00000000..3c0eb33e --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionRepositoryTest.java @@ -0,0 +1,88 @@ +package org.fuseri.moduleexercise.question; + +import org.fuseri.moduleexercise.exercise.Exercise; +import org.fuseri.moduleexercise.exercise.ExerciseRepository; +import org.junit.jupiter.api.Assertions; +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.orm.jpa.DataJpaTest; +import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; + +@DataJpaTest +public class QuestionRepositoryTest { + + @Autowired + QuestionRepository repository; + + @Autowired + ExerciseRepository exerciseRepository; + + @Autowired + TestEntityManager entityManager; + + + Exercise exercise = new Exercise("name","desc",2,1L,new HashSet<>()); + + Question question = new Question("text",new HashSet<>(),exercise); + Question question2 = new Question("text2",new HashSet<>(),exercise); + + @BeforeEach + void init() { + exerciseRepository.save(exercise); + } + + @Test + void saveQuestion() { + Question saved = repository.save(question); + + Assertions.assertNotNull(saved); + Assertions.assertEquals(question, saved); + } + + @Test + void findById() { + entityManager.persist(question); + entityManager.flush(); + + Question found = repository.findById(question.getId()).orElse(null); + + Assertions.assertNotNull(found); + Assertions.assertEquals(found, question); + } + + + @Test + void testFindAllQuestions() { + entityManager.persist(question); + entityManager.persist(question2); + + Page<Question> coursePage = repository.findAll(PageRequest.of(0, 42)); + + Assertions.assertEquals(2, coursePage.getTotalElements()); + Assertions.assertEquals(coursePage.getContent(), Arrays.asList(question, question2)); + } + @Test + void testFindAllQuestionsEmpty() { + Page<Question> coursePage = repository.findAll(PageRequest.of(0, 42)); + + Assertions.assertEquals(0, coursePage.getTotalElements()); + Assertions.assertEquals(coursePage.getContent(), new ArrayList<>()); + } + + @Test + void testDeleteQuestion() { + Long id = entityManager.persist(question).getId(); + entityManager.flush(); + + repository.deleteById(id); + + Assertions.assertTrue(repository.findById(id).isEmpty()); + } +} diff --git a/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionServiceTest.java b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionServiceTest.java new file mode 100644 index 00000000..e2085f85 --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionServiceTest.java @@ -0,0 +1,66 @@ +package org.fuseri.moduleexercise.question; + +import jakarta.persistence.EntityNotFoundException; +import org.fuseri.moduleexercise.exercise.Exercise; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import java.util.HashSet; +import java.util.Optional; + +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@SpringBootTest +public class QuestionServiceTest { + + + + @MockBean + QuestionRepository repository; + + @Autowired + QuestionService service; + + Exercise exercise; + Question question; + Question question1; + + @BeforeEach + void setup() { + exercise = new Exercise("idioms", "exercise on basic idioms",2,1L,new HashSet<Question>()); + question = new Question("text",new HashSet<>(),exercise); + question1 = new Question("text2",new HashSet<>(),exercise); + } + + + @Test + void create() { + when(repository.save(question)).thenReturn(question); + Question result = service.create(question); + Assertions.assertEquals(question, result); + verify(repository).save(question); + } + + @Test + void notFound() { + when(repository.findById(anyLong())).thenReturn(Optional.empty()); + + Assertions.assertThrows(EntityNotFoundException.class, () -> service.find(anyLong())); + } + + @Test + void find() { + when(repository.findById(anyLong())).thenReturn(Optional.of(question)); + + Question result = service.find(anyLong()); + + Assertions.assertEquals(question, result); + verify(repository).findById(anyLong()); + } + +} -- GitLab