From 20a98990d980dbb6361860a5ff3e4d5ae7eb0284 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Sun, 22 Oct 2023 16:17:30 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/Overview.adoc | 20 +++++++++++++++++++ .../backend/global/response/ErrorCode.java | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/docs/asciidoc/Overview.adoc b/src/docs/asciidoc/Overview.adoc index 5f488cc2..318e4f2e 100644 --- a/src/docs/asciidoc/Overview.adoc +++ b/src/docs/asciidoc/Overview.adoc @@ -94,6 +94,15 @@ | `T0002` | 소모임을 수정, 삭제하려고 할 때 | 소모임장이 아님 (권한 없음) + +| `T0003` +| 소모임을 가입할 때 +| 소모임을 이미 탈퇴함 + +| `T0004` +| 소모임을 가입할 때 +| 소모임을 이미 가입함 + |=== === Board ErrorCode @@ -108,6 +117,17 @@ | 작성자가 아님 (권한 없음) |=== +|=== +| ErrorCode | Scope | Description +| `BC0001` +| API PATH에 boardId가 있을 때 +| boardId가 유효하지 않음 (존재하지 않음) + +| `BC0002` +| 게시글을 수정, 삭제하려고 할 때 +| 작성자가 아님 (권한 없음) +|=== + === Mission ErrorCode |=== | ErrorCode | Scope | Description diff --git a/src/main/java/com/moing/backend/global/response/ErrorCode.java b/src/main/java/com/moing/backend/global/response/ErrorCode.java index 45b306d2..3e6834e3 100644 --- a/src/main/java/com/moing/backend/global/response/ErrorCode.java +++ b/src/main/java/com/moing/backend/global/response/ErrorCode.java @@ -47,8 +47,8 @@ public enum ErrorCode { NOT_AUTH_BY_BOARD_ID_ERROR("B0002","권한이 없습니다."), //게시글 댓글 관련 에러 코드 - NOT_FOUND_BY_BOARD_COMMENT_ID_ERROR("B0001","해당 boardCommentId인 댓글이 존재하지 않습니다."), - NOT_AUTH_BY_BOARD_COMMENT_ID_ERROR("B0002","권한이 없습니다."); + NOT_FOUND_BY_BOARD_COMMENT_ID_ERROR("BC0001","해당 boardCommentId인 댓글이 존재하지 않습니다."), + NOT_AUTH_BY_BOARD_COMMENT_ID_ERROR("BC0002","권한이 없습니다."); private String errorCode; private String message; From 111ed774d8636380574bd42b8c43e035cfa6bbd9 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Sun, 22 Oct 2023 17:21:35 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=95=8C=EB=9E=8C=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/domain/entity/Member.java | 3 +++ .../application/service/AlarmUserCase.java | 27 ++++++++++++++++--- .../exception/AlarmInvalidException.java | 11 ++++++++ .../mypage/exception/MyPageException.java | 11 ++++++++ .../mypage/presentation/MyPageController.java | 14 ++++++++-- .../backend/global/response/ErrorCode.java | 4 ++- 6 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/moing/backend/domain/mypage/exception/AlarmInvalidException.java create mode 100644 src/main/java/com/moing/backend/domain/mypage/exception/MyPageException.java diff --git a/src/main/java/com/moing/backend/domain/member/domain/entity/Member.java b/src/main/java/com/moing/backend/domain/member/domain/entity/Member.java index 06bef64f..79825c9a 100644 --- a/src/main/java/com/moing/backend/domain/member/domain/entity/Member.java +++ b/src/main/java/com/moing/backend/domain/member/domain/entity/Member.java @@ -101,6 +101,9 @@ public void signUp(SignUpRequest signUpRequest) { this.birthDate = LocalDate.parse(signUpRequest.getBirthDate(), DateTimeFormatter.ISO_DATE);; this.fcmToken = signUpRequest.getFcmToken(); this.registrationStatus = RegistrationStatus.COMPLETED; + this.isNewUploadPush=true; + this.isFirePush=true; + this.isRemindPush=true; } @Builder diff --git a/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java b/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java index b535db5f..55e3a6ca 100644 --- a/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java +++ b/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java @@ -1,12 +1,11 @@ package com.moing.backend.domain.mypage.application.service; -import com.moing.backend.domain.member.application.mapper.MemberMapper; import com.moing.backend.domain.member.domain.entity.Member; import com.moing.backend.domain.member.domain.service.MemberGetService; import com.moing.backend.domain.mypage.application.dto.response.GetAlarmResponse; +import com.moing.backend.domain.mypage.exception.AlarmInvalidException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import org.springframework.web.bind.annotation.RequestBody; import javax.transaction.Transactional; @@ -15,10 +14,32 @@ @RequiredArgsConstructor public class AlarmUserCase { - private MemberGetService memberGetService; + private final MemberGetService memberGetService; public GetAlarmResponse getAlarm(String socialId){ Member member=memberGetService.getMemberBySocialId(socialId); return new GetAlarmResponse(member.isNewUploadPush(),member.isRemindPush(), member.isFirePush()); } + + public void updateAlarm(String socialId, String type, String status) { + Member member = memberGetService.getMemberBySocialId(socialId); + boolean push = "on".equals(status); + + switch (type) { + case "all": + member.updateAllPush(push); + break; + case "isNewUploadPush": + member.updateNewUploadPush(push); + break; + case "isRemindPush": + member.updateRemindPush(push); + break; + case "isFirePush": + member.updateFirePush(push); + break; + default: + throw new AlarmInvalidException(); + } + } } diff --git a/src/main/java/com/moing/backend/domain/mypage/exception/AlarmInvalidException.java b/src/main/java/com/moing/backend/domain/mypage/exception/AlarmInvalidException.java new file mode 100644 index 00000000..6fd3c4d2 --- /dev/null +++ b/src/main/java/com/moing/backend/domain/mypage/exception/AlarmInvalidException.java @@ -0,0 +1,11 @@ +package com.moing.backend.domain.mypage.exception; + +import com.moing.backend.global.response.ErrorCode; +import org.springframework.http.HttpStatus; + +public class AlarmInvalidException extends MyPageException { + public AlarmInvalidException() { + super(ErrorCode.INVALID_ALARM_ERROR, + HttpStatus.NOT_FOUND); + } +} diff --git a/src/main/java/com/moing/backend/domain/mypage/exception/MyPageException.java b/src/main/java/com/moing/backend/domain/mypage/exception/MyPageException.java new file mode 100644 index 00000000..20aabdc1 --- /dev/null +++ b/src/main/java/com/moing/backend/domain/mypage/exception/MyPageException.java @@ -0,0 +1,11 @@ +package com.moing.backend.domain.mypage.exception; + +import com.moing.backend.global.exception.ApplicationException; +import com.moing.backend.global.response.ErrorCode; +import org.springframework.http.HttpStatus; + +public abstract class MyPageException extends ApplicationException { + protected MyPageException(ErrorCode errorCode, HttpStatus httpStatus) { + super(errorCode, httpStatus); + } +} diff --git a/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java b/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java index 928980fc..6eb2532f 100644 --- a/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java +++ b/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java @@ -28,8 +28,6 @@ public class MyPageController { private final AlarmUserCase alarmUserCase; private final GetMyPageUserCase getMyPageUserCase; - //TODO 알림설정 수정 - /** * 로그아웃 * [POST] api/mypage/signOut @@ -95,4 +93,16 @@ public ResponseEntity> getAlarm(@Authenticatio return ResponseEntity.ok(SuccessResponse.create(GET_ALARM_SUCCESS.getMessage(), this.alarmUserCase.getAlarm(user.getSocialId()))); } + /** + * 알림정보 수정 + * [POST] api/mypage/alarm?type=all || isNewUploadPush || isRemindPush || isFirePush && status= on || off + */ + @PutMapping("/alarm") + public ResponseEntity updateAlarm(@AuthenticationPrincipal User user, + @RequestParam(name = "type") String type, + @RequestParam(name = "status") String status) { + this.alarmUserCase.updateAlarm(user.getSocialId(), type, status); + return ResponseEntity.ok(SuccessResponse.create(UPDATE_PROFILE_SUCCESS.getMessage())); + } + } diff --git a/src/main/java/com/moing/backend/global/response/ErrorCode.java b/src/main/java/com/moing/backend/global/response/ErrorCode.java index 3e6834e3..129e9f03 100644 --- a/src/main/java/com/moing/backend/global/response/ErrorCode.java +++ b/src/main/java/com/moing/backend/global/response/ErrorCode.java @@ -42,6 +42,9 @@ public enum ErrorCode { ALREADY_WITHDRAW_ERROR("T0003","이미 탈퇴한 회원입니다."), ALREADY_JOIN_ERROR("T0004","이미 가입한 회원입니다."), + //마이페이지 관련 에러 코드 + INVALID_ALARM_ERROR("MP0001","유효하지 않는 알람 입력값입니다"), + //게시글 관련 에러 코드 NOT_FOUND_BY_BOARD_ID_ERROR("B0001","해당 boardId인 게시글이 존재하지 않습니다."), NOT_AUTH_BY_BOARD_ID_ERROR("B0002","권한이 없습니다."), @@ -49,7 +52,6 @@ public enum ErrorCode { //게시글 댓글 관련 에러 코드 NOT_FOUND_BY_BOARD_COMMENT_ID_ERROR("BC0001","해당 boardCommentId인 댓글이 존재하지 않습니다."), NOT_AUTH_BY_BOARD_COMMENT_ID_ERROR("BC0002","권한이 없습니다."); - private String errorCode; private String message; From b30b2d37fb888d299afcd7be58a7a2eb18111a24 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Sun, 22 Oct 2023 17:47:43 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=EC=95=8C=EB=9E=8C=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20test=20docs=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/docs/asciidoc/Mypage-API.adoc | 11 +++ .../application/service/AlarmUserCase.java | 3 +- .../mypage/presentation/MyPageController.java | 5 +- .../presentation/MypageControllerTest.java | 87 ++++++++++++++++++- 4 files changed, 101 insertions(+), 5 deletions(-) diff --git a/src/docs/asciidoc/Mypage-API.adoc b/src/docs/asciidoc/Mypage-API.adoc index 59e4d843..adb5aa3b 100644 --- a/src/docs/asciidoc/Mypage-API.adoc +++ b/src/docs/asciidoc/Mypage-API.adoc @@ -33,3 +33,14 @@ Host: localhost:8080 { "profileImage" : "PROFILE_IMAGE_URL" } + + +[[Mypage-알람설정_조회]] +=== Mypage 알람설정 조회 +operation::mypage-controller-test/get_alarm[snippets='http-request,http-response,response-fields'] + + +[[Mypage-알람설정_수정]] +=== Mypage 알람설정 수정 +operation::mypage-controller-test/update_alarm[snippets='http-request,http-response,request-parameters,response-fields'] + diff --git a/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java b/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java index 55e3a6ca..1d9c7a6e 100644 --- a/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java +++ b/src/main/java/com/moing/backend/domain/mypage/application/service/AlarmUserCase.java @@ -21,7 +21,7 @@ public GetAlarmResponse getAlarm(String socialId){ return new GetAlarmResponse(member.isNewUploadPush(),member.isRemindPush(), member.isFirePush()); } - public void updateAlarm(String socialId, String type, String status) { + public GetAlarmResponse updateAlarm(String socialId, String type, String status) { Member member = memberGetService.getMemberBySocialId(socialId); boolean push = "on".equals(status); @@ -41,5 +41,6 @@ public void updateAlarm(String socialId, String type, String status) { default: throw new AlarmInvalidException(); } + return new GetAlarmResponse(member.isNewUploadPush(),member.isRemindPush(), member.isFirePush()); } } diff --git a/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java b/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java index 6eb2532f..daeb6ffb 100644 --- a/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java +++ b/src/main/java/com/moing/backend/domain/mypage/presentation/MyPageController.java @@ -98,11 +98,10 @@ public ResponseEntity> getAlarm(@Authenticatio * [POST] api/mypage/alarm?type=all || isNewUploadPush || isRemindPush || isFirePush && status= on || off */ @PutMapping("/alarm") - public ResponseEntity updateAlarm(@AuthenticationPrincipal User user, + public ResponseEntity> updateAlarm(@AuthenticationPrincipal User user, @RequestParam(name = "type") String type, @RequestParam(name = "status") String status) { - this.alarmUserCase.updateAlarm(user.getSocialId(), type, status); - return ResponseEntity.ok(SuccessResponse.create(UPDATE_PROFILE_SUCCESS.getMessage())); + return ResponseEntity.ok(SuccessResponse.create(UPDATE_PROFILE_SUCCESS.getMessage(), this.alarmUserCase.updateAlarm(user.getSocialId(), type, status))); } } diff --git a/src/test/java/com/moing/backend/domain/mypage/presentation/MypageControllerTest.java b/src/test/java/com/moing/backend/domain/mypage/presentation/MypageControllerTest.java index 161680db..d8364020 100644 --- a/src/test/java/com/moing/backend/domain/mypage/presentation/MypageControllerTest.java +++ b/src/test/java/com/moing/backend/domain/mypage/presentation/MypageControllerTest.java @@ -3,11 +3,11 @@ import com.moing.backend.config.CommonControllerTest; import com.moing.backend.domain.mypage.application.dto.request.UpdateProfileRequest; import com.moing.backend.domain.mypage.application.dto.request.WithdrawRequest; +import com.moing.backend.domain.mypage.application.dto.response.GetAlarmResponse; import com.moing.backend.domain.mypage.application.dto.response.GetMyPageResponse; import com.moing.backend.domain.mypage.application.dto.response.GetMyPageTeamBlock; import com.moing.backend.domain.mypage.application.dto.response.GetProfileResponse; import com.moing.backend.domain.mypage.application.service.*; -import com.moing.backend.domain.team.application.dto.response.CreateTeamResponse; import com.moing.backend.domain.team.domain.constant.Category; import org.junit.jupiter.api.Test; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -23,6 +23,8 @@ import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.requestParameters; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -240,4 +242,87 @@ public void update_profile() throws Exception { ) ); } + + + @Test + public void get_alarm() throws Exception { + //given + GetAlarmResponse output = GetAlarmResponse.builder() + .isNewUploadPush(true) + .isFirePush(true) + .isRemindPush(true) + .build(); + + given(alarmUserCase.getAlarm(any())).willReturn(output); + + //when + ResultActions actions = mockMvc.perform( + get("/api/mypage/alarm") + .header("Authorization", "Bearer ACCESS_TOKEN") + .contentType(MediaType.APPLICATION_JSON) + ); + + + //then + actions + .andExpect(status().isOk()) + .andDo( + restDocs.document( + requestHeaders( + headerWithName("Authorization").description("접근 토큰") + ), + responseFields( + fieldWithPath("isSuccess").description("true"), + fieldWithPath("message").description("알람 정보를 조회했습니다"), + fieldWithPath("data.newUploadPush").description("신규 공지 알림"), + fieldWithPath("data.remindPush").description("미션 리마인드 알림"), + fieldWithPath("data.firePush").description("불 던지기 알림") + ) + ) + ); + } + + @Test + public void update_alarm() throws Exception { + //given + GetAlarmResponse output = GetAlarmResponse.builder() + .isNewUploadPush(true) + .isFirePush(true) + .isRemindPush(true) + .build(); + + given(alarmUserCase.updateAlarm(any(),any(),any())).willReturn(output); + + //when + ResultActions actions = mockMvc.perform( + put("/api/mypage/alarm") + .header("Authorization", "Bearer ACCESS_TOKEN") + .contentType(MediaType.APPLICATION_JSON) + .param("type", "all") // 파라미터 추가 + .param("status", "on") // 파라미터 추가 + ); + + + //then + actions + .andExpect(status().isOk()) + .andDo( + restDocs.document( + requestHeaders( + headerWithName("Authorization").description("접근 토큰") + ), + requestParameters( // 요청 파라미터 문서화 + parameterWithName("type").description("all || isNewUploadPush || isRemindPush || isFirePush"), + parameterWithName("status").description("on || off") + ), + responseFields( + fieldWithPath("isSuccess").description("true"), + fieldWithPath("message").description("알람 정보를 수정했습니다"), + fieldWithPath("data.newUploadPush").description("신규 공지 알림"), + fieldWithPath("data.remindPush").description("미션 리마인드 알림"), + fieldWithPath("data.firePush").description("불 던지기 알림") + ) + ) + ); + } } From 92caa139ebde220a80483a3d40f83d96027f1136 Mon Sep 17 00:00:00 2001 From: minsu20 Date: Mon, 23 Oct 2023 03:15:35 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=ED=8C=80=EB=A9=A4=EB=B2=84=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/service/TeamMemberSaveService.java | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java index f3ca19d0..8d432399 100644 --- a/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java +++ b/src/main/java/com/moing/backend/domain/teamMember/domain/service/TeamMemberSaveService.java @@ -18,20 +18,19 @@ public class TeamMemberSaveService { private final TeamMemberRepository teamMemberRepository; public void addTeamMember(Team team, Member member){ - Optional existingTeamMemberOpt = teamMemberRepository.findTeamMemberByTeamAndMember(team, member); - - TeamMember teamMember = existingTeamMemberOpt.orElseGet(() -> { + Optional teamMember = teamMemberRepository.findTeamMemberByTeamAndMember(team, member); + if (teamMember.isPresent()) { + if (teamMember.get().isDeleted()) { + throw new AlreadyWithdrawTeamException(); + } else { + throw new AlreadyJoinTeamException(); + } + } else { TeamMember newMember = new TeamMember(); newMember.updateMember(member); newMember.updateTeam(team); team.addTeamMember(); - return teamMemberRepository.save(newMember); - }); - - if (teamMember.isDeleted()) { - throw new AlreadyWithdrawTeamException(); - } else { - throw new AlreadyJoinTeamException(); + this.teamMemberRepository.save(newMember); } } }