diff --git a/src/main/java/com/somemore/community/domain/CommunityBoard.java b/src/main/java/com/somemore/community/domain/CommunityBoard.java index 16e667158..0fe1a540a 100644 --- a/src/main/java/com/somemore/community/domain/CommunityBoard.java +++ b/src/main/java/com/somemore/community/domain/CommunityBoard.java @@ -1,5 +1,6 @@ package com.somemore.community.domain; +import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; import com.somemore.global.common.BaseEntity; import static lombok.AccessLevel.PROTECTED; @@ -52,4 +53,10 @@ public CommunityBoard(UUID writerId, String title, String content, String imgUrl public boolean isWriter(UUID writerId) { return this.writerId.equals(writerId); } + + public void updateWith(CommunityBoardUpdateRequestDto dto, String imgUrl) { + this.title = dto.title(); + this.content = dto.content(); + this.imgUrl = imgUrl; + } } \ No newline at end of file diff --git a/src/main/java/com/somemore/community/dto/request/CommunityBoardUpdateRequestDto.java b/src/main/java/com/somemore/community/dto/request/CommunityBoardUpdateRequestDto.java new file mode 100644 index 000000000..83077f439 --- /dev/null +++ b/src/main/java/com/somemore/community/dto/request/CommunityBoardUpdateRequestDto.java @@ -0,0 +1,18 @@ +package com.somemore.community.dto.request; + +import com.fasterxml.jackson.databind.PropertyNamingStrategies; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; + +@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) +@Builder +public record CommunityBoardUpdateRequestDto( + @Schema(description = "커뮤니티 게시글 제목", example = "11/29 OO도서관 봉사 같이 갈 사람 모집합니다.") + @NotBlank(message = "게시글 제목은 필수 값입니다.") + String title, + @Schema(description = "커뮤니티 게시글 내용", example = "저 포함 5명이 같이 가면 좋을 거 같아요") + @NotBlank(message = "게시글 내용은 필수 값입니다.") + String content +) {} \ No newline at end of file diff --git a/src/main/java/com/somemore/community/service/query/CommunityBoardQueryService.java b/src/main/java/com/somemore/community/service/CommunityBoardQueryService.java similarity index 96% rename from src/main/java/com/somemore/community/service/query/CommunityBoardQueryService.java rename to src/main/java/com/somemore/community/service/CommunityBoardQueryService.java index a1ce199f2..00aeb74b8 100644 --- a/src/main/java/com/somemore/community/service/query/CommunityBoardQueryService.java +++ b/src/main/java/com/somemore/community/service/CommunityBoardQueryService.java @@ -1,4 +1,4 @@ -package com.somemore.community.service.query; +package com.somemore.community.service; import com.somemore.center.usecase.query.CenterQueryUseCase; import com.somemore.community.domain.CommunityBoard; @@ -6,7 +6,7 @@ import com.somemore.community.dto.response.CommunityBoardGetResponseDto; import com.somemore.community.dto.response.WriterDetailDto; import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.query.CommunityBoardQueryUseCase; +import com.somemore.community.usecase.CommunityBoardQueryUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.volunteer.dto.response.VolunteerForCommunityResponseDto; import com.somemore.volunteer.usecase.query.FindVolunteerIdUseCase; diff --git a/src/main/java/com/somemore/community/service/command/CreateCommunityBoardService.java b/src/main/java/com/somemore/community/service/CreateCommunityBoardService.java similarity index 88% rename from src/main/java/com/somemore/community/service/command/CreateCommunityBoardService.java rename to src/main/java/com/somemore/community/service/CreateCommunityBoardService.java index e0734cd34..07ad1d456 100644 --- a/src/main/java/com/somemore/community/service/command/CreateCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/CreateCommunityBoardService.java @@ -1,9 +1,9 @@ -package com.somemore.community.service.command; +package com.somemore.community.service; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.command.CreateCommunityBoardUseCase; +import com.somemore.community.usecase.CreateCommunityBoardUseCase; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/com/somemore/community/service/command/DeleteCommunityBoardService.java b/src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java similarity index 92% rename from src/main/java/com/somemore/community/service/command/DeleteCommunityBoardService.java rename to src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java index 0e0fe857a..79c735bf9 100644 --- a/src/main/java/com/somemore/community/service/command/DeleteCommunityBoardService.java +++ b/src/main/java/com/somemore/community/service/DeleteCommunityBoardService.java @@ -1,8 +1,8 @@ -package com.somemore.community.service.command; +package com.somemore.community.service; import com.somemore.community.domain.CommunityBoard; import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.command.DeleteCommunityBoardUseCase; +import com.somemore.community.usecase.DeleteCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java b/src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java new file mode 100644 index 000000000..ef3f96c36 --- /dev/null +++ b/src/main/java/com/somemore/community/service/UpdateCommunityBoardService.java @@ -0,0 +1,45 @@ +package com.somemore.community.service; + +import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; +import com.somemore.community.repository.CommunityBoardRepository; +import com.somemore.community.usecase.UpdateCommunityBoardUseCase; +import com.somemore.global.exception.BadRequestException; + +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import static com.somemore.global.exception.ExceptionMessage.*; + + +@RequiredArgsConstructor +@Transactional +@Service +public class UpdateCommunityBoardService implements UpdateCommunityBoardUseCase { + + private final CommunityBoardRepository communityBoardRepository; + + @Override + public void updateCommunityBoard(CommunityBoardUpdateRequestDto requestDto, Long communityBoardId, UUID writerId, String imgUrl) { + CommunityBoard communityBoard = getCommunityBoardById(communityBoardId); + validateWriter(communityBoard, writerId); + communityBoard.updateWith(requestDto, imgUrl); + + communityBoardRepository.save(communityBoard); + } + + private CommunityBoard getCommunityBoardById(Long id) { + return communityBoardRepository.findById(id) + .orElseThrow(() -> new BadRequestException(NOT_EXISTS_COMMUNITY_BOARD.getMessage())); + } + + private void validateWriter(CommunityBoard communityBoard, UUID writerId) { + if (communityBoard.isWriter(writerId)) { + return; + } + + throw new BadRequestException(UNAUTHORIZED_COMMUNITY_BOARD.getMessage()); + } +} diff --git a/src/main/java/com/somemore/community/usecase/query/CommunityBoardQueryUseCase.java b/src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java similarity index 91% rename from src/main/java/com/somemore/community/usecase/query/CommunityBoardQueryUseCase.java rename to src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java index a7c3818c3..2b4da6312 100644 --- a/src/main/java/com/somemore/community/usecase/query/CommunityBoardQueryUseCase.java +++ b/src/main/java/com/somemore/community/usecase/CommunityBoardQueryUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase.query; +package com.somemore.community.usecase; import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; diff --git a/src/main/java/com/somemore/community/usecase/command/CreateCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java similarity index 85% rename from src/main/java/com/somemore/community/usecase/command/CreateCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java index d45a2dd12..2e0c3828f 100644 --- a/src/main/java/com/somemore/community/usecase/command/CreateCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/CreateCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase.command; +package com.somemore.community.usecase; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; diff --git a/src/main/java/com/somemore/community/usecase/command/DeleteCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java similarity index 72% rename from src/main/java/com/somemore/community/usecase/command/DeleteCommunityBoardUseCase.java rename to src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java index 88bca4548..d2f26500e 100644 --- a/src/main/java/com/somemore/community/usecase/command/DeleteCommunityBoardUseCase.java +++ b/src/main/java/com/somemore/community/usecase/DeleteCommunityBoardUseCase.java @@ -1,4 +1,4 @@ -package com.somemore.community.usecase.command; +package com.somemore.community.usecase; import java.util.UUID; diff --git a/src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java b/src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java new file mode 100644 index 000000000..e8690b283 --- /dev/null +++ b/src/main/java/com/somemore/community/usecase/UpdateCommunityBoardUseCase.java @@ -0,0 +1,13 @@ +package com.somemore.community.usecase; + +import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; + +import java.util.UUID; + +public interface UpdateCommunityBoardUseCase { + void updateCommunityBoard( + CommunityBoardUpdateRequestDto requestDto, + Long communityBoardId, + UUID writerId, + String imgUrl); +} diff --git a/src/main/java/com/somemore/global/exception/ExceptionMessage.java b/src/main/java/com/somemore/global/exception/ExceptionMessage.java index 9f92eefcb..2c3b040c7 100644 --- a/src/main/java/com/somemore/global/exception/ExceptionMessage.java +++ b/src/main/java/com/somemore/global/exception/ExceptionMessage.java @@ -10,7 +10,7 @@ public enum ExceptionMessage { NOT_EXISTS_CENTER("존재하지 않는 기관 ID 입니다."), NOT_EXISTS_COMMUNITY_BOARD("존재하지 않는 게시글 입니다."), - UNAUTHORIZED_COMMUNITY_BOARD("게시글 삭제 권한이 없습니다."), + UNAUTHORIZED_COMMUNITY_BOARD("해당 게시글에 권한이 없습니다."), NOT_EXISTS_LOCATION("존재하지 않는 위치 ID 입니다."), NOT_EXISTS_RECRUIT_BOARD("존재하지 않는 봉사 모집글 ID 입니다."), UNAUTHORIZED_RECRUIT_BOARD("자신이 작성한 봉사 모집글이 아닙니다."), diff --git a/src/test/java/com/somemore/community/service/query/CommunityBoardQueryServiceTest.java b/src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java similarity index 97% rename from src/test/java/com/somemore/community/service/query/CommunityBoardQueryServiceTest.java rename to src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java index 797edc4b8..0f3aaf55a 100644 --- a/src/test/java/com/somemore/community/service/query/CommunityBoardQueryServiceTest.java +++ b/src/test/java/com/somemore/community/service/CommunityBoardQueryServiceTest.java @@ -1,4 +1,4 @@ -package com.somemore.community.service.query; +package com.somemore.community.service; import com.somemore.IntegrationTestSupport; import com.somemore.auth.oauth.OAuthProvider; @@ -9,8 +9,8 @@ import com.somemore.community.dto.response.CommunityBoardGetDetailResponseDto; import com.somemore.community.dto.response.CommunityBoardGetResponseDto; import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.command.CreateCommunityBoardUseCase; -import com.somemore.community.usecase.command.DeleteCommunityBoardUseCase; +import com.somemore.community.usecase.CreateCommunityBoardUseCase; +import com.somemore.community.usecase.DeleteCommunityBoardUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import com.somemore.volunteer.domain.Volunteer; diff --git a/src/test/java/com/somemore/community/service/command/CreateCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java similarity index 98% rename from src/test/java/com/somemore/community/service/command/CreateCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java index d2cb672a7..d373da46a 100644 --- a/src/test/java/com/somemore/community/service/command/CreateCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/CreateCommunityBoardServiceTest.java @@ -1,4 +1,4 @@ -package com.somemore.community.service.command; +package com.somemore.community.service; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/java/com/somemore/community/service/command/DeleteCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java similarity index 94% rename from src/test/java/com/somemore/community/service/command/DeleteCommunityBoardServiceTest.java rename to src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java index 578bec665..e72667431 100644 --- a/src/test/java/com/somemore/community/service/command/DeleteCommunityBoardServiceTest.java +++ b/src/test/java/com/somemore/community/service/DeleteCommunityBoardServiceTest.java @@ -1,4 +1,4 @@ -package com.somemore.community.service.command; +package com.somemore.community.service; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -6,8 +6,8 @@ import com.somemore.IntegrationTestSupport; import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; import com.somemore.community.repository.CommunityBoardRepository; -import com.somemore.community.usecase.command.CreateCommunityBoardUseCase; -import com.somemore.community.usecase.query.CommunityBoardQueryUseCase; +import com.somemore.community.usecase.CreateCommunityBoardUseCase; +import com.somemore.community.usecase.CommunityBoardQueryUseCase; import com.somemore.global.exception.BadRequestException; import com.somemore.global.exception.ExceptionMessage; import org.assertj.core.api.ThrowableAssert; diff --git a/src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java b/src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java new file mode 100644 index 000000000..06bd1de86 --- /dev/null +++ b/src/test/java/com/somemore/community/service/UpdateCommunityBoardServiceTest.java @@ -0,0 +1,98 @@ +package com.somemore.community.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.somemore.IntegrationTestSupport; +import com.somemore.community.domain.CommunityBoard; +import com.somemore.community.dto.request.CommunityBoardCreateRequestDto; +import com.somemore.community.dto.request.CommunityBoardUpdateRequestDto; +import com.somemore.community.repository.CommunityBoardRepository; +import com.somemore.community.usecase.CreateCommunityBoardUseCase; +import com.somemore.global.exception.BadRequestException; +import com.somemore.global.exception.ExceptionMessage; +import org.assertj.core.api.ThrowableAssert; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Optional; +import java.util.UUID; + +class UpdateCommunityBoardServiceTest extends IntegrationTestSupport { + + @Autowired + private CreateCommunityBoardUseCase createCommunityBoardUseCase; + @Autowired + private CommunityBoardRepository communityBoardRepository; + @Autowired + private UpdateCommunityBoardService updateCommunityBoardService; + + private UUID writerId; + private Long communityId; + private String imgUrl; + + @BeforeEach + void setUp() { + CommunityBoardCreateRequestDto dto = CommunityBoardCreateRequestDto.builder() + .title("커뮤니티 테스트 제목") + .content("커뮤니티 테스트 내용") + .build(); + + writerId = UUID.randomUUID(); + imgUrl = "https://image.test.url/123"; + + communityId = createCommunityBoardUseCase.createCommunityBoard(dto, writerId, imgUrl); + } + + @AfterEach + void tearDown() { + communityBoardRepository.deleteAllInBatch(); + } + + @DisplayName("커뮤니티 게시글을 수정한다.") + @Test + void updateCommunityBoard() { + + //given + CommunityBoardUpdateRequestDto dto = CommunityBoardUpdateRequestDto.builder() + .title("수정된 커뮤니티 테스트 제목") + .content("수정된 커뮤니티 테스트 내용") + .build(); + + String newImgUrl = "https://image.test.url/567"; + + //when + updateCommunityBoardService.updateCommunityBoard(dto, communityId, writerId, newImgUrl); + + //then + Optional updatedCommunityBoard = communityBoardRepository.findById(communityId); + assertThat(updatedCommunityBoard).isNotNull(); + assertThat(updatedCommunityBoard.get().getId()).isEqualTo(communityId); + assertThat(updatedCommunityBoard.get().getWriterId()).isEqualTo(writerId); + assertThat(updatedCommunityBoard.get().getTitle()).isEqualTo("수정된 커뮤니티 테스트 제목"); + assertThat(updatedCommunityBoard.get().getContent()).isEqualTo("수정된 커뮤니티 테스트 내용"); + assertThat(updatedCommunityBoard.get().getImgUrl()).isEqualTo("https://image.test.url/567"); + } + + @DisplayName("작성자가 아닌 id로 커뮤니티 게시글을 수정하고자 할 때 예외를 던진다.") + @Test + void updateCommunityBoardNotWriterId() { + + //given + CommunityBoardUpdateRequestDto dto = CommunityBoardUpdateRequestDto.builder() + .title("수정된 커뮤니티 테스트 제목") + .content("수정된 커뮤니티 테스트 내용") + .build(); + + //when + ThrowableAssert.ThrowingCallable callable = () -> updateCommunityBoardService.updateCommunityBoard(dto, communityId, UUID.randomUUID(), null); + + //then + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(callable) + .withMessage(ExceptionMessage.UNAUTHORIZED_COMMUNITY_BOARD.getMessage()); + } +}