diff --git a/build.gradle b/build.gradle index 47ffe8e..bfd2e5c 100644 --- a/build.gradle +++ b/build.gradle @@ -53,6 +53,8 @@ dependencies { compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2:2.2.224' diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceController.java b/src/main/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceController.java index f558a95..dafd25f 100644 --- a/src/main/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceController.java +++ b/src/main/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceController.java @@ -7,12 +7,10 @@ import gdsc.konkuk.platformcore.application.attendance.exceptions.QrInvalidException; import gdsc.konkuk.platformcore.application.event.EventService; import gdsc.konkuk.platformcore.application.event.dtos.EventWithAttendance; -import gdsc.konkuk.platformcore.controller.attendance.dtos.AttendSuccessResponse; import gdsc.konkuk.platformcore.controller.attendance.dtos.AttendanceRegisterRequest; import gdsc.konkuk.platformcore.controller.attendance.dtos.AttendanceResponse; import gdsc.konkuk.platformcore.application.attendance.dtos.AttendanceStatus; import gdsc.konkuk.platformcore.domain.attendance.entity.Attendance; -import gdsc.konkuk.platformcore.domain.attendance.entity.Participant; import gdsc.konkuk.platformcore.global.responses.SuccessResponse; import jakarta.validation.Valid; import java.time.LocalDate; @@ -54,8 +52,8 @@ public ResponseEntity attend( @PathVariable Long attendanceId, @RequestParam String qrUuid, @AuthenticationPrincipal OidcUser oidcUser) { - Participant participant = attendanceService.attend(oidcUser.getEmail(), attendanceId, qrUuid); - return ResponseEntity.ok(SuccessResponse.of(AttendSuccessResponse.from(participant, attendanceId))); + attendanceService.attend(oidcUser.getEmail(), attendanceId, qrUuid); + return ResponseEntity.ok(SuccessResponse.messageOnly()); } @PostMapping() diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/attendance/dtos/AttendSuccessResponse.java b/src/main/java/gdsc/konkuk/platformcore/controller/attendance/dtos/AttendSuccessResponse.java deleted file mode 100644 index 43551c8..0000000 --- a/src/main/java/gdsc/konkuk/platformcore/controller/attendance/dtos/AttendSuccessResponse.java +++ /dev/null @@ -1,34 +0,0 @@ -package gdsc.konkuk.platformcore.controller.attendance.dtos; - -import gdsc.konkuk.platformcore.domain.attendance.entity.Participant; -import lombok.Builder; -import lombok.Getter; -import lombok.Setter; - - -@Getter -@Setter -public class AttendSuccessResponse { - private Long id; - private Long memberId; - private Long attendanceId; - private boolean isAttended; - - @Builder - private AttendSuccessResponse(Long id, Long memberId, Long attendanceId, boolean isAttended) { - this.id = id; - this.memberId =memberId; - this.attendanceId =attendanceId; - this.isAttended = isAttended; - } - - public static AttendSuccessResponse from(Participant participant, Long attendanceId) { - return AttendSuccessResponse.builder() - .id(participant.getId()) - .memberId(participant.getMemberId()) - .attendanceId(attendanceId) - .isAttended(participant.isAttended()) - .build(); - } -} - diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/email/EmailController.java b/src/main/java/gdsc/konkuk/platformcore/controller/email/EmailController.java index dbb5f3a..67b8774 100644 --- a/src/main/java/gdsc/konkuk/platformcore/controller/email/EmailController.java +++ b/src/main/java/gdsc/konkuk/platformcore/controller/email/EmailController.java @@ -3,7 +3,7 @@ import gdsc.konkuk.platformcore.application.email.EmailTaskFacade; import gdsc.konkuk.platformcore.application.email.EmailService; import gdsc.konkuk.platformcore.controller.email.dtos.EmailSendRequest; -import gdsc.konkuk.platformcore.controller.email.dtos.EmailTaskDetailsResponse; +import gdsc.konkuk.platformcore.controller.email.dtos.EmailTaskDetailResponse; import gdsc.konkuk.platformcore.controller.email.dtos.EmailTaskListResponse; import gdsc.konkuk.platformcore.controller.email.mapper.EmailTaskMapper; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; @@ -37,7 +37,7 @@ public ResponseEntity getAllEmailTask() { @GetMapping("/{taskId}") public ResponseEntity getEmailTask(@PathVariable Long taskId) { - EmailTaskDetailsResponse emailTask = EmailTaskMapper.mapToEmailTaskDetailsResponse(emailService.getTaskDetails(taskId)); + EmailTaskDetailResponse emailTask = EmailTaskMapper.mapToEmailTaskDetailsResponse(emailService.getTaskDetails(taskId)); return ResponseEntity.ok(SuccessResponse.of(emailTask)); } diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailSendRequest.java b/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailSendRequest.java index 28d16ea..4f2cb80 100644 --- a/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailSendRequest.java +++ b/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailSendRequest.java @@ -1,6 +1,6 @@ package gdsc.konkuk.platformcore.controller.email.dtos; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver; import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; @@ -34,17 +34,17 @@ public EmailSendRequest(String subject, String content, Set r } public static EmailTask toEntity(EmailSendRequest request) { - EmailDetails details = new EmailDetails(request.getSubject(), request.getContent()); + EmailDetail details = new EmailDetail(request.getSubject(), request.getContent()); EmailReceivers receivers = new EmailReceivers(request.toEmailReceivers()); return EmailTask.builder() - .emailDetails(details) + .emailDetail(details) .receivers(receivers) .sendAt(request.getSendAt()) .build(); } - public EmailDetails toEmailDetails() { - return new EmailDetails(subject, content); + public EmailDetail toEmailDetails() { + return new EmailDetail(subject, content); } public Set toEmailReceivers() { diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailTaskDetailsResponse.java b/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailTaskDetailResponse.java similarity index 65% rename from src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailTaskDetailsResponse.java rename to src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailTaskDetailResponse.java index 36ab312..7072eca 100644 --- a/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailTaskDetailsResponse.java +++ b/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/EmailTaskDetailResponse.java @@ -1,6 +1,6 @@ package gdsc.konkuk.platformcore.controller.email.dtos; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; import java.time.LocalDateTime; import java.util.List; @@ -8,16 +8,16 @@ import lombok.Getter; @Getter -public class EmailTaskDetailsResponse { +public class EmailTaskDetailResponse { private final String subject; private final String content; private final List receiverInfos; private final LocalDateTime sendAt; @Builder - public EmailTaskDetailsResponse(EmailDetails emailDetails, EmailReceivers emailReceivers, LocalDateTime sendAt) { - this.subject = emailDetails.getSubject(); - this.content = emailDetails.getContent(); + public EmailTaskDetailResponse(EmailDetail emailDetail, EmailReceivers emailReceivers, LocalDateTime sendAt) { + this.subject = emailDetail.getSubject(); + this.content = emailDetail.getContent(); this.receiverInfos = emailReceivers .getReceivers() .stream() diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/SimpleEmailTaskResponse.java b/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/SimpleEmailTaskResponse.java index d18ddb7..dddbe62 100644 --- a/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/SimpleEmailTaskResponse.java +++ b/src/main/java/gdsc/konkuk/platformcore/controller/email/dtos/SimpleEmailTaskResponse.java @@ -1,6 +1,6 @@ package gdsc.konkuk.platformcore.controller.email.dtos; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; import java.time.LocalDateTime; import java.util.Set; @@ -26,13 +26,12 @@ public SimpleEmailTaskResponse(Long id, String subject, Set r } public static SimpleEmailTaskResponse from(EmailTask emailTask) { - EmailDetails emailDetails = emailTask.getEmailDetails(); + EmailDetail emailDetail = emailTask.getEmailDetail(); Set receiverInfos = EmailReceiverInfo.fromValueObject(emailTask.getEmailReceivers()); - return SimpleEmailTaskResponse.builder() .id(emailTask.getId()) - .subject(emailDetails.getSubject()) + .subject(emailDetail.getSubject()) .receiverInfos(receiverInfos) .sendAt(emailTask.getSendAt()) .isSent(emailTask.isSent()) diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/email/mapper/EmailTaskMapper.java b/src/main/java/gdsc/konkuk/platformcore/controller/email/mapper/EmailTaskMapper.java index ea7f4ea..7f49118 100644 --- a/src/main/java/gdsc/konkuk/platformcore/controller/email/mapper/EmailTaskMapper.java +++ b/src/main/java/gdsc/konkuk/platformcore/controller/email/mapper/EmailTaskMapper.java @@ -2,7 +2,7 @@ import java.util.List; -import gdsc.konkuk.platformcore.controller.email.dtos.EmailTaskDetailsResponse; +import gdsc.konkuk.platformcore.controller.email.dtos.EmailTaskDetailResponse; import gdsc.konkuk.platformcore.controller.email.dtos.EmailTaskListResponse; import gdsc.konkuk.platformcore.controller.email.dtos.SimpleEmailTaskResponse; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; @@ -20,8 +20,8 @@ public static EmailTaskListResponse mapToEmailTaskListResponse(List e return new EmailTaskListResponse(simpleEmailTaskResponses); } - public static EmailTaskDetailsResponse mapToEmailTaskDetailsResponse(EmailTask emailTask) { - return new EmailTaskDetailsResponse( - emailTask.getEmailDetails(), emailTask.getEmailReceivers(), emailTask.getSendAt()); + public static EmailTaskDetailResponse mapToEmailTaskDetailsResponse(EmailTask emailTask) { + return new EmailTaskDetailResponse( + emailTask.getEmailDetail(), emailTask.getEmailReceivers(), emailTask.getSendAt()); } } diff --git a/src/main/java/gdsc/konkuk/platformcore/controller/member/dtos/MemberRegisterRequest.java b/src/main/java/gdsc/konkuk/platformcore/controller/member/dtos/MemberRegisterRequest.java index 51ec2a1..99404fc 100644 --- a/src/main/java/gdsc/konkuk/platformcore/controller/member/dtos/MemberRegisterRequest.java +++ b/src/main/java/gdsc/konkuk/platformcore/controller/member/dtos/MemberRegisterRequest.java @@ -18,7 +18,12 @@ public class MemberRegisterRequest { private String name; @NotEmpty private String email; + @NotEmpty + private String department; + @NotEmpty private String batch; + @NotEmpty + private String role; public static Member toEntity(MemberRegisterRequest request) { return Member.builder() @@ -26,7 +31,9 @@ public static Member toEntity(MemberRegisterRequest request) { .password(request.getPassword()) .name(request.getName()) .email(request.getEmail()) + .department(request.getDepartment()) .batch(request.getBatch()) + .role(request.getRole()) .build(); } } diff --git a/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailDetails.java b/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailDetail.java similarity index 89% rename from src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailDetails.java rename to src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailDetail.java index 0e121ad..bdf82eb 100644 --- a/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailDetails.java +++ b/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailDetail.java @@ -13,7 +13,7 @@ @Embeddable @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class EmailDetails { +public class EmailDetail { @Column(name = "email_subject") private String subject; @@ -21,7 +21,7 @@ public class EmailDetails { private String content; @Builder - public EmailDetails(String subject, String content) { + public EmailDetail(String subject, String content) { this.subject = validateNotNull(subject, "subject"); this.content = validateNotNull(content, "content"); } @@ -32,7 +32,7 @@ public boolean equals(Object o) { return true; if (o == null || getClass() != o.getClass()) return false; - EmailDetails that = (EmailDetails)o; + EmailDetail that = (EmailDetail)o; return Objects.equals(subject, that.subject) && Objects.equals(content, that.content); } diff --git a/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTask.java b/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTask.java index 326aba3..0dda41d 100644 --- a/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTask.java +++ b/src/main/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTask.java @@ -27,7 +27,7 @@ public class EmailTask { @Column(name = "task_id") private Long id; - @Embedded private EmailDetails emailDetails; + @Embedded private EmailDetail emailDetail; @Embedded private EmailReceivers emailReceivers; @@ -39,15 +39,15 @@ public class EmailTask { @Builder public EmailTask( - Long id, EmailDetails emailDetails, EmailReceivers receivers, LocalDateTime sendAt) { + Long id, EmailDetail emailDetail, EmailReceivers receivers, LocalDateTime sendAt) { this.id = id; - this.emailDetails = validateNotNull(emailDetails, "emailDetails"); + this.emailDetail = validateNotNull(emailDetail, "emailDetails"); this.emailReceivers = validateNotNull(receivers, "emailReceivers"); this.sendAt = validateNotNull(sendAt, "sendAt"); } - public void changeEmailDetails(final EmailDetails newEmailDetails) { - emailDetails = newEmailDetails; + public void changeEmailDetails(final EmailDetail newEmailDetail) { + emailDetail = newEmailDetail; } public void changeEmailReceivers(final Set set) { diff --git a/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/Member.java b/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/Member.java index 58e4069..bb590d6 100644 --- a/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/Member.java +++ b/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/Member.java @@ -61,7 +61,7 @@ public class Member { @Enumerated(EnumType.STRING) @Column(name = "member_role") - private MemberRole role = MemberRole.MEMBER; + private MemberRole role; @Column(name = "batch") private String batch; @@ -91,6 +91,7 @@ public Member( String email, // String profileImageUrl, String department, + String role, String batch) { this.id = id; this.memberId = validateNotNull(memberId, "memberId"); @@ -98,7 +99,8 @@ public Member( this.name = validateNotNull(name, "name"); this.email = validateNotNull(email, "email"); // this.profileImageUrl = profileImageUrl; - this.department = department; - this.batch = batch; + this.department = validateNotNull(department, "department"); + this.role = (role != null) ? MemberRole.from(role) : MemberRole.MEMBER; + this.batch = validateNotNull(batch, "batch"); } } diff --git a/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/MemberRole.java b/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/MemberRole.java index e6c01a1..0aac0af 100644 --- a/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/MemberRole.java +++ b/src/main/java/gdsc/konkuk/platformcore/domain/member/entity/MemberRole.java @@ -7,6 +7,15 @@ public enum MemberRole { private final String authority; + public static MemberRole from(String role) { + return switch (role) { + case "ROLE_LEAD" -> LEAD; + case "ROLE_ADMIN" -> ADMIN; + case "ROLE_MEMBER" -> MEMBER; + default -> throw new IllegalArgumentException("Invalid role: " + role); + }; + } + MemberRole(String authority) { this.authority = authority; } diff --git a/src/main/java/gdsc/konkuk/platformcore/external/email/EmailClient.java b/src/main/java/gdsc/konkuk/platformcore/external/email/EmailClient.java index 973deee..a018e19 100644 --- a/src/main/java/gdsc/konkuk/platformcore/external/email/EmailClient.java +++ b/src/main/java/gdsc/konkuk/platformcore/external/email/EmailClient.java @@ -12,7 +12,7 @@ import org.springframework.stereotype.Component; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; import gdsc.konkuk.platformcore.external.email.exceptions.EmailClientErrorCode; import gdsc.konkuk.platformcore.external.email.exceptions.EmailSendingException; @@ -28,28 +28,28 @@ public class EmailClient { private final JavaMailSender javaMailSender; public void sendEmailToReceivers(EmailTask email) { - EmailDetails emailDetails = email.getEmailDetails(); + EmailDetail emailDetail = email.getEmailDetail(); Set receivers = email.getEmailReceivers().getReceivers(); - receivers.forEach(receiver -> sendEmail(receiver, emailDetails)); + receivers.forEach(receiver -> sendEmail(receiver, emailDetail)); } public String replaceNameToken(String content, String name) { return content.replaceAll(EMAIL_RECEIVER_NAME_REGEXP, name); } - private MimeMessage generateMimeMessage(EmailReceiver to, EmailDetails emailDetails) + private MimeMessage generateMimeMessage(EmailReceiver to, EmailDetail emailDetail) throws MessagingException { - String emailContent = replaceNameToken(emailDetails.getContent(), to.getName()); + String emailContent = replaceNameToken(emailDetail.getContent(), to.getName()); String emailDestination = to.getEmail(); - String emailSubject = emailDetails.getSubject(); + String emailSubject = emailDetail.getSubject(); return convertToHTMLMimeMessage(emailDestination, emailSubject, emailContent); } - private void sendEmail(EmailReceiver to, EmailDetails emailDetails) { + private void sendEmail(EmailReceiver to, EmailDetail emailDetail) { try { log.info("Sending email to {}", to); - MimeMessage message = generateMimeMessage(to, emailDetails); + MimeMessage message = generateMimeMessage(to, emailDetail); javaMailSender.send(message); } catch (MailParseException | MessagingException e) { throw EmailSendingException.of(EmailClientErrorCode.MAIL_PARSING_ERROR, e.getMessage()); diff --git a/src/main/java/gdsc/konkuk/platformcore/global/utils/GetDefault.java b/src/main/java/gdsc/konkuk/platformcore/global/utils/GetDefault.java new file mode 100644 index 0000000..d825cac --- /dev/null +++ b/src/main/java/gdsc/konkuk/platformcore/global/utils/GetDefault.java @@ -0,0 +1,11 @@ +package gdsc.konkuk.platformcore.global.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class GetDefault { + public static T getDefault(T value, T defaultValue) { + return value == null ? defaultValue : value; + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/annotation/CustomMockUser.java b/src/test/java/gdsc/konkuk/platformcore/annotation/WithCustomUser.java similarity index 62% rename from src/test/java/gdsc/konkuk/platformcore/annotation/CustomMockUser.java rename to src/test/java/gdsc/konkuk/platformcore/annotation/WithCustomUser.java index 0a4eff6..96ad1d6 100644 --- a/src/test/java/gdsc/konkuk/platformcore/annotation/CustomMockUser.java +++ b/src/test/java/gdsc/konkuk/platformcore/annotation/WithCustomUser.java @@ -1,14 +1,14 @@ package gdsc.konkuk.platformcore.annotation; import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; +import gdsc.konkuk.platformcore.fixture.member.MemberFixture; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import org.springframework.security.test.context.support.WithSecurityContext; @Retention(RetentionPolicy.RUNTIME) -@WithSecurityContext(factory = WithMyCustomUserSecurityContextFactory.class) -public @interface CustomMockUser { - String memberId() default "202011288"; - +@WithSecurityContext(factory = WithCustomUserSecurityContextFactory.class) +public @interface WithCustomUser { + String memberId() default "2024000000"; MemberRole role() default MemberRole.MEMBER; } diff --git a/src/test/java/gdsc/konkuk/platformcore/annotation/WithMyCustomUserSecurityContextFactory.java b/src/test/java/gdsc/konkuk/platformcore/annotation/WithCustomUserSecurityContextFactory.java similarity index 87% rename from src/test/java/gdsc/konkuk/platformcore/annotation/WithMyCustomUserSecurityContextFactory.java rename to src/test/java/gdsc/konkuk/platformcore/annotation/WithCustomUserSecurityContextFactory.java index cd1836d..9af9174 100644 --- a/src/test/java/gdsc/konkuk/platformcore/annotation/WithMyCustomUserSecurityContextFactory.java +++ b/src/test/java/gdsc/konkuk/platformcore/annotation/WithCustomUserSecurityContextFactory.java @@ -10,9 +10,9 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.test.context.support.WithSecurityContextFactory; -public class WithMyCustomUserSecurityContextFactory implements WithSecurityContextFactory { +public class WithCustomUserSecurityContextFactory implements WithSecurityContextFactory { @Override - public SecurityContext createSecurityContext(CustomMockUser annotation) { + public SecurityContext createSecurityContext(WithCustomUser annotation) { String memberId = annotation.memberId(); MemberRole role = annotation.role(); @@ -31,4 +31,4 @@ public SecurityContext createSecurityContext(CustomMockUser annotation) { private List buildGrantedAuthoritiesFromRole(final MemberRole role) { return List.of(new SimpleGrantedAuthority(role.toString())); } -} \ No newline at end of file +} diff --git a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailIntegrationTest.java b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailIntegrationTest.java index 687019d..ca7d69b 100644 --- a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailIntegrationTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailIntegrationTest.java @@ -12,18 +12,17 @@ import static org.springframework.test.util.AssertionErrors.fail; import gdsc.konkuk.platformcore.application.email.exceptions.EmailAlreadyProcessedException; -import gdsc.konkuk.platformcore.controller.email.dtos.EmailReceiverInfo; import gdsc.konkuk.platformcore.controller.email.dtos.EmailSendRequest; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; import gdsc.konkuk.platformcore.domain.email.repository.EmailTaskRepository; import gdsc.konkuk.platformcore.external.discord.DiscordClient; import gdsc.konkuk.platformcore.external.email.EmailClient; import gdsc.konkuk.platformcore.external.email.exceptions.EmailSendingException; +import gdsc.konkuk.platformcore.fixture.email.EmailSendRequestFixture; import gdsc.konkuk.platformcore.global.exceptions.GlobalErrorCode; import gdsc.konkuk.platformcore.global.exceptions.TaskNotFoundException; import gdsc.konkuk.platformcore.global.scheduler.TaskInMemoryRepository; import java.time.LocalDateTime; -import java.util.Set; import java.util.concurrent.ScheduledThreadPoolExecutor; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; @@ -71,15 +70,9 @@ void tearDown() { @Transactional void should_save_task_at_InMemoryTaskRepository() { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.now().plusHours(1)) - .build(); + EmailSendRequest emailRequest = EmailSendRequestFixture.builder() + .sendAt(LocalDateTime.now().plusHours(1)).build() + .getFixture(); // when EmailTask emailTask = emailTaskFacade.register(emailRequest); @@ -95,19 +88,13 @@ void should_save_task_at_InMemoryTaskRepository() { @DisplayName("등록된 작업 스케줄된 시간에 실행 성공") void should_send_task_when_time_is_up() throws InterruptedException { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("example1@gmail.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2@gmail.com").name("guest2").build())) - .sendAt(LocalDateTime.now().plusSeconds(5L)) - .build(); + EmailSendRequest emailRequest = EmailSendRequestFixture.builder() + .sendAt(LocalDateTime.now().plusSeconds(5)).build() + .getFixture(); // when emailTaskFacade.register(emailRequest); - sleep(10000); + sleep(10_000); // then verify(emailClient).sendEmailToReceivers(any(EmailTask.class)); @@ -115,7 +102,6 @@ void should_send_task_when_time_is_up() throws InterruptedException { assertEquals(0, taskInMemoryRepository.size()); } - /* * 1. 작업 예약 * 2. 작업 수정 요청 @@ -125,38 +111,25 @@ void should_send_task_when_time_is_up() throws InterruptedException { @DisplayName("작업 수정 시 스케줄된 작업 취소 후 다시 스케줄") void should_cancel_and_schedule_new_when_update() { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.now().plusHours(1)) - .build(); - EmailTask emailTask = emailTaskFacade.register(emailRequest); - + EmailTask emailTaskToUpdate = emailTaskFacade.register( + EmailSendRequestFixture.builder() + .sendAt(LocalDateTime.now().plusMinutes(30)).build() + .getFixture()); assertEquals(1, executor.getQueue().size()); assertEquals(1, taskInMemoryRepository.size()); - EmailSendRequest updatedRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.now().plusHours(2)) - .build(); + EmailSendRequest updatedRequest = EmailSendRequestFixture.builder() + .sendAt(LocalDateTime.now().plusHours(1)).build() + .getFixture(); // when - emailTaskFacade.update(emailTask.getId(), updatedRequest); + emailTaskFacade.update(emailTaskToUpdate.getId(), updatedRequest); // then assertEquals(1, executor.getQueue().size()); assertNotNull( "Task Not Processed must remain in TaskRepository", - taskInMemoryRepository.getTask(String.valueOf(emailTask.getId())).getDelay(HOURS) > 1); + taskInMemoryRepository.getTask(String.valueOf(emailTaskToUpdate.getId())).getDelay(HOURS) > 1); } /* @@ -169,15 +142,9 @@ void should_cancel_and_schedule_new_when_update() { @Transactional void should_cancel_task() { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.now().plusHours(1)) - .build(); + EmailSendRequest emailRequest = EmailSendRequestFixture.builder() + .sendAt(LocalDateTime.now().plusHours(1)).build() + .getFixture(); EmailTask emailTask = emailTaskFacade.register(emailRequest); assertEquals(1, executor.getQueue().size()); @@ -189,26 +156,20 @@ void should_cancel_task() { assertTrue(emailTaskRepository.findById(emailTask.getId()).isEmpty()); assertThrows( TaskNotFoundException.class, - () -> taskInMemoryRepository.getTask("1")); + () -> taskInMemoryRepository.getTask(emailTask.getId().toString())); } @Test @DisplayName("이미 처리된 작업 취소 시도 시 예외 발생") void should_fail_when_cancel_already_processed_task() throws Exception { //given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.now().plusSeconds(1L)) - .build(); + EmailSendRequest emailRequest = EmailSendRequestFixture.builder() + .sendAt(LocalDateTime.now().plusSeconds(1)).build() + .getFixture(); //when EmailTask scheduledTask = emailTaskFacade.register(emailRequest); - sleep(2000); + sleep(2_000); //then try{ @@ -222,24 +183,19 @@ void should_fail_when_cancel_already_processed_task() throws Exception { @Test void should_send_discord_message_when_email_sending_error() throws InterruptedException { //given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.now().plusSeconds(1L)) - .build(); + EmailSendRequest emailRequest = EmailSendRequestFixture.builder() + .sendAt(LocalDateTime.now().plusSeconds(1)).build() + .getFixture(); + doThrow(EmailSendingException.of(GlobalErrorCode.INTERNAL_SERVER_ERROR)) - .when(emailClient).sendEmailToReceivers(any()); + .when(emailClient).sendEmailToReceivers(any(EmailTask.class)); //when - EmailTask scheduledTask = emailTaskFacade.register(emailRequest); + emailTaskFacade.register(emailRequest); sleep(2000); //then - verify(emailClient).sendEmailToReceivers(any()); + verify(emailClient).sendEmailToReceivers(any(EmailTask.class)); verify(discordClient).sendErrorMessage(any()); } } diff --git a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceHelperTest.java b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceHelperTest.java index 7419eaa..6b75dc8 100644 --- a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceHelperTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceHelperTest.java @@ -5,14 +5,10 @@ import static org.mockito.MockitoAnnotations.*; import gdsc.konkuk.platformcore.application.email.exceptions.EmailNotFoundException; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; -import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver; -import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; import gdsc.konkuk.platformcore.domain.email.repository.EmailTaskRepository; -import java.time.LocalDateTime; +import gdsc.konkuk.platformcore.fixture.email.EmailTaskFixture; import java.util.Optional; -import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; @@ -22,17 +18,6 @@ class EmailServiceHelperTest { @Mock private EmailTaskRepository emailTaskRepository; - private final EmailTask mock1 = - EmailTask.builder() - .id(1L) - .emailDetails(new EmailDetails("subject", "content")) - .receivers(new EmailReceivers( - Set.of( - EmailReceiver.builder().email("example1.com").name("guest1").build(), - EmailReceiver.builder().email("example2.com").name("guest2").build()))) - .sendAt(LocalDateTime.of(2021, 1, 1, 1, 1)) - .build(); - @BeforeEach void setUp() { openMocks(this); @@ -41,23 +26,27 @@ void setUp() { @Test void should_return_task_when_exists() { // given - given(emailTaskRepository.findById(any())).willReturn(Optional.of(mock1)); + EmailTask emailTaskToRequest = EmailTaskFixture.builder().build().getFixture(); + given(emailTaskRepository.findById(emailTaskToRequest.getId())) + .willReturn(Optional.of(emailTaskToRequest)); // when - EmailTask emailTask = EmailServiceHelper.findEmailTaskById(emailTaskRepository, 1L); + EmailTask emailTaskFound = + EmailServiceHelper.findEmailTaskById(emailTaskRepository, emailTaskToRequest.getId()); // then - assertEquals(mock1.getEmailDetails(), emailTask.getEmailDetails()); - assertEquals(mock1.getEmailReceivers(), emailTask.getEmailReceivers()); + assertEquals(emailTaskToRequest.getEmailDetail(), emailTaskFound.getEmailDetail()); + assertEquals(emailTaskToRequest.getEmailReceivers(), emailTaskFound.getEmailReceivers()); } @Test void should_fail_when_not_exists() { // given - given(emailTaskRepository.findById(any())).willReturn(Optional.empty()); + given(emailTaskRepository.findById(any(Long.class))).willReturn(Optional.empty()); // when - Executable executable = () -> EmailServiceHelper.findEmailTaskById(emailTaskRepository, 1L); + Executable executable = + () -> EmailServiceHelper.findEmailTaskById(emailTaskRepository, 0L); // then assertThrows(EmailNotFoundException.class, executable); diff --git a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceTest.java b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceTest.java index 908ac57..a3a865f 100644 --- a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailServiceTest.java @@ -6,17 +6,14 @@ import gdsc.konkuk.platformcore.application.email.exceptions.EmailAlreadyProcessedException; import gdsc.konkuk.platformcore.application.email.exceptions.EmailNotFoundException; -import gdsc.konkuk.platformcore.controller.email.dtos.EmailReceiverInfo; import gdsc.konkuk.platformcore.controller.email.dtos.EmailSendRequest; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; -import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver; -import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; import gdsc.konkuk.platformcore.domain.email.repository.EmailTaskRepository; +import gdsc.konkuk.platformcore.fixture.email.EmailSendRequestFixture; +import gdsc.konkuk.platformcore.fixture.email.EmailTaskFixture; import java.time.LocalDateTime; import java.util.List; import java.util.Optional; -import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -28,101 +25,66 @@ class EmailServiceTest { private EmailService subject; - private final EmailTask mock1 = - EmailTask.builder() - .id(1L) - .emailDetails(new EmailDetails("subject", "content")) - .receivers(new EmailReceivers( - Set.of( - EmailReceiver.builder().email("example1.com").name("guest1").build(), - EmailReceiver.builder().email("example2.com").name("guest2").build()))) - .sendAt(LocalDateTime.of(2021, 1, 1, 1, 1)) - .build(); - - private final EmailTask mock2 = - EmailTask.builder() - .id(2L) - .emailDetails(new EmailDetails("subject2", "content2")) - .receivers(new EmailReceivers( - Set.of( - EmailReceiver.builder().email("example1.com").name("guest1").build(), - EmailReceiver.builder().email("example2.com").name("guest2").build()))) - .sendAt(LocalDateTime.now()) - .build(); - - List mockEmailTaskList = List.of(mock1, mock2); - - private final EmailTask mockAlreadySent = - EmailTask.builder() - .id(3L) - .emailDetails(new EmailDetails("subject3", "content3")) - .receivers(new EmailReceivers( - Set.of( - EmailReceiver.builder().email("example1.com").name("guest1").build(), - EmailReceiver.builder().email("example2.com").name("guest2").build()))) - .sendAt(LocalDateTime.now()) - .build(); - @BeforeEach void setUp() { openMocks(this); subject = new EmailService(emailTaskRepository); - mockAlreadySent.markAsSent(); } @Test @DisplayName("getAllTaskAsList : 모든 이메일 전송 작업 목록 조회 성공") void should_success_when_getAllTaskAsList() { - - given(emailTaskRepository.findAll()).willReturn(mockEmailTaskList); + // given + List emailTaskListToFind = List.of( + EmailTaskFixture.builder().id(1L).build().getFixture(), + EmailTaskFixture.builder().id(2L).build().getFixture(), + EmailTaskFixture.builder().id(3L).build().getFixture() + ); + given(emailTaskRepository.findAll()).willReturn(emailTaskListToFind); // when List actual = subject.getAllTaskAsList(); // then - assertEquals(mockEmailTaskList.size(), actual.size()); - assertEquals(mockEmailTaskList.get(0).getId(), actual.get(0).getId()); - assertEquals(mockEmailTaskList.get(1).getId(), actual.get(1).getId()); + assertEquals(emailTaskListToFind.size(), actual.size()); + for(int i = 0; i < actual.size(); i++) { + assertEquals(emailTaskListToFind.get(i).getId(), actual.get(i).getId()); + } } @Test @DisplayName("getTaskDetails : 특정 이메일 전송 작업 조회 성공") void should_success_when_getTaskDetails() { // given - given(emailTaskRepository.findById(1L)).willReturn(java.util.Optional.of(mock1)); + EmailTask emailTaskToFind = EmailTaskFixture.builder().build().getFixture(); + given(emailTaskRepository.findById(emailTaskToFind.getId())) + .willReturn(java.util.Optional.of(emailTaskToFind)); // when - EmailTask actual = subject.getTaskDetails(1L); + EmailTask actual = subject.getTaskDetails(emailTaskToFind.getId()); // then - assertEquals(mock1.getId(), actual.getId()); - assertEquals(mock1.getEmailDetails().getSubject(), actual.getEmailDetails().getSubject()); + assertEquals(emailTaskToFind.getId(), actual.getId()); + assertEquals(emailTaskToFind.getEmailDetail().getSubject(), actual.getEmailDetail().getSubject()); assertEquals( - mock1.getEmailReceivers().getReceivers(), actual.getEmailReceivers().getReceivers()); + emailTaskToFind.getEmailReceivers().getReceivers(), + actual.getEmailReceivers().getReceivers()); } @Test @DisplayName("registerTask : 이메일 전송 작업 등록 성공") void should_success_when_register_task() { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos( - Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.of(2021, 1, 1, 1, 1)) - .build(); - given(emailTaskRepository.save(any(EmailTask.class))).willReturn(mock1); + EmailSendRequest emailRegisterRequest = EmailSendRequestFixture.builder().build().getFixture(); + given(emailTaskRepository.save(any(EmailTask.class))) + .willReturn(EmailSendRequest.toEntity(emailRegisterRequest)); // when - EmailTask expected = EmailSendRequest.toEntity(emailRequest); - EmailTask actual = subject.registerTask(EmailSendRequest.toEntity(emailRequest)); + EmailTask expected = EmailSendRequest.toEntity(emailRegisterRequest); + EmailTask actual = subject.registerTask(EmailSendRequest.toEntity(emailRegisterRequest)); // then - assertEquals(expected.getEmailDetails(), actual.getEmailDetails()); + assertEquals(expected.getEmailDetail(), actual.getEmailDetail()); assertEquals(expected.getEmailReceivers(), actual.getEmailReceivers()); } @@ -130,24 +92,17 @@ void should_success_when_register_task() { @DisplayName("update : 이메일 전송 작업 수정 성공") void should_success_when_update_task() { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject2") - .content("content2") - .receiverInfos( - Set.of( - EmailReceiverInfo.builder().email("example2.com").name("guest2").build(), - EmailReceiverInfo.builder().email("example4.com").name("guest4").build())) - .sendAt(LocalDateTime.of(2021, 1, 1, 1, 1)) - .build(); - given(emailTaskRepository.findById(1L)).willReturn(java.util.Optional.of(mock1)); + EmailSendRequest emailUpdateRequest = EmailSendRequestFixture.builder().build().getFixture(); + EmailTask emailTaskToUpdate = EmailTaskFixture.builder().id(1L).build().getFixture(); + given(emailTaskRepository.findById(emailTaskToUpdate.getId())) + .willReturn(Optional.of(emailTaskToUpdate)); // when - EmailTask expected = EmailSendRequest.toEntity(emailRequest); - EmailTask actual = subject.update(1L, emailRequest); + EmailTask expected = emailTaskToUpdate; + EmailTask actual = subject.update(emailTaskToUpdate.getId(), emailUpdateRequest); // then - assertEquals(expected.getEmailDetails(), actual.getEmailDetails()); + assertEquals(expected.getEmailDetail(), actual.getEmailDetail()); assertEquals(expected.getEmailReceivers(), actual.getEmailReceivers()); } @@ -155,57 +110,50 @@ void should_success_when_update_task() { @DisplayName("update : 이미 전송된 작업 수정 시도 실패") void should_fail_when_update_task_already_sent() { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject2") - .content("content2") - .receiverInfos( - Set.of( - EmailReceiverInfo.builder().email("example2.com").name("guest2").build(), - EmailReceiverInfo.builder().email("example4.com").name("guest4").build())) - .sendAt(LocalDateTime.of(2021, 1, 1, 1, 1)) - .build(); + EmailTask emailTaskAlreadySent = EmailTaskFixture.builder() + .sendAt(LocalDateTime.now().minusHours(1)).build().getFixture(); + emailTaskAlreadySent.markAsSent(); + EmailSendRequest emailRequest = EmailSendRequestFixture.builder().build().getFixture(); // when - when(emailTaskRepository.findById(1L)).thenReturn(Optional.of(mockAlreadySent)); + when(emailTaskRepository.findById(emailTaskAlreadySent.getId())) + .thenReturn(Optional.of(emailTaskAlreadySent)); // then - assertThrows(EmailAlreadyProcessedException.class, () -> subject.update(1L, emailRequest)); + assertThrows( + EmailAlreadyProcessedException.class, + () -> subject.update(emailTaskAlreadySent.getId(), emailRequest)); } @Test @DisplayName("update : 존재하지 않는 작업 수정 시도 실패") void should_fail_when_update_task_not_found() { // given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject2") - .content("content2") - .receiverInfos( - Set.of( - EmailReceiverInfo.builder().email("example2.com").name("guest2").build(), - EmailReceiverInfo.builder().email("example4.com").name("guest4").build())) - .sendAt(LocalDateTime.of(2021, 1, 1, 1, 1)) - .build(); + EmailSendRequest emailRequest = EmailSendRequestFixture.builder().build().getFixture(); // when - when(emailTaskRepository.findById(1L)).thenReturn(Optional.empty()); + when(emailTaskRepository.findById(0L)) + .thenReturn(Optional.empty()); // then - assertThrows(EmailNotFoundException.class, () -> subject.update(1L, emailRequest)); + assertThrows( + EmailNotFoundException.class, + () -> subject.update(0L, emailRequest)); } @Test @DisplayName("delete : 이메일 전송 작업 삭제 성공") void should_success_when_delete_task() { // given - given(emailTaskRepository.findById(1L)).willReturn(Optional.of(mock1)); + EmailTask emailTaskToCancel = EmailTaskFixture.builder().build().getFixture(); + given(emailTaskRepository.findById(emailTaskToCancel.getId())) + .willReturn(Optional.of(emailTaskToCancel)); + willDoNothing().given(emailTaskRepository).delete(emailTaskToCancel); // when - doNothing().when(emailTaskRepository).delete(mock1); - subject.delete(1L); + subject.delete(emailTaskToCancel.getId()); // then - verify(emailTaskRepository).delete(mock1); + verify(emailTaskRepository).delete(emailTaskToCancel); } } diff --git a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailTaskFacadeTest.java b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailTaskFacadeTest.java index afb617f..42c0635 100644 --- a/src/test/java/gdsc/konkuk/platformcore/application/email/EmailTaskFacadeTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/application/email/EmailTaskFacadeTest.java @@ -1,15 +1,17 @@ package gdsc.konkuk.platformcore.application.email; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.openMocks; -import gdsc.konkuk.platformcore.controller.email.dtos.EmailReceiverInfo; import gdsc.konkuk.platformcore.controller.email.dtos.EmailSendRequest; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver; import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; +import gdsc.konkuk.platformcore.fixture.email.EmailSendRequestFixture; +import gdsc.konkuk.platformcore.fixture.email.EmailTaskFixture; import gdsc.konkuk.platformcore.global.scheduler.TaskScheduler; import java.time.LocalDateTime; import java.util.Set; @@ -32,7 +34,7 @@ class EmailTaskFacadeTest { private final EmailTask mock1 = EmailTask.builder() .id(1L) - .emailDetails(new EmailDetails("subject", "content")) + .emailDetail(new EmailDetail("subject", "content")) .receivers(new EmailReceivers( Set.of( EmailReceiver.builder().email("example1.com").name("guest1").build(), @@ -49,37 +51,32 @@ void setUp() { @Test @DisplayName("예약 수정시 성공") void should_success_when_reschedule_task() { - //given - EmailSendRequest emailRequest = - EmailSendRequest.builder() - .subject("subject") - .content("content") - .receiverInfos( - Set.of( - EmailReceiverInfo.builder().email("example1.com").name("guest1").build(), - EmailReceiverInfo.builder().email("example2.com").name("guest2").build())) - .sendAt(LocalDateTime.of(2021, 1, 1, 1, 1)) - .build(); + //given + EmailSendRequest emailUpdateRequest = EmailSendRequestFixture.builder().build().getFixture(); + EmailTask emailTaskToUpdate = EmailTaskFixture.builder().id(1L).build().getFixture(); + given(emailService.update(emailTaskToUpdate.getId(), emailUpdateRequest)) + .willReturn(EmailTaskFixture.builder().id(1L).build().getFixture()); //when - when(emailService.update(1L, emailRequest)).thenReturn(mock1); + subject.update(emailTaskToUpdate.getId(), emailUpdateRequest); //then - subject.update(1L, emailRequest); - verify(emailTaskScheduler).cancelTask("1"); + verify(emailTaskScheduler).cancelTask(emailTaskToUpdate.getId().toString()); } @Test @DisplayName("예약 취소시 성공") void should_success_when_cancel_task() { //given - Long emailId = 1L; + EmailTask emailTaskToCancel = EmailTaskFixture.builder().build().getFixture(); + willDoNothing().given(emailTaskScheduler).cancelTask(emailTaskToCancel.getId().toString()); + willDoNothing().given(emailService).delete(emailTaskToCancel.getId()); //when - subject.cancel(1L); + subject.cancel(emailTaskToCancel.getId()); //then - verify(emailTaskScheduler).cancelTask("1"); - verify(emailService).delete(emailId); + verify(emailTaskScheduler).cancelTask(emailTaskToCancel.getId().toString()); + verify(emailService).delete(emailTaskToCancel.getId()); } } diff --git a/src/test/java/gdsc/konkuk/platformcore/application/member/MemberServiceTest.java b/src/test/java/gdsc/konkuk/platformcore/application/member/MemberServiceTest.java index 7868f56..c825080 100644 --- a/src/test/java/gdsc/konkuk/platformcore/application/member/MemberServiceTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/application/member/MemberServiceTest.java @@ -11,6 +11,8 @@ import gdsc.konkuk.platformcore.domain.attendance.repository.ParticipantRepository; import gdsc.konkuk.platformcore.domain.member.entity.Member; import gdsc.konkuk.platformcore.domain.member.repository.MemberRepository; +import gdsc.konkuk.platformcore.fixture.member.MemberFixture; +import gdsc.konkuk.platformcore.fixture.member.MemberRegisterRequestFixture; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -24,9 +26,6 @@ class MemberServiceTest { private MemberService subject; - @Mock - private Member member; - @Mock private MemberRepository memberRepository; @@ -42,26 +41,18 @@ class MemberServiceTest { @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); - subject = - new MemberService( - passwordEncoder, memberRepository, attendanceRepository, participantRepository); + subject = new MemberService(passwordEncoder, memberRepository, attendanceRepository, participantRepository); } @Test @DisplayName("Register : 새로운 멤버 회원가입 성공") void should_success_when_newMember_register() { // given - MemberRegisterRequest memberRegisterRequest = - MemberRegisterRequest.builder() - .memberId("202011288") - .password("password") - .email("example@konkuk.ac.kr") - .name("홍길동") - .batch("24-25") - .build(); - given(memberRepository.findByMemberId(any())).willReturn(Optional.empty()); - given(memberRepository.save(any(Member.class))).willReturn(member); - given(passwordEncoder.encode(any())).willReturn("password"); + MemberRegisterRequest memberRegisterRequest = MemberRegisterRequestFixture.builder().build().getFixture(); + Member memberToRegister = MemberFixture.builder().build().getFixture(); + given(memberRepository.findByMemberId(memberRegisterRequest.getMemberId())).willReturn(Optional.empty()); + given(memberRepository.save(any(Member.class))).willReturn(memberToRegister); + given(passwordEncoder.encode(memberRegisterRequest.getPassword())).willReturn(memberToRegister.getPassword()); // when Member actual = subject.register(memberRegisterRequest); @@ -74,16 +65,10 @@ void should_success_when_newMember_register() { @DisplayName("Register : 이미 존재하는 멤버 회원가입 실패") void should_fail_when_already_exist_member_register() { // given - MemberRegisterRequest memberRegisterRequest = - MemberRegisterRequest.builder() - .memberId("202011288") - .password("password") - .email("example@konkuk.ac.kr") - .name("홍길동") - .batch("24-25") - .build(); - given(memberRepository.findByMemberId(any())) - .willReturn(Optional.of(MemberRegisterRequest.toEntity(memberRegisterRequest))); + MemberRegisterRequest memberRegisterRequest = MemberRegisterRequestFixture.builder().build().getFixture(); + Member alreadyRegisteredMember = MemberFixture.builder().build().getFixture(); + given(memberRepository.findByMemberId(memberRegisterRequest.getMemberId())) + .willReturn(Optional.of(alreadyRegisteredMember)); // when Executable action = () -> subject.register(memberRegisterRequest); @@ -96,35 +81,25 @@ void should_fail_when_already_exist_member_register() { @DisplayName("withdraw : 존재하는 멤버 탈퇴 성공") void should_success_when_user_exists() { // given - Long targetId = 1L; - Member member = - Member.builder() - .id(1L) - .memberId("202011288") - .password("password") - .name("문다훈") - .email("example@gmail.com") - .batch("24-25") - .build(); - given(memberRepository.findById(any(Long.class))).willReturn(Optional.of(member)); + Member memberToDelete = MemberFixture.builder().build().getFixture(); + given(memberRepository.findById(memberToDelete.getId())).willReturn(Optional.of(memberToDelete)); // when - subject.withdraw(targetId); + subject.withdraw(memberToDelete.getId()); // then - assertTrue(member.isMemberDeleted()); - assertNotNull(member.getSoftDeletedAt()); + assertTrue(memberToDelete.isMemberDeleted()); + assertNotNull(memberToDelete.getSoftDeletedAt()); } @Test @DisplayName("withdraw : 존재하지 않는 멤버 탈퇴 실패") void should_fail_when_user_not_exists() { // given - Long targetId = 1L; given(memberRepository.findById(any(Long.class))).willReturn(Optional.empty()); // when - Executable action = () -> subject.withdraw(targetId); + Executable action = () -> subject.withdraw(0L); // then assertThrows(UserNotFoundException.class, action); @@ -134,21 +109,13 @@ void should_fail_when_user_not_exists() { @DisplayName("withdraw : 이미 삭제된 멤버 탈퇴 실패") void should_fail_when_user_already_deleted() { // given - Long targetId = 1L; - Member member = - Member.builder() - .id(1L) - .memberId("202011288") - .password("password") - .name("문다훈") - .email("example@gmail.com") - .batch("24-25") - .build(); - given(memberRepository.findById(any(Long.class))).willReturn(Optional.of(member)); + Member memberAlreadyDeleted = spy(MemberFixture.builder().build().getFixture()); + given(memberRepository.findById(memberAlreadyDeleted.getId())).willReturn(Optional.of(memberAlreadyDeleted)); + given(memberAlreadyDeleted.isMemberDeleted()).willReturn(true); // when `Member` soft deleted - subject.withdraw(targetId); - Executable action = () -> subject.withdraw(targetId); + subject.withdraw(memberAlreadyDeleted.getId()); + Executable action = () -> subject.withdraw(memberAlreadyDeleted.getId()); // then assertThrows(UserAlreadyDeletedException.class, action); diff --git a/src/test/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceControllerTest.java b/src/test/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceControllerTest.java index ba5367b..3af18a9 100644 --- a/src/test/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceControllerTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/controller/attendance/AttendanceControllerTest.java @@ -3,28 +3,34 @@ import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.fasterxml.jackson.databind.ObjectMapper; +import gdsc.konkuk.platformcore.annotation.RestDocsTest; +import gdsc.konkuk.platformcore.annotation.WithCustomUser; import gdsc.konkuk.platformcore.application.attendance.AttendanceService; import gdsc.konkuk.platformcore.application.attendance.dtos.AttendanceStatus; import gdsc.konkuk.platformcore.application.event.EventService; -import gdsc.konkuk.platformcore.application.event.dtos.EventWithAttendance; import gdsc.konkuk.platformcore.controller.attendance.dtos.AttendanceRegisterRequest; import gdsc.konkuk.platformcore.domain.attendance.entity.Attendance; -import gdsc.konkuk.platformcore.domain.attendance.entity.Participant; +import gdsc.konkuk.platformcore.domain.member.entity.Member; +import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; +import gdsc.konkuk.platformcore.fixture.attendance.AttendanceFixture; +import gdsc.konkuk.platformcore.fixture.attendance.AttendanceRegisterRequestFixture; +import gdsc.konkuk.platformcore.fixture.attendance.ParticipantFixture; +import gdsc.konkuk.platformcore.fixture.event.EventWithAttendanceFixture; +import gdsc.konkuk.platformcore.fixture.member.MemberFixture; +import gdsc.konkuk.platformcore.global.configs.SecurityConfig; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -35,7 +41,8 @@ import static com.epages.restdocs.apispec.ResourceDocumentation.resource; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doNothing; +import static org.mockito.BDDMockito.willDoNothing; +import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; @@ -49,15 +56,14 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@SpringBootTest -@ExtendWith({RestDocumentationExtension.class}) +@RestDocsTest +@WebMvcTest( + controllers = AttendanceController.class, + excludeFilters = {@ComponentScan.Filter(type = ASSIGNABLE_TYPE, classes = SecurityConfig.class)}) class AttendanceControllerTest { private MockMvc mockMvc; - @Mock - Attendance mockAttendance; - @Autowired private ObjectMapper objectMapper; @MockBean private AttendanceService attendanceService; @@ -76,21 +82,34 @@ void setUp( @Test @DisplayName("특정 달의 출석 정보를 조회할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_get_events_of_the_month_when_pass_year_month() throws Exception { // given - given(eventService.getEventsOfTheMonthWithAttendance(any(LocalDate.class))) + given(eventService.getEventsOfTheMonthWithAttendance(LocalDate.of(2024, 7, 1))) .willReturn( List.of( - // TODO: Fixture 정리 - EventWithAttendance.builder().attendanceId(0L).eventId(0L).build(), - EventWithAttendance.builder().attendanceId(1L).eventId(1L).build(), - EventWithAttendance.builder().attendanceId(2L).eventId(2L).build())); + EventWithAttendanceFixture.builder() + .eventId(1L) + .attendanceId(1L) + .startAt(LocalDateTime.of(2024, 7, 1, 15, 30)) + .build().getFixture(), + EventWithAttendanceFixture.builder() + .eventId(2L) + .attendanceId(null) + .startAt(LocalDateTime.of(2024, 7, 15, 15, 30)) + .build().getFixture(), + EventWithAttendanceFixture.builder() + .eventId(3L) + .attendanceId(2L) + .startAt(LocalDateTime.of(2024, 7, 21, 15, 30)) + .build().getFixture())); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.get("/api/v1/attendances?year=2021&month=1") + RestDocumentationRequestBuilders.get("/api/v1/attendances") + .queryParam("year", "2024") + .queryParam("month", "07") .with(csrf())); // then @@ -113,30 +132,35 @@ void should_get_events_of_the_month_when_pass_year_month() throws Exception { fieldWithPath("success").description("성공 여부"), fieldWithPath("message").description("메시지"), fieldWithPath("data[].eventId").description("이벤트 ID"), + fieldWithPath("data[].attendanceId").description("출석 ID").optional(), fieldWithPath("data[].title").description("이벤트 제목"), - fieldWithPath("data[].attendanceId").description("출석 ID"), fieldWithPath("data[].startAt").description("이벤트 시작 시간")) .build()))); } @Test @DisplayName("이벤트에 출석할 수 있다") - @WithMockUser void should_attend_when_pass_event_id_and_member_id() throws Exception { // given - Attendance attendance = Attendance.builder() - .id(1L) - .eventId(1L) - .build(); - given(attendanceService.attend(any(), any(), any())) - .willReturn(new Participant(1L, attendance, true)); + Member memberToAttend = MemberFixture.builder() + .email("ex@gmail.com").build().getFixture(); + Attendance attendanceToAttend = AttendanceFixture.builder() + .id(1L).activeQrUuid("uuid").build().getFixture(); + given(attendanceService.attend(memberToAttend.getEmail(), attendanceToAttend.getId(), attendanceToAttend.getActiveQrUuid())) + .willReturn(ParticipantFixture.builder() + .isAttended(true) + .memberId(memberToAttend.getId()) + .attendance(attendanceToAttend) + .build().getFixture()); // when ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.get( - "/api/v1/attendances/attend/{attendanceId}?qrUuid={uuid}", 1, "uuid") - .with(oidcLogin())); + "/api/v1/attendances/attend/{attendanceId}", 1L) + .queryParam("qrUuid", "uuid") + .with(oidcLogin() + .idToken(token -> token.claim("email", "ex@gmail.com")))); // then result @@ -156,23 +180,21 @@ void should_attend_when_pass_event_id_and_member_id() throws Exception { .responseFields( fieldWithPath("success").description("성공 여부"), fieldWithPath("message").description("메시지"), - fieldWithPath("data.id").description("참여자 ID"), - fieldWithPath("data.attendanceId").description("출석 ID"), - fieldWithPath("data.memberId").description("멤버 ID"), - fieldWithPath("data.attended").description("출석 여부")) + fieldWithPath("data").description("null")) .build()))); } @Test @DisplayName("이벤트 출석을 등록할 수 있다") - @WithMockUser + @WithCustomUser void should_register_attendance_when_pass_event_id() throws Exception { // given - AttendanceRegisterRequest registerRequest = - AttendanceRegisterRequest.builder().eventId(1L).batch("24-25").build(); - given(attendanceService.registerAttendance(any())).willReturn(mockAttendance); - given(mockAttendance.getActiveQrUuid()).willReturn("uuid"); - given(mockAttendance.getId()).willReturn(1L); + AttendanceRegisterRequest registerRequest = AttendanceRegisterRequestFixture.builder() + .eventId(1L).build().getFixture(); + Attendance attendanceToRegister = AttendanceFixture.builder() + .eventId(1L).build().getFixture(); + given(attendanceService.registerAttendance(any(AttendanceRegisterRequest.class))) + .willReturn(attendanceToRegister); // when ResultActions result = @@ -206,16 +228,20 @@ void should_register_attendance_when_pass_event_id() throws Exception { @Test @DisplayName("출석 현황을 조회할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_get_attendance_status_when_pass_attendance_id() throws Exception { // given - given(attendanceService.getAttendanceStatus(any(Long.class))) - .willReturn(AttendanceStatus.of(1L, 10, 6)); + Attendance attendanceToGetStatus = AttendanceFixture.builder() + .id(1L).build().getFixture(); + given(attendanceService.getAttendanceStatus(attendanceToGetStatus.getId())) + .willReturn(AttendanceStatus.of(attendanceToGetStatus.getId(), 10, 6)); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.get("/api/v1/attendances/{attendanceId}/status", 1) + RestDocumentationRequestBuilders.get( + "/api/v1/attendances/{attendanceId}/status", + 1L) .with(csrf())); // then @@ -243,15 +269,19 @@ void should_get_attendance_status_when_pass_attendance_id() throws Exception { @Test @DisplayName("이벤트 출석을 삭제할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_delete_attendance_when_pass_event_id() throws Exception { // given - doNothing().when(attendanceService).deleteAttendance(any(Long.class)); + Attendance attendanceToDelete = AttendanceFixture.builder() + .id(1L).build().getFixture(); + willDoNothing().given(attendanceService).deleteAttendance(attendanceToDelete.getId()); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.delete("/api/v1/attendances/{attendanceId}", 1) + RestDocumentationRequestBuilders.delete( + "/api/v1/attendances/{attendanceId}", 1L) + .contentType(APPLICATION_JSON) .with(csrf())); // then @@ -273,18 +303,23 @@ void should_delete_attendance_when_pass_event_id() throws Exception { @Test @DisplayName("QR 코드를 생성할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_generate_qr_when_pass_attendance_id() throws Exception { // given - given(attendanceService.generateQr(any(Long.class))).willReturn(mockAttendance); - given(attendanceService.registerAttendance(any())).willReturn(mockAttendance); - given(mockAttendance.getActiveQrUuid()).willReturn("uuid"); - given(mockAttendance.getId()).willReturn(1L); + Attendance attendanceToActive = AttendanceFixture.builder() + .id(1L).build().getFixture(); + given(attendanceService.generateQr(attendanceToActive.getId())) + .willAnswer(invocation -> { + attendanceToActive.generateQr(); + return attendanceToActive; + }); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.post("/api/v1/attendances/{attendanceId}/qr", 1) + RestDocumentationRequestBuilders.post( + "/api/v1/attendances/{attendanceId}/qr", 1L) + .contentType(APPLICATION_JSON) .with(csrf())); // then @@ -312,16 +347,19 @@ void should_generate_qr_when_pass_attendance_id() throws Exception { @Test @DisplayName("QR 코드를 만료시킬 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_expire_qr_when_pass_attendance_id_and_qr_uuid() throws Exception { // given - doNothing().when(attendanceService).expireQr(any(Long.class)); + Attendance attendanceToInactive = AttendanceFixture.builder() + .id(1L).build().getFixture(); + willDoNothing().given(attendanceService).expireQr(attendanceToInactive.getId()); // when ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.delete( - "/api/v1/attendances/{attendanceId}/qr", 1) + "/api/v1/attendances/{attendanceId}/qr", 1L) + .contentType(APPLICATION_JSON) .with(csrf())); // then diff --git a/src/test/java/gdsc/konkuk/platformcore/controller/auth/AuthControllerTest.java b/src/test/java/gdsc/konkuk/platformcore/controller/auth/AuthControllerTest.java index 5d2acce..0f22482 100644 --- a/src/test/java/gdsc/konkuk/platformcore/controller/auth/AuthControllerTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/controller/auth/AuthControllerTest.java @@ -12,6 +12,7 @@ import com.epages.restdocs.apispec.ResourceSnippetParameters; import gdsc.konkuk.platformcore.domain.member.entity.Member; import gdsc.konkuk.platformcore.domain.member.repository.MemberRepository; +import gdsc.konkuk.platformcore.fixture.member.MemberFixture; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -24,7 +25,6 @@ import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -56,26 +56,19 @@ void setUp(RestDocumentationContextProvider restDocumentation) { @Test @DisplayName("사용자 로그인 성공") - @WithMockUser void loginSuccess() throws Exception { // given - given(memberRepository.findByMemberId(any())) - .willReturn( - Optional.of( - Member.builder() - .memberId("202011288") - .password(passwordEncoder.encode("gdscgdsc")) - .name("우이산") - .email("helloworld@gmail.com") - .batch("24-25") - .build())); + Member memberToLogin = MemberFixture.builder() + .memberId("202400000").password("$2a$10$d7DjseDroHsRGVGR1zDUL.q7uwAQ2aH4nHM1JiQ1OFV.D0qUTl7w.").build().getFixture(); + given(memberRepository.findByMemberId(memberToLogin.getMemberId())) + .willReturn(Optional.of(memberToLogin)); // when ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.multipart("/login") - .formField("id", "202011288") - .formField("password", "gdscgdsc") + .formField("id", memberToLogin.getMemberId()) + .formField("password", "password") .contentType("application/x-www-form-urlencoded") .characterEncoding("UTF-8") .with(csrf())); @@ -95,8 +88,7 @@ void loginSuccess() throws Exception { } @Test - @DisplayName("사용자 로그인 실패") - @WithMockUser + @DisplayName("존재하지 않는 사용자 로그인 실패") void loginFail() throws Exception { // given given(memberRepository.findByMemberId(any())).willReturn(Optional.empty()); @@ -105,8 +97,8 @@ void loginFail() throws Exception { ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.multipart("/login") - .formField("id", "202011288") - .formField("password", "wrongpassword") + .formField("id", "2024000000") + .formField("password", "password") .contentType("application/x-www-form-urlencoded") .characterEncoding("UTF-8") .with(csrf())); diff --git a/src/test/java/gdsc/konkuk/platformcore/controller/email/EmailControllerTest.java b/src/test/java/gdsc/konkuk/platformcore/controller/email/EmailControllerTest.java index 527375d..6c39a6a 100644 --- a/src/test/java/gdsc/konkuk/platformcore/controller/email/EmailControllerTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/controller/email/EmailControllerTest.java @@ -1,7 +1,10 @@ package gdsc.konkuk.platformcore.controller.email; import static com.epages.restdocs.apispec.ResourceDocumentation.*; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.willDoNothing; import static org.mockito.Mockito.*; +import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE; import static org.springframework.http.MediaType.*; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; @@ -13,26 +16,25 @@ import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.fasterxml.jackson.databind.ObjectMapper; -import gdsc.konkuk.platformcore.annotation.CustomMockUser; +import gdsc.konkuk.platformcore.annotation.WithCustomUser; import gdsc.konkuk.platformcore.annotation.RestDocsTest; import gdsc.konkuk.platformcore.application.email.EmailService; import gdsc.konkuk.platformcore.application.email.EmailTaskFacade; -import gdsc.konkuk.platformcore.controller.email.dtos.EmailReceiverInfo; import gdsc.konkuk.platformcore.controller.email.dtos.EmailSendRequest; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; -import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver; -import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; -import java.time.LocalDateTime; +import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; +import gdsc.konkuk.platformcore.fixture.email.EmailSendRequestFixture; +import gdsc.konkuk.platformcore.fixture.email.EmailTaskFixture; +import gdsc.konkuk.platformcore.global.configs.SecurityConfig; import java.util.List; -import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; import org.springframework.restdocs.payload.JsonFieldType; @@ -42,11 +44,15 @@ import org.springframework.web.context.WebApplicationContext; @RestDocsTest -@SpringBootTest +@WebMvcTest( + controllers = EmailController.class, + excludeFilters = {@ComponentScan.Filter(type = ASSIGNABLE_TYPE, classes = SecurityConfig.class)}) class EmailControllerTest { private MockMvc mockMvc; - @MockBean private EmailService emailService; + + @MockBean + private EmailService emailService; @MockBean EmailTaskFacade emailTaskFacade; @@ -68,24 +74,14 @@ void setUp( @Test @DisplayName("이메일 전송 작업 등록 성공") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_send_email() throws Exception { //given - EmailSendRequest request = EmailSendRequest.builder() - .subject("예시 이메일 제목") - .content("Html 문자열") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("ex1@gmail.com").name("guest1").build(), - EmailReceiverInfo.builder().email("ex2@naver.com").name("guest2").build())) - .sendAt(LocalDateTime.of(2024, 7, 20, 12, 30)) - .build(); - EmailDetails emailDetails = request.toEmailDetails(); - EmailReceivers emailReceivers = new EmailReceivers(request.toEmailReceivers()); - EmailTask mockTask = new EmailTask(1L, emailDetails, emailReceivers, request.getSendAt()); + EmailSendRequest request = EmailSendRequestFixture.builder().build().getFixture(); + EmailTask emailTaskToSee = EmailTaskFixture.builder().build().getFixture(); + given(emailTaskFacade.register(any(EmailSendRequest.class))).willReturn(emailTaskToSee); //when - when(emailTaskFacade.register(any())).thenReturn(mockTask); - ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.post("/api/v1/emails") .contentType(APPLICATION_JSON) @@ -94,10 +90,8 @@ void should_success_when_send_email() throws Exception { //then result + .andDo(print()) .andExpect(status().isCreated()) - .andDo(print()); - - result .andDo( document("email post", preprocessRequest(prettyPrint()), @@ -109,170 +103,156 @@ void should_success_when_send_email() throws Exception { fieldWithPath("content").type(JsonFieldType.STRING).description("이메일 내용"), fieldWithPath("receiverInfos[].email").type(JsonFieldType.STRING).description("수신자 email"), fieldWithPath("receiverInfos[].name").type(JsonFieldType.STRING).description("수신자 이름"), - fieldWithPath("sendAt").type(JsonFieldType.STRING).description("수정할 이메일 발송 시간") - ) - .build())) - ); + fieldWithPath("sendAt").type(JsonFieldType.STRING).description("수정할 이메일 발송 시간")) + .build()))); } @Test @DisplayName("이메일 등록 내용 수정") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_update_emailTask() throws Exception { //given - EmailSendRequest request = EmailSendRequest.builder() - .subject("예시 이메일 제목 수정") - .content("Html 문자열") - .receiverInfos(Set.of( - EmailReceiverInfo.builder().email("update@gmail.com").name("guest1").build(), - EmailReceiverInfo.builder().email("update2@gmail.com").name("guest2").build(), - EmailReceiverInfo.builder().email("update3@gmail.com").name("guest3").build())) - .sendAt(LocalDateTime.of(2024,7,20,12,30)) - .build(); + EmailTask emailTaskToUpdate = EmailTaskFixture.builder() + .id(1L).build().getFixture(); + EmailSendRequest request = EmailSendRequestFixture.builder().build().getFixture(); //when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.patch("/api/v1/emails/{emailId}", 1L) + RestDocumentationRequestBuilders.patch( + "/api/v1/emails/{emailId}", 1L) .contentType(APPLICATION_JSON) .content(objectMapper.writeValueAsString(request)) .with(csrf())); //then - result.andExpect(status().isNoContent()) - .andDo(print()); - - result.andDo( - document("update email task", - preprocessRequest(prettyPrint()), - resource(ResourceSnippetParameters.builder() - .tag("email") - .description("이메일 전송 작업을 수정한다.") - .requestFields( - fieldWithPath("subject").type(JsonFieldType.STRING).description("수정할 이메일 제목"), - fieldWithPath("content").type(JsonFieldType.STRING).description("수정할 이메일 내용"), - fieldWithPath("receiverInfos[].email").type(JsonFieldType.STRING).description("수신자 email"), - fieldWithPath("receiverInfos[].name").type(JsonFieldType.STRING).description("수신자 이름"), - fieldWithPath("sendAt").type(JsonFieldType.STRING).description("수정할 이메일 발송 시간") - ).build())) - ); + result + .andDo(print()) + .andExpect(status().isNoContent()) + .andDo( + document("update email task", + preprocessRequest(prettyPrint()), + resource(ResourceSnippetParameters.builder() + .tag("email") + .description("이메일 전송 작업을 수정한다.") + .requestFields( + fieldWithPath("subject").type(JsonFieldType.STRING).description("수정할 이메일 제목"), + fieldWithPath("content").type(JsonFieldType.STRING).description("수정할 이메일 내용"), + fieldWithPath("receiverInfos[].email").type(JsonFieldType.STRING).description("수신자 email"), + fieldWithPath("receiverInfos[].name").type(JsonFieldType.STRING).description("수신자 이름"), + fieldWithPath("sendAt").type(JsonFieldType.STRING).description("수정할 이메일 발송 시간")) + .build()))); } @Test @DisplayName("이메일 전송 조회 - 모든 이메일 전송 작업 조회") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_get_all_task() throws Exception { //given - EmailDetails emailDetails = new EmailDetails("예시 이메일 제목", "Html 문자열"); - EmailReceivers emailReceivers = new EmailReceivers( - Set.of( - EmailReceiver.builder().email("example1@gmail.com").name("guest1").build(), - EmailReceiver.builder().email("example2@gmail.com").name("guest2").build(), - EmailReceiver.builder().email("example3@gmail.com").name("guest3").build())); - EmailTask emailTask = new EmailTask(1L, emailDetails, emailReceivers, LocalDateTime.of(2024, 7, 20, 12, 30)); + List emailTasksToSee = List.of( + EmailTaskFixture.builder().id(1L).build().getFixture(), + EmailTaskFixture.builder().id(2L).build().getFixture() + ); + given(emailService.getAllTaskAsList()).willReturn(emailTasksToSee); //when - when(emailService.getAllTaskAsList()).thenReturn(List.of(emailTask)); ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.get("/api/v1/emails") .contentType(APPLICATION_JSON) .with(csrf())); //then - result.andExpect(status().isOk()) - .andDo(print()); - - result.andDo( - document("get all email", - preprocessRequest(prettyPrint()), - resource(ResourceSnippetParameters.builder() - .tag("email") - .description("모든 이메일 전송 작업을 조회한다.") - .responseFields( - fieldWithPath("success").description(true), - fieldWithPath("message").description("이메일 전송 작업 조회 성공"), - fieldWithPath("data").description("이메일 전송 작업 목록"), - fieldWithPath("data.emailTasks").description("이메일 작업 목록"), - fieldWithPath("data.emailTasks[].id").description("이메일 작업의 ID (Mock객체에 대해 null일 수 있음.)"), - fieldWithPath("data.emailTasks[].subject").description("이메일 제목"), - fieldWithPath("data.emailTasks[].receiverInfos[].email").description("수신자 email"), - fieldWithPath("data.emailTasks[].receiverInfos[].name").description("수신자 이름"), - fieldWithPath("data.emailTasks[].sendAt").description("이메일 발송 예정 시간 (ISO 8601 형식)"), - fieldWithPath("data.emailTasks[].isSent").description("이메일 발송 여부") - ).build())) - ); + result + .andDo(print()) + .andExpect(status().isOk()) + .andDo( + document("get all email", + preprocessRequest(prettyPrint()), + resource(ResourceSnippetParameters.builder() + .tag("email") + .description("모든 이메일 전송 작업을 조회한다.") + .responseFields( + fieldWithPath("success").description(true), + fieldWithPath("message").description("이메일 전송 작업 조회 성공"), + fieldWithPath("data").description("이메일 전송 작업 목록"), + fieldWithPath("data.emailTasks").description("이메일 작업 목록"), + fieldWithPath("data.emailTasks[].id").description("이메일 작업의 ID"), + fieldWithPath("data.emailTasks[].subject").description("이메일 제목"), + fieldWithPath("data.emailTasks[].receiverInfos[].email").description("수신자 email"), + fieldWithPath("data.emailTasks[].receiverInfos[].name").description("수신자 이름"), + fieldWithPath("data.emailTasks[].sendAt").description("이메일 발송 예정 시간 (ISO 8601 형식)"), + fieldWithPath("data.emailTasks[].isSent").description("이메일 발송 여부")) + .build()))); } @Test @DisplayName("이메일 전송 조회 - 특정 이메일 전송 작업 세부내용 조회") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_get_specific_task() throws Exception { //given - EmailDetails emailDetails = new EmailDetails("예시 이메일 제목", "Html 문자열"); - EmailReceivers emailReceivers = new EmailReceivers( - Set.of( - EmailReceiver.builder().email("example@gmail.com").name("guest1").build(), - EmailReceiver.builder().email("example@naver.com").name("guest2").build())); - EmailTask emailTask = new EmailTask(1L, emailDetails, emailReceivers, LocalDateTime.of(2024, 7, 20, 12, 30)); + EmailTask emailTaskToSee = EmailTaskFixture.builder() + .id(1L).build().getFixture(); + given(emailService.getTaskDetails(emailTaskToSee.getId())) + .willReturn(emailTaskToSee); //when - when(emailService.getTaskDetails(any())).thenReturn(emailTask); ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.get("/api/v1/emails/{emailId}", 1) + RestDocumentationRequestBuilders.get( + "/api/v1/emails/{emailId}", 1L) .contentType(APPLICATION_JSON) .with(csrf())); //then - result.andExpect(status().isOk()) - .andDo(print()); - - result.andDo( - document("get email detail", - preprocessRequest(prettyPrint()), - resource(ResourceSnippetParameters.builder() - .tag("email") - .description("특정 이메일 상세정보를 조회한다.") - .responseFields( - fieldWithPath("success").description(true), - fieldWithPath("message").description("이메일 전송 작업 조회 성공"), - fieldWithPath("data").description("이메일 전송 작업 내용"), - fieldWithPath("data.subject").description("이메일 제목"), - fieldWithPath("data.content").description("이메일 내용"), - fieldWithPath("data.receiverInfos[].email").description("수신자 email"), - fieldWithPath("data.receiverInfos[].name").description("수신자 이름"), - fieldWithPath("data.sendAt").description("이메일 발송 예정 시간 (ISO 8601 형식)") - ) - .pathParameters( - parameterWithName("emailId").description("취소할 이메일 작업 ID") - ).build())) - ); + result + .andDo(print()) + .andExpect(status().isOk()) + .andDo( + document("get email detail", + preprocessRequest(prettyPrint()), + resource(ResourceSnippetParameters.builder() + .tag("email") + .description("특정 이메일 상세정보를 조회한다.") + .pathParameters( + parameterWithName("emailId").description("취소할 이메일 작업 ID")) + .responseFields( + fieldWithPath("success").description(true), + fieldWithPath("message").description("이메일 전송 작업 조회 성공"), + fieldWithPath("data").description("이메일 전송 작업 내용"), + fieldWithPath("data.subject").description("이메일 제목"), + fieldWithPath("data.content").description("이메일 내용"), + fieldWithPath("data.receiverInfos[].email").description("수신자 email"), + fieldWithPath("data.receiverInfos[].name").description("수신자 이름"), + fieldWithPath("data.sendAt").description("이메일 발송 예정 시간 (ISO 8601 형식)")) + .build()))); } @Test @DisplayName("등록된 이메일 작업을 취소한다.") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_cancel_registered_task() throws Exception { //given - doNothing().when(emailTaskFacade).cancel(any()); + EmailTask emailTaskToCancel = EmailTaskFixture.builder() + .id(1L).build().getFixture(); + willDoNothing().given(emailTaskFacade).cancel(emailTaskToCancel.getId()); //when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.delete("/api/v1/emails/{emailId}", 1) + RestDocumentationRequestBuilders.delete( + "/api/v1/emails/{emailId}", 1L) .contentType(APPLICATION_JSON) .with(csrf())); //then - result.andExpect(status().isNoContent()) - .andDo(print()); - - result.andDo( - document("cancel EmailTask", - preprocessRequest(prettyPrint()), - resource(ResourceSnippetParameters.builder() - .tag("email") - .description("특정 이메일 작업을 취소합니다.") - .pathParameters( - parameterWithName("emailId").description("취소할 이메일 작업 ID") - ).build())) - ); + result + .andDo(print()) + .andExpect(status().isNoContent()) + .andDo( + document("cancel EmailTask", + preprocessRequest(prettyPrint()), + resource(ResourceSnippetParameters.builder() + .tag("email") + .description("특정 이메일 작업을 취소합니다.") + .pathParameters( + parameterWithName("emailId").description("취소할 이메일 작업 ID")) + .build()))); } } diff --git a/src/test/java/gdsc/konkuk/platformcore/controller/event/EventControllerTest.java b/src/test/java/gdsc/konkuk/platformcore/controller/event/EventControllerTest.java index b600989..d729722 100644 --- a/src/test/java/gdsc/konkuk/platformcore/controller/event/EventControllerTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/controller/event/EventControllerTest.java @@ -5,8 +5,9 @@ import static com.epages.restdocs.apispec.ResourceDocumentation.resource; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.doNothing; +import static org.mockito.BDDMockito.willDoNothing; import static org.mockito.MockitoAnnotations.openMocks; +import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE; import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; @@ -21,31 +22,31 @@ import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.fasterxml.jackson.databind.ObjectMapper; -import gdsc.konkuk.platformcore.application.event.dtos.EventBrief; +import gdsc.konkuk.platformcore.annotation.RestDocsTest; +import gdsc.konkuk.platformcore.annotation.WithCustomUser; import gdsc.konkuk.platformcore.application.event.EventService; -import gdsc.konkuk.platformcore.controller.event.dtos.EventBriefResponse; import gdsc.konkuk.platformcore.controller.event.dtos.EventDetailResponse; import gdsc.konkuk.platformcore.controller.event.dtos.EventRegisterRequest; import gdsc.konkuk.platformcore.controller.event.dtos.EventUpdateRequest; import gdsc.konkuk.platformcore.controller.event.dtos.RetrospectUpdateRequest; import gdsc.konkuk.platformcore.domain.event.entity.Event; -import gdsc.konkuk.platformcore.domain.event.entity.Retrospect; -import java.net.URL; -import java.time.LocalDateTime; +import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; +import gdsc.konkuk.platformcore.fixture.event.EventBriefResponseFixture; +import gdsc.konkuk.platformcore.fixture.event.EventFixture; +import gdsc.konkuk.platformcore.fixture.event.EventRegisterRequestFixture; +import gdsc.konkuk.platformcore.fixture.event.EventUpdateRequestFixture; +import gdsc.konkuk.platformcore.global.configs.SecurityConfig; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.mock.web.MockMultipartFile; import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; @@ -53,15 +54,14 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.multipart.MultipartFile; -@SpringBootTest -@ExtendWith({RestDocumentationExtension.class}) +@RestDocsTest +@WebMvcTest( + controllers = EventController.class, + excludeFilters = {@ComponentScan.Filter(type = ASSIGNABLE_TYPE, classes = SecurityConfig.class)}) public class EventControllerTest { private MockMvc mockMvc; - @Mock Event event; - @Mock Retrospect retrospect; - @MockBean private EventService eventService; @Autowired private ObjectMapper objectMapper; @@ -80,40 +80,16 @@ void setUp( @Test @DisplayName("모든 이벤트를 간략 조회할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_get_all_events_when_request() throws Exception { // given - given(eventService.getAllBriefs()) - .willReturn( - EventBriefResponse.builder() - .eventBriefs( - List.of( - EventBrief.builder() - .id(1L) - .title("test event1") - .content("test event content") - .startAt(LocalDateTime.now()) - .thumbnail(new URL("https://foo.com/bar/baz.jpg")) - .build(), - EventBrief.builder() - .id(2L) - .title("test event2") - .content("test event content 2") - .startAt(LocalDateTime.now()) - .thumbnail(new URL("https://foo.com/bar/baz.jpg")) - .build(), - EventBrief.builder() - .id(3L) - .title("test event3") - .content("test event content") - .startAt(LocalDateTime.now()) - .thumbnail(new URL("https://foo.com/bar/baz.jpg")) - .build())) - .build()); + given(eventService.getAllBriefs()).willReturn(EventBriefResponseFixture.builder().build().getFixture()); // when ResultActions result = - mockMvc.perform(RestDocumentationRequestBuilders.get("/api/v1/events").with(csrf())); + mockMvc.perform(RestDocumentationRequestBuilders + .get("/api/v1/events") + .with(csrf())); // then result @@ -135,35 +111,25 @@ void should_get_all_events_when_request() throws Exception { fieldWithPath("data.eventBriefs[].title").description("이벤트 제목"), fieldWithPath("data.eventBriefs[].content").description("이벤트 내용"), fieldWithPath("data.eventBriefs[].startAt").description("이벤트 시작 시간"), - fieldWithPath("data.eventBriefs[].thumbnail").description("썸네일 URL")) + fieldWithPath("data.eventBriefs[].thumbnail").description("썸네일 URL").optional()) .build()))); } @Test @DisplayName("특정 이벤트를 상세 조회할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_get_event_detail_when_pass_event_id() throws Exception { // given - given(eventService.getEvent(any(Long.class))) - .willReturn( - EventDetailResponse.builder() - .id(1L) - .title("test title") - .content("test content") - .location("test location") - .startAt(LocalDateTime.now()) - .endAt(LocalDateTime.now().plusHours(2)) - .images( - List.of( - new URL("https://foo.com/bar/baz1.jpg"), - new URL("https://foo.com/bar/baz2.jpg"), - new URL("https://foo.com/bar/baz3.png"))) - .build()); + Event eventToSee = EventFixture.builder() + .id(1L).build().getFixture(); + given(eventService.getEvent(eventToSee.getId())).willReturn(EventDetailResponse.fromEntity(eventToSee)); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.get("/api/v1/events/{eventId}", 1L).with(csrf())); + RestDocumentationRequestBuilders + .get("/api/v1/events/{eventId}", 1L) + .with(csrf())); // then result @@ -195,17 +161,13 @@ void should_get_event_detail_when_pass_event_id() throws Exception { @Test @DisplayName("이벤트를 등록할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_register_event_when_requested() throws Exception { // given - EventRegisterRequest eventRegisterRequest = - EventRegisterRequest.builder() - .title("test title") - .content("test description") - .location("test location") - .startAt(LocalDateTime.now()) - .endAt(LocalDateTime.now().plusHours(2)) - .build(); + EventRegisterRequest eventRegisterRequest = EventRegisterRequestFixture.builder().build().getFixture(); + given(eventService.register(any(EventRegisterRequest.class), any(List.class))) + .willReturn(EventFixture.builder().build().getFixture()); + MockMultipartFile mockImages = new MockMultipartFile("images", "test.jpg", "image/jpeg", "test".getBytes()); MockMultipartFile mockDetail = @@ -214,20 +176,21 @@ void should_register_event_when_requested() throws Exception { "", "application/json", objectMapper.writeValueAsString(eventRegisterRequest).getBytes()); - given(eventService.register(any(), any())).willReturn(this.event); + String mockRequestBodyForDocument = + objectMapper.writeValueAsString( + new Object() { + public final Object detail = eventRegisterRequest; + public final List images = List.of(); + }); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.multipart("/api/v1/events") + RestDocumentationRequestBuilders + .multipart("/api/v1/events") .file(mockImages) .file(mockDetail) - .content( - objectMapper.writeValueAsString( - new Object() { - public Object detail = eventRegisterRequest; - public List images = List.of(); - })) + .content(mockRequestBodyForDocument) .with(csrf())); // then @@ -270,18 +233,13 @@ void should_register_event_when_requested() throws Exception { @Test @DisplayName("이벤트를 수정할 수 있다") - @WithMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_update_event_when_requested() throws Exception { // given - EventUpdateRequest eventUpdateRequest = - EventUpdateRequest.builder() - .title("test title") - .content("test description") - .startAt(LocalDateTime.now()) - .endAt(LocalDateTime.now().plusHours(2)) - .eventImagesToDelete( - List.of(new URL("https://s3.com/key1"), new URL("https://s3.com/key2"))) - .build(); + EventUpdateRequest eventUpdateRequest = EventUpdateRequestFixture.builder().build().getFixture(); + willDoNothing().given(eventService) + .update(any(Long.class), any(EventUpdateRequest.class), any(List.class)); + MockMultipartFile mockImages = new MockMultipartFile("new-images", "test.jpg", "image/jpeg", "test".getBytes()); MockMultipartFile mockDetail = @@ -290,27 +248,29 @@ void should_update_event_when_requested() throws Exception { "", "application/json", objectMapper.writeValueAsString(eventUpdateRequest).getBytes()); - doNothing().when(eventService).update(any(Long.class), any(EventUpdateRequest.class), any()); + String mockRequestBodyForDocument = + objectMapper.writeValueAsString( + new Object() { + public final Object detail = eventUpdateRequest; + public final List newImages = List.of(); + }); // when MockMultipartHttpServletRequestBuilder putMultipartRestDocumentationRequestBuilder = - RestDocumentationRequestBuilders.multipart("/api/v1/events/{eventId}", 1L); + RestDocumentationRequestBuilders + .multipart("/api/v1/events/{eventId}", 1L); putMultipartRestDocumentationRequestBuilder.with( request -> { request.setMethod("PATCH"); return request; }); + ResultActions result = mockMvc.perform( putMultipartRestDocumentationRequestBuilder .file(mockImages) .file(mockDetail) - .content( - objectMapper.writeValueAsString( - new Object() { - public Object detail = eventUpdateRequest; - public List newImages = List.of(); - })) + .content(mockRequestBodyForDocument) .with(csrf())); // then @@ -344,7 +304,7 @@ void should_update_event_when_requested() throws Exception { - location(String?): 이벤트 장소 - startAt(DateTime?): 이벤트 시작 시간 - endAt(DateTime?): 이벤트 종료 시간 - - eventImageKeysToDelete(String[]?): 삭제할 이미지 URL 목록 + - eventImagesToDelete(URL[]?): 삭제할 이미지 URL 목록 """), fieldWithPath("detail.title").description("이벤트 제목").optional(), fieldWithPath("detail.content").description("이벤트 내용").optional(), @@ -361,20 +321,23 @@ void should_update_event_when_requested() throws Exception { } @Test - @WithMockUser @DisplayName("회고 수정 성공") + @WithCustomUser(role = MemberRole.ADMIN) void should_update_retrospect_when_pass_content() throws Exception { // given - RetrospectUpdateRequest retrospectUpdateRequest = - RetrospectUpdateRequest.builder().content("content").build(); - doNothing().when(eventService).updateRetrospect(any(Long.class), any(String.class)); + Event eventToUpdateRetrospect = EventFixture.builder() + .id(1L).build().getFixture(); + RetrospectUpdateRequest retrospectUpdateRequest = new RetrospectUpdateRequest("content"); + willDoNothing().given(eventService) + .updateRetrospect(eventToUpdateRetrospect.getId(), "content"); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.patch("/api/v1/events/{eventId}/retrospect", 1L) - .contentType(APPLICATION_JSON) + RestDocumentationRequestBuilders + .patch("/api/v1/events/{eventId}/retrospect", 1L) .content(objectMapper.writeValueAsString(retrospectUpdateRequest)) + .contentType(APPLICATION_JSON) .with(csrf())); // then @@ -400,16 +363,21 @@ void should_update_retrospect_when_pass_content() throws Exception { } @Test - @WithMockUser @DisplayName("이벤트 삭제 성공") + @WithCustomUser(role = MemberRole.ADMIN) void should_delete_event_when_pass_event_id() throws Exception { // given - doNothing().when(eventService).delete(any(Long.class)); + Event eventToDelete = EventFixture.builder() + .id(1L).build().getFixture(); + willDoNothing().given(eventService).delete(eventToDelete.getId()); // when ResultActions result = mockMvc.perform( - RestDocumentationRequestBuilders.delete("/api/v1/events/{eventId}", 1L).with(csrf())); + RestDocumentationRequestBuilders + .delete("/api/v1/events/{eventId}", 1L) + .contentType(APPLICATION_JSON) + .with(csrf())); // then result diff --git a/src/test/java/gdsc/konkuk/platformcore/controller/member/MemberControllerTest.java b/src/test/java/gdsc/konkuk/platformcore/controller/member/MemberControllerTest.java index 062a47b..58c21c1 100644 --- a/src/test/java/gdsc/konkuk/platformcore/controller/member/MemberControllerTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/controller/member/MemberControllerTest.java @@ -2,6 +2,7 @@ import static com.epages.restdocs.apispec.ResourceDocumentation.*; import static org.mockito.BDDMockito.*; +import static org.springframework.context.annotation.FilterType.ASSIGNABLE_TYPE; import static org.springframework.http.MediaType.*; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*; import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; @@ -11,11 +12,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; -import gdsc.konkuk.platformcore.application.attendance.dtos.MemberAttendanceInfo; -import gdsc.konkuk.platformcore.application.member.dtos.MemberAttendances; import com.epages.restdocs.apispec.ResourceSnippetParameters; import com.fasterxml.jackson.databind.ObjectMapper; -import gdsc.konkuk.platformcore.annotation.CustomMockUser; +import gdsc.konkuk.platformcore.annotation.RestDocsTest; +import gdsc.konkuk.platformcore.annotation.WithCustomUser; import gdsc.konkuk.platformcore.application.member.MemberService; import gdsc.konkuk.platformcore.application.member.exceptions.UserAlreadyExistException; import gdsc.konkuk.platformcore.controller.member.dtos.AttendanceUpdateInfo; @@ -23,33 +23,34 @@ import gdsc.konkuk.platformcore.controller.member.dtos.MemberRegisterRequest; import gdsc.konkuk.platformcore.domain.member.entity.Member; import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; -import java.time.LocalDateTime; +import gdsc.konkuk.platformcore.fixture.member.MemberAttendancesFixture; +import gdsc.konkuk.platformcore.fixture.member.MemberFixture; +import gdsc.konkuk.platformcore.fixture.member.MemberRegisterRequestFixture; +import gdsc.konkuk.platformcore.global.configs.SecurityConfig; +import java.time.LocalDate; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; import org.springframework.restdocs.RestDocumentationContextProvider; -import org.springframework.restdocs.RestDocumentationExtension; import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -@SpringBootTest -@ExtendWith({RestDocumentationExtension.class}) +@RestDocsTest +@WebMvcTest( + controllers = MemberController.class, + excludeFilters = {@ComponentScan.Filter(type = ASSIGNABLE_TYPE, classes = SecurityConfig.class)}) class MemberControllerTest { MockMvc mockMvc; - @Mock Member member; - @MockBean private MemberService memberService; @Autowired private ObjectMapper objectMapper; @@ -67,12 +68,13 @@ void setUp( @Test @DisplayName("멤버 로그인 여부 확인") - @WithMockUser + @WithCustomUser void should_success_when_check_login() throws Exception { // when ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.post("/api/v1/members/check-login") + .contentType(APPLICATION_JSON) .with(csrf())); // then @@ -97,17 +99,14 @@ void should_success_when_check_login() throws Exception { @Test @DisplayName("새로운 멤버 회원 가입 성공") + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_newMember() throws Exception { // given - MemberRegisterRequest memberRegisterRequest = - MemberRegisterRequest.builder() - .memberId("202011288") - .password("password") - .email("example@konkuk.ac.kr") - .name("홍길동") - .batch("24-25") - .build(); - given(memberService.register(any(MemberRegisterRequest.class))).willReturn(member); + MemberRegisterRequest memberRegisterRequest = MemberRegisterRequestFixture.builder() + .memberId("202400000").password("password").build().getFixture(); + Member memberToRegister = MemberFixture.builder() + .memberId("202400000").password("$2a$10$d7DjseDroHsRGVGR1zDUL").build().getFixture(); + given(memberService.register(any(MemberRegisterRequest.class))).willReturn(memberToRegister); // when ResultActions result = @@ -136,7 +135,9 @@ void should_success_when_newMember() throws Exception { fieldWithPath("password").description("비밀번호"), fieldWithPath("email").description("이메일"), fieldWithPath("name").description("이름"), - fieldWithPath("batch").description("배치")) + fieldWithPath("department").description("학과"), + fieldWithPath("batch").description("배치"), + fieldWithPath("role").description("역할")) .responseFields( fieldWithPath("success").description(true), fieldWithPath("message").description("회원 가입 성공"), @@ -146,16 +147,10 @@ void should_success_when_newMember() throws Exception { @Test @DisplayName("이미 존재하는 유저 회원 가입 실패") + @WithCustomUser(role = MemberRole.ADMIN) void should_fail_when_existingMember() throws Exception { // given - MemberRegisterRequest memberRegisterRequest = - MemberRegisterRequest.builder() - .memberId("202011288") - .password("password") - .email("example@konkuk.ac.kr") - .name("홍길동") - .batch("24-25") - .build(); + MemberRegisterRequest memberRegisterRequest = MemberRegisterRequestFixture.builder().build().getFixture(); given(memberService.register(any(MemberRegisterRequest.class))) .willThrow(UserAlreadyExistException.class); @@ -173,9 +168,11 @@ void should_fail_when_existingMember() throws Exception { @Test @DisplayName("회원 탈퇴 성공") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_delete_member() throws Exception { // given + Member memberToWithdraw = MemberFixture.builder().build().getFixture(); + willDoNothing().given(memberService).withdraw(memberToWithdraw.getId()); // when ResultActions result = @@ -202,122 +199,23 @@ void should_success_when_delete_member() throws Exception { @Test @DisplayName("특정 배치의 특정 월의 멤버 출석 정보 조회 성공") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_get_attendances_by_batch() throws Exception { // given - // TODO: fixture로 변경 + // TODO: 좀 더 상세하고 정확한 Fixture 필요 (`batch`, `eventId`, `participantId` 등) given(memberService.getMemberAttendanceWithBatchAndPeriod(anyString(), any())) .willReturn( List.of( - MemberAttendances.builder() - .memberId(0L) - .memberName("홍길동") - .department("컴퓨터공학과") - .memberRole(MemberRole.MEMBER) - .totalAttendances(3L) - .actualAttendances(2L) - .attendanceInfoList( - List.of( - MemberAttendanceInfo.builder() - .attendanceId(1L) - .memberId(0L) - .eventId(1L) - .participantId(1L) - .attendanceDate(LocalDateTime.of(2024, 7, 3, 0, 0)) - .isAttended(true) - .build(), - MemberAttendanceInfo.builder() - .attendanceId(2L) - .memberId(0L) - .eventId(2L) - .participantId(2L) - .attendanceDate(LocalDateTime.of(2024, 7, 5, 0, 0)) - .isAttended(false) - .build(), - MemberAttendanceInfo.builder() - .attendanceId(3L) - .memberId(0L) - .eventId(3L) - .participantId(3L) - .attendanceDate(LocalDateTime.of(2024, 7, 8, 0, 0)) - .isAttended(true) - .build())) - .build(), - MemberAttendances.builder() - .memberId(1L) - .memberName("전우치") - .department("기술경영학과") - .memberRole(MemberRole.MEMBER) - .totalAttendances(3L) - .actualAttendances(1L) - .attendanceInfoList( - List.of( - MemberAttendanceInfo.builder() - .attendanceId(1L) - .memberId(1L) - .eventId(1L) - .participantId(4L) - .attendanceDate(LocalDateTime.of(2024, 7, 3, 0, 0)) - .isAttended(true) - .build(), - MemberAttendanceInfo.builder() - .attendanceId(2L) - .memberId(1L) - .eventId(2L) - .participantId(5L) - .attendanceDate(LocalDateTime.of(2024, 7, 5, 0, 0)) - .isAttended(false) - .build(), - MemberAttendanceInfo.builder() - .attendanceId(3L) - .memberId(1L) - .eventId(3L) - .participantId(6L) - .attendanceDate(LocalDateTime.of(2024, 7, 8, 0, 0)) - .isAttended(false) - .build())) - .build(), - MemberAttendances.builder() - .memberId(2L) - .memberName("이순신") - .department("컴퓨터공학과") - .memberRole(MemberRole.MEMBER) - .totalAttendances(3L) - .actualAttendances(2L) - .attendanceInfoList( - List.of( - MemberAttendanceInfo.builder() - .attendanceId(1L) - .memberId(2L) - .eventId(1L) - .participantId(7L) - .attendanceDate(LocalDateTime.of(2024, 7, 3, 0, 0)) - .isAttended(true) - .build(), - MemberAttendanceInfo.builder() - .attendanceId(2L) - .memberId(2L) - .eventId(2L) - .participantId(8L) - .attendanceDate(LocalDateTime.of(2024, 7, 5, 0, 0)) - .isAttended(false) - .build(), - MemberAttendanceInfo.builder() - .attendanceId(3L) - .memberId(2L) - .eventId(3L) - .participantId(9L) - .attendanceDate(LocalDateTime.of(2024, 7, 8, 0, 0)) - .isAttended(true) - .build())) - .build())); + MemberAttendancesFixture.builder().memberId(1L).memberName("member1").build().getFixture(), + MemberAttendancesFixture.builder().memberId(2L).memberName("member2").build().getFixture(), + MemberAttendancesFixture.builder().memberId(3L).memberName("member3").build().getFixture())); // when ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.get("/api/v1/members/{batch}/attendances", "24-25") .param("year", "2024") - .param("month", "7") + .param("month", "07") .contentType(APPLICATION_JSON) .with(csrf())); @@ -368,26 +266,25 @@ void should_success_when_get_attendances_by_batch() throws Exception { @Test @DisplayName("특정 배치의 특정 월의 멤버 출석 정보 수정 성공") - @CustomMockUser + @WithCustomUser(role = MemberRole.ADMIN) void should_success_when_update_attendances_by_batch() throws Exception { // given - List attendanceUpdateInfoList = - List.of( + List attendanceUpdateInfoList = List.of( AttendanceUpdateInfo.builder().participantId(1L).isAttended(true).build(), AttendanceUpdateInfo.builder().participantId(2L).isAttended(false).build(), AttendanceUpdateInfo.builder().participantId(3L).isAttended(true).build()); - AttendanceUpdateRequest attendanceUpdateRequest = - AttendanceUpdateRequest.builder() - .attendanceUpdateInfoList(attendanceUpdateInfoList) - .build(); - doNothing().when(memberService).updateAttendances(anyString(), any(), any()); + AttendanceUpdateRequest attendanceUpdateRequest = new AttendanceUpdateRequest(attendanceUpdateInfoList); + willDoNothing().given(memberService).updateAttendances( + "24-25", + LocalDate.of(2024, 7, 1), + attendanceUpdateInfoList); // when ResultActions result = mockMvc.perform( RestDocumentationRequestBuilders.patch("/api/v1/members/{batch}/attendances", "24-25") .param("year", "2024") - .param("month", "7") + .param("month", "07") .contentType(APPLICATION_JSON) .content(objectMapper.writeValueAsString(attendanceUpdateRequest)) .with(csrf())); diff --git a/src/test/java/gdsc/konkuk/platformcore/domain/attendance/entity/AttendanceTest.java b/src/test/java/gdsc/konkuk/platformcore/domain/attendance/entity/AttendanceTest.java index 255605d..4dcc563 100644 --- a/src/test/java/gdsc/konkuk/platformcore/domain/attendance/entity/AttendanceTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/domain/attendance/entity/AttendanceTest.java @@ -9,30 +9,32 @@ class AttendanceTest { @Test - @DisplayName("QR코드가 null이거나 불일치하는지 하면 실패 확인") + @DisplayName("QR코드가 null이거나 불일치하면 실패") void should_fail_when_Qr_expired() { //given Attendance attendance = Attendance.builder() .activeQrUuid("example") .build(); - assertThrows(QrInvalidException.class, () -> - attendance.validateActiveQr("example2") - ); + + // when, then + assertThrows(QrInvalidException.class, + () -> attendance.validateActiveQr("example2")); } @Test - @DisplayName("QR코드를 expire했을때 기존 QR은 validation실패 확인") + @DisplayName("QR코드를 expire했을 때, 기존 QR은 validation 실패") void should_fail_when_qr_expired() { - //given + // given Attendance attendance = Attendance.builder() .activeQrUuid("example") .build(); - //when + + // when attendance.expireQr(); - assertThrows(QrInvalidException.class, () -> - attendance.validateActiveQr("example") + // then + assertThrows(QrInvalidException.class, + () -> attendance.validateActiveQr("example") ); } - } diff --git a/src/test/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTaskTest.java b/src/test/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTaskTest.java index 175f647..726bcb9 100644 --- a/src/test/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTaskTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/domain/email/entity/EmailTaskTest.java @@ -16,7 +16,7 @@ class EmailTaskTest { void should_success_when_change_email_receivers() { //given EmailTask emailTask = EmailTask.builder() - .emailDetails(EmailDetails.builder() + .emailDetail(EmailDetail.builder() .subject("예시 이메일 제목") .content("Html 문자열") .build()) @@ -45,19 +45,19 @@ void should_success_when_change_email_details() { // given EmailTask emailTask = EmailTask.builder() - .emailDetails(EmailDetails.builder().subject("예시 이메일 제목").content("Html 문자열").build()) + .emailDetail(EmailDetail.builder().subject("예시 이메일 제목").content("Html 문자열").build()) .receivers(new EmailReceivers(Set.of())) .sendAt(LocalDateTime.of(2021, 10, 10, 10, 10)) .build(); - EmailDetails newEmailDetails = - EmailDetails.builder().subject("newSubject").content("newContent").build(); + EmailDetail newEmailDetail = + EmailDetail.builder().subject("newSubject").content("newContent").build(); // when - emailTask.changeEmailDetails(newEmailDetails); + emailTask.changeEmailDetails(newEmailDetail); // then - assertEquals(newEmailDetails, emailTask.getEmailDetails()); + assertEquals(newEmailDetail, emailTask.getEmailDetail()); } @Test @@ -66,7 +66,7 @@ void should_success_when_mark_task_success() { // given EmailTask emailTask = EmailTask.builder() - .emailDetails(EmailDetails.builder().subject("예시 이메일 제목").content("Html 문자열").build()) + .emailDetail(EmailDetail.builder().subject("예시 이메일 제목").content("Html 문자열").build()) .receivers(new EmailReceivers(Set.of())) .sendAt(LocalDateTime.of(2021, 10, 10, 10, 10)) .build(); @@ -84,7 +84,7 @@ void should_success_when_get_overlapping_receivers() { // given EmailTask emailTask = EmailTask.builder() - .emailDetails(EmailDetails.builder().subject("예시 이메일 제목").content("Html 문자열").build()) + .emailDetail(EmailDetail.builder().subject("예시 이메일 제목").content("Html 문자열").build()) .receivers(new EmailReceivers( Set.of( EmailReceiver.builder().email("example1.com").name("guest1").build(), @@ -109,7 +109,7 @@ void should_success_when_get_receivers_not_in_prev_set() { // given EmailTask emailTask = EmailTask.builder() - .emailDetails(EmailDetails.builder().subject("예시 이메일 제목").content("Html 문자열").build()) + .emailDetail(EmailDetail.builder().subject("예시 이메일 제목").content("Html 문자열").build()) .receivers(new EmailReceivers( Set.of( EmailReceiver.builder().email("example1.com").name("guest1").build(), diff --git a/src/test/java/gdsc/konkuk/platformcore/external/email/EmailClientTest.java b/src/test/java/gdsc/konkuk/platformcore/external/email/EmailClientTest.java index 8ab74f3..04fb4fc 100644 --- a/src/test/java/gdsc/konkuk/platformcore/external/email/EmailClientTest.java +++ b/src/test/java/gdsc/konkuk/platformcore/external/email/EmailClientTest.java @@ -5,7 +5,7 @@ import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.*; -import gdsc.konkuk.platformcore.domain.email.entity.EmailDetails; +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver; import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; @@ -40,7 +40,7 @@ void should_fail_when_email_parsing() { // given EmailTask emailTask = EmailTask.builder() - .emailDetails(EmailDetails.builder().subject("예시 이메일 제목").content("Html 문자열").build()) + .emailDetail(EmailDetail.builder().subject("예시 이메일 제목").content("Html 문자열").build()) .receivers(new EmailReceivers( Set.of(EmailReceiver.builder().email("aaa@gmail.com").name("guest1").build()))) .sendAt(LocalDateTime.of(2021, 10, 10, 10, 10)) @@ -60,7 +60,7 @@ void should_replace_to_receiver_name_when_name_token() { // given EmailTask emailTask = EmailTask.builder() - .emailDetails(EmailDetails.builder() + .emailDetail(EmailDetail.builder() .subject("예시 이메일 제목") .content("안녕하세요, {이름}님 합격을 축하드립니다!. {이름}님과 함께할 수 있어 기쁩니다.") .build()) diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/AttendanceFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/AttendanceFixture.java new file mode 100644 index 0000000..185bd46 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/AttendanceFixture.java @@ -0,0 +1,21 @@ +package gdsc.konkuk.platformcore.fixture.attendance; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.attendance.entity.Attendance; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class AttendanceFixture { + private final Attendance fixture; + + @Builder + public AttendanceFixture(Long id, Long eventId, String activeQrUuid) { + this.fixture = Attendance.builder() + .id(getDefault(id, 0L)) + .eventId(getDefault(eventId, 0L)) + .activeQrUuid(getDefault(activeQrUuid, "uuid")) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/AttendanceRegisterRequestFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/AttendanceRegisterRequestFixture.java new file mode 100644 index 0000000..dd62329 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/AttendanceRegisterRequestFixture.java @@ -0,0 +1,20 @@ +package gdsc.konkuk.platformcore.fixture.attendance; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.controller.attendance.dtos.AttendanceRegisterRequest; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class AttendanceRegisterRequestFixture { + private final AttendanceRegisterRequest fixture; + + @Builder + public AttendanceRegisterRequestFixture(Long eventId, String batch) { + this.fixture = AttendanceRegisterRequest.builder() + .eventId(getDefault(eventId, 0L)) + .batch(getDefault(batch, "24-25")) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/ParticipantFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/ParticipantFixture.java new file mode 100644 index 0000000..03b0f27 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/attendance/ParticipantFixture.java @@ -0,0 +1,22 @@ +package gdsc.konkuk.platformcore.fixture.attendance; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.attendance.entity.Attendance; +import gdsc.konkuk.platformcore.domain.attendance.entity.Participant; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class ParticipantFixture { + private final Participant fixture; + + @Builder + public ParticipantFixture(Long memberId, Attendance attendance, Boolean isAttended) { + this.fixture = Participant.builder() + .memberId(getDefault(memberId, 0L)) + .attendance(getDefault(attendance, AttendanceFixture.builder().build().getFixture())) + .isAttended(getDefault(isAttended, false)) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailDetailFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailDetailFixture.java new file mode 100644 index 0000000..cea8427 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailDetailFixture.java @@ -0,0 +1,24 @@ +package gdsc.konkuk.platformcore.fixture.email; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EmailDetailFixture { + private final EmailDetail fixture; + + @Builder + public EmailDetailFixture(String subject, String content) { + this.fixture = EmailDetail.builder() + .subject(getDefault(subject, "subject")) + .content(getDefault(content, """ + 안녕하세요 {이름}! + 잘 지내시나요? + 다시 볼 날을 기대할게요 {이름}! + """)) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailReceiverFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailReceiverFixture.java new file mode 100644 index 0000000..8d91d4b --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailReceiverFixture.java @@ -0,0 +1,20 @@ +package gdsc.konkuk.platformcore.fixture.email; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.email.entity.EmailReceiver; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EmailReceiverFixture { + private final EmailReceiver fixture; + + @Builder + public EmailReceiverFixture(String email, String name) { + this.fixture = EmailReceiver.builder() + .email(getDefault(email, "ex@gmail.com")) + .name(getDefault(name, "guest")) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailReceiverInfosFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailReceiverInfosFixture.java new file mode 100644 index 0000000..c4355e3 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailReceiverInfosFixture.java @@ -0,0 +1,26 @@ +package gdsc.konkuk.platformcore.fixture.email; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.controller.email.dtos.EmailReceiverInfo; +import java.util.Set; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EmailReceiverInfosFixture { + private final Set fixture; + + @Builder + public EmailReceiverInfosFixture(Set emailReceiverInfos) { + this.fixture = getDefault(emailReceiverInfos, Set.of( + EmailReceiverInfo.builder() + .email("ex1@gmail.com") + .name("guest1") + .build(), + EmailReceiverInfo.builder() + .email("ex2@gmail.com") + .name("guest2") + .build())); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailSendRequestFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailSendRequestFixture.java new file mode 100644 index 0000000..e32a680 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailSendRequestFixture.java @@ -0,0 +1,26 @@ +package gdsc.konkuk.platformcore.fixture.email; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.controller.email.dtos.EmailReceiverInfo; +import gdsc.konkuk.platformcore.controller.email.dtos.EmailSendRequest; +import java.time.LocalDateTime; + +import java.util.Set; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EmailSendRequestFixture { + private final EmailSendRequest fixture; + + @Builder + public EmailSendRequestFixture(String subject, String content, LocalDateTime sendAt, Set receiverInfos) { + this.fixture = EmailSendRequest.builder() + .subject(getDefault(subject, "subject")) + .content(getDefault(content, "content")) + .sendAt(getDefault(sendAt, LocalDateTime.now().plusHours(1))) + .receiverInfos(getDefault(receiverInfos, EmailReceiverInfosFixture.builder().build().getFixture())) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailTaskFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailTaskFixture.java new file mode 100644 index 0000000..71df989 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/email/EmailTaskFixture.java @@ -0,0 +1,31 @@ +package gdsc.konkuk.platformcore.fixture.email; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.email.entity.EmailDetail; +import gdsc.konkuk.platformcore.domain.email.entity.EmailReceivers; +import gdsc.konkuk.platformcore.domain.email.entity.EmailTask; +import java.time.LocalDateTime; +import java.util.Set; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EmailTaskFixture { + private final EmailTask fixture; + + @Builder + public EmailTaskFixture(Long id, EmailDetail emailDetail, EmailReceivers receivers, LocalDateTime sendAt) { + this.fixture = + EmailTask.builder() + .id(getDefault(id, 0L)) + .emailDetail(getDefault(emailDetail, EmailDetailFixture.builder().build().getFixture())) + .receivers(getDefault( + receivers, + new EmailReceivers(Set.of( + EmailReceiverFixture.builder().email("ex1@gmail.com").name("guest1").build().getFixture(), + EmailReceiverFixture.builder().email("ex2@gmail.com").name("guest2").build().getFixture())))) + .sendAt(getDefault(sendAt, LocalDateTime.now().plusHours(1))) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventBriefResponseFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventBriefResponseFixture.java new file mode 100644 index 0000000..6a23ffc --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventBriefResponseFixture.java @@ -0,0 +1,28 @@ +package gdsc.konkuk.platformcore.fixture.event; + +import static gdsc.konkuk.platformcore.application.event.EventMapper.mapEventListToEventBriefList; +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.application.event.dtos.EventBrief; +import gdsc.konkuk.platformcore.controller.event.dtos.EventBriefResponse; +import java.net.MalformedURLException; +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EventBriefResponseFixture { + private final EventBriefResponse fixture; + + @Builder + public EventBriefResponseFixture(List eventBriefs) throws MalformedURLException { + this.fixture = EventBriefResponse.builder() + .eventBriefs(getDefault(eventBriefs, mapEventListToEventBriefList( + List.of( + EventFixture.builder().id(1L).build().getFixture(), + EventFixture.builder().id(2L).build().getFixture(), + EventFixture.builder().id(3L).build().getFixture() + )))) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventFixture.java new file mode 100644 index 0000000..6cfcee7 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventFixture.java @@ -0,0 +1,35 @@ +package gdsc.konkuk.platformcore.fixture.event; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.event.entity.Event; +import gdsc.konkuk.platformcore.domain.event.entity.EventImage; +import java.net.MalformedURLException; +import java.net.URL; +import java.time.LocalDateTime; +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EventFixture { + private final Event fixture; + + @Builder + public EventFixture(Long id, String title, String content, String location, LocalDateTime startAt, LocalDateTime endAt, List eventImageList, String retrospectContent) + throws MalformedURLException { + this.fixture = Event.builder() + .id(getDefault(id, 0L)) + .title(getDefault(title, "title")) + .content(getDefault(content, "content")) + .location(getDefault(location, "location")) + .startAt(getDefault(startAt, LocalDateTime.now())) + .endAt(getDefault(endAt, LocalDateTime.now().plusHours(1))) + .eventImageList(getDefault(eventImageList, List.of( + EventImageFixture.builder().url(new URL("https://s3.com/foo/bar1.png")).build().getFixture(), + EventImageFixture.builder().url(new URL("https://s3.com/foo/bar2.jpeg")).build().getFixture() + ))) + .retrospectContent(getDefault(retrospectContent, "retrospect")) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventImageFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventImageFixture.java new file mode 100644 index 0000000..bd2d058 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventImageFixture.java @@ -0,0 +1,22 @@ +package gdsc.konkuk.platformcore.fixture.event; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.event.entity.EventImage; +import java.net.MalformedURLException; +import java.net.URL; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EventImageFixture { + private final EventImage fixture; + + @Builder + public EventImageFixture(Long eventId, URL url) throws MalformedURLException { + this.fixture = EventImage.builder() + .eventId(getDefault(eventId, 0L)) + .url(getDefault(url, new URL("https://example.com/foo/bar.jpg"))) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventRegisterRequestFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventRegisterRequestFixture.java new file mode 100644 index 0000000..fa0e887 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventRegisterRequestFixture.java @@ -0,0 +1,24 @@ +package gdsc.konkuk.platformcore.fixture.event; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.controller.event.dtos.EventRegisterRequest; +import java.time.LocalDateTime; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EventRegisterRequestFixture { + private final EventRegisterRequest fixture; + + @Builder + public EventRegisterRequestFixture(String title, String content, String location, LocalDateTime startAt, LocalDateTime endAt) { + this.fixture = EventRegisterRequest.builder() + .title(getDefault(title, "title")) + .content(getDefault(content, "content")) + .location(getDefault(location, "location")) + .startAt(getDefault(startAt, LocalDateTime.now())) + .endAt(getDefault(endAt, LocalDateTime.now().plusHours(1))) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventUpdateRequestFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventUpdateRequestFixture.java new file mode 100644 index 0000000..a6184f3 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventUpdateRequestFixture.java @@ -0,0 +1,32 @@ +package gdsc.konkuk.platformcore.fixture.event; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.controller.event.dtos.EventUpdateRequest; +import java.net.MalformedURLException; +import java.net.URL; +import java.time.LocalDateTime; +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EventUpdateRequestFixture { + private final EventUpdateRequest fixture; + + @Builder + public EventUpdateRequestFixture(String title, String content, String location, LocalDateTime startAt, LocalDateTime endAt, List eventImagesToDelete) + throws MalformedURLException { + this.fixture = EventUpdateRequest.builder() + .title(getDefault(title, "title")) + .content(getDefault(content, "content")) + .location(getDefault(location, "location")) + .startAt(getDefault(startAt, LocalDateTime.now())) + .endAt(getDefault(endAt, LocalDateTime.now().plusHours(1))) + .eventImagesToDelete(getDefault(eventImagesToDelete, List.of( + EventImageFixture.builder().url(new URL("https://s3.com/foo/bar1.png")).build().getFixture().getUrl(), + EventImageFixture.builder().url(new URL("https://s3.com/foo/bar2.jpeg")).build().getFixture().getUrl() + ))) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventWithAttendanceFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventWithAttendanceFixture.java new file mode 100644 index 0000000..0fdbbea --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/event/EventWithAttendanceFixture.java @@ -0,0 +1,23 @@ +package gdsc.konkuk.platformcore.fixture.event; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.application.event.dtos.EventWithAttendance; +import java.time.LocalDateTime; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class EventWithAttendanceFixture { + private final EventWithAttendance fixture; + + @Builder + public EventWithAttendanceFixture(Long eventId, Long attendanceId, String title, LocalDateTime startAt) { + this.fixture = EventWithAttendance.builder() + .eventId(getDefault(eventId, 0L)) + .attendanceId(getDefault(attendanceId, null)) + .title(getDefault(title, "title")) + .startAt(getDefault(startAt, LocalDateTime.now())) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberAttendancesFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberAttendancesFixture.java new file mode 100644 index 0000000..7ca9ff9 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberAttendancesFixture.java @@ -0,0 +1,53 @@ +package gdsc.konkuk.platformcore.fixture.member; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.application.attendance.dtos.MemberAttendanceInfo; +import gdsc.konkuk.platformcore.application.member.dtos.MemberAttendances; +import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; +import java.time.LocalDateTime; +import java.util.List; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class MemberAttendancesFixture { + private final MemberAttendances fixture; + + @Builder + public MemberAttendancesFixture(Long memberId, String memberName, MemberRole memberRole, String department, Long totalAttendances, Long actualAttendances, List attendanceInfoList) { + this.fixture = MemberAttendances.builder() + .memberId(getDefault(memberId, 0L)) + .memberName(getDefault(memberName, "name")) + .memberRole(getDefault(memberRole, MemberRole.MEMBER)) + .department(getDefault(department, "department")) + .totalAttendances(getDefault(totalAttendances, 3L)) + .actualAttendances(getDefault(actualAttendances, 2L)) + .attendanceInfoList(getDefault(attendanceInfoList, List.of( + MemberAttendanceInfo.builder() + .attendanceId(0L) + .memberId(0L) + .eventId(0L) + .participantId(0L) + .attendanceDate(LocalDateTime.now()) + .isAttended(true) + .build(), + MemberAttendanceInfo.builder() + .attendanceId(1L) + .memberId(0L) + .eventId(1L) + .participantId(1L) + .attendanceDate(LocalDateTime.now().plusDays(3)) + .isAttended(false) + .build(), + MemberAttendanceInfo.builder() + .attendanceId(2L) + .memberId(0L) + .eventId(2L) + .participantId(2L) + .attendanceDate(LocalDateTime.now().plusDays(5)) + .isAttended(true) + .build()))) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberFixture.java new file mode 100644 index 0000000..2002172 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberFixture.java @@ -0,0 +1,27 @@ +package gdsc.konkuk.platformcore.fixture.member; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.domain.member.entity.Member; +import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class MemberFixture { + private final Member fixture; + + @Builder + public MemberFixture(Long id, String memberId, String password, String name, String email, String department, MemberRole role, String batch) { + this.fixture = Member.builder() + .id(getDefault(id, 0L)) + .memberId(getDefault(memberId, "202400000")) + .password(getDefault(password, "$2a$10$d7DjseDroHsRGVGR1zDUL.q7uwAQ2aH4nHM1JiQ1OFV.D0qUTl7w." /* == encoded "password" */)) + .name(getDefault(name, "name")) + .email(getDefault(email, "ex@gmail.com")) + .department(getDefault(department, "department")) + .role(getDefault(role, MemberRole.MEMBER).toString()) + .batch(getDefault(batch, "24-25")) + .build(); + } +} diff --git a/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberRegisterRequestFixture.java b/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberRegisterRequestFixture.java new file mode 100644 index 0000000..d60c667 --- /dev/null +++ b/src/test/java/gdsc/konkuk/platformcore/fixture/member/MemberRegisterRequestFixture.java @@ -0,0 +1,26 @@ +package gdsc.konkuk.platformcore.fixture.member; + +import static gdsc.konkuk.platformcore.global.utils.GetDefault.getDefault; + +import gdsc.konkuk.platformcore.controller.member.dtos.MemberRegisterRequest; +import gdsc.konkuk.platformcore.domain.member.entity.MemberRole; +import lombok.Builder; +import lombok.Getter; + +@Getter +public class MemberRegisterRequestFixture { + private final MemberRegisterRequest fixture; + + @Builder + public MemberRegisterRequestFixture(String memberId, String password, String email, String name, String department, String batch, MemberRole role) { + this.fixture = MemberRegisterRequest.builder() + .memberId(getDefault(memberId, "2024000000")) + .password(getDefault(password, "password")) + .email(getDefault(email, "ex@gmail.com")) + .name(getDefault(name, "name")) + .department(getDefault(department, "department")) + .batch(getDefault(batch, "24-25")) + .role(getDefault(role, MemberRole.MEMBER).toString()) + .build(); + } +}