diff --git a/src/main/java/PNUMEAT/Backend/domain/team/controller/TeamController.java b/src/main/java/PNUMEAT/Backend/domain/team/controller/TeamController.java index 0905432..adaa01f 100644 --- a/src/main/java/PNUMEAT/Backend/domain/team/controller/TeamController.java +++ b/src/main/java/PNUMEAT/Backend/domain/team/controller/TeamController.java @@ -1,6 +1,7 @@ package PNUMEAT.Backend.domain.team.controller; import PNUMEAT.Backend.domain.auth.entity.Member; +import PNUMEAT.Backend.domain.team.dto.request.TeamAnnouncementRequest; import PNUMEAT.Backend.domain.team.dto.request.TeamJoinRequest; import PNUMEAT.Backend.domain.team.dto.request.TeamRequest; import PNUMEAT.Backend.domain.team.dto.response.MyTeamResponse; @@ -106,6 +107,17 @@ public ResponseEntity> joinTeam(@PathVariable("teamId") Long team .contentType(MediaType.APPLICATION_JSON) .body(ApiResponse.successResponseWithMessage(TEAM_JOIN_SUCCESS.getMessage())); } + + @PatchMapping("/{teamId}/announcement") + public ResponseEntity> updateTeamAnnouncement(@PathVariable("teamId") Long teamId, + @RequestBody @Valid TeamAnnouncementRequest teamAnnouncementRequest, + @LoginMember Member member) { + teamService.updateTeamAnnouncement(member, teamAnnouncementRequest.teamAnnouncement(), teamId); + + return ResponseEntity.status(TEAM_ANNOUNCEMENT_UPDATE_SUCCESS.getStatusCode()) + .contentType(MediaType.APPLICATION_JSON) + .body(ApiResponse.successResponseWithMessage(TEAM_ANNOUNCEMENT_UPDATE_SUCCESS.getMessage())); + } } diff --git a/src/main/java/PNUMEAT/Backend/domain/team/dto/request/TeamAnnouncementRequest.java b/src/main/java/PNUMEAT/Backend/domain/team/dto/request/TeamAnnouncementRequest.java new file mode 100644 index 0000000..dd69918 --- /dev/null +++ b/src/main/java/PNUMEAT/Backend/domain/team/dto/request/TeamAnnouncementRequest.java @@ -0,0 +1,13 @@ +package PNUMEAT.Backend.domain.team.dto.request; + +import PNUMEAT.Backend.global.validation.annotation.NotNullOrBlank; +import jakarta.validation.constraints.Size; + +public record TeamAnnouncementRequest( + @NotNullOrBlank + @Size( + max = 255, + message = "글자 수를 초과했습니다." + ) + String teamAnnouncement) { +} diff --git a/src/main/java/PNUMEAT/Backend/domain/team/dto/response/MyTeamResponse.java b/src/main/java/PNUMEAT/Backend/domain/team/dto/response/MyTeamResponse.java index f7ee23f..be81e91 100644 --- a/src/main/java/PNUMEAT/Backend/domain/team/dto/response/MyTeamResponse.java +++ b/src/main/java/PNUMEAT/Backend/domain/team/dto/response/MyTeamResponse.java @@ -16,6 +16,7 @@ public record MyTeamResponse(Long teamId, int memberCount, int streakDays, int successMemberCount, + String teamAnnouncement, LocalDate createdAt, List members) { @@ -30,6 +31,7 @@ public static MyTeamResponse of(Team team){ team.getTeamMembers().size(), team.getStreakDays(), 0, // 게시물 엔티티 없는 관계로 0으로 설정 + team.getTeamAnnouncement(), team.getCreatedDate().toLocalDate(), team.getTeamMembers().stream() .map(tm -> MemberProfileResponse.of(tm.getMember())) diff --git a/src/main/java/PNUMEAT/Backend/domain/team/entity/Team.java b/src/main/java/PNUMEAT/Backend/domain/team/entity/Team.java index c316de7..1e9a259 100644 --- a/src/main/java/PNUMEAT/Backend/domain/team/entity/Team.java +++ b/src/main/java/PNUMEAT/Backend/domain/team/entity/Team.java @@ -35,6 +35,8 @@ public class Team extends TimeStamp { private int streakDays = 0; + private String teamAnnouncement=""; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member teamManager; @@ -58,4 +60,6 @@ public Team(String teamName, Topic teamTopic, String teamExplain, int maxPartici public void updateTeamIconUrl(String teamIconUrl){ this.teamIconUrl = teamIconUrl; } + + public void updateTeamAnnouncement(String teamAnnouncement) { this.teamAnnouncement = teamAnnouncement; } } diff --git a/src/main/java/PNUMEAT/Backend/domain/team/service/TeamService.java b/src/main/java/PNUMEAT/Backend/domain/team/service/TeamService.java index 76e21c2..14e7130 100644 --- a/src/main/java/PNUMEAT/Backend/domain/team/service/TeamService.java +++ b/src/main/java/PNUMEAT/Backend/domain/team/service/TeamService.java @@ -7,8 +7,8 @@ import PNUMEAT.Backend.domain.team.repository.TeamRepository; import PNUMEAT.Backend.domain.teamMember.entity.TeamMember; import PNUMEAT.Backend.domain.teamMember.repository.TeamMemberRepository; -import PNUMEAT.Backend.global.error.ComonException; import PNUMEAT.Backend.global.error.Team.TeamAlreadyJoinException; +import PNUMEAT.Backend.global.error.Team.TeamManagerInvalidException; import PNUMEAT.Backend.global.error.Team.TeamNotFoundException; import PNUMEAT.Backend.global.error.Team.TeamPasswordInvalidException; import PNUMEAT.Backend.global.images.ImageService; @@ -23,8 +23,6 @@ import java.util.Collections; import java.util.List; -import static PNUMEAT.Backend.global.error.ErrorCode.*; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -83,6 +81,20 @@ public TeamMember joinTeam(Member member, String password, Long teamId){ return teamMemberRepository.save(new TeamMember(team, member)); } + @Transactional + public Team updateTeamAnnouncement(Member member, String teamAnnouncement, Long teamId){ + Team team = teamRepository.findById(teamId) + .orElseThrow(TeamNotFoundException::new); + + if(!member.getUuid().equals(team.getTeamManager().getUuid())) { + throw new TeamManagerInvalidException(); + } + + team.updateTeamAnnouncement(teamAnnouncement); + + return team; + } + private void validatePassword(String password, Team team) { if (!password.equals(team.getTeamPassword())) { throw new TeamPasswordInvalidException(); diff --git a/src/main/java/PNUMEAT/Backend/global/error/ErrorCode.java b/src/main/java/PNUMEAT/Backend/global/error/ErrorCode.java index 9848bba..d0b23d6 100644 --- a/src/main/java/PNUMEAT/Backend/global/error/ErrorCode.java +++ b/src/main/java/PNUMEAT/Backend/global/error/ErrorCode.java @@ -19,15 +19,14 @@ public enum ErrorCode { //ARTICLE ARTICLE_FORBIDDEN_ERROR(HttpStatus.FORBIDDEN, "게시글 권한이 없습니다."), + ARTICLE_NOT_FOUND_ERROR(HttpStatus.NOT_FOUND, "존재 하지 않는 게시글 입니다."), //TEAM TOPIC_INVALID_ERROR(HttpStatus.BAD_REQUEST, "주제가 올바른 형식이 아닙니다."), TEAM_NOT_FOUND_ERROR(HttpStatus.NOT_FOUND, "팀이 존재하지 않습니다."), TEAM_PASSWORD_INVALID(HttpStatus.BAD_REQUEST, "팀 비밀번호가 옳지 않습니다."), TEAM_ALREADY_JOIN(HttpStatus.CONFLICT, "이미 팀에 가입했습니다."), - - // ARTICLE - ARTICLE_NOT_FOUND_ERROR(HttpStatus.NOT_FOUND, "존재 하지 않는 게시글 입니다."), + TEAM_MANAGER_INVALID_ERROR(HttpStatus.BAD_REQUEST, "팀의 매니저가 옳지 않습니다."), //IMAGE IMAGE_FILE_UPLOAD_ERROR(HttpStatus.BAD_REQUEST,"이미지 파일 업로드 에러발생."), diff --git a/src/main/java/PNUMEAT/Backend/global/error/Team/TeamManagerInvalidException.java b/src/main/java/PNUMEAT/Backend/global/error/Team/TeamManagerInvalidException.java new file mode 100644 index 0000000..8c59c85 --- /dev/null +++ b/src/main/java/PNUMEAT/Backend/global/error/Team/TeamManagerInvalidException.java @@ -0,0 +1,11 @@ +package PNUMEAT.Backend.global.error.Team; + +import PNUMEAT.Backend.global.error.ComonException; + +import static PNUMEAT.Backend.global.error.ErrorCode.TEAM_MANAGER_INVALID_ERROR; + +public class TeamManagerInvalidException extends ComonException { + public TeamManagerInvalidException(){ + super(TEAM_MANAGER_INVALID_ERROR); + } +} diff --git a/src/main/java/PNUMEAT/Backend/global/response/ResponseMessageEnum.java b/src/main/java/PNUMEAT/Backend/global/response/ResponseMessageEnum.java index d7023a8..1f7a0b7 100644 --- a/src/main/java/PNUMEAT/Backend/global/response/ResponseMessageEnum.java +++ b/src/main/java/PNUMEAT/Backend/global/response/ResponseMessageEnum.java @@ -9,6 +9,7 @@ public enum ResponseMessageEnum { TEAM_TOTAL_DETAILS_SUCCESS("전체 팀을 성공적으로 조회했습니다.",200), MY_TEAM_DETAILS_SUCCESS("나의 팀을 성공적으로 조회했습니다.",200), TEAM_JOIN_SUCCESS("팀에 성공적으로 가입했습니다.", 200), + TEAM_ANNOUNCEMENT_UPDATE_SUCCESS("팀 공지가 성공적으로 업데이트되었습니다.", 200), //Article ARTICLE_CREATE_SUCCESS("게시글이 성공적으로 생성되었습니다.",201), diff --git a/src/test/java/PNUMEAT/Backend/domain/team/service/TeamServiceTest.java b/src/test/java/PNUMEAT/Backend/domain/team/service/TeamServiceTest.java index d520c66..2f5618d 100644 --- a/src/test/java/PNUMEAT/Backend/domain/team/service/TeamServiceTest.java +++ b/src/test/java/PNUMEAT/Backend/domain/team/service/TeamServiceTest.java @@ -265,4 +265,52 @@ private Team createTeam(String teamName, String teamExplain, int maxParticipant, .teamManager(teamManager) .build(); } + + @Test + @DisplayName("팀 공지 업데이트 하기 - 정상 업데이트") + void updateTeamAnnouncement_정상_업데이트() { + // given + Long teamId = team2.getTeamId(); + String teamAnnouncement = "팀 공지 입니다."; + + given(teamRepository.findById(teamId)).willReturn(Optional.of(team2)); + + // when + Team team = teamService.updateTeamAnnouncement(member, teamAnnouncement, teamId); + + // then + assertThat(team.getTeamId()).isEqualTo(teamId); + assertThat(team.getTeamManager().getUuid()).isEqualTo(member.getUuid()); + assertThat(team.getTeamAnnouncement()).isEqualTo(teamAnnouncement); + + } + + @Test + @DisplayName("팀 공지 올리기 - 팀이 존재하지 않을 때") + void updateTeamAnnouncement_팀이_존재하지_않을_때() { + // given + Long teamId = team2.getTeamId(); + String teamAnnouncement = "팀 공지 입니다."; + given(teamRepository.findById(teamId)).willReturn(Optional.empty()); + + // expected + assertThatThrownBy(() -> teamService.updateTeamAnnouncement(member, teamAnnouncement, teamId)) + .isInstanceOf(ComonException.class) + .hasMessage(TEAM_NOT_FOUND_ERROR.getMessage()); + } + + @Test + @DisplayName("팀 공지 올리기 - 팀의 매니저가 아닐 때") + void updateTeamAnnouncement_팀의_매니저가_아닐_때() { + // given + Long teamId = team2.getTeamId(); + String teamAnnouncement = "팀 공지 입니다."; + Member invalidMember = new Member("INVALID", "INVALID", "ROLE_USER"); + given(teamRepository.findById(teamId)).willReturn(Optional.of(team2)); + + // expected + assertThatThrownBy(() -> teamService.updateTeamAnnouncement(invalidMember, teamAnnouncement, teamId)) + .isInstanceOf(ComonException.class) + .hasMessage(TEAM_MANAGER_INVALID_ERROR.getMessage()); + } } \ No newline at end of file