From 1263a766e4db763aee011c492d1146c3bd6ff097 Mon Sep 17 00:00:00 2001 From: sypark Date: Sat, 31 Aug 2024 22:58:12 +0900 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8feature[#197]:=20=EB=82=A0?= =?UTF-8?q?=EC=A7=9C=20=EA=B8=B0=EB=B0=98=20=EB=AA=A9=ED=91=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=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 --- .../goal/controller/GoalController.java | 38 +++++++++++++++++++ .../goal/dto/response/GoalListResponse.java | 17 +++++++++ .../goal/dto/response/GoalResponse.java | 15 ++++++++ 3 files changed, 70 insertions(+) create mode 100644 src/main/java/com/sillim/recordit/goal/controller/GoalController.java create mode 100644 src/main/java/com/sillim/recordit/goal/dto/response/GoalListResponse.java create mode 100644 src/main/java/com/sillim/recordit/goal/dto/response/GoalResponse.java diff --git a/src/main/java/com/sillim/recordit/goal/controller/GoalController.java b/src/main/java/com/sillim/recordit/goal/controller/GoalController.java new file mode 100644 index 0000000..781acc6 --- /dev/null +++ b/src/main/java/com/sillim/recordit/goal/controller/GoalController.java @@ -0,0 +1,38 @@ +package com.sillim.recordit.goal.controller; + +import com.sillim.recordit.config.security.authenticate.CurrentMember; +import com.sillim.recordit.goal.domain.MonthlyGoal; +import com.sillim.recordit.goal.domain.WeeklyGoal; +import com.sillim.recordit.goal.dto.response.GoalListResponse; +import com.sillim.recordit.goal.service.MonthlyGoalQueryService; +import com.sillim.recordit.goal.service.WeeklyGoalQueryService; +import com.sillim.recordit.member.domain.Member; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/goals") +public class GoalController { + + private final MonthlyGoalQueryService monthlyGoalQueryService; + private final WeeklyGoalQueryService weeklyGoalQueryService; + + @GetMapping + public ResponseEntity getGoalListByDate( + @RequestParam final Integer year, + @RequestParam final Integer month, + @CurrentMember final Member member) { + + List monthlyGoals = + monthlyGoalQueryService.searchAllByDate(year, month, member.getId()); + List weeklyGoals = + weeklyGoalQueryService.searchAllWeeklyGoalByDate(year, month, member.getId()); + return ResponseEntity.ok(GoalListResponse.of(monthlyGoals, weeklyGoals)); + } +} diff --git a/src/main/java/com/sillim/recordit/goal/dto/response/GoalListResponse.java b/src/main/java/com/sillim/recordit/goal/dto/response/GoalListResponse.java new file mode 100644 index 0000000..372a178 --- /dev/null +++ b/src/main/java/com/sillim/recordit/goal/dto/response/GoalListResponse.java @@ -0,0 +1,17 @@ +package com.sillim.recordit.goal.dto.response; + +import com.sillim.recordit.goal.domain.MonthlyGoal; +import com.sillim.recordit.goal.domain.WeeklyGoal; +import java.util.List; + +public record GoalListResponse(List monthlyGoals, List weeklyGoals) { + + public static GoalListResponse of( + final List monthlyGoals, final List weeklyGoals) { + List monthlyGoalResponses = + monthlyGoals.stream().map(GoalResponse::from).toList(); + List weeklyGoalResponses = + weeklyGoals.stream().map(GoalResponse::from).toList(); + return new GoalListResponse(monthlyGoalResponses, weeklyGoalResponses); + } +} diff --git a/src/main/java/com/sillim/recordit/goal/dto/response/GoalResponse.java b/src/main/java/com/sillim/recordit/goal/dto/response/GoalResponse.java new file mode 100644 index 0000000..d91887a --- /dev/null +++ b/src/main/java/com/sillim/recordit/goal/dto/response/GoalResponse.java @@ -0,0 +1,15 @@ +package com.sillim.recordit.goal.dto.response; + +import com.sillim.recordit.goal.domain.MonthlyGoal; +import com.sillim.recordit.goal.domain.WeeklyGoal; + +public record GoalResponse(Long id, String title) { + + public static GoalResponse from(final MonthlyGoal monthlyGoal) { + return new GoalResponse(monthlyGoal.getId(), monthlyGoal.getTitle()); + } + + public static GoalResponse from(final WeeklyGoal weeklyGoal) { + return new GoalResponse(weeklyGoal.getId(), weeklyGoal.getTitle()); + } +} From 96f8498abd41fbc51dcc684b61f0c5241eb37646 Mon Sep 17 00:00:00 2001 From: sypark Date: Sat, 31 Aug 2024 23:29:27 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=A8feature[#197]:=20=ED=95=A0=20?= =?UTF-8?q?=EC=9D=BC=20=EC=B6=94=EA=B0=80/=EC=88=98=EC=A0=95=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=EA=B3=BC=20=EC=97=B0=EA=B4=80=20=EC=A3=BC=20=EB=AA=A9?= =?UTF-8?q?=ED=91=9C=20=EC=97=B0=EA=B2=B0=20=EA=B8=B0=EB=8A=A5=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sillim/recordit/task/service/TaskGroupService.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/sillim/recordit/task/service/TaskGroupService.java b/src/main/java/com/sillim/recordit/task/service/TaskGroupService.java index 3c544b3..0254f60 100644 --- a/src/main/java/com/sillim/recordit/task/service/TaskGroupService.java +++ b/src/main/java/com/sillim/recordit/task/service/TaskGroupService.java @@ -6,6 +6,7 @@ import com.sillim.recordit.goal.domain.WeeklyGoal; import com.sillim.recordit.goal.dto.RelatedGoals; import com.sillim.recordit.goal.service.MonthlyGoalQueryService; +import com.sillim.recordit.goal.service.WeeklyGoalQueryService; import com.sillim.recordit.task.domain.TaskGroup; import com.sillim.recordit.task.domain.repetition.TaskRepetitionPatternFactory; import com.sillim.recordit.task.dto.request.TaskGroupUpdateRequest; @@ -21,7 +22,7 @@ public class TaskGroupService { private final MonthlyGoalQueryService monthlyGoalQueryService; - // TODO: WeeklyGoal 기능 구현 후 추가 필요 + private final WeeklyGoalQueryService weeklyGoalQueryService; private final TaskGroupRepository taskGroupRepository; @@ -137,7 +138,8 @@ private RelatedGoals getRelatedGoals( return RelatedGoals.empty(); } if (monthlyGoalId == null) { - WeeklyGoal weeklyGoal = null; + WeeklyGoal weeklyGoal = + weeklyGoalQueryService.searchByIdAndCheckAuthority(weeklyGoalId, memberId); return RelatedGoals.from(weeklyGoal); } if (weeklyGoalId == null) { @@ -147,7 +149,8 @@ private RelatedGoals getRelatedGoals( } MonthlyGoal monthlyGoal = monthlyGoalQueryService.searchByIdAndCheckAuthority(monthlyGoalId, memberId); - WeeklyGoal weeklyGoal = null; + WeeklyGoal weeklyGoal = + weeklyGoalQueryService.searchByIdAndCheckAuthority(weeklyGoalId, memberId); return RelatedGoals.of(monthlyGoal, weeklyGoal); } } From ad55c4782b18aa26b1d22ff381fe91b2a51f2bf2 Mon Sep 17 00:00:00 2001 From: sypark Date: Sat, 31 Aug 2024 23:39:18 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=85test[#197]:=20=ED=95=B4=EB=8B=B9?= =?UTF-8?q?=20=EC=9B=94=20=EB=AA=A9=ED=91=9C=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../goal/controller/GoalControllerTest.java | 111 ++++++++++++++++++ .../task/service/TaskGroupServiceTest.java | 2 + 2 files changed, 113 insertions(+) create mode 100644 src/test/java/com/sillim/recordit/goal/controller/GoalControllerTest.java diff --git a/src/test/java/com/sillim/recordit/goal/controller/GoalControllerTest.java b/src/test/java/com/sillim/recordit/goal/controller/GoalControllerTest.java new file mode 100644 index 0000000..2cb778a --- /dev/null +++ b/src/test/java/com/sillim/recordit/goal/controller/GoalControllerTest.java @@ -0,0 +1,111 @@ +package com.sillim.recordit.goal.controller; + +import static com.sillim.recordit.support.restdocs.ApiDocumentUtils.getDocumentRequest; +import static com.sillim.recordit.support.restdocs.ApiDocumentUtils.getDocumentResponse; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.spy; +import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; +import static org.springframework.restdocs.request.RequestDocumentation.queryParameters; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.sillim.recordit.goal.domain.MonthlyGoal; +import com.sillim.recordit.goal.domain.WeeklyGoal; +import com.sillim.recordit.goal.fixture.MonthlyGoalFixture; +import com.sillim.recordit.goal.fixture.WeeklyGoalFixture; +import com.sillim.recordit.goal.service.MonthlyGoalQueryService; +import com.sillim.recordit.goal.service.WeeklyGoalQueryService; +import com.sillim.recordit.member.domain.Member; +import com.sillim.recordit.member.fixture.MemberFixture; +import com.sillim.recordit.support.restdocs.RestDocsTest; +import java.util.List; +import java.util.stream.LongStream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.servlet.ResultActions; + +@WebMvcTest(GoalController.class) +public class GoalControllerTest extends RestDocsTest { + + @MockBean MonthlyGoalQueryService monthlyGoalQueryService; + @MockBean WeeklyGoalQueryService weeklyGoalQueryService; + + private Member member; + + @BeforeEach + void beforeEach() { + member = MemberFixture.DEFAULT.getMember(); + } + + @Test + @DisplayName("당월의 목표 목록을 조회한다.") + void monthlyGoalListTest() throws Exception { + List monthlyGoals = + LongStream.rangeClosed(1, 3) + .mapToObj( + (id) -> { + MonthlyGoal goal = + spy(MonthlyGoalFixture.DEFAULT.getWithMember(member)); + given(goal.getId()).willReturn(id); + given(goal.isAchieved()).willReturn(id % 2 == 0); + return goal; + }) + .toList(); + given(monthlyGoalQueryService.searchAllByDate(anyInt(), anyInt(), any())) + .willReturn(monthlyGoals); + List weeklyGoals = + LongStream.rangeClosed(1, 2) + .mapToObj( + (id) -> { + WeeklyGoal goal = + spy(WeeklyGoalFixture.DEFAULT.getWithMember(member)); + given(goal.getId()).willReturn(id); + given(goal.isAchieved()).willReturn(id % 2 == 0); + return goal; + }) + .toList(); + given(weeklyGoalQueryService.searchAllWeeklyGoalByDate(anyInt(), anyInt(), any())) + .willReturn(weeklyGoals); + + ResultActions perform = + mockMvc.perform( + get("/api/v1/goals") + .headers(authorizationHeader()) + .queryParam("year", "2024") + .queryParam("month", "4")); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.monthlyGoals.size()").value(3)) + .andExpect(jsonPath("$.weeklyGoals.size()").value(2)) + .andExpect(jsonPath("$.monthlyGoals.[0].id").value(1)) + .andExpect(jsonPath("$.monthlyGoals.[0].title").value("취뽀하기!")) + .andExpect(jsonPath("$.monthlyGoals.[1].id").value(2)) + .andExpect(jsonPath("$.monthlyGoals.[1].title").value("취뽀하기!")) + .andExpect(jsonPath("$.monthlyGoals.[2].id").value(3)) + .andExpect(jsonPath("$.monthlyGoals.[2].title").value("취뽀하기!")) + .andExpect(jsonPath("$.weeklyGoals.[0].id").value(1)) + .andExpect(jsonPath("$.weeklyGoals.[0].title").value("데이터베이스 3장까지")) + .andExpect(jsonPath("$.weeklyGoals.[1].id").value(2)) + .andExpect(jsonPath("$.weeklyGoals.[1].title").value("데이터베이스 3장까지")); + + perform.andDo(print()) + .andDo( + document( + "goal-list", + getDocumentRequest(), + getDocumentResponse(), + requestHeaders(authorizationDesc()), + queryParameters( + parameterWithName("year").description("조회할 연도"), + parameterWithName("month").description("조회할 월")))); + } +} diff --git a/src/test/java/com/sillim/recordit/task/service/TaskGroupServiceTest.java b/src/test/java/com/sillim/recordit/task/service/TaskGroupServiceTest.java index 85ad834..8d1813a 100644 --- a/src/test/java/com/sillim/recordit/task/service/TaskGroupServiceTest.java +++ b/src/test/java/com/sillim/recordit/task/service/TaskGroupServiceTest.java @@ -11,6 +11,7 @@ import com.sillim.recordit.goal.domain.MonthlyGoal; import com.sillim.recordit.goal.domain.WeeklyGoal; import com.sillim.recordit.goal.service.MonthlyGoalQueryService; +import com.sillim.recordit.goal.service.WeeklyGoalQueryService; import com.sillim.recordit.task.domain.TaskGroup; import com.sillim.recordit.task.domain.TaskRepetitionType; import com.sillim.recordit.task.domain.repetition.TaskRepetitionPattern; @@ -34,6 +35,7 @@ class TaskGroupServiceTest { @InjectMocks TaskGroupService taskGroupService; @Mock TaskGroupRepository taskGroupRepository; @Mock MonthlyGoalQueryService monthlyGoalQueryService; + @Mock WeeklyGoalQueryService weeklyGoalQueryService; // TODO: WeeklyGoal 기능 구현 후 테스트 추가 필요