From 5cdbbd9b52eff0f1da63a6068b884479861d525b Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Mon, 22 Jul 2024 21:47:29 +0900 Subject: [PATCH 01/12] =?UTF-8?q?:sparkles:=20[STMT-263]=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=EC=A0=84=EC=97=AD=20=EC=B2=98=EB=A6=AC=EA=B8=B0:?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=20=EC=B6=94=EC=A0=81=20=EA=B2=B0=EA=B3=BC?= =?UTF-8?q?=20=EC=B6=9C=EB=A0=A5=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/handler/GlobalExceptionHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/stumeet/server/common/exception/handler/GlobalExceptionHandler.java b/src/main/java/com/stumeet/server/common/exception/handler/GlobalExceptionHandler.java index 4f3d4e23..e54f15e3 100644 --- a/src/main/java/com/stumeet/server/common/exception/handler/GlobalExceptionHandler.java +++ b/src/main/java/com/stumeet/server/common/exception/handler/GlobalExceptionHandler.java @@ -38,6 +38,7 @@ public class GlobalExceptionHandler { protected ResponseEntity handleSecurityViolationException(final SecurityViolationException e) { log.warn(SECURITY_LOG_MESSAGE, e.getClass().getSimpleName(), e.getMessage()); log.debug(e.getMessage(), e); + e.printStackTrace(); ErrorCode errorCode = e.getErrorCode(); ApiResponse response = ApiResponse.fail(errorCode); @@ -50,6 +51,7 @@ protected ResponseEntity handleSecurityViolationException(final Sec protected ResponseEntity handleBusinessException(final BusinessException e) { log.warn(WARN_LOG_MESSAGE, e.getClass().getSimpleName(), e.getMessage()); log.debug(e.getMessage(), e); + e.printStackTrace(); ErrorCode errorCode = e.getErrorCode(); ApiResponse response = ApiResponse.fail(errorCode); @@ -129,6 +131,7 @@ protected ResponseEntity handleMaxUploadSizeExceededException(final @ExceptionHandler(BadRequestException.class) protected ResponseEntity handleCustomBadRequestException(final BadRequestException e) { log.warn(ERROR_LOG_MESSAGE, e.getClass().getSimpleName(), e.getMessage()); + e.printStackTrace(); String message = String.format("%s %s", e.getErrorCode().getMessage(), e.getMessage()); ApiResponse response = ApiResponse.fail(e.getErrorCode().getHttpStatusCode(), message); From 9fd63123cd12ed63cdd9aad3e06f98ba9b00c347 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:11:59 +0900 Subject: [PATCH 02/12] =?UTF-8?q?:sparkles:=20[STMT-263]=20activity=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=A9=94=EC=84=9C=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../port/in/mapper/ActivityUseCaseMapper.java | 152 ++++++++++-------- .../service/ActivityCreateService.java | 18 +-- .../service/model/ActivityModifySource.java | 25 +++ ...yCreateSource.java => ActivitySource.java} | 2 +- .../activity/domain/model/Activity.java | 18 ++- .../domain/model/ActivityCategory.java | 13 +- .../service/ActivityCreateServiceTest.java | 11 +- 7 files changed, 149 insertions(+), 90 deletions(-) create mode 100644 src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java rename src/main/java/com/stumeet/server/activity/application/service/model/{ActivityCreateSource.java => ActivitySource.java} (94%) diff --git a/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java b/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java index dc540eea..033670e0 100644 --- a/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java +++ b/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java @@ -7,7 +7,8 @@ import com.stumeet.server.activity.adapter.in.response.ActivityParticipantSimpleResponse; import com.stumeet.server.activity.adapter.in.response.PageInfoResponse; import com.stumeet.server.activity.application.port.in.command.ActivityCreateCommand; -import com.stumeet.server.activity.application.service.model.ActivityCreateSource; +import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; +import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.domain.model.Activity; import com.stumeet.server.activity.domain.model.ActivityCategory; @@ -23,73 +24,92 @@ @RequiredArgsConstructor public class ActivityUseCaseMapper { - private final ActivityParticipantUseCaseMapper activityParticipantUseCaseMapper; + private final ActivityParticipantUseCaseMapper activityParticipantUseCaseMapper; - public ActivityCreateSource toSource(Long studyId, ActivityCreateCommand command, Long id) { - return ActivityCreateSource.builder() - .id(null) - .studyId(studyId) - .author(ActivityCreateSource.ActivityMemberCreateSource.builder() - .id(id) - .build()) - .category(ActivityCategory.getByName(command.category())) - .title(command.title()) - .content(command.content()) - .location(command.location()) - .link(command.link()) - .startDate(command.startDate()) - .endDate(command.endDate()) - .isNotice(command.isNotice()) - .createdAt(LocalDateTime.now()) - .build(); - } + public ActivitySource toCreateSource(Long studyId, ActivityCreateCommand command, Long id) { + return ActivitySource.builder() + .id(null) + .studyId(studyId) + .author(ActivitySource.ActivityMemberCreateSource.builder() + .id(id) + .build()) + .category(ActivityCategory.getByName(command.category())) + .title(command.title()) + .content(command.content()) + .location(command.location()) + .link(command.link()) + .startDate(command.startDate()) + .endDate(command.endDate()) + .isNotice(command.isNotice()) + .createdAt(LocalDateTime.now()) + .build(); + } - public ActivityDetailResponse toDetailResponse( - Activity activity, - List activityImages, - ActivityParticipantSimpleResponse author, - List participants, - String status - ) { - return ActivityDetailResponse.builder() - .id(activity.getId()) - .category(activity.getCategory().name()) - .title(activity.getTitle()) - .content(activity.getContent()) - .imageUrl(activityImages) - .author(author) - .participants(participants) - .status(status) - .startDate(activity.getStartDate()) - .endDate(activity.getEndDate()) - .location(activity.getLocation()) - .createdAt(activity.getCreatedAt()) - .build(); - } + public ActivitySource toModifySource(Activity exist, ActivityModifyCommand command) { + return ActivitySource.builder() + .id(exist.getId()) + .studyId(exist.getStudy().getId()) + .author(ActivitySource.ActivityMemberCreateSource.builder() + .id(exist.getAuthor().getId()) + .build()) + .category(ActivityCategory.getByName(command.category())) + .title(command.title()) + .content(command.content()) + .location(command.location()) + .link(command.link()) + .startDate(command.startDate()) + .endDate(command.endDate()) + .isNotice(command.isNotice()) + .createdAt(exist.getCreatedAt()) + .build(); + } - private ActivityListDetailedPageResponse toListDetailedPageResponse(Activity activity) { - return ActivityListDetailedPageResponse.builder() - .id(activity.getId()) - .category(activity.getCategory().name()) - .title(activity.getTitle()) - .content(activity.getContent()) - .startDate(activity.getStartDate()) - .endDate(activity.getEndDate()) - .location(activity.getLocation()) - .author(activityParticipantUseCaseMapper.toResponse(activity.getAuthor())) - .createdAt(activity.getCreatedAt()) - .build(); - } + public ActivityDetailResponse toDetailResponse( + Activity activity, + List activityImages, + ActivityParticipantSimpleResponse author, + List participants, + String status + ) { + return ActivityDetailResponse.builder() + .id(activity.getId()) + .category(activity.getCategory().name()) + .title(activity.getTitle()) + .content(activity.getContent()) + .imageUrl(activityImages) + .author(author) + .participants(participants) + .status(status) + .startDate(activity.getStartDate()) + .endDate(activity.getEndDate()) + .location(activity.getLocation()) + .createdAt(activity.getCreatedAt()) + .build(); + } - public ActivityListDetailedPageResponses toListDetailedPageResponses( - Page activities, - PageInfoResponse pageInfoResponse - ) { - return ActivityListDetailedPageResponses.builder() - .items(activities.stream() - .map(this::toListDetailedPageResponse) - .toList()) - .pageInfo(pageInfoResponse) - .build(); - } + private ActivityListDetailedPageResponse toListDetailedPageResponse(Activity activity) { + return ActivityListDetailedPageResponse.builder() + .id(activity.getId()) + .category(activity.getCategory().name()) + .title(activity.getTitle()) + .content(activity.getContent()) + .startDate(activity.getStartDate()) + .endDate(activity.getEndDate()) + .location(activity.getLocation()) + .author(activityParticipantUseCaseMapper.toResponse(activity.getAuthor())) + .createdAt(activity.getCreatedAt()) + .build(); + } + + public ActivityListDetailedPageResponses toListDetailedPageResponses( + Page activities, + PageInfoResponse pageInfoResponse + ) { + return ActivityListDetailedPageResponses.builder() + .items(activities.stream() + .map(this::toListDetailedPageResponse) + .toList()) + .pageInfo(pageInfoResponse) + .build(); + } } \ No newline at end of file diff --git a/src/main/java/com/stumeet/server/activity/application/service/ActivityCreateService.java b/src/main/java/com/stumeet/server/activity/application/service/ActivityCreateService.java index 504496e1..5ffc1259 100644 --- a/src/main/java/com/stumeet/server/activity/application/service/ActivityCreateService.java +++ b/src/main/java/com/stumeet/server/activity/application/service/ActivityCreateService.java @@ -1,12 +1,12 @@ package com.stumeet.server.activity.application.service; import com.stumeet.server.activity.application.port.in.ActivityCreateUseCase; -import com.stumeet.server.activity.application.service.model.ActivityCreateSource; +import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.application.port.in.command.ActivityCreateCommand; import com.stumeet.server.activity.application.port.in.mapper.ActivityImageUseCaseMapper; import com.stumeet.server.activity.application.port.in.mapper.ActivityParticipantUseCaseMapper; import com.stumeet.server.activity.application.port.in.mapper.ActivityUseCaseMapper; -import com.stumeet.server.activity.application.port.out.ActivityCreatePort; +import com.stumeet.server.activity.application.port.out.ActivitySavePort; import com.stumeet.server.activity.application.port.out.ActivityImageCreatePort; import com.stumeet.server.activity.application.port.out.ActivityParticipantCreatePort; import com.stumeet.server.activity.domain.model.Activity; @@ -25,7 +25,7 @@ @RequiredArgsConstructor public class ActivityCreateService implements ActivityCreateUseCase { - private final ActivityCreatePort activityCreatePort; + private final ActivitySavePort activitySavePort; private final ActivityImageCreatePort activityImageCreatePort; private final ActivityParticipantCreatePort activityParticipantPort; @@ -34,21 +34,21 @@ public class ActivityCreateService implements ActivityCreateUseCase { private final ActivityUseCaseMapper activityUseCaseMapper; private final ActivityImageUseCaseMapper activityImageUseCaseMapper; - private final ActivityParticipantUseCaseMapper activityMemberUseCaseMapper; + private final ActivityParticipantUseCaseMapper activityParticipantUseCaseMapper; @Override public void create(Long studyId, ActivityCreateCommand command, Long memberId) { studyValidationUseCase.checkById(studyId); studyMemberValidationUseCase.checkStudyJoinMember(studyId, memberId); - ActivityCreateSource activitySource = activityUseCaseMapper.toSource(studyId, command, memberId); + ActivitySource activitySource = activityUseCaseMapper.toCreateSource(studyId, command, memberId); Activity activity = activitySource.category().create(activitySource); - Activity createdActivity = activityCreatePort.create(activity); + Activity createdActivity = activitySavePort.save(activity); + + List participants = activityParticipantUseCaseMapper.toDomains(command.participants(), createdActivity); + activityParticipantPort.create(participants); List images = activityImageUseCaseMapper.toDomains(command.images(), createdActivity); activityImageCreatePort.create(images); - - List participants = activityMemberUseCaseMapper.toDomains(command.participants(), createdActivity); - activityParticipantPort.create(participants); } } diff --git a/src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java b/src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java new file mode 100644 index 00000000..97866949 --- /dev/null +++ b/src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java @@ -0,0 +1,25 @@ +package com.stumeet.server.activity.application.service.model; + +import java.time.LocalDateTime; + +import com.stumeet.server.activity.domain.model.ActivityCategory; +import com.stumeet.server.activity.domain.model.ActivityMember; + +import lombok.Builder; + +@Builder +public record ActivityModifySource( + Long id, + Long studyId, + ActivityMember author, + ActivityCategory category, + String title, + String content, + LocalDateTime startDate, + LocalDateTime endDate, + String location, + String link, + boolean isNotice, + LocalDateTime createdAt +) { +} diff --git a/src/main/java/com/stumeet/server/activity/application/service/model/ActivityCreateSource.java b/src/main/java/com/stumeet/server/activity/application/service/model/ActivitySource.java similarity index 94% rename from src/main/java/com/stumeet/server/activity/application/service/model/ActivityCreateSource.java rename to src/main/java/com/stumeet/server/activity/application/service/model/ActivitySource.java index ce3d23f1..3a50f983 100644 --- a/src/main/java/com/stumeet/server/activity/application/service/model/ActivityCreateSource.java +++ b/src/main/java/com/stumeet/server/activity/application/service/model/ActivitySource.java @@ -6,7 +6,7 @@ import java.time.LocalDateTime; @Builder -public record ActivityCreateSource( +public record ActivitySource( Long id, Long studyId, ActivityMemberCreateSource author, diff --git a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java index 3b4252db..49d710a8 100644 --- a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java +++ b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java @@ -5,8 +5,10 @@ import lombok.Getter; import java.time.LocalDateTime; +import java.util.Objects; -import org.springframework.cglib.core.Local; +import com.stumeet.server.activity.application.service.model.ActivitySource; +import com.stumeet.server.activity.domain.exception.ActivityManagementAccessDeniedException; @AllArgsConstructor(access = AccessLevel.PROTECTED) @Getter @@ -36,4 +38,18 @@ public abstract class Activity { private LocalDateTime createdAt; + public Activity modify(Long memberId, ActivitySource source) { + validateAuthor(memberId); + return source.category().create(source); + } + + private void validateAuthor(Long memberId) { + if(!isAuthor(memberId)) { + throw new ActivityManagementAccessDeniedException(); + } + } + + private boolean isAuthor(Long memberId) { + return Objects.equals(this.author.getId(), memberId); + } } diff --git a/src/main/java/com/stumeet/server/activity/domain/model/ActivityCategory.java b/src/main/java/com/stumeet/server/activity/domain/model/ActivityCategory.java index 01000095..f087a78d 100644 --- a/src/main/java/com/stumeet/server/activity/domain/model/ActivityCategory.java +++ b/src/main/java/com/stumeet/server/activity/domain/model/ActivityCategory.java @@ -1,6 +1,6 @@ package com.stumeet.server.activity.domain.model; -import com.stumeet.server.activity.application.service.model.ActivityCreateSource; +import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.domain.exception.NotExistsActivityCategoryException; import lombok.Getter; @@ -13,7 +13,7 @@ public enum ActivityCategory { DEFAULT(DefaultStatus.NONE) { @Override - public Activity create(ActivityCreateSource source) { + public Activity create(ActivitySource source) { return Default.builder() .id(source.id()) .study(ActivityLinkedStudy.builder().id(source.studyId()).build()) @@ -35,7 +35,7 @@ public Activity create(ActivityCreateSource source) { MEET(MeetStatus.MEET_NOT_STARTED) { @Override - public Activity create(ActivityCreateSource source) { + public Activity create(ActivitySource source) { return Meet.builder() .id(source.id()) .study(ActivityLinkedStudy.builder().id(source.studyId()).build()) @@ -59,7 +59,7 @@ public Activity create(ActivityCreateSource source) { }, ASSIGNMENT(AssignmentStatus.ASSIGNMENT_NOT_STARTED) { @Override - public Activity create(ActivityCreateSource source) { + public Activity create(ActivitySource source) { return Assignment.builder() .id(source.id()) .study(ActivityLinkedStudy.builder().id(source.studyId()).build()) @@ -72,7 +72,7 @@ public Activity create(ActivityCreateSource source) { .category(source.category()) .title(source.title()) .content(source.content()) - .link(source.content()) + .link(source.link()) .startDate(source.startDate()) .endDate(source.endDate()) .isNotice(source.isNotice()) @@ -90,6 +90,5 @@ public static ActivityCategory getByName(String category) { .orElseThrow(() -> new NotExistsActivityCategoryException(category)); } - public abstract Activity create(ActivityCreateSource source); - + public abstract Activity create(ActivitySource source); } diff --git a/src/test/java/com/stumeet/server/activity/application/service/ActivityCreateServiceTest.java b/src/test/java/com/stumeet/server/activity/application/service/ActivityCreateServiceTest.java index 56ebce83..53247160 100644 --- a/src/test/java/com/stumeet/server/activity/application/service/ActivityCreateServiceTest.java +++ b/src/test/java/com/stumeet/server/activity/application/service/ActivityCreateServiceTest.java @@ -4,7 +4,7 @@ import com.stumeet.server.activity.application.port.in.mapper.ActivityImageUseCaseMapper; import com.stumeet.server.activity.application.port.in.mapper.ActivityParticipantUseCaseMapper; import com.stumeet.server.activity.application.port.in.mapper.ActivityUseCaseMapper; -import com.stumeet.server.activity.application.port.out.ActivityCreatePort; +import com.stumeet.server.activity.application.port.out.ActivitySavePort; import com.stumeet.server.activity.application.port.out.ActivityImageCreatePort; import com.stumeet.server.activity.application.port.out.ActivityParticipantCreatePort; import com.stumeet.server.activity.domain.model.Activity; @@ -14,7 +14,6 @@ import com.stumeet.server.study.application.port.in.StudyValidationUseCase; import com.stumeet.server.study.domain.exception.StudyNotExistsException; import com.stumeet.server.studymember.application.port.in.StudyMemberValidationUseCase; -import com.stumeet.server.studymember.domain.exception.NotStudyAdminException; import com.stumeet.server.studymember.domain.exception.StudyMemberNotJoinedException; import com.stumeet.server.template.UnitTest; import org.junit.jupiter.api.DisplayName; @@ -35,7 +34,7 @@ class ActivityCreateServiceTest extends UnitTest { private ActivityCreateService activityCreateService; @Mock - private ActivityCreatePort activityCreatePort; + private ActivitySavePort activitySavePort; @Mock private ActivityImageCreatePort activityImageCreatePort; @@ -71,9 +70,9 @@ void successTest() { ActivityCreateCommand request = ActivityStub.getDefaultActivityCreateCommand(); Activity activity = ActivityStub.getDefaultActivity(); - given(activityUseCaseMapper.toSource(any(), any(), any())) + given(activityUseCaseMapper.toCreateSource(any(), any(), any())) .willReturn(ActivityStub.getDefaultCreateSource()); - given(activityCreatePort.create(any())) + given(activitySavePort.save(any())) .willReturn(ActivityStub.getDefaultActivity()); given(activityImageUseCaseMapper.toDomains(any(), any())) .willReturn(ActivityStub.getActivityImages(activity)); @@ -82,7 +81,7 @@ void successTest() { activityCreateService.create(studyId, request, memberId); - then(activityCreatePort).should().create(any()); + then(activitySavePort).should().save(any()); then(activityImageCreatePort).should().create(any()); then(activityParticipantPort).should().create(any()); } From ea1c0280950df85e95aeb70492b3641dabad75ab Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:17:45 +0900 Subject: [PATCH 03/12] =?UTF-8?q?:sparkles:=20[STMT-263]=20activity=20imag?= =?UTF-8?q?e=20update=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../out/persistence/ActivityImagePersistenceAdapter.java | 6 ++++++ .../application/port/out/ActivityImageCommandPort.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityImagePersistenceAdapter.java b/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityImagePersistenceAdapter.java index 69858228..70e2817d 100644 --- a/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityImagePersistenceAdapter.java +++ b/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityImagePersistenceAdapter.java @@ -40,4 +40,10 @@ public void deleteAllByActivityId(Long studyId, Long activityId) { jpaActivityImageRepository.deleteAllByActivityId(activityId); EventPublisher.raise(new ActivityImageDeleteEvent(this, studyId, activityId)); } + + @Override + public void update(Long activityId, List activityImages) { + jpaActivityImageRepository.deleteAllByActivityId(activityId); + create(activityImages); + } } diff --git a/src/main/java/com/stumeet/server/activity/application/port/out/ActivityImageCommandPort.java b/src/main/java/com/stumeet/server/activity/application/port/out/ActivityImageCommandPort.java index 25220621..cbc0d9d2 100644 --- a/src/main/java/com/stumeet/server/activity/application/port/out/ActivityImageCommandPort.java +++ b/src/main/java/com/stumeet/server/activity/application/port/out/ActivityImageCommandPort.java @@ -1,6 +1,12 @@ package com.stumeet.server.activity.application.port.out; +import java.util.List; + +import com.stumeet.server.activity.domain.model.ActivityImage; + public interface ActivityImageCommandPort { void deleteAllByActivityId(Long studyId, Long activityId); + + void update(Long activityId, List activityImages); } From ff1227598df661d1276b4cd325a6b174190cff4d Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:18:13 +0900 Subject: [PATCH 04/12] =?UTF-8?q?:sparkles:=20[STMT-263]=20activity=20part?= =?UTF-8?q?icipant=20update=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/ActivityParticipantPersistenceAdapter.java | 6 ++++++ .../port/out/ActivityParticipantCommandPort.java | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityParticipantPersistenceAdapter.java b/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityParticipantPersistenceAdapter.java index 007324ba..8dff5617 100644 --- a/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityParticipantPersistenceAdapter.java +++ b/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityParticipantPersistenceAdapter.java @@ -37,4 +37,10 @@ public List findAllByActivityId(Long activityId) { public void deleteByActivityId(Long activityId) { jpaActivityParticipantRepository.deleteAllByActivityId(activityId); } + + @Override + public void update(Long activityId, List participants) { + deleteByActivityId(activityId); + create(participants); + } } diff --git a/src/main/java/com/stumeet/server/activity/application/port/out/ActivityParticipantCommandPort.java b/src/main/java/com/stumeet/server/activity/application/port/out/ActivityParticipantCommandPort.java index 1aa3d03f..a2a95403 100644 --- a/src/main/java/com/stumeet/server/activity/application/port/out/ActivityParticipantCommandPort.java +++ b/src/main/java/com/stumeet/server/activity/application/port/out/ActivityParticipantCommandPort.java @@ -1,6 +1,12 @@ package com.stumeet.server.activity.application.port.out; +import java.util.List; + +import com.stumeet.server.activity.domain.model.ActivityParticipant; + public interface ActivityParticipantCommandPort { void deleteByActivityId(Long activityId); + + void update(Long activityId, List participants); } From e8b8160cb47e76a03615a1bd5167c54de1e21e90 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:24:54 +0900 Subject: [PATCH 05/12] =?UTF-8?q?:recycle:=20[STMT-263]=20activity=20creat?= =?UTF-8?q?e=20->=20save=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../out/mapper/ActivityPersistenceMapper.java | 6 +- .../ActivityPersistenceAdapter.java | 102 +++++++++--------- ...yCreatePort.java => ActivitySavePort.java} | 4 +- 3 files changed, 56 insertions(+), 56 deletions(-) rename src/main/java/com/stumeet/server/activity/application/port/out/{ActivityCreatePort.java => ActivitySavePort.java} (60%) diff --git a/src/main/java/com/stumeet/server/activity/adapter/out/mapper/ActivityPersistenceMapper.java b/src/main/java/com/stumeet/server/activity/adapter/out/mapper/ActivityPersistenceMapper.java index 72df7146..db920e34 100644 --- a/src/main/java/com/stumeet/server/activity/adapter/out/mapper/ActivityPersistenceMapper.java +++ b/src/main/java/com/stumeet/server/activity/adapter/out/mapper/ActivityPersistenceMapper.java @@ -5,7 +5,7 @@ import com.stumeet.server.activity.adapter.out.model.ActivityJpaEntity; import com.stumeet.server.activity.adapter.out.model.ActivityLinkedStudyJpaEntity; import com.stumeet.server.activity.adapter.out.model.ActivityMemberJpaEntity; -import com.stumeet.server.activity.application.service.model.ActivityCreateSource; +import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.domain.model.Activity; import com.stumeet.server.activity.domain.model.Meet; @@ -17,9 +17,9 @@ public class ActivityPersistenceMapper { public Activity toDomain(ActivityJpaEntity entity) { - ActivityCreateSource request = ActivityCreateSource.builder() + ActivitySource request = ActivitySource.builder() .id(entity.getId()) - .author(ActivityCreateSource.ActivityMemberCreateSource.builder() + .author(ActivitySource.ActivityMemberCreateSource.builder() .id(entity.getAuthor().getId()) .name(entity.getAuthor().getName()) .image(entity.getAuthor().getImage()) diff --git a/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityPersistenceAdapter.java b/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityPersistenceAdapter.java index decc28f8..bbe1cea1 100644 --- a/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityPersistenceAdapter.java +++ b/src/main/java/com/stumeet/server/activity/adapter/out/persistence/ActivityPersistenceAdapter.java @@ -10,7 +10,7 @@ import com.stumeet.server.activity.adapter.out.mapper.ActivityPersistenceMapper; import com.stumeet.server.activity.adapter.out.model.ActivityJpaEntity; import com.stumeet.server.activity.application.port.out.ActivityAuthorValidationPort; -import com.stumeet.server.activity.application.port.out.ActivityCreatePort; +import com.stumeet.server.activity.application.port.out.ActivitySavePort; import com.stumeet.server.activity.application.port.out.ActivityDeletePort; import com.stumeet.server.activity.application.port.out.ActivityQueryPort; import com.stumeet.server.activity.domain.exception.NotExistsActivityException; @@ -22,54 +22,54 @@ @PersistenceAdapter @RequiredArgsConstructor -public class ActivityPersistenceAdapter implements ActivityCreatePort, ActivityQueryPort, ActivityAuthorValidationPort, ActivityDeletePort { - - private final JpaActivityRepository jpaActivityRepository; - private final ActivityPersistenceMapper activityPersistenceMapper; - - @Override - public Activity create(Activity activity) { - ActivityJpaEntity entity = activityPersistenceMapper.toEntity(activity); - - return activityPersistenceMapper.toDomain(jpaActivityRepository.save(entity)); - } - - @Override - public Activity getById(Long activityId) { - ActivityJpaEntity entity = jpaActivityRepository.findById(activityId) - .orElseThrow(() -> new NotExistsActivityException(activityId)); - - return activityPersistenceMapper.toDomain(entity); - } - - @Override - public Page getDetailPagesByCondition(Pageable pageable, Boolean isNotice, Long studyId, ActivityCategory category) { - Page entities = - jpaActivityRepository.findDetailPagesByCondition(pageable, isNotice, studyId, category); - - return activityPersistenceMapper.toDomainPages(entities); - } - - @Override - public Page getPaginatedBriefsByCondition(Pageable pageable, Boolean isNotice, Long memberId, - Long studyId, ActivityCategory category, LocalDateTime startDate, LocalDateTime endDate) { - return jpaActivityRepository.findBriefsByConditionWithPagination(pageable, isNotice, memberId, studyId, category, startDate, endDate); - } - - @Override - public List getBriefsByCondition(Boolean isNotice, Long memberId, Long studyId, - ActivityCategory category, LocalDateTime startDate, LocalDateTime endDate) { - return jpaActivityRepository.findBriefsByCondition(isNotice, memberId, studyId, category, startDate, endDate); - } - - @Override - public boolean isNotActivityAuthor(Long memberId, Long activityId) { - return jpaActivityRepository.findByIdAndAuthorId(activityId, memberId) - .isEmpty(); - } - - @Override - public void deleteById(Long activityId) { - jpaActivityRepository.deleteById(activityId); - } +public class ActivityPersistenceAdapter implements ActivitySavePort, ActivityQueryPort, ActivityAuthorValidationPort, ActivityDeletePort { + + private final JpaActivityRepository jpaActivityRepository; + private final ActivityPersistenceMapper activityPersistenceMapper; + + @Override + public Activity save(Activity activity) { + ActivityJpaEntity entity = activityPersistenceMapper.toEntity(activity); + + return activityPersistenceMapper.toDomain(jpaActivityRepository.save(entity)); + } + + @Override + public Activity getById(Long activityId) { + ActivityJpaEntity entity = jpaActivityRepository.findById(activityId) + .orElseThrow(() -> new NotExistsActivityException(activityId)); + + return activityPersistenceMapper.toDomain(entity); + } + + @Override + public Page getDetailPagesByCondition(Pageable pageable, Boolean isNotice, Long studyId, ActivityCategory category) { + Page entities = + jpaActivityRepository.findDetailPagesByCondition(pageable, isNotice, studyId, category); + + return activityPersistenceMapper.toDomainPages(entities); + } + + @Override + public Page getPaginatedBriefsByCondition(Pageable pageable, Boolean isNotice, Long memberId, + Long studyId, ActivityCategory category, LocalDateTime startDate, LocalDateTime endDate) { + return jpaActivityRepository.findBriefsByConditionWithPagination(pageable, isNotice, memberId, studyId, category, startDate, endDate); + } + + @Override + public List getBriefsByCondition(Boolean isNotice, Long memberId, Long studyId, + ActivityCategory category, LocalDateTime startDate, LocalDateTime endDate) { + return jpaActivityRepository.findBriefsByCondition(isNotice, memberId, studyId, category, startDate, endDate); + } + + @Override + public boolean isNotActivityAuthor(Long memberId, Long activityId) { + return jpaActivityRepository.findByIdAndAuthorId(activityId, memberId) + .isEmpty(); + } + + @Override + public void deleteById(Long activityId) { + jpaActivityRepository.deleteById(activityId); + } } diff --git a/src/main/java/com/stumeet/server/activity/application/port/out/ActivityCreatePort.java b/src/main/java/com/stumeet/server/activity/application/port/out/ActivitySavePort.java similarity index 60% rename from src/main/java/com/stumeet/server/activity/application/port/out/ActivityCreatePort.java rename to src/main/java/com/stumeet/server/activity/application/port/out/ActivitySavePort.java index 7f97f4e1..2d10bffb 100644 --- a/src/main/java/com/stumeet/server/activity/application/port/out/ActivityCreatePort.java +++ b/src/main/java/com/stumeet/server/activity/application/port/out/ActivitySavePort.java @@ -2,6 +2,6 @@ import com.stumeet.server.activity.domain.model.Activity; -public interface ActivityCreatePort { - Activity create(Activity activity); +public interface ActivitySavePort { + Activity save(Activity activity); } From b4ea11c58c1d92fd9a24033c4d3bea2dd70a656c Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:25:34 +0900 Subject: [PATCH 06/12] =?UTF-8?q?:sparkles:=20[STMT-263]=20activity=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/ActivityModifyApi.java | 40 +++++++++++++ .../port/in/ActivityModifyUseCase.java | 8 +++ .../in/command/ActivityModifyCommand.java | 52 ++++++++++++++++ .../service/ActivityModifyService.java | 59 +++++++++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 src/main/java/com/stumeet/server/activity/adapter/in/ActivityModifyApi.java create mode 100644 src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java create mode 100644 src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityModifyCommand.java create mode 100644 src/main/java/com/stumeet/server/activity/application/service/ActivityModifyService.java diff --git a/src/main/java/com/stumeet/server/activity/adapter/in/ActivityModifyApi.java b/src/main/java/com/stumeet/server/activity/adapter/in/ActivityModifyApi.java new file mode 100644 index 00000000..e19ee02e --- /dev/null +++ b/src/main/java/com/stumeet/server/activity/adapter/in/ActivityModifyApi.java @@ -0,0 +1,40 @@ +package com.stumeet.server.activity.adapter.in; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +import com.stumeet.server.activity.application.port.in.ActivityModifyUseCase; +import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; +import com.stumeet.server.common.annotation.WebAdapter; +import com.stumeet.server.common.auth.model.LoginMember; +import com.stumeet.server.common.model.ApiResponse; +import com.stumeet.server.common.response.SuccessCode; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; + +@WebAdapter +@RequestMapping("/api/v1") +@RequiredArgsConstructor +public class ActivityModifyApi { + + private final ActivityModifyUseCase activityModifyUseCase; + + @PatchMapping("/studies/{studyId}/activities/{activityId}") + public ResponseEntity> modify( + @AuthenticationPrincipal LoginMember loginMember, + @PathVariable Long studyId, + @PathVariable Long activityId, + @RequestBody @Valid ActivityModifyCommand command + ) { + activityModifyUseCase.modify(loginMember.getId(), studyId, activityId, command); + + return ResponseEntity.status(HttpStatus.OK) + .body(ApiResponse.success(SuccessCode.UPDATE_SUCCESS)); + } +} diff --git a/src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java b/src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java new file mode 100644 index 00000000..c6122257 --- /dev/null +++ b/src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java @@ -0,0 +1,8 @@ +package com.stumeet.server.activity.application.port.in; + +import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; + +public interface ActivityModifyUseCase { + + void modify(Long memberId, Long studyId, Long activityId, ActivityModifyCommand command); +} diff --git a/src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityModifyCommand.java b/src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityModifyCommand.java new file mode 100644 index 00000000..62dfcb83 --- /dev/null +++ b/src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityModifyCommand.java @@ -0,0 +1,52 @@ +package com.stumeet.server.activity.application.port.in.command; + +import java.time.LocalDateTime; +import java.util.List; + +import org.springframework.format.annotation.DateTimeFormat; + +import com.stumeet.server.common.annotation.validator.NullOrNotBlank; + +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Builder; + +@Builder +public record ActivityModifyCommand( + @NotBlank(message = "활동 카테고리를 입력해주세요") + String category, + + @NotBlank(message = "활동 제목을 입력해주세요") + @Size(max = 100, message = "활동 제목은 100자 이하여야 합니다") + String title, + + @NotBlank(message = "활동 내용을 입력해주세요") + @Size(max = 500, message = "활동 내용은 500자 이하여야 합니다") + String content, + + @NotNull(message = "이미지 리스트를 전달해주세요") + @Size(max = 5, message = "이미지는 5개 이하로 등록할 수 있습니다") + List images, + + boolean isNotice, + + @Nullable + @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + LocalDateTime startDate, + + @Nullable + @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + LocalDateTime endDate, + + @NullOrNotBlank + String location, + + @NullOrNotBlank + String link, + + @NotNull(message = "참여 멤버 리스트를 전달해주세요") + List participants +) { +} diff --git a/src/main/java/com/stumeet/server/activity/application/service/ActivityModifyService.java b/src/main/java/com/stumeet/server/activity/application/service/ActivityModifyService.java new file mode 100644 index 00000000..baa7ba08 --- /dev/null +++ b/src/main/java/com/stumeet/server/activity/application/service/ActivityModifyService.java @@ -0,0 +1,59 @@ +package com.stumeet.server.activity.application.service; + +import java.util.List; + +import org.springframework.transaction.annotation.Transactional; + +import com.stumeet.server.activity.application.port.in.ActivityAuthorityValidationUseCase; +import com.stumeet.server.activity.application.port.in.ActivityModifyUseCase; +import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; +import com.stumeet.server.activity.application.port.in.mapper.ActivityImageUseCaseMapper; +import com.stumeet.server.activity.application.port.in.mapper.ActivityParticipantUseCaseMapper; +import com.stumeet.server.activity.application.port.in.mapper.ActivityUseCaseMapper; +import com.stumeet.server.activity.application.port.out.ActivityImageCommandPort; +import com.stumeet.server.activity.application.port.out.ActivityParticipantCommandPort; +import com.stumeet.server.activity.application.port.out.ActivitySavePort; +import com.stumeet.server.activity.application.port.out.ActivityQueryPort; +import com.stumeet.server.activity.application.service.model.ActivitySource; +import com.stumeet.server.activity.domain.model.Activity; +import com.stumeet.server.activity.domain.model.ActivityImage; +import com.stumeet.server.activity.domain.model.ActivityParticipant; +import com.stumeet.server.common.annotation.UseCase; +import com.stumeet.server.studymember.application.port.in.StudyMemberValidationUseCase; + +import lombok.RequiredArgsConstructor; + +@Transactional +@UseCase +@RequiredArgsConstructor +public class ActivityModifyService implements ActivityModifyUseCase { + + private final StudyMemberValidationUseCase studyMemberValidationUseCase; + private final ActivityAuthorityValidationUseCase activityAuthorityValidationUseCase; + + private final ActivityQueryPort activityQueryPort; + private final ActivitySavePort activitySavePort; + private final ActivityImageCommandPort activityImageCommandPort; + private final ActivityParticipantCommandPort activityParticipantCommandPort; + + private final ActivityUseCaseMapper activityUseCaseMapper; + private final ActivityImageUseCaseMapper activityImageUseCaseMapper; + private final ActivityParticipantUseCaseMapper activityParticipantUseCaseMapper; + + @Override + public void modify(Long memberId, Long studyId, Long activityId, ActivityModifyCommand command) { + studyMemberValidationUseCase.checkStudyJoinMember(studyId, memberId); + activityAuthorityValidationUseCase.checkDeleteAuthority(studyId, memberId, activityId); + + Activity exist = activityQueryPort.getById(activityId); + ActivitySource source = activityUseCaseMapper.toModifySource(exist, command); + Activity modified = exist.modify(memberId, source); + activitySavePort.save(modified); + + List participants = activityParticipantUseCaseMapper.toDomains(command.participants(), modified); + activityParticipantCommandPort.update(activityId, participants); + + List images = activityImageUseCaseMapper.toDomains(command.images(), modified); + activityImageCommandPort.update(activityId, images); + } +} From f6a2aea9d86bb64ae335afd0f9c253c89d3ce117 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:27:40 +0900 Subject: [PATCH 07/12] =?UTF-8?q?:recycle:=20[STMT-263]=20activityCreateSo?= =?UTF-8?q?urce=20->=20activitySource=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/com/stumeet/server/stub/ActivityStub.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/stumeet/server/stub/ActivityStub.java b/src/test/java/com/stumeet/server/stub/ActivityStub.java index 1c04c8ca..e3951c7f 100644 --- a/src/test/java/com/stumeet/server/stub/ActivityStub.java +++ b/src/test/java/com/stumeet/server/stub/ActivityStub.java @@ -1,7 +1,7 @@ package com.stumeet.server.stub; import com.stumeet.server.activity.adapter.in.response.*; -import com.stumeet.server.activity.application.service.model.ActivityCreateSource; +import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.application.port.in.command.ActivityCreateCommand; import com.stumeet.server.activity.domain.model.*; import com.stumeet.server.member.domain.Member; @@ -87,12 +87,12 @@ public static ActivityCreateCommand getMeetActivityCreateCommandPeriodInvalid() .build(); } - public static ActivityCreateSource getDefaultCreateSource() { + public static ActivitySource getDefaultCreateSource() { Member member = MemberStub.getMember(); - return ActivityCreateSource.builder() + return ActivitySource.builder() .id(1L) .studyId(StudyStub.getStudyId()) - .author(ActivityCreateSource.ActivityMemberCreateSource.builder() + .author(ActivitySource.ActivityMemberCreateSource.builder() .id(member.getId()) .name(member.getName()) .image(member.getImage()) From a351fc5ac6343fd49ac8cd4102582995ff185486 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:28:47 +0900 Subject: [PATCH 08/12] =?UTF-8?q?:white=5Fcheck=5Fmark:=20[STMT-263]=20DEF?= =?UTF-8?q?AULT=20=EC=9C=A0=ED=98=95=EC=9D=98=20=ED=99=9C=EB=8F=99?= =?UTF-8?q?=EC=9D=98=20setup=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EA=B8=B0=ED=95=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/resources/db/setup.sql | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/resources/db/setup.sql b/src/test/resources/db/setup.sql index 256cec16..1bbcc85f 100644 --- a/src/test/resources/db/setup.sql +++ b/src/test/resources/db/setup.sql @@ -44,8 +44,8 @@ INSERT INTO study_member (member_id, study_id, is_admin, is_sent_grape) VALUES ( -- [TABLE: activity] -- 스터디 1 (공지) 기본 활동 -INSERT INTO activity(id, study_id, author_id, category, title, content, is_notice, start_date, end_date, location) -VALUES (1, 1, 4, 'DEFAULT', 'title', 'content', true, '2024-04-01T00:00:00', '2050-05-01T00:00:00', null); +INSERT INTO activity(id, study_id, author_id, category, title, content, is_notice,location) +VALUES (1, 1, 4, 'DEFAULT', 'title', 'content', true, null); INSERT INTO activity_image (activity_id, image) VALUES (1, 'https://example.com/images/image1.png'); INSERT INTO activity_image (activity_id, image) VALUES (1, 'https://example.com/images/image2.png'); @@ -55,8 +55,8 @@ INSERT INTO activity_participant (activity_id, member_id, status) VALUES (1, 2, INSERT INTO activity_participant (activity_id, member_id, status) VALUES (1, 4, 'NONE'); -- 스터디 1 기본 활동 -INSERT INTO activity (id, study_id, author_id, category, title, content, is_notice, start_date, end_date, location) -VALUES (2, 1, 1, 'DEFAULT', 'title', 'content', false, '2024-04-08T00:00:00', '2050-05-01T00:00:00', null); +INSERT INTO activity (id, study_id, author_id, category, title, content, is_notice, location) +VALUES (2, 1, 1, 'DEFAULT', 'title', 'content', false, null); INSERT INTO activity_image (activity_id, image) VALUES (2, 'https://example.com/images/image1.png'); INSERT INTO activity_image (activity_id, image) VALUES (2, 'https://example.com/images/image2.png'); @@ -105,8 +105,8 @@ VALUES (7, 1, 1, 'ASSIGNMENT', 'title', 'content', false, '2024-04-08T00:00:00', INSERT INTO activity_participant (activity_id, member_id, status) VALUES (6, 2, 'PERFORMED'); -- 스터디 2 (공지) 기본 활동 -INSERT INTO activity(id, study_id, author_id, category, title, content, is_notice, start_date, end_date, location) -VALUES (8, 2, 1, 'DEFAULT', 'title', 'content', true, '2024-04-01T00:00:00', '2024-04-08T00:00:00', '성신여대 카페구월'); +INSERT INTO activity(id, study_id, author_id, category, title, content, is_notice, location) +VALUES (8, 2, 1, 'DEFAULT', 'title', 'content', true, '성신여대 카페구월'); INSERT INTO activity_image (activity_id, image) VALUES (8, 'https://example.com/images/image1.png'); INSERT INTO activity_image (activity_id, image) VALUES (8, 'https://example.com/images/image2.png'); From 4390386362121ae890cebf098b162a3b6de8d51e Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 22:32:53 +0900 Subject: [PATCH 09/12] =?UTF-8?q?:recycle:=20[STMT-263]=20modify=20->=20up?= =?UTF-8?q?date=EB=A1=9C=20=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...tyModifyApi.java => ActivityUpdateApi.java} | 14 +++++++------- .../port/in/ActivityModifyUseCase.java | 8 -------- .../port/in/ActivityUpdateUseCase.java | 8 ++++++++ ...Command.java => ActivityUpdateCommand.java} | 2 +- .../port/in/mapper/ActivityUseCaseMapper.java | 4 ++-- ...Service.java => ActivityUpdateService.java} | 18 +++++++++--------- .../server/activity/domain/model/Activity.java | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) rename src/main/java/com/stumeet/server/activity/adapter/in/{ActivityModifyApi.java => ActivityUpdateApi.java} (77%) delete mode 100644 src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java create mode 100644 src/main/java/com/stumeet/server/activity/application/port/in/ActivityUpdateUseCase.java rename src/main/java/com/stumeet/server/activity/application/port/in/command/{ActivityModifyCommand.java => ActivityUpdateCommand.java} (97%) rename src/main/java/com/stumeet/server/activity/application/service/{ActivityModifyService.java => ActivityUpdateService.java} (82%) diff --git a/src/main/java/com/stumeet/server/activity/adapter/in/ActivityModifyApi.java b/src/main/java/com/stumeet/server/activity/adapter/in/ActivityUpdateApi.java similarity index 77% rename from src/main/java/com/stumeet/server/activity/adapter/in/ActivityModifyApi.java rename to src/main/java/com/stumeet/server/activity/adapter/in/ActivityUpdateApi.java index e19ee02e..068c05c9 100644 --- a/src/main/java/com/stumeet/server/activity/adapter/in/ActivityModifyApi.java +++ b/src/main/java/com/stumeet/server/activity/adapter/in/ActivityUpdateApi.java @@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import com.stumeet.server.activity.application.port.in.ActivityModifyUseCase; -import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; +import com.stumeet.server.activity.application.port.in.ActivityUpdateUseCase; +import com.stumeet.server.activity.application.port.in.command.ActivityUpdateCommand; import com.stumeet.server.common.annotation.WebAdapter; import com.stumeet.server.common.auth.model.LoginMember; import com.stumeet.server.common.model.ApiResponse; @@ -21,18 +21,18 @@ @WebAdapter @RequestMapping("/api/v1") @RequiredArgsConstructor -public class ActivityModifyApi { +public class ActivityUpdateApi { - private final ActivityModifyUseCase activityModifyUseCase; + private final ActivityUpdateUseCase activityUpdateUseCase; @PatchMapping("/studies/{studyId}/activities/{activityId}") - public ResponseEntity> modify( + public ResponseEntity> update( @AuthenticationPrincipal LoginMember loginMember, @PathVariable Long studyId, @PathVariable Long activityId, - @RequestBody @Valid ActivityModifyCommand command + @RequestBody @Valid ActivityUpdateCommand command ) { - activityModifyUseCase.modify(loginMember.getId(), studyId, activityId, command); + activityUpdateUseCase.update(loginMember.getId(), studyId, activityId, command); return ResponseEntity.status(HttpStatus.OK) .body(ApiResponse.success(SuccessCode.UPDATE_SUCCESS)); diff --git a/src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java b/src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java deleted file mode 100644 index c6122257..00000000 --- a/src/main/java/com/stumeet/server/activity/application/port/in/ActivityModifyUseCase.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.stumeet.server.activity.application.port.in; - -import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; - -public interface ActivityModifyUseCase { - - void modify(Long memberId, Long studyId, Long activityId, ActivityModifyCommand command); -} diff --git a/src/main/java/com/stumeet/server/activity/application/port/in/ActivityUpdateUseCase.java b/src/main/java/com/stumeet/server/activity/application/port/in/ActivityUpdateUseCase.java new file mode 100644 index 00000000..31ccc15f --- /dev/null +++ b/src/main/java/com/stumeet/server/activity/application/port/in/ActivityUpdateUseCase.java @@ -0,0 +1,8 @@ +package com.stumeet.server.activity.application.port.in; + +import com.stumeet.server.activity.application.port.in.command.ActivityUpdateCommand; + +public interface ActivityUpdateUseCase { + + void update(Long memberId, Long studyId, Long activityId, ActivityUpdateCommand command); +} diff --git a/src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityModifyCommand.java b/src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityUpdateCommand.java similarity index 97% rename from src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityModifyCommand.java rename to src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityUpdateCommand.java index 62dfcb83..c231f298 100644 --- a/src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityModifyCommand.java +++ b/src/main/java/com/stumeet/server/activity/application/port/in/command/ActivityUpdateCommand.java @@ -14,7 +14,7 @@ import lombok.Builder; @Builder -public record ActivityModifyCommand( +public record ActivityUpdateCommand( @NotBlank(message = "활동 카테고리를 입력해주세요") String category, diff --git a/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java b/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java index 033670e0..b2bc501c 100644 --- a/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java +++ b/src/main/java/com/stumeet/server/activity/application/port/in/mapper/ActivityUseCaseMapper.java @@ -7,7 +7,7 @@ import com.stumeet.server.activity.adapter.in.response.ActivityParticipantSimpleResponse; import com.stumeet.server.activity.adapter.in.response.PageInfoResponse; import com.stumeet.server.activity.application.port.in.command.ActivityCreateCommand; -import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; +import com.stumeet.server.activity.application.port.in.command.ActivityUpdateCommand; import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.domain.model.Activity; import com.stumeet.server.activity.domain.model.ActivityCategory; @@ -45,7 +45,7 @@ public ActivitySource toCreateSource(Long studyId, ActivityCreateCommand command .build(); } - public ActivitySource toModifySource(Activity exist, ActivityModifyCommand command) { + public ActivitySource toUpdateSource(Activity exist, ActivityUpdateCommand command) { return ActivitySource.builder() .id(exist.getId()) .studyId(exist.getStudy().getId()) diff --git a/src/main/java/com/stumeet/server/activity/application/service/ActivityModifyService.java b/src/main/java/com/stumeet/server/activity/application/service/ActivityUpdateService.java similarity index 82% rename from src/main/java/com/stumeet/server/activity/application/service/ActivityModifyService.java rename to src/main/java/com/stumeet/server/activity/application/service/ActivityUpdateService.java index baa7ba08..a77d358e 100644 --- a/src/main/java/com/stumeet/server/activity/application/service/ActivityModifyService.java +++ b/src/main/java/com/stumeet/server/activity/application/service/ActivityUpdateService.java @@ -5,8 +5,8 @@ import org.springframework.transaction.annotation.Transactional; import com.stumeet.server.activity.application.port.in.ActivityAuthorityValidationUseCase; -import com.stumeet.server.activity.application.port.in.ActivityModifyUseCase; -import com.stumeet.server.activity.application.port.in.command.ActivityModifyCommand; +import com.stumeet.server.activity.application.port.in.ActivityUpdateUseCase; +import com.stumeet.server.activity.application.port.in.command.ActivityUpdateCommand; import com.stumeet.server.activity.application.port.in.mapper.ActivityImageUseCaseMapper; import com.stumeet.server.activity.application.port.in.mapper.ActivityParticipantUseCaseMapper; import com.stumeet.server.activity.application.port.in.mapper.ActivityUseCaseMapper; @@ -26,7 +26,7 @@ @Transactional @UseCase @RequiredArgsConstructor -public class ActivityModifyService implements ActivityModifyUseCase { +public class ActivityUpdateService implements ActivityUpdateUseCase { private final StudyMemberValidationUseCase studyMemberValidationUseCase; private final ActivityAuthorityValidationUseCase activityAuthorityValidationUseCase; @@ -41,19 +41,19 @@ public class ActivityModifyService implements ActivityModifyUseCase { private final ActivityParticipantUseCaseMapper activityParticipantUseCaseMapper; @Override - public void modify(Long memberId, Long studyId, Long activityId, ActivityModifyCommand command) { + public void update(Long memberId, Long studyId, Long activityId, ActivityUpdateCommand command) { studyMemberValidationUseCase.checkStudyJoinMember(studyId, memberId); activityAuthorityValidationUseCase.checkDeleteAuthority(studyId, memberId, activityId); Activity exist = activityQueryPort.getById(activityId); - ActivitySource source = activityUseCaseMapper.toModifySource(exist, command); - Activity modified = exist.modify(memberId, source); - activitySavePort.save(modified); + ActivitySource source = activityUseCaseMapper.toUpdateSource(exist, command); + Activity updated = exist.update(memberId, source); + activitySavePort.save(updated); - List participants = activityParticipantUseCaseMapper.toDomains(command.participants(), modified); + List participants = activityParticipantUseCaseMapper.toDomains(command.participants(), updated); activityParticipantCommandPort.update(activityId, participants); - List images = activityImageUseCaseMapper.toDomains(command.images(), modified); + List images = activityImageUseCaseMapper.toDomains(command.images(), updated); activityImageCommandPort.update(activityId, images); } } diff --git a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java index 49d710a8..a6507b15 100644 --- a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java +++ b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java @@ -38,7 +38,7 @@ public abstract class Activity { private LocalDateTime createdAt; - public Activity modify(Long memberId, ActivitySource source) { + public Activity update(Long memberId, ActivitySource source) { validateAuthor(memberId); return source.category().create(source); } From 8a29fa4f64157b303cb2f441b35b7dbcdab6bedb Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 23:32:17 +0900 Subject: [PATCH 10/12] =?UTF-8?q?:recycle:=20[STMT-263]=20period=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=EC=9D=84=20Activity=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EC=97=90=20=EA=B3=B5=ED=86=B5=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/model/ActivityModifySource.java | 25 ----------- .../activity/domain/model/Activity.java | 42 +++++++++++++++++-- .../activity/domain/model/ActivityPeriod.java | 42 ------------------- .../activity/domain/model/Assignment.java | 7 ---- .../server/activity/domain/model/Meet.java | 7 ---- .../com/stumeet/server/stub/ActivityStub.java | 15 +++++++ 6 files changed, 53 insertions(+), 85 deletions(-) delete mode 100644 src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java delete mode 100644 src/main/java/com/stumeet/server/activity/domain/model/ActivityPeriod.java diff --git a/src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java b/src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java deleted file mode 100644 index 97866949..00000000 --- a/src/main/java/com/stumeet/server/activity/application/service/model/ActivityModifySource.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.stumeet.server.activity.application.service.model; - -import java.time.LocalDateTime; - -import com.stumeet.server.activity.domain.model.ActivityCategory; -import com.stumeet.server.activity.domain.model.ActivityMember; - -import lombok.Builder; - -@Builder -public record ActivityModifySource( - Long id, - Long studyId, - ActivityMember author, - ActivityCategory category, - String title, - String content, - LocalDateTime startDate, - LocalDateTime endDate, - String location, - String link, - boolean isNotice, - LocalDateTime createdAt -) { -} diff --git a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java index a6507b15..ecf4353a 100644 --- a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java +++ b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java @@ -1,7 +1,5 @@ package com.stumeet.server.activity.domain.model; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; import lombok.Getter; import java.time.LocalDateTime; @@ -9,8 +7,9 @@ import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.domain.exception.ActivityManagementAccessDeniedException; +import com.stumeet.server.common.exception.model.BadRequestException; +import com.stumeet.server.common.response.ErrorCode; -@AllArgsConstructor(access = AccessLevel.PROTECTED) @Getter public abstract class Activity { @@ -38,13 +37,48 @@ public abstract class Activity { private LocalDateTime createdAt; + protected Activity(Long id, ActivityLinkedStudy study, ActivityMember author, ActivityCategory category, + String title, + String content, String link, String location, LocalDateTime startDate, LocalDateTime endDate, + boolean isNotice, + LocalDateTime createdAt) { + validatePeriod(category, startDate, endDate); + + this.id = id; + this.study = study; + this.author = author; + this.category = category; + this.title = title; + this.content = content; + this.link = link; + this.location = location; + this.startDate = startDate; + this.endDate = endDate; + this.isNotice = isNotice; + this.createdAt = createdAt; + } + + private void validatePeriod(ActivityCategory category, LocalDateTime startDate, LocalDateTime endDate) { + if (ActivityCategory.DEFAULT.equals(category)) { + return; + } + + if (startDate == null || endDate == null) { + throw new BadRequestException(ErrorCode.ACTIVITY_PERIOD_REQUIRED_EXCEPTION); + } + + if (startDate.isAfter(endDate)) { + throw new BadRequestException(ErrorCode.INVALID_PERIOD_EXCEPTION); + } + } + public Activity update(Long memberId, ActivitySource source) { validateAuthor(memberId); return source.category().create(source); } private void validateAuthor(Long memberId) { - if(!isAuthor(memberId)) { + if (!isAuthor(memberId)) { throw new ActivityManagementAccessDeniedException(); } } diff --git a/src/main/java/com/stumeet/server/activity/domain/model/ActivityPeriod.java b/src/main/java/com/stumeet/server/activity/domain/model/ActivityPeriod.java deleted file mode 100644 index af5d2d03..00000000 --- a/src/main/java/com/stumeet/server/activity/domain/model/ActivityPeriod.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.stumeet.server.activity.domain.model; - -import java.time.LocalDateTime; - -import com.stumeet.server.common.exception.model.BadRequestException; -import com.stumeet.server.common.response.ErrorCode; - -import lombok.Builder; -import lombok.Getter; - -@Getter -public class ActivityPeriod { - - private LocalDateTime startDate; - - private LocalDateTime endDate; - - @Builder - private ActivityPeriod(LocalDateTime startDate, LocalDateTime endDate) { - validate(startDate, endDate); - - this.startDate = startDate; - this.endDate = endDate; - } - - private void validate(LocalDateTime startDate, LocalDateTime endDate) { - validateNonNull(startDate, endDate); - validatePeriod(startDate, endDate); - } - - private void validateNonNull(LocalDateTime startDate, LocalDateTime endDate) { - if (startDate == null || endDate == null) { - throw new BadRequestException(ErrorCode.ACTIVITY_PERIOD_REQUIRED_EXCEPTION); - } - } - - private void validatePeriod(LocalDateTime startDate, LocalDateTime endDate) { - if (startDate.isAfter(endDate)) { - throw new BadRequestException(ErrorCode.INVALID_PERIOD_EXCEPTION); - } - } -} diff --git a/src/main/java/com/stumeet/server/activity/domain/model/Assignment.java b/src/main/java/com/stumeet/server/activity/domain/model/Assignment.java index 586d82ee..2592c6b4 100644 --- a/src/main/java/com/stumeet/server/activity/domain/model/Assignment.java +++ b/src/main/java/com/stumeet/server/activity/domain/model/Assignment.java @@ -6,15 +6,8 @@ public class Assignment extends Activity { - private ActivityPeriod period; - @Builder protected Assignment(Long id, ActivityLinkedStudy study, ActivityMember author, ActivityCategory category, String title, String content, boolean isNotice, LocalDateTime startDate, LocalDateTime endDate, String link, LocalDateTime createdAt) { super(id, study, author, category, title, content, link, null, startDate, endDate, isNotice, createdAt); - - this.period = ActivityPeriod.builder() - .startDate(startDate) - .endDate(endDate) - .build(); } } diff --git a/src/main/java/com/stumeet/server/activity/domain/model/Meet.java b/src/main/java/com/stumeet/server/activity/domain/model/Meet.java index e64ec857..c905ac30 100644 --- a/src/main/java/com/stumeet/server/activity/domain/model/Meet.java +++ b/src/main/java/com/stumeet/server/activity/domain/model/Meet.java @@ -11,18 +11,11 @@ @Getter public class Meet extends Activity { - private ActivityPeriod period; - @Builder protected Meet(Long id, ActivityLinkedStudy study, ActivityMember author, ActivityCategory category, String title, String content, String location, String link, LocalDateTime startDate, LocalDateTime endDate, boolean isNotice, LocalDateTime createdAt) { super(id, study, author, category, title, content, link, location, startDate, endDate, isNotice, createdAt); validateLocationNonNull(location); - - this.period = ActivityPeriod.builder() - .startDate(startDate) - .endDate(endDate) - .build(); } private void validateLocationNonNull(String location) { diff --git a/src/test/java/com/stumeet/server/stub/ActivityStub.java b/src/test/java/com/stumeet/server/stub/ActivityStub.java index e3951c7f..5b61f8a1 100644 --- a/src/test/java/com/stumeet/server/stub/ActivityStub.java +++ b/src/test/java/com/stumeet/server/stub/ActivityStub.java @@ -1,6 +1,7 @@ package com.stumeet.server.stub; import com.stumeet.server.activity.adapter.in.response.*; +import com.stumeet.server.activity.application.port.in.command.ActivityUpdateCommand; import com.stumeet.server.activity.application.service.model.ActivitySource; import com.stumeet.server.activity.application.port.in.command.ActivityCreateCommand; import com.stumeet.server.activity.domain.model.*; @@ -87,6 +88,20 @@ public static ActivityCreateCommand getMeetActivityCreateCommandPeriodInvalid() .build(); } + public static ActivityUpdateCommand getActivityUpdateCommand() { + return ActivityUpdateCommand.builder() + .category("MEET") + .title("title") + .content("content") + .images(List.of("https://example.com/image1.png", "https://example.com/image2.png", "https://example.com/image3.png")) + .location("서울") + .startDate(LocalDateTime.parse("2024-05-01T00:00:00")) + .endDate(LocalDateTime.parse("2024-05-02T00:00:00")) + .isNotice(true) + .participants(List.of(MemberStub.getMemberId())) + .build(); + } + public static ActivitySource getDefaultCreateSource() { Member member = MemberStub.getMember(); return ActivitySource.builder() From ca1d77b1a32ad812e4a46f53ad6708a97f003797 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Fri, 26 Jul 2024 23:46:44 +0900 Subject: [PATCH 11/12] =?UTF-8?q?:white=5Fcheck=5Fmark:=20[STMT-263]=20?= =?UTF-8?q?=ED=99=9C=EB=8F=99=20=EC=88=98=EC=A0=95=20API=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/ActivityUpdateApiTest.java | 211 ++++++++++++++++++ .../com/stumeet/server/stub/ActivityStub.java | 28 +++ 2 files changed, 239 insertions(+) create mode 100644 src/test/java/com/stumeet/server/activity/adapter/in/ActivityUpdateApiTest.java diff --git a/src/test/java/com/stumeet/server/activity/adapter/in/ActivityUpdateApiTest.java b/src/test/java/com/stumeet/server/activity/adapter/in/ActivityUpdateApiTest.java new file mode 100644 index 00000000..ba987aa6 --- /dev/null +++ b/src/test/java/com/stumeet/server/activity/adapter/in/ActivityUpdateApiTest.java @@ -0,0 +1,211 @@ +package com.stumeet.server.activity.adapter.in; + +import static org.springframework.restdocs.headers.HeaderDocumentation.*; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.*; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.http.MediaType; + +import com.stumeet.server.activity.application.port.in.command.ActivityUpdateCommand; +import com.stumeet.server.common.auth.model.AuthenticationHeader; +import com.stumeet.server.helper.WithMockMember; +import com.stumeet.server.stub.ActivityStub; +import com.stumeet.server.stub.StudyStub; +import com.stumeet.server.stub.TokenStub; +import com.stumeet.server.template.ApiTest; + +class ActivityUpdateApiTest extends ApiTest { + + @Nested + @DisplayName("활동 수정 API") + class UpdateActivity { + + private final String path = "/api/v1/studies/{studyId}/activities/{activityId}"; + + @Test + @WithMockMember(id = 4L) + @DisplayName("[성공] 활동 수정에 성공한다.") + void success() throws Exception { + ActivityUpdateCommand command = ActivityStub.getActivityUpdateCommand(); + + mockMvc.perform(patch(path, StudyStub.getStudyId(), ActivityStub.getActivityId()) + .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken()) + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(command))) + .andExpect(status().isOk()) + .andDo(document("update-activity/success", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AuthenticationHeader.ACCESS_TOKEN.getName()) + .description("서버로부터 전달받은 액세스 토큰") + ), + requestFields( + fieldWithPath("category").description("활동 카테고리"), + fieldWithPath("title").description("활동 제목"), + fieldWithPath("content").description("활동 내용"), + fieldWithPath("images[]").description("활동 이미지 URL 리스트"), + fieldWithPath("isNotice").description("공지 여부"), + fieldWithPath("startDate").description("활동 시작 일시").optional(), + fieldWithPath("endDate").description("활동 종료 일시").optional(), + fieldWithPath("location").description("활동 장소").optional(), + fieldWithPath("link").description("링크").optional(), + fieldWithPath("participants").description("참여자 ID 리스트") + ), + responseFields( + fieldWithPath("code").description("응답 상태"), + fieldWithPath("message").description("응답 메시지") + ))); + } + + @Test + @WithMockMember + @DisplayName("[실패] 작성자가 아닌 경우 수정에 실패한다.") + void fail_when_member_is_not_author() throws Exception { + ActivityUpdateCommand command = ActivityStub.getActivityUpdateCommand(); + + mockMvc.perform(patch(path, StudyStub.getStudyId(), ActivityStub.getActivityId()) + .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken()) + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(command))) + .andExpect(status().isForbidden()) + .andDo(document("update-activity/fail/not-author", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AuthenticationHeader.ACCESS_TOKEN.getName()) + .description("서버로부터 전달받은 액세스 토큰") + ), + requestFields( + fieldWithPath("category").description("활동 카테고리"), + fieldWithPath("title").description("활동 제목"), + fieldWithPath("content").description("활동 내용"), + fieldWithPath("images[]").description("활동 이미지 URL 리스트"), + fieldWithPath("isNotice").description("공지 여부"), + fieldWithPath("startDate").description("활동 시작 일시").optional(), + fieldWithPath("endDate").description("활동 종료 일시").optional(), + fieldWithPath("location").description("활동 장소").optional(), + fieldWithPath("link").description("링크").optional(), + fieldWithPath("participants").description("참여자 ID 리스트") + ), + responseFields( + fieldWithPath("code").description("응답 상태"), + fieldWithPath("message").description("응답 메시지") + ))); + } + + @Test + @WithMockMember(id = 3L) + @DisplayName("[실패] 스터디 멤버가 아닌 경우 활동 수정에 실패한다.") + void fail_when_member_is_not_joined_member() throws Exception { + ActivityUpdateCommand command = ActivityStub.getActivityUpdateCommand(); + + mockMvc.perform(patch(path, StudyStub.getStudyId(), ActivityStub.getActivityId()) + .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken()) + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(command))) + .andExpect(status().isForbidden()) + .andDo(document("update-activity/fail/not-joined-member", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AuthenticationHeader.ACCESS_TOKEN.getName()) + .description("서버로부터 전달받은 액세스 토큰") + ), + requestFields( + fieldWithPath("category").description("활동 카테고리"), + fieldWithPath("title").description("활동 제목"), + fieldWithPath("content").description("활동 내용"), + fieldWithPath("images[]").description("활동 이미지 URL 리스트"), + fieldWithPath("isNotice").description("공지 여부"), + fieldWithPath("startDate").description("활동 시작 일시").optional(), + fieldWithPath("endDate").description("활동 종료 일시").optional(), + fieldWithPath("location").description("활동 장소").optional(), + fieldWithPath("link").description("링크").optional(), + fieldWithPath("participants").description("참여자 ID 리스트") + ), + responseFields( + fieldWithPath("code").description("응답 상태"), + fieldWithPath("message").description("응답 메시지") + ))); + } + + @Test + @WithMockMember(id = 4L) + @DisplayName("[실패] 모임/과제 유형으로 수정하는 경우 활동 기간이 null이면 활동 수정에 실패한다.") + void fail_when_period_null() throws Exception { + ActivityUpdateCommand command = ActivityStub.getNullPeriodActivityUpdateCommand(); + + mockMvc.perform(patch(path, StudyStub.getStudyId(), ActivityStub.getActivityId()) + .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken()) + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(command))) + .andExpect(status().isBadRequest()) + .andDo(document("update-activity/fail/period-null", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AuthenticationHeader.ACCESS_TOKEN.getName()) + .description("서버로부터 전달받은 액세스 토큰") + ), + requestFields( + fieldWithPath("category").description("활동 카테고리"), + fieldWithPath("title").description("활동 제목"), + fieldWithPath("content").description("활동 내용"), + fieldWithPath("images[]").description("활동 이미지 URL 리스트"), + fieldWithPath("isNotice").description("공지 여부"), + fieldWithPath("startDate").description("활동 시작 일시").optional(), + fieldWithPath("endDate").description("활동 종료 일시").optional(), + fieldWithPath("location").description("활동 장소").optional(), + fieldWithPath("link").description("링크").optional(), + fieldWithPath("participants").description("참여자 ID 리스트") + ), + responseFields( + fieldWithPath("code").description("응답 상태"), + fieldWithPath("message").description("응답 메시지") + ))); + } + + @Test + @WithMockMember(id = 4L) + @DisplayName("[실패] 모임/과제 유형으로 수정하는 경우 활동 기간이 유효하지 않으면 활동 수정에 실패한다.") + void fail_when_period_invalid() throws Exception { + ActivityUpdateCommand command = ActivityStub.getInvalidPeriodActivityUpdateCommand(); + + mockMvc.perform(patch(path, StudyStub.getStudyId(), ActivityStub.getActivityId()) + .header(AuthenticationHeader.ACCESS_TOKEN.getName(), TokenStub.getMockAccessToken()) + .contentType(MediaType.APPLICATION_JSON) + .content(toJson(command))) + .andExpect(status().isBadRequest()) + .andDo(document("update-activity/fail/period-invalid", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + requestHeaders( + headerWithName(AuthenticationHeader.ACCESS_TOKEN.getName()) + .description("서버로부터 전달받은 액세스 토큰") + ), + requestFields( + fieldWithPath("category").description("활동 카테고리"), + fieldWithPath("title").description("활동 제목"), + fieldWithPath("content").description("활동 내용"), + fieldWithPath("images[]").description("활동 이미지 URL 리스트"), + fieldWithPath("isNotice").description("공지 여부"), + fieldWithPath("startDate").description("활동 시작 일시").optional(), + fieldWithPath("endDate").description("활동 종료 일시").optional(), + fieldWithPath("location").description("활동 장소").optional(), + fieldWithPath("link").description("링크").optional(), + fieldWithPath("participants").description("참여자 ID 리스트") + ), + responseFields( + fieldWithPath("code").description("응답 상태"), + fieldWithPath("message").description("응답 메시지") + ))); + } + } +} \ No newline at end of file diff --git a/src/test/java/com/stumeet/server/stub/ActivityStub.java b/src/test/java/com/stumeet/server/stub/ActivityStub.java index 5b61f8a1..ff553fc7 100644 --- a/src/test/java/com/stumeet/server/stub/ActivityStub.java +++ b/src/test/java/com/stumeet/server/stub/ActivityStub.java @@ -102,6 +102,34 @@ public static ActivityUpdateCommand getActivityUpdateCommand() { .build(); } + public static ActivityUpdateCommand getNullPeriodActivityUpdateCommand() { + return ActivityUpdateCommand.builder() + .category("MEET") + .title("title") + .content("content") + .images(List.of("https://example.com/image1.png", "https://example.com/image2.png", "https://example.com/image3.png")) + .location("서울") + .startDate(LocalDateTime.parse("2024-05-01T00:00:00")) + .endDate(null) + .isNotice(true) + .participants(List.of(MemberStub.getMemberId())) + .build(); + } + + public static ActivityUpdateCommand getInvalidPeriodActivityUpdateCommand() { + return ActivityUpdateCommand.builder() + .category("MEET") + .title("title") + .content("content") + .images(List.of("https://example.com/image1.png", "https://example.com/image2.png", "https://example.com/image3.png")) + .location("서울") + .startDate(LocalDateTime.parse("9999-12-31T00:00:00")) + .endDate(LocalDateTime.parse("2024-05-01T00:00:00")) + .isNotice(true) + .participants(List.of(MemberStub.getMemberId())) + .build(); + } + public static ActivitySource getDefaultCreateSource() { Member member = MemberStub.getMember(); return ActivitySource.builder() From 7332ad32e0c062afbe0fef9055fd78058654ef97 Mon Sep 17 00:00:00 2001 From: Lee ChanMi Date: Sat, 27 Jul 2024 00:03:56 +0900 Subject: [PATCH 12/12] =?UTF-8?q?:bug:=20[STMT-263]=20isAuthor=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=A0=91=EA=B7=BC=20=EC=A0=9C=ED=95=9C?= =?UTF-8?q?=EC=9E=90=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/stumeet/server/activity/domain/model/Activity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java index ecf4353a..f293bdb9 100644 --- a/src/main/java/com/stumeet/server/activity/domain/model/Activity.java +++ b/src/main/java/com/stumeet/server/activity/domain/model/Activity.java @@ -83,7 +83,7 @@ private void validateAuthor(Long memberId) { } } - private boolean isAuthor(Long memberId) { + public boolean isAuthor(Long memberId) { return Objects.equals(this.author.getId(), memberId); } }