diff --git a/application/model/src/main/java/org/fuseri/model/dto/common/DomainObjectDto.java b/application/model/src/main/java/org/fuseri/model/dto/common/DomainObjectDto.java index 36ec98b086e27e26deb3e31adeed36e66868d3e5..7824c73ce2a163dd543b3dd4f17b70d44fb3e74a 100644 --- a/application/model/src/main/java/org/fuseri/model/dto/common/DomainObjectDto.java +++ b/application/model/src/main/java/org/fuseri/model/dto/common/DomainObjectDto.java @@ -1,6 +1,5 @@ package org.fuseri.model.dto.common; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; @@ -9,7 +8,6 @@ import lombok.Setter; @Setter public abstract class DomainObjectDto { - @NotBlank @NotNull private Long id; } diff --git a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/Course.java b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/Course.java index 455637c7c192242c581e4c1200b261996cac3930..99e1ff83bc6f5d1ffcaffcd2689327a4e29e1ff9 100644 --- a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/Course.java +++ b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/Course.java @@ -1,11 +1,12 @@ package org.fuseri.modulelanguageschool.course; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.Table; +import jakarta.persistence.*; import lombok.*; import org.fuseri.modulelanguageschool.common.DomainObject; +import org.fuseri.modulelanguageschool.user.User; + +import java.util.List; +import java.util.Set; @Getter @Setter @@ -23,4 +24,15 @@ public class Course extends DomainObject { @Enumerated(EnumType.STRING) private ProficiencyLevel proficiency; + + @ManyToMany + private Set<User> students; + + public void enrolStudent(User student) { + students.add(student); + } + + public void expelStudent(User student) { + students.remove(student); + } } diff --git a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseController.java b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseController.java index 75e92aa7908ae19009769db434bebbb248839fe1..6d11099e7e28d6256f5c6faf11ab54e7a2bb9eae 100644 --- a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseController.java +++ b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseController.java @@ -23,7 +23,6 @@ import java.util.List; @RequestMapping("/courses") public class CourseController { - public static final String COURSE_NAME = "english b2 course"; private final CourseFacade courseFacade; @Autowired @@ -67,28 +66,25 @@ public class CourseController { /** * Retrieves a paginated list of courses of a given language * - * @param page the page number to retrieve * @param lang the language to find courses of * @return the Result containing the requested page of CourseDtos */ @GetMapping("/findAllByLang") - public List<CourseDto> findAll(@RequestParam int page, @RequestParam LanguageTypeDto lang) { - return new ArrayList<>(); + public List<CourseDto> findAll(@RequestParam LanguageTypeDto lang) { + return courseFacade.findAll(lang); } /** * Retrieves a paginated list of courses of a given language and proficiency * - * @param page the page number to retrieve * @param lang the language to find courses of * @param prof the proficiency of the language * @return the Result containing the requested page of CourseDtos */ @GetMapping("/findAllByLangProf") - public List<CourseDto> findAll(@RequestParam int page, - @RequestParam LanguageTypeDto lang, + public List<CourseDto> findAll(@RequestParam LanguageTypeDto lang, @RequestParam ProficiencyLevelDto prof) { - return new ArrayList<>(); + return courseFacade.findAll(lang, prof); } /** @@ -123,9 +119,7 @@ public class CourseController { */ @PatchMapping("/enrol/{id}") public CourseDto enrol(@PathVariable Long id, @RequestBody UserDto student) { - var course = new CourseDto(0L, COURSE_NAME, 10, LanguageTypeDto.ENGLISH, ProficiencyLevelDto.B2); - course.setStudentIds(new ArrayList<>(List.of(student.getId()))); - return course; + return courseFacade.enrol(id, student); } /** @@ -137,7 +131,7 @@ public class CourseController { */ @PatchMapping("/expel/{id}") public CourseDto expel(@PathVariable Long id, @RequestBody UserDto student) { - return new CourseDto(0L, COURSE_NAME, 10, LanguageTypeDto.ENGLISH, ProficiencyLevelDto.B2); + return courseFacade.expel(id, student); } } diff --git a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseFacade.java b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseFacade.java index 9899db25414b7d7ef3a6e69384c89f6a365b9ca5..db7f28aac1051afbb68b097701e87d5b7cd916d5 100644 --- a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseFacade.java +++ b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseFacade.java @@ -2,6 +2,10 @@ package org.fuseri.modulelanguageschool.course; import org.fuseri.model.dto.course.CourseCreateDto; import org.fuseri.model.dto.course.CourseDto; +import org.fuseri.model.dto.course.LanguageTypeDto; +import org.fuseri.model.dto.course.ProficiencyLevelDto; +import org.fuseri.model.dto.user.UserDto; +import org.fuseri.modulelanguageschool.user.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.domain.Page; @@ -9,16 +13,20 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + @Service @Transactional public class CourseFacade { private final CourseService courseService; private final CourseMapper courseMapper; + private final UserMapper userMapper; @Autowired - public CourseFacade(CourseService courseService, CourseMapper courseMapper) { + public CourseFacade(CourseService courseService, CourseMapper courseMapper, UserMapper userMapper) { this.courseService = courseService; this.courseMapper = courseMapper; + this.userMapper = userMapper; } @Transactional @@ -46,4 +54,20 @@ public class CourseFacade { public void delete(Long id) { courseService.delete(id); } + + public List<CourseDto> findAll(LanguageTypeDto lang) { + return courseMapper.mapToList(courseService.findAll(Language.valueOf(lang.name()))); + } + + public List<CourseDto> findAll(LanguageTypeDto lang, ProficiencyLevelDto prof) { + return courseMapper.mapToList(courseService.findAll(Language.valueOf(lang.name()), ProficiencyLevel.valueOf(prof.name()))); + } + + public CourseDto enrol(Long id, UserDto student) { + return courseMapper.mapToDto(courseService.enrol(id, userMapper.fromDto(student))); + } + + public CourseDto expel(Long id, UserDto student) { + return courseMapper.mapToDto(courseService.expel(id, userMapper.fromDto(student))); + } } diff --git a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseRepository.java b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseRepository.java index 1dcad4467b891675816f8b3f58e82b5b92766a31..4ea630cc6ecdf2f0d68624041e1f529758f6082f 100644 --- a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseRepository.java +++ b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseRepository.java @@ -1,9 +1,17 @@ package org.fuseri.modulelanguageschool.course; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface CourseRepository extends JpaRepository<Course, Long> { + @Query("SELECT c FROM Course c WHERE c.language = ?1") + List<Course> findAllByLang(Language language); + + @Query("SELECT c FROM Course c WHERE c.language = ?1 AND c.proficiency = ?2") + List<Course> findAllByLangProf(Language language, ProficiencyLevel proficiencyLevel); } diff --git a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseService.java b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseService.java index eb20658504ff81a3fa342dcd0ed88037da2329df..13079299f90503bc9f66ca889e05cd59ae6473f0 100644 --- a/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseService.java +++ b/application/module-language-school/src/main/java/org/fuseri/modulelanguageschool/course/CourseService.java @@ -1,12 +1,14 @@ package org.fuseri.modulelanguageschool.course; import org.fuseri.modulelanguageschool.common.ResourceNotFoundException; +import org.fuseri.modulelanguageschool.user.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Optional; @Service @@ -54,4 +56,34 @@ public class CourseService { public void delete(Long id) { courseRepository.deleteById(id); } + + public List<Course> findAll(Language language) { + return courseRepository.findAllByLang(language); + } + + public List<Course> findAll(Language language, ProficiencyLevel proficiencyLevel) { + return courseRepository.findAllByLangProf(language, proficiencyLevel); + } + + public Course enrol(Long id, User student) { + Optional<Course> optionalCourse = courseRepository.findById(id); + if (optionalCourse.isPresent()) { + Course course = optionalCourse.get(); + course.enrolStudent(student); + return courseRepository.save(course); + } else { + throw new ResourceNotFoundException("Course with id: " + id + " was not found."); + } + } + + public Course expel(Long id, User student) { + Optional<Course> optionalCourse = courseRepository.findById(id); + if (optionalCourse.isPresent()) { + Course course = optionalCourse.get(); + course.expelStudent(student); + return courseRepository.save(course); + } else { + throw new ResourceNotFoundException("Course with id: " + id + " was not found."); + } + } } diff --git a/application/module-language-school/src/test/java/org/fuseri/modulelanguageschool/course/CourseTest.java b/application/module-language-school/src/test/java/org/fuseri/modulelanguageschool/course/CourseTest.java index 05add7ac41aec771688261bfdeebe2d113c013a2..bab37001f3c7832fbc9dac03940fe2ad3b981f26 100644 --- a/application/module-language-school/src/test/java/org/fuseri/modulelanguageschool/course/CourseTest.java +++ b/application/module-language-school/src/test/java/org/fuseri/modulelanguageschool/course/CourseTest.java @@ -126,7 +126,7 @@ public class CourseTest { void findAllByLang() throws Exception { int page = 0; LanguageTypeDto lang = LanguageTypeDto.ENGLISH; - Mockito.when(courseController.findAll(page, lang)).thenReturn(new ArrayList<>()); + Mockito.when(courseController.findAll(lang)).thenReturn(new ArrayList<>()); String response = mockMvc.perform(get("/courses/findAllByLang") .param("page", Integer.toString(page)) .param("lang", lang.toString())) @@ -136,33 +136,18 @@ public class CourseTest { assertThat("response", response, is("[]")); } - @Test - void findAllByLangWithoutParameters() throws Exception { - Mockito.when(courseController.findAll(ArgumentMatchers.anyInt(), - ArgumentMatchers.isA(LanguageTypeDto.class))) - .thenReturn(new ArrayList<>()); - mockMvc.perform(get("/courses/findAllByLang")) - .andExpect(status().is4xxClientError()); - } - @Test void findAllByLangWithoutLang() throws Exception { - Mockito.when(courseController.findAll(ArgumentMatchers.anyInt(), - ArgumentMatchers.isA(LanguageTypeDto.class))) - .thenReturn(new ArrayList<>()); - String page = "0"; - mockMvc.perform(get("/courses/findAllByLang").param("page", page)) + mockMvc.perform(get("/courses/findAllByLang")) .andExpect(status().is4xxClientError()); } @Test void findAllByLangProf() throws Exception { - int page = 0; LanguageTypeDto lang = LanguageTypeDto.ENGLISH; ProficiencyLevelDto proficiencyLevel = ProficiencyLevelDto.A1; - Mockito.when(courseController.findAll(page, lang, proficiencyLevel)).thenReturn(new ArrayList<>()); + Mockito.when(courseController.findAll(lang, proficiencyLevel)).thenReturn(new ArrayList<>()); String response = mockMvc.perform(get("/courses/findAllByLangProf") - .param("page", Integer.toString(page)) .param("lang", lang.toString()) .param("prof", proficiencyLevel.toString())) .andExpect(status().isOk()) @@ -173,7 +158,7 @@ public class CourseTest { @Test void findAllByLangProfWithoutParameters() throws Exception { - Mockito.when(courseController.findAll(ArgumentMatchers.anyInt(), + Mockito.when(courseController.findAll( ArgumentMatchers.isA(LanguageTypeDto.class), ArgumentMatchers.isA(ProficiencyLevelDto.class))) .thenReturn(new ArrayList<>()); @@ -183,7 +168,7 @@ public class CourseTest { @Test void findAllByLangProfWithoutLangProf() throws Exception { - Mockito.when(courseController.findAll(ArgumentMatchers.anyInt(), + Mockito.when(courseController.findAll( ArgumentMatchers.isA(LanguageTypeDto.class), ArgumentMatchers.isA(ProficiencyLevelDto.class))) .thenReturn(new ArrayList<>());