Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 리뷰 등록시 모임 참여 유저 조회 API 수정 #229

Merged
merged 6 commits into from
Feb 16, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.request.CreateMeetingRequest;
import net.teumteum.meeting.domain.request.UpdateMeetingRequest;
import net.teumteum.meeting.domain.response.MeetingParticipantsResponse;
import net.teumteum.meeting.domain.response.MeetingParticipantResponse;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
Expand Down Expand Up @@ -43,14 +43,14 @@ public class MeetingController {
public MeetingResponse createMeeting(
@RequestPart @Valid CreateMeetingRequest meetingRequest,
@RequestPart List<MultipartFile> images) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.createMeeting(images, meetingRequest, userId);
}

@GetMapping("/{meetingId}")
@ResponseStatus(HttpStatus.OK)
public MeetingResponse getMeetingById(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.getMeetingById(meetingId, userId);
}

Expand All @@ -64,7 +64,7 @@ public PageDto<MeetingsResponse> getMeetingsByCondition(
@RequestParam(value = "participantUserId", required = false) Long participantUserId,
@RequestParam(value = "isBookmarked", required = false) Boolean isBookmarked,
@RequestParam(value = "searchWord", required = false) String searchWord) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.getMeetingsBySpecification(pageable, topic, meetingAreaStreet, participantUserId,
searchWord, isBookmarked, isOpen, userId);
}
Expand All @@ -74,55 +74,56 @@ public PageDto<MeetingsResponse> getMeetingsByCondition(
public MeetingResponse updateMeeting(@PathVariable Long meetingId,
@RequestPart @Valid UpdateMeetingRequest request,
@RequestPart List<MultipartFile> images) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.updateMeeting(meetingId, images, request, userId);
}

@DeleteMapping("/{meetingId}")
@ResponseStatus(HttpStatus.OK)
public void deleteMeeting(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.deleteMeeting(meetingId, userId);
}

@PostMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.CREATED)
public MeetingResponse addParticipant(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.addParticipant(meetingId, userId);
}

@DeleteMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.OK)
public void deleteParticipant(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.cancelParticipant(meetingId, userId);
}

@GetMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.OK)
public List<MeetingParticipantsResponse> getParticipants(@PathVariable("meetingId") Long meetingId) {
return meetingService.getParticipants(meetingId);
public List<MeetingParticipantResponse> getParticipants(@PathVariable("meetingId") Long meetingId) {
Long userId = getCurrentUserId();
return meetingService.getParticipants(meetingId, userId);
}

@PostMapping("/{meetingId}/reports")
@ResponseStatus(HttpStatus.CREATED)
public void reportMeeting(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.reportMeeting(meetingId, userId);
}

@PostMapping("/{meetingId}/bookmarks")
@ResponseStatus(HttpStatus.CREATED)
public void addBookmark(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.addBookmark(meetingId, userId);
}

@DeleteMapping("/{meetingId}/bookmarks")
@ResponseStatus(HttpStatus.OK)
public void deleteBookmark(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.cancelBookmark(meetingId, userId);
}

Expand All @@ -132,4 +133,8 @@ public ErrorResponse handleIllegalArgumentException(IllegalArgumentException ill
Sentry.captureException(illegalArgumentException);
return ErrorResponse.of(illegalArgumentException);
}

private Long getCurrentUserId() {
return securityService.getCurrentUserId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import net.teumteum.user.domain.User;

public record MeetingParticipantsResponse(
public record MeetingParticipantResponse(
Long id,
Long characterId,
String name,
String job
) {

public static MeetingParticipantsResponse of(
public static MeetingParticipantResponse of(
User user
) {
return new MeetingParticipantsResponse(
return new MeetingParticipantResponse(
user.getId(),
user.getCharacterId(),
user.getName(),
Expand Down
18 changes: 14 additions & 4 deletions src/main/java/net/teumteum/meeting/service/MeetingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.request.CreateMeetingRequest;
import net.teumteum.meeting.domain.request.UpdateMeetingRequest;
import net.teumteum.meeting.domain.response.MeetingParticipantsResponse;
import net.teumteum.meeting.domain.response.MeetingParticipantResponse;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
Expand Down Expand Up @@ -94,7 +94,8 @@ public void deleteMeeting(Long meetingId, Long userId) {
}

@Transactional(readOnly = true)
public PageDto<MeetingsResponse> getMeetingsBySpecification(Pageable pageable, Topic topic, String meetingAreaStreet,
public PageDto<MeetingsResponse> getMeetingsBySpecification(Pageable pageable, Topic topic,
String meetingAreaStreet,
Long participantUserId, String searchWord, Boolean isBookmarked, Boolean isOpen, Long userId) {

Specification<Meeting> spec = MeetingSpecification.withIsOpen(isOpen);
Expand Down Expand Up @@ -153,13 +154,16 @@ public void cancelParticipant(Long meetingId, Long userId) {
}

@Transactional(readOnly = true)
public List<MeetingParticipantsResponse> getParticipants(Long meetingId) {
public List<MeetingParticipantResponse> getParticipants(Long meetingId, Long userId) {
var existMeeting = getMeeting(meetingId);

checkMeetingContainUser(existMeeting, userId);

return existMeeting.getParticipantUserIds().stream()
.filter(id -> !id.equals(userId))
.map(userConnector::findUserById)
.flatMap(Optional::stream)
.map(MeetingParticipantsResponse::of)
.map(MeetingParticipantResponse::of)
.toList();
}

Expand Down Expand Up @@ -207,4 +211,10 @@ public void reportMeeting(Long meetingId, Long userId) {
throw new IllegalArgumentException("모임 개설자는 모임을 신고할 수 없습니다.");
}
}

private void checkMeetingContainUser(Meeting meeting, Long userId) {
if (!meeting.getParticipantUserIds().contains(userId)) {
throw new IllegalArgumentException("모임에 참여하지 않은 회원입니다.");
}
}
}
118 changes: 73 additions & 45 deletions src/test/java/net/teumteum/integration/MeetingIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package net.teumteum.integration;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
import net.teumteum.core.error.ErrorResponse;
import net.teumteum.meeting.domain.Meeting;
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.Condition;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
Expand Down Expand Up @@ -42,10 +44,10 @@ void Return_meeting_info_if_exist_meeting_id_received() {
// when
var result = api.getMeetingById(VALID_TOKEN, meeting.getId());
// then
Assertions.assertThat(
result.expectStatus().isOk()
.expectBody(MeetingResponse.class)
.returnResult().getResponseBody())
assertThat(
result.expectStatus().isOk()
.expectBody(MeetingResponse.class)
.returnResult().getResponseBody())
.usingRecursiveComparison()
.isEqualTo(expected);
}
Expand Down Expand Up @@ -75,10 +77,10 @@ void Return_is_bookmarked_true_if_user_bookmarked_meeting() {
// when
var result = api.getMeetingById(VALID_TOKEN, meeting.getId());
// then
Assertions.assertThat(
result.expectStatus().isOk()
.expectBody(MeetingResponse.class)
.returnResult().getResponseBody())
assertThat(
result.expectStatus().isOk()
.expectBody(MeetingResponse.class)
.returnResult().getResponseBody())
.extracting(MeetingResponse::isBookmarked)
.isEqualTo(true);
}
Expand Down Expand Up @@ -158,11 +160,11 @@ void Return_meeting_list_if_topic_and_page_nation_received() {
// when
var result = api.getMeetingsByTopic(VALID_TOKEN, FIRST_PAGE_NATION, true, Topic.스터디);
// then
Assertions.assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
.usingRecursiveComparison()
.isEqualTo(expected);
}
Expand Down Expand Up @@ -192,11 +194,11 @@ void Return_meeting_list_if_search_word_and_page_nation_received() {
// when
var result = api.getMeetingsByTopic(VALID_TOKEN, FIRST_PAGE_NATION, true, Topic.스터디);
// then
Assertions.assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
.usingRecursiveComparison()
.isEqualTo(expected);
}
Expand All @@ -222,11 +224,11 @@ void Return_meeting_list_if_participant_user_id_and_page_nation_received() {
// when
var result = api.getMeetingsByTopic(VALID_TOKEN, FIRST_PAGE_NATION, true, Topic.스터디);
// then
Assertions.assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
.usingRecursiveComparison()
.isEqualTo(expected);
}
Expand All @@ -252,11 +254,11 @@ void Return_has_next_true_if_more_data_exists_than_requested_size_and_page() {
// when
var result = api.getMeetingsByTopic(VALID_TOKEN, FIRST_PAGE_NATION, true, Topic.스터디);
// then
Assertions.assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
assertThat(
result.expectStatus().isOk()
.expectBody(new ParameterizedTypeReference<PageDto<MeetingsResponse>>() {
})
.returnResult().getResponseBody())
.usingRecursiveComparison()
.isEqualTo(expected);
}
Expand All @@ -277,11 +279,11 @@ void Join_meeting_if_exist_meeting_id_received() {
// when
var result = api.joinMeeting(VALID_TOKEN, existMeeting.getId());
// then
Assertions.assertThat(
result.expectStatus().isCreated()
.expectBody(MeetingResponse.class)
.returnResult()
.getResponseBody())
assertThat(
result.expectStatus().isCreated()
.expectBody(MeetingResponse.class)
.returnResult()
.getResponseBody())
.extracting(MeetingResponse::participantIds)
.has(new Condition<>(ids -> ids.contains(me.getId()), "참여자 목록에 나를 포함한다.")
);
Expand Down Expand Up @@ -380,11 +382,11 @@ void Return_400_bad_request_if_not_joined_meeting_id_received() {
// when
var result = api.cancelMeeting(VALID_TOKEN, meeting.getId());
// then
Assertions.assertThat(result.expectStatus().isBadRequest()
.expectBody(ErrorResponse.class)
.returnResult()
.getResponseBody()
)
assertThat(result.expectStatus().isBadRequest()
.expectBody(ErrorResponse.class)
.returnResult()
.getResponseBody()
)
.extracting(ErrorResponse::getMessage)
.isEqualTo("참여하지 않은 모임입니다.");
}
Expand All @@ -400,11 +402,11 @@ void Return_400_bad_request_if_closed_meeting_id_received() {
// when
var result = api.cancelMeeting(VALID_TOKEN, meeting.getId());
// then
Assertions.assertThat(result.expectStatus().isBadRequest()
.expectBody(ErrorResponse.class)
.returnResult()
.getResponseBody()
)
assertThat(result.expectStatus().isBadRequest()
.expectBody(ErrorResponse.class)
.returnResult()
.getResponseBody()
)
.extracting(ErrorResponse::getMessage)
.isEqualTo("종료된 모임에서 참여를 취소할 수 없습니다.");
}
Expand Down Expand Up @@ -488,11 +490,37 @@ class Get_meeting_participants_api {
@DisplayName("참여한 meeting id 가 주어지면, 참여한 참가자들의 정보가 주어진다.")
void Get_participants_if_exist_meeting_id_received() {
// given
var meeting = repository.saveAndGetOpenMeeting();
var me = repository.saveAndGetUser();
var meeting = repository.saveAndGetClosedMetingWithParticipantUserIds(List.of(me.getId(), 2L));

securityContextSetting.set(me.getId());

// when
var result = api.getMeetingParticipants(VALID_TOKEN, meeting.getId());

// then
result.expectStatus().isOk();
}

@Test
@DisplayName("API 호출한 회원이 모임에 참여하지 않았다면, 400 bad request 을 응답한다.")
void Return_400_bad_request_if_meeting_not_contain_user() {
// given
var me = repository.saveAndGetUser();
var meeting = repository.saveAndGetClosedMetingWithParticipantUserIds(List.of(100L, 101L));

securityContextSetting.set(me.getId());

// when
var result = api.getMeetingParticipants(VALID_TOKEN, meeting.getId());

// then
assertThat(result.expectStatus().isBadRequest()
.expectBody(ErrorResponse.class)
.returnResult()
.getResponseBody())
.extracting(ErrorResponse::getMessage)
.isEqualTo("모임에 참여하지 않은 회원입니다.");
}
}
}
Loading
Loading