@@ -398,7 +398,8 @@ void kickMember_Success() {
398398 RoomMember targetMember = RoomMember .createVisitor (testRoom , targetUser );
399399
400400 given (roomMemberRepository .findByRoomIdAndUserId (1L , 1L )).willReturn (Optional .of (hostMember ));
401- given (roomMemberRepository .findByRoomIdAndUserId (1L , 2L )).willReturn (Optional .of (targetMember ));
401+ given (roomParticipantService .getParticipants (1L )).willReturn (java .util .Set .of (2L )); // 온라인 사용자 목록
402+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 2L )).willReturn (Optional .empty ()); // VISITOR는 DB에 없음
402403 given (roomRepository .findById (1L )).willReturn (Optional .of (testRoom ));
403404
404405 // when
@@ -408,6 +409,94 @@ void kickMember_Success() {
408409 verify (roomParticipantService , times (1 )).exitRoom (2L , 1L ); // Redis 퇴장 확인
409410 }
410411
412+ @ Test
413+ @ DisplayName ("멤버 추방 - VISITOR 추방 성공" )
414+ void kickMember_VisitorSuccess () {
415+ // given
416+ RoomMember hostMember = RoomMember .createHost (testRoom , testUser );
417+
418+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 1L )).willReturn (Optional .of (hostMember ));
419+ given (roomParticipantService .getParticipants (1L )).willReturn (java .util .Set .of (2L )); // VISITOR가 온라인 상태
420+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 2L )).willReturn (Optional .empty ()); // DB에 없음
421+ given (roomRepository .findById (1L )).willReturn (Optional .of (testRoom ));
422+
423+ // when
424+ roomService .kickMember (1L , 2L , 1L );
425+
426+ // then
427+ verify (roomParticipantService , times (1 )).exitRoom (2L , 1L );
428+ }
429+
430+ @ Test
431+ @ DisplayName ("멤버 추방 - MEMBER 추방 성공" )
432+ void kickMember_MemberSuccess () {
433+ // given
434+ RoomMember hostMember = RoomMember .createHost (testRoom , testUser );
435+
436+ User targetUser = User .builder ()
437+ .id (2L )
438+ .username ("target" )
439+ 440+ .role (Role .USER )
441+ .build ();
442+ UserProfile targetProfile = new UserProfile ();
443+ targetProfile .setNickname ("대상유저" );
444+ targetUser .setUserProfile (targetProfile );
445+
446+ RoomMember targetMember = RoomMember .create (testRoom , targetUser , RoomRole .MEMBER );
447+
448+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 1L )).willReturn (Optional .of (hostMember ));
449+ given (roomParticipantService .getParticipants (1L )).willReturn (java .util .Set .of (2L )); // MEMBER가 온라인 상태
450+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 2L )).willReturn (Optional .of (targetMember )); // DB에 있음
451+ given (roomRepository .findById (1L )).willReturn (Optional .of (testRoom ));
452+
453+ // when
454+ roomService .kickMember (1L , 2L , 1L );
455+
456+ // then
457+ verify (roomParticipantService , times (1 )).exitRoom (2L , 1L );
458+ }
459+
460+ @ Test
461+ @ DisplayName ("멤버 추방 - 방장 추방 실패" )
462+ void kickMember_CannotKickHost () {
463+ // given
464+ RoomMember hostMember = RoomMember .createHost (testRoom , testUser );
465+
466+ User anotherHost = User .builder ()
467+ .id (2L )
468+ .username ("host2" )
469+ 470+ .role (Role .USER )
471+ .build ();
472+
473+ RoomMember targetHostMember = RoomMember .createHost (testRoom , anotherHost );
474+
475+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 1L )).willReturn (Optional .of (hostMember ));
476+ given (roomParticipantService .getParticipants (1L )).willReturn (java .util .Set .of (2L ));
477+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 2L )).willReturn (Optional .of (targetHostMember ));
478+
479+ // when & then
480+ assertThatThrownBy (() -> roomService .kickMember (1L , 2L , 1L ))
481+ .isInstanceOf (CustomException .class )
482+ .hasFieldOrPropertyWithValue ("errorCode" , ErrorCode .CANNOT_KICK_HOST );
483+ }
484+
485+ @ Test
486+ @ DisplayName ("멤버 추방 - 오프라인 사용자 추방 실패" )
487+ void kickMember_OfflineUser () {
488+ // given
489+ RoomMember hostMember = RoomMember .createHost (testRoom , testUser );
490+
491+ given (roomMemberRepository .findByRoomIdAndUserId (1L , 1L )).willReturn (Optional .of (hostMember ));
492+ given (roomParticipantService .getParticipants (1L )).willReturn (java .util .Set .of ()); // 온라인 사용자 없음
493+
494+ // when & then
495+ assertThatThrownBy (() -> roomService .kickMember (1L , 2L , 1L ))
496+ .isInstanceOf (CustomException .class )
497+ .hasFieldOrPropertyWithValue ("errorCode" , ErrorCode .NOT_ROOM_MEMBER );
498+ }
499+
411500 @ Test
412501 @ DisplayName ("멤버 추방 - 권한 없음" )
413502 void kickMember_NoPermission () {
0 commit comments