diff --git a/api/pom.xml b/api/pom.xml index fe6bed8d5586379cb9254b99e4c79b59a177d52b..66ed7cf7a68a41d9d7e4ff9a2cca73b0b6c191d4 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -76,6 +76,13 @@ <artifactId>postgresql</artifactId> </dependency> + <!-- https://mvnrepository.com/artifact/junit/junit --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13</version> + <scope>test</scope> + </dependency> <!-- Logging --> <dependency> @@ -108,6 +115,14 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> + <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <version>1.10.19</version> + <scope>test</scope> + </dependency> + </dependencies> <build> diff --git a/api/src/main/java/cz/cvut/fel/sem/controller/QuizController.java b/api/src/main/java/cz/cvut/fel/sem/controller/QuizController.java index bf95cf6ddefc6da35519d0bd8551aee9795de7ee..cf25325f24fa060a474ced9e8e8754df0acb7dce 100644 --- a/api/src/main/java/cz/cvut/fel/sem/controller/QuizController.java +++ b/api/src/main/java/cz/cvut/fel/sem/controller/QuizController.java @@ -34,12 +34,12 @@ public class QuizController { @CrossOrigin @GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) public Quiz getQuiz(@PathVariable Long id) { - return quizService.getQuiz(id); + return quizService.getQuizById(id); } @CrossOrigin @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) public List<QuizDto> getAll() { - return quizService.getAllQuizes(); + return quizService.getAllQuizzes(); } } diff --git a/api/src/main/java/cz/cvut/fel/sem/controller/UserController.java b/api/src/main/java/cz/cvut/fel/sem/controller/UserController.java index 38a07d10e4b44cc097028de37908fcf02e5e5882..204ae01d2f8105b80dd6e0c424a3e13e4893ba13 100644 --- a/api/src/main/java/cz/cvut/fel/sem/controller/UserController.java +++ b/api/src/main/java/cz/cvut/fel/sem/controller/UserController.java @@ -37,7 +37,7 @@ public class UserController { @CrossOrigin @GetMapping(value = "/{email:.+}", produces = MediaType.APPLICATION_JSON_VALUE) public Boolean getUserByEmail(@PathVariable String email) { - return userService.getUserByEmail(email) != null; + return userService.exists(email); } /*@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE) diff --git a/api/src/main/java/cz/cvut/fel/sem/mapper/AnswerMapper.java b/api/src/main/java/cz/cvut/fel/sem/mapper/AnswerMapper.java index cb32919dc8809ac9e1e162fbe2f25adb7784d199..22c6a4545797a5444a81e073adfe7774673cb749 100644 --- a/api/src/main/java/cz/cvut/fel/sem/mapper/AnswerMapper.java +++ b/api/src/main/java/cz/cvut/fel/sem/mapper/AnswerMapper.java @@ -6,6 +6,8 @@ import cz.cvut.fel.sem.model.quizQuestion.AnswerPosition; import cz.cvut.fel.sem.model.quizQuestion.Question; import org.springframework.stereotype.Component; +import java.util.List; + @Component public class AnswerMapper { public Answer mapToModel(AnswerDto answerDto, AnswerPosition answerPosition, Question question){ @@ -15,4 +17,15 @@ public class AnswerMapper { public AnswerDto mapToDto(Answer answer){ return new AnswerDto(answer.getValue(), answer.isCorrect()); } + + public AnswerDto getSpecificAnswerDtoFromList(List<Answer> answerList, AnswerPosition answerPosition){ + Answer answerToMap = null; + for(Answer answer : answerList){ + if(answer.getAnswerPosition().equals(answerPosition)){ + answerToMap = answer; + } + } + answerToMap = answerToMap == null ? new Answer("", false, answerPosition, null) : answerToMap; + return mapToDto(answerToMap); + } } diff --git a/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionMapper.java b/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionMapper.java index 48a5ace587261a7a52bcf23d264f23e72ca200fe..d9426911fa33c87b727221a8a3a65054d65116a5 100644 --- a/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionMapper.java +++ b/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionMapper.java @@ -2,7 +2,6 @@ package cz.cvut.fel.sem.mapper; import cz.cvut.fel.sem.dto.question.AnswerDto; import cz.cvut.fel.sem.dto.question.QuestionDto; -import cz.cvut.fel.sem.dto.question.QuestionTextDto; import cz.cvut.fel.sem.model.quizQuestion.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -48,22 +47,11 @@ public class QuestionMapper { return questions; } - public AnswerDto getAnswer(List<Answer> answerList, AnswerPosition answerPosition){ - Answer answerToMap = null; - for(Answer answer : answerList){ - if(answer.getAnswerPosition().equals(answerPosition)){ - answerToMap = answer; - } - } - answerToMap = answerToMap == null ? new Answer("", false, answerPosition, null) : answerToMap; - return answerMapper.mapToDto(answerToMap); - } - public QuestionDto mapOneQuestionToDto(Question question){ - AnswerDto topRightAnswer = getAnswer(question.getAnswers(), AnswerPosition.TOPRIGHT); - AnswerDto topLeftAnswer = getAnswer(question.getAnswers(), AnswerPosition.TOPLEFT); - AnswerDto bottomRightAnswer = getAnswer(question.getAnswers(), AnswerPosition.BOTTOMRIGHT); - AnswerDto bottomLeftAnswer = getAnswer(question.getAnswers(), AnswerPosition.BOTTOMLEFT); + AnswerDto topRightAnswer = answerMapper.getSpecificAnswerDtoFromList(question.getAnswers(), AnswerPosition.TOPRIGHT); + AnswerDto topLeftAnswer = answerMapper.getSpecificAnswerDtoFromList(question.getAnswers(), AnswerPosition.TOPLEFT); + AnswerDto bottomRightAnswer = answerMapper.getSpecificAnswerDtoFromList(question.getAnswers(), AnswerPosition.BOTTOMRIGHT); + AnswerDto bottomLeftAnswer = answerMapper.getSpecificAnswerDtoFromList(question.getAnswers(), AnswerPosition.BOTTOMLEFT); return new QuestionDto( question.getKey(), question.getQuestionType(), diff --git a/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionTextMapper.java b/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionTextMapper.java index 67b2ab88f68e52e0e18a9dafa74f7b4c8bb929d0..808c3ba06f248a8550d4b269e978ea5eb0c81cfa 100644 --- a/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionTextMapper.java +++ b/api/src/main/java/cz/cvut/fel/sem/mapper/QuestionTextMapper.java @@ -1,7 +1,6 @@ package cz.cvut.fel.sem.mapper; import cz.cvut.fel.sem.dto.question.QuestionTextDto; -import cz.cvut.fel.sem.model.quizQuestion.LanguageType; import cz.cvut.fel.sem.model.quizQuestion.QuestionText; import cz.cvut.fel.sem.model.quizQuestion.Question; import org.springframework.beans.factory.annotation.Autowired; @@ -16,7 +15,6 @@ public class QuestionTextMapper { this.languageTypeMapper = languageTypeMapper; } - public QuestionText mapToModel(QuestionTextDto questionTextDto, Question question){ return new QuestionText( questionTextDto.getValue(), diff --git a/api/src/main/java/cz/cvut/fel/sem/repository/QuestionRepository.java b/api/src/main/java/cz/cvut/fel/sem/repository/QuestionRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..313f6f45529978f101968cc2ab9faa587796dac0 --- /dev/null +++ b/api/src/main/java/cz/cvut/fel/sem/repository/QuestionRepository.java @@ -0,0 +1,8 @@ +package cz.cvut.fel.sem.repository; + + +import cz.cvut.fel.sem.model.quizQuestion.Question; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface QuestionRepository extends JpaRepository<Question, Long> { +} diff --git a/api/src/main/java/cz/cvut/fel/sem/service/QuizService.java b/api/src/main/java/cz/cvut/fel/sem/service/QuizService.java index 8ea61232929b44a78bd9691a3cf1f842d4d8606d..fb3703f026d46af5522d860964335c12e14b7836 100644 --- a/api/src/main/java/cz/cvut/fel/sem/service/QuizService.java +++ b/api/src/main/java/cz/cvut/fel/sem/service/QuizService.java @@ -1,9 +1,11 @@ package cz.cvut.fel.sem.service; import cz.cvut.fel.sem.dto.question.QuizDto; +import cz.cvut.fel.sem.exception.NotFoundException; import cz.cvut.fel.sem.mapper.QuizMapper; import cz.cvut.fel.sem.model.quizQuestion.Question; import cz.cvut.fel.sem.model.quizQuestion.Quiz; +import cz.cvut.fel.sem.repository.QuestionRepository; import cz.cvut.fel.sem.repository.QuizRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -17,27 +19,40 @@ import java.util.Objects; public class QuizService { private final QuizRepository quizRepository; private final QuizMapper quizMapper; + private final QuestionRepository questionRepository; @Autowired - public QuizService(QuizRepository quizRepository, QuizMapper quizMapper) { + public QuizService(QuizRepository quizRepository, QuizMapper quizMapper, QuestionRepository questionRepository) { this.quizRepository = quizRepository; this.quizMapper = quizMapper; + this.questionRepository = questionRepository; } @Transactional public void saveQuiz(QuizDto quizDto) { Objects.requireNonNull(quizDto); + //If the quiz is being updated, delete its questions first to prevent database duplicating + if(quizDto.getId() != null){ + Quiz originalQuiz = quizRepository.getOne(quizDto.getId()); + for(Question question : originalQuiz.getQuestions()){ + questionRepository.delete(question); + } + } Quiz quizToSave = quizMapper.mapToModel(quizDto); quizRepository.save(quizToSave); } @Transactional - public Quiz getQuiz(Long id){ - return quizRepository.getOne(id); + public Quiz getQuizById(Long id){ + Quiz foundQuiz = quizRepository.getOne(id); + if(foundQuiz == null){ + throw new NotFoundException("Quiz with id " + id + "was not found"); + } + return foundQuiz; } @Transactional - public List<QuizDto> getAllQuizes(){ + public List<QuizDto> getAllQuizzes(){ List<Quiz> quizzes = quizRepository.findAll(); List<QuizDto> quizDtos = new ArrayList<>(); for(Quiz quiz : quizzes){ diff --git a/api/src/main/java/cz/cvut/fel/sem/service/UserService.java b/api/src/main/java/cz/cvut/fel/sem/service/UserService.java index e677b7ccf5d1302a8d794f8a0e6a5cd4c9f7932b..574ffda4d10a52ba74127b30608c8228a05cbfac 100644 --- a/api/src/main/java/cz/cvut/fel/sem/service/UserService.java +++ b/api/src/main/java/cz/cvut/fel/sem/service/UserService.java @@ -34,7 +34,11 @@ public class UserService { @Transactional public User getUserByEmail(String email) { Objects.requireNonNull(email); - return userRepository.findByEmail(email); + User user = userRepository.findByEmail(email); + if(user == null) { + throw new NotFoundException("User with email" + email + " was not found"); + } + return user; } @Transactional @@ -42,7 +46,7 @@ public class UserService { Objects.requireNonNull(id); Optional<User> optionalUser = userRepository.findById(id); if(!optionalUser.isPresent()){ - throw new NotFoundException("User with " + id + " was not found"); + throw new NotFoundException("User with id" + id + " was not found"); } return optionalUser.get(); } diff --git a/api/src/test/java/cz/cvut/fel/sem/mapper/AnswerMapperTest.java b/api/src/test/java/cz/cvut/fel/sem/mapper/AnswerMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..753bbf43b81e188a4f05fdf72086f442ddcceafe --- /dev/null +++ b/api/src/test/java/cz/cvut/fel/sem/mapper/AnswerMapperTest.java @@ -0,0 +1,63 @@ +package cz.cvut.fel.sem.mapper; + +import cz.cvut.fel.sem.dto.question.AnswerDto; +import cz.cvut.fel.sem.model.quizQuestion.Answer; +import cz.cvut.fel.sem.model.quizQuestion.AnswerPosition; +import cz.cvut.fel.sem.model.quizQuestion.Question; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.List; + +import static org.junit.Assert.*; + +@RunWith(MockitoJUnitRunner.class) +public class AnswerMapperTest { + @InjectMocks private AnswerMapper sut; + + @Test + public void mapToModel_answerDtoProvided_answerObjectWithCorrectValuesReturned(){ + //Arrange + AnswerDto answerDto = new AnswerDto("answerValue", true); + AnswerPosition answerPosition = AnswerPosition.TOPLEFT; + Question question = new Question(); + + //Act + Answer actualResult = sut.mapToModel(answerDto, answerPosition, question); + + //Verify + assertEquals("answerValue", actualResult.getValue()); + assertTrue(actualResult.isCorrect()); + assertEquals(AnswerPosition.TOPLEFT, actualResult.getAnswerPosition()); + assertEquals(question, actualResult.getQuestion()); + } + + @Test + public void mapToDto_answerProvided_answerDtoObjectWithCorrectValuesReturned(){ + //Arrange + Answer answer = new Answer("answerValue", true, AnswerPosition.TOPLEFT, new Question()); + + //Act + AnswerDto actualResult = sut.mapToDto(answer); + + //Verify + assertEquals("answerValue", actualResult.getValue()); + assertTrue(actualResult.isCorrect()); + } + + @Test + public void getSpecificAnswerDtoFromList_validArgumentsProvided_answerReturned(){ + //Arrange + Answer answer = new Answer("answerValue", true, AnswerPosition.TOPLEFT, null); + Answer answer2 = new Answer("answerValue2", true, AnswerPosition.TOPRIGHT, null); + List<Answer> answersList = List.of(answer, answer2); + + //Act + AnswerDto actualResult = sut.getSpecificAnswerDtoFromList(answersList, AnswerPosition.TOPRIGHT); + + //Verify + assertEquals(answer2.getValue(), actualResult.getValue()); + } +} diff --git a/api/src/test/java/cz/cvut/fel/sem/mapper/LanguageTypeMapperTest.java b/api/src/test/java/cz/cvut/fel/sem/mapper/LanguageTypeMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8224d44eaae8858f0b0192ef22de6ec2a88f31dc --- /dev/null +++ b/api/src/test/java/cz/cvut/fel/sem/mapper/LanguageTypeMapperTest.java @@ -0,0 +1,87 @@ +package cz.cvut.fel.sem.mapper; + +import cz.cvut.fel.sem.exception.NotFoundException; +import cz.cvut.fel.sem.model.quizQuestion.LanguageType; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.junit.MockitoJUnitRunner; +import static org.junit.Assert.*; + +@RunWith(MockitoJUnitRunner.class) +public class LanguageTypeMapperTest { + @InjectMocks + private LanguageTypeMapper sut; + + @Test + public void mapStringToLanguageType_javaStringProvided_javaEnumReturned(){ + //Arrange + String javaString = "text/x-java"; + + //Act + LanguageType actualResult = sut.mapStringToLanguageType(javaString); + + //Verify + assertEquals(actualResult, LanguageType.JAVA); + } + + @Test + public void mapStringToLanguageType_cStringProvided_cEnumReturned(){ + //Arrange + String cString = "text/x-csrc"; + + //Act + LanguageType actualResult = sut.mapStringToLanguageType(cString); + + //Verify + assertEquals(actualResult, LanguageType.C); + } + + @Test + public void mapStringToLanguageType_cPlusPlusStringProvided_cPlusPlusEnumReturned(){ + //Arrange + String cPlusPlusString = "text/x-c++src"; + + //Act + LanguageType actualResult = sut.mapStringToLanguageType(cPlusPlusString); + + //Verify + assertEquals(actualResult, LanguageType.CPLUSPLUS); + } + + @Test + public void mapStringToLanguageType_plaintextStringProvided_plaintextEnumReturned(){ + //Arrange + String plaintextString = "PLAINTEXT"; + + //Act + LanguageType actualResult = sut.mapStringToLanguageType(plaintextString); + + //Verify + assertEquals(actualResult, LanguageType.PLAINTEXT); + } + + @Test + public void mapStringToLanguageType_pythonStringProvided_pythonEnumReturned(){ + //Arrange + String pythonString = "text/x-python"; + + //Act + LanguageType actualResult = sut.mapStringToLanguageType(pythonString); + + //Verify + assertEquals(actualResult, LanguageType.PYTHON); + } + + @Test + public void mapStringToLanguageType_invalidStringProvided_notFoundExceptionTrown(){ + //Arrange + String invalidString = "invalid"; + + //Act + NotFoundException notFoundException = assertThrows(NotFoundException.class, () -> sut.mapStringToLanguageType(invalidString)); + + //Verify + assertEquals("Language" + invalidString + "not found", notFoundException.getMessage()); + } +} diff --git a/api/src/test/java/cz/cvut/fel/sem/mapper/QuestionMapperTest.java b/api/src/test/java/cz/cvut/fel/sem/mapper/QuestionMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c34687baa83e439c41ec56195cd611a1e891a4a7 --- /dev/null +++ b/api/src/test/java/cz/cvut/fel/sem/mapper/QuestionMapperTest.java @@ -0,0 +1,132 @@ +package cz.cvut.fel.sem.mapper; +import cz.cvut.fel.sem.dto.question.AnswerDto; +import cz.cvut.fel.sem.dto.question.QuestionDto; +import cz.cvut.fel.sem.dto.question.QuestionTextDto; +import cz.cvut.fel.sem.model.quizQuestion.*; +import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class QuestionMapperTest { + @InjectMocks QuestionMapper sut; + + @Mock QuestionTextMapper questionTextMapper; + + @Mock AnswerMapper answerMapper; + + @BeforeEach + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @AfterEach + public void afterEach() throws Exception { + verifyNoMoreInteractions(questionTextMapper); + verifyNoMoreInteractions(answerMapper); + } + + @Test + public void mapOneQuestionToModel_validArgumentsProvided_modelQuestionReturned(){ + //Arrange + QuestionTextDto questionTextDto = new QuestionTextDto(); + AnswerDto answerToThemAll = new AnswerDto(); + QuestionDto questionDto = new QuestionDto(1, QuestionType.QUIZ, "questionName", + questionTextDto, answerToThemAll, answerToThemAll, answerToThemAll, answerToThemAll); + + QuestionText questionText = mock(QuestionText.class); + Answer answerToReturn = mock(Answer.class); + Quiz emptyQuiz = mock(Quiz.class); + when(questionTextMapper.mapToModel(eq(questionTextDto), any())).thenReturn(questionText); + when(answerMapper.mapToModel(eq(answerToThemAll), any(), any())).thenReturn(answerToReturn); + + //Act + Question actualResult = sut.mapOneQuestionToModel(questionDto, emptyQuiz); + + //Verify + assertEquals(List.of(answerToReturn, answerToReturn, answerToReturn, answerToReturn), actualResult.getAnswers()); + assertEquals(questionText, actualResult.getQuestionText()); + assertEquals(1, actualResult.getKey()); + assertEquals(QuestionType.QUIZ, actualResult.getQuestionType()); + assertEquals("questionName", actualResult.getName()); + + verifyNoMoreInteractions(questionText); + verifyNoMoreInteractions(answerToReturn); + verifyNoMoreInteractions(emptyQuiz); + } + + @Test + public void mapOneQuestionToDto_validArgumentsProvided_dtoQuestionReturned(){ + //Arrange + QuestionText questionText = new QuestionText(); + Answer answer = new Answer(); + List<Answer> answerList = List.of(answer, answer, answer, answer); + Quiz quiz = new Quiz(); + Question question = new Question(1, QuestionType.QUIZ, "questionName", questionText, answerList, quiz); + + QuestionTextDto questionTextDto = mock(QuestionTextDto.class); + AnswerDto answerDto = mock(AnswerDto.class); + when(questionTextMapper.mapToDto(questionText)).thenReturn(questionTextDto); + when(answerMapper.getSpecificAnswerDtoFromList(eq(answerList), any())).thenReturn(answerDto); + + //Act + QuestionDto actualResult = sut.mapOneQuestionToDto(question); + + //Verify + assertEquals(answerDto, actualResult.getBottomLeftAnswer()); + assertEquals(answerDto, actualResult.getBottomRightAnswer()); + assertEquals(answerDto, actualResult.getTopLeftAnswer()); + assertEquals(answerDto, actualResult.getTopRightAnswer()); + assertEquals(questionTextDto, actualResult.getQuestionText()); + assertEquals(1, actualResult.getKey()); + assertEquals(QuestionType.QUIZ, actualResult.getQuestionType()); + assertEquals("questionName", actualResult.getName()); + + verifyNoMoreInteractions(questionTextDto); + verifyNoMoreInteractions(answerDto); + } + + @Test + public void mapListToModel_listProvided_correctAmountOfModelAnswersReturned(){ + //Arrange + + //Not giving any parameters to questionDto here, + //because correct mapping of one dto entity to model is tested in previous test already + QuestionDto questionDto = new QuestionDto(); + List<QuestionDto> dtoList = List.of(questionDto, questionDto, questionDto); + + //Act + List<Question> actualResult = sut.mapListToModel(dtoList, null); + + //Verify + assertEquals(3, actualResult.size()); + } + + @Test + public void mapListToDto_listProvided_correctAmountOfDtoAnswersReturned(){ + //Arrange + + //Not giving any parameters to question here, + //because correct mapping of one model entity to dto is tested in previous test already + Question question = new Question(); + List<Question> questionList = List.of(question, question); + + //Act + List<QuestionDto> actualResult = sut.mapListToDto(questionList); + + //Verify + assertEquals(2, actualResult.size()); + } +} diff --git a/api/src/test/java/cz/cvut/fel/sem/mapper/QuestionTextMapperTest.java b/api/src/test/java/cz/cvut/fel/sem/mapper/QuestionTextMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e88b7ba256c03c01d002190baa42c4660c03d065 --- /dev/null +++ b/api/src/test/java/cz/cvut/fel/sem/mapper/QuestionTextMapperTest.java @@ -0,0 +1,63 @@ +package cz.cvut.fel.sem.mapper; + +import cz.cvut.fel.sem.dto.question.QuestionTextDto; +import cz.cvut.fel.sem.model.quizQuestion.LanguageType; +import cz.cvut.fel.sem.model.quizQuestion.Question; +import cz.cvut.fel.sem.model.quizQuestion.QuestionText; +import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; + +@RunWith(MockitoJUnitRunner.class) +public class QuestionTextMapperTest { + @InjectMocks QuestionTextMapper sut; + + @Mock LanguageTypeMapper languageTypeMapper; + + @BeforeEach + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @AfterEach + public void afterEach() throws Exception { + verifyNoMoreInteractions(languageTypeMapper); + } + + @Test + public void mapToModel_validArgumentsProvided_modelObjectReturned(){ + //Arrange + QuestionTextDto questionTextDto = new QuestionTextDto("questionTextValue", "text/x-java"); + when(languageTypeMapper.mapStringToLanguageType("text/x-java")).thenReturn(LanguageType.JAVA); + Question question = new Question(); + + //Act + QuestionText actualResult = sut.mapToModel(questionTextDto, question); + + //Verify + assertEquals(LanguageType.JAVA, actualResult.getLanguageType()); + assertEquals("questionTextValue", actualResult.getValue()); + assertEquals(question, actualResult.getQuestion()); + } + + @Test + public void mapToDto_validArgumentsProvided_dtoObjectReturned(){ + //Arrange + QuestionText questionText = new QuestionText("questionTextValue", LanguageType.C, new Question()); + + //Act + QuestionTextDto actualResult = sut.mapToDto(questionText); + + //Verify + assertEquals("questionTextValue", actualResult.getValue()); + assertEquals("text/x-csrc", actualResult.getLanguage()); + } +} diff --git a/api/src/test/java/cz/cvut/fel/sem/mapper/QuizMapperTest.java b/api/src/test/java/cz/cvut/fel/sem/mapper/QuizMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..13dde49322d71ed1c1d9f604f9f2af32317fd4af --- /dev/null +++ b/api/src/test/java/cz/cvut/fel/sem/mapper/QuizMapperTest.java @@ -0,0 +1,72 @@ +package cz.cvut.fel.sem.mapper; + +import cz.cvut.fel.sem.dto.question.QuestionDto; +import cz.cvut.fel.sem.dto.question.QuizDto; +import cz.cvut.fel.sem.model.quizQuestion.Question; +import cz.cvut.fel.sem.model.quizQuestion.Quiz; +import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class QuizMapperTest { + @InjectMocks QuizMapper sut; + + @Mock QuestionMapper questionMapper; + + @BeforeEach + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @AfterEach + public void afterEach() throws Exception { + verifyNoMoreInteractions(questionMapper); + } + + @Test + public void mapToModel_validArgumentsProvided_modelObjectReturned(){ + //Arrange + List<QuestionDto> dtoList = List.of(new QuestionDto(), new QuestionDto()); + QuizDto quizDto = new QuizDto(1L, "quizName", dtoList); + List<Question> questionList = List.of(new Question(), new Question()); + when(questionMapper.mapListToModel(eq(quizDto.getQuestions()), any())).thenReturn(questionList); + + //Act + Quiz actualResult = sut.mapToModel(quizDto); + + //Verify + assertEquals(java.util.Optional.of(1L), java.util.Optional.of(actualResult.getId())); + assertEquals("quizName", actualResult.getName()); + assertEquals(questionList, actualResult.getQuestions()); + } + + @Test + public void mapToDto_validArgumentsProvided_dtoObjectReturned(){ + //Arrange + List<Question> questionList = List.of(new Question(), new Question()); + Quiz quiz = new Quiz(questionList, "quizName"); + List<QuestionDto> dtoList = List.of(new QuestionDto(), new QuestionDto()); + when(questionMapper.mapListToDto(quiz.getQuestions())).thenReturn(dtoList); + + //Act + QuizDto actualResult = sut.mapToDto(quiz); + + //Verify + assertEquals("quizName", actualResult.getName()); + assertEquals(dtoList, actualResult.getQuestions()); + } +} diff --git a/api/src/test/java/cz/cvut/fel/sem/service/QuizServiceTest.java b/api/src/test/java/cz/cvut/fel/sem/service/QuizServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b12f7c7d8ff641533f9df2395642c7634c094ce5 --- /dev/null +++ b/api/src/test/java/cz/cvut/fel/sem/service/QuizServiceTest.java @@ -0,0 +1,102 @@ +package cz.cvut.fel.sem.service; + +import cz.cvut.fel.sem.dto.question.QuizDto; +import cz.cvut.fel.sem.exception.NotFoundException; +import cz.cvut.fel.sem.mapper.QuizMapper; +import cz.cvut.fel.sem.model.quizQuestion.Quiz; +import cz.cvut.fel.sem.repository.QuizRepository; +import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import java.util.List; + +@RunWith(MockitoJUnitRunner.class) +public class QuizServiceTest { + @Mock + private QuizRepository quizRepository; + @Mock + private QuizMapper quizMapper; + + @InjectMocks + private QuizService sut; + + @BeforeEach + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @AfterEach + public void afterEach() throws Exception { + verifyNoMoreInteractions(quizMapper); + verifyNoMoreInteractions(quizRepository); + } + + @Test + public void getAllQuizzes_fetchingAllQuizzes_AllQuizzesReturned(){ + //Arrange + Quiz quiz1 = mock(Quiz.class); + Quiz quiz2 = mock(Quiz.class); + QuizDto quizDto1 = mock(QuizDto.class); + QuizDto quizDto2 = mock(QuizDto.class); + when(quizMapper.mapToDto(quiz1)).thenReturn(quizDto1); + when(quizMapper.mapToDto(quiz2)).thenReturn(quizDto2); + List<Quiz> quizList = List.of(quiz1, quiz2); + when(quizRepository.findAll()).thenReturn(quizList); + + //Act + List<QuizDto> dtoQuizzes = sut.getAllQuizzes(); + + //Verify + assertEquals(2, dtoQuizzes.size()); +// assertEquals(1, dtoQuizzes.stream().filter(quizDto -> quizDto.getName().equals("Quiz1")).count()); +// assertEquals(1, dtoQuizzes.stream().filter(quizDto -> quizDto.getName().equals("Quiz2")).count()); + +// Mockito.verify(quizDto2, times(2)).getName(); +// Mockito.verify(quizDto1, times(2)).getName(); + verifyNoMoreInteractions(quiz1); + verifyNoMoreInteractions(quiz2); + verifyNoMoreInteractions(quizDto1); + verifyNoMoreInteractions(quizDto2); + } + + @Test + public void getQuizById_existingIdProvided_quizFetched(){ + //Arrange + Long id = 1L; + Quiz quiz = mock(Quiz.class); + when(quizRepository.getOne(id)).thenReturn(quiz); + + //Act + Quiz actualQuiz = sut.getQuizById(id); + + //Verify + assertEquals(quiz, actualQuiz); + + verifyNoMoreInteractions(quiz); + + } + + @Test + public void getQuizById_notExistingIdProvided_notFoundExceptionThrown(){ + //Arrange + Long id = 1L; + + //Act + NotFoundException result = assertThrows(NotFoundException.class, () -> sut.getQuizById(id)); + + //Verify + assertEquals("Quiz with id " + id + "was not found", result.getMessage()); + + } +} diff --git a/api/src/test/java/cz/cvut/fel/sem/service/UserServiceTest.java b/api/src/test/java/cz/cvut/fel/sem/service/UserServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b6f8c27e50e2754514ab626524f2486193a77da9 --- /dev/null +++ b/api/src/test/java/cz/cvut/fel/sem/service/UserServiceTest.java @@ -0,0 +1,130 @@ +package cz.cvut.fel.sem.service; + +import cz.cvut.fel.sem.exception.NotFoundException; +import cz.cvut.fel.sem.model.User; +import cz.cvut.fel.sem.repository.UserRepository; +import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.security.crypto.password.PasswordEncoder; + +import java.util.Optional; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +/** + * Tests UserService methods + * Each method name follows naming convention: methodName_testedState_expectedOutput + */ +@RunWith(MockitoJUnitRunner.class) +public class UserServiceTest { + @Mock private UserRepository userRepository; + + @Mock private PasswordEncoder passwordEncoder; + + @InjectMocks UserService sut; + + @BeforeEach + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @AfterEach + public void afterEach() throws Exception { + verifyNoMoreInteractions(userRepository); + verifyNoMoreInteractions(passwordEncoder); + } + + @Test + public void getUserByEmail_userWithEmailExists_userWithEmailIsFound(){ + //Arrange + User user = mock(User.class); + String email = "testEmail"; + when(userRepository.findByEmail("testEmail")).thenReturn(user); + + //Act + User actualUser = sut.getUserByEmail(email); + + //Verify + assertEquals(user, actualUser); + + verifyNoMoreInteractions(user); + } + + @Test + public void getUserByEmail_userWithEmailDoesntExist_notFoundExceptionThrown(){ + //Arrange + String email = "notExistingEmail"; + + //Act + NotFoundException result = assertThrows(NotFoundException.class, () -> sut.getUserByEmail(email)); + + //Verify + assertEquals("User with email" + email + " was not found", result.getMessage()); + } + + @Test + public void getUserById_userWithIdExists_userWithIdIsFound(){ + //Arrange + User user = mock(User.class); + Long id = 1L; + when(userRepository.findById(id)).thenReturn(Optional.of(user)); + + //Act + User actualUser = sut.getUserById(id); + + //Verify + assertEquals(user, actualUser); + + verifyNoMoreInteractions(user); + } + + @Test + public void getUserById_userWithIdDoesntExist_notFoundExceptionThrown(){ + //Arrange + Long id = 1L; + + //Act + NotFoundException result = assertThrows(NotFoundException.class, () -> sut.getUserById(id)); + + //Verify + assertEquals("User with id" + id + " was not found", result.getMessage()); + } + + @Test + public void exists_userWithEmailDoesntExist_returnsFalse(){ + //Arrange + String email = "notExistingEmail"; + + //Act + boolean actualOutcome = sut.exists(email); + + //Verify + assertFalse(actualOutcome); + } + + @Test + public void exists_userWithEmailExists_returnsTrue(){ + //Arrange + String email = "existingEmail"; + User user = mock(User.class); + when(userRepository.findByEmail(email)).thenReturn(user); + + //Act + boolean actualOutcome = sut.exists(email); + + //Verify + assertTrue(actualOutcome); + + verifyNoMoreInteractions(user); + } + +}