1+ package com .back .domain .level ;
2+
3+ import com .back .domain .level .entity .LevelXP ;
4+ import com .back .domain .level .repository .LevelXPRepository ;
5+ import com .back .domain .level .service .LevelUpService ;
6+ import com .back .domain .member .entity .Member ;
7+ import com .back .domain .member .repository .MemberRepository ;
8+ import com .back .domain .reward .entity .ContentType ;
9+ import com .back .domain .reward .entity .Reward ;
10+ import com .back .domain .reward .entity .RewardContent ;
11+ import com .back .domain .reward .entity .RewardType ;
12+ import com .back .domain .reward .repository .RewardRepository ;
13+ import org .junit .jupiter .api .BeforeEach ;
14+ import org .junit .jupiter .api .DisplayName ;
15+ import org .junit .jupiter .api .Test ;
16+ import org .springframework .beans .factory .annotation .Autowired ;
17+ import org .springframework .boot .test .context .SpringBootTest ;
18+ import org .springframework .transaction .annotation .Transactional ;
19+
20+ import java .util .List ;
21+ import java .util .Optional ;
22+
23+ import static org .assertj .core .api .Assertions .assertThat ;
24+
25+ @ SpringBootTest
26+ @ Transactional
27+ class LevelUpServiceTest {
28+
29+ @ Autowired private LevelUpService levelUpService ;
30+ @ Autowired private MemberRepository memberRepository ;
31+ @ Autowired private LevelXPRepository levelXPRepository ;
32+ @ Autowired private RewardRepository rewardRepository ;
33+
34+
35+ // 테스트용 상수
36+ private final int INITIAL_LEVEL = 1 ;
37+ private final int INITIAL_XP = 1000 ;
38+ private final int NEXT_LEVEL = 2 ;
39+
40+
41+ @ BeforeEach
42+ void setupData () {
43+ // 테스트 전 LevelXP 데이터 초기화 (Level 1, Level 2)
44+ // Level 1 데이터 (시작 누적 XP: 0L, 다음 레벨 필요 XP: 1500)
45+ levelXPRepository .save (new LevelXP (INITIAL_LEVEL , 500 , 0L ));
46+ // Level 2 데이터 (시작 누적 XP: 1500L, 다음 레벨 필요 XP: 1500 + X)
47+ long REQUIRED_XP_FOR_LEVEL2 = 1500L ;
48+ levelXPRepository .save (new LevelXP (NEXT_LEVEL , 1000 , REQUIRED_XP_FOR_LEVEL2 ));
49+ }
50+
51+
52+ @ Test
53+ @ DisplayName ("XP 요구치 충족 시 레벨업이 발생하고, DB에 저장된 보상을 성공적으로 지급한다" )
54+ void checkLevelUp_ShouldLevelUpAndGiveReward_IntegrationSuccess () {
55+ // GIVEN
56+
57+ // 1. 테스트 멤버 저장 (DB가 ID를 자동 생성합니다!)
58+ Member member = Member .builder ()
59+ .level (INITIAL_LEVEL )
60+ .xp (INITIAL_XP )
61+ .money (0 )
62+ .build ();
63+ member = memberRepository .save (member );
64+ Integer memberId = member .getId ();
65+
66+ // 2. 레벨업 보상 데이터 저장 (DB가 ID를 자동 생성합니다!)
67+ int MONEY_REWARD_AMOUNT = 500 ;
68+ Reward level2Reward = new Reward (
69+ RewardType .LEVELUP ,
70+ List .of (new RewardContent (ContentType .MONEY , MONEY_REWARD_AMOUNT )),
71+ NEXT_LEVEL // Level 2 달성 시 지급
72+ );
73+ rewardRepository .save (level2Reward );
74+
75+ // 3. 레벨업에 충분한 XP를 수동으로 설정 (Level 1000 -> 1501)
76+ int xpToLevelUp = 1501 ;
77+ member .setXp (xpToLevelUp );
78+ memberRepository .save (member ); // XP 변경 사항 저장
79+
80+ // WHEN
81+ // LevelUpService가 DB에서 member를 로드하고 로직을 수행합니다.
82+ levelUpService .checkLevelUp (memberId );
83+
84+ // THEN
85+ // 1. DB에서 변경된 멤버 정보를 다시 조회합니다.
86+ Optional <Member > updatedMemberOpt = memberRepository .findById (memberId );
87+ assertThat (updatedMemberOpt ).isPresent ();
88+ Member updatedMember = updatedMemberOpt .get ();
89+
90+ // 2. 레벨 및 XP 변경 확인
91+ assertThat (updatedMember .getLevel ()).isEqualTo (NEXT_LEVEL );
92+ assertThat (updatedMember .getXp ()).isEqualTo (xpToLevelUp );
93+
94+ // 3. 보상 지급 확인 (MONEY가 500 증가했는지)
95+ assertThat (updatedMember .getMoney ()).isEqualTo (MONEY_REWARD_AMOUNT ); // 0 + 500
96+ }
97+
98+
99+ @ Test
100+ @ DisplayName ("XP가 레벨업 요구치에 미달하면 레벨 및 보상 변화가 없다" )
101+ void checkLevelUp_ShouldNotLevelUp_NoChange () {
102+ // GIVEN
103+
104+ // 1. 테스트 멤버 저장
105+ Member member = Member .builder ()
106+ .level (INITIAL_LEVEL )
107+ .xp (INITIAL_XP )
108+ .money (0 )
109+ .build ();
110+ member = memberRepository .save (member );
111+ Integer memberId = member .getId ();
112+
113+ // 2. 레벨업에 부족한 XP를 설정 (Level 1000 -> 1499)
114+ int xpBelowLevelUp = 1499 ; // 요구치 1500 미만
115+ member .setXp (xpBelowLevelUp );
116+ memberRepository .save (member );
117+
118+ // WHEN
119+ levelUpService .checkLevelUp (memberId );
120+
121+ // THEN
122+ // 1. DB에서 변경된 멤버 정보를 다시 조회합니다.
123+ Member updatedMember = memberRepository .findById (memberId ).get ();
124+
125+ // 2. 레벨 및 XP 확인
126+ assertThat (updatedMember .getLevel ()).isEqualTo (INITIAL_LEVEL );
127+ assertThat (updatedMember .getXp ()).isEqualTo (xpBelowLevelUp );
128+
129+ // 3. 머니 보상 미지급 확인
130+ assertThat (updatedMember .getMoney ()).isEqualTo (0 );
131+ }
132+ }
0 commit comments