From db76ed0a27966b90f5a7a196463d44ecf9435924 Mon Sep 17 00:00:00 2001 From: linirini <101927543+linirini@users.noreply.github.com> Date: Tue, 8 Aug 2023 20:47:16 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20member=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20api=20=EA=B0=9C=EB=B0=9C=20(#96)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 --- src/docs/asciidoc/ohdab.adoc | 33 ++- .../member/controller/MemberController.java | 40 +++- .../controller/mapper/MemberWebMapper.java | 53 ++++- .../controller/request/AddTeacherReq.java | 20 ++ .../controller/response/AddTeacherRes.java | 11 + .../controller/response/DeleteTeacherRes.java | 11 + .../response/GetTeacherListRes.java | 21 ++ .../member/controller/response/LoginRes.java | 4 +- .../java/com/ohdab/member/domain/Member.java | 1 + .../member/repository/MemberRepository.java | 10 + .../member/service/AddTeacherService.java | 53 +++++ .../member/service/DeleteTeacherService.java | 33 +++ .../member/service/GetTeacherListService.java | 45 ++++ .../com/ohdab/member/service/JoinService.java | 14 +- .../ohdab/member/service/LoginService.java | 13 +- .../member/service/UserDetailServiceImpl.java | 4 +- .../ohdab/member/service/dto/JoinReqDto.java | 14 -- .../ohdab/member/service/dto/LoginReqDto.java | 12 -- .../ohdab/member/service/dto/LoginResDto.java | 12 -- .../service/dto/MemberDtoForAddTeacher.java | 16 ++ .../dto/MemberDtoForGetTeacherList.java | 23 ++ .../member/service/dto/MemberDtoForJoin.java | 18 ++ .../member/service/dto/MemberDtoForLogin.java | 24 +++ .../service/helper/MemberHelperService.java | 14 +- .../service/usecase/AddTeacherUsecase.java | 8 + .../service/usecase/DeleteTeacherUsecase.java | 6 + .../usecase/GetTeacherListUsecase.java | 9 + .../member/service/usecase/JoinUsecase.java | 4 +- .../member/service/usecase/LoginUsecase.java | 5 +- .../Controller/MemberControllerTest.java | 201 ++++++++++++++++++ .../repository/MemberRepositoryTest.java | 123 +++++++++++ .../member/service/AddTeacherServiceTest.java | 44 ++++ .../service/DeleteTeacherServiceTest.java | 55 +++++ .../service/GetTeacherListServiceTest.java | 62 ++++++ .../controller/MemberControllerTest.java | 104 --------- 35 files changed, 944 insertions(+), 176 deletions(-) create mode 100644 src/main/java/com/ohdab/member/controller/request/AddTeacherReq.java create mode 100644 src/main/java/com/ohdab/member/controller/response/AddTeacherRes.java create mode 100644 src/main/java/com/ohdab/member/controller/response/DeleteTeacherRes.java create mode 100644 src/main/java/com/ohdab/member/controller/response/GetTeacherListRes.java create mode 100644 src/main/java/com/ohdab/member/service/AddTeacherService.java create mode 100644 src/main/java/com/ohdab/member/service/DeleteTeacherService.java create mode 100644 src/main/java/com/ohdab/member/service/GetTeacherListService.java delete mode 100644 src/main/java/com/ohdab/member/service/dto/JoinReqDto.java delete mode 100644 src/main/java/com/ohdab/member/service/dto/LoginReqDto.java delete mode 100644 src/main/java/com/ohdab/member/service/dto/LoginResDto.java create mode 100644 src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java create mode 100644 src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java create mode 100644 src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java create mode 100644 src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java create mode 100644 src/main/java/com/ohdab/member/service/usecase/AddTeacherUsecase.java create mode 100644 src/main/java/com/ohdab/member/service/usecase/DeleteTeacherUsecase.java create mode 100644 src/main/java/com/ohdab/member/service/usecase/GetTeacherListUsecase.java create mode 100644 src/test/java/com/ohdab/member/Controller/MemberControllerTest.java create mode 100644 src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java create mode 100644 src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java create mode 100644 src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java create mode 100644 src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java delete mode 100644 src/test/java/com/ohdab/webmvc/member/controller/MemberControllerTest.java diff --git a/src/docs/asciidoc/ohdab.adoc b/src/docs/asciidoc/ohdab.adoc index 4317a13a..35ec9a0f 100644 --- a/src/docs/asciidoc/ohdab.adoc +++ b/src/docs/asciidoc/ohdab.adoc @@ -25,4 +25,35 @@ include::{snippets}/members/login/http-request.adoc[] ==== Response -include::{snippets}/members/login/http-response.adoc[] \ No newline at end of file +include::{snippets}/members/login/http-response.adoc + +=== 선생님 목록 조회 + +==== Request + +include::{snippets}/members/teachers/http-request.adoc[] + +==== Response + +include::{snippets}/members/teachers/http-response.adoc[] + +=== 선생님 추가 + +==== Request + +include::{snippets}/members/teachers/enrollment/http-request.adoc[] + +==== Response + +include::{snippets}/members/teachers/enrollment/http-response.adoc[] + +=== 선생님 삭제 + +==== Request + +include::{snippets}/members/teachers/expulsion/{teacher-id}/http-request.adoc[] + +==== Response + +include::{snippets}/members/teachers/expulsion/{teacher-id}/http-response.adoc[] + diff --git a/src/main/java/com/ohdab/member/controller/MemberController.java b/src/main/java/com/ohdab/member/controller/MemberController.java index 50333491..601283cd 100644 --- a/src/main/java/com/ohdab/member/controller/MemberController.java +++ b/src/main/java/com/ohdab/member/controller/MemberController.java @@ -1,13 +1,23 @@ package com.ohdab.member.controller; import com.ohdab.member.controller.mapper.MemberWebMapper; +import com.ohdab.member.controller.request.AddTeacherReq; import com.ohdab.member.controller.request.JoinReq; import com.ohdab.member.controller.request.LoginReq; +import com.ohdab.member.controller.response.AddTeacherRes; +import com.ohdab.member.controller.response.DeleteTeacherRes; +import com.ohdab.member.controller.response.GetTeacherListRes; import com.ohdab.member.controller.response.JoinRes; import com.ohdab.member.controller.response.LoginRes; -import com.ohdab.member.service.dto.LoginResDto; +import com.ohdab.member.service.dto.MemberDtoForAddTeacher; +import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; +import com.ohdab.member.service.dto.MemberDtoForLogin; +import com.ohdab.member.service.usecase.AddTeacherUsecase; +import com.ohdab.member.service.usecase.DeleteTeacherUsecase; +import com.ohdab.member.service.usecase.GetTeacherListUsecase; import com.ohdab.member.service.usecase.JoinUsecase; import com.ohdab.member.service.usecase.LoginUsecase; +import java.util.List; import javax.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -20,6 +30,9 @@ public class MemberController { private final JoinUsecase joinUsecase; private final LoginUsecase loginUsecase; + private final GetTeacherListUsecase getTeacherListUsecase; + private final AddTeacherUsecase addTeacherUsecase; + private final DeleteTeacherUsecase deleteTeacherUsecase; @PostMapping("/join") public ResponseEntity join(@Valid @RequestBody JoinReq joinReq) { @@ -29,7 +42,8 @@ public ResponseEntity join(@Valid @RequestBody JoinReq joinReq) { @PostMapping("/login") public ResponseEntity login(@Valid @RequestBody LoginReq loginReq) { - LoginResDto loginResDto = loginUsecase.login(MemberWebMapper.toLoginReqDto(loginReq)); + MemberDtoForLogin.Response loginResDto = + loginUsecase.login(MemberWebMapper.toLoginReqDto(loginReq)); return ResponseEntity.ok(MemberWebMapper.toLoginRes(loginResDto)); } @@ -37,4 +51,26 @@ public ResponseEntity login(@Valid @RequestBody LoginReq loginReq) { public String adminAndTokenTest() { return "hohoho"; } + + @GetMapping("/teachers") + public ResponseEntity getTeacherList() { + List teacherDtoList = + getTeacherListUsecase.getTeacherList(); + return ResponseEntity.ok(MemberWebMapper.teacherDtoListToResponseList(teacherDtoList)); + } + + @PostMapping("/teachers/enrollment") + public ResponseEntity addTeacher( + @RequestBody @Valid AddTeacherReq addTeacherReq) { + MemberDtoForAddTeacher.Request addTeacherDto = + MemberWebMapper.addTeacherRequestToDto(addTeacherReq); + addTeacherUsecase.addTeacher(addTeacherDto); + return ResponseEntity.ok(MemberWebMapper.createAddTeacherRes()); + } + + @PatchMapping("/teachers/expulsion/{teacher-id}") + public ResponseEntity deleteTeacher(@PathVariable("teacher-id") long id) { + deleteTeacherUsecase.deleteTeacherById(id); + return ResponseEntity.ok(MemberWebMapper.createDeleteTeacherRes()); + } } diff --git a/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java b/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java index c6c4e24c..3097a5d7 100644 --- a/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java +++ b/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java @@ -1,34 +1,41 @@ package com.ohdab.member.controller.mapper; +import com.ohdab.member.controller.request.AddTeacherReq; import com.ohdab.member.controller.request.JoinReq; import com.ohdab.member.controller.request.LoginReq; +import com.ohdab.member.controller.response.AddTeacherRes; +import com.ohdab.member.controller.response.DeleteTeacherRes; +import com.ohdab.member.controller.response.GetTeacherListRes; import com.ohdab.member.controller.response.JoinRes; import com.ohdab.member.controller.response.LoginRes; -import com.ohdab.member.service.dto.JoinReqDto; -import com.ohdab.member.service.dto.LoginReqDto; -import com.ohdab.member.service.dto.LoginResDto; +import com.ohdab.member.service.dto.MemberDtoForAddTeacher; +import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; +import com.ohdab.member.service.dto.MemberDtoForJoin; +import com.ohdab.member.service.dto.MemberDtoForLogin; +import java.util.List; +import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; @NoArgsConstructor(access = AccessLevel.PROTECTED) public class MemberWebMapper { - public static JoinReqDto toJoinReqDto(JoinReq joinReq) { - return JoinReqDto.builder() + public static MemberDtoForJoin.Request toJoinReqDto(JoinReq joinReq) { + return MemberDtoForJoin.Request.builder() .name(joinReq.getName()) .password(joinReq.getPassword()) .role(joinReq.getRole()) .build(); } - public static LoginReqDto toLoginReqDto(LoginReq loginReq) { - return LoginReqDto.builder() + public static MemberDtoForLogin.Request toLoginReqDto(LoginReq loginReq) { + return MemberDtoForLogin.Request.builder() .name(loginReq.getName()) .password(loginReq.getPassword()) .build(); } - public static LoginRes toLoginRes(LoginResDto loginResDto) { + public static LoginRes toLoginRes(MemberDtoForLogin.Response loginResDto) { return LoginRes.builder() .message("로그인에 성공하였습니다.") .memberId(loginResDto.getMemberId()) @@ -39,4 +46,34 @@ public static LoginRes toLoginRes(LoginResDto loginResDto) { public static JoinRes toJoinRes() { return JoinRes.builder().message("회원가입이 완료되었습니다.").build(); } + + public static GetTeacherListRes teacherDtoListToResponseList( + List teacherDtoList) { + return GetTeacherListRes.builder() + .teachers( + teacherDtoList.stream() + .map( + t -> + GetTeacherListRes.TeacherInfo.builder() + .id(t.getId()) + .name(t.getName()) + .authorities(t.getAuthorities()) + .status(t.getStatus()) + .build()) + .collect(Collectors.toList())) + .build(); + } + + public static MemberDtoForAddTeacher.Request addTeacherRequestToDto( + AddTeacherReq addTeacherReq) { + return MemberDtoForAddTeacher.Request.builder().name(addTeacherReq.getName()).build(); + } + + public static AddTeacherRes createAddTeacherRes() { + return AddTeacherRes.builder().message("선생님 추가 및 회원가입에 성공하였습니다.").build(); + } + + public static DeleteTeacherRes createDeleteTeacherRes() { + return DeleteTeacherRes.builder().message("선생님 삭제 및 탈퇴에 성공하였습니다.").build(); + } } diff --git a/src/main/java/com/ohdab/member/controller/request/AddTeacherReq.java b/src/main/java/com/ohdab/member/controller/request/AddTeacherReq.java new file mode 100644 index 00000000..40d6f967 --- /dev/null +++ b/src/main/java/com/ohdab/member/controller/request/AddTeacherReq.java @@ -0,0 +1,20 @@ +package com.ohdab.member.controller.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import javax.validation.constraints.NotBlank; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AddTeacherReq { + + @NotBlank(message = "Teacher name cannot be blank") + @JsonProperty("teacher_name") + String name; +} diff --git a/src/main/java/com/ohdab/member/controller/response/AddTeacherRes.java b/src/main/java/com/ohdab/member/controller/response/AddTeacherRes.java new file mode 100644 index 00000000..03ca6ce6 --- /dev/null +++ b/src/main/java/com/ohdab/member/controller/response/AddTeacherRes.java @@ -0,0 +1,11 @@ +package com.ohdab.member.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class AddTeacherRes { + + String message; +} diff --git a/src/main/java/com/ohdab/member/controller/response/DeleteTeacherRes.java b/src/main/java/com/ohdab/member/controller/response/DeleteTeacherRes.java new file mode 100644 index 00000000..09c9a394 --- /dev/null +++ b/src/main/java/com/ohdab/member/controller/response/DeleteTeacherRes.java @@ -0,0 +1,11 @@ +package com.ohdab.member.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class DeleteTeacherRes { + + String message; +} diff --git a/src/main/java/com/ohdab/member/controller/response/GetTeacherListRes.java b/src/main/java/com/ohdab/member/controller/response/GetTeacherListRes.java new file mode 100644 index 00000000..68c6c8fa --- /dev/null +++ b/src/main/java/com/ohdab/member/controller/response/GetTeacherListRes.java @@ -0,0 +1,21 @@ +package com.ohdab.member.controller.response; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class GetTeacherListRes { + + List teachers; + + @Builder + @Getter + public static class TeacherInfo { + long id; + String name; + List authorities; + String status; + } +} diff --git a/src/main/java/com/ohdab/member/controller/response/LoginRes.java b/src/main/java/com/ohdab/member/controller/response/LoginRes.java index 6d75ea01..9585d70b 100644 --- a/src/main/java/com/ohdab/member/controller/response/LoginRes.java +++ b/src/main/java/com/ohdab/member/controller/response/LoginRes.java @@ -1,6 +1,6 @@ package com.ohdab.member.controller.response; -import com.ohdab.member.service.dto.LoginResDto; +import com.ohdab.member.service.dto.MemberDtoForLogin; import lombok.Builder; import lombok.Getter; @@ -12,7 +12,7 @@ public class LoginRes { private Long memberId; private String jwtToken; - public static LoginRes toRes(LoginResDto loginResDto) { + public static LoginRes toRes(MemberDtoForLogin.Response loginResDto) { return LoginRes.builder() .message("로그인에 성공하였습니다.") .memberId(loginResDto.getMemberId()) diff --git a/src/main/java/com/ohdab/member/domain/Member.java b/src/main/java/com/ohdab/member/domain/Member.java index d3792669..e7a49bda 100644 --- a/src/main/java/com/ohdab/member/domain/Member.java +++ b/src/main/java/com/ohdab/member/domain/Member.java @@ -56,6 +56,7 @@ private void setMemberInfo(MemberInfo memberInfo) { + memberInfo.getName().length() + "\""); } + this.memberInfo = memberInfo; } public boolean matchPassword( diff --git a/src/main/java/com/ohdab/member/repository/MemberRepository.java b/src/main/java/com/ohdab/member/repository/MemberRepository.java index bd7ac33d..86adad8a 100644 --- a/src/main/java/com/ohdab/member/repository/MemberRepository.java +++ b/src/main/java/com/ohdab/member/repository/MemberRepository.java @@ -1,10 +1,20 @@ package com.ohdab.member.repository; +import com.ohdab.member.domain.Authority; import com.ohdab.member.domain.Member; +import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface MemberRepository extends JpaRepository { Optional findByMemberInfoName(String name); + + List findByAuthoritiesContaining(Authority role); + + boolean existsByMemberInfoName(String name); + + Long countByMemberInfoNameContaining(String name); + + boolean existsById(long id); } diff --git a/src/main/java/com/ohdab/member/service/AddTeacherService.java b/src/main/java/com/ohdab/member/service/AddTeacherService.java new file mode 100644 index 00000000..fe29a39c --- /dev/null +++ b/src/main/java/com/ohdab/member/service/AddTeacherService.java @@ -0,0 +1,53 @@ +package com.ohdab.member.service; + +import com.ohdab.member.exception.NoMemberException; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.service.dto.MemberDtoForAddTeacher; +import com.ohdab.member.service.dto.MemberDtoForJoin; +import com.ohdab.member.service.helper.MemberHelperService; +import com.ohdab.member.service.usecase.AddTeacherUsecase; +import com.ohdab.member.service.usecase.JoinUsecase; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class AddTeacherService implements AddTeacherUsecase { + + private final MemberRepository memberRepository; + private final JoinUsecase joinUsecase; + private final MemberHelperService memberHelperService; + + @Override + public void addTeacher(MemberDtoForAddTeacher.Request addTeacherReqDto) { + String name = addTeacherReqDto.getName(); + name = changeNameIfDuplicated(name); + String password = name; + MemberDtoForJoin.Request memberDtoForJoin = + MemberDtoForJoin.Request.builder() + .name(name) + .password(password) + .role(List.of("TEACHER", "STUDENT")) + .build(); + // TODO:선생님 추가 시 회원가입 요청 + joinUsecase.join(memberDtoForJoin); + throwIfJoinFailed(name); + } + + private String changeNameIfDuplicated(String name) { + if (memberHelperService.checkIfMemberExistByName(memberRepository, name)) { + long sameNameCount = memberRepository.countByMemberInfoNameContaining(name); + return name = name + sameNameCount; + } + return name; + } + + private void throwIfJoinFailed(String name) { + if (!memberHelperService.checkIfMemberExistByName(memberRepository, name)) { + throw new NoMemberException("Join Failed with teacher name \"" + name + "\""); + } + } +} diff --git a/src/main/java/com/ohdab/member/service/DeleteTeacherService.java b/src/main/java/com/ohdab/member/service/DeleteTeacherService.java new file mode 100644 index 00000000..56c2298b --- /dev/null +++ b/src/main/java/com/ohdab/member/service/DeleteTeacherService.java @@ -0,0 +1,33 @@ +package com.ohdab.member.service; + +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.MemberStatus; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.service.helper.MemberHelperService; +import com.ohdab.member.service.usecase.DeleteTeacherUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class DeleteTeacherService implements DeleteTeacherUsecase { + + private final MemberRepository memberRepository; + private final MemberHelperService memberHelperService; + + @Override + public void deleteTeacherById(long id) { + Member member = memberHelperService.findExistingMemberById(memberRepository, id); + throwIfInactiveMember(member); + member.withdrawal(); + } + + private void throwIfInactiveMember(Member member) { + if (member.getStatus() == MemberStatus.INACTIVE) { + throw new IllegalStateException( + "Already withdrawal Member with id \"" + member.getId() + "\""); + } + } +} diff --git a/src/main/java/com/ohdab/member/service/GetTeacherListService.java b/src/main/java/com/ohdab/member/service/GetTeacherListService.java new file mode 100644 index 00000000..ff56606b --- /dev/null +++ b/src/main/java/com/ohdab/member/service/GetTeacherListService.java @@ -0,0 +1,45 @@ +package com.ohdab.member.service; + +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; +import com.ohdab.member.service.usecase.GetTeacherListUsecase; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class GetTeacherListService implements GetTeacherListUsecase { + + private final MemberRepository memberRepository; + + @Override + public List getTeacherList() { + Authority role = new Authority("TEACHER"); + List memberList = memberRepository.findByAuthoritiesContaining(role); + return memberDomainListToMemberDtoList(memberList); + } + + private List memberDomainListToMemberDtoList( + List members) { + return members.stream() + .map( + member -> + MemberDtoForGetTeacherList.Response.builder() + .id(member.getId()) + .name(member.getMemberInfo().getName()) + .authorities(createAuthoritiesDto(member.getAuthorities())) + .status(member.getStatus().name()) + .build()) + .collect(Collectors.toList()); + } + + private static List createAuthoritiesDto(List authorities) { + return authorities.stream().map(auth -> auth.getRole()).collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/ohdab/member/service/JoinService.java b/src/main/java/com/ohdab/member/service/JoinService.java index a2ba5e23..28466b09 100644 --- a/src/main/java/com/ohdab/member/service/JoinService.java +++ b/src/main/java/com/ohdab/member/service/JoinService.java @@ -5,7 +5,7 @@ import com.ohdab.member.domain.memberinfo.MemberInfo; import com.ohdab.member.exception.DuplicatedMemberException; import com.ohdab.member.repository.MemberRepository; -import com.ohdab.member.service.dto.JoinReqDto; +import com.ohdab.member.service.dto.MemberDtoForJoin; import com.ohdab.member.service.usecase.JoinUsecase; import java.util.List; import java.util.Optional; @@ -25,7 +25,7 @@ public class JoinService implements JoinUsecase { @Transactional @Override - public void join(JoinReqDto joinReqDto) { + public void join(MemberDtoForJoin.Request joinReqDto) { checkDuplicatedMember(joinReqDto.getName()); Member member = createMember(joinReqDto, createAuthorities(joinReqDto)); memberRepository.save(member); @@ -38,24 +38,24 @@ private void checkDuplicatedMember(String name) { } } - private List createAuthorities(JoinReqDto joinReqDto) { + private List createAuthorities(MemberDtoForJoin.Request joinReqDto) { List roleList = joinReqDto.getRole(); return roleList.stream() .map(role -> Authority.builder().role(role).build()) .collect(Collectors.toList()); } - private Member createMember(JoinReqDto joinReqDto, List authorities) { + private Member createMember(MemberDtoForJoin.Request joinReqDto, List authorities) { return Member.builder() .memberInfo(createMemberInfo(joinReqDto)) .authorities(authorities) .build(); } - private MemberInfo createMemberInfo(JoinReqDto joinReqDto) { + private MemberInfo createMemberInfo(MemberDtoForJoin.Request memberDtoForJoin) { return MemberInfo.builder() - .name(joinReqDto.getName()) - .password(passwordEncoder.encode(joinReqDto.getPassword())) + .name(memberDtoForJoin.getName()) + .password(passwordEncoder.encode(memberDtoForJoin.getPassword())) .build(); } } diff --git a/src/main/java/com/ohdab/member/service/LoginService.java b/src/main/java/com/ohdab/member/service/LoginService.java index b273421a..fb25e982 100644 --- a/src/main/java/com/ohdab/member/service/LoginService.java +++ b/src/main/java/com/ohdab/member/service/LoginService.java @@ -2,8 +2,8 @@ import com.ohdab.core.util.jwt.JwtTokenProvider; import com.ohdab.member.domain.Member; -import com.ohdab.member.service.dto.LoginReqDto; -import com.ohdab.member.service.dto.LoginResDto; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.service.dto.MemberDtoForLogin; import com.ohdab.member.service.helper.MemberHelperService; import com.ohdab.member.service.usecase.LoginUsecase; import lombok.RequiredArgsConstructor; @@ -21,21 +21,24 @@ @Transactional(readOnly = true) public class LoginService implements LoginUsecase { + private final MemberRepository memberRepository; private final MemberHelperService memberHelperService; private final UserDetailsService userDetailsService; private final JwtTokenProvider jwtTokenProvider; private final PasswordEncoder passwordEncoder; @Override - public LoginResDto login(LoginReqDto loginReqDto) { + public MemberDtoForLogin.Response login(MemberDtoForLogin.Request loginReqDto) { UserDetails userDetails = userDetailsService.loadUserByUsername(loginReqDto.getName()); - Member member = memberHelperService.findExistingMember(loginReqDto.getName()); + Member member = + memberHelperService.findExistingMemberByName( + memberRepository, loginReqDto.getName()); if (!member.matchPassword( passwordEncoder, loginReqDto.getPassword(), userDetails.getPassword())) { throw new BadCredentialsException("비밀번호가 일치하지 않습니다."); } Authentication authentication = createAuthentication(userDetails); - return LoginResDto.builder() + return MemberDtoForLogin.Response.builder() .memberId(member.getId()) .jwtToken(jwtTokenProvider.createToken(authentication, member.getId())) .build(); diff --git a/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java b/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java index 2026cf4b..ba9e2aed 100644 --- a/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java +++ b/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java @@ -1,6 +1,7 @@ package com.ohdab.member.service; import com.ohdab.member.domain.Member; +import com.ohdab.member.repository.MemberRepository; import com.ohdab.member.service.helper.MemberHelperService; import java.util.List; import java.util.stream.Collectors; @@ -16,11 +17,12 @@ @RequiredArgsConstructor public class UserDetailServiceImpl implements UserDetailsService { + private final MemberRepository memberRepository; private final MemberHelperService memberHelperService; @Override public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException { - Member member = memberHelperService.findExistingMember(name); + Member member = memberHelperService.findExistingMemberByName(memberRepository, name); return createUserDetails(member); } diff --git a/src/main/java/com/ohdab/member/service/dto/JoinReqDto.java b/src/main/java/com/ohdab/member/service/dto/JoinReqDto.java deleted file mode 100644 index 0e15ce45..00000000 --- a/src/main/java/com/ohdab/member/service/dto/JoinReqDto.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.ohdab.member.service.dto; - -import java.util.List; -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class JoinReqDto { - - private String name; - private String password; - private List role; -} diff --git a/src/main/java/com/ohdab/member/service/dto/LoginReqDto.java b/src/main/java/com/ohdab/member/service/dto/LoginReqDto.java deleted file mode 100644 index 10aaf4b8..00000000 --- a/src/main/java/com/ohdab/member/service/dto/LoginReqDto.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.ohdab.member.service.dto; - -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class LoginReqDto { - - private String name; - private String password; -} diff --git a/src/main/java/com/ohdab/member/service/dto/LoginResDto.java b/src/main/java/com/ohdab/member/service/dto/LoginResDto.java deleted file mode 100644 index 93202f1f..00000000 --- a/src/main/java/com/ohdab/member/service/dto/LoginResDto.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.ohdab.member.service.dto; - -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class LoginResDto { - - private Long memberId; - private String jwtToken; -} diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java new file mode 100644 index 00000000..7531ca45 --- /dev/null +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java @@ -0,0 +1,16 @@ +package com.ohdab.member.service.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class MemberDtoForAddTeacher { + + @Builder + @Getter + public static class Request { + + private String name; + } +} diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java new file mode 100644 index 00000000..d1b9970f --- /dev/null +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java @@ -0,0 +1,23 @@ +package com.ohdab.member.service.dto; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class MemberDtoForGetTeacherList { + + @Builder + @Getter + public static class Response { + + private Long id; + + private String name; + + private List authorities; + + private String status; + } +} diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java new file mode 100644 index 00000000..c36df827 --- /dev/null +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java @@ -0,0 +1,18 @@ +package com.ohdab.member.service.dto; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class MemberDtoForJoin { + + @Builder + @Getter + public static class Request { + private String name; + private String password; + private List role; + } +} diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java new file mode 100644 index 00000000..1137d91c --- /dev/null +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java @@ -0,0 +1,24 @@ +package com.ohdab.member.service.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class MemberDtoForLogin { + + @Getter + @Builder + public static class Request { + + private String name; + private String password; + } + + @Getter + @Builder + public static class Response { + private Long memberId; + private String jwtToken; + } +} diff --git a/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java b/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java index 3b494397..39127bca 100644 --- a/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java +++ b/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java @@ -10,11 +10,19 @@ @RequiredArgsConstructor public final class MemberHelperService { - private final MemberRepository memberRepository; - - public Member findExistingMember(String name) { + public Member findExistingMemberByName(MemberRepository memberRepository, String name) { return memberRepository .findByMemberInfoName(name) .orElseThrow(() -> new NoMemberException("존재하지 않는 회원입니다.")); } + + public Member findExistingMemberById(MemberRepository memberRepository, long id) { + return memberRepository + .findById(id) + .orElseThrow(() -> new NoMemberException("Unknown member with id \"" + id + "\"")); + } + + public boolean checkIfMemberExistByName(MemberRepository memberRepository, String name) { + return memberRepository.existsByMemberInfoName(name); + } } diff --git a/src/main/java/com/ohdab/member/service/usecase/AddTeacherUsecase.java b/src/main/java/com/ohdab/member/service/usecase/AddTeacherUsecase.java new file mode 100644 index 00000000..2385edfe --- /dev/null +++ b/src/main/java/com/ohdab/member/service/usecase/AddTeacherUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.member.service.usecase; + +import com.ohdab.member.service.dto.MemberDtoForAddTeacher; + +public interface AddTeacherUsecase { + + void addTeacher(MemberDtoForAddTeacher.Request addTeacherReqDto); +} diff --git a/src/main/java/com/ohdab/member/service/usecase/DeleteTeacherUsecase.java b/src/main/java/com/ohdab/member/service/usecase/DeleteTeacherUsecase.java new file mode 100644 index 00000000..67dce89e --- /dev/null +++ b/src/main/java/com/ohdab/member/service/usecase/DeleteTeacherUsecase.java @@ -0,0 +1,6 @@ +package com.ohdab.member.service.usecase; + +public interface DeleteTeacherUsecase { + + void deleteTeacherById(long id); +} diff --git a/src/main/java/com/ohdab/member/service/usecase/GetTeacherListUsecase.java b/src/main/java/com/ohdab/member/service/usecase/GetTeacherListUsecase.java new file mode 100644 index 00000000..e688d195 --- /dev/null +++ b/src/main/java/com/ohdab/member/service/usecase/GetTeacherListUsecase.java @@ -0,0 +1,9 @@ +package com.ohdab.member.service.usecase; + +import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; +import java.util.List; + +public interface GetTeacherListUsecase { + + List getTeacherList(); +} diff --git a/src/main/java/com/ohdab/member/service/usecase/JoinUsecase.java b/src/main/java/com/ohdab/member/service/usecase/JoinUsecase.java index 0edda1c0..be929c90 100644 --- a/src/main/java/com/ohdab/member/service/usecase/JoinUsecase.java +++ b/src/main/java/com/ohdab/member/service/usecase/JoinUsecase.java @@ -1,8 +1,8 @@ package com.ohdab.member.service.usecase; -import com.ohdab.member.service.dto.JoinReqDto; +import com.ohdab.member.service.dto.MemberDtoForJoin; public interface JoinUsecase { - void join(JoinReqDto joinReqDto); + void join(MemberDtoForJoin.Request joinReqDto); } diff --git a/src/main/java/com/ohdab/member/service/usecase/LoginUsecase.java b/src/main/java/com/ohdab/member/service/usecase/LoginUsecase.java index 2323af13..0980b496 100644 --- a/src/main/java/com/ohdab/member/service/usecase/LoginUsecase.java +++ b/src/main/java/com/ohdab/member/service/usecase/LoginUsecase.java @@ -1,9 +1,8 @@ package com.ohdab.member.service.usecase; -import com.ohdab.member.service.dto.LoginReqDto; -import com.ohdab.member.service.dto.LoginResDto; +import com.ohdab.member.service.dto.MemberDtoForLogin; public interface LoginUsecase { - LoginResDto login(LoginReqDto loginReqDto); + MemberDtoForLogin.Response login(MemberDtoForLogin.Request loginReqDto); } diff --git a/src/test/java/com/ohdab/member/Controller/MemberControllerTest.java b/src/test/java/com/ohdab/member/Controller/MemberControllerTest.java new file mode 100644 index 00000000..1d650359 --- /dev/null +++ b/src/test/java/com/ohdab/member/Controller/MemberControllerTest.java @@ -0,0 +1,201 @@ +package com.ohdab.member.Controller; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ohdab.member.controller.MemberController; +import com.ohdab.member.controller.request.AddTeacherReq; +import com.ohdab.member.controller.request.JoinReq; +import com.ohdab.member.controller.request.LoginReq; +import com.ohdab.member.controller.response.JoinRes; +import com.ohdab.member.controller.response.LoginRes; +import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; +import com.ohdab.member.service.dto.MemberDtoForLogin; +import com.ohdab.member.service.usecase.AddTeacherUsecase; +import com.ohdab.member.service.usecase.DeleteTeacherUsecase; +import com.ohdab.member.service.usecase.GetTeacherListUsecase; +import com.ohdab.member.service.usecase.JoinUsecase; +import com.ohdab.member.service.usecase.LoginUsecase; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; + +@AutoConfigureRestDocs +@WebMvcTest(controllers = MemberController.class) +class MemberControllerTest { + + @Autowired private MockMvc mockMvc; + @Autowired private ObjectMapper objectMapper; + @MockBean private JoinUsecase joinUsecase; + @MockBean private LoginUsecase loginUsecase; + @MockBean private GetTeacherListUsecase getTeacherListUsecase; + @MockBean private AddTeacherUsecase addTeacherUsecase; + @MockBean private DeleteTeacherUsecase deleteTeacherUsecase; + + @Test + @WithMockUser + void 회원가입() throws Exception { + // given + final String JOIN_URL = "/members/join"; + final JoinReq joinReq = + JoinReq.builder().name("홍길동").password("1234").role(List.of("STUDENT")).build(); + final JoinRes joinRes = JoinRes.builder().message("회원가입이 완료되었습니다.").build(); + + // when + + // then + mockMvc.perform( + post(JOIN_URL) + .with(csrf()) + .content(objectMapper.writeValueAsString(joinReq)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value(joinRes.getMessage())) + .andDo(print()) + .andDo(createDocument("members/join")); + } + + @Test + @WithMockUser + void 로그인() throws Exception { + // given + final String LOGIN_URL = "/members/login"; + final LoginReq loginReq = LoginReq.builder().name("홍길동").password("1234").build(); + final LoginRes loginRes = + LoginRes.builder() + .memberId(1L) + .message("로그인에 성공하였습니다.") + .jwtToken("jwt-token") + .build(); + final MemberDtoForLogin.Response loginResDto = + MemberDtoForLogin.Response.builder().memberId(1L).jwtToken("jwt-token").build(); + + // when + when(loginUsecase.login(any())).thenReturn(loginResDto); + + // then + mockMvc.perform( + post(LOGIN_URL) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(loginReq))) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value(loginRes.getMessage()), + jsonPath("$.memberId").value(loginRes.getMemberId()), + jsonPath("$.jwtToken").value(loginRes.getJwtToken())) + .andDo(print()) + .andDo(createDocument("members/login")); + } + + @Test + @WithMockUser + void 선생님_목록_조회() throws Exception { + // given + final String url = "/members/teachers"; + + List responseList = new ArrayList<>(); + + responseList.add(createTeacher(1L, "선생님")); + responseList.add(createTeacher(2L, "선생님2")); + responseList.add(createTeacher(3L, "선생님3")); + + // when + when(getTeacherListUsecase.getTeacherList()).thenReturn(responseList); + + // then + mockMvc.perform(get(url).with(csrf())) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.teachers[0].id").value(1), + jsonPath("$.teachers[0].name").value("선생님"), + jsonPath("$.teachers[0].authorities[0]").value("TEACHER"), + jsonPath("$.teachers[0].status").value("ACTIVE"), + jsonPath("$.teachers[1].id").value(2), + jsonPath("$.teachers[1].name").value("선생님2"), + jsonPath("$.teachers[1].authorities[0]").value("TEACHER"), + jsonPath("$.teachers[1].status").value("ACTIVE"), + jsonPath("$.teachers[2].id").value(3), + jsonPath("$.teachers[2].name").value("선생님3"), + jsonPath("$.teachers[2].authorities[0]").value("TEACHER"), + jsonPath("$.teachers[2].status").value("ACTIVE")) + .andDo(print()) + .andDo(createDocument("members/teachers")); + } + + private MemberDtoForGetTeacherList.Response createTeacher(long id, String name) { + return MemberDtoForGetTeacherList.Response.builder() + .id(id) + .name(name) + .authorities(List.of("TEACHER")) + .status("ACTIVE") + .build(); + } + + @Test + @WithMockUser + void 선생님_추가() throws Exception { + // given + final String url = "/members/teachers/enrollment"; + final AddTeacherReq addTeacherReq = AddTeacherReq.builder().name("선생님").build(); + + // when + + // then + mockMvc.perform( + post(url) + .with(csrf()) + .content(objectMapper.writeValueAsString(addTeacherReq)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("선생님 추가 및 회원가입에 성공하였습니다.")) + .andDo(print()) + .andDo(createDocument("members/teachers/enrollment")); + } + + @Test + @WithMockUser + void 선생님_삭제() throws Exception { + // given + final String url = "/members/teachers/expulsion/{teacher-id}"; + + // when + + // then + mockMvc.perform(patch(url, 1).with(csrf())) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("선생님 삭제 및 탈퇴에 성공하였습니다.")) + .andDo(print()) + .andDo(createDocument("members/teachers/expulsion/{teacher-id}")); + } + + private RestDocumentationResultHandler createDocument(String identifier) { + return document( + identifier, preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); + } +} diff --git a/src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java b/src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java new file mode 100644 index 00000000..ea8752d6 --- /dev/null +++ b/src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java @@ -0,0 +1,123 @@ +package com.ohdab.member.repository; + +import static com.ohdab.member.domain.MemberStatus.INACTIVE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.groups.Tuple.tuple; + +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.memberinfo.MemberInfo; +import java.util.ArrayList; +import java.util.List; +import javax.persistence.EntityManager; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +public class MemberRepositoryTest { + + @Autowired private MemberRepository memberRepository; + @Autowired private EntityManager entityManager; + + @Test + @DisplayName("선생님 목록 조회 성공 테스트") + void 선생님_목록_조회_성공() { + // given + Authority teacher = new Authority("TEACHER"); + Authority student = new Authority("STUDENT"); + Member teacher1 = memberRepository.save(createMember("선생님", "tjstodsla", teacher)); + Member teacher2 = memberRepository.save(createMember("선생님2", "tjstodsla2", teacher)); + Member teacher3 = memberRepository.save(createMember("선생님3", "tjstodsla3", teacher)); + Member student1 = memberRepository.save(createMember("학생", "gkrtod", student)); + entityManager.flush(); + entityManager.clear(); + + // when + List results = memberRepository.findByAuthoritiesContaining(teacher); + + // then + assertThat(results) + .hasSize(3) + .extracting( + Member::getId, + m -> m.getMemberInfo().getName(), + m -> m.getMemberInfo().getPassword(), + m -> m.getAuthorities().get(0).getRole(), + Member::getStatus) + .contains( + tuple( + teacher1.getId(), + teacher1.getMemberInfo().getName(), + teacher1.getMemberInfo().getPassword(), + teacher1.getAuthorities().get(0).getRole(), + teacher1.getStatus()), + tuple( + teacher2.getId(), + teacher2.getMemberInfo().getName(), + teacher2.getMemberInfo().getPassword(), + teacher2.getAuthorities().get(0).getRole(), + teacher2.getStatus()), + tuple( + teacher3.getId(), + teacher3.getMemberInfo().getName(), + teacher3.getMemberInfo().getPassword(), + teacher3.getAuthorities().get(0).getRole(), + teacher3.getStatus())); + } + + @Test + @DisplayName("선생님 추가 성공 테스트") + void 선생님_추가_성공() { + // given + Authority teacher = new Authority("TEACHER"); + Member member = createMember("선생님", "tjstodsla", teacher); + + // when + memberRepository.save(member); + Member result = memberRepository.findById(member.getId()).get(); + + // then + assertThat(result) + .extracting( + Member::getId, + m -> m.getMemberInfo().getName(), + m -> m.getMemberInfo().getPassword(), + m -> m.getAuthorities().get(0).getRole(), + Member::getStatus) + .containsExactly( + member.getId(), + member.getMemberInfo().getName(), + member.getMemberInfo().getPassword(), + member.getAuthorities().get(0).getRole(), + member.getStatus()); + } + + @Test + @DisplayName("선생님 삭제(탈퇴) 성공 테스트") + void 선생님_삭제_및_탈퇴_성공() { + // given + Authority teacher = new Authority("TEACHER"); + Member member = createMember("선생님", "tjstodsla", teacher); + + // when + memberRepository.save(member); + member.withdrawal(); + Member result = memberRepository.findById(member.getId()).get(); + + // then + assertThat(result) + .extracting(Member::getId, Member::getStatus) + .containsExactly(member.getId(), INACTIVE); + } + + private Member createMember(String name, String password, Authority role) { + List authorities = new ArrayList<>(); + authorities.add(role); + return Member.builder() + .memberInfo(MemberInfo.builder().name(name).password(password).build()) + .authorities(authorities) + .build(); + } +} diff --git a/src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java b/src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java new file mode 100644 index 00000000..7c40438a --- /dev/null +++ b/src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java @@ -0,0 +1,44 @@ +package com.ohdab.member.service; + +import static org.assertj.core.api.Assertions.assertThatNoException; + +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.service.dto.MemberDtoForAddTeacher; +import com.ohdab.member.service.helper.MemberHelperService; +import com.ohdab.member.service.usecase.AddTeacherUsecase; +import com.ohdab.member.service.usecase.JoinUsecase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {AddTeacherService.class, MemberHelperService.class}) +public class AddTeacherServiceTest { + + @Autowired private AddTeacherUsecase addTeacherUsecase; + @MockBean private MemberRepository memberRepository; + @MockBean private JoinUsecase joinUsecase; + + @Test + @DisplayName("선생님 추가 성공 테스트") + void 선생님_추가_성공() { + // given + String name = "선생님"; + MemberDtoForAddTeacher.Request memberDtoForAddTeacherReqDto = + MemberDtoForAddTeacher.Request.builder().name(name).build(); + + // when + Mockito.when(memberRepository.existsByMemberInfoName(Mockito.anyString())) + .thenReturn(false); + Mockito.when(memberRepository.existsByMemberInfoName(Mockito.anyString())).thenReturn(true); + + // then + assertThatNoException() + .isThrownBy(() -> addTeacherUsecase.addTeacher(memberDtoForAddTeacherReqDto)); + } +} diff --git a/src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java b/src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java new file mode 100644 index 00000000..fff4a4ed --- /dev/null +++ b/src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java @@ -0,0 +1,55 @@ +package com.ohdab.member.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; + +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.memberinfo.MemberInfo; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.service.helper.MemberHelperService; +import com.ohdab.member.service.usecase.DeleteTeacherUsecase; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {DeleteTeacherService.class, MemberHelperService.class}) +public class DeleteTeacherServiceTest { + + @Autowired private DeleteTeacherUsecase deleteTeacherUsecase; + @MockBean private MemberRepository memberRepository; + + @Test + @DisplayName("선생님 삭제 성공 테스트") + void 선생님_삭제_성공_테스트() { + // given + long id = 1; + Member member = createTeacher("선생님", "tjstodsla"); + + // when + Mockito.when(memberRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(member)); + + // then + assertThatNoException().isThrownBy(() -> deleteTeacherUsecase.deleteTeacherById(id)); + assertThat(member.getStatus().name()).isEqualTo("INACTIVE"); + } + + private Member createTeacher(String name, String password) { + List authorities = new ArrayList<>(); + authorities.add(new Authority("TEACHER")); + return Member.builder() + .memberInfo(MemberInfo.builder().name(name).password(password).build()) + .authorities(authorities) + .build(); + } +} diff --git a/src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java b/src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java new file mode 100644 index 00000000..dbc1bea6 --- /dev/null +++ b/src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java @@ -0,0 +1,62 @@ +package com.ohdab.member.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.tuple; + +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.memberinfo.MemberInfo; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; +import com.ohdab.member.service.usecase.GetTeacherListUsecase; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {GetTeacherListService.class}) +public class GetTeacherListServiceTest { + + @Autowired private GetTeacherListUsecase getTeacherListUsecase; + @MockBean private MemberRepository memberRepository; + + @Test + @DisplayName("선생님 목록 조회 성공 테스트") + void 선생님_목록_조회_성공() { + // given + List teachers = new ArrayList<>(); + teachers.add(createTeacher("선생님1", "tjstodsla1")); + teachers.add(createTeacher("선생님2", "tjstodsla2")); + teachers.add(createTeacher("선생님3", "tjstodsla3")); + + // when + Mockito.when(memberRepository.findByAuthoritiesContaining(Mockito.any())) + .thenReturn(teachers); + List results = getTeacherListUsecase.getTeacherList(); + + // then + assertThat(results) + .hasSize(3) + .extracting(m -> m.getName(), m -> m.getAuthorities().get(0), m -> m.getStatus()) + .contains( + tuple("선생님1", "TEACHER", "ACTIVE"), + tuple("선생님2", "TEACHER", "ACTIVE"), + tuple("선생님3", "TEACHER", "ACTIVE")); + } + + private Member createTeacher(String name, String password) { + List authorities = new ArrayList<>(); + authorities.add(new Authority("TEACHER")); + return Member.builder() + .memberInfo(MemberInfo.builder().name(name).password(password).build()) + .authorities(authorities) + .build(); + } +} diff --git a/src/test/java/com/ohdab/webmvc/member/controller/MemberControllerTest.java b/src/test/java/com/ohdab/webmvc/member/controller/MemberControllerTest.java deleted file mode 100644 index 0e1cd368..00000000 --- a/src/test/java/com/ohdab/webmvc/member/controller/MemberControllerTest.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.ohdab.webmvc.member.controller; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ohdab.member.controller.MemberController; -import com.ohdab.member.controller.request.JoinReq; -import com.ohdab.member.controller.request.LoginReq; -import com.ohdab.member.controller.response.JoinRes; -import com.ohdab.member.controller.response.LoginRes; -import com.ohdab.member.service.dto.LoginResDto; -import com.ohdab.member.service.usecase.JoinUsecase; -import com.ohdab.member.service.usecase.LoginUsecase; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.web.servlet.MockMvc; - -@AutoConfigureRestDocs -@WebMvcTest(controllers = MemberController.class) -class MemberControllerTest { - - @Autowired private MockMvc mockMvc; - @Autowired private ObjectMapper objectMapper; - @MockBean private JoinUsecase joinUsecase; - @MockBean private LoginUsecase loginUsecase; - - @Test - @WithMockUser - void 회원가입() throws Exception { - // given - final String JOIN_URL = "/members/join"; - final JoinReq joinReq = - JoinReq.builder().name("홍길동").password("1234").role(List.of("STUDENT")).build(); - final JoinRes joinRes = JoinRes.builder().message("회원가입이 완료되었습니다.").build(); - - // when - - // then - mockMvc.perform( - post(JOIN_URL) - .with(csrf()) - .content(objectMapper.writeValueAsString(joinReq)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpectAll( - status().isOk(), - content().contentType(MediaType.APPLICATION_JSON), - jsonPath("$.message").value(joinRes.getMessage())) - .andDo(print()) - .andDo(createDocument("members/join")); - } - - @Test - @WithMockUser - void 로그인() throws Exception { - // given - final String LOGIN_URL = "/members/login"; - final LoginReq loginReq = LoginReq.builder().name("홍길동").password("1234").build(); - final LoginRes loginRes = - LoginRes.builder() - .memberId(1L) - .message("로그인에 성공하였습니다.") - .jwtToken("jwt-token") - .build(); - final LoginResDto loginResDto = - LoginResDto.builder().memberId(1L).jwtToken("jwt-token").build(); - - // when - when(loginUsecase.login(any())).thenReturn(loginResDto); - - // then - mockMvc.perform( - post(LOGIN_URL) - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(loginReq))) - .andExpectAll( - status().isOk(), - content().contentType(MediaType.APPLICATION_JSON), - jsonPath("$.message").value(loginRes.getMessage()), - jsonPath("$.memberId").value(loginRes.getMemberId()), - jsonPath("$.jwtToken").value(loginRes.getJwtToken())) - .andDo(print()) - .andDo(createDocument("members/login")); - } - - private RestDocumentationResultHandler createDocument(String identifier) { - return document( - identifier, preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); - } -} From a6f8904b0c72834e88c65f5540b36a92807cc888 Mon Sep 17 00:00:00 2001 From: Jonghan Sim Date: Tue, 8 Aug 2023 21:18:14 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20mistakenote=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20api=20=EA=B0=9C=EB=B0=9C=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory --- build.gradle | 8 +- src/docs/asciidoc/ohdab.adoc | 44 ++++ .../member/repository/MemberRepository.java | 2 + .../repository/mapper/MemberMapper.java | 12 + .../controller/MistakeNoteController.java | 73 ++++++ .../controller/mapper/MistakeNoteMapper.java | 92 ++++++++ .../request/SaveMistakeNoteInfoReq.java | 17 ++ .../response/GetAllMistakeNoteInfoRes.java | 29 +++ .../GetMistakeNoteInfoOfStudentRes.java | 12 + .../response/GetNumberWrongNTimes.java | 11 + .../response/SaveMistakeNoteInfoRes.java | 11 + .../ohdab/mistakenote/domain/MistakeNote.java | 36 ++- .../exception/NoMistakeNoteException.java | 18 ++ .../NoNumbersWrongNTimesException.java | 18 ++ .../NumberIsOutOfRangeException.java | 18 ++ .../repository/MistakeNoteRepository.java | 15 ++ .../mapper/MistakeRecordMapper.java | 14 ++ .../service/GetMistakeNoteInfoService.java | 89 +++++++ .../service/GetNumberWrongNTimesService.java | 78 +++++++ .../service/GetNumbersWrongNTimesService.java | 19 ++ .../service/SaveMistakeNoteInfoService.java | 51 ++++ .../service/dto/GetAllMistakeNoteInfoDto.java | 32 +++ .../dto/GetMistakeNoteInfoOfStudentDto.java | 24 ++ .../service/dto/GetNumberWrongNTimesDto.java | 28 +++ .../service/dto/SaveMistakeNoteInfoDto.java | 14 ++ .../helper/MistakeNoteHelperService.java | 17 ++ .../usecase/GetMistakeNoteInfoUsecase.java | 12 + .../usecase/GetNumberWrongNTimesUsecase.java | 9 + .../usecase/GetNumbersWrongNTimesUsecase.java | 9 + .../usecase/SaveMistakeNoteInfoUsecase.java | 8 + .../service/NumberScopeCheckService.java | 34 +++ .../exception/NoWorkbookException.java | 18 ++ .../repository/WorkbookRepository.java | 6 + src/main/resources/mapper/MemberMapper.xml | 14 ++ .../resources/mapper/MistakeRecordMapper.xml | 24 ++ .../MemberControllerTest.java | 0 .../repository/mapper/MemberMapperTest.java | 70 ++++++ .../controller/MistakeNoteControllerTest.java | 220 ++++++++++++++++++ .../repository/MistakeNoteRepositoryTest.java | 107 +++++++++ .../mapper/MistakeRecordMapperTest.java | 144 ++++++++++++ .../GetMistakeNoteInfoServiceTest.java | 171 ++++++++++++++ .../GetNumberWrongNTimesServiceTest.java | 178 ++++++++++++++ .../SaveMistakeNoteInfoServiceTest.java | 113 +++++++++ src/test/resources/application.yml | 6 +- 44 files changed, 1910 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/ohdab/member/repository/mapper/MemberMapper.java create mode 100644 src/main/java/com/ohdab/mistakenote/controller/MistakeNoteController.java create mode 100644 src/main/java/com/ohdab/mistakenote/controller/mapper/MistakeNoteMapper.java create mode 100644 src/main/java/com/ohdab/mistakenote/controller/request/SaveMistakeNoteInfoReq.java create mode 100644 src/main/java/com/ohdab/mistakenote/controller/response/GetAllMistakeNoteInfoRes.java create mode 100644 src/main/java/com/ohdab/mistakenote/controller/response/GetMistakeNoteInfoOfStudentRes.java create mode 100644 src/main/java/com/ohdab/mistakenote/controller/response/GetNumberWrongNTimes.java create mode 100644 src/main/java/com/ohdab/mistakenote/controller/response/SaveMistakeNoteInfoRes.java create mode 100644 src/main/java/com/ohdab/mistakenote/exception/NoMistakeNoteException.java create mode 100644 src/main/java/com/ohdab/mistakenote/exception/NoNumbersWrongNTimesException.java create mode 100644 src/main/java/com/ohdab/mistakenote/exception/NumberIsOutOfRangeException.java create mode 100644 src/main/java/com/ohdab/mistakenote/repository/MistakeNoteRepository.java create mode 100644 src/main/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapper.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/GetNumbersWrongNTimesService.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/dto/GetAllMistakeNoteInfoDto.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/dto/GetMistakeNoteInfoOfStudentDto.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/dto/GetNumberWrongNTimesDto.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/dto/SaveMistakeNoteInfoDto.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/usecase/GetMistakeNoteInfoUsecase.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/usecase/GetNumberWrongNTimesUsecase.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/usecase/GetNumbersWrongNTimesUsecase.java create mode 100644 src/main/java/com/ohdab/mistakenote/service/usecase/SaveMistakeNoteInfoUsecase.java create mode 100644 src/main/java/com/ohdab/workbook/domain/service/NumberScopeCheckService.java create mode 100644 src/main/java/com/ohdab/workbook/exception/NoWorkbookException.java create mode 100644 src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java create mode 100644 src/main/resources/mapper/MemberMapper.xml create mode 100644 src/main/resources/mapper/MistakeRecordMapper.xml rename src/test/java/com/ohdab/member/{Controller => controller}/MemberControllerTest.java (100%) create mode 100644 src/test/java/com/ohdab/member/repository/mapper/MemberMapperTest.java create mode 100644 src/test/java/com/ohdab/mistakenote/controller/MistakeNoteControllerTest.java create mode 100644 src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java create mode 100644 src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java create mode 100644 src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java create mode 100644 src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java create mode 100644 src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java diff --git a/build.gradle b/build.gradle index 1abce634..d56a53eb 100644 --- a/build.gradle +++ b/build.gradle @@ -50,18 +50,20 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation("io.jsonwebtoken:jjwt-api:0.11.5") + implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0' + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' - runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5") - runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5") + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' testImplementation 'com.h2database:h2:2.1.214' testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.2.0' testImplementation 'com.h2database:h2' asciidoctorExtensions 'org.springframework.restdocs:spring-restdocs-asciidoctor' } diff --git a/src/docs/asciidoc/ohdab.adoc b/src/docs/asciidoc/ohdab.adoc index 35ec9a0f..636fa14c 100644 --- a/src/docs/asciidoc/ohdab.adoc +++ b/src/docs/asciidoc/ohdab.adoc @@ -57,3 +57,47 @@ include::{snippets}/members/teachers/expulsion/{teacher-id}/http-request.adoc[] include::{snippets}/members/teachers/expulsion/{teacher-id}/http-response.adoc[] + +include::{snippets}/members/login/http-response.adoc[] + +== MistakeNote + +=== 교재 상세조회(전체 학생에 대한 오답노트 조회) + +==== Request + +include::{snippets}/mistake_note/getAllMistakeNoteInfo/http-request.adoc[] + +==== Response + +include::{snippets}/mistake_note/getAllMistakeNoteInfo/http-response.adoc[] + +=== 학생별 N번 틀린 문제 문자열 출력 + +==== Request + +include::{snippets}/mistake_note/getNumberWrongNTimes/http-request.adoc[] + +==== Response + +include::{snippets}/mistake_note/getNumberWrongNTimes/http-response.adoc[] + +=== 학생별 오답노트 조회 + +==== Request + +include::{snippets}/mistake_note/getMistakeNoteInfoByStudent/http-request.adoc[] + +==== Response + +include::{snippets}/mistake_note/getMistakeNoteInfoByStudent/http-response.adoc[] + +=== 오답 기록하기 + +==== Request + +include::{snippets}/mistake_note/saveMistakeNoteInfo/http-request.adoc[] + +==== Response + +include::{snippets}/mistake_note/saveMistakeNoteInfo/http-response.adoc[] \ No newline at end of file diff --git a/src/main/java/com/ohdab/member/repository/MemberRepository.java b/src/main/java/com/ohdab/member/repository/MemberRepository.java index 86adad8a..8dd5b143 100644 --- a/src/main/java/com/ohdab/member/repository/MemberRepository.java +++ b/src/main/java/com/ohdab/member/repository/MemberRepository.java @@ -17,4 +17,6 @@ public interface MemberRepository extends JpaRepository { Long countByMemberInfoNameContaining(String name); boolean existsById(long id); + + Optional findActiveMemberById(long memberId); } diff --git a/src/main/java/com/ohdab/member/repository/mapper/MemberMapper.java b/src/main/java/com/ohdab/member/repository/mapper/MemberMapper.java new file mode 100644 index 00000000..2131b97e --- /dev/null +++ b/src/main/java/com/ohdab/member/repository/mapper/MemberMapper.java @@ -0,0 +1,12 @@ +package com.ohdab.member.repository.mapper; + +import static com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; + +import java.util.List; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface MemberMapper { + + List findAllStudent(List studentIdList); +} diff --git a/src/main/java/com/ohdab/mistakenote/controller/MistakeNoteController.java b/src/main/java/com/ohdab/mistakenote/controller/MistakeNoteController.java new file mode 100644 index 00000000..17487b26 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/controller/MistakeNoteController.java @@ -0,0 +1,73 @@ +package com.ohdab.mistakenote.controller; + +import com.ohdab.mistakenote.controller.mapper.MistakeNoteMapper; +import com.ohdab.mistakenote.controller.request.SaveMistakeNoteInfoReq; +import com.ohdab.mistakenote.controller.response.GetAllMistakeNoteInfoRes; +import com.ohdab.mistakenote.controller.response.GetMistakeNoteInfoOfStudentRes; +import com.ohdab.mistakenote.controller.response.GetNumberWrongNTimes; +import com.ohdab.mistakenote.controller.response.SaveMistakeNoteInfoRes; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import com.ohdab.mistakenote.service.usecase.GetMistakeNoteInfoUsecase; +import com.ohdab.mistakenote.service.usecase.GetNumberWrongNTimesUsecase; +import com.ohdab.mistakenote.service.usecase.SaveMistakeNoteInfoUsecase; +import java.util.List; +import javax.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/mistake-notes") +public class MistakeNoteController { + + private final GetMistakeNoteInfoUsecase getMistakeNoteInfoUsecase; + private final GetNumberWrongNTimesUsecase getNumberWrongNTimesUsecase; + private final SaveMistakeNoteInfoUsecase saveMistakeNoteInfoUsecase; + + @GetMapping("/workbooks/{workbook-id}/students/{student-id}") + public ResponseEntity> getMistakeNoteInfoOfStudent( + @PathVariable(name = "workbook-id") long workbookId, + @PathVariable(name = "student-id") long studentId) { + GetMistakeNoteInfoOfStudentDto.Response mistakeNoteInfo = + getMistakeNoteInfoUsecase.getMistakeNoteInfoOfStudent(workbookId, studentId); + return ResponseEntity.ok( + MistakeNoteMapper.toGetMistakeNoteInfoOfStudentRes(mistakeNoteInfo)); + } + + @GetMapping("/workbooks/{workbook-id}/{mistake-note-id}") + public ResponseEntity getNumberWrongNTimes( + @PathVariable(name = "workbook-id") long workbookId, + @PathVariable(name = "mistake-note-id") long mistakeNoteId, + @RequestParam(name = "count") int count, + @RequestParam(name = "from") int from, + @RequestParam(name = "to") int to) { + GetNumberWrongNTimesDto.Response numberWrongNTimes = + getNumberWrongNTimesUsecase.getNumberWrongNTimes( + MistakeNoteMapper.toGetNumberWrongNTimeDto( + workbookId, mistakeNoteId, count, from, to)); + return ResponseEntity.ok(MistakeNoteMapper.toGetNumberWrongNTimesRes(numberWrongNTimes)); + } + + @PostMapping("/workbooks/{workbook-id}/students/{student-id}") + public ResponseEntity saveMistakeNoteInfo( + @PathVariable(name = "workbook-id") long workbookId, + @PathVariable(name = "student-id") long studentId, + @Valid @RequestBody SaveMistakeNoteInfoReq saveMistakeNoteInfoReq) { + saveMistakeNoteInfoUsecase.saveMistakeNoteInfo( + MistakeNoteMapper.toSaveMistakeNoteInfoDto( + workbookId, studentId, saveMistakeNoteInfoReq)); + return ResponseEntity.ok(SaveMistakeNoteInfoRes.builder().message("오답이 기록되었습니다.").build()); + } + + @GetMapping("/workbooks/{workbook-id}") + public ResponseEntity getAllMistakeNoteInfo( + @PathVariable(name = "workbook-id") long workbookId) { + GetAllMistakeNoteInfoDto.Response getAllMistakeNoteInfoDto = + getMistakeNoteInfoUsecase.getAllMistakeNoteInfo(workbookId); + return ResponseEntity.ok( + MistakeNoteMapper.toGetAllMistakeNoteInfoRes(getAllMistakeNoteInfoDto)); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/controller/mapper/MistakeNoteMapper.java b/src/main/java/com/ohdab/mistakenote/controller/mapper/MistakeNoteMapper.java new file mode 100644 index 00000000..14fd25d6 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/controller/mapper/MistakeNoteMapper.java @@ -0,0 +1,92 @@ +package com.ohdab.mistakenote.controller.mapper; + +import com.ohdab.mistakenote.controller.request.SaveMistakeNoteInfoReq; +import com.ohdab.mistakenote.controller.response.GetAllMistakeNoteInfoRes; +import com.ohdab.mistakenote.controller.response.GetMistakeNoteInfoOfStudentRes; +import com.ohdab.mistakenote.controller.response.GetNumberWrongNTimes; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import com.ohdab.mistakenote.service.dto.SaveMistakeNoteInfoDto; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class MistakeNoteMapper { + + public static List toGetMistakeNoteInfoOfStudentRes( + GetMistakeNoteInfoOfStudentDto.Response responseDto) { + return responseDto.getMistakeNoteInfo().stream() + .map( + dto -> + GetMistakeNoteInfoOfStudentRes.builder() + .wrongNumber(dto.getWrongNumber()) + .wrongCount(dto.getWrongCount()) + .build()) + .collect(Collectors.toList()); + } + + public static SaveMistakeNoteInfoDto toSaveMistakeNoteInfoDto( + long workbookId, long studentId, SaveMistakeNoteInfoReq saveMistakeNoteInfoReq) { + return SaveMistakeNoteInfoDto.builder() + .workbookId(workbookId) + .studentId(studentId) + .mistakeNumbers(saveMistakeNoteInfoReq.getMistakeNumbers()) + .build(); + } + + public static GetAllMistakeNoteInfoRes toGetAllMistakeNoteInfoRes( + GetAllMistakeNoteInfoDto.Response responseDto) { + return GetAllMistakeNoteInfoRes.builder() + .students(mapToStudentInfoRes(responseDto.getStudents())) + .mistakeNoteInfo( + mapToMistakeNoteInfoOfStudentRes(responseDto.getAllMistakeNoteInfo())) + .build(); + } + + private static List mapToStudentInfoRes( + List students) { + return students.stream() + .map( + dto -> + GetAllMistakeNoteInfoRes.StudentInfoRes.builder() + .studentId(dto.getStudentId()) + .name(dto.getName()) + .build()) + .collect(Collectors.toList()); + } + + private static List + mapToMistakeNoteInfoOfStudentRes( + List mistakeNoteInfo) { + return mistakeNoteInfo.stream() + .map( + dto -> + GetAllMistakeNoteInfoRes.AllMistakeNoteInfoRes.builder() + .wrongNumber(dto.getWrongNumber()) + .wrongStudentsCount(dto.getWrongStudentsCount()) + .build()) + .collect(Collectors.toList()); + } + + public static GetNumberWrongNTimesDto.Request toGetNumberWrongNTimeDto( + long workbookId, long mistakeNoteId, int count, int from, int to) { + return GetNumberWrongNTimesDto.Request.builder() + .workbookId(workbookId) + .mistakeNoteId(mistakeNoteId) + .count(count) + .from(from) + .to(to) + .build(); + } + + public static GetNumberWrongNTimes toGetNumberWrongNTimesRes( + GetNumberWrongNTimesDto.Response numbersWrongNTimes) { + return GetNumberWrongNTimes.builder() + .wrongNumber(numbersWrongNTimes.getWrongNumber()) + .build(); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/controller/request/SaveMistakeNoteInfoReq.java b/src/main/java/com/ohdab/mistakenote/controller/request/SaveMistakeNoteInfoReq.java new file mode 100644 index 00000000..62ee7df2 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/controller/request/SaveMistakeNoteInfoReq.java @@ -0,0 +1,17 @@ +package com.ohdab.mistakenote.controller.request; + +import java.util.List; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import lombok.*; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class SaveMistakeNoteInfoReq { + + @NotNull(message = "기록할 문제 번호를 하나 이상 입력해야 합니다.") + @Size(min = 1, max = 6000) + private List mistakeNumbers; +} diff --git a/src/main/java/com/ohdab/mistakenote/controller/response/GetAllMistakeNoteInfoRes.java b/src/main/java/com/ohdab/mistakenote/controller/response/GetAllMistakeNoteInfoRes.java new file mode 100644 index 00000000..bdc9095d --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/controller/response/GetAllMistakeNoteInfoRes.java @@ -0,0 +1,29 @@ +package com.ohdab.mistakenote.controller.response; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class GetAllMistakeNoteInfoRes { + + private List students; + private List mistakeNoteInfo; + + @Getter + @Builder + public static class StudentInfoRes { + + private long studentId; + private String name; + } + + @Getter + @Builder + public static class AllMistakeNoteInfoRes { + + private int wrongNumber; + private int wrongStudentsCount; + } +} diff --git a/src/main/java/com/ohdab/mistakenote/controller/response/GetMistakeNoteInfoOfStudentRes.java b/src/main/java/com/ohdab/mistakenote/controller/response/GetMistakeNoteInfoOfStudentRes.java new file mode 100644 index 00000000..f5688208 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/controller/response/GetMistakeNoteInfoOfStudentRes.java @@ -0,0 +1,12 @@ +package com.ohdab.mistakenote.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class GetMistakeNoteInfoOfStudentRes { + + private int wrongNumber; + private int wrongCount; +} diff --git a/src/main/java/com/ohdab/mistakenote/controller/response/GetNumberWrongNTimes.java b/src/main/java/com/ohdab/mistakenote/controller/response/GetNumberWrongNTimes.java new file mode 100644 index 00000000..45ff2e73 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/controller/response/GetNumberWrongNTimes.java @@ -0,0 +1,11 @@ +package com.ohdab.mistakenote.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class GetNumberWrongNTimes { + + private String wrongNumber; +} diff --git a/src/main/java/com/ohdab/mistakenote/controller/response/SaveMistakeNoteInfoRes.java b/src/main/java/com/ohdab/mistakenote/controller/response/SaveMistakeNoteInfoRes.java new file mode 100644 index 00000000..66fdcf92 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/controller/response/SaveMistakeNoteInfoRes.java @@ -0,0 +1,11 @@ +package com.ohdab.mistakenote.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class SaveMistakeNoteInfoRes { + + private String message; +} diff --git a/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java b/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java index f2bb2c0f..1881dea4 100644 --- a/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java +++ b/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java @@ -2,6 +2,8 @@ import com.ohdab.core.baseentity.BaseEntity; import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.service.NumberScopeCheckService; import com.ohdab.workbook.domain.workbookid.WorkbookId; import java.util.HashMap; import java.util.List; @@ -45,17 +47,29 @@ public MistakeNote( this.mistakeRecords = mistakeRecords; } - // TODO: refactoring - public void addMistakeNumbers(List numbers) { - if (numbers.isEmpty()) { - throw new IllegalArgumentException("예외"); - } - for (int number : numbers) { - if (mistakeRecords.containsKey(number)) { - mistakeRecords.put(number, mistakeRecords.get(number) + 1); - continue; - } - mistakeRecords.put(number, 1); + public void addMistakeNumbers( + NumberScopeCheckService numberScopeCheckService, + Workbook workbook, + List numbers) { + numberScopeCheckService.numberScopeCheck(workbook, numbers); + checkMistakeNumbersSize(numbers); + updateWrongCount(numbers); + } + + private void checkMistakeNumbersSize(List numbers) { + if (numbers.isEmpty() || numbers.size() > 500) { + throw new IllegalArgumentException("틀린 문제 번호는 최소 1개 이상, 500개 이하로 입력할 수 있습니다."); } } + + private void updateWrongCount(List numbers) { + numbers.forEach( + number -> { + if (mistakeRecords.containsKey(number)) { + mistakeRecords.put(number, mistakeRecords.get(number) + 1); + } else { + mistakeRecords.put(number, 1); + } + }); + } } diff --git a/src/main/java/com/ohdab/mistakenote/exception/NoMistakeNoteException.java b/src/main/java/com/ohdab/mistakenote/exception/NoMistakeNoteException.java new file mode 100644 index 00000000..aaad1f6e --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/exception/NoMistakeNoteException.java @@ -0,0 +1,18 @@ +package com.ohdab.mistakenote.exception; + +public class NoMistakeNoteException extends RuntimeException { + + public NoMistakeNoteException() {} + + public NoMistakeNoteException(String message) { + super(message); + } + + public NoMistakeNoteException(String message, Throwable cause) { + super(message, cause); + } + + public NoMistakeNoteException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/exception/NoNumbersWrongNTimesException.java b/src/main/java/com/ohdab/mistakenote/exception/NoNumbersWrongNTimesException.java new file mode 100644 index 00000000..94c797b9 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/exception/NoNumbersWrongNTimesException.java @@ -0,0 +1,18 @@ +package com.ohdab.mistakenote.exception; + +public class NoNumbersWrongNTimesException extends RuntimeException { + + public NoNumbersWrongNTimesException() {} + + public NoNumbersWrongNTimesException(String message) { + super(message); + } + + public NoNumbersWrongNTimesException(String message, Throwable cause) { + super(message, cause); + } + + public NoNumbersWrongNTimesException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/exception/NumberIsOutOfRangeException.java b/src/main/java/com/ohdab/mistakenote/exception/NumberIsOutOfRangeException.java new file mode 100644 index 00000000..14305781 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/exception/NumberIsOutOfRangeException.java @@ -0,0 +1,18 @@ +package com.ohdab.mistakenote.exception; + +public class NumberIsOutOfRangeException extends RuntimeException { + + public NumberIsOutOfRangeException() {} + + public NumberIsOutOfRangeException(String message) { + super(message); + } + + public NumberIsOutOfRangeException(String message, Throwable cause) { + super(message, cause); + } + + public NumberIsOutOfRangeException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/repository/MistakeNoteRepository.java b/src/main/java/com/ohdab/mistakenote/repository/MistakeNoteRepository.java new file mode 100644 index 00000000..74b833b4 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/repository/MistakeNoteRepository.java @@ -0,0 +1,15 @@ +package com.ohdab.mistakenote.repository; + +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.List; +import java.util.Optional; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MistakeNoteRepository extends JpaRepository { + + Optional findByWorkbookIdAndStudentId(WorkbookId workbookId, StudentId studentId); + + List findByWorkbookId(WorkbookId workbookId); +} diff --git a/src/main/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapper.java b/src/main/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapper.java new file mode 100644 index 00000000..71e4a94a --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapper.java @@ -0,0 +1,14 @@ +package com.ohdab.mistakenote.repository.mapper; + +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import java.util.List; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface MistakeRecordMapper { + + List findAllMistakeNoteInfo(List mistakeNoteIdList); + + List findNumbersWrongNTimes(GetNumberWrongNTimesDto.Request request); +} diff --git a/src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java b/src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java new file mode 100644 index 00000000..2bbe5495 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java @@ -0,0 +1,89 @@ +package com.ohdab.mistakenote.service; + +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.exception.NoMemberException; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.repository.mapper.MemberMapper; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.mistakenote.exception.NoMistakeNoteException; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.mistakenote.repository.mapper.MistakeRecordMapper; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto.Response.MistakeNoteInfoDto; +import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; +import com.ohdab.mistakenote.service.usecase.GetMistakeNoteInfoUsecase; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class GetMistakeNoteInfoService implements GetMistakeNoteInfoUsecase { + + private final MistakeNoteHelperService mistakeNoteHelperService; + private final MistakeNoteRepository mistakeNoteRepository; + private final MemberRepository memberRepository; + private final MistakeRecordMapper mistakeRecordMapper; + private final MemberMapper memberMapper; + + @Override + public GetMistakeNoteInfoOfStudentDto.Response getMistakeNoteInfoOfStudent( + long workbookId, long studentId) { + if (mistakeNoteHelperService.isNotExistingMember(memberRepository, studentId)) { + throw new NoMemberException("존재하지 않는 회원입니다."); + } + MistakeNote mistakeNote = + mistakeNoteRepository + .findByWorkbookIdAndStudentId( + new WorkbookId(workbookId), new StudentId(studentId)) + .orElseThrow(() -> new NoMistakeNoteException("존재하지 않는 오답노트입니다.")); + return mapToMistakeNoteInfo(mistakeNote); + } + + private GetMistakeNoteInfoOfStudentDto.Response mapToMistakeNoteInfo(MistakeNote mistakeNote) { + List mistakeNoteInfo = new ArrayList<>(); + Map mistakeRecords = mistakeNote.getMistakeRecords(); + mistakeRecords.forEach( + (number, count) -> + mistakeNoteInfo.add( + MistakeNoteInfoDto.builder() + .wrongNumber(number) + .wrongCount(count) + .build())); + return GetMistakeNoteInfoOfStudentDto.Response.builder() + .mistakeNoteInfo(mistakeNoteInfo) + .build(); + } + + @Override + public GetAllMistakeNoteInfoDto.Response getAllMistakeNoteInfo(long workbookId) { + List mistakeNotes = + mistakeNoteRepository.findByWorkbookId(new WorkbookId(workbookId)); + List students = memberMapper.findAllStudent(getStudentIdList(mistakeNotes)); + List allMistakeNoteInfoDto = + mistakeRecordMapper.findAllMistakeNoteInfo(getMistakeNoteIdList(mistakeNotes)); + return GetAllMistakeNoteInfoDto.Response.builder() + .students(students) + .allMistakeNoteInfo(allMistakeNoteInfoDto) + .build(); + } + + private List getStudentIdList(List mistakeNotes) { + return mistakeNotes.stream() + .map(mistakeNote -> mistakeNote.getStudentId().getId()) + .collect(Collectors.toList()); + } + + private List getMistakeNoteIdList(List mistakeNotes) { + return mistakeNotes.stream().map(MistakeNote::getId).collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java b/src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java new file mode 100644 index 00000000..f5245336 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java @@ -0,0 +1,78 @@ +package com.ohdab.mistakenote.service; + +import com.ohdab.mistakenote.exception.NoNumbersWrongNTimesException; +import com.ohdab.mistakenote.exception.NumberIsOutOfRangeException; +import com.ohdab.mistakenote.repository.mapper.MistakeRecordMapper; +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import com.ohdab.mistakenote.service.usecase.GetNumberWrongNTimesUsecase; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.exception.NoWorkbookException; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class GetNumberWrongNTimesService implements GetNumberWrongNTimesUsecase { + + private final MistakeRecordMapper mistakeRecordMapper; + private final WorkbookRepository workbookRepository; + + @Override + public GetNumberWrongNTimesDto.Response getNumberWrongNTimes( + GetNumberWrongNTimesDto.Request getNumberWrongNTimeDto) { + Workbook workbook = + workbookRepository + .findById(getNumberWrongNTimeDto.getWorkbookId()) + .orElseThrow(() -> new NoWorkbookException("존재하지 않는 교재입니다.")); + checkNumberIsInRange(getNumberWrongNTimeDto, workbook); + List numberWrongNTimes = + mistakeRecordMapper.findNumbersWrongNTimes(getNumberWrongNTimeDto); + return GetNumberWrongNTimesDto.Response.builder() + .wrongNumber(wrongNumbersToString(numberWrongNTimes)) + .build(); + } + + private void checkNumberIsInRange( + GetNumberWrongNTimesDto.Request getNumberWrongNTimeDto, Workbook workbook) { + int startingNumber = getStartingNumber(workbook); + int endingNumber = getEndingNumber(workbook); + int from = getFrom(getNumberWrongNTimeDto); + int to = getTo(getNumberWrongNTimeDto); + if (isNotInRange(from, startingNumber, endingNumber) + || isNotInRange(to, startingNumber, endingNumber)) { + throw new NumberIsOutOfRangeException("교재에 존재하지 않는 번호를 요청했습니다."); + } + } + + private int getStartingNumber(Workbook workbook) { + return workbook.getWorkbookInfo().getStartingNumber(); + } + + private int getEndingNumber(Workbook workbook) { + return workbook.getWorkbookInfo().getEndingNumber(); + } + + private int getTo(GetNumberWrongNTimesDto.Request getNumberWrongNTimeDto) { + return getNumberWrongNTimeDto.getTo(); + } + + private int getFrom(GetNumberWrongNTimesDto.Request getNumberWrongNTimeDto) { + return getNumberWrongNTimeDto.getFrom(); + } + + private boolean isNotInRange(int target, int startingNumber, int endingNumber) { + return (target < startingNumber || endingNumber < target); + } + + private String wrongNumbersToString(List numberWrongNTimes) { + if (numberWrongNTimes.isEmpty()) { + throw new NoNumbersWrongNTimesException("틀린 문제가 없습니다."); + } + return numberWrongNTimes.stream().map(String::valueOf).collect(Collectors.joining(",")); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/GetNumbersWrongNTimesService.java b/src/main/java/com/ohdab/mistakenote/service/GetNumbersWrongNTimesService.java new file mode 100644 index 00000000..5d93977f --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/GetNumbersWrongNTimesService.java @@ -0,0 +1,19 @@ +package com.ohdab.mistakenote.service; + +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import com.ohdab.mistakenote.service.usecase.GetNumbersWrongNTimesUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class GetNumbersWrongNTimesService implements GetNumbersWrongNTimesUsecase { + + @Override + public GetNumberWrongNTimesDto.Response getNumberWrongNTimes( + GetNumberWrongNTimesDto.Request getNumberWrongNTimeDto) { + return null; + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java b/src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java new file mode 100644 index 00000000..a2d68147 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java @@ -0,0 +1,51 @@ +package com.ohdab.mistakenote.service; + +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.exception.NoMemberException; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.mistakenote.exception.NoMistakeNoteException; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.mistakenote.service.dto.SaveMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; +import com.ohdab.mistakenote.service.usecase.SaveMistakeNoteInfoUsecase; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.service.NumberScopeCheckService; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import com.ohdab.workbook.exception.NoWorkbookException; +import com.ohdab.workbook.repository.WorkbookRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class SaveMistakeNoteInfoService implements SaveMistakeNoteInfoUsecase { + + private final MistakeNoteHelperService mistakeNoteHelperService; + private final NumberScopeCheckService numberScopeCheckService; + private final MemberRepository memberRepository; + private final MistakeNoteRepository mistakeNoteRepository; + private final WorkbookRepository workbookRepository; + + @Override + public void saveMistakeNoteInfo(SaveMistakeNoteInfoDto saveMistakeNoteInfoDto) { + if (mistakeNoteHelperService.isNotExistingMember( + memberRepository, saveMistakeNoteInfoDto.getStudentId())) { + throw new NoMemberException("존재하지 않는 회원입니다."); + } + MistakeNote mistakeNote = + mistakeNoteRepository + .findByWorkbookIdAndStudentId( + new WorkbookId(saveMistakeNoteInfoDto.getWorkbookId()), + new StudentId(saveMistakeNoteInfoDto.getStudentId())) + .orElseThrow(() -> new NoMistakeNoteException("존재하지 않는 오답노트입니다.")); + Workbook workbook = + workbookRepository + .findById(saveMistakeNoteInfoDto.getWorkbookId()) + .orElseThrow(() -> new NoWorkbookException("존재하지 않는 교재입니다.")); + mistakeNote.addMistakeNumbers( + numberScopeCheckService, workbook, saveMistakeNoteInfoDto.getMistakeNumbers()); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/dto/GetAllMistakeNoteInfoDto.java b/src/main/java/com/ohdab/mistakenote/service/dto/GetAllMistakeNoteInfoDto.java new file mode 100644 index 00000000..ab557842 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/dto/GetAllMistakeNoteInfoDto.java @@ -0,0 +1,32 @@ +package com.ohdab.mistakenote.service.dto; + +import java.util.List; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class GetAllMistakeNoteInfoDto { + + @Getter + @Builder + public static class Response { + private List students; + private List allMistakeNoteInfo; + + @Getter + @Builder + public static class StudentInfoDto { + private long studentId; + private String name; + } + + @Getter + @Builder + public static class AllMistakeNoteInfoDto { + private int wrongNumber; + private int wrongStudentsCount; + } + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/dto/GetMistakeNoteInfoOfStudentDto.java b/src/main/java/com/ohdab/mistakenote/service/dto/GetMistakeNoteInfoOfStudentDto.java new file mode 100644 index 00000000..b7705cec --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/dto/GetMistakeNoteInfoOfStudentDto.java @@ -0,0 +1,24 @@ +package com.ohdab.mistakenote.service.dto; + +import java.util.List; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class GetMistakeNoteInfoOfStudentDto { + + @Getter + @Builder + public static class Response { + private List mistakeNoteInfo; + + @Getter + @Builder + public static class MistakeNoteInfoDto { + private int wrongNumber; + private int wrongCount; + } + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/dto/GetNumberWrongNTimesDto.java b/src/main/java/com/ohdab/mistakenote/service/dto/GetNumberWrongNTimesDto.java new file mode 100644 index 00000000..bfd43c18 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/dto/GetNumberWrongNTimesDto.java @@ -0,0 +1,28 @@ +package com.ohdab.mistakenote.service.dto; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class GetNumberWrongNTimesDto { + + @Getter + @Builder + public static class Request { + + private long workbookId; + private long mistakeNoteId; + private int count; + private int from; + private int to; + } + + @Getter + @Builder + public static class Response { + + private String wrongNumber; + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/dto/SaveMistakeNoteInfoDto.java b/src/main/java/com/ohdab/mistakenote/service/dto/SaveMistakeNoteInfoDto.java new file mode 100644 index 00000000..c1795131 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/dto/SaveMistakeNoteInfoDto.java @@ -0,0 +1,14 @@ +package com.ohdab.mistakenote.service.dto; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class SaveMistakeNoteInfoDto { + + private long workbookId; + private long studentId; + private List mistakeNumbers; +} diff --git a/src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java b/src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java new file mode 100644 index 00000000..7c817f7f --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java @@ -0,0 +1,17 @@ +package com.ohdab.mistakenote.service.helper; + +import com.ohdab.member.domain.Member; +import com.ohdab.member.repository.MemberRepository; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class MistakeNoteHelperService { + + public boolean isNotExistingMember(MemberRepository memberRepository, long memberId) { + Optional memberOpt = memberRepository.findActiveMemberById(memberId); + return memberOpt.isEmpty(); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/usecase/GetMistakeNoteInfoUsecase.java b/src/main/java/com/ohdab/mistakenote/service/usecase/GetMistakeNoteInfoUsecase.java new file mode 100644 index 00000000..4ce4c857 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/usecase/GetMistakeNoteInfoUsecase.java @@ -0,0 +1,12 @@ +package com.ohdab.mistakenote.service.usecase; + +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; + +public interface GetMistakeNoteInfoUsecase { + + GetMistakeNoteInfoOfStudentDto.Response getMistakeNoteInfoOfStudent( + long workbookId, long studentId); + + GetAllMistakeNoteInfoDto.Response getAllMistakeNoteInfo(long workbookId); +} diff --git a/src/main/java/com/ohdab/mistakenote/service/usecase/GetNumberWrongNTimesUsecase.java b/src/main/java/com/ohdab/mistakenote/service/usecase/GetNumberWrongNTimesUsecase.java new file mode 100644 index 00000000..8e5ea748 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/usecase/GetNumberWrongNTimesUsecase.java @@ -0,0 +1,9 @@ +package com.ohdab.mistakenote.service.usecase; + +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; + +public interface GetNumberWrongNTimesUsecase { + + GetNumberWrongNTimesDto.Response getNumberWrongNTimes( + GetNumberWrongNTimesDto.Request getNumbersWrongNTimeDto); +} diff --git a/src/main/java/com/ohdab/mistakenote/service/usecase/GetNumbersWrongNTimesUsecase.java b/src/main/java/com/ohdab/mistakenote/service/usecase/GetNumbersWrongNTimesUsecase.java new file mode 100644 index 00000000..4ddca95a --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/usecase/GetNumbersWrongNTimesUsecase.java @@ -0,0 +1,9 @@ +package com.ohdab.mistakenote.service.usecase; + +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; + +public interface GetNumbersWrongNTimesUsecase { + + GetNumberWrongNTimesDto.Response getNumberWrongNTimes( + GetNumberWrongNTimesDto.Request getNumbersWrongNTimeDto); +} diff --git a/src/main/java/com/ohdab/mistakenote/service/usecase/SaveMistakeNoteInfoUsecase.java b/src/main/java/com/ohdab/mistakenote/service/usecase/SaveMistakeNoteInfoUsecase.java new file mode 100644 index 00000000..32854a23 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/service/usecase/SaveMistakeNoteInfoUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.mistakenote.service.usecase; + +import com.ohdab.mistakenote.service.dto.SaveMistakeNoteInfoDto; + +public interface SaveMistakeNoteInfoUsecase { + + void saveMistakeNoteInfo(SaveMistakeNoteInfoDto saveMistakeNoteInfoDto); +} diff --git a/src/main/java/com/ohdab/workbook/domain/service/NumberScopeCheckService.java b/src/main/java/com/ohdab/workbook/domain/service/NumberScopeCheckService.java new file mode 100644 index 00000000..536998ec --- /dev/null +++ b/src/main/java/com/ohdab/workbook/domain/service/NumberScopeCheckService.java @@ -0,0 +1,34 @@ +package com.ohdab.workbook.domain.service; + +import com.ohdab.workbook.domain.Workbook; +import java.util.List; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +public class NumberScopeCheckService { + + public void numberScopeCheck(Workbook workbook, List numbers) { + int startingNumber = getStartingNumber(workbook); + int endingNumber = getEndingNumber(workbook); + verify(numbers, startingNumber, endingNumber); + } + + private int getEndingNumber(Workbook workbook) { + return workbook.getWorkbookInfo().getEndingNumber(); + } + + private int getStartingNumber(Workbook workbook) { + return workbook.getWorkbookInfo().getStartingNumber(); + } + + private void verify(List numbers, int startingNumber, int endingNumber) { + numbers.forEach( + number -> { + if (number < startingNumber || number > endingNumber) { + throw new IllegalArgumentException("책에 없는 문제 번호가 포함되어있습니다."); + } + }); + } +} diff --git a/src/main/java/com/ohdab/workbook/exception/NoWorkbookException.java b/src/main/java/com/ohdab/workbook/exception/NoWorkbookException.java new file mode 100644 index 00000000..97538bcc --- /dev/null +++ b/src/main/java/com/ohdab/workbook/exception/NoWorkbookException.java @@ -0,0 +1,18 @@ +package com.ohdab.workbook.exception; + +public class NoWorkbookException extends RuntimeException { + + public NoWorkbookException() {} + + public NoWorkbookException(String message) { + super(message); + } + + public NoWorkbookException(String message, Throwable cause) { + super(message, cause); + } + + public NoWorkbookException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java b/src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java new file mode 100644 index 00000000..cd6ca05f --- /dev/null +++ b/src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java @@ -0,0 +1,6 @@ +package com.ohdab.workbook.repository; + +import com.ohdab.workbook.domain.Workbook; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface WorkbookRepository extends JpaRepository {} diff --git a/src/main/resources/mapper/MemberMapper.xml b/src/main/resources/mapper/MemberMapper.xml new file mode 100644 index 00000000..1375935a --- /dev/null +++ b/src/main/resources/mapper/MemberMapper.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/src/main/resources/mapper/MistakeRecordMapper.xml b/src/main/resources/mapper/MistakeRecordMapper.xml new file mode 100644 index 00000000..74b97799 --- /dev/null +++ b/src/main/resources/mapper/MistakeRecordMapper.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/ohdab/member/Controller/MemberControllerTest.java b/src/test/java/com/ohdab/member/controller/MemberControllerTest.java similarity index 100% rename from src/test/java/com/ohdab/member/Controller/MemberControllerTest.java rename to src/test/java/com/ohdab/member/controller/MemberControllerTest.java diff --git a/src/test/java/com/ohdab/member/repository/mapper/MemberMapperTest.java b/src/test/java/com/ohdab/member/repository/mapper/MemberMapperTest.java new file mode 100644 index 00000000..b30834b3 --- /dev/null +++ b/src/test/java/com/ohdab/member/repository/mapper/MemberMapperTest.java @@ -0,0 +1,70 @@ +package com.ohdab.member.repository.mapper; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.memberinfo.MemberInfo; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; +import java.util.List; +import javax.persistence.EntityManager; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mybatis.spring.boot.test.autoconfigure.AutoConfigureMybatis; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +@AutoConfigureMybatis +class MemberMapperTest { + + @Autowired private MemberMapper memberMapper; + @Autowired private MemberRepository memberRepository; + @Autowired private EntityManager em; + + @DisplayName("특정 반의 학생 명단을 조회한다.") + @Test + void 교재_상세조회_학생명단() { + // given + final Member student1 = + Member.builder() + .memberInfo(MemberInfo.builder().name("갑").password("1234").build()) + .authorities(List.of(new Authority("STUDENT"))) + .build(); + final Member student2 = + Member.builder() + .memberInfo(MemberInfo.builder().name("을").password("1234").build()) + .authorities(List.of(new Authority("STUDENT"))) + .build(); + final Member student3 = + Member.builder() + .memberInfo(MemberInfo.builder().name("병").password("1234").build()) + .authorities(List.of(new Authority("STUDENT"))) + .build(); + + Member savedStudent1 = memberRepository.save(student1); + Member savedStudent2 = memberRepository.save(student2); + Member savedStudent3 = memberRepository.save(student3); + + em.flush(); + em.clear(); + + // when + List result = + memberMapper.findAllStudent( + List.of( + savedStudent1.getId(), + savedStudent2.getId(), + savedStudent3.getId())); + + // then + assertThat(result) + .hasSize(3) + .extracting("studentId", "name") + .contains(tuple(savedStudent1.getId(), "갑")) + .contains(tuple(savedStudent2.getId(), "을")) + .contains(tuple(savedStudent3.getId(), "병")); + } +} diff --git a/src/test/java/com/ohdab/mistakenote/controller/MistakeNoteControllerTest.java b/src/test/java/com/ohdab/mistakenote/controller/MistakeNoteControllerTest.java new file mode 100644 index 00000000..8ac346c7 --- /dev/null +++ b/src/test/java/com/ohdab/mistakenote/controller/MistakeNoteControllerTest.java @@ -0,0 +1,220 @@ +package com.ohdab.mistakenote.controller; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +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.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ohdab.mistakenote.controller.request.SaveMistakeNoteInfoReq; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto.Response.MistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import com.ohdab.mistakenote.service.dto.SaveMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.usecase.GetMistakeNoteInfoUsecase; +import com.ohdab.mistakenote.service.usecase.GetNumberWrongNTimesUsecase; +import com.ohdab.mistakenote.service.usecase.SaveMistakeNoteInfoUsecase; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; + +@AutoConfigureRestDocs +@WebMvcTest(controllers = MistakeNoteController.class) +class MistakeNoteControllerTest { + + @Autowired private MockMvc mockMvc; + @Autowired private ObjectMapper objectMapper; + @MockBean private GetMistakeNoteInfoUsecase getMistakeNoteInfoUsecase; + @MockBean private GetNumberWrongNTimesUsecase getNumberWrongNTimesUsecase; + @MockBean private SaveMistakeNoteInfoUsecase saveMistakeNoteInfoUsecase; + + @Test + @WithMockUser + void 학생별_오답노트_조회() throws Exception { + // given + final String GET_MISTAKE_NOTE_INFO_BY_STUDENT_URL = + "/mistake-notes/workbooks/{workbook-id}/students/{student-id}"; + + final List mistakeNoteInfo = new ArrayList<>(); + mistakeNoteInfo.add(MistakeNoteInfoDto.builder().wrongNumber(1).wrongCount(3).build()); + mistakeNoteInfo.add(MistakeNoteInfoDto.builder().wrongNumber(2).wrongCount(1).build()); + final GetMistakeNoteInfoOfStudentDto.Response responseDto = + GetMistakeNoteInfoOfStudentDto.Response.builder() + .mistakeNoteInfo(mistakeNoteInfo) + .build(); + + // when + when(getMistakeNoteInfoUsecase.getMistakeNoteInfoOfStudent(anyLong(), anyLong())) + .thenReturn(responseDto); + + // then + mockMvc.perform( + get(GET_MISTAKE_NOTE_INFO_BY_STUDENT_URL, 1, 2) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$[0].wrongNumber") + .value(responseDto.getMistakeNoteInfo().get(0).getWrongNumber()), + jsonPath("$[0].wrongCount") + .value(responseDto.getMistakeNoteInfo().get(0).getWrongCount()), + jsonPath("$[1].wrongNumber") + .value(responseDto.getMistakeNoteInfo().get(1).getWrongNumber()), + jsonPath("$[1].wrongCount") + .value(responseDto.getMistakeNoteInfo().get(1).getWrongCount())) + .andDo(print()) + .andDo(createDocument("mistake_note/getMistakeNoteInfoByStudent")); + } + + @Test + @WithMockUser + void 오답_기록하기() throws Exception { + // given + final String SAVE_MISTAKE_NOTE_INFO_URL = + "/mistake-notes/workbooks/{workbook-id}/students/{student-id}"; + + final List mistakeNumbers = new ArrayList<>(); + mistakeNumbers.add(1); + mistakeNumbers.add(2); + mistakeNumbers.add(3); + final SaveMistakeNoteInfoReq saveMistakeNoteInfoReq = + SaveMistakeNoteInfoReq.builder().mistakeNumbers(mistakeNumbers).build(); + + // when + doNothing() + .when(saveMistakeNoteInfoUsecase) + .saveMistakeNoteInfo(any(SaveMistakeNoteInfoDto.class)); + + // then + mockMvc.perform( + post(SAVE_MISTAKE_NOTE_INFO_URL, 1, 2) + .with(csrf()) + .content(objectMapper.writeValueAsString(saveMistakeNoteInfoReq)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("오답이 기록되었습니다.")) + .andDo(print()) + .andDo(createDocument("mistake_note/saveMistakeNoteInfo")); + } + + @Test + @WithMockUser + void 교재_상세조회() throws Exception { + // given + final String GET_MISTAKE_NOTE_INFO_OF_CLASSROOM_URL = + "/mistake-notes/workbooks/{workbook-id}"; + + final List students = new ArrayList<>(); + students.add(StudentInfoDto.builder().studentId(2).name("갑").build()); + students.add(StudentInfoDto.builder().studentId(3).name("을").build()); + students.add(StudentInfoDto.builder().studentId(4).name("병").build()); + + final List mistakeNoteInfo = + new ArrayList<>(); + mistakeNoteInfo.add( + GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto.builder() + .wrongNumber(1) + .wrongStudentsCount(4) + .build()); + mistakeNoteInfo.add( + GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto.builder() + .wrongNumber(4) + .wrongStudentsCount(2) + .build()); + mistakeNoteInfo.add( + GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto.builder() + .wrongNumber(10) + .wrongStudentsCount(7) + .build()); + + final GetAllMistakeNoteInfoDto.Response responseDto = + GetAllMistakeNoteInfoDto.Response.builder() + .students(students) + .allMistakeNoteInfo(mistakeNoteInfo) + .build(); + + // when + when(getMistakeNoteInfoUsecase.getAllMistakeNoteInfo(anyLong())).thenReturn(responseDto); + + // then + mockMvc.perform( + get(GET_MISTAKE_NOTE_INFO_OF_CLASSROOM_URL, 1) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.students.[0].studentId").value(2), + jsonPath("$.students.[0].name").value("갑"), + jsonPath("$.students.[1].studentId").value(3), + jsonPath("$.students.[1].name").value("을"), + jsonPath("$.students.[2].studentId").value(4), + jsonPath("$.students.[2].name").value("병"), + jsonPath("$.mistakeNoteInfo.[0].wrongNumber").value(1), + jsonPath("$.mistakeNoteInfo.[0].wrongStudentsCount").value(4), + jsonPath("$.mistakeNoteInfo.[1].wrongNumber").value(4), + jsonPath("$.mistakeNoteInfo.[1].wrongStudentsCount").value(2), + jsonPath("$.mistakeNoteInfo.[2].wrongNumber").value(10), + jsonPath("$.mistakeNoteInfo.[2].wrongStudentsCount").value(7)) + .andDo(print()) + .andDo(createDocument("mistake_note/getAllMistakeNoteInfo")); + } + + @Test + @WithMockUser + void 학생별_N번_이상_틀린_문제_출력() throws Exception { + // given + final String GET_NUMBER_WRONG_N_TIMES = + "/mistake-notes/workbooks/{workbook-id}/{mistake-note-id}"; + + final String wrongNumber = "30,31,33,40,45,50"; + + final GetNumberWrongNTimesDto.Response responseDto = + GetNumberWrongNTimesDto.Response.builder().wrongNumber(wrongNumber).build(); + + // when + when(getNumberWrongNTimesUsecase.getNumberWrongNTimes( + any(GetNumberWrongNTimesDto.Request.class))) + .thenReturn(responseDto); + + // then + mockMvc.perform( + get(GET_NUMBER_WRONG_N_TIMES, 1L, 2L) + .param("count", "2") + .param("from", "30") + .param("to", "50") + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.wrongNumber").value(wrongNumber)) + .andDo(print()) + .andDo(createDocument("mistake_note/getNumberWrongNTimes")); + } + + private RestDocumentationResultHandler createDocument(String identifier) { + return document( + identifier, preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); + } +} diff --git a/src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java b/src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java new file mode 100644 index 00000000..05f8f8a8 --- /dev/null +++ b/src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java @@ -0,0 +1,107 @@ +package com.ohdab.mistakenote.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.persistence.EntityManager; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class MistakeNoteRepositoryTest { + + @Autowired private MistakeNoteRepository mistakeNoteRepository; + @Autowired private EntityManager em; + + @DisplayName("교재 id와 학생 id를 통해 오답노트를 조회한다.") + @Test + void 학생별_오답노트_조회() { + // given + final StudentId studentId = new StudentId(1L); + final WorkbookId workbookId = new WorkbookId(2L); + + final Map mistakeRecords = new HashMap<>(); + mistakeRecords.put(1, 2); + mistakeRecords.put(2, 4); + mistakeRecords.put(4, 1); + final MistakeNote mistakeNote = + MistakeNote.builder() + .workbookId(workbookId) + .studentId(studentId) + .mistakeRecords(mistakeRecords) + .build(); + + mistakeNoteRepository.save(mistakeNote); + em.flush(); + em.clear(); + + // when + MistakeNote result = + mistakeNoteRepository.findByWorkbookIdAndStudentId(workbookId, studentId).get(); + + // then + assertThat(result.getWorkbookId().getId()).isEqualTo(workbookId.getId()); + assertThat(result.getStudentId().getId()).isEqualTo(studentId.getId()); + assertThat(result.getMistakeRecords()).containsEntry(1, 2); + assertThat(result.getMistakeRecords()).containsEntry(2, 4); + assertThat(result.getMistakeRecords()).containsEntry(4, 1); + } + + @DisplayName("변경감지를 활용하여 틀린 문제 번호마다 틀린 횟수를 저장한다.") + @Test + void 오답_기록하기() { + // given + final List numbers = new ArrayList<>(); + numbers.add(1); + numbers.add(2); + numbers.add(3); + numbers.add(5); + + final StudentId studentId = new StudentId(1L); + final WorkbookId workbookId = new WorkbookId(2L); + + final Map mistakeRecords = new HashMap<>(); + mistakeRecords.put(1, 2); + mistakeRecords.put(2, 4); + mistakeRecords.put(4, 1); + final MistakeNote mistakeNote = + MistakeNote.builder() + .workbookId(workbookId) + .studentId(studentId) + .mistakeRecords(mistakeRecords) + .build(); + + MistakeNote savedMistakeNote = mistakeNoteRepository.save(mistakeNote); + Map savedRecords = savedMistakeNote.getMistakeRecords(); + + // when + numbers.forEach( + number -> { + if (savedRecords.containsKey(number)) { + savedRecords.put(number, savedRecords.get(number) + 1); + } else { + savedRecords.put(number, 1); + } + }); + em.flush(); + em.clear(); + + // then + MistakeNote result = mistakeNoteRepository.findById(savedMistakeNote.getId()).get(); + Map resultRecords = result.getMistakeRecords(); + assertThat(resultRecords) + .containsEntry(1, 3) + .containsEntry(2, 5) + .containsEntry(3, 1) + .containsEntry(4, 1) + .containsEntry(5, 1); + } +} diff --git a/src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java b/src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java new file mode 100644 index 00000000..3b9122c3 --- /dev/null +++ b/src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java @@ -0,0 +1,144 @@ +package com.ohdab.mistakenote.repository.mapper; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.persistence.EntityManager; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.mybatis.spring.boot.test.autoconfigure.AutoConfigureMybatis; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +@AutoConfigureMybatis +class MistakeRecordMapperTest { + + @Autowired private MistakeRecordMapper mistakeRecordMapper; + @Autowired private MistakeNoteRepository mistakeNoteRepository; + @Autowired private EntityManager em; + + @DisplayName("전체 학생에 대한 오답노트를 조회한다.") + @Test + void 교재_상세조회() { + // given + final WorkbookId workbookId = new WorkbookId(10L); + + final StudentId studentId1 = new StudentId(1L); + final Map mistakeRecords1 = new HashMap<>(); + mistakeRecords1.put(1, 1); + mistakeRecords1.put(2, 2); + mistakeRecords1.put(3, 3); + final MistakeNote mistakeNote1 = + MistakeNote.builder() + .workbookId(workbookId) + .studentId(studentId1) + .mistakeRecords(mistakeRecords1) + .build(); + + final StudentId studentId2 = new StudentId(2L); + final Map mistakeRecords2 = new HashMap<>(); + mistakeRecords2.put(3, 1); + mistakeRecords2.put(4, 2); + mistakeRecords2.put(5, 1); + final MistakeNote mistakeNote2 = + MistakeNote.builder() + .workbookId(workbookId) + .studentId(studentId2) + .mistakeRecords(mistakeRecords2) + .build(); + + final StudentId studentId3 = new StudentId(3L); + final Map mistakeRecords3 = new HashMap<>(); + mistakeRecords3.put(1, 1); + mistakeRecords3.put(102, 1); + mistakeRecords3.put(110, 2); + final MistakeNote mistakeNote3 = + MistakeNote.builder() + .workbookId(workbookId) + .studentId(studentId3) + .mistakeRecords(mistakeRecords3) + .build(); + + MistakeNote savedMistakeNote1 = mistakeNoteRepository.save(mistakeNote1); + MistakeNote savedMistakeNote2 = mistakeNoteRepository.save(mistakeNote2); + MistakeNote savedMistakeNote3 = mistakeNoteRepository.save(mistakeNote3); + + em.flush(); + em.clear(); + + // when + List result = + mistakeRecordMapper.findAllMistakeNoteInfo( + List.of( + savedMistakeNote1.getId(), + savedMistakeNote2.getId(), + savedMistakeNote3.getId())); + + // then + assertThat(result) + .extracting("wrongNumber", "wrongStudentsCount") + .contains(tuple(1, 2)) + .contains(tuple(2, 1)) + .contains(tuple(3, 2)) + .contains(tuple(4, 1)) + .contains(tuple(5, 1)) + .contains(tuple(102, 1)) + .contains(tuple(110, 1)); + } + + @DisplayName("주어진 범위 내에서 N번 이상 틀린 문제 번호를 오름차순으로 조회한다.") + @Test + void 학생별_N번_이상_틀린_문제_출력() { + // given + final WorkbookId workbookId = new WorkbookId(10L); + + final StudentId studentId = new StudentId(1L); + final Map mistakeRecords = new HashMap<>(); + mistakeRecords.put(1, 1); + mistakeRecords.put(2, 2); + + mistakeRecords.put(10, 2); + mistakeRecords.put(20, 3); + mistakeRecords.put(22, 1); + mistakeRecords.put(25, 2); + mistakeRecords.put(30, 1); + + mistakeRecords.put(40, 4); + final MistakeNote mistakeNote = + MistakeNote.builder() + .workbookId(workbookId) + .studentId(studentId) + .mistakeRecords(mistakeRecords) + .build(); + + MistakeNote savedMistakeNote = mistakeNoteRepository.save(mistakeNote); + + em.flush(); + em.clear(); + + final GetNumberWrongNTimesDto.Request requestDto = + GetNumberWrongNTimesDto.Request.builder() + .workbookId(10L) + .mistakeNoteId(savedMistakeNote.getId()) + .count(2) + .from(10) + .to(30) + .build(); + + // when + List result = mistakeRecordMapper.findNumbersWrongNTimes(requestDto); + + // then + assertThat(result).hasSize(3).contains(10, 20, 25); + } +} diff --git a/src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java b/src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java new file mode 100644 index 00000000..205dd00f --- /dev/null +++ b/src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java @@ -0,0 +1,171 @@ +package com.ohdab.mistakenote.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.when; + +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.memberinfo.MemberInfo; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.member.repository.mapper.MemberMapper; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.mistakenote.repository.mapper.MistakeRecordMapper; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; +import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; +import com.ohdab.mistakenote.service.usecase.GetMistakeNoteInfoUsecase; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.*; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {GetMistakeNoteInfoService.class, MistakeNoteHelperService.class}) +class GetMistakeNoteInfoServiceTest { + + @Autowired private GetMistakeNoteInfoUsecase getMistakeNoteInfoUsecase; + @Autowired private MistakeNoteHelperService mistakeNoteHelperService; + @MockBean private MistakeNoteRepository mistakeNoteRepository; + @MockBean private MemberRepository memberRepository; + @MockBean private MistakeRecordMapper mistakeRecordMapper; + @MockBean private MemberMapper memberMapper; + + @DisplayName("교재 Id, 학생 Id를 통해 학생별 오답노트를 조회한다.") + @Test + void 학생별_오답노트_조회() throws Exception { + // given + final long workbookId = 1; + final long studentId = 2; + + final List authorities = new ArrayList<>(); + authorities.add(new Authority("TEACHER")); + + final Member findMember = + Member.builder() + .memberInfo(MemberInfo.builder().name("test").password("1234").build()) + .authorities(authorities) + .build(); + + final Map mistakeRecords = new HashMap<>(); + mistakeRecords.put(1, 2); + mistakeRecords.put(2, 4); + mistakeRecords.put(4, 1); + + final MistakeNote mistakeNote = + MistakeNote.builder() + .workbookId(new WorkbookId(workbookId)) + .studentId(new StudentId(studentId)) + .mistakeRecords(mistakeRecords) + .build(); + + // when + when(memberRepository.findActiveMemberById(anyLong())).thenReturn(Optional.of(findMember)); + when(mistakeNoteRepository.findByWorkbookIdAndStudentId( + any(WorkbookId.class), any(StudentId.class))) + .thenReturn(Optional.of(mistakeNote)); + GetMistakeNoteInfoOfStudentDto.Response result = + getMistakeNoteInfoUsecase.getMistakeNoteInfoOfStudent(workbookId, studentId); + + // then + assertThat(result.getMistakeNoteInfo().get(0).getWrongNumber()).isEqualTo(1); + assertThat(result.getMistakeNoteInfo().get(0).getWrongCount()).isEqualTo(2); + assertThat(result.getMistakeNoteInfo().get(1).getWrongNumber()).isEqualTo(2); + assertThat(result.getMistakeNoteInfo().get(1).getWrongCount()).isEqualTo(4); + assertThat(result.getMistakeNoteInfo().get(2).getWrongNumber()).isEqualTo(4); + assertThat(result.getMistakeNoteInfo().get(2).getWrongCount()).isEqualTo(1); + } + + @DisplayName("교재 id를 통해 해당 교재에 대한 모든 학생들의 오답 기록을 조회한다.") + @Test + void 교재_상세조회() { + // given + final WorkbookId workbookId = new WorkbookId(1L); + + List mistakeNotes = new ArrayList<>(); + + final Map mistakeRecords2 = new HashMap<>(); + mistakeRecords2.put(1, 2); + mistakeRecords2.put(2, 2); + mistakeRecords2.put(3, 2); + mistakeNotes.add( + MistakeNote.builder() + .workbookId(workbookId) + .studentId(new StudentId(2L)) + .mistakeRecords(mistakeRecords2) + .build()); + + final Map mistakeNoteRecords3 = new HashMap<>(); + mistakeNoteRecords3.put(2, 2); + mistakeNoteRecords3.put(3, 2); + mistakeNoteRecords3.put(4, 2); + mistakeNotes.add( + MistakeNote.builder() + .workbookId(workbookId) + .studentId(new StudentId(3L)) + .mistakeRecords(mistakeNoteRecords3) + .build()); + + final Map mistakeRecords4 = new HashMap<>(); + mistakeRecords4.put(3, 2); + mistakeRecords4.put(4, 2); + mistakeRecords4.put(5, 2); + mistakeNotes.add( + MistakeNote.builder() + .workbookId(workbookId) + .studentId(new StudentId(4L)) + .mistakeRecords(mistakeRecords4) + .build()); + + final List students = new ArrayList<>(); + students.add(StudentInfoDto.builder().studentId(10L).name("갑").build()); + students.add(StudentInfoDto.builder().studentId(11L).name("을").build()); + students.add(StudentInfoDto.builder().studentId(12L).name("병").build()); + + final List allMistakeNoteInfoDto = new ArrayList<>(); + allMistakeNoteInfoDto.add( + AllMistakeNoteInfoDto.builder().wrongNumber(1).wrongStudentsCount(1).build()); + allMistakeNoteInfoDto.add( + AllMistakeNoteInfoDto.builder().wrongNumber(2).wrongStudentsCount(2).build()); + allMistakeNoteInfoDto.add( + AllMistakeNoteInfoDto.builder().wrongNumber(3).wrongStudentsCount(3).build()); + allMistakeNoteInfoDto.add( + AllMistakeNoteInfoDto.builder().wrongNumber(4).wrongStudentsCount(2).build()); + allMistakeNoteInfoDto.add( + AllMistakeNoteInfoDto.builder().wrongNumber(5).wrongStudentsCount(1).build()); + + // when + when(mistakeNoteRepository.findByWorkbookId(any(WorkbookId.class))) + .thenReturn(mistakeNotes); + when(memberMapper.findAllStudent(anyList())).thenReturn(students); + when(mistakeRecordMapper.findAllMistakeNoteInfo(anyList())) + .thenReturn(allMistakeNoteInfoDto); + GetAllMistakeNoteInfoDto.Response result = + getMistakeNoteInfoUsecase.getAllMistakeNoteInfo(workbookId.getId()); + + // then + assertThat(result.getAllMistakeNoteInfo()).hasSize(5); + assertThat(result.getStudents()).hasSize(3); + assertThat(result.getAllMistakeNoteInfo()) + .extracting(AllMistakeNoteInfoDto::getWrongNumber) + .contains(1, 2, 3, 4, 5); + assertThat(result.getAllMistakeNoteInfo()) + .extracting(AllMistakeNoteInfoDto::getWrongStudentsCount) + .contains(1, 2, 3, 2, 1); + assertThat(result.getStudents()) + .extracting(StudentInfoDto::getStudentId) + .contains(10L, 11L, 12L); + assertThat(result.getStudents()) + .extracting(StudentInfoDto::getName) + .contains("갑", "을", "병"); + } +} diff --git a/src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java b/src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java new file mode 100644 index 00000000..5455b28b --- /dev/null +++ b/src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java @@ -0,0 +1,178 @@ +package com.ohdab.mistakenote.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchException; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; + +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.mistakenote.exception.NoNumbersWrongNTimesException; +import com.ohdab.mistakenote.exception.NumberIsOutOfRangeException; +import com.ohdab.mistakenote.repository.mapper.MistakeRecordMapper; +import com.ohdab.mistakenote.service.dto.GetNumberWrongNTimesDto; +import com.ohdab.mistakenote.service.usecase.GetNumberWrongNTimesUsecase; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {GetNumberWrongNTimesService.class}) +class GetNumberWrongNTimesServiceTest { + + @Autowired private GetNumberWrongNTimesUsecase getNumberWrongNTimesUsecase; + + @MockBean private MistakeRecordMapper mistakeRecordMapper; + @MockBean private WorkbookRepository workbookRepository; + + @DisplayName("getNumbersWrongNTimes 메서드는") + @Nested + class getNumbersWrongNTimes { + + @DisplayName("요청받은 범위가 해당 교재의 문제범위에 속하고") + @Nested + class ifInRange { + + @DisplayName("N번 이상 틀린 문제가 존재한다면") + @Nested + class ifResultIsExist { + @DisplayName("틀린 문제번호들을 쉼표로 구분하여 공백없는 문자열로 반환한다") + @Test + void success() { + // given + final GetNumberWrongNTimesDto.Request requestDto = + GetNumberWrongNTimesDto.Request.builder() + .workbookId(1L) + .mistakeNoteId(2L) + .count(2) + .from(10) + .to(20) + .build(); + + final Workbook workbook = + Workbook.builder() + .classroomId(new ClassroomId(10L)) + .workbookInfo( + WorkbookInfo.builder() + .name("책이름") + .description("설명") + .startingNumber(1) + .endingNumber(1000) + .build()) + .build(); + + final List numberWrongNTimes = List.of(10, 11, 12, 19, 20); + + // when + when(workbookRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(workbook)); + when(mistakeRecordMapper.findNumbersWrongNTimes(requestDto)) + .thenReturn(numberWrongNTimes); + GetNumberWrongNTimesDto.Response result = + getNumberWrongNTimesUsecase.getNumberWrongNTimes(requestDto); + + // then + assertThat(result).extracting("wrongNumber").isEqualTo("10,11,12,19,20"); + } + } + + @DisplayName("N번 이상 틀린 문제가 없다면") + @Nested + class ifNoResult { + + @DisplayName("NoNumbersWrongNTimesException 예외를 던진다.") + @Test + void throwNoNumbersWrongNTimesException() { + // given + final GetNumberWrongNTimesDto.Request requestDto = + GetNumberWrongNTimesDto.Request.builder() + .workbookId(1L) + .mistakeNoteId(2L) + .count(2) + .from(10) + .to(20) + .build(); + + final Workbook workbook = + Workbook.builder() + .classroomId(new ClassroomId(10L)) + .workbookInfo( + WorkbookInfo.builder() + .name("책이름") + .description("설명") + .startingNumber(1) + .endingNumber(1000) + .build()) + .build(); + + final List numberWrongNTimes = new ArrayList<>(); + + // when + when(workbookRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(workbook)); + when(mistakeRecordMapper.findNumbersWrongNTimes(requestDto)) + .thenReturn(numberWrongNTimes); + Throwable thrown = + catchException( + () -> + getNumberWrongNTimesUsecase.getNumberWrongNTimes( + requestDto)); + + // then + assertThat(thrown).isInstanceOf(NoNumbersWrongNTimesException.class); + } + } + } + + @DisplayName("요청받은 범위가 해당 교재의 문제범위에 속하지 않는다면") + @Nested + class ifIsNotInRange { + + @DisplayName("NumberIsOutOfRangeException 예외를 던진다.") + @Test + void trowNumberIsOutOfRangeException() { + // given + final GetNumberWrongNTimesDto.Request requestDto = + GetNumberWrongNTimesDto.Request.builder() + .workbookId(1L) + .mistakeNoteId(2L) + .count(2) + .from(20) + .to(2000) + .build(); + + final Workbook workbook = + Workbook.builder() + .classroomId(new ClassroomId(10L)) + .workbookInfo( + WorkbookInfo.builder() + .name("책이름") + .description("설명") + .startingNumber(1) + .endingNumber(1000) + .build()) + .build(); + + // when + when(workbookRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(workbook)); + Throwable thrown = + catchException( + () -> getNumberWrongNTimesUsecase.getNumberWrongNTimes(requestDto)); + + // then + assertThat(thrown).isInstanceOf(NumberIsOutOfRangeException.class); + } + } + } +} diff --git a/src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java b/src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java new file mode 100644 index 00000000..a16bd98d --- /dev/null +++ b/src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java @@ -0,0 +1,113 @@ +package com.ohdab.mistakenote.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; + +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.memberinfo.MemberInfo; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.mistakenote.service.dto.SaveMistakeNoteInfoDto; +import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; +import com.ohdab.mistakenote.service.usecase.SaveMistakeNoteInfoUsecase; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.service.NumberScopeCheckService; +import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.*; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration( + classes = { + SaveMistakeNoteInfoService.class, + MistakeNoteHelperService.class, + NumberScopeCheckService.class + }) +class SaveMistakeNoteInfoServiceTest { + + @Autowired private SaveMistakeNoteInfoUsecase saveMistakeNoteInfoUsecase; + @MockBean private MemberRepository memberRepository; + @MockBean private MistakeNoteRepository mistakeNoteRepository; + @MockBean private WorkbookRepository workbookRepository; + + @DisplayName("틀린 문제의 번호들을 입력하여 학생의 오답을 기록한다.") + @Test + void 오답_기록하기() { + // given + final long workbookId = 1L; + final long studentId = 2L; + + final List authorities = new ArrayList<>(); + authorities.add(new Authority("STUDENT")); + final Member findMember = + Member.builder() + .memberInfo(MemberInfo.builder().name("test").password("1234").build()) + .authorities(authorities) + .build(); + + final List mistakeNumbers = new ArrayList<>(); + mistakeNumbers.add(1); + mistakeNumbers.add(2); + mistakeNumbers.add(3); + mistakeNumbers.add(5); + final SaveMistakeNoteInfoDto saveMistakeNoteInfoDto = + SaveMistakeNoteInfoDto.builder() + .workbookId(workbookId) + .studentId(studentId) + .mistakeNumbers(mistakeNumbers) + .build(); + + final Map mistakeRecords = new HashMap<>(); + mistakeRecords.put(1, 2); + mistakeRecords.put(2, 4); + mistakeRecords.put(4, 1); + final MistakeNote mistakeNote = + MistakeNote.builder() + .workbookId(new WorkbookId(workbookId)) + .studentId(new StudentId(studentId)) + .mistakeRecords(mistakeRecords) + .build(); + + final WorkbookInfo workbookInfo = + WorkbookInfo.builder() + .name("test workbook") + .description("test description") + .startingNumber(1) + .endingNumber(4000) + .build(); + final Workbook workbook = + Workbook.builder() + .classroomId(new ClassroomId(3L)) + .workbookInfo(workbookInfo) + .build(); + + // when + when(memberRepository.findActiveMemberById(anyLong())).thenReturn(Optional.of(findMember)); + when(mistakeNoteRepository.findByWorkbookIdAndStudentId( + any(WorkbookId.class), any(StudentId.class))) + .thenReturn(Optional.of(mistakeNote)); + when(workbookRepository.findById(anyLong())).thenReturn(Optional.of(workbook)); + saveMistakeNoteInfoUsecase.saveMistakeNoteInfo(saveMistakeNoteInfoDto); + + // then + assertThat(mistakeNote.getMistakeRecords()).containsEntry(1, 3); + assertThat(mistakeNote.getMistakeRecords()).containsEntry(2, 5); + assertThat(mistakeNote.getMistakeRecords()).containsEntry(3, 1); + assertThat(mistakeNote.getMistakeRecords()).containsEntry(4, 1); + assertThat(mistakeNote.getMistakeRecords()).containsEntry(5, 1); + } +} diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml index b076decc..1bc70598 100644 --- a/src/test/resources/application.yml +++ b/src/test/resources/application.yml @@ -9,4 +9,8 @@ spring: properties: hibernate: format_sql: true - use_sql_comments: true \ No newline at end of file + use_sql_comments: true + +mybatis: + mapper-locations: mapper/*.xml + type-aliases-package: com/ohdab \ No newline at end of file From 148dc4b78896b553a34599f248711f8308b6385a Mon Sep 17 00:00:00 2001 From: seongha_h <11pi885@gmail.com> Date: Wed, 9 Aug 2023 00:05:48 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20classroom=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20api=20=EA=B0=9C=EB=B0=9C=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> --- src/docs/asciidoc/ohdab.adoc | 59 ++++- .../controller/ClassroomController.java | 73 ++++++ .../controller/mapper/ClassroomMapper.java | 79 +++++++ .../controller/request/AddClassroomReq.java | 22 ++ .../request/UpdateClassroomReq.java | 19 ++ .../controller/response/AddClassroomRes.java | 10 + .../response/ClassroomDetailRes.java | 20 ++ .../controller/response/ClassroomResList.java | 21 ++ .../response/DeleteClassroomRes.java | 10 + .../response/UpdateClassroomRes.java | 10 + .../com/ohdab/classroom/domain/Classroom.java | 7 +- .../domain/classroomInfo/ClassroomInfo.java | 2 + .../classroom/domain/classroomInfo/Grade.java | 32 ++- .../CannotFindClassroomException.java | 8 + .../exception/CannotFindGradeException.java | 8 + .../exception/CannotFindTeacherException.java | 8 + .../repository/ClassroomRepository.java | 12 + .../service/AddClassroomService.java | 52 +++++ .../service/ClassroomDetailService.java | 25 +++ .../service/DeleteClassroomService.java | 24 ++ .../service/FindClassroomDetailService.java | 25 +++ .../service/FindClassroomListService.java | 25 +++ .../service/UpdateClassroomInfoService.java | 34 +++ .../service/dto/ClassroomDetailDto.java | 38 ++++ .../classroom/service/dto/ClassroomDto.java | 39 ++++ .../service/dto/ClassroomUpdateDto.java | 19 ++ .../helper/ClassroomServiceHelper.java | 26 +++ .../mapper/ClassroomDetailServiceMapper.java | 36 +++ .../mapper/ClassroomServiceMapper.java | 43 ++++ .../service/usecase/AddClassroomUsecase.java | 8 + .../usecase/ClassroomDetailUsecase.java | 8 + .../usecase/DeleteClassroomUsecase.java | 6 + .../usecase/FindClassroomDetailUsecase.java | 8 + .../usecase/FindClassroomListUsecase.java | 9 + .../usecase/UpdateClassroomInfoUsecase.java | 8 + .../member/repository/MemberRepository.java | 2 - .../controller/ClassroomControllerTest.java | 211 ++++++++++++++++++ .../AddClassroomRepositoryTest.java | 48 ++++ .../DeleteClassroomRepositoryTest.java | 49 ++++ ...AllClassroomByTeacherIdRepositoryTest.java | 62 +++++ ...ClassroomByTeacherIdRepositoryTestReq.java | 65 ++++++ .../FindClassroomByIdRepositoryTest.java | 52 +++++ .../UpdateClassroomRepositoryTest.java | 55 +++++ .../service/AddClassroomServiceTest.java | 49 ++++ .../UpdateClassroomInfoServiceTest.java | 62 +++++ 45 files changed, 1472 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/ohdab/classroom/controller/ClassroomController.java create mode 100644 src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java create mode 100644 src/main/java/com/ohdab/classroom/controller/request/AddClassroomReq.java create mode 100644 src/main/java/com/ohdab/classroom/controller/request/UpdateClassroomReq.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/AddClassroomRes.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/ClassroomDetailRes.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/ClassroomResList.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/DeleteClassroomRes.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/UpdateClassroomRes.java create mode 100644 src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java create mode 100644 src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java create mode 100644 src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java create mode 100644 src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java create mode 100644 src/main/java/com/ohdab/classroom/service/AddClassroomService.java create mode 100644 src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java create mode 100644 src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java create mode 100644 src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java create mode 100644 src/main/java/com/ohdab/classroom/service/FindClassroomListService.java create mode 100644 src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/ClassroomDetailDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/ClassroomDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/ClassroomUpdateDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java create mode 100644 src/main/java/com/ohdab/classroom/service/mapper/ClassroomDetailServiceMapper.java create mode 100644 src/main/java/com/ohdab/classroom/service/mapper/ClassroomServiceMapper.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/AddClassroomUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/ClassroomDetailUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/DeleteClassroomUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/FindClassroomDetailUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/FindClassroomListUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/UpdateClassroomInfoUsecase.java create mode 100644 src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java create mode 100644 src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java create mode 100644 src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java create mode 100644 src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTest.java create mode 100644 src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java create mode 100644 src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java create mode 100644 src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java create mode 100644 src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java create mode 100644 src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java diff --git a/src/docs/asciidoc/ohdab.adoc b/src/docs/asciidoc/ohdab.adoc index 636fa14c..863b0ce9 100644 --- a/src/docs/asciidoc/ohdab.adoc +++ b/src/docs/asciidoc/ohdab.adoc @@ -25,7 +25,7 @@ include::{snippets}/members/login/http-request.adoc[] ==== Response -include::{snippets}/members/login/http-response.adoc +include::{snippets}/members/login/http-response.adoc[] === 선생님 목록 조회 @@ -57,9 +57,6 @@ include::{snippets}/members/teachers/expulsion/{teacher-id}/http-request.adoc[] include::{snippets}/members/teachers/expulsion/{teacher-id}/http-response.adoc[] - -include::{snippets}/members/login/http-response.adoc[] - == MistakeNote === 교재 상세조회(전체 학생에 대한 오답노트 조회) @@ -100,4 +97,56 @@ include::{snippets}/mistake_note/saveMistakeNoteInfo/http-request.adoc[] ==== Response -include::{snippets}/mistake_note/saveMistakeNoteInfo/http-response.adoc[] \ No newline at end of file +include::{snippets}/mistake_note/saveMistakeNoteInfo/http-response.adoc[] + +== Classroom + +=== 반 추가 + +==== Request + +include::{snippets}/classrooms/enrollment/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/enrollment/http-response.adoc[] + +=== 반 목록 조회 + +==== Request + +include::{snippets}/classrooms?teacherId=/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms?teacherId=/http-response.adoc[] + +=== 반 상세 조회 + +==== Request + +include::{snippets}/classrooms/{classroom-id}/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/{classroom-id}/http-response.adoc[] + +=== 반 정보 수정 + +==== Request + +include::{snippets}/classrooms/info/{classroom-id}/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/info/{classroom-id}/http-response.adoc[] + +=== 반 삭제 + +==== Request + +include::{snippets}/classrooms/expulsion/{classroom-id}/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/expulsion/{classroom-id}/http-response.adoc[] diff --git a/src/main/java/com/ohdab/classroom/controller/ClassroomController.java b/src/main/java/com/ohdab/classroom/controller/ClassroomController.java new file mode 100644 index 00000000..83fa7667 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/ClassroomController.java @@ -0,0 +1,73 @@ +package com.ohdab.classroom.controller; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; +import static com.ohdab.classroom.service.dto.ClassroomUpdateDto.ClassroomUpdateDtoRequest; + +import com.ohdab.classroom.controller.mapper.ClassroomMapper; +import com.ohdab.classroom.controller.request.AddClassroomReq; +import com.ohdab.classroom.controller.request.UpdateClassroomReq; +import com.ohdab.classroom.controller.response.*; +import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.classroom.service.usecase.*; +import java.util.List; +import javax.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/classrooms") +public class ClassroomController { + + private final AddClassroomUsecase addClassroomUsecase; + private final FindClassroomListUsecase findClassroomListUsecase; + private final FindClassroomDetailUsecase findClassroomDetailUsecase; + private final UpdateClassroomInfoUsecase updateClassroomInfoUsecase; + private final DeleteClassroomUsecase deleteClassroomUsecase; + + @PostMapping("/enrollment") + public ResponseEntity addClassroom( + @Valid @RequestBody AddClassroomReq addClassroomReq) { + ClassroomDto.Request classroomReqDto = + ClassroomMapper.classroomReqToClassroomDtoRequest(addClassroomReq); + addClassroomUsecase.addClassroom(classroomReqDto); + return ResponseEntity.ok(ClassroomMapper.createClassRoomRes()); + } + + @GetMapping("") + public ResponseEntity getClassroomListByTeacherId( + @RequestParam(name = "teacherId") long teacherId) { + List responses = + findClassroomListUsecase.findClassroomListByTeacherId(teacherId); + return ResponseEntity.ok(ClassroomMapper.classroomDtoListToClassroomResList(responses)); + } + + @GetMapping("/{classroom-id}") + public ResponseEntity getClassroomDetailById( + @PathVariable("classroom-id") long id) { + ClassroomDetailDtoResponse classroomDetail = + findClassroomDetailUsecase.getClassroomDetailById(id); + ClassroomDetailRes classroomDetailRes = + ClassroomMapper.ClassroomDetailToClassroomDetailRes(classroomDetail); + return ResponseEntity.ok(classroomDetailRes); + } + + @PatchMapping("/info/{classroom-id}") + public ResponseEntity updateClassroom( + @PathVariable(name = "classroom-id") long classroomId, + @RequestBody @Valid UpdateClassroomReq request) { + ClassroomUpdateDtoRequest classroomUpdateDto = + ClassroomMapper.classroomUpdateDtoReqToClassroomUpdateDtoRequest( + classroomId, request); + updateClassroomInfoUsecase.updateClassroomInfo(classroomUpdateDto); + return ResponseEntity.ok(UpdateClassroomRes.builder().message("반 정보 수정 성공").build()); + } + + @DeleteMapping("/expulsion/{classroom-id}") + public ResponseEntity deleteClassroom( + @PathVariable(name = "classroom-id") long classroomId) { + deleteClassroomUsecase.deleteClassroomById(classroomId); + return ResponseEntity.ok(DeleteClassroomRes.builder().message("반 삭제 성공").build()); + } +} diff --git a/src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java b/src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java new file mode 100644 index 00000000..fe0e2dc4 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java @@ -0,0 +1,79 @@ +package com.ohdab.classroom.controller.mapper; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; +import static com.ohdab.classroom.service.dto.ClassroomUpdateDto.ClassroomUpdateDtoRequest; + +import com.ohdab.classroom.controller.request.AddClassroomReq; +import com.ohdab.classroom.controller.request.UpdateClassroomReq; +import com.ohdab.classroom.controller.response.AddClassroomRes; +import com.ohdab.classroom.controller.response.ClassroomDetailRes; +import com.ohdab.classroom.controller.response.ClassroomResList; +import com.ohdab.classroom.service.dto.ClassroomDto; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ClassroomMapper { + public static ClassroomDto.Request classroomReqToClassroomDtoRequest( + AddClassroomReq addClassroomReq) { + + return ClassroomDto.Request.builder() + .info( + ClassroomDto.Info.builder() + .name(addClassroomReq.getName()) + .description(addClassroomReq.getDescription()) + .grade(addClassroomReq.getGrade()) + .build()) + .teacherId(addClassroomReq.getTeacherId()) + .build(); + } + + public static AddClassroomRes createClassRoomRes() { + return AddClassroomRes.builder().message("반이 추가되었습니다.").build(); + } + + public static ClassroomResList classroomDtoListToClassroomResList( + List classroomDtoList) { + return ClassroomResList.builder() + .classroomInfoList( + classroomDtoList.stream() + .map( + classroomDto -> + ClassroomResList.ClassroomInfo.builder() + .id(classroomDto.getId()) + .name(classroomDto.getInfo().getName()) + .description( + classroomDto + .getInfo() + .getDescription()) + .grade(classroomDto.getInfo().getGrade()) + .build()) + .collect(Collectors.toList())) + .build(); + } + + public static ClassroomDetailRes ClassroomDetailToClassroomDetailRes( + ClassroomDetailDtoResponse detailDto) { + return ClassroomDetailRes.builder() + .id(detailDto.getClassroomId()) + .teacherId(detailDto.getTeacherId()) + .name(detailDto.getInfo().getName()) + .description(detailDto.getInfo().getDescription()) + .grade(detailDto.getInfo().getGrade()) + .studentIds(detailDto.getStudentIds()) + .workbookIds(detailDto.getWorkbookIds()) + .build(); + } + + public static ClassroomUpdateDtoRequest classroomUpdateDtoReqToClassroomUpdateDtoRequest( + long classroomId, UpdateClassroomReq request) { + return ClassroomUpdateDtoRequest.builder() + .classroomId(classroomId) + .name(request.getName()) + .description(request.getDescription()) + .grade(request.getGrade()) + .build(); + } +} diff --git a/src/main/java/com/ohdab/classroom/controller/request/AddClassroomReq.java b/src/main/java/com/ohdab/classroom/controller/request/AddClassroomReq.java new file mode 100644 index 00000000..8e37aacf --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/request/AddClassroomReq.java @@ -0,0 +1,22 @@ +package com.ohdab.classroom.controller.request; + +import javax.validation.constraints.NotNull; +import lombok.*; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AddClassroomReq { + + @NotNull(message = "반 이름은 필수 입력 값입니다.") + private String name; + + @NotNull(message = "반 설명은 필수 입력값 입니다.") + private String description; + + private String grade; + + @NotNull(message = "선생님 아이디는 필수 입력값 입니다.") + private long teacherId; +} diff --git a/src/main/java/com/ohdab/classroom/controller/request/UpdateClassroomReq.java b/src/main/java/com/ohdab/classroom/controller/request/UpdateClassroomReq.java new file mode 100644 index 00000000..2c8a10d2 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/request/UpdateClassroomReq.java @@ -0,0 +1,19 @@ +package com.ohdab.classroom.controller.request; + +import javax.validation.constraints.NotNull; +import lombok.*; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class UpdateClassroomReq { + + @NotNull(message = "반 이름은 필수 입력 값입니다.") + private String name; + + @NotNull(message = "반 설명은 필수 입력값 입니다.") + private String description; + + private String grade; +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/AddClassroomRes.java b/src/main/java/com/ohdab/classroom/controller/response/AddClassroomRes.java new file mode 100644 index 00000000..e4ba2e04 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/AddClassroomRes.java @@ -0,0 +1,10 @@ +package com.ohdab.classroom.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class AddClassroomRes { + String message; +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/ClassroomDetailRes.java b/src/main/java/com/ohdab/classroom/controller/response/ClassroomDetailRes.java new file mode 100644 index 00000000..6859f217 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/ClassroomDetailRes.java @@ -0,0 +1,20 @@ +package com.ohdab.classroom.controller.response; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class ClassroomDetailRes { + + private long id; + + private String name; + private String description; + private String grade; + + private long teacherId; + private List studentIds; + private List workbookIds; +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/ClassroomResList.java b/src/main/java/com/ohdab/classroom/controller/response/ClassroomResList.java new file mode 100644 index 00000000..05189e6e --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/ClassroomResList.java @@ -0,0 +1,21 @@ +package com.ohdab.classroom.controller.response; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class ClassroomResList { + + List classroomInfoList; + + @Getter + @Builder + public static class ClassroomInfo { + private long id; + private String name; + private String description; + private String grade; + } +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/DeleteClassroomRes.java b/src/main/java/com/ohdab/classroom/controller/response/DeleteClassroomRes.java new file mode 100644 index 00000000..0a6a9773 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/DeleteClassroomRes.java @@ -0,0 +1,10 @@ +package com.ohdab.classroom.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class DeleteClassroomRes { + String message; +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/UpdateClassroomRes.java b/src/main/java/com/ohdab/classroom/controller/response/UpdateClassroomRes.java new file mode 100644 index 00000000..d8fe7759 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/UpdateClassroomRes.java @@ -0,0 +1,10 @@ +package com.ohdab.classroom.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class UpdateClassroomRes { + String message; +} diff --git a/src/main/java/com/ohdab/classroom/domain/Classroom.java b/src/main/java/com/ohdab/classroom/domain/Classroom.java index 2b6b3785..363eaec7 100644 --- a/src/main/java/com/ohdab/classroom/domain/Classroom.java +++ b/src/main/java/com/ohdab/classroom/domain/Classroom.java @@ -5,6 +5,7 @@ import com.ohdab.member.domain.student.studentid.StudentId; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.ArrayList; import java.util.List; import javax.persistence.*; import lombok.AccessLevel; @@ -31,11 +32,11 @@ public class Classroom extends BaseEntity { @ElementCollection @CollectionTable(name = "STUDENT_LIST", joinColumns = @JoinColumn(name = "classroom_id")) - private List students; + private List students = new ArrayList<>(); @ElementCollection @CollectionTable(name = "WORKBOOK_LIST", joinColumns = @JoinColumn(name = "classroom_id")) - private List workbooks; + private List workbooks = new ArrayList<>(); @Builder public Classroom(ClassroomInfo classroomInfo, TeacherId teacher) { @@ -49,7 +50,7 @@ public Classroom(ClassroomInfo classroomInfo, TeacherId teacher) { setTeacher(teacher); } - private void setClassroomInfo(ClassroomInfo classroomInfo) { + public void setClassroomInfo(ClassroomInfo classroomInfo) { this.classroomInfo = classroomInfo; } diff --git a/src/main/java/com/ohdab/classroom/domain/classroomInfo/ClassroomInfo.java b/src/main/java/com/ohdab/classroom/domain/classroomInfo/ClassroomInfo.java index 411febaa..0739f6c0 100644 --- a/src/main/java/com/ohdab/classroom/domain/classroomInfo/ClassroomInfo.java +++ b/src/main/java/com/ohdab/classroom/domain/classroomInfo/ClassroomInfo.java @@ -28,6 +28,7 @@ private void setName(String name) { throw new IllegalStateException( "Name length cannot exceed 20 : current length \"" + name.length() + "\""); } + this.name = name; } private void setDescription(String description) { @@ -37,6 +38,7 @@ private void setDescription(String description) { + name.length() + "\""); } + this.description = description; } private void setGrade(Grade grade) { diff --git a/src/main/java/com/ohdab/classroom/domain/classroomInfo/Grade.java b/src/main/java/com/ohdab/classroom/domain/classroomInfo/Grade.java index e6167f8b..a7207840 100644 --- a/src/main/java/com/ohdab/classroom/domain/classroomInfo/Grade.java +++ b/src/main/java/com/ohdab/classroom/domain/classroomInfo/Grade.java @@ -1,13 +1,33 @@ package com.ohdab.classroom.domain.classroomInfo; +import java.util.HashMap; +import java.util.Map; import lombok.Getter; @Getter public enum Grade { - MID_1, - MID_2, - MID_3, - HIGH_1, - HIGH_2, - HIGH_3; + MID_1("mid1"), + MID_2("mid2"), + MID_3("mid3"), + HIGH_1("high1"), + HIGH_2("high2"), + HIGH_3("high3"); + + public final String label; + + private Grade(String label) { + this.label = label; + } + + private static final Map BY_LABEL = new HashMap<>(); + + static { + for (Grade e : values()) { + BY_LABEL.put(e.label, e); + } + } + + public static Grade valueOfLabel(String label) { + return BY_LABEL.get(label); + } } diff --git a/src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java b/src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java new file mode 100644 index 00000000..a47134d0 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.exception; + +public class CannotFindClassroomException extends RuntimeException { + + public CannotFindClassroomException(String message, Exception e) { + super(message); + } +} diff --git a/src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java b/src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java new file mode 100644 index 00000000..0ff1854f --- /dev/null +++ b/src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.exception; + +public class CannotFindGradeException extends RuntimeException { + + public CannotFindGradeException(String message, Exception e) { + super(message); + } +} diff --git a/src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java b/src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java new file mode 100644 index 00000000..1c55bc17 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.exception; + +public class CannotFindTeacherException extends RuntimeException { + + public CannotFindTeacherException(String message) { + super(message); + } +} diff --git a/src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java b/src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java new file mode 100644 index 00000000..78846980 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java @@ -0,0 +1,12 @@ +package com.ohdab.classroom.repository; + +import com.ohdab.classroom.domain.Classroom; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ClassroomRepository extends JpaRepository { + + List findAllByTeacherId(long teacherId); + + Classroom findClassroomById(long classroomId); +} diff --git a/src/main/java/com/ohdab/classroom/service/AddClassroomService.java b/src/main/java/com/ohdab/classroom/service/AddClassroomService.java new file mode 100644 index 00000000..78a44491 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/AddClassroomService.java @@ -0,0 +1,52 @@ +package com.ohdab.classroom.service; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.exception.CannotFindTeacherException; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.classroom.service.helper.ClassroomServiceHelper; +import com.ohdab.classroom.service.usecase.AddClassroomUsecase; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import com.ohdab.member.repository.MemberRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class AddClassroomService implements AddClassroomUsecase { + + private final MemberRepository memberRepository; + private final ClassroomRepository classroomRepository; + + @Override + public void addClassroom(ClassroomDto.Request classroomReqDto) { + long teacherId = classroomReqDto.getTeacherId(); + throwIfTeacherDoesNotExist(teacherId); + + ClassroomInfo classroomInfo = + ClassroomInfo.builder() + .name(classroomReqDto.getInfo().getName()) + .description(classroomReqDto.getInfo().getDescription()) + .grade( + ClassroomServiceHelper.findGradeByString( + classroomReqDto.getInfo().getGrade())) + .build(); + + Classroom classroom = + Classroom.builder() + .teacher(TeacherId.builder().id(teacherId).build()) + .classroomInfo(classroomInfo) + .build(); + + classroomRepository.save(classroom); + } + + private void throwIfTeacherDoesNotExist(Long teacherId) { + if (!memberRepository.existsById(teacherId)) { + throw new CannotFindTeacherException("cannot find teacher by id : " + teacherId); + } + } +} diff --git a/src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java b/src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java new file mode 100644 index 00000000..46051019 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java @@ -0,0 +1,25 @@ +package com.ohdab.classroom.service; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.mapper.ClassroomDetailServiceMapper; +import com.ohdab.classroom.service.usecase.ClassroomDetailUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ClassroomDetailService implements ClassroomDetailUsecase { + + private final ClassroomRepository classroomRepository; + + @Override + public ClassroomDetailDtoResponse getClassroomDetailById(long classroomId) { + Classroom classroom = classroomRepository.findClassroomById(classroomId); + return ClassroomDetailServiceMapper.classroomToClassroomDetail(classroom); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java b/src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java new file mode 100644 index 00000000..142025e0 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java @@ -0,0 +1,24 @@ +package com.ohdab.classroom.service; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.helper.ClassroomServiceHelper; +import com.ohdab.classroom.service.usecase.DeleteClassroomUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class DeleteClassroomService implements DeleteClassroomUsecase { + + private final ClassroomRepository classroomRepository; + + @Override + public void deleteClassroomById(long classroomId) { + Classroom classroom = + ClassroomServiceHelper.getClassroomById(classroomId, classroomRepository); + classroomRepository.delete(classroom); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java b/src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java new file mode 100644 index 00000000..1a39848b --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java @@ -0,0 +1,25 @@ +package com.ohdab.classroom.service; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.mapper.ClassroomDetailServiceMapper; +import com.ohdab.classroom.service.usecase.FindClassroomDetailUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class FindClassroomDetailService implements FindClassroomDetailUsecase { + + private final ClassroomRepository classroomRepository; + + @Override + public ClassroomDetailDtoResponse getClassroomDetailById(long classroomId) { + Classroom classroom = classroomRepository.findClassroomById(classroomId); + return ClassroomDetailServiceMapper.classroomToClassroomDetail(classroom); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/FindClassroomListService.java b/src/main/java/com/ohdab/classroom/service/FindClassroomListService.java new file mode 100644 index 00000000..7bef280d --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/FindClassroomListService.java @@ -0,0 +1,25 @@ +package com.ohdab.classroom.service; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.classroom.service.mapper.ClassroomServiceMapper; +import com.ohdab.classroom.service.usecase.FindClassroomListUsecase; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class FindClassroomListService implements FindClassroomListUsecase { + + private final ClassroomRepository classroomRepository; + + @Override + public List findClassroomListByTeacherId(long teacherId) { + List classroomList = classroomRepository.findAllByTeacherId(teacherId); + return ClassroomServiceMapper.classroomListToClassroomDtoList(classroomList); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java b/src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java new file mode 100644 index 00000000..1a50deb5 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java @@ -0,0 +1,34 @@ +package com.ohdab.classroom.service; + +import static com.ohdab.classroom.service.dto.ClassroomUpdateDto.ClassroomUpdateDtoRequest; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.helper.ClassroomServiceHelper; +import com.ohdab.classroom.service.usecase.UpdateClassroomInfoUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class UpdateClassroomInfoService implements UpdateClassroomInfoUsecase { + + private final ClassroomRepository classroomRepository; + + @Override + public void updateClassroomInfo(ClassroomUpdateDtoRequest request) { + Classroom classroom = + ClassroomServiceHelper.getClassroomById( + request.getClassroomId(), classroomRepository); + classroom.setClassroomInfo( + ClassroomInfo.builder() + .name(request.getName()) + .description(request.getDescription()) + .grade(ClassroomServiceHelper.findGradeByString(request.getGrade())) + .build()); + classroomRepository.save(classroom); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/ClassroomDetailDto.java b/src/main/java/com/ohdab/classroom/service/dto/ClassroomDetailDto.java new file mode 100644 index 00000000..3dbdc648 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/ClassroomDetailDto.java @@ -0,0 +1,38 @@ +package com.ohdab.classroom.service.dto; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class ClassroomDetailDto { + + @Getter + @Builder + public static class ClassroomDetailDtoInfo { + private String name; + private String description; + private String grade; + } + + @Getter + @Builder + public static class ClassroomDetailDtoRequest { + private long classroomId; + } + + @Getter + @Builder + public static class ClassroomDetailDtoResponse { + private long classroomId; + + private long teacherId; + + private ClassroomDetailDtoInfo info; + + private List studentIds; + + private List workbookIds; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/ClassroomDto.java b/src/main/java/com/ohdab/classroom/service/dto/ClassroomDto.java new file mode 100644 index 00000000..3391df22 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/ClassroomDto.java @@ -0,0 +1,39 @@ +package com.ohdab.classroom.service.dto; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class ClassroomDto { + + @Getter + @Builder + public static class Info { + private String name; + private String description; + private String grade; + } + + @Getter + @Builder + public static class Request { + private Info info; + private long teacherId; + } + + @Getter + @Builder + public static class Response { + private long id; + + private long teacherId; + + private Info info; + + private List studentIds; + + private List workbookIds; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/ClassroomUpdateDto.java b/src/main/java/com/ohdab/classroom/service/dto/ClassroomUpdateDto.java new file mode 100644 index 00000000..5e1813c5 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/ClassroomUpdateDto.java @@ -0,0 +1,19 @@ +package com.ohdab.classroom.service.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class ClassroomUpdateDto { + + @Getter + @Builder + public static class ClassroomUpdateDtoRequest { + private long classroomId; + + private String name; + private String description; + private String grade; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java b/src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java new file mode 100644 index 00000000..56a9821a --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java @@ -0,0 +1,26 @@ +package com.ohdab.classroom.service.helper; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.classroom.exception.CannotFindClassroomException; +import com.ohdab.classroom.exception.CannotFindGradeException; +import com.ohdab.classroom.repository.ClassroomRepository; + +public class ClassroomServiceHelper { + + public static Grade findGradeByString(String stringGrade) { + try { + return Grade.valueOfLabel(stringGrade); + } catch (Exception e) { + throw new CannotFindGradeException("Cannot find Grade : " + stringGrade, e); + } + } + + public static Classroom getClassroomById(long id, ClassroomRepository classroomRepository) { + try { + return classroomRepository.findClassroomById(id); + } catch (Exception e) { + throw new CannotFindClassroomException("반을 찾을 수 없습니다. id : " + id, e); + } + } +} diff --git a/src/main/java/com/ohdab/classroom/service/mapper/ClassroomDetailServiceMapper.java b/src/main/java/com/ohdab/classroom/service/mapper/ClassroomDetailServiceMapper.java new file mode 100644 index 00000000..1bb1c07e --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/mapper/ClassroomDetailServiceMapper.java @@ -0,0 +1,36 @@ +package com.ohdab.classroom.service.mapper; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoInfo; +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ClassroomDetailServiceMapper { + + public static ClassroomDetailDtoResponse classroomToClassroomDetail(Classroom classroom) { + return ClassroomDetailDtoResponse.builder() + .classroomId(classroom.getId()) + .teacherId(classroom.getTeacher().getId()) + .info( + ClassroomDetailDtoInfo.builder() + .name(classroom.getClassroomInfo().getName()) + .description(classroom.getClassroomInfo().getDescription()) + .grade(classroom.getClassroomInfo().getGrade().getLabel()) + .build()) + .studentIds( + classroom.getStudents().stream() + .map(StudentId::getId) + .collect(Collectors.toList())) + .workbookIds( + classroom.getWorkbooks().stream() + .map(WorkbookId::getId) + .collect(Collectors.toList())) + .build(); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/mapper/ClassroomServiceMapper.java b/src/main/java/com/ohdab/classroom/service/mapper/ClassroomServiceMapper.java new file mode 100644 index 00000000..b61c6f4c --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/mapper/ClassroomServiceMapper.java @@ -0,0 +1,43 @@ +package com.ohdab.classroom.service.mapper; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.List; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ClassroomServiceMapper { + + public static List classroomListToClassroomDtoList( + List classrooms) { + return classrooms.stream() + .map(ClassroomServiceMapper::classroomToClassroomDto) + .collect(Collectors.toList()); + } + + public static ClassroomDto.Response classroomToClassroomDto(Classroom classroom) { + + return ClassroomDto.Response.builder() + .id(classroom.getId()) + .teacherId(classroom.getTeacher().getId()) + .info( + ClassroomDto.Info.builder() + .name(classroom.getClassroomInfo().getName()) + .description(classroom.getClassroomInfo().getDescription()) + .grade(classroom.getClassroomInfo().getGrade().getLabel()) + .build()) + .studentIds( + classroom.getStudents().stream() + .map(StudentId::getId) + .collect(Collectors.toList())) + .workbookIds( + classroom.getWorkbooks().stream() + .map(WorkbookId::getId) + .collect(Collectors.toList())) + .build(); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/AddClassroomUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/AddClassroomUsecase.java new file mode 100644 index 00000000..26ca4e4c --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/AddClassroomUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.service.usecase; + +import com.ohdab.classroom.service.dto.ClassroomDto; + +public interface AddClassroomUsecase { + + void addClassroom(ClassroomDto.Request classroomReqDto); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/ClassroomDetailUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/ClassroomDetailUsecase.java new file mode 100644 index 00000000..e8b7113b --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/ClassroomDetailUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.service.usecase; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; + +public interface ClassroomDetailUsecase { + + ClassroomDetailDtoResponse getClassroomDetailById(long classroomId); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/DeleteClassroomUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/DeleteClassroomUsecase.java new file mode 100644 index 00000000..ad02e544 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/DeleteClassroomUsecase.java @@ -0,0 +1,6 @@ +package com.ohdab.classroom.service.usecase; + +public interface DeleteClassroomUsecase { + + void deleteClassroomById(long classroomId); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/FindClassroomDetailUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/FindClassroomDetailUsecase.java new file mode 100644 index 00000000..b314251e --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/FindClassroomDetailUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.service.usecase; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; + +public interface FindClassroomDetailUsecase { + + ClassroomDetailDtoResponse getClassroomDetailById(long classroomId); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/FindClassroomListUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/FindClassroomListUsecase.java new file mode 100644 index 00000000..990e555a --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/FindClassroomListUsecase.java @@ -0,0 +1,9 @@ +package com.ohdab.classroom.service.usecase; + +import com.ohdab.classroom.service.dto.ClassroomDto; +import java.util.List; + +public interface FindClassroomListUsecase { + + List findClassroomListByTeacherId(long teacherId); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/UpdateClassroomInfoUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/UpdateClassroomInfoUsecase.java new file mode 100644 index 00000000..51cc942f --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/UpdateClassroomInfoUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.service.usecase; + +import static com.ohdab.classroom.service.dto.ClassroomUpdateDto.ClassroomUpdateDtoRequest; + +public interface UpdateClassroomInfoUsecase { + + void updateClassroomInfo(ClassroomUpdateDtoRequest request); +} diff --git a/src/main/java/com/ohdab/member/repository/MemberRepository.java b/src/main/java/com/ohdab/member/repository/MemberRepository.java index 8dd5b143..ddeee0c3 100644 --- a/src/main/java/com/ohdab/member/repository/MemberRepository.java +++ b/src/main/java/com/ohdab/member/repository/MemberRepository.java @@ -16,7 +16,5 @@ public interface MemberRepository extends JpaRepository { Long countByMemberInfoNameContaining(String name); - boolean existsById(long id); - Optional findActiveMemberById(long memberId); } diff --git a/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java b/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java new file mode 100644 index 00000000..af9660aa --- /dev/null +++ b/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java @@ -0,0 +1,211 @@ +package com.ohdab.classroom.controller; + +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoInfo; +import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; +import static org.mockito.Mockito.when; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ohdab.classroom.controller.request.AddClassroomReq; +import com.ohdab.classroom.controller.request.UpdateClassroomReq; +import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.classroom.service.usecase.*; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.test.web.servlet.MockMvc; + +@AutoConfigureRestDocs +@WebMvcTest(controllers = ClassroomController.class) +class ClassroomControllerTest { + + @Autowired private MockMvc mockMvc; + @Autowired private ObjectMapper objectMapper; + @MockBean private AddClassroomUsecase addClassroomUsecase; + @MockBean private FindClassroomListUsecase findClassroomListUsecase; + @MockBean private FindClassroomDetailUsecase findClassroomDetailUsecase; + @MockBean private UpdateClassroomInfoUsecase updateClassroomInfoUsecase; + @MockBean private DeleteClassroomUsecase deleteClassroomUsecase; + + @Test + @WithMockUser + void 반추가() throws Exception { + // given + final String url = "/classrooms/enrollment"; + final AddClassroomReq addClassroomReq = + AddClassroomReq.builder() + .name("1반") + .description("1반 설명입니다.") + .grade("high1") + .teacherId(1) + .build(); + + // when + + // then + mockMvc.perform( + post(url) + .with(csrf()) + .content(objectMapper.writeValueAsString(addClassroomReq)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("반이 추가되었습니다.")) + .andDo(print()) + .andDo(createDocument("classrooms/enrollment")); + } + + @Test + @WithMockUser + void 선생님_아이디로_반목록_조회() throws Exception { + // given + final String url = "/classrooms"; + + List responseList = new ArrayList<>(); + + responseList.add( + ClassroomDto.Response.builder() + .teacherId(1L) + .id(1) + .info( + ClassroomDto.Info.builder() + .name("1") + .description("111") + .grade("high1") + .build()) + .build()); + responseList.add( + ClassroomDto.Response.builder() + .teacherId(1L) + .id(2) + .info( + ClassroomDto.Info.builder() + .name("2") + .description("222") + .grade("high2") + .build()) + .build()); + + // when + when(findClassroomListUsecase.findClassroomListByTeacherId(1L)).thenReturn(responseList); + // then + mockMvc.perform(get(url).with(csrf()).param("teacherId", "1")) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.classroomInfoList[0].id").value(1), + jsonPath("$.classroomInfoList[0].name").value(1), + jsonPath("$.classroomInfoList[1].id").value(2), + jsonPath("$.classroomInfoList[1].name").value(2), + jsonPath("$.classroomInfoList[1].description").value(222), + jsonPath("$.classroomInfoList[1].grade").value("high2")) + .andDo(print()) + .andDo(createDocument("classrooms?teacherId=")); + } + + @Test + @WithMockUser + void 반_상세조회() throws Exception { + // given + final String url = "/classrooms/"; + + List studentIds = new ArrayList<>(); + studentIds.add(3L); + + List workbookIds = new ArrayList<>(); + workbookIds.add(4L); + + ClassroomDetailDtoResponse classroomDetailDtoResponse = + ClassroomDetailDtoResponse.builder() + .classroomId(1) + .teacherId(2) + .info( + ClassroomDetailDtoInfo.builder() + .name("1반") + .description("1반 설명") + .grade("high1") + .build()) + .studentIds(studentIds) + .workbookIds(workbookIds) + .build(); + + // when + when(findClassroomDetailUsecase.getClassroomDetailById(1L)) + .thenReturn(classroomDetailDtoResponse); + + // then + mockMvc.perform(get(url + "{classroom-id}", 1).with(csrf())) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.id").value(1), + jsonPath("$.teacherId").value(2), + jsonPath("$.name").value("1반"), + jsonPath("$.description").value("1반 설명"), + jsonPath("$.grade").value("high1"), + jsonPath("$.studentIds[0]").value(3), + jsonPath("$.workbookIds[0]").value(4)) + .andDo(print()) + .andDo(createDocument("classrooms/{classroom-id}")); + } + + @Test + @WithMockUser + void 반정보수정() throws Exception { + // given + final String url = "/classrooms/info/"; + UpdateClassroomReq request = + UpdateClassroomReq.builder().name("2반").description("2222").grade("high2").build(); + + // when + + // then + mockMvc.perform( + patch(url + "{classroom-id}", 1) + .with(csrf()) + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("반 정보 수정 성공")) + .andDo(print()) + .andDo(createDocument("classrooms/info/{classroom-id}")); + } + + @Test + @WithMockUser + void 반삭제() throws Exception { + // given + final String url = "/classrooms/expulsion/"; + + // when + + // then + mockMvc.perform(delete(url + "{classroom-id}", 1).with(csrf())) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("반 삭제 성공")) + .andDo(print()) + .andDo(createDocument("classrooms/expulsion/{classroom-id}")); + } + + private RestDocumentationResultHandler createDocument(String identifier) { + return document( + identifier, preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); + } +} diff --git a/src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java new file mode 100644 index 00000000..d1a77378 --- /dev/null +++ b/src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java @@ -0,0 +1,48 @@ +package com.ohdab.classroom.repository; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import java.util.List; +import javax.persistence.EntityManager; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class AddClassroomRepositoryTest { + + @Autowired private ClassroomRepository classroomRepository; + @Autowired private EntityManager em; + + @Test + @DisplayName("반 추가 (저장) 테스트 -> 선생님 아이디를 통해 조회") + void 반_추가_테스트() { + // given + long id = 1L; + TeacherId teacherId = TeacherId.builder().id(id).build(); + String name = "1반"; + String desc = "1반에 대한 설명입니다."; + + ClassroomInfo classroomInfo = + ClassroomInfo.builder().name(name).description(desc).grade(Grade.HIGH_1).build(); + + Classroom classroom = + Classroom.builder().classroomInfo(classroomInfo).teacher(teacherId).build(); + + // when + classroomRepository.save(classroom); + List foundClassrooms = classroomRepository.findAllByTeacherId(teacherId.getId()); + // then + Assertions.assertThat(foundClassrooms.get(0).getTeacher().getId()) + .isEqualTo(teacherId.getId()); + Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getName()).isEqualTo(name); + Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getDescription()) + .isEqualTo(desc); + Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getGrade()) + .isEqualTo(Grade.HIGH_1); + } +} diff --git a/src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java new file mode 100644 index 00000000..fd599264 --- /dev/null +++ b/src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java @@ -0,0 +1,49 @@ +package com.ohdab.classroom.repository; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import java.util.List; +import javax.persistence.EntityManager; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +public class DeleteClassroomRepositoryTest { + + @Autowired private ClassroomRepository classroomRepository; + @Autowired private EntityManager em; + + @Test + @DisplayName("반 삭제 테스트") + void 반삭제() { + // given + long id = 1L; + TeacherId teacherId = TeacherId.builder().id(id).build(); + String name = "1반"; + String desc = "1반에 대한 설명입니다."; + + ClassroomInfo classroomInfo = + ClassroomInfo.builder().name(name).description(desc).grade(Grade.HIGH_1).build(); + + Classroom classroom = + Classroom.builder().classroomInfo(classroomInfo).teacher(teacherId).build(); + classroomRepository.save(classroom); + long classroomId = classroomRepository.findAllByTeacherId(1).get(0).getId(); + em.clear(); + + Classroom foundClassroom = classroomRepository.findClassroomById(classroomId); + // when + classroomRepository.delete(foundClassroom); + em.flush(); + em.clear(); + + List classrooms = classroomRepository.findAllByTeacherId(1); + // then + Assertions.assertThat(classrooms.size()).isEqualTo(0); + } +} diff --git a/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTest.java new file mode 100644 index 00000000..2fde2af7 --- /dev/null +++ b/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTest.java @@ -0,0 +1,62 @@ +package com.ohdab.classroom.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import java.util.List; +import javax.persistence.EntityManager; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class FindAllClassroomByTeacherIdRepositoryTest { + + @Autowired private ClassroomRepository classroomRepository; + @Autowired private EntityManager em; + + @Test + void 선생님_아이디로_반목록_조회() { + // given + Classroom classroom1 = + Classroom.builder() + .teacher(TeacherId.builder().id(1L).build()) + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("1반 설명") + .grade(Grade.HIGH_1) + .build()) + .build(); + classroomRepository.save(classroom1); + + Classroom classroom2 = + Classroom.builder() + .teacher(TeacherId.builder().id(1L).build()) + .classroomInfo( + ClassroomInfo.builder() + .name("2반") + .description("2반 설명") + .grade(Grade.HIGH_1) + .build()) + .build(); + classroomRepository.save(classroom2); + + // when + List foundClassrooms = classroomRepository.findAllByTeacherId(1L); + + // then + assertThat(foundClassrooms.get(0).getTeacher().getId()).isEqualTo(1L); + assertThat(foundClassrooms.get(0).getClassroomInfo().getName()).isEqualTo("1반"); + assertThat(foundClassrooms.get(0).getClassroomInfo().getDescription()).isEqualTo("1반 설명"); + assertThat(foundClassrooms.get(0).getClassroomInfo().getGrade()).isEqualTo(Grade.HIGH_1); + + assertThat(foundClassrooms.get(1).getTeacher().getId()).isEqualTo(1L); + assertThat(foundClassrooms.get(1).getClassroomInfo().getName()).isEqualTo("2반"); + assertThat(foundClassrooms.get(1).getClassroomInfo().getDescription()).isEqualTo("2반 설명"); + assertThat(foundClassrooms.get(1).getClassroomInfo().getGrade()).isEqualTo(Grade.HIGH_1); + } +} diff --git a/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java b/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java new file mode 100644 index 00000000..7d9d6bee --- /dev/null +++ b/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java @@ -0,0 +1,65 @@ +package com.ohdab.classroom.repository; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import java.util.List; +import javax.persistence.EntityManager; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class FindAllClassroomByTeacherIdRepositoryTestReq { + + @Autowired private ClassroomRepository classroomRepository; + @Autowired private EntityManager em; + + @Test + void 선생님_아이디로_반목록_조회() { + // given + Classroom classroom1 = + Classroom.builder() + .teacher(TeacherId.builder().id(1L).build()) + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("1반 설명") + .grade(Grade.HIGH_1) + .build()) + .build(); + classroomRepository.save(classroom1); + + Classroom classroom2 = + Classroom.builder() + .teacher(TeacherId.builder().id(1L).build()) + .classroomInfo( + ClassroomInfo.builder() + .name("2반") + .description("2반 설명") + .grade(Grade.HIGH_1) + .build()) + .build(); + classroomRepository.save(classroom2); + + // when + List foundClassrooms = classroomRepository.findAllByTeacherId(1L); + + // then + Assertions.assertThat(foundClassrooms.get(0).getTeacher().getId()).isEqualTo(1L); + Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getName()).isEqualTo("1반"); + Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getDescription()) + .isEqualTo("1반 설명"); + Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getGrade()) + .isEqualTo(Grade.HIGH_1); + + Assertions.assertThat(foundClassrooms.get(1).getTeacher().getId()).isEqualTo(1L); + Assertions.assertThat(foundClassrooms.get(1).getClassroomInfo().getName()).isEqualTo("2반"); + Assertions.assertThat(foundClassrooms.get(1).getClassroomInfo().getDescription()) + .isEqualTo("2반 설명"); + Assertions.assertThat(foundClassrooms.get(1).getClassroomInfo().getGrade()) + .isEqualTo(Grade.HIGH_1); + } +} diff --git a/src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java new file mode 100644 index 00000000..1e78dbe6 --- /dev/null +++ b/src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java @@ -0,0 +1,52 @@ +package com.ohdab.classroom.repository; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import javax.persistence.EntityManager; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class FindClassroomByIdRepositoryTest { + + @Autowired private ClassroomRepository classroomRepository; + @Autowired private EntityManager em; + + @Test + void 반_상세조회() { + + // given + Classroom classroom1 = + Classroom.builder() + .teacher(TeacherId.builder().id(2L).build()) + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("1반 설명") + .grade(Grade.HIGH_1) + .build()) + .build(); + classroom1.addStudent(StudentId.builder().id(3).build()); + classroom1.addWorkbook(WorkbookId.builder().id(4).build()); + classroomRepository.save(classroom1); + long id = classroom1.getId(); + // when + Classroom foundClassroom = classroomRepository.findClassroomById(id); + + // then + assertThat(foundClassroom.getId()).isEqualTo(id); + assertThat(foundClassroom.getTeacher().getId()).isEqualTo(2); + assertThat(foundClassroom.getClassroomInfo().getName()).isEqualTo("1반"); + assertThat(foundClassroom.getClassroomInfo().getDescription()).isEqualTo("1반 설명"); + assertThat(foundClassroom.getClassroomInfo().getGrade()).isEqualTo(Grade.HIGH_1); + assertThat(foundClassroom.getStudents().get(0).getId()).isEqualTo(3); + assertThat(foundClassroom.getWorkbooks().get(0).getId()).isEqualTo(4); + } +} diff --git a/src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java new file mode 100644 index 00000000..e0c1c78f --- /dev/null +++ b/src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java @@ -0,0 +1,55 @@ +package com.ohdab.classroom.repository; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import javax.persistence.EntityManager; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +public class UpdateClassroomRepositoryTest { + + @Autowired private ClassroomRepository classroomRepository; + @Autowired private EntityManager em; + + @Test + @DisplayName("반 수정 repo 테스트") + void 반_수정_레포_테스트() { + // given + long id = 1L; + TeacherId teacherId = TeacherId.builder().id(id).build(); + String name = "1반"; + String desc = "1반에 대한 설명입니다."; + + ClassroomInfo classroomInfo = + ClassroomInfo.builder().name(name).description(desc).grade(Grade.HIGH_1).build(); + + Classroom classroom = + Classroom.builder().classroomInfo(classroomInfo).teacher(teacherId).build(); + classroomRepository.save(classroom); + em.flush(); + em.clear(); + Classroom saveClassroom = classroomRepository.findAllByTeacherId(1).get(0); + + saveClassroom.setClassroomInfo( + ClassroomInfo.builder().name("2반").description("22").grade(Grade.HIGH_2).build()); + classroomRepository.save(saveClassroom); + em.flush(); + em.clear(); + + // when + Classroom foundClassrooom = classroomRepository.findClassroomById(saveClassroom.getId()); + + // then + Assertions.assertThat(foundClassrooom.getId()).isEqualTo(saveClassroom.getId()); + Assertions.assertThat(foundClassrooom.getClassroomInfo().getName()).isEqualTo("2반"); + Assertions.assertThat(foundClassrooom.getClassroomInfo().getDescription()).isEqualTo("22"); + Assertions.assertThat(foundClassrooom.getClassroomInfo().getGrade()) + .isEqualTo(Grade.HIGH_2); + } +} diff --git a/src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java b/src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java new file mode 100644 index 00000000..51c0db03 --- /dev/null +++ b/src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java @@ -0,0 +1,49 @@ +package com.ohdab.classroom.service; + +import static org.assertj.core.api.Assertions.assertThatNoException; + +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.member.repository.MemberRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {AddClassroomService.class}) +class AddClassroomServiceTest { + + @Autowired private AddClassroomService addClassroomService; + @MockBean private MemberRepository memberRepository; + @MockBean private ClassroomRepository classroomRepository; + + @Test + @DisplayName("반 정보와 선생님 id를 통해 반을 추가 테스트") + void 반추가() throws Exception { + // given + long id = 1L; + String name = "1반"; + String desc = "1반에 대한 설명입니다."; + String grade = "high1"; + ClassroomDto.Request classroomReqDto = + ClassroomDto.Request.builder() + .info( + ClassroomDto.Info.builder() + .name(name) + .description(desc) + .grade(grade) + .build()) + .teacherId(id) + .build(); + // when + Mockito.when(memberRepository.existsById(Mockito.anyLong())).thenReturn(true); + addClassroomService.addClassroom(classroomReqDto); + // then + assertThatNoException().isThrownBy(() -> System.out.println("success")); + } +} diff --git a/src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java b/src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java new file mode 100644 index 00000000..29a53fb7 --- /dev/null +++ b/src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java @@ -0,0 +1,62 @@ +package com.ohdab.classroom.service; + +import static org.assertj.core.api.Assertions.assertThatNoException; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomUpdateDto; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import com.ohdab.member.repository.MemberRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {UpdateClassroomInfoService.class}) +class UpdateClassroomInfoServiceTest { + + @Autowired private UpdateClassroomInfoService updateClassroomInfoService; + @MockBean private MemberRepository memberRepository; + @MockBean private ClassroomRepository classroomRepository; + + @Test + @DisplayName("반 정보 수정 테스트") + void updateClassroomInfo() { + // given + String name = "1반"; + String desc = "1반에 대한 설명입니다."; + Classroom classroom = + Classroom.builder() + .teacher(TeacherId.builder().id(1).build()) + .classroomInfo( + ClassroomInfo.builder() + .name(name) + .description(desc) + .grade(Grade.HIGH_1) + .build()) + .build(); + + ClassroomUpdateDto.ClassroomUpdateDtoRequest request = + ClassroomUpdateDto.ClassroomUpdateDtoRequest.builder() + .classroomId(1L) + .name("2반") + .description("22") + .grade("high2") + .build(); + + // when + Mockito.when(memberRepository.existsById(Mockito.anyLong())).thenReturn(true); + Mockito.when(classroomRepository.findClassroomById(Mockito.anyLong())) + .thenReturn(classroom); + updateClassroomInfoService.updateClassroomInfo(request); + // then + assertThatNoException().isThrownBy(() -> System.out.println("success")); + } +} From 360687c282ef58b0c6d359a397cbc1a7768e1e79 Mon Sep 17 00:00:00 2001 From: Jonghan Sim Date: Tue, 15 Aug 2023 21:07:56 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20classroom=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20API=20=EA=B0=9C=EB=B0=9C=20(#144)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim * feat: 학생 삭제 controller 단위 테스트 & 구현 (#104) * test: controller 단위 테스트 * feat: contoller 구현 * docs: REST Docs 작성 * fix: url 수정 * feat: 학생 삭제 service 단위 테스트 & 구현 (#105) * test: controller 단위 테스트 * feat: contoller 구현 * docs: REST Docs 작성 * fix: url 수정 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * style: spotless 적용 * feat : 교재 목록 조회 service 테스트 및 구현 * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * feat : 교재 목록 조회 service 테스트 작성 * feat : 교재 목록 조회 service 구현 * refactor : domain to dto 메서드로 분리 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 교재 목록 조회 repository 테스트 및 구현 * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * feat : 교재 목록 조회 service 테스트 작성 * feat : 교재 목록 조회 service 구현 * feat : 반 식별자로 반에 있는 교재 목록 조회하는 workbook repository 테스트 작성 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 교재 목록 조회 Controller 테스트 및 구현 (#111) * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * feat : 교재 목록 조회 service 테스트 작성 * feat : 교재 목록 조회 service 구현 * feat : 반 식별자로 반에 있는 교재 목록 조회하는 workbook repository 테스트 작성 * feat : 교재 목록 조회 Controller 구현 * feat : 교재 목록 조회 Controller 테스트 작성 * fix : docs url 오류 수정 * fix --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * refactor: 예외 클래스명 통일 및 코드 수정 (#113) * fix: 예외 클래스명 통일 * fix: 테스트명 수정 * refactor: 테스트 접근 제어자 수정 및 테스트 코드 간소화 * fix: helper service final 클래스로 변경 및 스태틱 메서드로 변경 * fix: exception 생성자 통일 * feat : 교재 추가 Service 테스트 및 구현 (#115) * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * feat : 교재 추가 Service 테스트 작성 * fix : 교재 추가 service 테스트 수정 * feat : 교재 추가 service 구현 * feat : 교재 추가 시 오답노트 생성 로직 추가 * fix : 교재 추가 로직 및 예외 처리 수정 * fix : MistakeNote builder 하나로 통일 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 교재 추가 Repository 테스트 및 구현 (#117) * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * feat : 교재 추가 Service 테스트 작성 * fix : 교재 추가 service 테스트 수정 * feat : 교재 추가 service 구현 * feat : 교재 추가 시 오답노트 생성 로직 추가 * feat : 교재 저장 성공 repository 테스트 작성 * feat : 반 식별자와 교재 이름으로 교재 존재 여부 확인 성공 repository 테스트 작성 * fix : 교재 추가 로직 및 예외 처리 수정 * feat : 오답 노트 생성 성공 repository 테스트 작성 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * fix: mistakenote 생성자 수정 (#122) * feat : 교재 추가 controller 테스트 작성 및 구현 (#120) * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * feat : 교재 추가 controller 구현 * feat : 교재 추가 controller 테스트 작성 * fix : docs url 오류 수정 * fix : saveMistakeNote 수정 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat: 학생 추가(회원 가입 요청, 오답노트 생성) controller 단위 테스트 & 구현 (#126) * test: controller 단위 테스트 * feat: controller 구현 * docs: rest docs 추가 * feat : 교재 정보 수정 Service 테스트 및 구현 (#127) * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * merge : conflict 해결 * feat : 교재 정보 수정 service 테스트 작성 * feat : 교재 정보 수정 service 구현 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * [Feat/#128] 교재 정보 수정 성공 repository 테스트 및 구현 (#129) * feat: classroom 도메인 api 개발 (#99) * feat: 반 추가 service & test (#25) * feat : addClassroom Service & test * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat: 반 추가 Repository 테스트 & 구현 (#27) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * refactor : 인터페이스 이름 변경 * Update src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim * feat : 반 추가 Controller 테스트 & 구현 (#41) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * refactor : 인터페이스 이름 변경 * fix : addClassroom 인터페이스 이름 변경 --------- Co-authored-by: seongha * feat : 반 목록 조회 Service & Dto 결합 (inner class) (#47) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 repository 구현 & 테스트 (#50) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * fix : Controller dto, request, response 객체 수정 --------- Co-authored-by: seongha * feat : 반 목록 조회 controller 구현 & 테스트 (#51) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import --------- Co-authored-by: seongha * feat/#55 반 상세조회 Service 작성 (#69) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#56 반 상세조회 Repository Test 작성 (#70) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 --------- Co-authored-by: seongha * Feat/#57 반 상세조회 Controller 구현 & Test 작성 (#72) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 --------- Co-authored-by: seongha * Feat/#82 반 수정 Service 구현 & test (#85) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 --------- Co-authored-by: seongha * Feat/#83 반 수정 repostory 구현 & test (#86) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 --------- Co-authored-by: seongha * Feat/#84 반 수정 controller 작성 & test 작성 (#87) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 --------- Co-authored-by: seongha * Feat/#89 반 삭제 Service 작성 (#92) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 --------- Co-authored-by: seongha * Feat/#90 반 삭제 Repository 구현 & test (#93) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 --------- Co-authored-by: seongha * Feat/#91 반 삭제 Controller 구현 & Test 작성 (#94) * feat : addClassroom Service & test * style : spotless 적용 * feat : repository 구현 & 테스트 작성 * feat : repository 구현 & 테스트 작성 * feat : 반 추가 controller 작성 & 테스트 * style : spotless 적용 * fix : 코드리뷰 변경사항 수정 * style : spotless 적용 * docs : 반 추가 api 문서 추가 * feat : findClassroomService 구현 및 ClassroomDto 리팩토링 * refactor : 인터페이스 이름 변경 * style : spotyless 적용 * fix : addClassroom 인터페이스 이름 변경 * style : spotless 적용 * test : 반 목록 조회 테스트 작성 * feat : 반 목록 조회 controller 구현 & test 작성 * fix : Controller dto, request, response 객체 수정 * feat : 반 상세조회 Service 구현 * fix : controller dto 변경, getClassroomListByTeacherId 인자를 query String 으로 변경 * style : spotless 적용 * style : optimize import * style : optimize import * style : spotless 적용 * test : 반 상세조회 repository test 작성 * feat : 반 상세조회 controller 작성 * fix : test 버그 수정 -> 전체 테스트시 Id 값이 변경되어 테스트 실패하는 것 수정 * style : spotless 적용 * feat : 반 수정 Service 작성 * test : 반 수정 repository 테스트 작성 * test : 테스트 수정 * test : 테스트 실패 수정 * feat : 반 수정 controller 구현 & test 작성 * docs : 문서 작성 * docs : 반 상세조회 추가로 인한 docs 패키지 변경 적용 * feat: 반 삭제 Service 작성 * test : 반 삭제 테스트 작성 * feat : 반 삭제 Controller 작성 --------- Co-authored-by: seongha * merge : conflict resolve (#100) * merge : conflict resolve * style : spotlessApply * [Fix] Resolve Conflict (#101) * feat: member 도메인 api 개발 (#96) * [Feat/#33] 선생님 목록 조회 서비스 테스트 및 구현 (#38) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * fix : dto mapper 수정 * fix : stream 사용 * [Feat/#39] 선생님 추가 service 테스트 작성 및 구현 (#42) * feat : 선생님 목록 조회 성공 서비스 테스트 작성 * feat : 선생님 목록 조회 서비스 구현 * spotless 적용 * feat : 선생님 추가 서비스 테스트 작성 * fix : service와 repository의 domain 반환 형태를 Dto 반환하도록 변경 * fix : repository 반환 형태 복구 * feat : 선생님 추가 서비스 구현 * fix : spotless 적용 * fix : Repository JPA method 수정 * fix : dto mapper 수정 * fix : 이름 중복 제거 메서드명 변경 * fix : 서비스 테스트 분리 및 ReqDto 명칭 변경 * fix : stream 사용 * fix : spotless 적용 * fix : 임시 join service 요청 추가 * [Feat/#43] 선생님 삭제 service 테스트 작성 및 구현 (#53) * fix : dto inner 클래스로 수정 * feat : 선생님 삭제 서비스 테스트 작성 * feat : 선생님 삭제 서비스 구현 * fix : 예외 추가 및 도메인 규칙 사용하도록 로직 수정 * fix : 선생님 삭제 서비스 테스트 수정 및 예외 삭제 * [Feat/#54] 선생님 목록 조회 repository 테스트 및 구현 (#59) * feat : 선생님 목록 조회 repository 테스트 * refactor : repository test assertion refactoring * [Feat/#60] 선생님 추가 repository 테스트 및 구현 (#63) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * [Feat/#74] 선생님 목록 조회 Controller 테스트 및 구현 (#75) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * [Feat/#76] 선생님 추가 Controller 테스트 및 구현 (#77) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#78] 선생님 삭제 controller 테스트 및 구현 (#79) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat : 선생님 목록 조회 controller 테스트 및 구현 * feat : 선생님 추가 Controller 테스트 및 구현 * feat : 선생님 삭제 Controller 테스트 및 구현 * fix : spotless 적용 * [Feat/#64] 선생님 삭제(탈퇴) repository 테스트 및 구현 (#68) * feat : 선생님 목록 조회 repository 테스트 * feat : 선생님 추가 repository 테스트 및 구현 * merge : feature-member * feat : 선생님 삭제(탈퇴) repository 테스트 및 구현 * feat: mistakenote 도메인 api 개발 (#98) * feat: 학생별 오답노트 조회 controller 단위 테스트 & 구현 (#22) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * feat: 학생별 오답노트 조회 service 단위 테스트 & 구현 (#23) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * fix: workbookRepository 주입 제거 * feat: 학생별 오답노트 조회 repository 단위 테스트 (#24) * test: 학생별 오답노트 조회 controller 단위 테스트 * feat: 학생별 오답노트 조회 controller 구현 * fix: 테스트 클래스 패키지 이동 * style: spotless 적용 * fix: DI 오류 수정 * docs: rest docs 작성 * test: service 단위 테스트 * test: service 단위 테스트 * style: 라인 공백 * feat: 학생별 오답노트 조회 service 구현 * test: 삭제 회원 검사로직 추가 * test: 회원 삭제 여부 로직을 위한 테스트 추가 * feat: 회원 삭제 여부 메서드 추가 * test: 오답노트 조회 repository 단위 테스트 * fix: workbookRepository 주입 제거 * feat: 오답 기록하기 controller 테스트 & 구현 (#31) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * feat: 오답 기록하기 service 단위 테스트 & 구현 (#32) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * feat: 오답 기록하기 repository 단위 테스트 & 구현 (#34) * test: controller 단위 테스트 * fix: usecase 매개변수 수정 * feat: controller 구현 * feat: serivce 구현체 추가 * docs: rest docs 작성 * fix: req 클래스 validation 추가 * test: service 테스트 클래스 생성 * test: 오답 기록하기 메서드 단위테스트 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: 틀린 문제 번호 배열 -> 리스트로 변경 * fix: service 단위 테스트 결과값 검증으로 변경 * refactor: 오답 기록 메서드 리팩토링 * feat: service 구현 * style: spotless 적용 * feat: 문제 번호의 범위 검사를 위한 도메인 서비스 추가 * test: repository 단위 테스트 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) controller 단위 테스트 & 구현 (#44) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) service 단위 테스트 & 구현 (#58) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * fix: 과거 dto 클래스 삭제 * feat: 교재 상세조회(전체 학생에 대한 오답노트 조회) mapper 단위 테스트 (#62) * test: controller 단위 테스트 * feat: controller 구현 * style: 람다식 중괄호 제거 * refactor: 맵핑 메서드 분리 * style: 메서드 순서 변경 * docs: REST Doc 작성 * f * fix: dto inner 클래스로 수정 * fix: dto 클래명 수정 * test: service 단위 테스트 * feat: servie 일부 구현 * feat: mybatis 설정 및 mapper 구현 * test: service 단위 테스트 * feat: service 구현 * fix: 버전 이슈로 인한 mybatis 다운 그레이드 * test: mybatis test 의존성 주입 * fix: mapper 파일 경로 수정 * fix: mybatis 설정 수정 * fix: mapper 클래스 경로 수정 * fix: 쿼리 별칭을 쌍따옴로 지정하도록 변경 * test: MistakeNoteMapper 단위 테스트 * MemberMapper 단위 테스트 * fix: 과거 dto 클래스 삭제 * fix: member setter 추가 * feat: 학생별 N번 이상 틀린 문제 출력 controller 단위 테스트 & 구현 (#71) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * feat: 학생별 N번 이상 틀린 문제 출력 service 단위 테스트 & 구현 (#73) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * feat: 학생별 N번 이상 틀린 문제 출력 repository 단위 테스트 & 구현 (#81) * test: controller 단위 테스트 & REST Docs 작성 * feat: controller 구현 * fix: usecase 분리 * style: spotless 적용 * test: service 단위 테스트 * feat: service 구현 * style: spotless 적용 * fix: workbookId path variable 추가 * style: spotless 적용 * fix: 문제 범위에 대한 test 추가 * feat: service 구현 * fix: 메서드 및 변수명에서 numbers를 number로 변경 * style: spotless 적용 * fix: 메서드 및 변수명에서 numbers -> number로 변경 * refactor: 범위 검사 로직 리팩토링 * fix: test 메서드 및 클래스명 영어로 변경 * fix: 범위 검사 메서드 하나로 통일 * test: repository 단위 테스트 * feat: mapper 쿼리 작성 * style: spotless 적용 * merge: develop 브랜치 병합 * feat: repository 누락 메서드 추가 * Delete src/test/java/com/ohdab/member/Controller directory * merge : conflict resolve * style : spotlessApply --------- Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: Jonghan Sim --------- Co-authored-by: seongha Co-authored-by: Jonghan Sim Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> * merge : conflict 해결 * feat : 교재 정보 수정 service 테스트 작성 * feat : 교재 정보 수정 service 구현 * feat : 교재 정보 수정 repository test 작성 * fix : repository test 수정 * fix : repository test 수정 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: Jonghan Sim * merge : conflict 해결 * feat : 교재 정보 수정 Controller 테스트 및 구현 (#131) * merge : conflict 해결 * feat : 교재 정보 수정 service 테스트 작성 * feat : 교재 정보 수정 service 구현 * feat : 교재 정보 수정 repository test 작성 * feat : 교재 정보 수정 controller 구현 * feat : 교재 정보 수정 controller 테스트 작성 * feat: 학생 추가(회원 가입 요청, 오답노트 생성) service 단위 테스트 & 구현 (#132) * test: controller 단위 테스트 * feat: controller 구현 * feat: servie 구현 및 테스트, 이벤트 추가 * test: studentAddedHandler 단위 테스트 * fix: 테스트 패키지 경로 복구 * feat: transactional 추가 * docs: rest docs 추가 * test: MockBean 추가 * feat: 학생 추가시 오답노트 생성 로직 추가 * feat: 예외 enum 클래스 추가 (#135) * feat: exception enum 클래스 추가 * feat: controller advice 추가 * feat: member domain 권한 초기화 * fix : 교재 추가 서비스 수정 (#136) * feat : 교재 추가 시 오답노트 생성 수정 * fix : spotless * fix: 예외 메시지 적용 (#139) * fix: 예외 메시지 enum으로 변경 * fix: 에러 메시지 수정 * style: spotless 적용 --------- Co-authored-by: seongha_h <11pi885@gmail.com> Co-authored-by: seongha Co-authored-by: linirini <101927543+linirini@users.noreply.github.com> Co-authored-by: linirini <2001yerin@naver.com> --- src/docs/asciidoc/ohdab.adoc | 58 ++++- .../controller/ClassroomController.java | 60 +++++ .../controller/mapper/ClassroomMapper.java | 51 ++++ .../controller/request/AddStudentReq.java | 14 ++ .../controller/request/AddWorkbookReq.java | 27 ++ .../request/UpdateWorkbookInfoReq.java | 21 ++ .../controller/response/AddStudentRes.java | 11 + .../controller/response/AddWorkbookRes.java | 10 + .../response/ClassroomWorkbookListRes.java | 23 ++ .../response/UpdateWorkbookInfoRes.java | 10 + .../com/ohdab/classroom/domain/Classroom.java | 38 ++- .../classroom/event/StudentAddedEvent.java | 20 ++ .../CannotFindClassroomException.java | 8 - .../exception/CannotFindGradeException.java | 8 - .../exception/CannotFindTeacherException.java | 8 - .../exception/NoClassroomException.java | 18 ++ .../classroom/exception/NoGradeException.java | 18 ++ .../exception/NoStudentException.java | 18 ++ .../exception/NoTeacherException.java | 18 ++ .../repository/ClassroomRepository.java | 3 +- .../service/AddClassroomService.java | 14 +- .../classroom/service/AddStudentService.java | 74 ++++++ .../classroom/service/AddWorkbookService.java | 74 ++++++ .../service/ClassroomDetailService.java | 10 +- .../service/DeleteClassroomService.java | 6 +- .../service/DeleteStudentService.java | 30 +++ .../service/FindClassroomDetailService.java | 10 +- .../service/GetWorkbookListService.java | 51 ++++ .../service/UpdateClassroomInfoService.java | 11 +- .../service/UpdateWorkbookInfoService.java | 46 ++++ .../classroom/service/dto/AddStudentDto.java | 18 ++ .../service/dto/ClassroomAddWorkbookDto.java | 19 ++ .../service/dto/ClassroomWorkbookDto.java | 19 ++ .../dto/ClassroomWorkbookUpdateDto.java | 18 ++ .../service/dto/DeleteStudentDto.java | 15 ++ .../helper/ClassroomHelperService.java | 42 ++++ .../helper/ClassroomServiceHelper.java | 26 -- .../service/usecase/AddStudentUsecase.java | 8 + .../service/usecase/AddWorkbookUsecase.java | 8 + .../service/usecase/DeleteStudentUsecase.java | 6 + .../usecase/GetWorkbookListUsecase.java | 9 + .../usecase/UpdateWorkbookInfoUsecase.java | 8 + .../ohdab/core/exception/ExceptionEnum.java | 44 ++++ .../handler/ClassroomExceptionHandler.java | 55 +++++ .../handler/CommonExceptionHandler.java | 21 ++ .../handler/MemberExceptionHandler.java | 62 +++++ .../handler/MistakeNoteExceptionHandler.java | 56 +++++ .../handler/WorkbookExceptionHandler.java | 58 +++++ .../event/handler/StudentAddedHandler.java | 26 ++ .../member/controller/MemberController.java | 12 +- .../controller/response/DeleteStudentRes.java | 11 + .../java/com/ohdab/member/domain/Member.java | 20 +- .../exception/AlreadyWithdrawlException.java | 18 ++ .../MemberContentOverflowException.java | 18 ++ .../exception/NoAuthorityException.java | 18 ++ .../member/service/AddTeacherService.java | 11 +- .../member/service/DeleteTeacherService.java | 6 +- .../com/ohdab/member/service/JoinService.java | 3 +- .../ohdab/member/service/LoginService.java | 8 +- .../member/service/UserDetailServiceImpl.java | 6 +- .../service/dto/MemberDtoForAddTeacher.java | 5 +- .../dto/MemberDtoForGetTeacherList.java | 5 +- .../member/service/dto/MemberDtoForJoin.java | 5 +- .../member/service/dto/MemberDtoForLogin.java | 5 +- .../service/helper/MemberHelperService.java | 18 +- .../ohdab/mistakenote/domain/MistakeNote.java | 18 +- .../MistakeNumbersSizeException.java | 18 ++ .../service/GetMistakeNoteInfoService.java | 14 +- .../service/GetNumberWrongNTimesService.java | 12 +- .../service/SaveMistakeNoteInfoService.java | 20 +- .../helper/MistakeNoteHelperService.java | 11 +- .../com/ohdab/workbook/domain/Workbook.java | 12 +- .../domain/workbookInfo/WorkbookInfo.java | 19 +- .../DuplicatedWorkbookException.java | 18 ++ .../InvalidWorkbookNumberRangeException.java | 18 ++ .../WorkbookContentOverflowException.java | 18 ++ .../repository/WorkbookRepository.java | 9 +- .../controller/ClassroomControllerTest.java | 159 +++++++++++- .../AddClassroomRepositoryTest.java | 15 +- .../DeleteClassroomRepositoryTest.java | 16 +- ...ClassroomByTeacherIdRepositoryTestReq.java | 25 +- .../FindClassroomByIdRepositoryTest.java | 13 +- .../UpdateClassroomRepositoryTest.java | 25 +- .../service/AddClassroomServiceTest.java | 11 +- .../service/AddStudentServiceTest.java | 100 ++++++++ .../service/AddWorkbookServiceTest.java | 88 +++++++ .../service/DeleteStudentServiceTest.java | 233 ++++++++++++++++++ .../service/GetWorkbookListServiceTest.java | 73 ++++++ .../UpdateClassroomInfoServiceTest.java | 14 +- .../UpdateWorkbookInfoServiceTest.java | 64 +++++ .../handler/StudentAddedHandlerTest.java | 37 +++ .../repository/MemberRepositoryTest.java | 2 +- .../member/service/AddTeacherServiceTest.java | 5 +- .../service/DeleteTeacherServiceTest.java | 2 +- .../service/GetTeacherListServiceTest.java | 2 +- .../repository/MistakeNoteRepositoryTest.java | 34 ++- .../mapper/MistakeRecordMapperTest.java | 4 +- .../GetMistakeNoteInfoServiceTest.java | 45 ++-- .../GetNumberWrongNTimesServiceTest.java | 4 +- .../SaveMistakeNoteInfoServiceTest.java | 19 +- .../repository/WorkbookRepositoryTest.java | 176 +++++++++++++ 101 files changed, 2522 insertions(+), 286 deletions(-) create mode 100644 src/main/java/com/ohdab/classroom/controller/request/AddStudentReq.java create mode 100644 src/main/java/com/ohdab/classroom/controller/request/AddWorkbookReq.java create mode 100644 src/main/java/com/ohdab/classroom/controller/request/UpdateWorkbookInfoReq.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/AddStudentRes.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/AddWorkbookRes.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/ClassroomWorkbookListRes.java create mode 100644 src/main/java/com/ohdab/classroom/controller/response/UpdateWorkbookInfoRes.java create mode 100644 src/main/java/com/ohdab/classroom/event/StudentAddedEvent.java delete mode 100644 src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java delete mode 100644 src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java delete mode 100644 src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java create mode 100644 src/main/java/com/ohdab/classroom/exception/NoClassroomException.java create mode 100644 src/main/java/com/ohdab/classroom/exception/NoGradeException.java create mode 100644 src/main/java/com/ohdab/classroom/exception/NoStudentException.java create mode 100644 src/main/java/com/ohdab/classroom/exception/NoTeacherException.java create mode 100644 src/main/java/com/ohdab/classroom/service/AddStudentService.java create mode 100644 src/main/java/com/ohdab/classroom/service/AddWorkbookService.java create mode 100644 src/main/java/com/ohdab/classroom/service/DeleteStudentService.java create mode 100644 src/main/java/com/ohdab/classroom/service/GetWorkbookListService.java create mode 100644 src/main/java/com/ohdab/classroom/service/UpdateWorkbookInfoService.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/AddStudentDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/ClassroomAddWorkbookDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookUpdateDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/dto/DeleteStudentDto.java create mode 100644 src/main/java/com/ohdab/classroom/service/helper/ClassroomHelperService.java delete mode 100644 src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/AddStudentUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/AddWorkbookUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/DeleteStudentUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/GetWorkbookListUsecase.java create mode 100644 src/main/java/com/ohdab/classroom/service/usecase/UpdateWorkbookInfoUsecase.java create mode 100644 src/main/java/com/ohdab/core/exception/ExceptionEnum.java create mode 100644 src/main/java/com/ohdab/core/exception/handler/ClassroomExceptionHandler.java create mode 100644 src/main/java/com/ohdab/core/exception/handler/CommonExceptionHandler.java create mode 100644 src/main/java/com/ohdab/core/exception/handler/MemberExceptionHandler.java create mode 100644 src/main/java/com/ohdab/core/exception/handler/MistakeNoteExceptionHandler.java create mode 100644 src/main/java/com/ohdab/core/exception/handler/WorkbookExceptionHandler.java create mode 100644 src/main/java/com/ohdab/core/util/event/handler/StudentAddedHandler.java create mode 100644 src/main/java/com/ohdab/member/controller/response/DeleteStudentRes.java create mode 100644 src/main/java/com/ohdab/member/exception/AlreadyWithdrawlException.java create mode 100644 src/main/java/com/ohdab/member/exception/MemberContentOverflowException.java create mode 100644 src/main/java/com/ohdab/member/exception/NoAuthorityException.java create mode 100644 src/main/java/com/ohdab/mistakenote/exception/MistakeNumbersSizeException.java create mode 100644 src/main/java/com/ohdab/workbook/exception/DuplicatedWorkbookException.java create mode 100644 src/main/java/com/ohdab/workbook/exception/InvalidWorkbookNumberRangeException.java create mode 100644 src/main/java/com/ohdab/workbook/exception/WorkbookContentOverflowException.java create mode 100644 src/test/java/com/ohdab/classroom/service/AddStudentServiceTest.java create mode 100644 src/test/java/com/ohdab/classroom/service/AddWorkbookServiceTest.java create mode 100644 src/test/java/com/ohdab/classroom/service/DeleteStudentServiceTest.java create mode 100644 src/test/java/com/ohdab/classroom/service/GetWorkbookListServiceTest.java create mode 100644 src/test/java/com/ohdab/classroom/service/UpdateWorkbookInfoServiceTest.java create mode 100644 src/test/java/com/ohdab/core/util/event/handler/StudentAddedHandlerTest.java create mode 100644 src/test/java/com/ohdab/workbook/repository/WorkbookRepositoryTest.java diff --git a/src/docs/asciidoc/ohdab.adoc b/src/docs/asciidoc/ohdab.adoc index 863b0ce9..6966c2b1 100644 --- a/src/docs/asciidoc/ohdab.adoc +++ b/src/docs/asciidoc/ohdab.adoc @@ -115,11 +115,11 @@ include::{snippets}/classrooms/enrollment/http-response.adoc[] ==== Request -include::{snippets}/classrooms?teacherId=/http-request.adoc[] +include::{snippets}/classrooms/http-request.adoc[] ==== Response -include::{snippets}/classrooms?teacherId=/http-response.adoc[] +include::{snippets}/classrooms/http-response.adoc[] === 반 상세 조회 @@ -150,3 +150,57 @@ include::{snippets}/classrooms/expulsion/{classroom-id}/http-request.adoc[] ==== Response include::{snippets}/classrooms/expulsion/{classroom-id}/http-response.adoc[] + +=== 학생 추가 + +==== Request + +include::{snippets}/classrooms/addStudent/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/addStudent/http-response.adoc[] + +=== 학생 삭제 + +==== Request + +include::{snippets}/classrooms/deleteStudent/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/deleteStudent/http-response.adoc[] + +=== 교재 목록 조회 + +==== Request + +include::{snippets}/classrooms/{classroom-id}/workbooks/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/{classroom-id}/workbooks/http-response.adoc[] + +======= + +=== 교재 추가 + +==== Request + +include::{snippets}/classrooms/{classroom-id}/addWorkbooks/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/{classroom-id}/addWorkbooks/http-response.adoc[] + +=== 교재 정보 수정 + +==== Request + +include::{snippets}/classrooms/workbooks/info/{workbook-id}/http-request.adoc[] + +==== Response + +include::{snippets}/classrooms/workbooks/info/{workbook-id}/http-response.adoc[] + + diff --git a/src/main/java/com/ohdab/classroom/controller/ClassroomController.java b/src/main/java/com/ohdab/classroom/controller/ClassroomController.java index 83fa7667..926e278c 100644 --- a/src/main/java/com/ohdab/classroom/controller/ClassroomController.java +++ b/src/main/java/com/ohdab/classroom/controller/ClassroomController.java @@ -5,10 +5,17 @@ import com.ohdab.classroom.controller.mapper.ClassroomMapper; import com.ohdab.classroom.controller.request.AddClassroomReq; +import com.ohdab.classroom.controller.request.AddStudentReq; +import com.ohdab.classroom.controller.request.AddWorkbookReq; import com.ohdab.classroom.controller.request.UpdateClassroomReq; +import com.ohdab.classroom.controller.request.UpdateWorkbookInfoReq; import com.ohdab.classroom.controller.response.*; +import com.ohdab.classroom.service.dto.ClassroomAddWorkbookDto; import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.classroom.service.dto.ClassroomWorkbookDto; +import com.ohdab.classroom.service.dto.ClassroomWorkbookUpdateDto; import com.ohdab.classroom.service.usecase.*; +import com.ohdab.member.controller.response.DeleteStudentRes; import java.util.List; import javax.validation.Valid; import lombok.RequiredArgsConstructor; @@ -25,6 +32,11 @@ public class ClassroomController { private final FindClassroomDetailUsecase findClassroomDetailUsecase; private final UpdateClassroomInfoUsecase updateClassroomInfoUsecase; private final DeleteClassroomUsecase deleteClassroomUsecase; + private final DeleteStudentUsecase deleteStudentUsecase; + private final GetWorkbookListUsecase getWorkbookListUsecase; + private final AddWorkbookUsecase addWorkbookUsecase; + private final UpdateWorkbookInfoUsecase updateWorkbookInfoUsecase; + private final AddStudentUsecase addStudentUsecase; @PostMapping("/enrollment") public ResponseEntity addClassroom( @@ -70,4 +82,52 @@ public ResponseEntity deleteClassroom( deleteClassroomUsecase.deleteClassroomById(classroomId); return ResponseEntity.ok(DeleteClassroomRes.builder().message("반 삭제 성공").build()); } + + @PatchMapping("/{classroom-id}/expulsion/students/{student-id}") + public ResponseEntity deleteStudent( + @PathVariable("classroom-id") long classroomId, + @PathVariable("student-id") long studentId) { + deleteStudentUsecase.deleteStudent(classroomId, studentId); + return ResponseEntity.ok(DeleteStudentRes.builder().message("학생을 삭제하였습니다.").build()); + } + + @GetMapping("/{classroom-id}/workbooks") + public ResponseEntity getWorkbookListByClassroomId( + @PathVariable(name = "classroom-id") long classroomId) { + List classroomWorkbookDtoList = + getWorkbookListUsecase.getWorkbookListByClassroomId(classroomId); + return ResponseEntity.ok( + ClassroomMapper.classroomWorkbookDtoListToResponseList(classroomWorkbookDtoList)); + } + + @PostMapping("/{classroom-id}/workbooks") + public ResponseEntity getWorkbookListByClassroomId( + @PathVariable(name = "classroom-id") long classroomId, + @RequestBody @Valid AddWorkbookReq addWorkbookReq) { + ClassroomAddWorkbookDto.Request addWorkbookDto = + ClassroomMapper.addWorkbookRequestToDto(addWorkbookReq); + addWorkbookUsecase.addWorkbookByClassroomId(classroomId, addWorkbookDto); + return ResponseEntity.ok( + AddWorkbookRes.builder().message("해당 반에 교재 및 오답노트가 추가되었습니다.").build()); + } + + @PatchMapping("/workbooks/info/{workbook-id}") + public ResponseEntity updateWorkInfobook( + @PathVariable(name = "workbook-id") long workbookId, + UpdateWorkbookInfoReq updateWorkbookInfoReq) { + ClassroomWorkbookUpdateDto.Request workbookUpdateDtoReq = + ClassroomMapper.updateWorkbookRequestToDto(workbookId, updateWorkbookInfoReq); + updateWorkbookInfoUsecase.updateWorkbookInfo(workbookUpdateDtoReq); + return ResponseEntity.ok( + UpdateWorkbookInfoRes.builder().message("교재 정보가 수정 되었습니다.").build()); + } + + @PostMapping("/{classroom-id}/students/enrollment") + public ResponseEntity addStudent( + @PathVariable(name = "classroom-id") long classroomId, + @RequestBody @Valid AddStudentReq addStudentReq) { + addStudentUsecase.addStudent( + ClassroomMapper.toAddStudentDtoRequest(classroomId, addStudentReq)); + return ResponseEntity.ok(AddStudentRes.builder().message("해당 반에 학생이 추가되었습니다.").build()); + } } diff --git a/src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java b/src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java index fe0e2dc4..e954e25d 100644 --- a/src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java +++ b/src/main/java/com/ohdab/classroom/controller/mapper/ClassroomMapper.java @@ -4,11 +4,20 @@ import static com.ohdab.classroom.service.dto.ClassroomUpdateDto.ClassroomUpdateDtoRequest; import com.ohdab.classroom.controller.request.AddClassroomReq; +import com.ohdab.classroom.controller.request.AddStudentReq; +import com.ohdab.classroom.controller.request.AddWorkbookReq; import com.ohdab.classroom.controller.request.UpdateClassroomReq; +import com.ohdab.classroom.controller.request.UpdateWorkbookInfoReq; import com.ohdab.classroom.controller.response.AddClassroomRes; import com.ohdab.classroom.controller.response.ClassroomDetailRes; import com.ohdab.classroom.controller.response.ClassroomResList; +import com.ohdab.classroom.controller.response.ClassroomWorkbookListRes; +import com.ohdab.classroom.service.dto.AddStudentDto; +import com.ohdab.classroom.service.dto.ClassroomAddWorkbookDto; +import com.ohdab.classroom.service.dto.ClassroomAddWorkbookDto.Request; import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.classroom.service.dto.ClassroomWorkbookDto.Response; +import com.ohdab.classroom.service.dto.ClassroomWorkbookUpdateDto; import java.util.List; import java.util.stream.Collectors; import lombok.AccessLevel; @@ -76,4 +85,46 @@ public static ClassroomUpdateDtoRequest classroomUpdateDtoReqToClassroomUpdateDt .grade(request.getGrade()) .build(); } + + public static ClassroomWorkbookListRes classroomWorkbookDtoListToResponseList( + List classroomWorkbookDtoList) { + return ClassroomWorkbookListRes.builder() + .workbookList( + classroomWorkbookDtoList.stream() + .map( + w -> + ClassroomWorkbookListRes.WorkbookInfo.builder() + .id(w.getId()) + .name(w.getName()) + .createdAt(w.getCreatedAt().toLocalDate()) + .build()) + .collect(Collectors.toList())) + .build(); + } + + public static Request addWorkbookRequestToDto(AddWorkbookReq addWorkbookReq) { + return ClassroomAddWorkbookDto.Request.builder() + .name(addWorkbookReq.getName()) + .description(addWorkbookReq.getDescription()) + .startingNumber(addWorkbookReq.getStartingNumber()) + .endingNumber(addWorkbookReq.getEndingNumber()) + .build(); + } + + public static ClassroomWorkbookUpdateDto.Request updateWorkbookRequestToDto( + long workbookId, UpdateWorkbookInfoReq updateWorkbookInfoReq) { + return ClassroomWorkbookUpdateDto.Request.builder() + .id(workbookId) + .name(updateWorkbookInfoReq.getName()) + .description(updateWorkbookInfoReq.getDescription()) + .build(); + } + + public static AddStudentDto.Request toAddStudentDtoRequest( + long classroomId, AddStudentReq addStudentReq) { + return AddStudentDto.Request.builder() + .classroomId(classroomId) + .studentName(addStudentReq.getStudentName()) + .build(); + } } diff --git a/src/main/java/com/ohdab/classroom/controller/request/AddStudentReq.java b/src/main/java/com/ohdab/classroom/controller/request/AddStudentReq.java new file mode 100644 index 00000000..005c3be9 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/request/AddStudentReq.java @@ -0,0 +1,14 @@ +package com.ohdab.classroom.controller.request; + +import javax.validation.constraints.NotNull; +import lombok.*; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AddStudentReq { + + @NotNull(message = "학생 이름은 필수 입력 값입니다.") + private String studentName; +} diff --git a/src/main/java/com/ohdab/classroom/controller/request/AddWorkbookReq.java b/src/main/java/com/ohdab/classroom/controller/request/AddWorkbookReq.java new file mode 100644 index 00000000..c9a4bc74 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/request/AddWorkbookReq.java @@ -0,0 +1,27 @@ +package com.ohdab.classroom.controller.request; + +import javax.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AddWorkbookReq { + + @NotNull(message = "교재 이름은 필수 입력 값입니다.") + private String name; + + @NotNull(message = "교재 설명은 필수 입력값 입니다.") + private String description; + + @NotNull(message = "교재 문제의 시작 번호는 필수 입력값 입니다.") + private int startingNumber; + + @NotNull(message = "교재 문제의 끝 번호는 필수 입력값 입니다.") + private int endingNumber; +} diff --git a/src/main/java/com/ohdab/classroom/controller/request/UpdateWorkbookInfoReq.java b/src/main/java/com/ohdab/classroom/controller/request/UpdateWorkbookInfoReq.java new file mode 100644 index 00000000..704e61f8 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/request/UpdateWorkbookInfoReq.java @@ -0,0 +1,21 @@ +package com.ohdab.classroom.controller.request; + +import javax.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class UpdateWorkbookInfoReq { + + @NotNull(message = "교재 이름은 필수 입력 값입니다.") + private String name; + + @NotNull(message = "교재 설명은 필수 입력값 입니다.") + private String description; +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/AddStudentRes.java b/src/main/java/com/ohdab/classroom/controller/response/AddStudentRes.java new file mode 100644 index 00000000..2a5d607c --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/AddStudentRes.java @@ -0,0 +1,11 @@ +package com.ohdab.classroom.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class AddStudentRes { + + private String message; +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/AddWorkbookRes.java b/src/main/java/com/ohdab/classroom/controller/response/AddWorkbookRes.java new file mode 100644 index 00000000..0d4afe73 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/AddWorkbookRes.java @@ -0,0 +1,10 @@ +package com.ohdab.classroom.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class AddWorkbookRes { + String message; +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/ClassroomWorkbookListRes.java b/src/main/java/com/ohdab/classroom/controller/response/ClassroomWorkbookListRes.java new file mode 100644 index 00000000..56dbcdd3 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/ClassroomWorkbookListRes.java @@ -0,0 +1,23 @@ +package com.ohdab.classroom.controller.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.time.LocalDate; +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class ClassroomWorkbookListRes { + + @JsonProperty("workbooks") + List workbookList; + + @Getter + @Builder + public static class WorkbookInfo { + long id; + String name; + LocalDate createdAt; + } +} diff --git a/src/main/java/com/ohdab/classroom/controller/response/UpdateWorkbookInfoRes.java b/src/main/java/com/ohdab/classroom/controller/response/UpdateWorkbookInfoRes.java new file mode 100644 index 00000000..3e3a18b0 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/controller/response/UpdateWorkbookInfoRes.java @@ -0,0 +1,10 @@ +package com.ohdab.classroom.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class UpdateWorkbookInfoRes { + String message; +} diff --git a/src/main/java/com/ohdab/classroom/domain/Classroom.java b/src/main/java/com/ohdab/classroom/domain/Classroom.java index 363eaec7..fde41409 100644 --- a/src/main/java/com/ohdab/classroom/domain/Classroom.java +++ b/src/main/java/com/ohdab/classroom/domain/Classroom.java @@ -1,10 +1,13 @@ package com.ohdab.classroom.domain; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.exception.NoStudentException; import com.ohdab.core.baseentity.BaseEntity; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.student.studentid.StudentId; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import com.ohdab.workbook.domain.workbookid.WorkbookId; +import io.jsonwebtoken.lang.Assert; import java.util.ArrayList; import java.util.List; import javax.persistence.*; @@ -40,35 +43,30 @@ public class Classroom extends BaseEntity { @Builder public Classroom(ClassroomInfo classroomInfo, TeacherId teacher) { - if (classroomInfo == null) { - throw new IllegalStateException("ClassroomInfo cannot be null"); - } - if (teacher == null) { - throw new IllegalStateException("Teacher cannot be null"); - } - setClassroomInfo(classroomInfo); - setTeacher(teacher); - } - - public void setClassroomInfo(ClassroomInfo classroomInfo) { + Assert.notNull(classroomInfo, ExceptionEnum.IS_NULL.getMessage()); + Assert.notNull(teacher, ExceptionEnum.IS_NULL.getMessage()); this.classroomInfo = classroomInfo; - } - - private void setTeacher(TeacherId teacher) { this.teacher = teacher; } public void addStudent(StudentId student) { - if (student == null) { - throw new IllegalStateException("Student cannot be null."); - } + Assert.notNull(student, ExceptionEnum.IS_NULL.getMessage()); this.students.add(student); } public void addWorkbook(WorkbookId workbook) { - if (workbook == null) { - throw new IllegalStateException("Workbook cannot be null."); - } + Assert.notNull(workbook, ExceptionEnum.IS_NULL.getMessage()); this.workbooks.add(workbook); } + + public void deleteStudent(long studentId) { + if (!students.removeIf(student -> student.getId() == studentId)) { + throw new NoStudentException(ExceptionEnum.NO_STUDENT.getMessage()); + } + } + + public void updateClassroomInfo(ClassroomInfo classroomInfo) { + Assert.notNull(classroomInfo, ExceptionEnum.IS_NULL.getMessage()); + this.classroomInfo = classroomInfo; + } } diff --git a/src/main/java/com/ohdab/classroom/event/StudentAddedEvent.java b/src/main/java/com/ohdab/classroom/event/StudentAddedEvent.java new file mode 100644 index 00000000..26449043 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/event/StudentAddedEvent.java @@ -0,0 +1,20 @@ +package com.ohdab.classroom.event; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class StudentAddedEvent { + + private String studentName; + private String password; + + @Builder + public StudentAddedEvent(String studentName) { + this.studentName = studentName; + this.password = "1234"; + } +} diff --git a/src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java b/src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java deleted file mode 100644 index a47134d0..00000000 --- a/src/main/java/com/ohdab/classroom/exception/CannotFindClassroomException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.ohdab.classroom.exception; - -public class CannotFindClassroomException extends RuntimeException { - - public CannotFindClassroomException(String message, Exception e) { - super(message); - } -} diff --git a/src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java b/src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java deleted file mode 100644 index 0ff1854f..00000000 --- a/src/main/java/com/ohdab/classroom/exception/CannotFindGradeException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.ohdab.classroom.exception; - -public class CannotFindGradeException extends RuntimeException { - - public CannotFindGradeException(String message, Exception e) { - super(message); - } -} diff --git a/src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java b/src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java deleted file mode 100644 index 1c55bc17..00000000 --- a/src/main/java/com/ohdab/classroom/exception/CannotFindTeacherException.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.ohdab.classroom.exception; - -public class CannotFindTeacherException extends RuntimeException { - - public CannotFindTeacherException(String message) { - super(message); - } -} diff --git a/src/main/java/com/ohdab/classroom/exception/NoClassroomException.java b/src/main/java/com/ohdab/classroom/exception/NoClassroomException.java new file mode 100644 index 00000000..6ca31249 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/exception/NoClassroomException.java @@ -0,0 +1,18 @@ +package com.ohdab.classroom.exception; + +public class NoClassroomException extends RuntimeException { + + public NoClassroomException() {} + + public NoClassroomException(String message) { + super(message); + } + + public NoClassroomException(String message, Throwable cause) { + super(message, cause); + } + + public NoClassroomException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/classroom/exception/NoGradeException.java b/src/main/java/com/ohdab/classroom/exception/NoGradeException.java new file mode 100644 index 00000000..e178b827 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/exception/NoGradeException.java @@ -0,0 +1,18 @@ +package com.ohdab.classroom.exception; + +public class NoGradeException extends RuntimeException { + + public NoGradeException() {} + + public NoGradeException(String message) { + super(message); + } + + public NoGradeException(String message, Throwable cause) { + super(message, cause); + } + + public NoGradeException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/classroom/exception/NoStudentException.java b/src/main/java/com/ohdab/classroom/exception/NoStudentException.java new file mode 100644 index 00000000..9b75564a --- /dev/null +++ b/src/main/java/com/ohdab/classroom/exception/NoStudentException.java @@ -0,0 +1,18 @@ +package com.ohdab.classroom.exception; + +public class NoStudentException extends RuntimeException { + + public NoStudentException() {} + + public NoStudentException(String message) { + super(message); + } + + public NoStudentException(String message, Throwable cause) { + super(message, cause); + } + + public NoStudentException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/classroom/exception/NoTeacherException.java b/src/main/java/com/ohdab/classroom/exception/NoTeacherException.java new file mode 100644 index 00000000..85aa5bbc --- /dev/null +++ b/src/main/java/com/ohdab/classroom/exception/NoTeacherException.java @@ -0,0 +1,18 @@ +package com.ohdab.classroom.exception; + +public class NoTeacherException extends RuntimeException { + + public NoTeacherException() {} + + public NoTeacherException(String message) { + super(message); + } + + public NoTeacherException(String message, Throwable cause) { + super(message, cause); + } + + public NoTeacherException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java b/src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java index 78846980..dfdebca6 100644 --- a/src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java +++ b/src/main/java/com/ohdab/classroom/repository/ClassroomRepository.java @@ -1,6 +1,7 @@ package com.ohdab.classroom.repository; import com.ohdab.classroom.domain.Classroom; +import com.ohdab.member.domain.student.studentid.StudentId; import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; @@ -8,5 +9,5 @@ public interface ClassroomRepository extends JpaRepository { List findAllByTeacherId(long teacherId); - Classroom findClassroomById(long classroomId); + List findStudentsById(long classroomId); } diff --git a/src/main/java/com/ohdab/classroom/service/AddClassroomService.java b/src/main/java/com/ohdab/classroom/service/AddClassroomService.java index 78a44491..c980445b 100644 --- a/src/main/java/com/ohdab/classroom/service/AddClassroomService.java +++ b/src/main/java/com/ohdab/classroom/service/AddClassroomService.java @@ -1,12 +1,14 @@ package com.ohdab.classroom.service; +import static com.ohdab.classroom.service.helper.ClassroomHelperService.findGradeByString; + import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; -import com.ohdab.classroom.exception.CannotFindTeacherException; +import com.ohdab.classroom.exception.NoTeacherException; import com.ohdab.classroom.repository.ClassroomRepository; import com.ohdab.classroom.service.dto.ClassroomDto; -import com.ohdab.classroom.service.helper.ClassroomServiceHelper; import com.ohdab.classroom.service.usecase.AddClassroomUsecase; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import com.ohdab.member.repository.MemberRepository; import lombok.RequiredArgsConstructor; @@ -30,9 +32,7 @@ public void addClassroom(ClassroomDto.Request classroomReqDto) { ClassroomInfo.builder() .name(classroomReqDto.getInfo().getName()) .description(classroomReqDto.getInfo().getDescription()) - .grade( - ClassroomServiceHelper.findGradeByString( - classroomReqDto.getInfo().getGrade())) + .grade(findGradeByString(classroomReqDto.getInfo().getGrade())) .build(); Classroom classroom = @@ -44,9 +44,9 @@ public void addClassroom(ClassroomDto.Request classroomReqDto) { classroomRepository.save(classroom); } - private void throwIfTeacherDoesNotExist(Long teacherId) { + private void throwIfTeacherDoesNotExist(long teacherId) { if (!memberRepository.existsById(teacherId)) { - throw new CannotFindTeacherException("cannot find teacher by id : " + teacherId); + throw new NoTeacherException(ExceptionEnum.NO_TEACHER.getMessage()); } } } diff --git a/src/main/java/com/ohdab/classroom/service/AddStudentService.java b/src/main/java/com/ohdab/classroom/service/AddStudentService.java new file mode 100644 index 00000000..b1a0155c --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/AddStudentService.java @@ -0,0 +1,74 @@ +package com.ohdab.classroom.service; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.event.StudentAddedEvent; +import com.ohdab.classroom.exception.NoClassroomException; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.AddStudentDto; +import com.ohdab.classroom.service.usecase.AddStudentUsecase; +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.exception.NoMemberException; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class AddStudentService implements AddStudentUsecase { + + private final ApplicationEventPublisher publisher; + private final ClassroomRepository classroomRepository; + private final MemberRepository memberRepository; + private final MistakeNoteRepository mistakeNoteRepository; + + @Override + public void addStudent(AddStudentDto.Request addStudentReq) { + Classroom classroom = findClassroomById(addStudentReq.getClassroomId()); + publishStudentAddedEvent(addStudentReq.getStudentName()); + Member student = findMemberByName(addStudentReq.getStudentName()); + createMistakeNoteForAddedStudent(classroom, student); + classroom.addStudent(new StudentId(student.getId())); + } + + private Classroom findClassroomById(long classroomId) { + return classroomRepository + .findById(classroomId) + .orElseThrow( + () -> new NoClassroomException(ExceptionEnum.NO_CLASSROOM.getMessage())); + } + + private void publishStudentAddedEvent(String studentName) { + publisher.publishEvent(StudentAddedEvent.builder().studentName(studentName).build()); + } + + private Member findMemberByName(String studentName) { + return memberRepository + .findByMemberInfoName(studentName) + .orElseThrow(() -> new NoMemberException(ExceptionEnum.NO_MEMBER.getMessage())); + } + + private void createMistakeNoteForAddedStudent(Classroom classroom, Member student) { + long studentId = student.getId(); + List workbooks = classroom.getWorkbooks(); + List mistakeNotes = + workbooks.stream() + .map( + workbookId -> + MistakeNote.builder() + .workbookId(workbookId) + .studentId(new StudentId(studentId)) + .build()) + .collect(Collectors.toList()); + mistakeNoteRepository.saveAll(mistakeNotes); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/AddWorkbookService.java b/src/main/java/com/ohdab/classroom/service/AddWorkbookService.java new file mode 100644 index 00000000..17a6d17d --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/AddWorkbookService.java @@ -0,0 +1,74 @@ +package com.ohdab.classroom.service; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomAddWorkbookDto; +import com.ohdab.classroom.service.dto.ClassroomAddWorkbookDto.Request; +import com.ohdab.classroom.service.helper.ClassroomHelperService; +import com.ohdab.classroom.service.usecase.AddWorkbookUsecase; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.mistakenote.domain.MistakeNote; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import com.ohdab.workbook.domain.workbookid.WorkbookId; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class AddWorkbookService implements AddWorkbookUsecase { + + private final ClassroomRepository classroomRepository; + private final WorkbookRepository workbookRepository; + private final MistakeNoteRepository mistakeNoteRepository; + + @Override + public void addWorkbookByClassroomId(long classroomId, Request addWorkbookDto) { + Classroom classroom = + ClassroomHelperService.findExistingClassroom(classroomId, classroomRepository); + ClassroomId classroomId1 = new ClassroomId(classroomId); + ClassroomHelperService.throwIfDuplicatedWorkbookName( + workbookRepository, classroomId1, addWorkbookDto.getName()); + Workbook workbook = saveWorkbook(classroomId1, addWorkbookDto); + WorkbookId workbookId = new WorkbookId(workbook.getId()); + classroom.addWorkbook(workbookId); + saveMistakeNote(classroomId, workbookId); + } + + private Workbook saveWorkbook( + ClassroomId classroomId, ClassroomAddWorkbookDto.Request addWorkbookDto) { + Workbook workbook = + Workbook.builder() + .workbookInfo( + WorkbookInfo.builder() + .name(addWorkbookDto.getName()) + .description(addWorkbookDto.getDescription()) + .startingNumber(addWorkbookDto.getStartingNumber()) + .endingNumber(addWorkbookDto.getEndingNumber()) + .build()) + .classroomId(classroomId) + .build(); + return workbookRepository.save(workbook); + } + + private void saveMistakeNote(long classroomId, WorkbookId workbookId) { + List studentIdList = classroomRepository.findStudentsById(classroomId); + List mistakeNoteList = + studentIdList.stream() + .map( + studentId -> + MistakeNote.builder() + .studentId(studentId) + .workbookId(workbookId) + .build()) + .collect(Collectors.toList()); + mistakeNoteRepository.saveAll(mistakeNoteList); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java b/src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java index 46051019..49471837 100644 --- a/src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java +++ b/src/main/java/com/ohdab/classroom/service/ClassroomDetailService.java @@ -3,9 +3,11 @@ import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.exception.NoClassroomException; import com.ohdab.classroom.repository.ClassroomRepository; import com.ohdab.classroom.service.mapper.ClassroomDetailServiceMapper; import com.ohdab.classroom.service.usecase.ClassroomDetailUsecase; +import com.ohdab.core.exception.ExceptionEnum; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,7 +21,13 @@ public class ClassroomDetailService implements ClassroomDetailUsecase { @Override public ClassroomDetailDtoResponse getClassroomDetailById(long classroomId) { - Classroom classroom = classroomRepository.findClassroomById(classroomId); + Classroom classroom = + classroomRepository + .findById(classroomId) + .orElseThrow( + () -> + new NoClassroomException( + ExceptionEnum.NO_CLASSROOM.getMessage())); return ClassroomDetailServiceMapper.classroomToClassroomDetail(classroom); } } diff --git a/src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java b/src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java index 142025e0..5b86d714 100644 --- a/src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java +++ b/src/main/java/com/ohdab/classroom/service/DeleteClassroomService.java @@ -1,8 +1,9 @@ package com.ohdab.classroom.service; +import static com.ohdab.classroom.service.helper.ClassroomHelperService.findExistingClassroom; + import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.repository.ClassroomRepository; -import com.ohdab.classroom.service.helper.ClassroomServiceHelper; import com.ohdab.classroom.service.usecase.DeleteClassroomUsecase; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -17,8 +18,7 @@ public class DeleteClassroomService implements DeleteClassroomUsecase { @Override public void deleteClassroomById(long classroomId) { - Classroom classroom = - ClassroomServiceHelper.getClassroomById(classroomId, classroomRepository); + Classroom classroom = findExistingClassroom(classroomId, classroomRepository); classroomRepository.delete(classroom); } } diff --git a/src/main/java/com/ohdab/classroom/service/DeleteStudentService.java b/src/main/java/com/ohdab/classroom/service/DeleteStudentService.java new file mode 100644 index 00000000..586ddf00 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/DeleteStudentService.java @@ -0,0 +1,30 @@ +package com.ohdab.classroom.service; + +import static com.ohdab.classroom.service.helper.ClassroomHelperService.findExistingClassroom; +import static com.ohdab.member.service.helper.MemberHelperService.findExistingMemberById; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.usecase.DeleteStudentUsecase; +import com.ohdab.member.domain.Member; +import com.ohdab.member.repository.MemberRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class DeleteStudentService implements DeleteStudentUsecase { + + private final ClassroomRepository classroomRepository; + private final MemberRepository memberRepository; + + @Override + public void deleteStudent(long classroomId, long studentId) { + Classroom classroom = findExistingClassroom(classroomId, classroomRepository); + Member student = findExistingMemberById(memberRepository, studentId); + student.withdrawal(); + classroom.deleteStudent(studentId); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java b/src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java index 1a39848b..3665967b 100644 --- a/src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java +++ b/src/main/java/com/ohdab/classroom/service/FindClassroomDetailService.java @@ -3,9 +3,11 @@ import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.exception.NoClassroomException; import com.ohdab.classroom.repository.ClassroomRepository; import com.ohdab.classroom.service.mapper.ClassroomDetailServiceMapper; import com.ohdab.classroom.service.usecase.FindClassroomDetailUsecase; +import com.ohdab.core.exception.ExceptionEnum; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,7 +21,13 @@ public class FindClassroomDetailService implements FindClassroomDetailUsecase { @Override public ClassroomDetailDtoResponse getClassroomDetailById(long classroomId) { - Classroom classroom = classroomRepository.findClassroomById(classroomId); + Classroom classroom = + classroomRepository + .findById(classroomId) + .orElseThrow( + () -> + new NoClassroomException( + ExceptionEnum.NO_CLASSROOM.getMessage())); return ClassroomDetailServiceMapper.classroomToClassroomDetail(classroom); } } diff --git a/src/main/java/com/ohdab/classroom/service/GetWorkbookListService.java b/src/main/java/com/ohdab/classroom/service/GetWorkbookListService.java new file mode 100644 index 00000000..cc001e05 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/GetWorkbookListService.java @@ -0,0 +1,51 @@ +package com.ohdab.classroom.service; + +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.classroom.exception.NoClassroomException; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomWorkbookDto; +import com.ohdab.classroom.service.usecase.GetWorkbookListUsecase; +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class GetWorkbookListService implements GetWorkbookListUsecase { + + private final ClassroomRepository classroomRepository; + private final WorkbookRepository workbookRepository; + + @Override + public List getWorkbookListByClassroomId(long classroomId) { + throwIfUnknownClassroomId(classroomId); + List workbookList = + workbookRepository.findByClassroomId(new ClassroomId(classroomId)); + return workbookDomainListToWorkbookDtoList(workbookList); + } + + private void throwIfUnknownClassroomId(long classroomId) { + if (!classroomRepository.existsById(classroomId)) { + throw new NoClassroomException(ExceptionEnum.NO_CLASSROOM.getMessage()); + } + } + + private List workbookDomainListToWorkbookDtoList( + List workbookList) { + return workbookList.stream() + .map( + workbook -> + ClassroomWorkbookDto.Response.builder() + .id(workbook.getId()) + .name(workbook.getWorkbookInfo().getName()) + .createdAt(workbook.getCreatedAt()) + .build()) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java b/src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java index 1a50deb5..90240488 100644 --- a/src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java +++ b/src/main/java/com/ohdab/classroom/service/UpdateClassroomInfoService.java @@ -1,11 +1,12 @@ package com.ohdab.classroom.service; import static com.ohdab.classroom.service.dto.ClassroomUpdateDto.ClassroomUpdateDtoRequest; +import static com.ohdab.classroom.service.helper.ClassroomHelperService.findExistingClassroom; +import static com.ohdab.classroom.service.helper.ClassroomHelperService.findGradeByString; import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; import com.ohdab.classroom.repository.ClassroomRepository; -import com.ohdab.classroom.service.helper.ClassroomServiceHelper; import com.ohdab.classroom.service.usecase.UpdateClassroomInfoUsecase; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -20,14 +21,12 @@ public class UpdateClassroomInfoService implements UpdateClassroomInfoUsecase { @Override public void updateClassroomInfo(ClassroomUpdateDtoRequest request) { - Classroom classroom = - ClassroomServiceHelper.getClassroomById( - request.getClassroomId(), classroomRepository); - classroom.setClassroomInfo( + Classroom classroom = findExistingClassroom(request.getClassroomId(), classroomRepository); + classroom.updateClassroomInfo( ClassroomInfo.builder() .name(request.getName()) .description(request.getDescription()) - .grade(ClassroomServiceHelper.findGradeByString(request.getGrade())) + .grade(findGradeByString(request.getGrade())) .build()); classroomRepository.save(classroom); } diff --git a/src/main/java/com/ohdab/classroom/service/UpdateWorkbookInfoService.java b/src/main/java/com/ohdab/classroom/service/UpdateWorkbookInfoService.java new file mode 100644 index 00000000..4dc73487 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/UpdateWorkbookInfoService.java @@ -0,0 +1,46 @@ +package com.ohdab.classroom.service; + +import com.ohdab.classroom.service.dto.ClassroomWorkbookUpdateDto.Request; +import com.ohdab.classroom.service.helper.ClassroomHelperService; +import com.ohdab.classroom.service.usecase.UpdateWorkbookInfoUsecase; +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import com.ohdab.workbook.exception.NoWorkbookException; +import com.ohdab.workbook.repository.WorkbookRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class UpdateWorkbookInfoService implements UpdateWorkbookInfoUsecase { + + private final WorkbookRepository workbookRepository; + + @Override + public void updateWorkbookInfo(Request updateWorkbookReq) { + throwIfUnknownWorkbookId(updateWorkbookReq.getId()); + Workbook workbook = workbookRepository.findById(updateWorkbookReq.getId()).get(); + ClassroomHelperService.throwIfDuplicatedWorkbookName( + workbookRepository, workbook.getClassroomId(), updateWorkbookReq.getName()); + workbook.updateWorkbookInfo(setWorkbookInfo(updateWorkbookReq, workbook)); + workbookRepository.save(workbook); + } + + private void throwIfUnknownWorkbookId(long id) { + if (!workbookRepository.existsById(id)) { + throw new NoWorkbookException(ExceptionEnum.NO_WORKBOOK.getMessage()); + } + } + + private WorkbookInfo setWorkbookInfo(Request updateWorkbookReq, Workbook workbook) { + return WorkbookInfo.builder() + .name(updateWorkbookReq.getName()) + .description(updateWorkbookReq.getDescription()) + .startingNumber(workbook.getWorkbookInfo().getStartingNumber()) + .endingNumber(workbook.getWorkbookInfo().getEndingNumber()) + .build(); + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/AddStudentDto.java b/src/main/java/com/ohdab/classroom/service/dto/AddStudentDto.java new file mode 100644 index 00000000..5f86bff5 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/AddStudentDto.java @@ -0,0 +1,18 @@ +package com.ohdab.classroom.service.dto; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AddStudentDto { + + @Getter + @Builder + public static class Request { + + private long classroomId; + private String studentName; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/ClassroomAddWorkbookDto.java b/src/main/java/com/ohdab/classroom/service/dto/ClassroomAddWorkbookDto.java new file mode 100644 index 00000000..3555e565 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/ClassroomAddWorkbookDto.java @@ -0,0 +1,19 @@ +package com.ohdab.classroom.service.dto; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ClassroomAddWorkbookDto { + + @Getter + @Builder + public static class Request { + String name; + String description; + int startingNumber; + int endingNumber; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookDto.java b/src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookDto.java new file mode 100644 index 00000000..16ea079b --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookDto.java @@ -0,0 +1,19 @@ +package com.ohdab.classroom.service.dto; + +import java.time.LocalDateTime; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ClassroomWorkbookDto { + + @Getter + @Builder + public static class Response { + Long id; + String name; + LocalDateTime createdAt; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookUpdateDto.java b/src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookUpdateDto.java new file mode 100644 index 00000000..84bc1e0f --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/ClassroomWorkbookUpdateDto.java @@ -0,0 +1,18 @@ +package com.ohdab.classroom.service.dto; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ClassroomWorkbookUpdateDto { + + @Builder + @Getter + public static class Request { + long id; + String name; + String description; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/dto/DeleteStudentDto.java b/src/main/java/com/ohdab/classroom/service/dto/DeleteStudentDto.java new file mode 100644 index 00000000..36513cd8 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/dto/DeleteStudentDto.java @@ -0,0 +1,15 @@ +package com.ohdab.classroom.service.dto; + +import lombok.Builder; +import lombok.Getter; + +public class DeleteStudentDto { + + @Getter + @Builder + public static class Request { + + private long classroomId; + private long studentId; + } +} diff --git a/src/main/java/com/ohdab/classroom/service/helper/ClassroomHelperService.java b/src/main/java/com/ohdab/classroom/service/helper/ClassroomHelperService.java new file mode 100644 index 00000000..82b743bc --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/helper/ClassroomHelperService.java @@ -0,0 +1,42 @@ +package com.ohdab.classroom.service.helper; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.classroom.exception.NoClassroomException; +import com.ohdab.classroom.exception.NoGradeException; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.workbook.exception.DuplicatedWorkbookException; +import com.ohdab.workbook.repository.WorkbookRepository; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public final class ClassroomHelperService { + + public static Grade findGradeByString(String stringGrade) { + try { + return Grade.valueOfLabel(stringGrade); + } catch (NullPointerException e) { + throw new NoGradeException(ExceptionEnum.NO_GRADE.getMessage()); + } catch (ClassCastException e) { + throw new IllegalArgumentException("인자의 자료형이 잘못되었습니다."); + } + } + + public static Classroom findExistingClassroom( + long classroomId, ClassroomRepository classroomRepository) { + return classroomRepository + .findById(classroomId) + .orElseThrow( + () -> new NoClassroomException(ExceptionEnum.NO_CLASSROOM.getMessage())); + } + + public static void throwIfDuplicatedWorkbookName( + WorkbookRepository workbookRepository, ClassroomId classroomId, String name) { + if (workbookRepository.existsByClassroomIdAndWorkbookInfoName(classroomId, name)) { + throw new DuplicatedWorkbookException(ExceptionEnum.DUPLICATED_WORKBOOK.getMessage()); + } + } +} diff --git a/src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java b/src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java deleted file mode 100644 index 56a9821a..00000000 --- a/src/main/java/com/ohdab/classroom/service/helper/ClassroomServiceHelper.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.ohdab.classroom.service.helper; - -import com.ohdab.classroom.domain.Classroom; -import com.ohdab.classroom.domain.classroomInfo.Grade; -import com.ohdab.classroom.exception.CannotFindClassroomException; -import com.ohdab.classroom.exception.CannotFindGradeException; -import com.ohdab.classroom.repository.ClassroomRepository; - -public class ClassroomServiceHelper { - - public static Grade findGradeByString(String stringGrade) { - try { - return Grade.valueOfLabel(stringGrade); - } catch (Exception e) { - throw new CannotFindGradeException("Cannot find Grade : " + stringGrade, e); - } - } - - public static Classroom getClassroomById(long id, ClassroomRepository classroomRepository) { - try { - return classroomRepository.findClassroomById(id); - } catch (Exception e) { - throw new CannotFindClassroomException("반을 찾을 수 없습니다. id : " + id, e); - } - } -} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/AddStudentUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/AddStudentUsecase.java new file mode 100644 index 00000000..455d3bdd --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/AddStudentUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.service.usecase; + +import com.ohdab.classroom.service.dto.AddStudentDto; + +public interface AddStudentUsecase { + + void addStudent(AddStudentDto.Request addStudentReq); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/AddWorkbookUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/AddWorkbookUsecase.java new file mode 100644 index 00000000..d18bebf6 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/AddWorkbookUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.service.usecase; + +import com.ohdab.classroom.service.dto.ClassroomAddWorkbookDto; + +public interface AddWorkbookUsecase { + + void addWorkbookByClassroomId(long classroomId, ClassroomAddWorkbookDto.Request addWorkbookDto); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/DeleteStudentUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/DeleteStudentUsecase.java new file mode 100644 index 00000000..4fa32f8e --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/DeleteStudentUsecase.java @@ -0,0 +1,6 @@ +package com.ohdab.classroom.service.usecase; + +public interface DeleteStudentUsecase { + + void deleteStudent(long classroomId, long studentId); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/GetWorkbookListUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/GetWorkbookListUsecase.java new file mode 100644 index 00000000..37120e8d --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/GetWorkbookListUsecase.java @@ -0,0 +1,9 @@ +package com.ohdab.classroom.service.usecase; + +import com.ohdab.classroom.service.dto.ClassroomWorkbookDto; +import java.util.List; + +public interface GetWorkbookListUsecase { + + List getWorkbookListByClassroomId(long classroomId); +} diff --git a/src/main/java/com/ohdab/classroom/service/usecase/UpdateWorkbookInfoUsecase.java b/src/main/java/com/ohdab/classroom/service/usecase/UpdateWorkbookInfoUsecase.java new file mode 100644 index 00000000..d127b2e3 --- /dev/null +++ b/src/main/java/com/ohdab/classroom/service/usecase/UpdateWorkbookInfoUsecase.java @@ -0,0 +1,8 @@ +package com.ohdab.classroom.service.usecase; + +import com.ohdab.classroom.service.dto.ClassroomWorkbookUpdateDto; + +public interface UpdateWorkbookInfoUsecase { + + void updateWorkbookInfo(ClassroomWorkbookUpdateDto.Request updateWorkbookReq); +} diff --git a/src/main/java/com/ohdab/core/exception/ExceptionEnum.java b/src/main/java/com/ohdab/core/exception/ExceptionEnum.java new file mode 100644 index 00000000..b559b734 --- /dev/null +++ b/src/main/java/com/ohdab/core/exception/ExceptionEnum.java @@ -0,0 +1,44 @@ +package com.ohdab.core.exception; + +import lombok.Getter; + +@Getter +public enum ExceptionEnum { + + // 600 - classroom + NO_CLASSROOM(600, "존재하지 않는 교실입니다."), + NO_GRADE(601, "존재하지 않는 학년입니다."), + NO_STUDENT(602, "존재하지 않는 학생입니다."), + NO_TEACHER(603, "존재하지 않는 선생님입니다."), + + // 700 - member + ALREADY_WITHDRAWL(700, "이미 탈퇴한 계정입니다."), + DUPLICATED_MEMBER(701, "이미 존재하는 회원입니다."), + NO_MEMBER(702, "존재하지 않는 회원입니다."), + MEMBER_CONTENT_OVERFLOW(703, "최대 글자수를 초과했습니다."), + NO_AUTHORITY(704, "권한정보가 누락되었습니다."), + + // 800 - mistakeNote + NO_MISTAKE_NOTE(800, "존재하지 않는 오답노트입니다."), + NO_NUMBERS_WRONG_N_TIMES(801, ""), + NUMBER_IS_OUT_OF_RANGE(802, "N번 이상 틀린 문제가 없습니다."), + MISTAKE_NUMBERS_SIZE(803, "기록 가능한 문제수를 초과했습니다."), + + // 900 - workbook + WORKBOOK_CONTENT_OVERFLOW(900, "최대 글자수를 초과했습니다."), + DUPLICATED_WORKBOOK(901, "이미 존재하는 교재입니다."), + INVALID_WORKBOOK_NUMBER_RANGE(902, "허용 범위를 벗어난 문제 번호입니다."), + NO_WORKBOOK(903, "존재하지 않는 교재입니다."), + + // 1000 - null + IS_NULL(1000, "필수 입력값이 누락되었습니다."), + ; + + private int errorCode; + private String message; + + ExceptionEnum(int errorCode, String message) { + this.errorCode = errorCode; + this.message = message; + } +} diff --git a/src/main/java/com/ohdab/core/exception/handler/ClassroomExceptionHandler.java b/src/main/java/com/ohdab/core/exception/handler/ClassroomExceptionHandler.java new file mode 100644 index 00000000..e635ce3f --- /dev/null +++ b/src/main/java/com/ohdab/core/exception/handler/ClassroomExceptionHandler.java @@ -0,0 +1,55 @@ +package com.ohdab.core.exception.handler; + +import com.ohdab.classroom.exception.NoClassroomException; +import com.ohdab.classroom.exception.NoGradeException; +import com.ohdab.classroom.exception.NoStudentException; +import com.ohdab.classroom.exception.NoTeacherException; +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.core.template.ErrorMessage; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class ClassroomExceptionHandler { + + @ExceptionHandler + public ResponseEntity noClassroomException(NoClassroomException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_CLASSROOM.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity noGradeException(NoGradeException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_GRADE.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity noStudentException(NoStudentException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_STUDENT.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity noTeacherException(NoTeacherException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_TEACHER.getErrorCode()) + .message(e.getMessage()) + .build()); + } +} diff --git a/src/main/java/com/ohdab/core/exception/handler/CommonExceptionHandler.java b/src/main/java/com/ohdab/core/exception/handler/CommonExceptionHandler.java new file mode 100644 index 00000000..fb20b792 --- /dev/null +++ b/src/main/java/com/ohdab/core/exception/handler/CommonExceptionHandler.java @@ -0,0 +1,21 @@ +package com.ohdab.core.exception.handler; + +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.core.template.ErrorMessage; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class CommonExceptionHandler { + + @ExceptionHandler + public ResponseEntity illegalArgumentException(IllegalArgumentException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.IS_NULL.getErrorCode()) + .message(e.getMessage()) + .build()); + } +} diff --git a/src/main/java/com/ohdab/core/exception/handler/MemberExceptionHandler.java b/src/main/java/com/ohdab/core/exception/handler/MemberExceptionHandler.java new file mode 100644 index 00000000..58cdb067 --- /dev/null +++ b/src/main/java/com/ohdab/core/exception/handler/MemberExceptionHandler.java @@ -0,0 +1,62 @@ +package com.ohdab.core.exception.handler; + +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.core.template.ErrorMessage; +import com.ohdab.member.exception.*; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class MemberExceptionHandler { + + @ExceptionHandler + public ResponseEntity alreadyWithdrawException(AlreadyWithdrawlException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.ALREADY_WITHDRAWL.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity duplicatedMemberException(DuplicatedMemberException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.DUPLICATED_MEMBER.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity noMemberException(NoMemberException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_MEMBER.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity contentOverflowException(MemberContentOverflowException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.MEMBER_CONTENT_OVERFLOW.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity noAuthorityException(NoAuthorityException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_AUTHORITY.getErrorCode()) + .message(e.getMessage()) + .build()); + } +} diff --git a/src/main/java/com/ohdab/core/exception/handler/MistakeNoteExceptionHandler.java b/src/main/java/com/ohdab/core/exception/handler/MistakeNoteExceptionHandler.java new file mode 100644 index 00000000..38b984fc --- /dev/null +++ b/src/main/java/com/ohdab/core/exception/handler/MistakeNoteExceptionHandler.java @@ -0,0 +1,56 @@ +package com.ohdab.core.exception.handler; + +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.core.template.ErrorMessage; +import com.ohdab.mistakenote.exception.MistakeNumbersSizeException; +import com.ohdab.mistakenote.exception.NoMistakeNoteException; +import com.ohdab.mistakenote.exception.NoNumbersWrongNTimesException; +import com.ohdab.mistakenote.exception.NumberIsOutOfRangeException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class MistakeNoteExceptionHandler { + + @ExceptionHandler + public ResponseEntity noMistakeException(NoMistakeNoteException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_MISTAKE_NOTE.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity noNumbersWrongNTimesException( + NoNumbersWrongNTimesException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_NUMBERS_WRONG_N_TIMES.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity numberIsOutOfRangeException(NumberIsOutOfRangeException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NUMBER_IS_OUT_OF_RANGE.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity mistakeNumberSizeException(MistakeNumbersSizeException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.MISTAKE_NUMBERS_SIZE.getErrorCode()) + .message(e.getMessage()) + .build()); + } +} diff --git a/src/main/java/com/ohdab/core/exception/handler/WorkbookExceptionHandler.java b/src/main/java/com/ohdab/core/exception/handler/WorkbookExceptionHandler.java new file mode 100644 index 00000000..d8f66f73 --- /dev/null +++ b/src/main/java/com/ohdab/core/exception/handler/WorkbookExceptionHandler.java @@ -0,0 +1,58 @@ +package com.ohdab.core.exception.handler; + +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.core.template.ErrorMessage; +import com.ohdab.workbook.exception.DuplicatedWorkbookException; +import com.ohdab.workbook.exception.InvalidWorkbookNumberRangeException; +import com.ohdab.workbook.exception.NoWorkbookException; +import com.ohdab.workbook.exception.WorkbookContentOverflowException; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class WorkbookExceptionHandler { + + @ExceptionHandler + public ResponseEntity contentOverflowException( + WorkbookContentOverflowException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.WORKBOOK_CONTENT_OVERFLOW.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity duplicatedWorkbookException(DuplicatedWorkbookException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.DUPLICATED_WORKBOOK.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity invalidWorkbookNumberRangeException( + InvalidWorkbookNumberRangeException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode( + ExceptionEnum.INVALID_WORKBOOK_NUMBER_RANGE.getErrorCode()) + .message(e.getMessage()) + .build()); + } + + @ExceptionHandler + public ResponseEntity noWorkbookException(NoWorkbookException e) { + return ResponseEntity.badRequest() + .body( + ErrorMessage.builder() + .errorCode(ExceptionEnum.NO_WORKBOOK.getErrorCode()) + .message(e.getMessage()) + .build()); + } +} diff --git a/src/main/java/com/ohdab/core/util/event/handler/StudentAddedHandler.java b/src/main/java/com/ohdab/core/util/event/handler/StudentAddedHandler.java new file mode 100644 index 00000000..40ed849a --- /dev/null +++ b/src/main/java/com/ohdab/core/util/event/handler/StudentAddedHandler.java @@ -0,0 +1,26 @@ +package com.ohdab.core.util.event.handler; + +import com.ohdab.classroom.event.StudentAddedEvent; +import com.ohdab.member.service.dto.MemberDtoForJoin; +import com.ohdab.member.service.usecase.JoinUsecase; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.context.event.EventListener; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class StudentAddedHandler { + + private final JoinUsecase joinUsecase; + + @EventListener(StudentAddedEvent.class) + public void join(StudentAddedEvent event) { + joinUsecase.join( + MemberDtoForJoin.Request.builder() + .name(event.getStudentName()) + .password(event.getPassword()) + .role(List.of("STUDENT")) + .build()); + } +} diff --git a/src/main/java/com/ohdab/member/controller/MemberController.java b/src/main/java/com/ohdab/member/controller/MemberController.java index 601283cd..27ac4b54 100644 --- a/src/main/java/com/ohdab/member/controller/MemberController.java +++ b/src/main/java/com/ohdab/member/controller/MemberController.java @@ -4,19 +4,11 @@ import com.ohdab.member.controller.request.AddTeacherReq; import com.ohdab.member.controller.request.JoinReq; import com.ohdab.member.controller.request.LoginReq; -import com.ohdab.member.controller.response.AddTeacherRes; -import com.ohdab.member.controller.response.DeleteTeacherRes; -import com.ohdab.member.controller.response.GetTeacherListRes; -import com.ohdab.member.controller.response.JoinRes; -import com.ohdab.member.controller.response.LoginRes; +import com.ohdab.member.controller.response.*; import com.ohdab.member.service.dto.MemberDtoForAddTeacher; import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; import com.ohdab.member.service.dto.MemberDtoForLogin; -import com.ohdab.member.service.usecase.AddTeacherUsecase; -import com.ohdab.member.service.usecase.DeleteTeacherUsecase; -import com.ohdab.member.service.usecase.GetTeacherListUsecase; -import com.ohdab.member.service.usecase.JoinUsecase; -import com.ohdab.member.service.usecase.LoginUsecase; +import com.ohdab.member.service.usecase.*; import java.util.List; import javax.validation.Valid; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/ohdab/member/controller/response/DeleteStudentRes.java b/src/main/java/com/ohdab/member/controller/response/DeleteStudentRes.java new file mode 100644 index 00000000..9c8364a4 --- /dev/null +++ b/src/main/java/com/ohdab/member/controller/response/DeleteStudentRes.java @@ -0,0 +1,11 @@ +package com.ohdab.member.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class DeleteStudentRes { + + private String message; +} diff --git a/src/main/java/com/ohdab/member/domain/Member.java b/src/main/java/com/ohdab/member/domain/Member.java index e7a49bda..7cea412a 100644 --- a/src/main/java/com/ohdab/member/domain/Member.java +++ b/src/main/java/com/ohdab/member/domain/Member.java @@ -1,7 +1,13 @@ package com.ohdab.member.domain; import com.ohdab.core.baseentity.BaseEntity; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.memberinfo.MemberInfo; +import com.ohdab.member.exception.AlreadyWithdrawlException; +import com.ohdab.member.exception.MemberContentOverflowException; +import com.ohdab.member.exception.NoAuthorityException; +import io.jsonwebtoken.lang.Assert; +import java.util.ArrayList; import java.util.List; import javax.persistence.*; import lombok.AccessLevel; @@ -30,13 +36,15 @@ public class Member extends BaseEntity { @ElementCollection @CollectionTable(name = "MEMBER_AUTHORITY", joinColumns = @JoinColumn(name = "member_id")) - private List authorities; + private List authorities = new ArrayList<>(); @Enumerated(EnumType.STRING) private MemberStatus status; @Builder public Member(MemberInfo memberInfo, List authorities) { + Assert.notNull(memberInfo, ExceptionEnum.IS_NULL.getMessage()); + Assert.notNull(authorities, ExceptionEnum.IS_NULL.getMessage()); setMemberInfo(memberInfo); setAuthorities(authorities); this.status = MemberStatus.ACTIVE; @@ -44,17 +52,15 @@ public Member(MemberInfo memberInfo, List authorities) { private void setAuthorities(List authorities) { if (authorities.isEmpty()) { - throw new IllegalArgumentException("권한은 반드시 추가해야함"); + throw new NoAuthorityException(ExceptionEnum.NO_AUTHORITY.getMessage()); } this.authorities = authorities; } private void setMemberInfo(MemberInfo memberInfo) { if (memberInfo.getName().length() > 20) { - throw new IllegalStateException( - "Name length cannot exceed 20 : current length \"" - + memberInfo.getName().length() - + "\""); + throw new MemberContentOverflowException( + ExceptionEnum.MEMBER_CONTENT_OVERFLOW.getMessage()); } this.memberInfo = memberInfo; } @@ -66,7 +72,7 @@ public boolean matchPassword( public void withdrawal() { if (this.status == MemberStatus.INACTIVE) { - throw new IllegalStateException("예외"); + throw new AlreadyWithdrawlException(ExceptionEnum.ALREADY_WITHDRAWL.getMessage()); } this.status = MemberStatus.INACTIVE; } diff --git a/src/main/java/com/ohdab/member/exception/AlreadyWithdrawlException.java b/src/main/java/com/ohdab/member/exception/AlreadyWithdrawlException.java new file mode 100644 index 00000000..a42c0cd1 --- /dev/null +++ b/src/main/java/com/ohdab/member/exception/AlreadyWithdrawlException.java @@ -0,0 +1,18 @@ +package com.ohdab.member.exception; + +public class AlreadyWithdrawlException extends RuntimeException { + + public AlreadyWithdrawlException() {} + + public AlreadyWithdrawlException(String message) { + super(message); + } + + public AlreadyWithdrawlException(String message, Throwable cause) { + super(message, cause); + } + + public AlreadyWithdrawlException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/member/exception/MemberContentOverflowException.java b/src/main/java/com/ohdab/member/exception/MemberContentOverflowException.java new file mode 100644 index 00000000..266519c1 --- /dev/null +++ b/src/main/java/com/ohdab/member/exception/MemberContentOverflowException.java @@ -0,0 +1,18 @@ +package com.ohdab.member.exception; + +public class MemberContentOverflowException extends RuntimeException { + + public MemberContentOverflowException() {} + + public MemberContentOverflowException(String message) { + super(message); + } + + public MemberContentOverflowException(String message, Throwable cause) { + super(message, cause); + } + + public MemberContentOverflowException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/member/exception/NoAuthorityException.java b/src/main/java/com/ohdab/member/exception/NoAuthorityException.java new file mode 100644 index 00000000..610b2a31 --- /dev/null +++ b/src/main/java/com/ohdab/member/exception/NoAuthorityException.java @@ -0,0 +1,18 @@ +package com.ohdab.member.exception; + +public class NoAuthorityException extends RuntimeException { + + public NoAuthorityException() {} + + public NoAuthorityException(String message) { + super(message); + } + + public NoAuthorityException(String message, Throwable cause) { + super(message, cause); + } + + public NoAuthorityException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/member/service/AddTeacherService.java b/src/main/java/com/ohdab/member/service/AddTeacherService.java index fe29a39c..d25031c9 100644 --- a/src/main/java/com/ohdab/member/service/AddTeacherService.java +++ b/src/main/java/com/ohdab/member/service/AddTeacherService.java @@ -1,10 +1,12 @@ package com.ohdab.member.service; +import static com.ohdab.member.service.helper.MemberHelperService.checkIfMemberExistByName; + +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.exception.NoMemberException; import com.ohdab.member.repository.MemberRepository; import com.ohdab.member.service.dto.MemberDtoForAddTeacher; import com.ohdab.member.service.dto.MemberDtoForJoin; -import com.ohdab.member.service.helper.MemberHelperService; import com.ohdab.member.service.usecase.AddTeacherUsecase; import com.ohdab.member.service.usecase.JoinUsecase; import java.util.List; @@ -19,7 +21,6 @@ public class AddTeacherService implements AddTeacherUsecase { private final MemberRepository memberRepository; private final JoinUsecase joinUsecase; - private final MemberHelperService memberHelperService; @Override public void addTeacher(MemberDtoForAddTeacher.Request addTeacherReqDto) { @@ -38,7 +39,7 @@ public void addTeacher(MemberDtoForAddTeacher.Request addTeacherReqDto) { } private String changeNameIfDuplicated(String name) { - if (memberHelperService.checkIfMemberExistByName(memberRepository, name)) { + if (checkIfMemberExistByName(memberRepository, name)) { long sameNameCount = memberRepository.countByMemberInfoNameContaining(name); return name = name + sameNameCount; } @@ -46,8 +47,8 @@ private String changeNameIfDuplicated(String name) { } private void throwIfJoinFailed(String name) { - if (!memberHelperService.checkIfMemberExistByName(memberRepository, name)) { - throw new NoMemberException("Join Failed with teacher name \"" + name + "\""); + if (!checkIfMemberExistByName(memberRepository, name)) { + throw new NoMemberException(ExceptionEnum.NO_MEMBER.getMessage()); } } } diff --git a/src/main/java/com/ohdab/member/service/DeleteTeacherService.java b/src/main/java/com/ohdab/member/service/DeleteTeacherService.java index 56c2298b..65e1138b 100644 --- a/src/main/java/com/ohdab/member/service/DeleteTeacherService.java +++ b/src/main/java/com/ohdab/member/service/DeleteTeacherService.java @@ -1,9 +1,10 @@ package com.ohdab.member.service; +import static com.ohdab.member.service.helper.MemberHelperService.findExistingMemberById; + import com.ohdab.member.domain.Member; import com.ohdab.member.domain.MemberStatus; import com.ohdab.member.repository.MemberRepository; -import com.ohdab.member.service.helper.MemberHelperService; import com.ohdab.member.service.usecase.DeleteTeacherUsecase; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -15,11 +16,10 @@ public class DeleteTeacherService implements DeleteTeacherUsecase { private final MemberRepository memberRepository; - private final MemberHelperService memberHelperService; @Override public void deleteTeacherById(long id) { - Member member = memberHelperService.findExistingMemberById(memberRepository, id); + Member member = findExistingMemberById(memberRepository, id); throwIfInactiveMember(member); member.withdrawal(); } diff --git a/src/main/java/com/ohdab/member/service/JoinService.java b/src/main/java/com/ohdab/member/service/JoinService.java index 28466b09..26d68467 100644 --- a/src/main/java/com/ohdab/member/service/JoinService.java +++ b/src/main/java/com/ohdab/member/service/JoinService.java @@ -1,5 +1,6 @@ package com.ohdab.member.service; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.Authority; import com.ohdab.member.domain.Member; import com.ohdab.member.domain.memberinfo.MemberInfo; @@ -34,7 +35,7 @@ public void join(MemberDtoForJoin.Request joinReqDto) { private void checkDuplicatedMember(String name) { Optional member = memberRepository.findByMemberInfoName(name); if (member.isPresent()) { - throw new DuplicatedMemberException("이미 존재하는 회원입니다."); + throw new DuplicatedMemberException(ExceptionEnum.DUPLICATED_WORKBOOK.getMessage()); } } diff --git a/src/main/java/com/ohdab/member/service/LoginService.java b/src/main/java/com/ohdab/member/service/LoginService.java index fb25e982..e121414d 100644 --- a/src/main/java/com/ohdab/member/service/LoginService.java +++ b/src/main/java/com/ohdab/member/service/LoginService.java @@ -1,10 +1,11 @@ package com.ohdab.member.service; +import static com.ohdab.member.service.helper.MemberHelperService.findExistingMemberByName; + import com.ohdab.core.util.jwt.JwtTokenProvider; import com.ohdab.member.domain.Member; import com.ohdab.member.repository.MemberRepository; import com.ohdab.member.service.dto.MemberDtoForLogin; -import com.ohdab.member.service.helper.MemberHelperService; import com.ohdab.member.service.usecase.LoginUsecase; import lombok.RequiredArgsConstructor; import org.springframework.security.authentication.BadCredentialsException; @@ -22,7 +23,6 @@ public class LoginService implements LoginUsecase { private final MemberRepository memberRepository; - private final MemberHelperService memberHelperService; private final UserDetailsService userDetailsService; private final JwtTokenProvider jwtTokenProvider; private final PasswordEncoder passwordEncoder; @@ -30,9 +30,7 @@ public class LoginService implements LoginUsecase { @Override public MemberDtoForLogin.Response login(MemberDtoForLogin.Request loginReqDto) { UserDetails userDetails = userDetailsService.loadUserByUsername(loginReqDto.getName()); - Member member = - memberHelperService.findExistingMemberByName( - memberRepository, loginReqDto.getName()); + Member member = findExistingMemberByName(memberRepository, loginReqDto.getName()); if (!member.matchPassword( passwordEncoder, loginReqDto.getPassword(), userDetails.getPassword())) { throw new BadCredentialsException("비밀번호가 일치하지 않습니다."); diff --git a/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java b/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java index ba9e2aed..ceccb6fc 100644 --- a/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java +++ b/src/main/java/com/ohdab/member/service/UserDetailServiceImpl.java @@ -1,8 +1,9 @@ package com.ohdab.member.service; +import static com.ohdab.member.service.helper.MemberHelperService.findExistingMemberByName; + import com.ohdab.member.domain.Member; import com.ohdab.member.repository.MemberRepository; -import com.ohdab.member.service.helper.MemberHelperService; import java.util.List; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; @@ -18,11 +19,10 @@ public class UserDetailServiceImpl implements UserDetailsService { private final MemberRepository memberRepository; - private final MemberHelperService memberHelperService; @Override public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException { - Member member = memberHelperService.findExistingMemberByName(memberRepository, name); + Member member = findExistingMemberByName(memberRepository, name); return createUserDetails(member); } diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java index 7531ca45..e0c0c1a4 100644 --- a/src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForAddTeacher.java @@ -1,10 +1,11 @@ package com.ohdab.member.service.dto; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; -@Getter -@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class MemberDtoForAddTeacher { @Builder diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java index d1b9970f..21faeb2c 100644 --- a/src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForGetTeacherList.java @@ -1,11 +1,12 @@ package com.ohdab.member.service.dto; import java.util.List; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; -@Builder -@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class MemberDtoForGetTeacherList { @Builder diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java index c36df827..a14fc777 100644 --- a/src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForJoin.java @@ -1,11 +1,12 @@ package com.ohdab.member.service.dto; import java.util.List; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; -@Getter -@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class MemberDtoForJoin { @Builder diff --git a/src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java b/src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java index 1137d91c..c68bd001 100644 --- a/src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java +++ b/src/main/java/com/ohdab/member/service/dto/MemberDtoForLogin.java @@ -1,10 +1,11 @@ package com.ohdab.member.service.dto; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; -@Getter -@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class MemberDtoForLogin { @Getter diff --git a/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java b/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java index 39127bca..1c027dba 100644 --- a/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java +++ b/src/main/java/com/ohdab/member/service/helper/MemberHelperService.java @@ -1,28 +1,28 @@ package com.ohdab.member.service.helper; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.Member; import com.ohdab.member.exception.NoMemberException; import com.ohdab.member.repository.MemberRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; -@Service -@RequiredArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public final class MemberHelperService { - public Member findExistingMemberByName(MemberRepository memberRepository, String name) { + public static Member findExistingMemberByName(MemberRepository memberRepository, String name) { return memberRepository .findByMemberInfoName(name) - .orElseThrow(() -> new NoMemberException("존재하지 않는 회원입니다.")); + .orElseThrow(() -> new NoMemberException(ExceptionEnum.NO_MEMBER.getMessage())); } - public Member findExistingMemberById(MemberRepository memberRepository, long id) { + public static Member findExistingMemberById(MemberRepository memberRepository, long id) { return memberRepository .findById(id) - .orElseThrow(() -> new NoMemberException("Unknown member with id \"" + id + "\"")); + .orElseThrow(() -> new NoMemberException(ExceptionEnum.NO_MEMBER.getMessage())); } - public boolean checkIfMemberExistByName(MemberRepository memberRepository, String name) { + public static boolean checkIfMemberExistByName(MemberRepository memberRepository, String name) { return memberRepository.existsByMemberInfoName(name); } } diff --git a/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java b/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java index 1881dea4..3b41e32f 100644 --- a/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java +++ b/src/main/java/com/ohdab/mistakenote/domain/MistakeNote.java @@ -1,10 +1,13 @@ package com.ohdab.mistakenote.domain; import com.ohdab.core.baseentity.BaseEntity; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.mistakenote.exception.MistakeNumbersSizeException; import com.ohdab.workbook.domain.Workbook; import com.ohdab.workbook.domain.service.NumberScopeCheckService; import com.ohdab.workbook.domain.workbookid.WorkbookId; +import io.jsonwebtoken.lang.Assert; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,11 +45,24 @@ public class MistakeNote extends BaseEntity { @Builder public MistakeNote( WorkbookId workbookId, StudentId studentId, Map mistakeRecords) { + Assert.notNull(workbookId, ExceptionEnum.IS_NULL.getMessage()); + Assert.notNull(studentId, ExceptionEnum.IS_NULL.getMessage()); this.workbookId = workbookId; this.studentId = studentId; + setMistakeRecords(mistakeRecords); + } + + private void setMistakeRecords(Map mistakeRecords) { + if (mistakeRecords == null) mistakeRecords = new HashMap<>(); this.mistakeRecords = mistakeRecords; } + @Builder + public MistakeNote(WorkbookId workbookId, StudentId studentId) { + this.workbookId = workbookId; + this.studentId = studentId; + } + public void addMistakeNumbers( NumberScopeCheckService numberScopeCheckService, Workbook workbook, @@ -58,7 +74,7 @@ public void addMistakeNumbers( private void checkMistakeNumbersSize(List numbers) { if (numbers.isEmpty() || numbers.size() > 500) { - throw new IllegalArgumentException("틀린 문제 번호는 최소 1개 이상, 500개 이하로 입력할 수 있습니다."); + throw new MistakeNumbersSizeException(ExceptionEnum.MISTAKE_NUMBERS_SIZE.getMessage()); } } diff --git a/src/main/java/com/ohdab/mistakenote/exception/MistakeNumbersSizeException.java b/src/main/java/com/ohdab/mistakenote/exception/MistakeNumbersSizeException.java new file mode 100644 index 00000000..3c04ead4 --- /dev/null +++ b/src/main/java/com/ohdab/mistakenote/exception/MistakeNumbersSizeException.java @@ -0,0 +1,18 @@ +package com.ohdab.mistakenote.exception; + +public class MistakeNumbersSizeException extends RuntimeException { + + public MistakeNumbersSizeException() {} + + public MistakeNumbersSizeException(String message) { + super(message); + } + + public MistakeNumbersSizeException(String message, Throwable cause) { + super(message, cause); + } + + public MistakeNumbersSizeException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java b/src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java index 2bbe5495..9461b54c 100644 --- a/src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java +++ b/src/main/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoService.java @@ -1,5 +1,8 @@ package com.ohdab.mistakenote.service; +import static com.ohdab.mistakenote.service.helper.MistakeNoteHelperService.isNotExistingMember; + +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.student.studentid.StudentId; import com.ohdab.member.exception.NoMemberException; import com.ohdab.member.repository.MemberRepository; @@ -13,7 +16,6 @@ import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto.Response.MistakeNoteInfoDto; -import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; import com.ohdab.mistakenote.service.usecase.GetMistakeNoteInfoUsecase; import com.ohdab.workbook.domain.workbookid.WorkbookId; import java.util.ArrayList; @@ -29,7 +31,6 @@ @Transactional(readOnly = true) public class GetMistakeNoteInfoService implements GetMistakeNoteInfoUsecase { - private final MistakeNoteHelperService mistakeNoteHelperService; private final MistakeNoteRepository mistakeNoteRepository; private final MemberRepository memberRepository; private final MistakeRecordMapper mistakeRecordMapper; @@ -38,14 +39,17 @@ public class GetMistakeNoteInfoService implements GetMistakeNoteInfoUsecase { @Override public GetMistakeNoteInfoOfStudentDto.Response getMistakeNoteInfoOfStudent( long workbookId, long studentId) { - if (mistakeNoteHelperService.isNotExistingMember(memberRepository, studentId)) { - throw new NoMemberException("존재하지 않는 회원입니다."); + if (isNotExistingMember(memberRepository, studentId)) { + throw new NoMemberException(ExceptionEnum.NO_MEMBER.getMessage()); } MistakeNote mistakeNote = mistakeNoteRepository .findByWorkbookIdAndStudentId( new WorkbookId(workbookId), new StudentId(studentId)) - .orElseThrow(() -> new NoMistakeNoteException("존재하지 않는 오답노트입니다.")); + .orElseThrow( + () -> + new NoMistakeNoteException( + ExceptionEnum.NO_MISTAKE_NOTE.getMessage())); return mapToMistakeNoteInfo(mistakeNote); } diff --git a/src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java b/src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java index f5245336..679fd3be 100644 --- a/src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java +++ b/src/main/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesService.java @@ -1,5 +1,6 @@ package com.ohdab.mistakenote.service; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.mistakenote.exception.NoNumbersWrongNTimesException; import com.ohdab.mistakenote.exception.NumberIsOutOfRangeException; import com.ohdab.mistakenote.repository.mapper.MistakeRecordMapper; @@ -28,7 +29,10 @@ public GetNumberWrongNTimesDto.Response getNumberWrongNTimes( Workbook workbook = workbookRepository .findById(getNumberWrongNTimeDto.getWorkbookId()) - .orElseThrow(() -> new NoWorkbookException("존재하지 않는 교재입니다.")); + .orElseThrow( + () -> + new NoWorkbookException( + ExceptionEnum.NO_WORKBOOK.getMessage())); checkNumberIsInRange(getNumberWrongNTimeDto, workbook); List numberWrongNTimes = mistakeRecordMapper.findNumbersWrongNTimes(getNumberWrongNTimeDto); @@ -45,7 +49,8 @@ private void checkNumberIsInRange( int to = getTo(getNumberWrongNTimeDto); if (isNotInRange(from, startingNumber, endingNumber) || isNotInRange(to, startingNumber, endingNumber)) { - throw new NumberIsOutOfRangeException("교재에 존재하지 않는 번호를 요청했습니다."); + throw new NumberIsOutOfRangeException( + ExceptionEnum.NUMBER_IS_OUT_OF_RANGE.getMessage()); } } @@ -71,7 +76,8 @@ private boolean isNotInRange(int target, int startingNumber, int endingNumber) { private String wrongNumbersToString(List numberWrongNTimes) { if (numberWrongNTimes.isEmpty()) { - throw new NoNumbersWrongNTimesException("틀린 문제가 없습니다."); + throw new NoNumbersWrongNTimesException( + ExceptionEnum.NO_NUMBERS_WRONG_N_TIMES.getMessage()); } return numberWrongNTimes.stream().map(String::valueOf).collect(Collectors.joining(",")); } diff --git a/src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java b/src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java index a2d68147..e186ab84 100644 --- a/src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java +++ b/src/main/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoService.java @@ -1,5 +1,8 @@ package com.ohdab.mistakenote.service; +import static com.ohdab.mistakenote.service.helper.MistakeNoteHelperService.isNotExistingMember; + +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.member.domain.student.studentid.StudentId; import com.ohdab.member.exception.NoMemberException; import com.ohdab.member.repository.MemberRepository; @@ -7,7 +10,6 @@ import com.ohdab.mistakenote.exception.NoMistakeNoteException; import com.ohdab.mistakenote.repository.MistakeNoteRepository; import com.ohdab.mistakenote.service.dto.SaveMistakeNoteInfoDto; -import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; import com.ohdab.mistakenote.service.usecase.SaveMistakeNoteInfoUsecase; import com.ohdab.workbook.domain.Workbook; import com.ohdab.workbook.domain.service.NumberScopeCheckService; @@ -23,7 +25,6 @@ @Transactional public class SaveMistakeNoteInfoService implements SaveMistakeNoteInfoUsecase { - private final MistakeNoteHelperService mistakeNoteHelperService; private final NumberScopeCheckService numberScopeCheckService; private final MemberRepository memberRepository; private final MistakeNoteRepository mistakeNoteRepository; @@ -31,20 +32,25 @@ public class SaveMistakeNoteInfoService implements SaveMistakeNoteInfoUsecase { @Override public void saveMistakeNoteInfo(SaveMistakeNoteInfoDto saveMistakeNoteInfoDto) { - if (mistakeNoteHelperService.isNotExistingMember( - memberRepository, saveMistakeNoteInfoDto.getStudentId())) { - throw new NoMemberException("존재하지 않는 회원입니다."); + if (isNotExistingMember(memberRepository, saveMistakeNoteInfoDto.getStudentId())) { + throw new NoMemberException(ExceptionEnum.NO_MEMBER.getMessage()); } MistakeNote mistakeNote = mistakeNoteRepository .findByWorkbookIdAndStudentId( new WorkbookId(saveMistakeNoteInfoDto.getWorkbookId()), new StudentId(saveMistakeNoteInfoDto.getStudentId())) - .orElseThrow(() -> new NoMistakeNoteException("존재하지 않는 오답노트입니다.")); + .orElseThrow( + () -> + new NoMistakeNoteException( + ExceptionEnum.NO_MISTAKE_NOTE.getMessage())); Workbook workbook = workbookRepository .findById(saveMistakeNoteInfoDto.getWorkbookId()) - .orElseThrow(() -> new NoWorkbookException("존재하지 않는 교재입니다.")); + .orElseThrow( + () -> + new NoWorkbookException( + ExceptionEnum.NO_WORKBOOK.getMessage())); mistakeNote.addMistakeNumbers( numberScopeCheckService, workbook, saveMistakeNoteInfoDto.getMistakeNumbers()); } diff --git a/src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java b/src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java index 7c817f7f..a8052491 100644 --- a/src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java +++ b/src/main/java/com/ohdab/mistakenote/service/helper/MistakeNoteHelperService.java @@ -3,14 +3,13 @@ import com.ohdab.member.domain.Member; import com.ohdab.member.repository.MemberRepository; import java.util.Optional; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; -@Service -@RequiredArgsConstructor -public class MistakeNoteHelperService { +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public final class MistakeNoteHelperService { - public boolean isNotExistingMember(MemberRepository memberRepository, long memberId) { + public static boolean isNotExistingMember(MemberRepository memberRepository, long memberId) { Optional memberOpt = memberRepository.findActiveMemberById(memberId); return memberOpt.isEmpty(); } diff --git a/src/main/java/com/ohdab/workbook/domain/Workbook.java b/src/main/java/com/ohdab/workbook/domain/Workbook.java index 37057542..2aa886e4 100644 --- a/src/main/java/com/ohdab/workbook/domain/Workbook.java +++ b/src/main/java/com/ohdab/workbook/domain/Workbook.java @@ -2,7 +2,9 @@ import com.ohdab.classroom.domain.classroomid.ClassroomId; import com.ohdab.core.baseentity.BaseEntity; +import com.ohdab.core.exception.ExceptionEnum; import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import io.jsonwebtoken.lang.Assert; import javax.persistence.*; import lombok.AccessLevel; import lombok.Builder; @@ -35,14 +37,14 @@ public class Workbook extends BaseEntity { @Builder public Workbook(WorkbookInfo workbookInfo, ClassroomId classroomId) { - setWorkbookInfo(workbookInfo); + Assert.notNull(workbookInfo, ExceptionEnum.IS_NULL.getMessage()); + Assert.notNull(classroomId, ExceptionEnum.IS_NULL.getMessage()); + this.workbookInfo = workbookInfo; this.classroomId = classroomId; } - private void setWorkbookInfo(WorkbookInfo workbookInfo) { - if (workbookInfo == null) { - throw new IllegalArgumentException("예외"); - } + public void updateWorkbookInfo(WorkbookInfo workbookInfo) { + Assert.notNull(workbookInfo, ExceptionEnum.IS_NULL.getMessage()); this.workbookInfo = workbookInfo; } } diff --git a/src/main/java/com/ohdab/workbook/domain/workbookInfo/WorkbookInfo.java b/src/main/java/com/ohdab/workbook/domain/workbookInfo/WorkbookInfo.java index ffd777ff..41c0edd8 100644 --- a/src/main/java/com/ohdab/workbook/domain/workbookInfo/WorkbookInfo.java +++ b/src/main/java/com/ohdab/workbook/domain/workbookInfo/WorkbookInfo.java @@ -1,5 +1,8 @@ package com.ohdab.workbook.domain.workbookInfo; +import com.ohdab.core.exception.ExceptionEnum; +import com.ohdab.workbook.exception.InvalidWorkbookNumberRangeException; +import com.ohdab.workbook.exception.WorkbookContentOverflowException; import javax.persistence.Embeddable; import lombok.AccessLevel; import lombok.Builder; @@ -26,18 +29,16 @@ public WorkbookInfo(String name, String description, int startingNumber, int end private void setName(String name) { if (name.length() > 20) { - throw new IllegalStateException( - "Name length cannot exceed 20 : current length \"" + name.length() + "\""); + throw new WorkbookContentOverflowException( + ExceptionEnum.WORKBOOK_CONTENT_OVERFLOW.getMessage()); } this.name = name; } private void setDescription(String description) { if (description != null && description.length() > 30) { - throw new IllegalStateException( - "Description length cannot exceed 30 : current length \"" - + description.length() - + "\""); + throw new WorkbookContentOverflowException( + ExceptionEnum.WORKBOOK_CONTENT_OVERFLOW.getMessage()); } this.description = description; } @@ -47,10 +48,12 @@ private void setRange(int startingNumber, int endingNumber) { || startingNumber > 5000 || endingNumber < 0 || endingNumber > 5000) { - throw new IllegalStateException(""); + throw new InvalidWorkbookNumberRangeException( + ExceptionEnum.INVALID_WORKBOOK_NUMBER_RANGE.getMessage()); } if (startingNumber > endingNumber) { - throw new IllegalStateException(""); + throw new InvalidWorkbookNumberRangeException( + ExceptionEnum.INVALID_WORKBOOK_NUMBER_RANGE.getMessage()); } this.startingNumber = startingNumber; this.endingNumber = endingNumber; diff --git a/src/main/java/com/ohdab/workbook/exception/DuplicatedWorkbookException.java b/src/main/java/com/ohdab/workbook/exception/DuplicatedWorkbookException.java new file mode 100644 index 00000000..f43c2ffe --- /dev/null +++ b/src/main/java/com/ohdab/workbook/exception/DuplicatedWorkbookException.java @@ -0,0 +1,18 @@ +package com.ohdab.workbook.exception; + +public class DuplicatedWorkbookException extends RuntimeException { + + public DuplicatedWorkbookException() {} + + public DuplicatedWorkbookException(String message) { + super(message); + } + + public DuplicatedWorkbookException(String message, Throwable cause) { + super(message, cause); + } + + public DuplicatedWorkbookException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/workbook/exception/InvalidWorkbookNumberRangeException.java b/src/main/java/com/ohdab/workbook/exception/InvalidWorkbookNumberRangeException.java new file mode 100644 index 00000000..af6cb257 --- /dev/null +++ b/src/main/java/com/ohdab/workbook/exception/InvalidWorkbookNumberRangeException.java @@ -0,0 +1,18 @@ +package com.ohdab.workbook.exception; + +public class InvalidWorkbookNumberRangeException extends RuntimeException { + + public InvalidWorkbookNumberRangeException() {} + + public InvalidWorkbookNumberRangeException(String message) { + super(message); + } + + public InvalidWorkbookNumberRangeException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidWorkbookNumberRangeException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/workbook/exception/WorkbookContentOverflowException.java b/src/main/java/com/ohdab/workbook/exception/WorkbookContentOverflowException.java new file mode 100644 index 00000000..6fe5513a --- /dev/null +++ b/src/main/java/com/ohdab/workbook/exception/WorkbookContentOverflowException.java @@ -0,0 +1,18 @@ +package com.ohdab.workbook.exception; + +public class WorkbookContentOverflowException extends RuntimeException { + + public WorkbookContentOverflowException() {} + + public WorkbookContentOverflowException(String message) { + super(message); + } + + public WorkbookContentOverflowException(String message, Throwable cause) { + super(message, cause); + } + + public WorkbookContentOverflowException(Throwable cause) { + super(cause); + } +} diff --git a/src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java b/src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java index cd6ca05f..d33d7bb8 100644 --- a/src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java +++ b/src/main/java/com/ohdab/workbook/repository/WorkbookRepository.java @@ -1,6 +1,13 @@ package com.ohdab.workbook.repository; +import com.ohdab.classroom.domain.classroomid.ClassroomId; import com.ohdab.workbook.domain.Workbook; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -public interface WorkbookRepository extends JpaRepository {} +public interface WorkbookRepository extends JpaRepository { + + List findByClassroomId(ClassroomId id); + + boolean existsByClassroomIdAndWorkbookInfoName(ClassroomId classroomId, String name); +} diff --git a/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java b/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java index af9660aa..79c7f155 100644 --- a/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java +++ b/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java @@ -2,6 +2,9 @@ import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoInfo; import static com.ohdab.classroom.service.dto.ClassroomDetailDto.ClassroomDetailDtoResponse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; @@ -12,12 +15,19 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.ohdab.classroom.controller.request.AddClassroomReq; +import com.ohdab.classroom.controller.request.AddStudentReq; +import com.ohdab.classroom.controller.request.AddWorkbookReq; import com.ohdab.classroom.controller.request.UpdateClassroomReq; +import com.ohdab.classroom.controller.request.UpdateWorkbookInfoReq; +import com.ohdab.classroom.service.dto.AddStudentDto; import com.ohdab.classroom.service.dto.ClassroomDto; +import com.ohdab.classroom.service.dto.ClassroomWorkbookDto; import com.ohdab.classroom.service.usecase.*; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -38,6 +48,11 @@ class ClassroomControllerTest { @MockBean private FindClassroomDetailUsecase findClassroomDetailUsecase; @MockBean private UpdateClassroomInfoUsecase updateClassroomInfoUsecase; @MockBean private DeleteClassroomUsecase deleteClassroomUsecase; + @MockBean private DeleteStudentUsecase deleteStudentUsecase; + @MockBean private GetWorkbookListUsecase getWorkbookListUsecase; + @MockBean private AddWorkbookUsecase addWorkbookUsecase; + @MockBean private UpdateWorkbookInfoUsecase updateWorkbookInfoUsecase; + @MockBean private AddStudentUsecase addStudentUsecase; @Test @WithMockUser @@ -113,7 +128,7 @@ class ClassroomControllerTest { jsonPath("$.classroomInfoList[1].description").value(222), jsonPath("$.classroomInfoList[1].grade").value("high2")) .andDo(print()) - .andDo(createDocument("classrooms?teacherId=")); + .andDo(createDocument("classrooms")); } @Test @@ -204,6 +219,148 @@ class ClassroomControllerTest { .andDo(createDocument("classrooms/expulsion/{classroom-id}")); } + @Test + @WithMockUser + void 학생_삭제() throws Exception { + // given + final String url = "/classrooms/{classroom-id}/expulsion/students/{student-id}"; + + // when + doNothing().when(deleteStudentUsecase).deleteStudent(anyLong(), anyLong()); + + // then + mockMvc.perform(patch(url, 1L, 2L).with(csrf()).contentType(MediaType.APPLICATION_JSON)) + .andExpectAll(status().isOk(), content().contentType(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andDo(createDocument("classrooms/deleteStudent")); + } + + @Test + @WithMockUser + void 반_식별자로_교재_목록_조회() throws Exception { + // given + final String url = "/classrooms/{classroom-id}/workbooks"; + List workbookDtoList = new ArrayList<>(); + ClassroomWorkbookDto.Response workbookDtoRes1 = createWorkbookDto(1L, "교재"); + ClassroomWorkbookDto.Response workbookDtoRes2 = createWorkbookDto(2L, "교재2"); + ClassroomWorkbookDto.Response workbookDtoRes3 = createWorkbookDto(3L, "교재3"); + workbookDtoList.add(workbookDtoRes1); + workbookDtoList.add(workbookDtoRes2); + workbookDtoList.add(workbookDtoRes3); + + // when + when(getWorkbookListUsecase.getWorkbookListByClassroomId(Mockito.anyLong())) + .thenReturn(workbookDtoList); + + // then + mockMvc.perform(get(url, 1L).with(csrf())) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.workbooks[0].id").value(workbookDtoRes1.getId()), + jsonPath("$.workbooks[0].name").value(workbookDtoRes1.getName()), + jsonPath("$.workbooks[0].createdAt") + .value(workbookDtoRes1.getCreatedAt().toLocalDate().toString()), + jsonPath("$.workbooks[1].id").value(workbookDtoRes2.getId()), + jsonPath("$.workbooks[1].name").value(workbookDtoRes2.getName()), + jsonPath("$.workbooks[1].createdAt") + .value(workbookDtoRes2.getCreatedAt().toLocalDate().toString()), + jsonPath("$.workbooks[2].id").value(workbookDtoRes3.getId()), + jsonPath("$.workbooks[2].name").value(workbookDtoRes3.getName()), + jsonPath("$.workbooks[2].createdAt") + .value(workbookDtoRes3.getCreatedAt().toLocalDate().toString())) + .andDo(print()) + .andDo(createDocument("classrooms/{classroom-id}/workbooks")); + } + + @Test + @WithMockUser + void 반_식별자로_반에_교재_추가() throws Exception { + // given + String url = "/classrooms/{classroom-id}/workbooks"; + AddWorkbookReq addWorkbookReq = + AddWorkbookReq.builder() + .name("교재") + .description("교재에 대한 설명입니다.") + .startingNumber(1) + .endingNumber(2000) + .build(); + long classroomId = 1L; + + // when + + // then + mockMvc.perform( + post(url, classroomId) + .with(csrf()) + .content(objectMapper.writeValueAsString(addWorkbookReq)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("해당 반에 교재 및 오답노트가 추가되었습니다.")) + .andDo(print()) + .andDo(createDocument("classrooms/{classroom-id}/addWorkbooks")); + } + + @Test + @WithMockUser + void 교재_식별자로_교재_정보_수정() throws Exception { + // given + String url = "/classrooms/workbooks/info/{workbook-id}"; + UpdateWorkbookInfoReq updateWorkbookInfoReq = + UpdateWorkbookInfoReq.builder() + .name("수정할 교재명") + .description("수정할 교재에 대한 설명입니다.") + .build(); + long workbookId = 1L; + + // when + + // then + mockMvc.perform( + patch(url, workbookId) + .with(csrf()) + .content(objectMapper.writeValueAsString(updateWorkbookInfoReq)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("교재 정보가 수정 되었습니다.")) + .andDo(print()) + .andDo(createDocument("classrooms/workbooks/info/{workbook-id}")); + } + + void 학생_추가() throws Exception { + // given + final String ADD_STUDENT_URL = "/classrooms/{classroom-id}/students/enrollment"; + final AddStudentReq addStudentReq = AddStudentReq.builder().studentName("갑").build(); + + // when + doNothing().when(addStudentUsecase).addStudent(any(AddStudentDto.Request.class)); + + // then + mockMvc.perform( + post(ADD_STUDENT_URL, 1) + .with(csrf()) + .content(objectMapper.writeValueAsString(addStudentReq)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("해당 반에 학생이 추가되었습니다.")) + .andDo(print()) + .andDo(createDocument("classrooms/addStudent")); + } + + private ClassroomWorkbookDto.Response createWorkbookDto(long id, String name) { + return ClassroomWorkbookDto.Response.builder() + .id(id) + .name(name) + .createdAt(LocalDateTime.now()) + .build(); + } + private RestDocumentationResultHandler createDocument(String identifier) { return document( identifier, preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); diff --git a/src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java index d1a77378..dcb85f2a 100644 --- a/src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java +++ b/src/test/java/com/ohdab/classroom/repository/AddClassroomRepositoryTest.java @@ -1,12 +1,13 @@ package com.ohdab.classroom.repository; +import static org.assertj.core.api.Assertions.assertThat; + import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; import com.ohdab.classroom.domain.classroomInfo.Grade; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import java.util.List; import javax.persistence.EntityManager; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -36,13 +37,11 @@ class AddClassroomRepositoryTest { // when classroomRepository.save(classroom); List foundClassrooms = classroomRepository.findAllByTeacherId(teacherId.getId()); + // then - Assertions.assertThat(foundClassrooms.get(0).getTeacher().getId()) - .isEqualTo(teacherId.getId()); - Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getName()).isEqualTo(name); - Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getDescription()) - .isEqualTo(desc); - Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getGrade()) - .isEqualTo(Grade.HIGH_1); + assertThat(foundClassrooms.get(0).getTeacher().getId()).isEqualTo(teacherId.getId()); + assertThat(foundClassrooms.get(0).getClassroomInfo().getName()).isEqualTo(name); + assertThat(foundClassrooms.get(0).getClassroomInfo().getDescription()).isEqualTo(desc); + assertThat(foundClassrooms.get(0).getClassroomInfo().getGrade()).isEqualTo(Grade.HIGH_1); } } diff --git a/src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java index fd599264..fee1988d 100644 --- a/src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java +++ b/src/test/java/com/ohdab/classroom/repository/DeleteClassroomRepositoryTest.java @@ -1,19 +1,20 @@ package com.ohdab.classroom.repository; +import static org.assertj.core.api.Assertions.assertThat; + import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; import com.ohdab.classroom.domain.classroomInfo.Grade; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import java.util.List; import javax.persistence.EntityManager; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @DataJpaTest -public class DeleteClassroomRepositoryTest { +class DeleteClassroomRepositoryTest { @Autowired private ClassroomRepository classroomRepository; @Autowired private EntityManager em; @@ -32,18 +33,17 @@ public class DeleteClassroomRepositoryTest { Classroom classroom = Classroom.builder().classroomInfo(classroomInfo).teacher(teacherId).build(); - classroomRepository.save(classroom); - long classroomId = classroomRepository.findAllByTeacherId(1).get(0).getId(); - em.clear(); - Classroom foundClassroom = classroomRepository.findClassroomById(classroomId); + Classroom savedClassroom = classroomRepository.save(classroom); + // when - classroomRepository.delete(foundClassroom); + classroomRepository.delete(savedClassroom); em.flush(); em.clear(); List classrooms = classroomRepository.findAllByTeacherId(1); + // then - Assertions.assertThat(classrooms.size()).isEqualTo(0); + assertThat(classrooms).isEmpty(); } } diff --git a/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java b/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java index 7d9d6bee..cdcbb974 100644 --- a/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java +++ b/src/test/java/com/ohdab/classroom/repository/FindAllClassroomByTeacherIdRepositoryTestReq.java @@ -1,12 +1,13 @@ package com.ohdab.classroom.repository; +import static org.assertj.core.api.Assertions.assertThat; + import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; import com.ohdab.classroom.domain.classroomInfo.Grade; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import java.util.List; import javax.persistence.EntityManager; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @@ -43,23 +44,21 @@ class FindAllClassroomByTeacherIdRepositoryTestReq { .build()) .build(); classroomRepository.save(classroom2); + em.flush(); + em.clear(); // when List foundClassrooms = classroomRepository.findAllByTeacherId(1L); // then - Assertions.assertThat(foundClassrooms.get(0).getTeacher().getId()).isEqualTo(1L); - Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getName()).isEqualTo("1반"); - Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getDescription()) - .isEqualTo("1반 설명"); - Assertions.assertThat(foundClassrooms.get(0).getClassroomInfo().getGrade()) - .isEqualTo(Grade.HIGH_1); + assertThat(foundClassrooms.get(0).getTeacher().getId()).isEqualTo(1L); + assertThat(foundClassrooms.get(0).getClassroomInfo().getName()).isEqualTo("1반"); + assertThat(foundClassrooms.get(0).getClassroomInfo().getDescription()).isEqualTo("1반 설명"); + assertThat(foundClassrooms.get(0).getClassroomInfo().getGrade()).isEqualTo(Grade.HIGH_1); - Assertions.assertThat(foundClassrooms.get(1).getTeacher().getId()).isEqualTo(1L); - Assertions.assertThat(foundClassrooms.get(1).getClassroomInfo().getName()).isEqualTo("2반"); - Assertions.assertThat(foundClassrooms.get(1).getClassroomInfo().getDescription()) - .isEqualTo("2반 설명"); - Assertions.assertThat(foundClassrooms.get(1).getClassroomInfo().getGrade()) - .isEqualTo(Grade.HIGH_1); + assertThat(foundClassrooms.get(1).getTeacher().getId()).isEqualTo(1L); + assertThat(foundClassrooms.get(1).getClassroomInfo().getName()).isEqualTo("2반"); + assertThat(foundClassrooms.get(1).getClassroomInfo().getDescription()).isEqualTo("2반 설명"); + assertThat(foundClassrooms.get(1).getClassroomInfo().getGrade()).isEqualTo(Grade.HIGH_1); } } diff --git a/src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java index 1e78dbe6..1dc2c042 100644 --- a/src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java +++ b/src/test/java/com/ohdab/classroom/repository/FindClassroomByIdRepositoryTest.java @@ -23,7 +23,7 @@ class FindClassroomByIdRepositoryTest { void 반_상세조회() { // given - Classroom classroom1 = + Classroom classroom = Classroom.builder() .teacher(TeacherId.builder().id(2L).build()) .classroomInfo( @@ -33,12 +33,13 @@ class FindClassroomByIdRepositoryTest { .grade(Grade.HIGH_1) .build()) .build(); - classroom1.addStudent(StudentId.builder().id(3).build()); - classroom1.addWorkbook(WorkbookId.builder().id(4).build()); - classroomRepository.save(classroom1); - long id = classroom1.getId(); + classroom.addStudent(StudentId.builder().id(3).build()); + classroom.addWorkbook(WorkbookId.builder().id(4).build()); + classroomRepository.save(classroom); + long id = classroom.getId(); + // when - Classroom foundClassroom = classroomRepository.findClassroomById(id); + Classroom foundClassroom = classroomRepository.findById(id).get(); // then assertThat(foundClassroom.getId()).isEqualTo(id); diff --git a/src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java b/src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java index e0c1c78f..58397f6e 100644 --- a/src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java +++ b/src/test/java/com/ohdab/classroom/repository/UpdateClassroomRepositoryTest.java @@ -1,18 +1,19 @@ package com.ohdab.classroom.repository; +import static org.assertj.core.api.Assertions.assertThat; + import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; import com.ohdab.classroom.domain.classroomInfo.Grade; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import javax.persistence.EntityManager; -import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @DataJpaTest -public class UpdateClassroomRepositoryTest { +class UpdateClassroomRepositoryTest { @Autowired private ClassroomRepository classroomRepository; @Autowired private EntityManager em; @@ -31,25 +32,17 @@ public class UpdateClassroomRepositoryTest { Classroom classroom = Classroom.builder().classroomInfo(classroomInfo).teacher(teacherId).build(); - classroomRepository.save(classroom); - em.flush(); - em.clear(); - Classroom saveClassroom = classroomRepository.findAllByTeacherId(1).get(0); + Classroom savedClassroom = classroomRepository.save(classroom); - saveClassroom.setClassroomInfo( + // when + savedClassroom.updateClassroomInfo( ClassroomInfo.builder().name("2반").description("22").grade(Grade.HIGH_2).build()); - classroomRepository.save(saveClassroom); em.flush(); em.clear(); - // when - Classroom foundClassrooom = classroomRepository.findClassroomById(saveClassroom.getId()); - // then - Assertions.assertThat(foundClassrooom.getId()).isEqualTo(saveClassroom.getId()); - Assertions.assertThat(foundClassrooom.getClassroomInfo().getName()).isEqualTo("2반"); - Assertions.assertThat(foundClassrooom.getClassroomInfo().getDescription()).isEqualTo("22"); - Assertions.assertThat(foundClassrooom.getClassroomInfo().getGrade()) - .isEqualTo(Grade.HIGH_2); + assertThat(savedClassroom.getClassroomInfo().getName()).isEqualTo("2반"); + assertThat(savedClassroom.getClassroomInfo().getDescription()).isEqualTo("22"); + assertThat(savedClassroom.getClassroomInfo().getGrade()).isEqualTo(Grade.HIGH_2); } } diff --git a/src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java b/src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java index 51c0db03..ef645409 100644 --- a/src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java +++ b/src/test/java/com/ohdab/classroom/service/AddClassroomServiceTest.java @@ -1,6 +1,8 @@ package com.ohdab.classroom.service; import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.when; import com.ohdab.classroom.repository.ClassroomRepository; import com.ohdab.classroom.service.dto.ClassroomDto; @@ -8,7 +10,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; @@ -24,7 +25,7 @@ class AddClassroomServiceTest { @Test @DisplayName("반 정보와 선생님 id를 통해 반을 추가 테스트") - void 반추가() throws Exception { + void 반_추가() throws Exception { // given long id = 1L; String name = "1반"; @@ -41,9 +42,9 @@ class AddClassroomServiceTest { .teacherId(id) .build(); // when - Mockito.when(memberRepository.existsById(Mockito.anyLong())).thenReturn(true); - addClassroomService.addClassroom(classroomReqDto); + when(memberRepository.existsById(anyLong())).thenReturn(true); + // then - assertThatNoException().isThrownBy(() -> System.out.println("success")); + assertThatNoException().isThrownBy(() -> addClassroomService.addClassroom(classroomReqDto)); } } diff --git a/src/test/java/com/ohdab/classroom/service/AddStudentServiceTest.java b/src/test/java/com/ohdab/classroom/service/AddStudentServiceTest.java new file mode 100644 index 00000000..f4c371ed --- /dev/null +++ b/src/test/java/com/ohdab/classroom/service/AddStudentServiceTest.java @@ -0,0 +1,100 @@ +package com.ohdab.classroom.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.classroom.exception.NoClassroomException; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.AddStudentDto; +import com.ohdab.classroom.service.usecase.AddStudentUsecase; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import com.ohdab.member.repository.MemberRepository; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {AddStudentService.class}) +class AddStudentServiceTest { + + @Autowired private AddStudentUsecase addStudentUsecase; + @Autowired private ApplicationEventPublisher publisher; + @MockBean private ClassroomRepository classroomRepository; + @MockBean private MemberRepository memberRepository; + @MockBean private MistakeNoteRepository mistakeNoteRepository; + + @DisplayName("addStudent 메서드는") + @Nested + class AddStudent { + + @DisplayName("해당 반이 존재한다면") + @Nested + class ExistClassroom { + + @DisplayName("회원가입 이벤트 발생, 해당 반 학생 목록에 학생 id를 추가 및 해당 반의 교재에 대한 모든 오답노트를 생성한다.") + @Test + void joinStudentAndAddStudent() { + // given + final AddStudentDto.Request addStudentReq = + AddStudentDto.Request.builder().classroomId(1L).studentName("갑").build(); + + final Classroom classroom = + Classroom.builder() + .teacher(new TeacherId(10L)) + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("설명") + .grade(Grade.HIGH_1) + .build()) + .build(); + + // when + when(classroomRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(classroom)); + when(memberRepository.findByMemberInfoName(anyString())) + .thenReturn(Optional.ofNullable((mock(Member.class)))); + when(mock(Member.class).getId()).thenReturn(20L); + addStudentUsecase.addStudent(addStudentReq); + + // then + assertThat(classroom.getStudents()).hasSize(1); + } + } + + @DisplayName("해당 반이 존재하지 않는다면") + @Nested + class DoesNotExistClassroom { + @DisplayName("NoClassroomException 예외를 던진다.") + @Test + void throwNoClassroomException() { + // given + final AddStudentDto.Request addStudentReq = + AddStudentDto.Request.builder().classroomId(1L).studentName("갑").build(); + + // when + when(classroomRepository.findById(anyLong())).thenReturn(Optional.empty()); + + // then + assertThatThrownBy(() -> addStudentUsecase.addStudent(addStudentReq)) + .isInstanceOf(NoClassroomException.class); + } + } + } +} diff --git a/src/test/java/com/ohdab/classroom/service/AddWorkbookServiceTest.java b/src/test/java/com/ohdab/classroom/service/AddWorkbookServiceTest.java new file mode 100644 index 00000000..7f30c4f5 --- /dev/null +++ b/src/test/java/com/ohdab/classroom/service/AddWorkbookServiceTest.java @@ -0,0 +1,88 @@ +package com.ohdab.classroom.service; + +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomAddWorkbookDto; +import com.ohdab.classroom.service.usecase.AddWorkbookUsecase; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import com.ohdab.mistakenote.repository.MistakeNoteRepository; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {AddWorkbookService.class}) +public class AddWorkbookServiceTest { + + @Autowired private AddWorkbookUsecase addWorkbookUsecase; + @MockBean private WorkbookRepository workbookRepository; + @MockBean private ClassroomRepository classroomRepository; + @MockBean private MistakeNoteRepository mistakeNoteRepository; + + @Test + @DisplayName("교재 추가 성공 테스트") + void 교재_추가_성공() { + // given + long classroomId = 1L; + Classroom classroom = + Classroom.builder() + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("1반 설명입니다") + .grade(Grade.HIGH_1) + .build()) + .teacher(new TeacherId(1L)) + .build(); + long workbookId = 1L; + ClassroomAddWorkbookDto.Request addWorkbookDto = + ClassroomAddWorkbookDto.Request.builder() + .name("교재") + .description("교재 설명입니다.") + .startingNumber(1) + .endingNumber(2000) + .build(); + List studentIdList = new ArrayList<>(); + studentIdList.add(new StudentId(1L)); + studentIdList.add(new StudentId(2L)); + studentIdList.add(new StudentId(3L)); + + // when + when(classroomRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(classroom)); + when(workbookRepository.existsByClassroomIdAndWorkbookInfoName( + Mockito.any(), Mockito.any())) + .thenReturn(false); + when(workbookRepository.save(Mockito.any())).thenReturn(mock(Workbook.class)); + when(mock(Workbook.class).getId()).thenReturn(workbookId); + when(classroomRepository.findStudentsById(Mockito.anyLong())).thenReturn(studentIdList); + + // then + assertThatNoException() + .isThrownBy( + () -> + addWorkbookUsecase.addWorkbookByClassroomId( + classroomId, addWorkbookDto)); + assertThat(classroom.getWorkbooks().size()).isEqualTo(workbookId); + Mockito.verify(mistakeNoteRepository).saveAll(Mockito.any()); + } +} diff --git a/src/test/java/com/ohdab/classroom/service/DeleteStudentServiceTest.java b/src/test/java/com/ohdab/classroom/service/DeleteStudentServiceTest.java new file mode 100644 index 00000000..c4f41d7a --- /dev/null +++ b/src/test/java/com/ohdab/classroom/service/DeleteStudentServiceTest.java @@ -0,0 +1,233 @@ +package com.ohdab.classroom.service; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; + +import com.ohdab.classroom.domain.Classroom; +import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; +import com.ohdab.classroom.domain.classroomInfo.Grade; +import com.ohdab.classroom.exception.NoClassroomException; +import com.ohdab.classroom.exception.NoStudentException; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.DeleteStudentDto; +import com.ohdab.classroom.service.usecase.DeleteStudentUsecase; +import com.ohdab.member.domain.Authority; +import com.ohdab.member.domain.Member; +import com.ohdab.member.domain.MemberStatus; +import com.ohdab.member.domain.memberinfo.MemberInfo; +import com.ohdab.member.domain.student.studentid.StudentId; +import com.ohdab.member.domain.teacher.teacherid.TeacherId; +import com.ohdab.member.exception.AlreadyWithdrawlException; +import com.ohdab.member.repository.MemberRepository; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration( + classes = { + DeleteStudentService.class, + }) +class DeleteStudentServiceTest { + + @Autowired private DeleteStudentUsecase deleteStudentUsecase; + @MockBean private ClassroomRepository classroomRepository; + @MockBean private MemberRepository memberRepository; + + @DisplayName("deleteStudent 메서드는") + @Nested + class deleteStudent { + + @DisplayName("요청받은 교실이 존재하고") + @Nested + class ifClassroomExist { + + @DisplayName("삭제하려는 학생이 정상 회원이라면") + @Nested + class ifActiveStudent { + + @DisplayName("해당 학생을 학생 목록에서 삭제하고 탈퇴처리한다.") + @Test + void removeAndExpulsion() { + // given + final long classroomId = 1L; + final long studentId = 2L; + final DeleteStudentDto.Request requestDto = + DeleteStudentDto.Request.builder() + .classroomId(classroomId) + .studentId(studentId) + .build(); + + final Classroom classroom = + Classroom.builder() + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("설명") + .grade(Grade.HIGH_1) + .build()) + .teacher(new TeacherId(10L)) + .build(); + classroom.addStudent(new StudentId(studentId)); + + final Member student = + Member.builder() + .memberInfo( + MemberInfo.builder().name("값").password("1234").build()) + .authorities(List.of(new Authority("STUDENT"))) + .build(); + + // when + when(classroomRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(classroom)); + when(memberRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(student)); + + // then + assertThatCode(() -> deleteStudentUsecase.deleteStudent(classroomId, studentId)) + .doesNotThrowAnyException(); + assertThat(student.getStatus()).isEqualTo(MemberStatus.INACTIVE); + assertThat(classroom.getStudents()).isEmpty(); + } + } + + @DisplayName("삭제하려는 학생이 교실에 없는 학생이라면") + @Nested + class ifNotInClassroom { + + @DisplayName("NoStudentException 예외를 던진다.") + @Test + void throwNoStudentException() { + // given + final long classroomId = 1L; + final long studentId = 2L; + final DeleteStudentDto.Request requestDto = + DeleteStudentDto.Request.builder() + .classroomId(classroomId) + .studentId(studentId) + .build(); + + final Classroom classroom = + Classroom.builder() + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("설명") + .grade(Grade.HIGH_1) + .build()) + .teacher(new TeacherId(10L)) + .build(); + classroom.addStudent(new StudentId(3L)); + + final Member student = + Member.builder() + .memberInfo( + MemberInfo.builder().name("값").password("1234").build()) + .authorities(List.of(new Authority("STUDENT"))) + .build(); + + // when + when(classroomRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(classroom)); + when(memberRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(student)); + Throwable thrown = + catchException( + () -> + deleteStudentUsecase.deleteStudent( + classroomId, studentId)); + + // then + assertThat(thrown).isInstanceOf(NoStudentException.class); + } + } + + @DisplayName("삭제하려는 학생이 이미 탈퇴하였다면") + @Nested + class ifInActiveStudent { + + @DisplayName("AlreadyWithdrawlException 예외를 던진다.") + @Test + void throwAlreadyWithdrawlException() { + // given + final long classroomId = 1L; + final long studentId = 2L; + final DeleteStudentDto.Request requestDto = + DeleteStudentDto.Request.builder() + .classroomId(classroomId) + .studentId(studentId) + .build(); + + final Classroom classroom = + Classroom.builder() + .classroomInfo( + ClassroomInfo.builder() + .name("1반") + .description("설명") + .grade(Grade.HIGH_1) + .build()) + .teacher(new TeacherId(10L)) + .build(); + classroom.addStudent(new StudentId(studentId)); + + final Member student = + Member.builder() + .memberInfo( + MemberInfo.builder().name("값").password("1234").build()) + .authorities(List.of(new Authority("STUDENT"))) + .build(); + student.withdrawal(); + + // when + when(classroomRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(classroom)); + when(memberRepository.findById(anyLong())) + .thenReturn(Optional.ofNullable(student)); + Throwable thrown = + catchException( + () -> + deleteStudentUsecase.deleteStudent( + classroomId, studentId)); + + // then + assertThat(thrown).isInstanceOf(AlreadyWithdrawlException.class); + } + } + } + + @DisplayName("요청받은 교실이 존재하지 않는다면") + @Nested + class ifClassroomDoesNotExist { + + @DisplayName("NoClassroomException 예외를 던진다.") + @Test + void throwNoClassroomException() { + // given + final long classroomId = 1L; + final long studentId = 2L; + final DeleteStudentDto.Request requestDto = + DeleteStudentDto.Request.builder() + .classroomId(classroomId) + .studentId(studentId) + .build(); + + // when + when(classroomRepository.findById(anyLong())).thenThrow(NoClassroomException.class); + Throwable thrown = + catchException( + () -> deleteStudentUsecase.deleteStudent(classroomId, studentId)); + + // then + assertThat(thrown).isInstanceOf(NoClassroomException.class); + } + } + } +} diff --git a/src/test/java/com/ohdab/classroom/service/GetWorkbookListServiceTest.java b/src/test/java/com/ohdab/classroom/service/GetWorkbookListServiceTest.java new file mode 100644 index 00000000..7e874d9a --- /dev/null +++ b/src/test/java/com/ohdab/classroom/service/GetWorkbookListServiceTest.java @@ -0,0 +1,73 @@ +package com.ohdab.classroom.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.classroom.repository.ClassroomRepository; +import com.ohdab.classroom.service.dto.ClassroomWorkbookDto; +import com.ohdab.classroom.service.usecase.GetWorkbookListUsecase; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {GetWorkbookListService.class}) +class GetWorkbookListServiceTest { + + @Autowired private GetWorkbookListUsecase getWorkbookListUsecase; + @MockBean private ClassroomRepository classroomRepository; + @MockBean private WorkbookRepository workbookRepository; + + @Test + @DisplayName("교재 목록 조회 성공 테스트") + void 교재_목록_조회_성공() { + // given + long classroomId = 1L; + Workbook workbook1 = createWorkbook("교재"); + Workbook workbook2 = createWorkbook("교재2"); + Workbook workbook3 = createWorkbook("교재3"); + List workbookList = new ArrayList<>(); + workbookList.add(workbook1); + workbookList.add(workbook2); + workbookList.add(workbook3); + + // when + when(classroomRepository.existsById(Mockito.anyLong())).thenReturn(true); + when(workbookRepository.findByClassroomId(Mockito.any())).thenReturn(workbookList); + List results = + getWorkbookListUsecase.getWorkbookListByClassroomId(classroomId); + + // then + assertThat(results) + .hasSize(3) + .extracting(w -> w.getName()) + .contains( + workbook1.getWorkbookInfo().getName(), + workbook2.getWorkbookInfo().getName(), + workbook3.getWorkbookInfo().getName()); + } + + private Workbook createWorkbook(String name) { + return Workbook.builder() + .workbookInfo( + WorkbookInfo.builder() + .name(name) + .description(name + "의 설명입니다.") + .startingNumber(1) + .endingNumber(2000) + .build()) + .classroomId(new ClassroomId(1L)) + .build(); + } +} diff --git a/src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java b/src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java index 29a53fb7..57c6cb86 100644 --- a/src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java +++ b/src/test/java/com/ohdab/classroom/service/UpdateClassroomInfoServiceTest.java @@ -1,6 +1,8 @@ package com.ohdab.classroom.service; import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.when; import com.ohdab.classroom.domain.Classroom; import com.ohdab.classroom.domain.classroomInfo.ClassroomInfo; @@ -9,10 +11,10 @@ import com.ohdab.classroom.service.dto.ClassroomUpdateDto; import com.ohdab.member.domain.teacher.teacherid.TeacherId; import com.ohdab.member.repository.MemberRepository; +import java.util.Optional; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; @@ -52,11 +54,11 @@ void updateClassroomInfo() { .build(); // when - Mockito.when(memberRepository.existsById(Mockito.anyLong())).thenReturn(true); - Mockito.when(classroomRepository.findClassroomById(Mockito.anyLong())) - .thenReturn(classroom); - updateClassroomInfoService.updateClassroomInfo(request); + when(memberRepository.existsById(anyLong())).thenReturn(true); + when(classroomRepository.findById(anyLong())).thenReturn(Optional.ofNullable(classroom)); + // then - assertThatNoException().isThrownBy(() -> System.out.println("success")); + assertThatNoException() + .isThrownBy(() -> updateClassroomInfoService.updateClassroomInfo(request)); } } diff --git a/src/test/java/com/ohdab/classroom/service/UpdateWorkbookInfoServiceTest.java b/src/test/java/com/ohdab/classroom/service/UpdateWorkbookInfoServiceTest.java new file mode 100644 index 00000000..ac15c3ad --- /dev/null +++ b/src/test/java/com/ohdab/classroom/service/UpdateWorkbookInfoServiceTest.java @@ -0,0 +1,64 @@ +package com.ohdab.classroom.service; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatNoException; +import static org.mockito.Mockito.when; + +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.classroom.service.dto.ClassroomWorkbookUpdateDto; +import com.ohdab.classroom.service.usecase.UpdateWorkbookInfoUsecase; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import com.ohdab.workbook.repository.WorkbookRepository; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(classes = {UpdateWorkbookInfoService.class}) +public class UpdateWorkbookInfoServiceTest { + + @Autowired private UpdateWorkbookInfoUsecase updateWorkbookInfoUsecase; + @MockBean private WorkbookRepository workbookRepository; + + @Test + @DisplayName("교재 정보 수정 성공 테스트") + void 교재_정보_수정_성공() { + // given + long classroomId = 1L; + long workbookId = 2L; + String name = "수정된 교재명"; + String description = "수정된 교재 정보입니다."; + ClassroomWorkbookUpdateDto.Request updateWorkbookReq = + ClassroomWorkbookUpdateDto.Request.builder() + .id(workbookId) + .name(name) + .description(description) + .build(); + Workbook workbook = + Workbook.builder() + .workbookInfo( + WorkbookInfo.builder() + .name("교재") + .description("교재 정보입니다.") + .startingNumber(1) + .endingNumber(2000) + .build()) + .classroomId(new ClassroomId(classroomId)) + .build(); + + // when + when(workbookRepository.existsById(Mockito.anyLong())).thenReturn(true); + when(workbookRepository.findById(Mockito.anyLong())) + .thenReturn(Optional.ofNullable(workbook)); + + // then + assertThatNoException() + .isThrownBy(() -> updateWorkbookInfoUsecase.updateWorkbookInfo(updateWorkbookReq)); + } +} diff --git a/src/test/java/com/ohdab/core/util/event/handler/StudentAddedHandlerTest.java b/src/test/java/com/ohdab/core/util/event/handler/StudentAddedHandlerTest.java new file mode 100644 index 00000000..8ca8b7a0 --- /dev/null +++ b/src/test/java/com/ohdab/core/util/event/handler/StudentAddedHandlerTest.java @@ -0,0 +1,37 @@ +package com.ohdab.core.util.event.handler; + +import static org.assertj.core.api.Assertions.assertThat; + +import com.ohdab.classroom.event.StudentAddedEvent; +import com.ohdab.classroom.service.dto.AddStudentDto; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.test.context.event.ApplicationEvents; +import org.springframework.test.context.event.RecordApplicationEvents; + +@SpringBootTest +@RecordApplicationEvents +class StudentAddedHandlerTest { + + @Autowired private ApplicationEventPublisher publisher; + @Autowired private ApplicationEvents events; + + @DisplayName("학생 추가 이벤트 발생시 회원가입을 시킨다.") + @Test + void 학생_추가_이벤트_발생시_회원가입() { + // given + final AddStudentDto.Request addStudentReq = + AddStudentDto.Request.builder().classroomId(1L).studentName("갑").build(); + + // when + publisher.publishEvent( + StudentAddedEvent.builder().studentName(addStudentReq.getStudentName()).build()); + + // then + long count = events.stream(StudentAddedEvent.class).count(); + assertThat(count).isEqualTo(1); + } +} diff --git a/src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java b/src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java index ea8752d6..6ddcecbc 100644 --- a/src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java +++ b/src/test/java/com/ohdab/member/repository/MemberRepositoryTest.java @@ -16,7 +16,7 @@ import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; @DataJpaTest -public class MemberRepositoryTest { +class MemberRepositoryTest { @Autowired private MemberRepository memberRepository; @Autowired private EntityManager entityManager; diff --git a/src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java b/src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java index 7c40438a..6849343a 100644 --- a/src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java +++ b/src/test/java/com/ohdab/member/service/AddTeacherServiceTest.java @@ -4,7 +4,6 @@ import com.ohdab.member.repository.MemberRepository; import com.ohdab.member.service.dto.MemberDtoForAddTeacher; -import com.ohdab.member.service.helper.MemberHelperService; import com.ohdab.member.service.usecase.AddTeacherUsecase; import com.ohdab.member.service.usecase.JoinUsecase; import org.junit.jupiter.api.DisplayName; @@ -17,8 +16,8 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = {AddTeacherService.class, MemberHelperService.class}) -public class AddTeacherServiceTest { +@ContextConfiguration(classes = {AddTeacherService.class}) +class AddTeacherServiceTest { @Autowired private AddTeacherUsecase addTeacherUsecase; @MockBean private MemberRepository memberRepository; diff --git a/src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java b/src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java index fff4a4ed..1347b723 100644 --- a/src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java +++ b/src/test/java/com/ohdab/member/service/DeleteTeacherServiceTest.java @@ -23,7 +23,7 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {DeleteTeacherService.class, MemberHelperService.class}) -public class DeleteTeacherServiceTest { +class DeleteTeacherServiceTest { @Autowired private DeleteTeacherUsecase deleteTeacherUsecase; @MockBean private MemberRepository memberRepository; diff --git a/src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java b/src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java index dbc1bea6..c8e8f255 100644 --- a/src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java +++ b/src/test/java/com/ohdab/member/service/GetTeacherListServiceTest.java @@ -22,7 +22,7 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {GetTeacherListService.class}) -public class GetTeacherListServiceTest { +class GetTeacherListServiceTest { @Autowired private GetTeacherListUsecase getTeacherListUsecase; @MockBean private MemberRepository memberRepository; diff --git a/src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java b/src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java index 05f8f8a8..c2c0984e 100644 --- a/src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java +++ b/src/test/java/com/ohdab/mistakenote/repository/MistakeNoteRepositoryTest.java @@ -50,9 +50,10 @@ class MistakeNoteRepositoryTest { // then assertThat(result.getWorkbookId().getId()).isEqualTo(workbookId.getId()); assertThat(result.getStudentId().getId()).isEqualTo(studentId.getId()); - assertThat(result.getMistakeRecords()).containsEntry(1, 2); - assertThat(result.getMistakeRecords()).containsEntry(2, 4); - assertThat(result.getMistakeRecords()).containsEntry(4, 1); + assertThat(result.getMistakeRecords()) + .containsEntry(1, 2) + .containsEntry(2, 4) + .containsEntry(4, 1); } @DisplayName("변경감지를 활용하여 틀린 문제 번호마다 틀린 횟수를 저장한다.") @@ -104,4 +105,31 @@ class MistakeNoteRepositoryTest { .containsEntry(4, 1) .containsEntry(5, 1); } + + @Test + @DisplayName("오답 노트 생성 성공 테스트") + void 오답_노트_생성_성공_테스트() { + // given + MistakeNote mistakeNote = + MistakeNote.builder() + .studentId(new StudentId(1L)) + .workbookId(new WorkbookId(2L)) + .build(); + + // when + mistakeNote = mistakeNoteRepository.save(mistakeNote); + + // then + assertThat(mistakeNote) + .extracting( + m -> m.getId(), + m -> m.getWorkbookId().getId(), + m -> m.getStudentId().getId(), + m -> m.getMistakeRecords().size()) + .containsExactly( + mistakeNote.getId(), + mistakeNote.getWorkbookId().getId(), + mistakeNote.getStudentId().getId(), + mistakeNote.getMistakeRecords().size()); + } } diff --git a/src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java b/src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java index 3b9122c3..4c662826 100644 --- a/src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java +++ b/src/test/java/com/ohdab/mistakenote/repository/mapper/MistakeRecordMapperTest.java @@ -86,7 +86,9 @@ class MistakeRecordMapperTest { // then assertThat(result) - .extracting("wrongNumber", "wrongStudentsCount") + .extracting( + AllMistakeNoteInfoDto::getWrongNumber, + AllMistakeNoteInfoDto::getWrongStudentsCount) .contains(tuple(1, 2)) .contains(tuple(2, 1)) .contains(tuple(3, 2)) diff --git a/src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java b/src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java index 205dd00f..ca0bbb67 100644 --- a/src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java +++ b/src/test/java/com/ohdab/mistakenote/service/GetMistakeNoteInfoServiceTest.java @@ -1,6 +1,8 @@ package com.ohdab.mistakenote.service; +import static com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto.Response.MistakeNoteInfoDto; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.tuple; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; @@ -16,8 +18,7 @@ import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto; import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.AllMistakeNoteInfoDto; import com.ohdab.mistakenote.service.dto.GetAllMistakeNoteInfoDto.Response.StudentInfoDto; -import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto; -import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; +import com.ohdab.mistakenote.service.dto.GetMistakeNoteInfoOfStudentDto.Response; import com.ohdab.mistakenote.service.usecase.GetMistakeNoteInfoUsecase; import com.ohdab.workbook.domain.workbookid.WorkbookId; import java.util.*; @@ -30,11 +31,10 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = {GetMistakeNoteInfoService.class, MistakeNoteHelperService.class}) +@ContextConfiguration(classes = {GetMistakeNoteInfoService.class}) class GetMistakeNoteInfoServiceTest { @Autowired private GetMistakeNoteInfoUsecase getMistakeNoteInfoUsecase; - @Autowired private MistakeNoteHelperService mistakeNoteHelperService; @MockBean private MistakeNoteRepository mistakeNoteRepository; @MockBean private MemberRepository memberRepository; @MockBean private MistakeRecordMapper mistakeRecordMapper; @@ -73,16 +73,15 @@ class GetMistakeNoteInfoServiceTest { when(mistakeNoteRepository.findByWorkbookIdAndStudentId( any(WorkbookId.class), any(StudentId.class))) .thenReturn(Optional.of(mistakeNote)); - GetMistakeNoteInfoOfStudentDto.Response result = + Response result = getMistakeNoteInfoUsecase.getMistakeNoteInfoOfStudent(workbookId, studentId); // then - assertThat(result.getMistakeNoteInfo().get(0).getWrongNumber()).isEqualTo(1); - assertThat(result.getMistakeNoteInfo().get(0).getWrongCount()).isEqualTo(2); - assertThat(result.getMistakeNoteInfo().get(1).getWrongNumber()).isEqualTo(2); - assertThat(result.getMistakeNoteInfo().get(1).getWrongCount()).isEqualTo(4); - assertThat(result.getMistakeNoteInfo().get(2).getWrongNumber()).isEqualTo(4); - assertThat(result.getMistakeNoteInfo().get(2).getWrongCount()).isEqualTo(1); + assertThat(result.getMistakeNoteInfo()) + .extracting(MistakeNoteInfoDto::getWrongNumber, MistakeNoteInfoDto::getWrongCount) + .contains(tuple(1, 2)) + .contains(tuple(2, 4)) + .contains(tuple(4, 1)); } @DisplayName("교재 id를 통해 해당 교재에 대한 모든 학생들의 오답 기록을 조회한다.") @@ -154,18 +153,20 @@ class GetMistakeNoteInfoServiceTest { // then assertThat(result.getAllMistakeNoteInfo()).hasSize(5); - assertThat(result.getStudents()).hasSize(3); - assertThat(result.getAllMistakeNoteInfo()) - .extracting(AllMistakeNoteInfoDto::getWrongNumber) - .contains(1, 2, 3, 4, 5); assertThat(result.getAllMistakeNoteInfo()) - .extracting(AllMistakeNoteInfoDto::getWrongStudentsCount) - .contains(1, 2, 3, 2, 1); - assertThat(result.getStudents()) - .extracting(StudentInfoDto::getStudentId) - .contains(10L, 11L, 12L); + .extracting( + AllMistakeNoteInfoDto::getWrongNumber, + AllMistakeNoteInfoDto::getWrongStudentsCount) + .contains(tuple(1, 1)) + .contains(tuple(2, 2)) + .contains(tuple(3, 3)) + .contains(tuple(4, 2)) + .contains(tuple(5, 1)); + assertThat(result.getStudents()).hasSize(3); assertThat(result.getStudents()) - .extracting(StudentInfoDto::getName) - .contains("갑", "을", "병"); + .extracting(StudentInfoDto::getStudentId, StudentInfoDto::getName) + .contains(tuple(10L, "갑")) + .contains(tuple(11L, "을")) + .contains(tuple(12L, "병")); } } diff --git a/src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java b/src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java index 5455b28b..c6a19ab1 100644 --- a/src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java +++ b/src/test/java/com/ohdab/mistakenote/service/GetNumberWrongNTimesServiceTest.java @@ -82,7 +82,9 @@ void success() { getNumberWrongNTimesUsecase.getNumberWrongNTimes(requestDto); // then - assertThat(result).extracting("wrongNumber").isEqualTo("10,11,12,19,20"); + assertThat(result) + .extracting(GetNumberWrongNTimesDto.Response::getWrongNumber) + .isEqualTo("10,11,12,19,20"); } } diff --git a/src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java b/src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java index a16bd98d..5d270a32 100644 --- a/src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java +++ b/src/test/java/com/ohdab/mistakenote/service/SaveMistakeNoteInfoServiceTest.java @@ -14,7 +14,6 @@ import com.ohdab.mistakenote.domain.MistakeNote; import com.ohdab.mistakenote.repository.MistakeNoteRepository; import com.ohdab.mistakenote.service.dto.SaveMistakeNoteInfoDto; -import com.ohdab.mistakenote.service.helper.MistakeNoteHelperService; import com.ohdab.mistakenote.service.usecase.SaveMistakeNoteInfoUsecase; import com.ohdab.workbook.domain.Workbook; import com.ohdab.workbook.domain.service.NumberScopeCheckService; @@ -31,12 +30,7 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; @ExtendWith(SpringExtension.class) -@ContextConfiguration( - classes = { - SaveMistakeNoteInfoService.class, - MistakeNoteHelperService.class, - NumberScopeCheckService.class - }) +@ContextConfiguration(classes = {SaveMistakeNoteInfoService.class, NumberScopeCheckService.class}) class SaveMistakeNoteInfoServiceTest { @Autowired private SaveMistakeNoteInfoUsecase saveMistakeNoteInfoUsecase; @@ -104,10 +98,11 @@ class SaveMistakeNoteInfoServiceTest { saveMistakeNoteInfoUsecase.saveMistakeNoteInfo(saveMistakeNoteInfoDto); // then - assertThat(mistakeNote.getMistakeRecords()).containsEntry(1, 3); - assertThat(mistakeNote.getMistakeRecords()).containsEntry(2, 5); - assertThat(mistakeNote.getMistakeRecords()).containsEntry(3, 1); - assertThat(mistakeNote.getMistakeRecords()).containsEntry(4, 1); - assertThat(mistakeNote.getMistakeRecords()).containsEntry(5, 1); + assertThat(mistakeNote.getMistakeRecords()) + .containsEntry(1, 3) + .containsEntry(2, 5) + .containsEntry(3, 1) + .containsEntry(4, 1) + .containsEntry(5, 1); } } diff --git a/src/test/java/com/ohdab/workbook/repository/WorkbookRepositoryTest.java b/src/test/java/com/ohdab/workbook/repository/WorkbookRepositoryTest.java new file mode 100644 index 00000000..35d5ac70 --- /dev/null +++ b/src/test/java/com/ohdab/workbook/repository/WorkbookRepositoryTest.java @@ -0,0 +1,176 @@ +package com.ohdab.workbook.repository; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +import com.ohdab.classroom.domain.classroomid.ClassroomId; +import com.ohdab.workbook.domain.Workbook; +import com.ohdab.workbook.domain.workbookInfo.WorkbookInfo; +import java.time.format.DateTimeFormatter; +import java.util.List; +import javax.persistence.EntityManager; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +@DataJpaTest +class WorkbookRepositoryTest { + + @Autowired private WorkbookRepository workbookRepository; + + @Autowired private EntityManager entityManager; + + @Test + @DisplayName("반 식별자로 반에 있는 교재 목록 조회 성공 테스트") + void 반_식별자로_반에_있는_교재_목록_조회_성공() { + // given + long classroomId = 1L; + Workbook workbook1 = createAndSaveWorkbook("교재", classroomId); + Workbook workbook2 = createAndSaveWorkbook("교재2", classroomId); + Workbook workbook3 = createAndSaveWorkbook("교재3", 2L); + + // when + List results = workbookRepository.findByClassroomId(new ClassroomId(classroomId)); + + // then + assertThat(results) + .hasSize(2) + .extracting( + Workbook::getId, + w -> w.getClassroomId().getId(), + w -> w.getWorkbookInfo().getName(), + w -> w.getWorkbookInfo().getDescription(), + w -> w.getWorkbookInfo().getStartingNumber(), + w -> w.getWorkbookInfo().getEndingNumber(), + w -> + w.getCreatedAt() + .format( + DateTimeFormatter.ofPattern( + "uuuu-MM-dd'T'HH:mm:ss"))) + .contains( + tuple( + workbook1.getId(), + workbook1.getClassroomId().getId(), + workbook1.getWorkbookInfo().getName(), + workbook1.getWorkbookInfo().getDescription(), + workbook1.getWorkbookInfo().getStartingNumber(), + workbook1.getWorkbookInfo().getEndingNumber(), + workbook1 + .getCreatedAt() + .format( + DateTimeFormatter.ofPattern( + "uuuu-MM-dd'T'HH:mm:ss"))), + tuple( + workbook2.getId(), + workbook2.getClassroomId().getId(), + workbook2.getWorkbookInfo().getName(), + workbook2.getWorkbookInfo().getDescription(), + workbook2.getWorkbookInfo().getStartingNumber(), + workbook2.getWorkbookInfo().getEndingNumber(), + workbook2 + .getCreatedAt() + .format( + DateTimeFormatter.ofPattern( + "uuuu-MM-dd'T'HH:mm:ss")))); + } + + @Test + @DisplayName("교재 저장 성공 테스트") + void 교재_저장_성공() { + // given + Workbook workbook = createAndSaveWorkbook("교재", 1L); + + // when + workbook = workbookRepository.save(workbook); + Workbook result = workbookRepository.findById(workbook.getId()).get(); + + // then + assertThat(result) + .extracting( + Workbook::getId, + w -> w.getWorkbookInfo().getName(), + w -> w.getWorkbookInfo().getDescription(), + w -> w.getWorkbookInfo().getStartingNumber(), + w -> w.getWorkbookInfo().getEndingNumber(), + w -> w.getClassroomId().getId()) + .containsExactly( + workbook.getId(), + workbook.getWorkbookInfo().getName(), + workbook.getWorkbookInfo().getDescription(), + workbook.getWorkbookInfo().getStartingNumber(), + workbook.getWorkbookInfo().getEndingNumber(), + workbook.getClassroomId().getId()); + } + + @Test + @DisplayName("반 식별자와 교재 이름으로 교재 존재 여부 확인 성공 테스트") + void 반_식별자와_교재_이름으로_교재_존재_여부_확인_성공() { + // given + long classroomId = 1L; + String name = "교재"; + Workbook workbook = createAndSaveWorkbook(name, classroomId); + + // when + workbook = workbookRepository.save(workbook); + boolean result = + workbookRepository.existsByClassroomIdAndWorkbookInfoName( + new ClassroomId(classroomId), name); + + // then + assertThat(result).isTrue(); + } + + @Test + @DisplayName("교재 정보 수정 성공 테스트") + void 교재_정보_수정_성공() { + // given + Workbook workbook = createAndSaveWorkbook("교재", 1L); + String name = "수정 교재명"; + String description = "수정된 교재 정보입니다."; + + // when + workbook = workbookRepository.save(workbook); + workbook.updateWorkbookInfo( + WorkbookInfo.builder() + .name(name) + .description(description) + .startingNumber(workbook.getWorkbookInfo().getStartingNumber()) + .endingNumber(workbook.getWorkbookInfo().getEndingNumber()) + .build()); + entityManager.flush(); + entityManager.clear(); + Workbook result = workbookRepository.findById(workbook.getId()).get(); + + // then + assertThat(result) + .extracting( + Workbook::getId, + w -> w.getWorkbookInfo().getName(), + w -> w.getWorkbookInfo().getDescription(), + w -> w.getWorkbookInfo().getStartingNumber(), + w -> w.getWorkbookInfo().getEndingNumber(), + w -> w.getClassroomId().getId()) + .containsExactly( + workbook.getId(), + name, + description, + workbook.getWorkbookInfo().getStartingNumber(), + workbook.getWorkbookInfo().getEndingNumber(), + workbook.getClassroomId().getId()); + } + + private Workbook createAndSaveWorkbook(String name, long classroomId) { + return workbookRepository.save( + Workbook.builder() + .workbookInfo( + WorkbookInfo.builder() + .name(name) + .description(name + "의 설명입니다.") + .startingNumber(1) + .endingNumber(2000) + .build()) + .classroomId(new ClassroomId(classroomId)) + .build()); + } +} From 59c47d2ceafcdea36ce50be38aea54677b4f01fe Mon Sep 17 00:00:00 2001 From: simhani1 Date: Tue, 15 Aug 2023 21:29:17 +0900 Subject: [PATCH 5/8] =?UTF-8?q?test:=20controller=20=EB=8B=A8=EC=9C=84=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controller/MemberControllerTest.java | 201 ------------------ .../controller/MemberControllerTest.java | 31 ++- 2 files changed, 24 insertions(+), 208 deletions(-) delete mode 100644 src/test/java/com/ohdab/member/Controller/MemberControllerTest.java diff --git a/src/test/java/com/ohdab/member/Controller/MemberControllerTest.java b/src/test/java/com/ohdab/member/Controller/MemberControllerTest.java deleted file mode 100644 index 1d650359..00000000 --- a/src/test/java/com/ohdab/member/Controller/MemberControllerTest.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.ohdab.member.Controller; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; -import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.patch; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.ohdab.member.controller.MemberController; -import com.ohdab.member.controller.request.AddTeacherReq; -import com.ohdab.member.controller.request.JoinReq; -import com.ohdab.member.controller.request.LoginReq; -import com.ohdab.member.controller.response.JoinRes; -import com.ohdab.member.controller.response.LoginRes; -import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; -import com.ohdab.member.service.dto.MemberDtoForLogin; -import com.ohdab.member.service.usecase.AddTeacherUsecase; -import com.ohdab.member.service.usecase.DeleteTeacherUsecase; -import com.ohdab.member.service.usecase.GetTeacherListUsecase; -import com.ohdab.member.service.usecase.JoinUsecase; -import com.ohdab.member.service.usecase.LoginUsecase; -import java.util.ArrayList; -import java.util.List; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.http.MediaType; -import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.test.web.servlet.MockMvc; - -@AutoConfigureRestDocs -@WebMvcTest(controllers = MemberController.class) -class MemberControllerTest { - - @Autowired private MockMvc mockMvc; - @Autowired private ObjectMapper objectMapper; - @MockBean private JoinUsecase joinUsecase; - @MockBean private LoginUsecase loginUsecase; - @MockBean private GetTeacherListUsecase getTeacherListUsecase; - @MockBean private AddTeacherUsecase addTeacherUsecase; - @MockBean private DeleteTeacherUsecase deleteTeacherUsecase; - - @Test - @WithMockUser - void 회원가입() throws Exception { - // given - final String JOIN_URL = "/members/join"; - final JoinReq joinReq = - JoinReq.builder().name("홍길동").password("1234").role(List.of("STUDENT")).build(); - final JoinRes joinRes = JoinRes.builder().message("회원가입이 완료되었습니다.").build(); - - // when - - // then - mockMvc.perform( - post(JOIN_URL) - .with(csrf()) - .content(objectMapper.writeValueAsString(joinReq)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpectAll( - status().isOk(), - content().contentType(MediaType.APPLICATION_JSON), - jsonPath("$.message").value(joinRes.getMessage())) - .andDo(print()) - .andDo(createDocument("members/join")); - } - - @Test - @WithMockUser - void 로그인() throws Exception { - // given - final String LOGIN_URL = "/members/login"; - final LoginReq loginReq = LoginReq.builder().name("홍길동").password("1234").build(); - final LoginRes loginRes = - LoginRes.builder() - .memberId(1L) - .message("로그인에 성공하였습니다.") - .jwtToken("jwt-token") - .build(); - final MemberDtoForLogin.Response loginResDto = - MemberDtoForLogin.Response.builder().memberId(1L).jwtToken("jwt-token").build(); - - // when - when(loginUsecase.login(any())).thenReturn(loginResDto); - - // then - mockMvc.perform( - post(LOGIN_URL) - .with(csrf()) - .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(loginReq))) - .andExpectAll( - status().isOk(), - content().contentType(MediaType.APPLICATION_JSON), - jsonPath("$.message").value(loginRes.getMessage()), - jsonPath("$.memberId").value(loginRes.getMemberId()), - jsonPath("$.jwtToken").value(loginRes.getJwtToken())) - .andDo(print()) - .andDo(createDocument("members/login")); - } - - @Test - @WithMockUser - void 선생님_목록_조회() throws Exception { - // given - final String url = "/members/teachers"; - - List responseList = new ArrayList<>(); - - responseList.add(createTeacher(1L, "선생님")); - responseList.add(createTeacher(2L, "선생님2")); - responseList.add(createTeacher(3L, "선생님3")); - - // when - when(getTeacherListUsecase.getTeacherList()).thenReturn(responseList); - - // then - mockMvc.perform(get(url).with(csrf())) - .andExpectAll( - status().isOk(), - content().contentType(MediaType.APPLICATION_JSON), - jsonPath("$.teachers[0].id").value(1), - jsonPath("$.teachers[0].name").value("선생님"), - jsonPath("$.teachers[0].authorities[0]").value("TEACHER"), - jsonPath("$.teachers[0].status").value("ACTIVE"), - jsonPath("$.teachers[1].id").value(2), - jsonPath("$.teachers[1].name").value("선생님2"), - jsonPath("$.teachers[1].authorities[0]").value("TEACHER"), - jsonPath("$.teachers[1].status").value("ACTIVE"), - jsonPath("$.teachers[2].id").value(3), - jsonPath("$.teachers[2].name").value("선생님3"), - jsonPath("$.teachers[2].authorities[0]").value("TEACHER"), - jsonPath("$.teachers[2].status").value("ACTIVE")) - .andDo(print()) - .andDo(createDocument("members/teachers")); - } - - private MemberDtoForGetTeacherList.Response createTeacher(long id, String name) { - return MemberDtoForGetTeacherList.Response.builder() - .id(id) - .name(name) - .authorities(List.of("TEACHER")) - .status("ACTIVE") - .build(); - } - - @Test - @WithMockUser - void 선생님_추가() throws Exception { - // given - final String url = "/members/teachers/enrollment"; - final AddTeacherReq addTeacherReq = AddTeacherReq.builder().name("선생님").build(); - - // when - - // then - mockMvc.perform( - post(url) - .with(csrf()) - .content(objectMapper.writeValueAsString(addTeacherReq)) - .contentType(MediaType.APPLICATION_JSON)) - .andExpectAll( - status().isOk(), - content().contentType(MediaType.APPLICATION_JSON), - jsonPath("$.message").value("선생님 추가 및 회원가입에 성공하였습니다.")) - .andDo(print()) - .andDo(createDocument("members/teachers/enrollment")); - } - - @Test - @WithMockUser - void 선생님_삭제() throws Exception { - // given - final String url = "/members/teachers/expulsion/{teacher-id}"; - - // when - - // then - mockMvc.perform(patch(url, 1).with(csrf())) - .andExpectAll( - status().isOk(), - content().contentType(MediaType.APPLICATION_JSON), - jsonPath("$.message").value("선생님 삭제 및 탈퇴에 성공하였습니다.")) - .andDo(print()) - .andDo(createDocument("members/teachers/expulsion/{teacher-id}")); - } - - private RestDocumentationResultHandler createDocument(String identifier) { - return document( - identifier, preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())); - } -} diff --git a/src/test/java/com/ohdab/member/controller/MemberControllerTest.java b/src/test/java/com/ohdab/member/controller/MemberControllerTest.java index 1d650359..0a45c917 100644 --- a/src/test/java/com/ohdab/member/controller/MemberControllerTest.java +++ b/src/test/java/com/ohdab/member/controller/MemberControllerTest.java @@ -1,4 +1,4 @@ -package com.ohdab.member.Controller; +package com.ohdab.member.controller; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; @@ -12,7 +12,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import com.fasterxml.jackson.databind.ObjectMapper; -import com.ohdab.member.controller.MemberController; import com.ohdab.member.controller.request.AddTeacherReq; import com.ohdab.member.controller.request.JoinReq; import com.ohdab.member.controller.request.LoginReq; @@ -20,11 +19,7 @@ import com.ohdab.member.controller.response.LoginRes; import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; import com.ohdab.member.service.dto.MemberDtoForLogin; -import com.ohdab.member.service.usecase.AddTeacherUsecase; -import com.ohdab.member.service.usecase.DeleteTeacherUsecase; -import com.ohdab.member.service.usecase.GetTeacherListUsecase; -import com.ohdab.member.service.usecase.JoinUsecase; -import com.ohdab.member.service.usecase.LoginUsecase; +import com.ohdab.member.service.usecase.*; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.Test; @@ -48,6 +43,7 @@ class MemberControllerTest { @MockBean private GetTeacherListUsecase getTeacherListUsecase; @MockBean private AddTeacherUsecase addTeacherUsecase; @MockBean private DeleteTeacherUsecase deleteTeacherUsecase; + @MockBean private WithdrawlUsecase withdrawlUsecase; @Test @WithMockUser @@ -153,6 +149,27 @@ private MemberDtoForGetTeacherList.Response createTeacher(long id, String name) .build(); } + @Test + @WithMockUser + void 회원탈퇴() throws Exception { + // given + final String WITHDRAWL_URL = "/members/withdrawl/{member-id}"; + + // when + + // then + mockMvc.perform( + patch(WITHDRAWL_URL, 1) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpectAll( + status().isOk(), + content().contentType(MediaType.APPLICATION_JSON), + jsonPath("$.message").value("탈퇴되었습니다.")) + .andDo(print()) + .andDo(createDocument("members/withdrawl")); + } + @Test @WithMockUser void 선생님_추가() throws Exception { From 923feb719126e35d89c14cdc2e7a299d243f8281 Mon Sep 17 00:00:00 2001 From: simhani1 Date: Tue, 15 Aug 2023 21:29:32 +0900 Subject: [PATCH 6/8] =?UTF-8?q?docs:=20REST=20docs=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/ohdab.adoc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/docs/asciidoc/ohdab.adoc b/src/docs/asciidoc/ohdab.adoc index 6966c2b1..68eae2e8 100644 --- a/src/docs/asciidoc/ohdab.adoc +++ b/src/docs/asciidoc/ohdab.adoc @@ -17,6 +17,16 @@ include::{snippets}/members/join/http-request.adoc[] include::{snippets}/members/join/http-response.adoc[] +=== 회원탈퇴 + +==== Request + +include::{snippets}/members/withdrawl/http-request.adoc[] + +==== Response + +include::{snippets}/members/withdrawl/http-response.adoc[] + === 로그인 ==== Request From bef707d83e4d3ac2d719a9eed1ddb7c03bbff915 Mon Sep 17 00:00:00 2001 From: simhani1 Date: Tue, 15 Aug 2023 21:29:44 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20controller=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ohdab/member/controller/MemberController.java | 8 +++++--- .../member/controller/mapper/MemberWebMapper.java | 10 +++++----- .../member/controller/response/WithdrawlRes.java | 11 +++++++++++ .../ohdab/member/service/WithdrawlService.java | 15 +++++++++++++++ .../member/service/usecase/WithdrawlUsecase.java | 6 ++++++ 5 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/ohdab/member/controller/response/WithdrawlRes.java create mode 100644 src/main/java/com/ohdab/member/service/WithdrawlService.java create mode 100644 src/main/java/com/ohdab/member/service/usecase/WithdrawlUsecase.java diff --git a/src/main/java/com/ohdab/member/controller/MemberController.java b/src/main/java/com/ohdab/member/controller/MemberController.java index 27ac4b54..dfd642b0 100644 --- a/src/main/java/com/ohdab/member/controller/MemberController.java +++ b/src/main/java/com/ohdab/member/controller/MemberController.java @@ -25,6 +25,7 @@ public class MemberController { private final GetTeacherListUsecase getTeacherListUsecase; private final AddTeacherUsecase addTeacherUsecase; private final DeleteTeacherUsecase deleteTeacherUsecase; + private final WithdrawlUsecase withdrawlUsecase; @PostMapping("/join") public ResponseEntity join(@Valid @RequestBody JoinReq joinReq) { @@ -39,9 +40,10 @@ public ResponseEntity login(@Valid @RequestBody LoginReq loginReq) { return ResponseEntity.ok(MemberWebMapper.toLoginRes(loginResDto)); } - @GetMapping("/test") - public String adminAndTokenTest() { - return "hohoho"; + @PatchMapping("/withdrawl/{member-id}") + public ResponseEntity withdrawl(@PathVariable(name = "member-id") long memberId) { + withdrawlUsecase.withdrawl(memberId); + return ResponseEntity.ok(MemberWebMapper.createWithdrawlRes()); } @GetMapping("/teachers") diff --git a/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java b/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java index 3097a5d7..4829ad56 100644 --- a/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java +++ b/src/main/java/com/ohdab/member/controller/mapper/MemberWebMapper.java @@ -3,11 +3,7 @@ import com.ohdab.member.controller.request.AddTeacherReq; import com.ohdab.member.controller.request.JoinReq; import com.ohdab.member.controller.request.LoginReq; -import com.ohdab.member.controller.response.AddTeacherRes; -import com.ohdab.member.controller.response.DeleteTeacherRes; -import com.ohdab.member.controller.response.GetTeacherListRes; -import com.ohdab.member.controller.response.JoinRes; -import com.ohdab.member.controller.response.LoginRes; +import com.ohdab.member.controller.response.*; import com.ohdab.member.service.dto.MemberDtoForAddTeacher; import com.ohdab.member.service.dto.MemberDtoForGetTeacherList; import com.ohdab.member.service.dto.MemberDtoForJoin; @@ -76,4 +72,8 @@ public static AddTeacherRes createAddTeacherRes() { public static DeleteTeacherRes createDeleteTeacherRes() { return DeleteTeacherRes.builder().message("선생님 삭제 및 탈퇴에 성공하였습니다.").build(); } + + public static WithdrawlRes createWithdrawlRes() { + return WithdrawlRes.builder().message("탈퇴되었습니다.").build(); + } } diff --git a/src/main/java/com/ohdab/member/controller/response/WithdrawlRes.java b/src/main/java/com/ohdab/member/controller/response/WithdrawlRes.java new file mode 100644 index 00000000..3f210609 --- /dev/null +++ b/src/main/java/com/ohdab/member/controller/response/WithdrawlRes.java @@ -0,0 +1,11 @@ +package com.ohdab.member.controller.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class WithdrawlRes { + + private String message; +} diff --git a/src/main/java/com/ohdab/member/service/WithdrawlService.java b/src/main/java/com/ohdab/member/service/WithdrawlService.java new file mode 100644 index 00000000..eb8df379 --- /dev/null +++ b/src/main/java/com/ohdab/member/service/WithdrawlService.java @@ -0,0 +1,15 @@ +package com.ohdab.member.service; + +import com.ohdab.member.service.usecase.WithdrawlUsecase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional +public class WithdrawlService implements WithdrawlUsecase { + + @Override + public void withdrawl(long memberId) {} +} diff --git a/src/main/java/com/ohdab/member/service/usecase/WithdrawlUsecase.java b/src/main/java/com/ohdab/member/service/usecase/WithdrawlUsecase.java new file mode 100644 index 00000000..d8aecbe5 --- /dev/null +++ b/src/main/java/com/ohdab/member/service/usecase/WithdrawlUsecase.java @@ -0,0 +1,6 @@ +package com.ohdab.member.service.usecase; + +public interface WithdrawlUsecase { + + void withdrawl(long memberId); +} From 338e0eb63a5a9bac74fcc73a3628b0506fbf0ec3 Mon Sep 17 00:00:00 2001 From: simhani1 Date: Tue, 15 Aug 2023 21:56:55 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20REST=20docs=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/ohdab.adoc | 2 -- .../classroom/controller/ClassroomControllerTest.java | 8 +++----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/docs/asciidoc/ohdab.adoc b/src/docs/asciidoc/ohdab.adoc index 68eae2e8..f474782e 100644 --- a/src/docs/asciidoc/ohdab.adoc +++ b/src/docs/asciidoc/ohdab.adoc @@ -191,8 +191,6 @@ include::{snippets}/classrooms/{classroom-id}/workbooks/http-request.adoc[] include::{snippets}/classrooms/{classroom-id}/workbooks/http-response.adoc[] -======= - === 교재 추가 ==== Request diff --git a/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java b/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java index 79c7f155..34ff84f6 100644 --- a/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java +++ b/src/test/java/com/ohdab/classroom/controller/ClassroomControllerTest.java @@ -14,11 +14,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import com.fasterxml.jackson.databind.ObjectMapper; -import com.ohdab.classroom.controller.request.AddClassroomReq; -import com.ohdab.classroom.controller.request.AddStudentReq; -import com.ohdab.classroom.controller.request.AddWorkbookReq; -import com.ohdab.classroom.controller.request.UpdateClassroomReq; -import com.ohdab.classroom.controller.request.UpdateWorkbookInfoReq; +import com.ohdab.classroom.controller.request.*; import com.ohdab.classroom.service.dto.AddStudentDto; import com.ohdab.classroom.service.dto.ClassroomDto; import com.ohdab.classroom.service.dto.ClassroomWorkbookDto; @@ -331,6 +327,8 @@ class ClassroomControllerTest { .andDo(createDocument("classrooms/workbooks/info/{workbook-id}")); } + @Test + @WithMockUser void 학생_추가() throws Exception { // given final String ADD_STUDENT_URL = "/classrooms/{classroom-id}/students/enrollment";