Skip to content

Commit

Permalink
feat: 오늘 보상 벌레 조회 기능 구현 (#80)
Browse files Browse the repository at this point in the history
* feat: 오늘 얻은 벌레 조회 API 구현

* refactor: 쿼리 1번으로 수정

* feat: @CurrentMember 적용

* test: 벌레 조회 Controller 통합 테스트

* chore: 주석 제거

* test: 오늘 보상 벌레 조회 Controller 테스트

* test: memberService mock 처리

* chore: enum 비교 equals로 변경
  • Loading branch information
kmebin authored Nov 14, 2023
1 parent 622bc97 commit a3ac321
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 13 deletions.
8 changes: 8 additions & 0 deletions src/main/java/com/moabam/api/application/bug/BugMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.moabam.api.domain.bug.BugActionType;
import com.moabam.api.domain.bug.BugHistory;
import com.moabam.api.domain.bug.BugType;
import com.moabam.api.dto.TodayBugResponse;
import com.moabam.api.dto.bug.BugResponse;

import lombok.AccessLevel;
Expand All @@ -20,6 +21,13 @@ public static BugResponse toBugResponse(Bug bug) {
.build();
}

public static TodayBugResponse toTodayBugResponse(int morningBug, int nightBug) {
return TodayBugResponse.builder()
.morningBug(morningBug)
.nightBug(nightBug)
.build();
}

public static BugHistory toUseBugHistory(Long memberId, BugType bugType, int quantity) {
return BugHistory.builder()
.memberId(memberId)
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/moabam/api/application/bug/BugService.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
package com.moabam.api.application.bug;

import static com.moabam.api.domain.bug.BugActionType.*;
import static com.moabam.api.domain.bug.BugType.*;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.moabam.api.application.member.MemberService;
import com.moabam.api.domain.bug.BugHistory;
import com.moabam.api.domain.bug.BugType;
import com.moabam.api.domain.member.Member;
import com.moabam.api.domain.repository.BugHistorySearchRepository;
import com.moabam.api.dto.TodayBugResponse;
import com.moabam.api.dto.bug.BugResponse;
import com.moabam.global.common.util.ClockHolder;

import lombok.RequiredArgsConstructor;

Expand All @@ -15,10 +25,27 @@
public class BugService {

private final MemberService memberService;
private final BugHistorySearchRepository bugHistorySearchRepository;
private final ClockHolder clockHolder;

public BugResponse getBug(Long memberId) {
Member member = memberService.getById(memberId);

return BugMapper.toBugResponse(member.getBug());
}

public TodayBugResponse getTodayBug(Long memberId) {
List<BugHistory> todayRewardBug = bugHistorySearchRepository.find(memberId, REWARD, clockHolder.times());
int morningBug = calculateBugQuantity(todayRewardBug, MORNING);
int nightBug = calculateBugQuantity(todayRewardBug, NIGHT);

return BugMapper.toTodayBugResponse(morningBug, nightBug);
}

private int calculateBugQuantity(List<BugHistory> bugHistory, BugType bugType) {
return bugHistory.stream()
.filter(history -> bugType.equals(history.getBugType()))
.mapToInt(BugHistory::getQuantity)
.sum();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.moabam.api.domain.repository;

import static com.moabam.api.domain.bug.QBugHistory.*;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.stereotype.Repository;

import com.moabam.api.domain.bug.BugActionType;
import com.moabam.api.domain.bug.BugHistory;
import com.moabam.global.common.util.DynamicQuery;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;

@Repository
@RequiredArgsConstructor
public class BugHistorySearchRepository {

private final JPAQueryFactory jpaQueryFactory;

public List<BugHistory> find(Long memberId, BugActionType actionType, LocalDateTime dateTime) {
return jpaQueryFactory
.selectFrom(bugHistory)
.where(
DynamicQuery.generateEq(memberId, bugHistory.memberId::eq),
DynamicQuery.generateEq(actionType, bugHistory.actionType::eq),
DynamicQuery.generateEq(dateTime, this::equalDate)
)
.fetch();
}

private BooleanExpression equalDate(LocalDateTime dateTime) {
return bugHistory.createdAt.year().eq(dateTime.getYear())
.and(bugHistory.createdAt.month().eq(dateTime.getMonthValue()))
.and(bugHistory.createdAt.dayOfMonth().eq(dateTime.getDayOfMonth()));
}
}
11 changes: 11 additions & 0 deletions src/main/java/com/moabam/api/dto/TodayBugResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.moabam.api.dto;

import lombok.Builder;

@Builder
public record TodayBugResponse(
int morningBug,
int nightBug
) {

}
13 changes: 11 additions & 2 deletions src/main/java/com/moabam/api/presentation/BugController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import org.springframework.web.bind.annotation.RestController;

import com.moabam.api.application.bug.BugService;
import com.moabam.api.dto.TodayBugResponse;
import com.moabam.api.dto.bug.BugResponse;
import com.moabam.global.auth.annotation.CurrentMember;
import com.moabam.global.auth.model.AuthorizationMember;

import lombok.RequiredArgsConstructor;

Expand All @@ -20,7 +23,13 @@ public class BugController {

@GetMapping
@ResponseStatus(HttpStatus.OK)
public BugResponse getBug() {
return bugService.getBug(1L);
public BugResponse getBug(@CurrentMember AuthorizationMember member) {
return bugService.getBug(member.id());
}

@GetMapping("/today")
@ResponseStatus(HttpStatus.OK)
public TodayBugResponse getTodayBug(@CurrentMember AuthorizationMember member) {
return bugService.getTodayBug(member.id());
}
}
2 changes: 1 addition & 1 deletion src/main/resources/static/docs/coupon.html
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ <h3 id="_쿠폰_사용_진행_중">쿠폰 사용 (진행 중)</h3>
<div id="footer">
<div id="footer-text">
Version 0.0.1-SNAPSHOT<br>
Last updated 2023-11-12 16:01:40 +0900
Last updated 2023-11-13 18:48:03 +0900
</div>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/static/docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ <h4 id="_상태코드httpstatus"><a class="link" href="#_상태코드httpstatus"
<div id="footer">
<div id="footer-text">
Version 0.0.1-SNAPSHOT<br>
Last updated 2023-11-07 00:27:34 +0900
Last updated 2023-11-13 18:48:03 +0900
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js"></script>
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/static/docs/notification.html
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ <h4 id="_응답" class="discrete">응답</h4>
<div id="footer">
<div id="footer-text">
Version 0.0.1-SNAPSHOT<br>
Last updated 2023-11-12 16:01:40 +0900
Last updated 2023-11-13 18:48:03 +0900
</div>
</div>
</body>
Expand Down
60 changes: 52 additions & 8 deletions src/test/java/com/moabam/api/presentation/BugControllerTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.moabam.api.presentation;

import static com.moabam.global.auth.model.AuthorizationThreadLocal.*;
import static com.moabam.support.fixture.BugFixture.*;
import static com.moabam.support.fixture.BugHistoryFixture.*;
import static com.moabam.support.fixture.MemberFixture.*;
import static java.nio.charset.StandardCharsets.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
Expand All @@ -9,20 +12,30 @@
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

import java.util.List;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.moabam.api.application.bug.BugMapper;
import com.moabam.api.application.bug.BugService;
import com.moabam.api.application.member.MemberService;
import com.moabam.api.domain.bug.repository.BugHistoryRepository;
import com.moabam.api.domain.repository.BugHistorySearchRepository;
import com.moabam.api.dto.TodayBugResponse;
import com.moabam.api.dto.bug.BugResponse;
import com.moabam.support.annotation.WithMember;
import com.moabam.support.common.WithoutFilterSupporter;

@WebMvcTest(controllers = BugController.class)
@Transactional
@SpringBootTest
@AutoConfigureMockMvc
class BugControllerTest extends WithoutFilterSupporter {

@Autowired
Expand All @@ -32,25 +45,56 @@ class BugControllerTest extends WithoutFilterSupporter {
ObjectMapper objectMapper;

@MockBean
BugService bugService;
MemberService memberService;

@Autowired
BugHistoryRepository bugHistoryRepository;

@Autowired
BugHistorySearchRepository bugHistorySearchRepository;

@DisplayName("벌레를 조회한다.")
@WithMember
@Test
void get_bug_success() throws Exception {
// given
Long memberId = 1L;
Long memberId = getAuthorizationMember().id();
BugResponse expected = BugMapper.toBugResponse(bug());
given(bugService.getBug(memberId)).willReturn(expected);
given(memberService.getById(memberId)).willReturn(member());

// when, then
// expected
String content = mockMvc.perform(get("/bugs")
.contentType(APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk())
.andDo(print())
.andReturn()
.getResponse()
.getContentAsString(UTF_8);
BugResponse actual = objectMapper.readValue(content, BugResponse.class);
assertThat(actual).isEqualTo(expected);
}

@DisplayName("오늘 보상 벌레를 조회한다.")
@WithMember
@Test
void get_today_bug_success() throws Exception {
// given
Long memberId = getAuthorizationMember().id();
bugHistoryRepository.saveAll(List.of(
rewardMorningBug(memberId, 2),
rewardMorningBug(memberId, 3),
rewardNightBug(memberId, 5)));
TodayBugResponse expected = BugMapper.toTodayBugResponse(5, 5);

// expected
String content = mockMvc.perform(get("/bugs/today")
.contentType(APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(print())
.andReturn()
.getResponse()
.getContentAsString(UTF_8);
TodayBugResponse actual = objectMapper.readValue(content, TodayBugResponse.class);
assertThat(actual).isEqualTo(expected);
}
}
26 changes: 26 additions & 0 deletions src/test/java/com/moabam/support/fixture/BugHistoryFixture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.moabam.support.fixture;

import com.moabam.api.domain.bug.BugActionType;
import com.moabam.api.domain.bug.BugHistory;
import com.moabam.api.domain.bug.BugType;

public final class BugHistoryFixture {

public static BugHistory rewardMorningBug(Long memberId, int quantity) {
return BugHistory.builder()
.memberId(memberId)
.bugType(BugType.MORNING)
.actionType(BugActionType.REWARD)
.quantity(quantity)
.build();
}

public static BugHistory rewardNightBug(Long memberId, int quantity) {
return BugHistory.builder()
.memberId(memberId)
.bugType(BugType.NIGHT)
.actionType(BugActionType.REWARD)
.quantity(quantity)
.build();
}
}

0 comments on commit a3ac321

Please sign in to comment.