1+ package com .rentify .rentify_api .user .service ;
2+
3+ import static org .assertj .core .api .Assertions .assertThat ;
4+ import static org .assertj .core .api .Assertions .assertThatThrownBy ;
5+ import static org .mockito .ArgumentMatchers .any ;
6+ import static org .mockito .BDDMockito .given ;
7+ import static org .mockito .Mockito .never ;
8+ import static org .mockito .Mockito .times ;
9+ import static org .mockito .Mockito .verify ;
10+
11+ import com .rentify .rentify_api .common .exception .DuplicateException ;
12+ import com .rentify .rentify_api .common .exception .InvalidValueException ;
13+ import com .rentify .rentify_api .common .exception .NotFoundException ;
14+ import com .rentify .rentify_api .user .entity .EmailVerification ;
15+ import com .rentify .rentify_api .user .repository .EmailVerificationRepository ;
16+ import com .rentify .rentify_api .user .repository .UserRepository ;
17+ import java .time .LocalDateTime ;
18+ import java .util .Optional ;
19+ import org .junit .jupiter .api .DisplayName ;
20+ import org .junit .jupiter .api .Nested ;
21+ import org .junit .jupiter .api .Test ;
22+ import org .junit .jupiter .api .extension .ExtendWith ;
23+ import org .mockito .ArgumentCaptor ;
24+ import org .mockito .InjectMocks ;
25+ import org .mockito .Mock ;
26+ import org .mockito .junit .jupiter .MockitoExtension ;
27+
28+ @ ExtendWith (MockitoExtension .class )
29+ class AuthServiceTest {
30+
31+ @ Mock
32+ private UserRepository userRepository ;
33+ @ Mock
34+ private EmailVerificationRepository emailVerificationRepository ;
35+ @ Mock
36+ private MailService mailService ;
37+ @ InjectMocks
38+ private AuthService authService ;
39+
40+ @ Nested
41+ @ DisplayName ("이메일 인증 코드 전송 테스트 그룹" )
42+ class MailCodeVerification {
43+
44+ @ Test
45+ @ DisplayName ("이메일 인증 코드 전송 성공" )
46+ void send_mail_verification_code_success () {
47+ // given
48+ String email = "newmail@mail.com" ;
49+
50+ given (userRepository .existsByEmail (email )).willReturn (false );
51+
52+ // when
53+ authService .sendVerificationCode (email );
54+
55+ // then
56+ ArgumentCaptor <EmailVerification > captor = ArgumentCaptor .forClass (EmailVerification .class );
57+ verify (emailVerificationRepository , times (1 )).save (captor .capture ());
58+
59+ EmailVerification saved = captor .getValue ();
60+ assertThat (saved .getEmail ()).isEqualTo (email );
61+ assertThat (saved .getVerificationCode ()).isNotNull ();
62+ assertThat (saved .getIsVerified ()).isFalse ();
63+
64+ verify (mailService , times (1 )).sendAuthCode (email , saved .getVerificationCode ());
65+ }
66+
67+ @ Test
68+ @ DisplayName ("이미 가입된 메일 인증 요청" )
69+ void duplicate_mail_verification_request () {
70+ // given
71+ String email = "exists@mail.com" ;
72+
73+ given (userRepository .existsByEmail (email )).willReturn (true );
74+
75+ // when
76+ assertThatThrownBy (() -> authService .sendVerificationCode (email ))
77+ .isInstanceOf (DuplicateException .class )
78+ .hasMessage ("이미 가입된 계정입니다." );
79+
80+ verify (emailVerificationRepository , never ()).save (any ());
81+ verify (mailService , never ()).sendAuthCode (any (), any ());
82+ }
83+ }
84+
85+ @ Nested
86+ @ DisplayName ("이메일 인증 테스트 그룹" )
87+ class MailVerification {
88+
89+ @ Test
90+ @ DisplayName ("이메일 인증 성공" )
91+ void mail_verification_success () {
92+ // given
93+ String email = "abc@email.com" ;
94+ String code = "123456" ;
95+ EmailVerification verification = EmailVerification .builder ()
96+ .expiredAt (LocalDateTime .now ().plusMinutes (5 ))
97+ .verificationCode (code )
98+ .isVerified (false )
99+ .build ();
100+
101+ given (emailVerificationRepository .findFirstByEmailOrderByCreatedAtDesc (email ))
102+ .willReturn (Optional .of (verification ));
103+
104+ // when
105+ authService .verifyEmail (email , code );
106+
107+ // then
108+ assertThat (verification .getIsVerified ()).isTrue ();
109+ }
110+
111+ @ Test
112+ @ DisplayName ("이메일 인증 실패: 인증 요청 내역이 없는 경우 예외 발생" )
113+ void mail_verification_fail_not_found () {
114+ // given
115+ String email = "exists@mail.com" ;
116+
117+ given (emailVerificationRepository .findFirstByEmailOrderByCreatedAtDesc (email ))
118+ .willReturn (Optional .empty ());
119+
120+ // when & then
121+ assertThatThrownBy (() -> authService .verifyEmail (email , "123456" ))
122+ .isInstanceOf (NotFoundException .class );
123+ }
124+
125+ @ Test
126+ @ DisplayName ("이메일 인증 실패: 인증 시간이 만료된 경우 예외 발생" )
127+ void mail_verification_fail_expired () {
128+ // given
129+ String email = "mail@mail.com" ;
130+ EmailVerification verification = EmailVerification .builder ()
131+ .email (email )
132+ .expiredAt (LocalDateTime .now ().minusMinutes (1 ))
133+ .build ();
134+
135+ given (emailVerificationRepository .findFirstByEmailOrderByCreatedAtDesc (email ))
136+ .willReturn (Optional .of (verification ));
137+
138+ // when & then
139+ assertThatThrownBy (() -> authService .verifyEmail (email , "123445" ))
140+ .isInstanceOf (InvalidValueException .class );
141+ }
142+
143+ @ Test
144+ @ DisplayName ("이메일 인증 실패: 코드가 일치하지 않는 경우 예외 발생" )
145+ void mail_verification_fail_wrong_code () {
146+ // given
147+ String email = "mail@mail.com" ;
148+ String wrongCode = "132332" ;
149+
150+ EmailVerification verification = EmailVerification .builder ()
151+ .email (email )
152+ .expiredAt (LocalDateTime .now ().plusMinutes (5 ))
153+ .verificationCode ("123432" )
154+ .build ();
155+
156+ given (emailVerificationRepository .findFirstByEmailOrderByCreatedAtDesc (email ))
157+ .willReturn (Optional .of (verification ));
158+
159+ // when & then
160+ assertThatThrownBy (() -> authService .verifyEmail (email , wrongCode ))
161+ .isInstanceOf (InvalidValueException .class )
162+ .hasMessage ("인증 번호가 일치하지 않습니다." );
163+ }
164+ }
165+ }
0 commit comments