@@ -138,8 +138,8 @@ void findActiveUserIds_empty() {
138138 assertThat (activeIds ).isEmpty ();
139139 }
140140
141- @ Test @ DisplayName ("findActiveNicknameUsers - 활성 닉네임 사용자만 닉네임순으로 조회" )
142- void findActiveNicknameUsers () {
141+ @ Test @ DisplayName ("searchActiveUsers - 활성 닉네임 사용자만 닉네임순으로 조회" )
142+ void searchActiveUsers () {
143143 User charlie = user ("charlie@example.com" , "charlie" );
144144 charlie .setSignupStatus (SignupStatusType .COMPLETED );
145145 User bravo = user ("bravo@example.com" , "bravo" );
@@ -156,16 +156,16 @@ void findActiveNicknameUsers() {
156156 deleted .softDelete ();
157157 em .flush (); em .clear ();
158158
159- List <User > users = repo .findActiveNicknameUsers ( null , 0 , 20 );
159+ List <User > users = repo .searchActiveUsers ( null , null , 0 , 20 );
160160
161161 assertThat (users )
162162 .extracting (User ::getNickname )
163163 .containsExactly ("bravo" , "charlie" );
164- assertThat (repo .countActiveNicknameUsers ( null )).isEqualTo (2 );
164+ assertThat (repo .countSearchActiveUsers ( null , null )).isEqualTo (2 );
165165 }
166166
167- @ Test @ DisplayName ("findActiveNicknameUsers - 닉네임 검색과 페이징" )
168- void findActiveNicknameUsers_queryAndPagination () {
167+ @ Test @ DisplayName ("searchActiveUsers - 닉네임 검색과 페이징" )
168+ void searchActiveUsers_queryAndPagination () {
169169 User alpha = user ("alpha@example.com" , "alpha" );
170170 alpha .setSignupStatus (SignupStatusType .COMPLETED );
171171 User alpine = user ("alpine@example.com" , "alpine" );
@@ -174,20 +174,20 @@ void findActiveNicknameUsers_queryAndPagination() {
174174 bravo .setSignupStatus (SignupStatusType .COMPLETED );
175175 em .flush (); em .clear ();
176176
177- List <User > firstPage = repo .findActiveNicknameUsers ("alp" , 0 , 1 );
178- List <User > secondPage = repo .findActiveNicknameUsers ("alp" , 1 , 1 );
177+ List <User > firstPage = repo .searchActiveUsers ("alp" , null , 0 , 1 );
178+ List <User > secondPage = repo .searchActiveUsers ("alp" , null , 1 , 1 );
179179
180180 assertThat (firstPage )
181181 .extracting (User ::getNickname )
182182 .containsExactly ("alpha" );
183183 assertThat (secondPage )
184184 .extracting (User ::getNickname )
185185 .containsExactly ("alpine" );
186- assertThat (repo .countActiveNicknameUsers ("alp" )).isEqualTo (2 );
186+ assertThat (repo .countSearchActiveUsers ("alp" , null )).isEqualTo (2 );
187187 }
188188
189- @ Test @ DisplayName ("findActiveNicknameUsers - 닉네임 중간 문자열 검색" )
190- void findActiveNicknameUsers_containsQuery () {
189+ @ Test @ DisplayName ("searchActiveUsers - 닉네임 중간 문자열 검색" )
190+ void searchActiveUsers_containsQuery () {
191191 User duli = user ("duli@example.com" , "둘리" );
192192 duli .setSignupStatus (SignupStatusType .COMPLETED );
193193 User pigeon = user ("pigeon@example.com" , "비둘기" );
@@ -196,12 +196,100 @@ void findActiveNicknameUsers_containsQuery() {
196196 magpie .setSignupStatus (SignupStatusType .COMPLETED );
197197 em .flush (); em .clear ();
198198
199- List <User > users = repo .findActiveNicknameUsers ("둘" , 0 , 20 );
199+ List <User > users = repo .searchActiveUsers ("둘" , null , 0 , 20 );
200200
201201 assertThat (users )
202202 .extracting (User ::getNickname )
203203 .containsExactly ("둘리" , "비둘기" );
204- assertThat (repo .countActiveNicknameUsers ("둘" )).isEqualTo (2 );
204+ assertThat (repo .countSearchActiveUsers ("둘" , null )).isEqualTo (2 );
205+ }
206+
207+ @ Test @ DisplayName ("searchActiveUsers - ID 단독 검색" )
208+ void searchActiveUsers_byIdOnly () {
209+ User alpha = user ("id-alpha@example.com" , "id-alpha" );
210+ alpha .setSignupStatus (SignupStatusType .COMPLETED );
211+ User bravo = user ("id-bravo@example.com" , "id-bravo" );
212+ bravo .setSignupStatus (SignupStatusType .COMPLETED );
213+ em .flush (); em .clear ();
214+
215+ List <User > users = repo .searchActiveUsers (null , alpha .getId (), 0 , 20 );
216+
217+ assertThat (users )
218+ .extracting (User ::getId )
219+ .containsExactly (alpha .getId ());
220+ assertThat (repo .countSearchActiveUsers (null , alpha .getId ())).isEqualTo (1 );
221+ }
222+
223+ @ Test @ DisplayName ("searchActiveUsers - ID와 닉네임 OR 검색" )
224+ void searchActiveUsers_byIdOrNickname () {
225+ User alpha = user ("or-alpha@example.com" , "or-alpha" );
226+ alpha .setSignupStatus (SignupStatusType .COMPLETED );
227+ User bravo = user ("or-bravo@example.com" , "or-bravo" );
228+ bravo .setSignupStatus (SignupStatusType .COMPLETED );
229+ User charlie = user ("or-charlie@example.com" , "charlie-other" );
230+ charlie .setSignupStatus (SignupStatusType .COMPLETED );
231+ em .flush (); em .clear ();
232+
233+ List <User > users = repo .searchActiveUsers ("or-" , charlie .getId (), 0 , 20 );
234+
235+ assertThat (users )
236+ .extracting (User ::getId )
237+ .containsExactlyInAnyOrder (alpha .getId (), bravo .getId (), charlie .getId ());
238+ assertThat (repo .countSearchActiveUsers ("or-" , charlie .getId ())).isEqualTo (3 );
239+ }
240+
241+ @ Test @ DisplayName ("searchActiveUsers - 닉네임 null인 활성 사용자도 ID로 검색됨" )
242+ void searchActiveUsers_byIdAllowsNullNickname () {
243+ User profileRequired = user ("profile-required@example.com" , null );
244+ profileRequired .setSignupStatus (SignupStatusType .PROFILE_REQUIRED );
245+ em .flush (); em .clear ();
246+
247+ List <User > users = repo .searchActiveUsers (null , profileRequired .getId (), 0 , 20 );
248+
249+ assertThat (users ).extracting (User ::getId ).containsExactly (profileRequired .getId ());
250+ assertThat (repo .countSearchActiveUsers (null , profileRequired .getId ())).isEqualTo (1 );
251+ }
252+
253+ @ Test @ DisplayName ("searchActiveUsers - 닉네임 검색에는 null 닉네임 사용자 제외" )
254+ void searchActiveUsers_nicknameQueryExcludesNullNickname () {
255+ User withNickname = user ("with-nick@example.com" , "with-nick-target" );
256+ withNickname .setSignupStatus (SignupStatusType .COMPLETED );
257+ User noNickname = user ("no-nick@example.com" , null );
258+ noNickname .setSignupStatus (SignupStatusType .PROFILE_REQUIRED );
259+ em .flush (); em .clear ();
260+
261+ List <User > users = repo .searchActiveUsers ("nick-target" , null , 0 , 20 );
262+
263+ assertThat (users ).extracting (User ::getNickname ).containsExactly ("with-nick-target" );
264+ }
265+
266+ @ Test @ DisplayName ("searchActiveUsers - 쿼리 없을 때 닉네임 null 사용자 제외" )
267+ void searchActiveUsers_noQueryExcludesNullNickname () {
268+ User withNickname = user ("default-nick@example.com" , "default-nick" );
269+ withNickname .setSignupStatus (SignupStatusType .COMPLETED );
270+ User noNickname = user ("default-no-nick@example.com" , null );
271+ noNickname .setSignupStatus (SignupStatusType .PROFILE_REQUIRED );
272+ em .flush (); em .clear ();
273+
274+ List <User > users = repo .searchActiveUsers (null , null , 0 , 20 );
275+
276+ assertThat (users ).extracting (User ::getNickname ).containsExactly ("default-nick" );
277+ }
278+
279+ @ Test @ DisplayName ("searchActiveUsers - 탈퇴/삭제 사용자는 ID 검색에서도 제외" )
280+ void searchActiveUsers_byIdExcludesInactive () {
281+ User withdrawn = user ("inactive-withdrawn@example.com" , "withdrawn-user" );
282+ withdrawn .setSignupStatus (SignupStatusType .WITHDRAWN );
283+ User deleted = user ("inactive-deleted@example.com" , "deleted-user" );
284+ deleted .setSignupStatus (SignupStatusType .COMPLETED );
285+ em .flush ();
286+ deleted .softDelete ();
287+ em .flush (); em .clear ();
288+
289+ assertThat (repo .searchActiveUsers (null , withdrawn .getId (), 0 , 20 )).isEmpty ();
290+ assertThat (repo .countSearchActiveUsers (null , withdrawn .getId ())).isZero ();
291+ assertThat (repo .searchActiveUsers (null , deleted .getId (), 0 , 20 )).isEmpty ();
292+ assertThat (repo .countSearchActiveUsers (null , deleted .getId ())).isZero ();
205293 }
206294
207295 @ Test @ DisplayName ("save - 중복 닉네임은 제약조건 위반" )
0 commit comments