diff --git a/application/model/src/main/java/org/fuseri/model/dto/exercise/AnswerDto.java b/application/model/src/main/java/org/fuseri/model/dto/exercise/AnswerDto.java index 632cf5c472ffc75689a33ead0ccecdd718d96b35..433244900c287f01549b3e43a4971f68a86a2cc7 100644 --- a/application/model/src/main/java/org/fuseri/model/dto/exercise/AnswerDto.java +++ b/application/model/src/main/java/org/fuseri/model/dto/exercise/AnswerDto.java @@ -6,6 +6,8 @@ import lombok.AllArgsConstructor; import lombok.Getter; import org.fuseri.model.dto.common.DomainObjectDto; +import java.util.Objects; + @AllArgsConstructor @Getter public class AnswerDto extends DomainObjectDto { @@ -15,4 +17,22 @@ public class AnswerDto extends DomainObjectDto { @NotNull private boolean correct; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AnswerDto answerDto = (AnswerDto) o; + + if (correct != answerDto.correct) return false; + return Objects.equals(text, answerDto.text); + } + + @Override + public int hashCode() { + int result = text != null ? text.hashCode() : 0; + result = 31 * result + (correct ? 1 : 0); + return result; + } } diff --git a/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseDto.java b/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseDto.java index 250c3025478d0b155b8e0013e6ac58ac16ea9402..ff7abd444839ba89d15b50e72f31a3973b62ceef 100644 --- a/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseDto.java +++ b/application/model/src/main/java/org/fuseri/model/dto/exercise/ExerciseDto.java @@ -7,6 +7,8 @@ import lombok.Getter; import lombok.Setter; import org.fuseri.model.dto.common.DomainObjectDto; +import java.util.Objects; + @Getter @Setter public class ExerciseDto extends DomainObjectDto { @@ -23,4 +25,26 @@ public class ExerciseDto extends DomainObjectDto { @NotBlank private String courseId; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ExerciseDto that = (ExerciseDto) o; + + if (difficulty != that.difficulty) return false; + if (!Objects.equals(name, that.name)) return false; + if (!Objects.equals(description, that.description)) return false; + return Objects.equals(courseId, that.courseId); + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + (description != null ? description.hashCode() : 0); + result = 31 * result + difficulty; + result = 31 * result + (courseId != null ? courseId.hashCode() : 0); + return result; + } } diff --git a/application/model/src/main/java/org/fuseri/model/dto/exercise/QuestionDto.java b/application/model/src/main/java/org/fuseri/model/dto/exercise/QuestionDto.java index 6aa390931227ecb391227689ed1451c5f226aa7e..5cca20b14b60c9361eaea0893ff874500b690c61 100644 --- a/application/model/src/main/java/org/fuseri/model/dto/exercise/QuestionDto.java +++ b/application/model/src/main/java/org/fuseri/model/dto/exercise/QuestionDto.java @@ -7,6 +7,7 @@ import lombok.Setter; import org.fuseri.model.dto.common.DomainObjectDto; import java.util.List; +import java.util.Objects; @Getter @Setter @@ -20,4 +21,24 @@ public class QuestionDto extends DomainObjectDto { @Valid private List<AnswerDto> answers; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + QuestionDto that = (QuestionDto) o; + + if (!Objects.equals(text, that.text)) return false; + if (!Objects.equals(exerciseId, that.exerciseId)) return false; + return Objects.equals(answers, that.answers); + } + + @Override + public int hashCode() { + int result = text != null ? text.hashCode() : 0; + result = 31 * result + (exerciseId != null ? exerciseId.hashCode() : 0); + result = 31 * result + (answers != null ? answers.hashCode() : 0); + return result; + } } 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 new file mode 100644 index 0000000000000000000000000000000000000000..f3fd9e3e3a438386b2f2723edaef20b84b1c9db3 --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/answer/AnswerTest.java @@ -0,0 +1,173 @@ +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.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 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.List; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; + +@SpringBootTest +@AutoConfigureMockMvc +public class AnswerTest { + + @Autowired + ObjectMapper objectMapper; + @Autowired + private MockMvc mockMvc; + + public static String asJsonString(final Object obj) { + try { + return new ObjectMapper().writeValueAsString(obj); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private QuestionDto createQuestion(String 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; + } + + + private String createExercise() { + var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, "0"); + + String id = ""; + + 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(); + } catch (Exception e) { + assert (false); + } + return id; + } + + + @Test + void testCreateAnswer() throws Exception { + + List<AnswerDto> res = createAnswr(); + + var expected1 = new AnswerDto("True", false); + var expected2 = new AnswerDto("False", false); + + assert (res.get(0).equals(expected1)); + assert (res.get(1).equals(expected2)); + + } + + private List<AnswerDto> createAnswr() throws Exception { + var exerciseId = createExercise(); + var question = createQuestion(exerciseId); + + var incorrect1 = new AnswerInQuestionCreateDto("True", false); + var incorrect2 = new AnswerInQuestionCreateDto("False", false); + + var createAnswer = new AnswersCreateDto(question.getId(), List.of(incorrect1, incorrect2)); + + 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; + } + + + @Test + void getAnswer() throws Exception { + var exerciseId = createExercise(); + var question = createQuestion(exerciseId); + + var gets = mockMvc.perform(get(String.format("/answers/%s", question.getId()))); + + var content2 = gets.andReturn().getResponse().getContentAsString(); + + var res = objectMapper.readValue(content2, new TypeReference<List<AnswerDto>>() { + }); + + assert (res.equals(question.getAnswers())); + + } + + @Test + void TestUpdate() throws Exception { + + var exerciseId = createExercise(); + var question = createQuestion(exerciseId); + + var incorrect1 = new AnswerInQuestionCreateDto("True", false); + var incorrect2 = new AnswerInQuestionCreateDto("False", false); + + + var createAnswer = new AnswersCreateDto(question.getId(), List.of(incorrect1, incorrect2)); + + + 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>>() { + }); + + + var updated = """ + { + "text": "dis true", + "correct": false, + "questionId": "%s" + } + """; + + + 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); + + } + +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..00902bdcd8cbd8850552443d7d727cd500fe7a4a --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/exercise/ExerciseTest.java @@ -0,0 +1,161 @@ +package org.fuseri.moduleexercise.exercise; + +import com.fasterxml.jackson.core.type.TypeReference; +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.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.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; + + +@SpringBootTest +@AutoConfigureMockMvc +public class ExerciseTest { + @Autowired + ObjectMapper objectMapper; + @Autowired + private MockMvc mockMvc; + + public static String asJsonString(final Object obj) { + try { + return new ObjectMapper().writeValueAsString(obj); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + @Test + void getExercise() { + var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, "0"); + + String id = ""; + + 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(); + } catch (Exception e) { + assert (false); + } + + + try { + var theId = String.format("/exercises/%s", id); + var smth = mockMvc.perform(get(theId)); + + } catch (Exception e) { + //do absolutely nothing + } + } + + @Test + void getFiltered() { + + + var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 0, "0"); + var postExercise1 = new ExerciseCreateDto("idioms1", "exercise on basic idioms", 0, "0"); + var postExercise2 = new ExerciseCreateDto("idioms2", "exercise on basic idioms", 1, "0"); + + try { + var exercise1 = mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON)); + + 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 + } + + + Map<String, String> params; + + try { + var filtered = mockMvc.perform(get("/exercises/filter").param("page", "0").param("courseId", "0").param("difficulty", "0")); + + var content = filtered.andReturn().getResponse().getContentAsString(); + + var res = objectMapper.readValue(content, new TypeReference<Result<ExerciseDto>>() { + }); + + assert (res.getTotal() == 2); + } catch (Exception e) { + assert (false); + } + } + + @Test + void testCreateExercise() throws Exception { + var expectedResponse = new ExerciseDto(); + var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, "0"); + + mockMvc.perform(post("/exercises").content(asJsonString(postExercise)).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).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 TestUpdate() { + var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, "0"); + + String id = ""; + + 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(); + } catch (Exception e) { + assert (false); + } + + var expectedExercise = new ExerciseDto(); + expectedExercise.setId(id); + expectedExercise.setName("idioms"); + expectedExercise.setDifficulty(2); + expectedExercise.setCourseId("idioms"); + expectedExercise.setDescription("exercise on basic idioms"); + + var content = """ + { + "name": "idioms", + "description": "exercise on basic idioms", + "difficulty": 2, + "courseId": "idioms" + } + """; + + + try { + var theId = String.format("/exercises/%s", id); + var dis = mockMvc.perform(put(theId).content(content).contentType(MediaType.APPLICATION_JSON)); + + var str = dis.andReturn().getResponse().getContentAsString(); + + var res = objectMapper.readValue(str, ExerciseDto.class); + + assert res.equals(expectedExercise); + + } catch (Exception e) { + throw new RuntimeException(e); + } + + } + +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..a099ff7c8cf058e033931222d5c76469ac40003e --- /dev/null +++ b/application/module-exercise/src/test/java/org/fuseri/moduleexercise/question/QuestionTest.java @@ -0,0 +1,153 @@ +package org.fuseri.moduleexercise.question; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.fuseri.model.dto.common.Result; +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.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.List; +import java.util.Map; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; + + +@SpringBootTest +@AutoConfigureMockMvc +public class QuestionTest { + + @Autowired + ObjectMapper objectMapper; + @Autowired + private MockMvc mockMvc; + + public static String asJsonString(final Object obj) { + try { + return new ObjectMapper().writeValueAsString(obj); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Test + void testCreateQuestion() throws Exception { + String 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 QuestionDto createQuestion(String 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; + } + + private String createExercise() { + var postExercise = new ExerciseCreateDto("idioms", "exercise on basic idioms", 2, "0"); + + String id = ""; + + 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(); + } catch (Exception e) { + assert (false); + } + return id; + } + + + @Test + void getQuestion() throws Exception { + + + String exerciseId = createExercise(); + var question = createQuestion(exerciseId); + + var theId = String.format("/questions/%s", question.getId()); + + + var gets = mockMvc.perform(get(theId)); + + var content = gets.andReturn().getResponse().getContentAsString(); + var res = objectMapper.readValue(content, QuestionDto.class); + + assert res.equals(question); + + } + + @Test + void getByExercise() throws Exception { + + var exerciseId = createExercise(); + var question = createQuestion(exerciseId); + + var theId = String.format("/questions/exercise/%s", exerciseId); + + var smth = mockMvc.perform(get(theId).param("page", "0")); + + var content = smth.andReturn().getResponse().getContentAsString(); + + var res = objectMapper.readValue(content, new TypeReference<Result<QuestionDto>>() { + }); + + Map<String, String> params; + + assert (res.getItems().get(0).equals(question)); + } + + @Test + void TestUpdate() throws Exception { + String id = createExercise(); + var question = createQuestion(id); + + var updated = """ + { + "text": "wat a paradox?", + "exerciseId": "%s" + } + """; + + 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); + + question.setText("wat a paradox?"); + + assert (question.equals(res)); + + } +}