Skip to content

Commit fcf5718

Browse files
authored
Refactor: 프론트엔드 요청 사항에 따른 스터디룸 조회 수정 (#257) (#258)
* refactor: 스더티룸 권한에 대한 로직 개선 * fix: ci에서 통과 못한 테스트코드 수정 * fix:rest api와 웹소켓 중간 경로 통합 * fix:rest api와 웹소켓 중간 경로 통합 * fix: 에러 확인을 위한 통합테스트 추가, Room.create()메서드 수정 * refactor, feat : 조회 분할 * refactor: redis 로직 최적화 및 중복 검증 로직 제거 * fix: 에러 번호 수정 * feat: 스터디룸 방 비밀번호 변경 및 삭제 기능 구현 * fix:app-dev 제거 * feat: 웹소켓 기반 소극적 하트비트 * feat: 스터디룸 썸네일 기능 추가 및 webrtc 설정 변경에서 주석처리 * fix:소극적 하트비트 사용 주석처리 * Feat: 스터디 룸 내에 고양이 아바타 시스템과 프로필 이미지 url 연동 * fix: 기존 작성되어있던 test 코드 수정 * test: 아바타 테스트 코드 완료 * refactor: 프론트엔드 요청 사항에 따른 스터디룸 조회 마스킹 제거
1 parent eb34299 commit fcf5718

File tree

7 files changed

+53
-44
lines changed

7 files changed

+53
-44
lines changed

src/main/java/com/back/domain/studyroom/controller/RoomController.java

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,10 @@ public ResponseEntity<RsData<Void>> leaveRoom(
130130
@GetMapping("/all")
131131
@Operation(
132132
summary = "모든 방 목록 조회",
133-
description = "공개 방과 비공개 방 전체를 조회합니다. 비공개 방은 제목과 방장 정보가 마스킹됩니다. 열린 방(WAITING, ACTIVE)이 우선 표시되고, 닫힌 방(PAUSED, TERMINATED)은 뒤로 밀립니다."
133+
description = "공개 방과 비공개 방 전체를 조회합니다. 열린 방(WAITING, ACTIVE)이 우선 표시되고, 닫힌 방(PAUSED, TERMINATED)은 뒤로 밀립니다. 비로그인 사용자도 조회 가능합니다."
134134
)
135135
@ApiResponses({
136-
@ApiResponse(responseCode = "200", description = "조회 성공"),
137-
@ApiResponse(responseCode = "401", description = "인증 실패")
136+
@ApiResponse(responseCode = "200", description = "조회 성공")
138137
})
139138
public ResponseEntity<RsData<Map<String, Object>>> getAllRooms(
140139
@Parameter(description = "페이지 번호 (0부터 시작)") @RequestParam(defaultValue = "0") int page,
@@ -143,8 +142,8 @@ public ResponseEntity<RsData<Map<String, Object>>> getAllRooms(
143142
Pageable pageable = PageRequest.of(page, size);
144143
Page<Room> rooms = roomService.getAllRooms(pageable);
145144

146-
// 비공개 방 마스킹 포함한 변환
147-
List<RoomResponse> roomList = roomService.toRoomResponseListWithMasking(rooms.getContent());
145+
// 모든 정보 공개
146+
List<RoomResponse> roomList = roomService.toRoomResponseList(rooms.getContent());
148147

149148
Map<String, Object> response = new HashMap<>();
150149
response.put("rooms", roomList);
@@ -162,11 +161,10 @@ public ResponseEntity<RsData<Map<String, Object>>> getAllRooms(
162161
@GetMapping("/public")
163162
@Operation(
164163
summary = "공개 방 목록 조회",
165-
description = "공개 방 전체를 조회합니다. includeInactive=true로 설정하면 닫힌 방도 포함됩니다 (기본값: true). 열린 방이 우선 표시됩니다."
164+
description = "공개 방 전체를 조회합니다. includeInactive=true로 설정하면 닫힌 방도 포함됩니다 (기본값: true). 열린 방이 우선 표시됩니다. 비로그인 사용자도 조회 가능합니다."
166165
)
167166
@ApiResponses({
168-
@ApiResponse(responseCode = "200", description = "조회 성공"),
169-
@ApiResponse(responseCode = "401", description = "인증 실패")
167+
@ApiResponse(responseCode = "200", description = "조회 성공")
170168
})
171169
public ResponseEntity<RsData<Map<String, Object>>> getPublicRooms(
172170
@Parameter(description = "페이지 번호 (0부터 시작)") @RequestParam(defaultValue = "0") int page,
@@ -261,11 +259,10 @@ public ResponseEntity<RsData<Map<String, Object>>> getMyHostingRooms(
261259
@GetMapping
262260
@Operation(
263261
summary = "입장 가능한 공개 방 목록 조회 (기존)",
264-
description = "입장 가능한 공개 스터디 룸 목록을 페이징하여 조회합니다. 최신 생성 순으로 정렬됩니다."
262+
description = "입장 가능한 공개 스터디 룸 목록을 페이징하여 조회합니다. 최신 생성 순으로 정렬됩니다. 비로그인 사용자도 조회 가능합니다."
265263
)
266264
@ApiResponses({
267-
@ApiResponse(responseCode = "200", description = "조회 성공"),
268-
@ApiResponse(responseCode = "401", description = "인증 실패")
265+
@ApiResponse(responseCode = "200", description = "조회 성공")
269266
})
270267
public ResponseEntity<RsData<Map<String, Object>>> getRooms(
271268
@Parameter(description = "페이지 번호 (0부터 시작)") @RequestParam(defaultValue = "0") int page,
@@ -292,18 +289,17 @@ public ResponseEntity<RsData<Map<String, Object>>> getRooms(
292289
@GetMapping("/{roomId}")
293290
@Operation(
294291
summary = "방 상세 정보 조회",
295-
description = "특정 방의 상세 정보와 현재 온라인 멤버 목록을 조회합니다. 비공개 방은 멤버만 조회 가능합니다."
292+
description = "특정 방의 상세 정보와 현재 온라인 멤버 목록을 조회합니다. 비로그인 사용자도 조회 가능합니다."
296293
)
297294
@ApiResponses({
298295
@ApiResponse(responseCode = "200", description = "조회 성공"),
299-
@ApiResponse(responseCode = "403", description = "비공개 방에 대한 접근 권한 없음"),
300-
@ApiResponse(responseCode = "404", description = "존재하지 않는 방"),
301-
@ApiResponse(responseCode = "401", description = "인증 실패")
296+
@ApiResponse(responseCode = "404", description = "존재하지 않는 방")
302297
})
303298
public ResponseEntity<RsData<RoomDetailResponse>> getRoomDetail(
304299
@Parameter(description = "방 ID", required = true) @PathVariable Long roomId) {
305300

306-
Long currentUserId = currentUser.getUserId();
301+
// 비로그인 사용자는 userId = null로 처리
302+
Long currentUserId = currentUser.getUserIdOrNull();
307303

308304
Room room = roomService.getRoomDetail(roomId, currentUserId);
309305
List<RoomMember> members = roomService.getRoomMembers(roomId, currentUserId);
@@ -522,11 +518,10 @@ public ResponseEntity<RsData<List<RoomMemberResponse>>> getRoomMembers(
522518
@GetMapping("/popular")
523519
@Operation(
524520
summary = "인기 방 목록 조회",
525-
description = "참가자 수가 많은 인기 방 목록을 페이징하여 조회합니다. 참가자 수 내림차순에서 최신순으로 정렬됩니다."
521+
description = "참가자 수가 많은 인기 방 목록을 페이징하여 조회합니다. 공개방과 비공개방 모두 포함됩니다. 참가자 수 내림차순에서 최신순으로 정렬됩니다. 비로그인 사용자도 조회 가능합니다."
526522
)
527523
@ApiResponses({
528-
@ApiResponse(responseCode = "200", description = "조회 성공"),
529-
@ApiResponse(responseCode = "401", description = "인증 실패")
524+
@ApiResponse(responseCode = "200", description = "조회 성공")
530525
})
531526
public ResponseEntity<RsData<Map<String, Object>>> getPopularRooms(
532527
@Parameter(description = "페이지 번호 (0부터 시작)") @RequestParam(defaultValue = "0") int page,

src/main/java/com/back/domain/studyroom/repository/RoomRepositoryImpl.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,13 @@ public Page<Room> findRoomsWithFilters(String title, RoomStatus status, Boolean
157157
}
158158

159159
/**
160-
* 인기 방 조회 (참가자 수 기준)
160+
* 인기 방 조회 (참가자 수 기준) - 공개+비공개 포함
161161
*
162162
* 참고: 참가자 수는 Redis에서 조회하므로 DB에서는 정렬 불가
163163
* 서비스 레이어에서 Redis 데이터로 정렬 필요
164164
*
165165
* 조회 조건:
166-
* - 공개 방만 (isPrivate = false)
166+
* - 공개 방 + 비공개 방 모두 포함
167167
* - 활성화된 방만 (isActive = true)
168168
* @param pageable 페이징 정보
169169
* @return 페이징된 방 목록 (최신순 정렬)
@@ -174,7 +174,6 @@ public Page<Room> findPopularRooms(Pageable pageable) {
174174
.selectFrom(room)
175175
.leftJoin(room.createdBy, user).fetchJoin() // N+1 방지
176176
.where(
177-
room.isPrivate.eq(false),
178177
room.isActive.eq(true)
179178
)
180179
.orderBy(room.createdAt.desc()) // 최신순 (서비스에서 Redis 기반으로 재정렬)
@@ -187,7 +186,6 @@ public Page<Room> findPopularRooms(Pageable pageable) {
187186
.select(room.count())
188187
.from(room)
189188
.where(
190-
room.isPrivate.eq(false),
191189
room.isActive.eq(true)
192190
)
193191
.fetchOne();

src/main/java/com/back/domain/studyroom/service/RoomService.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,8 @@ public Room getRoomDetail(Long roomId, Long userId) {
257257
Room room = roomRepository.findById(roomId)
258258
.orElseThrow(() -> new CustomException(ErrorCode.ROOM_NOT_FOUND));
259259

260-
if (room.isPrivate()) {
261-
boolean isMember = roomMemberRepository.existsByRoomIdAndUserId(roomId, userId);
262-
if (!isMember) {
263-
throw new CustomException(ErrorCode.ROOM_FORBIDDEN);
264-
}
265-
}
260+
// ⭐ 비공개 방 접근 제한 제거 - 모든 사용자가 조회 가능
261+
// (프론트엔드에서 입장 시 로그인 체크)
266262

267263
return room;
268264
}
@@ -534,12 +530,7 @@ public List<RoomMember> getRoomMembers(Long roomId, Long userId) {
534530
Room room = roomRepository.findById(roomId)
535531
.orElseThrow(() -> new CustomException(ErrorCode.ROOM_NOT_FOUND));
536532

537-
if (room.isPrivate()) {
538-
boolean isMember = roomMemberRepository.existsByRoomIdAndUserId(roomId, userId);
539-
if (!isMember) {
540-
throw new CustomException(ErrorCode.ROOM_FORBIDDEN);
541-
}
542-
}
533+
// ⭐ 비공개 방 접근 제한 제거 - 모든 사용자가 조회 가능
543534

544535
// 1. Redis에서 온라인 사용자 ID 조회
545536
Set<Long> onlineUserIds = roomParticipantService.getParticipants(roomId);

src/main/java/com/back/global/security/SecurityConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
4242
.requestMatchers("api/ws/**", "/ws/**").permitAll()
4343
.requestMatchers(HttpMethod.GET, "/api/posts/**").permitAll()
4444
.requestMatchers("/api/rooms/*/messages/**").permitAll() //스터디 룸 내에 잡혀있어 있는 채팅 관련 전체 허용
45+
// 방 목록 조회 API 비로그인 허용
46+
.requestMatchers(HttpMethod.GET, "/api/rooms").permitAll()
47+
.requestMatchers(HttpMethod.GET, "/api/rooms/all").permitAll()
48+
.requestMatchers(HttpMethod.GET, "/api/rooms/public").permitAll()
49+
.requestMatchers(HttpMethod.GET, "/api/rooms/popular").permitAll()
50+
.requestMatchers(HttpMethod.GET, "/api/rooms/*").permitAll() // 방 상세 조회
4551
//.requestMatchers("/api/rooms/RoomChatApiControllerTest").permitAll() // 테스트용 임시 허용
4652
.requestMatchers("/","/swagger-ui/**", "/v3/api-docs/**").permitAll() // Swagger 허용
4753
.requestMatchers("/h2-console/**").permitAll() // H2 Console 허용

src/main/java/com/back/global/security/user/CurrentUser.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,21 @@ public boolean isAuthenticated() {
3030
}
3131

3232
public Long getUserId() { return getDetails().getUserId(); }
33+
34+
/**
35+
* 현재 사용자 ID 조회 (비로그인 시 null 반환)
36+
* 비로그인 접근이 허용되는 API에서 사용
37+
*/
38+
public Long getUserIdOrNull() {
39+
try {
40+
return getDetails().getUserId();
41+
} catch (CustomException e) {
42+
if (e.getErrorCode() == ErrorCode.UNAUTHORIZED) {
43+
return null;
44+
}
45+
throw e;
46+
}
47+
}
3348

3449
public String getUsername() { return getDetails().getUsername(); }
3550

src/test/java/com/back/domain/studyroom/controller/RoomControllerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ void getRooms() {
208208
@DisplayName("방 상세 정보 조회 API 테스트 - JWT 인증")
209209
void getRoomDetail() {
210210
// given
211-
given(currentUser.getUserId()).willReturn(1L);
211+
given(currentUser.getUserIdOrNull()).willReturn(1L);
212212

213213
given(roomService.getRoomDetail(eq(1L), eq(1L))).willReturn(testRoom);
214214
given(roomService.getRoomMembers(eq(1L), eq(1L))).willReturn(Arrays.asList(testMember));
@@ -229,7 +229,7 @@ void getRoomDetail() {
229229
assertThat(response.getBody().isSuccess()).isTrue();
230230
assertThat(response.getBody().getData().getTitle()).isEqualTo("테스트 방");
231231

232-
verify(currentUser, times(1)).getUserId();
232+
verify(currentUser, times(1)).getUserIdOrNull();
233233
verify(roomService, times(1)).getRoomDetail(eq(1L), eq(1L));
234234
verify(roomService, times(1)).getRoomMembers(eq(1L), eq(1L));
235235
verify(roomService, times(1)).toRoomDetailResponse(any(Room.class), anyList());

src/test/java/com/back/domain/studyroom/service/RoomServiceTest.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ void getRoomDetail_Success() {
258258
}
259259

260260
@Test
261-
@DisplayName("방 상세 정보 조회 - 비공개 방 권한 없음")
262-
void getRoomDetail_PrivateRoomForbidden() {
261+
@DisplayName("방 상세 정보 조회 - 비공개 방도 조회 가능")
262+
void getRoomDetail_PrivateRoomAllowed() {
263263
// given
264264
Room privateRoom = Room.create(
265265
"비공개 방",
@@ -273,12 +273,16 @@ void getRoomDetail_PrivateRoomForbidden() {
273273
null // thumbnailUrl
274274
);
275275
given(roomRepository.findById(1L)).willReturn(Optional.of(privateRoom));
276-
given(roomMemberRepository.existsByRoomIdAndUserId(1L, 2L)).willReturn(false);
276+
// ⭐ 비공개 방 접근 제한 제거되었으므로 권한 체크 안 함
277277

278-
// when & then
279-
assertThatThrownBy(() -> roomService.getRoomDetail(1L, 2L))
280-
.isInstanceOf(CustomException.class)
281-
.hasFieldOrPropertyWithValue("errorCode", ErrorCode.ROOM_FORBIDDEN);
278+
// when
279+
Room result = roomService.getRoomDetail(1L, 2L);
280+
281+
// then
282+
assertThat(result).isNotNull();
283+
assertThat(result.getTitle()).isEqualTo("비공개 방");
284+
assertThat(result.isPrivate()).isTrue();
285+
verify(roomMemberRepository, never()).existsByRoomIdAndUserId(any(), any());
282286
}
283287

284288
@Test

0 commit comments

Comments
 (0)