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

[BE] feat: 유저가 참여중인 방 리스트 조회 기능 구현(#29) #60

Merged
merged 4 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Hidden()
public @interface LoginUser {
public @interface LoginMember {
}
2 changes: 0 additions & 2 deletions backend/src/main/java/corea/auth/domain/AuthInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
public class AuthInfo {

private final Long id;

private final String name;

private final String email;

public static AuthInfo from(Member member){
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package corea.auth.resolver;

import corea.auth.RequestHandler;
import corea.auth.annotation.LoginUser;
import corea.auth.annotation.LoginMember;
import corea.auth.domain.AuthInfo;
import corea.exception.CoreaException;
import corea.exception.ExceptionType;
Expand All @@ -25,7 +25,7 @@ public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolve

@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(LoginUser.class);
return parameter.hasParameterAnnotation(LoginMember.class);
}

@Override
Expand Down
6 changes: 4 additions & 2 deletions backend/src/main/java/corea/exception/CoreaException.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package corea.exception;

import lombok.Getter;
import org.springframework.http.HttpStatus;

@Getter
public class CoreaException extends RuntimeException {

private final ExceptionType exceptionType;
Expand All @@ -17,7 +19,7 @@ public CoreaException(ExceptionType exceptionType, String message) {
}

public CoreaException(ExceptionType exceptionType, Throwable cause) {
super(cause);
super(exceptionType.getMessage(), cause);
this.exceptionType = exceptionType;
}

Expand All @@ -27,6 +29,6 @@ public HttpStatus getHttpStatus() {

@Override
public String getMessage() {
return exceptionType.getMessage();
return super.getMessage();
}
}
8 changes: 7 additions & 1 deletion backend/src/main/java/corea/exception/ExceptionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@

public enum ExceptionType {
Copy link
Contributor

@youngsu5582 youngsu5582 Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 보면서 생각난 부분인데
어차피 동적으로 생성해서 정적인 값을 사용하지 않는다면

    MEMBER_NOT_FOUND_ERROR(HttpStatus.NOT_FOUND,"해당 %d에 해당하는 멤버가 없습니다."),

    public String getFormattedMessage(Object... args){
        return String.format(message,args);
    }

이렇게 하는건 어떤지?

  • 정적 메시지와 동적 메시지가 서로 차이가 나면 관리 포인트 증가
  • 메시지 변수가 존재할 필요가 없음

Copy link
Contributor Author

@jcoding-play jcoding-play Jul 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은것 같은데??
애초에 나는 원래 에러 메시지 자세하게 적는거 좋아해서 대부분 동적으로 생성하긴 할거라 좋을듯?? 👍

근데 이것도 한가지 걸리는 점은, 매번 예외 메세지를 작성할 때 필요한 args를 확인해야 한다는 단점도 생각나긴 하는 것 같네용
이거는 다같이 얘기해보면 좋을 것 같습니다~


SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR,"서버에 문제가 발생했습니다."),
MEMBER_NOT_FOUND(HttpStatus.BAD_REQUEST, "해당 멤버를 찾을 수 없습니다."),
ROOM_NOT_FOUND(HttpStatus.BAD_REQUEST, "방을 찾을 수 없습니다."),
NOT_FOUND_ERROR(HttpStatus.NOT_FOUND,"해당하는 값이 없습니다."),
AUTHORIZATION_ERROR(HttpStatus.UNAUTHORIZED,"인증에 실패했습니다."),
ALREADY_APPLY(HttpStatus.BAD_REQUEST,"해당 방에 이미 참여했습니다"),
SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR,"서버에 문제가 발생했습니다.");
;

private final HttpStatus httpStatus;
private final String message;

ExceptionType(final HttpStatus httpStatus, final String message) {
this.httpStatus = httpStatus;
this.message = message;
}

public HttpStatus getHttpStatus() {
return httpStatus;
}

public String getMessage() {
return message;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package corea.matching.controller;

import corea.auth.annotation.LoginUser;
import corea.auth.annotation.LoginMember;
import corea.auth.domain.AuthInfo;
import corea.matching.dto.ParticipationRequest;
import corea.matching.service.ParticipationService;
Expand All @@ -19,7 +19,7 @@ public class ParticipateController implements ParticipationControllerSpecificati
private final ParticipationService participationService;

@PostMapping("/{id}")
public ResponseEntity<Void> participate(@PathVariable long id, @LoginUser AuthInfo authInfo) {
public ResponseEntity<Void> participate(@PathVariable long id, @LoginMember AuthInfo authInfo) {
participationService.participate(new ParticipationRequest(id, authInfo.getId()));
return ResponseEntity.ok()
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ public interface ParticipationRepository extends JpaRepository<Participation, Lo

List<Participation> findAllByRoomId(long roomId);

List<Participation> findAllByMemberId(long memberId);

boolean existsByRoomIdAndMemberId(long roomId, long memberId);
}
14 changes: 11 additions & 3 deletions backend/src/main/java/corea/room/controller/RoomController.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package corea.room.controller;

import corea.auth.annotation.LoginMember;
import corea.auth.domain.AuthInfo;
import corea.room.dto.RoomResponse;
import corea.room.dto.RoomResponses;
import corea.room.service.RoomService;
Expand All @@ -18,14 +20,20 @@ public class RoomController {
private final RoomService roomService;

@GetMapping("/{id}")
public ResponseEntity<RoomResponse> room(@PathVariable final long id) {
final RoomResponse response = roomService.findOne(id);
public ResponseEntity<RoomResponse> room(@PathVariable long id) {
RoomResponse response = roomService.findOne(id);
return ResponseEntity.ok(response);
}

@GetMapping
public ResponseEntity<RoomResponses> rooms() {
final RoomResponses response = roomService.findAll();
RoomResponses response = roomService.findAll();
return ResponseEntity.ok(response);
}

@GetMapping("/participated")
public ResponseEntity<RoomResponses> participatedRooms(@LoginMember AuthInfo authInfo) {
RoomResponses response = roomService.findParticipatedRooms(authInfo.getId());
return ResponseEntity.ok(response);
}
}
2 changes: 1 addition & 1 deletion backend/src/main/java/corea/room/domain/Room.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class Room {
private LocalDateTime reviewDeadline;

public Room(String title, String content, int matchingSize, String repositoryLink, String thumbnailLink, String keyword, int currentParticipantsSize, int limitedParticipantsSize, Member manager, LocalDateTime recruitmentDeadline, LocalDateTime reviewDeadline) {
this(null,title,content,matchingSize,repositoryLink,thumbnailLink,keyword,currentParticipantsSize,limitedParticipantsSize,manager,recruitmentDeadline,reviewDeadline);
this(null, title, content, matchingSize, repositoryLink, thumbnailLink, keyword, currentParticipantsSize, limitedParticipantsSize, manager, recruitmentDeadline, reviewDeadline);
}
}

15 changes: 9 additions & 6 deletions backend/src/main/java/corea/room/dto/RoomCreateRequest.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
package corea.room.dto;

import corea.member.domain.Member;
import corea.room.domain.Room;

import java.time.LocalDateTime;

public record RoomCreateRequest(
String title,
String content,
long memberId,
Member manager,
String repositoryLink,
String thumbnailLink,
int matchingSize,
String keyword,
long currentParticipantsSize,
long limitedParticipantsSize,
LocalDateTime submissionDeadline,
int currentParticipantsSize,
int limitedParticipantsSize,
LocalDateTime recruitmentDeadline,
LocalDateTime reviewDeadline
) {

//TODO 해당 객체를 사용한다면 반영
public Room toEntity() {
return null;
return new Room(title, content, matchingSize,
repositoryLink, thumbnailLink, keyword,
currentParticipantsSize, limitedParticipantsSize, manager,
recruitmentDeadline, reviewDeadline);
}
}
17 changes: 13 additions & 4 deletions backend/src/main/java/corea/room/dto/RoomResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,20 @@ public record RoomResponse(
LocalDateTime reviewDeadline
) {

public static RoomResponse of(final Room room) {
public static RoomResponse from(Room room) {
return new RoomResponse(
room.getId(), room.getTitle(), room.getContent(), room.getManager().getEmail(),
room.getRepositoryLink(), room.getThumbnailLink(), room.getMatchingSize(), List.of(room.getKeyword()),
room.getCurrentParticipantsSize(), room.getLimitedParticipantsSize(), room.getRecruitmentDeadline(), room.getReviewDeadline()
room.getId(),
room.getTitle(),
room.getContent(),
room.getManager().getName(),
room.getRepositoryLink(),
room.getThumbnailLink(),
room.getMatchingSize(),
List.of(room.getKeyword()),
room.getCurrentParticipantsSize(),
room.getLimitedParticipantsSize(),
room.getRecruitmentDeadline(),
room.getReviewDeadline()
);
}
}
11 changes: 11 additions & 0 deletions backend/src/main/java/corea/room/dto/RoomResponses.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package corea.room.dto;

import corea.room.domain.Room;

import java.util.List;

import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toList;

public record RoomResponses(List<RoomResponse> rooms) {

public static RoomResponses from(List<Room> rooms) {
return rooms.stream()
.map(RoomResponse::from)
.collect(collectingAndThen(toList(), RoomResponses::new));
}
}
40 changes: 23 additions & 17 deletions backend/src/main/java/corea/room/service/RoomService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package corea.room.service;

import corea.exception.CoreaException;
import corea.exception.ExceptionType;
import corea.matching.domain.Participation;
import corea.matching.repository.ParticipationRepository;
import corea.member.domain.Member;
import corea.room.domain.Room;
import corea.room.dto.RoomCreateRequest;
import corea.room.dto.RoomResponse;
import corea.room.dto.RoomResponses;
import corea.member.repository.MemberRepository;
import corea.room.repository.RoomRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -21,32 +25,34 @@
public class RoomService {

private final RoomRepository roomRepository;
private final MemberRepository memberRepository;
private final ParticipationRepository participationRepository;

public RoomResponse create(final RoomCreateRequest request) {
final Room room = roomRepository.save(request.toEntity());
return toRoomResponse(room);
public RoomResponse create(RoomCreateRequest request) {
Room room = roomRepository.save(request.toEntity());
return RoomResponse.from(room);
}

public RoomResponse findOne(final long id) {
final Room room = getRoom(id);
return toRoomResponse(room);
public RoomResponse findOne(long id) {
Room room = getRoom(id);
return RoomResponse.from(room);
}

public RoomResponses findAll() {
final List<Room> rooms = roomRepository.findAll();
public RoomResponses findParticipatedRooms(long memberId) {
List<Participation> participations = participationRepository.findAllByMemberId(memberId);

return rooms.stream()
.map(this::toRoomResponse)
.collect(collectingAndThen(toList(), RoomResponses::new));
return participations.stream()
.map(Participation::getRoomId)
.map(this::getRoom)
.collect(collectingAndThen(toList(), RoomResponses::from));
}

private RoomResponse toRoomResponse(final Room room) {
return RoomResponse.of(room);
public RoomResponses findAll() {
final List<Room> rooms = roomRepository.findAll();
return RoomResponses.from(rooms);
}

private Room getRoom(final long roomId) {
private Room getRoom(long roomId) {
return roomRepository.findById(roomId)
.orElseThrow(() -> new IllegalArgumentException(String.format("해당 Id의 방이 없습니다. 입력된 Id=%d", roomId)));
.orElseThrow(() -> new CoreaException(ExceptionType.ROOM_NOT_FOUND, String.format("해당 Id의 방이 없습니다. 입력된 Id=%d", roomId)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package corea.room.acceptance;

import corea.matching.dto.ParticipationRequest;
import corea.matching.service.ParticipationService;
import corea.member.domain.Member;
import corea.member.repository.MemberRepository;
import corea.room.dto.RoomResponse;
import corea.room.dto.RoomResponses;
import corea.room.fixture.MemberFixture;
import corea.room.fixture.RoomFixture;
import corea.room.service.RoomService;
import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;

import java.util.List;

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

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class RoomAcceptanceTest {

@LocalServerPort
int port;

@Autowired
RoomService roomService;

@Autowired
MemberRepository memberRepository;

@Autowired
ParticipationService participationService;

@BeforeEach
void setUp() {
RestAssured.port = port;
}

@Test
@DisplayName("현재 로그인한 멤버가 참여 중인 방을 보여준다.")
void participatedRooms() {
Member pororo = memberRepository.save(MemberFixture.MEMBER_PORORO());
Member ash = memberRepository.save(MemberFixture.MEMBER_ASH());
RoomResponse roomResponse = roomService.create(RoomFixture.ROOM_CREATE_REQUEST(ash));
participationService.participate(new ParticipationRequest(roomResponse.id(), pororo.getId()));

RoomResponses response = RestAssured.given().log().all()
.header("Authorization", "[email protected]")
.when().get("/rooms/participated")
.then().log().all()
.statusCode(200)
.extract().as(RoomResponses.class);

List<RoomResponse> rooms = response.rooms();
assertThat(rooms).hasSize(1);
assertThat(rooms.get(0).author()).isEqualTo("박민아");
}
Comment on lines +44 to +62
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 방을 생성하고, 방을 입장하는 API를 구현하지 않았기 때문에, 일단은 repository와 service를 가져와서 구현했습니다. 추후 RestAssured로 수정하겠습니다.

}
14 changes: 14 additions & 0 deletions backend/src/test/java/corea/room/fixture/MemberFixture.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package corea.room.fixture;

import corea.member.domain.Member;

public class MemberFixture {

public static Member MEMBER_PORORO() {
return new Member("jcoding-play", null, "조경찬", "[email protected]", true, 5f);
}

public static Member MEMBER_ASH() {
return new Member("ashsty", null, "박민아", null, false, 1.5f);
}
}
Loading