diff --git a/src/main/java/com/nexters/goalpanzi/application/mission/MissionService.java b/src/main/java/com/nexters/goalpanzi/application/mission/MissionService.java index 7077f5d8..70cefc9e 100644 --- a/src/main/java/com/nexters/goalpanzi/application/mission/MissionService.java +++ b/src/main/java/com/nexters/goalpanzi/application/mission/MissionService.java @@ -9,6 +9,7 @@ import com.nexters.goalpanzi.domain.mission.repository.MissionRepository; import com.nexters.goalpanzi.exception.ErrorCode; import com.nexters.goalpanzi.exception.ForbiddenException; +import com.nexters.goalpanzi.exception.NotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; @@ -63,6 +64,13 @@ public MissionDetailResponse getMission(final Long missionId) { return MissionDetailResponse.from(mission); } + public MissionDetailResponse getMissionByInvitationCode(final InvitationCode invitationCode) { + Mission mission = missionRepository.findByInvitationCode(invitationCode) + .orElseThrow(() -> new NotFoundException(ErrorCode.NOT_FOUND_MISSION, invitationCode)); + + return MissionDetailResponse.from(mission); + } + @Transactional public void deleteMission(final Long memberId, final Long missionId) { Mission mission = missionRepository.getMission(missionId); diff --git a/src/main/java/com/nexters/goalpanzi/domain/mission/InvitationCode.java b/src/main/java/com/nexters/goalpanzi/domain/mission/InvitationCode.java index 603b2101..2feaf303 100644 --- a/src/main/java/com/nexters/goalpanzi/domain/mission/InvitationCode.java +++ b/src/main/java/com/nexters/goalpanzi/domain/mission/InvitationCode.java @@ -7,6 +7,7 @@ import lombok.NoArgsConstructor; import org.springframework.util.StringUtils; +import java.util.Objects; import java.util.Random; import static com.nexters.goalpanzi.exception.ErrorCode.INVALID_INVITATION_CODE; @@ -46,4 +47,24 @@ private void validate() { throw new IllegalArgumentException(INVALID_INVITATION_CODE.getMessage()); } } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + InvitationCode code1 = (InvitationCode) o; + return Objects.equals(code, code1.code); + } + + @Override + public int hashCode() { + return Objects.hashCode(code); + } + + @Override + public String toString() { + return "InvitationCode{" + + "code='" + code + '\'' + + '}'; + } } diff --git a/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionController.java b/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionController.java index 475c87bf..6fa6c6f9 100644 --- a/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionController.java +++ b/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionController.java @@ -3,6 +3,7 @@ import com.nexters.goalpanzi.application.mission.MissionService; import com.nexters.goalpanzi.application.mission.dto.response.MissionDetailResponse; import com.nexters.goalpanzi.common.argumentresolver.LoginMemberId; +import com.nexters.goalpanzi.domain.mission.InvitationCode; import com.nexters.goalpanzi.presentation.mission.dto.CreateMissionRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RequiredArgsConstructor @@ -51,4 +53,13 @@ public ResponseEntity deleteMission( return ResponseEntity.noContent().build(); } + + @Override + @GetMapping + public ResponseEntity getMissionByInvitationCode( + @RequestParam final String invitationCode) { + MissionDetailResponse response = missionService.getMissionByInvitationCode(new InvitationCode(invitationCode)); + + return ResponseEntity.ok(response); + } } diff --git a/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionControllerDocs.java b/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionControllerDocs.java index dc324f14..ad00747c 100644 --- a/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionControllerDocs.java +++ b/src/main/java/com/nexters/goalpanzi/presentation/mission/MissionControllerDocs.java @@ -11,6 +11,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; @Tag(name = "미션") public interface MissionControllerDocs { @@ -31,4 +32,10 @@ ResponseEntity deleteMission( @PathVariable("/{missionId}") Long missionId, @Parameter(in = ParameterIn.HEADER, hidden = true) @LoginMemberId final Long memberId ); + + @Operation(summary = "초대코드로 미션 조회", description = "초대코드로 미션정보를 조회합니다.") + ResponseEntity getMissionByInvitationCode( + @RequestParam String invitationCode + ); + } diff --git a/src/test/java/com/nexters/goalpanzi/acceptance/MissionAcceptanceTest.java b/src/test/java/com/nexters/goalpanzi/acceptance/MissionAcceptanceTest.java index 1b0c4993..7c659d35 100644 --- a/src/test/java/com/nexters/goalpanzi/acceptance/MissionAcceptanceTest.java +++ b/src/test/java/com/nexters/goalpanzi/acceptance/MissionAcceptanceTest.java @@ -67,6 +67,31 @@ public class MissionAcceptanceTest extends AcceptanceTest { () -> assertThat(actual.hostMemberId()).isEqualTo(1L)); } + @Test + void 초대코드로_미션을_조회한다() { + LoginResponse login = 구글_로그인(new GoogleLoginCommand(EMAIL_HOST)).as(LoginResponse.class); + + CreateMissionRequest request = new CreateMissionRequest(DESCRIPTION, LocalDateTime.now(), + LocalDateTime.now().plusDays(5), TimeOfDay.EVERYDAY, + List.of(DayOfWeek.MONDAY, DayOfWeek.FRIDAY), 20); + + MissionDetailResponse mission = 미션_생성(request, login.accessToken()).as(MissionDetailResponse.class); + + MissionDetailResponse actual = RestAssured.given().log().all() + .contentType(MediaType.APPLICATION_JSON_VALUE) + .header(HttpHeaders.AUTHORIZATION, BEARER + login.accessToken()) + .when().get("/api/missions?invitationCode=" + mission.invitationCode()) + .then().log().all() + .statusCode(HttpStatus.OK.value()) + .extract().as(MissionDetailResponse.class); + + assertAll( + () -> assertThat(actual.description()).isEqualTo(DESCRIPTION), + () -> assertThat(actual.boardCount()).isEqualTo(20), + () -> assertThat(actual.missionDays()).containsExactly(DayOfWeek.MONDAY, DayOfWeek.FRIDAY), + () -> assertThat(actual.hostMemberId()).isEqualTo(1L)); + } + @Test void 미션을_생성한_사용자는_자동으로_경쟁에_참가된다() { LoginResponse login = 구글_로그인(new GoogleLoginCommand(EMAIL_HOST)).as(LoginResponse.class);