622 lines
25 KiB
Java

package roomescape.reservation.controller;
import static org.assertj.core.api.Assertions.*;
import static org.hamcrest.Matchers.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Map;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.jdbc.Sql.ExecutionPhase;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import io.restassured.http.Header;
import roomescape.member.infrastructure.persistence.Member;
import roomescape.member.infrastructure.persistence.MemberRepository;
import roomescape.member.infrastructure.persistence.Role;
import roomescape.payment.infrastructure.client.TossPaymentClient;
import roomescape.payment.infrastructure.persistence.CanceledPaymentEntity;
import roomescape.payment.infrastructure.persistence.CanceledPaymentRepository;
import roomescape.payment.infrastructure.persistence.PaymentEntity;
import roomescape.payment.infrastructure.persistence.PaymentRepository;
import roomescape.payment.web.PaymentApprove;
import roomescape.payment.web.PaymentCancel;
import roomescape.reservation.domain.Reservation;
import roomescape.reservation.domain.ReservationStatus;
import roomescape.reservation.domain.ReservationTime;
import roomescape.reservation.domain.repository.ReservationRepository;
import roomescape.reservation.domain.repository.ReservationTimeRepository;
import roomescape.reservation.dto.request.AdminReservationRequest;
import roomescape.reservation.dto.request.ReservationRequest;
import roomescape.reservation.dto.request.WaitingRequest;
import roomescape.theme.infrastructure.persistence.Theme;
import roomescape.theme.infrastructure.persistence.ThemeRepository;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Sql(scripts = "/truncate.sql", executionPhase = ExecutionPhase.BEFORE_TEST_METHOD)
public class ReservationControllerTest {
@Autowired
private ReservationRepository reservationRepository;
@Autowired
private ReservationTimeRepository reservationTimeRepository;
@Autowired
private ThemeRepository themeRepository;
@Autowired
private MemberRepository memberRepository;
@Autowired
private PaymentRepository paymentRepository;
@Autowired
private CanceledPaymentRepository canceledPaymentRepository;
@MockBean
private TossPaymentClient paymentClient;
@LocalServerPort
private int port;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
@DisplayName("처음으로 등록하는 예약의 id는 1이다.")
void firstPost() {
String accessTokenCookie = getAdminAccessTokenCookieByLogin("admin@admin.com", "12341234");
LocalTime time = LocalTime.of(17, 30);
LocalDate date = LocalDate.now().plusDays(1L);
reservationTimeRepository.save(new ReservationTime(time));
themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Map<String, String> reservationParams = Map.of(
"date", date.toString(),
"timeId", "1",
"themeId", "1",
"paymentKey", "pk",
"orderId", "oi",
"amount", "1000",
"paymentType", "DEFAULT"
);
when(paymentClient.confirmPayment(any(PaymentApprove.Request.class))).thenReturn(
new PaymentApprove.Response("pk", "oi", OffsetDateTime.of(date, time, ZoneOffset.ofHours(9)), 1000L));
RestAssured.given().log().all()
.contentType(ContentType.JSON)
.port(port)
.header("Cookie", accessTokenCookie)
.body(reservationParams)
.when().post("/reservations")
.then().log().all()
.statusCode(201)
.body("data.id", is(1))
.header("Location", "/reservations/1");
}
@Test
@DisplayName("대기중인 예약을 취소한다.")
void cancelWaiting() {
// given
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
String accessTokenCookie = getAccessTokenCookieByLogin("email@email.com", "password");
ReservationTime reservationTime = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member member1 = memberRepository.save(new Member(null, "name1", "email1r@email.com", "password", Role.MEMBER));
// when
reservationRepository.save(new Reservation(LocalDate.now().plusDays(1), reservationTime, theme, member1,
ReservationStatus.CONFIRMED));
Reservation waiting = reservationRepository.save(
new Reservation(LocalDate.now().plusDays(1), reservationTime, theme, member,
ReservationStatus.WAITING));
// then
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessTokenCookie)
.when().delete("/reservations/waiting/{id}", waiting.getId())
.then().log().all()
.statusCode(204);
}
@Test
@DisplayName("회원은 자신이 아닌 다른 회원의 예약을 취소할 수 없다.")
void cantCancelOtherMembersWaiting() {
// given
Member confirmedMember = memberRepository.save(
new Member(null, "name", "email@email.com", "password", Role.MEMBER));
String accessTokenCookie = getAccessTokenCookieByLogin("email@email.com", "password");
ReservationTime reservationTime = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member waitingMember = memberRepository.save(
new Member(null, "name1", "email1r@email.com", "password", Role.MEMBER));
// when
reservationRepository.save(new Reservation(LocalDate.now().plusDays(1), reservationTime, theme, confirmedMember,
ReservationStatus.CONFIRMED));
Reservation waiting = reservationRepository.save(
new Reservation(LocalDate.now().plusDays(1), reservationTime, theme, waitingMember,
ReservationStatus.WAITING));
// then
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessTokenCookie)
.when().delete("/reservations/waiting/{id}", waiting.getId())
.then().log().all()
.statusCode(404);
}
@Test
@DisplayName("관리자 권한이 있으면 전체 예약정보를 조회할 수 있다.")
void readEmptyReservations() {
// given
String accessTokenCookie = getAdminAccessTokenCookieByLogin("admin@admin.com", "12341234");
ReservationTime reservationTime = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
// when
reservationRepository.save(
new Reservation(LocalDate.now(), reservationTime, theme, member, ReservationStatus.CONFIRMED));
reservationRepository.save(new Reservation(LocalDate.now().plusDays(1), reservationTime, theme, member,
ReservationStatus.CONFIRMED));
reservationRepository.save(new Reservation(LocalDate.now().plusDays(2), reservationTime, theme, member,
ReservationStatus.CONFIRMED));
// then
RestAssured.given().log().all()
.port(port)
.header(new Header("Cookie", accessTokenCookie))
.when().get("/reservations")
.then().log().all()
.statusCode(200)
.body("data.reservations.size()", is(3));
}
@Test
@DisplayName("예약 취소는 관리자만 할 수 있다.")
void canRemoveMyReservation() {
// given
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
String accessTokenCookie = getAccessTokenCookieByLogin(member.getEmail(), member.getPassword());
ReservationTime reservationTime = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Reservation reservation = reservationRepository.save(
new Reservation(LocalDate.now(), reservationTime, theme, member, ReservationStatus.CONFIRMED));
// when & then
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessTokenCookie)
.when().delete("/reservations/" + reservation.getId())
.then().log().all()
.statusCode(302);
}
@Test
@DisplayName("관리자가 대기중인 예약을 거절한다.")
void denyWaiting() {
// given
String adminTokenCookie = getAdminAccessTokenCookieByLogin("admin@email.com", "password");
ReservationTime reservationTime = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member confirmedMember = memberRepository.save(
new Member(null, "name1", "email@email.com", "password", Role.MEMBER));
Member waitingMember = memberRepository.save(
new Member(null, "name1", "email1@email.com", "password", Role.MEMBER));
reservationRepository.save(
new Reservation(LocalDate.now(), reservationTime, theme, confirmedMember, ReservationStatus.CONFIRMED));
Reservation waiting = reservationRepository.save(
new Reservation(LocalDate.now(), reservationTime, theme, waitingMember, ReservationStatus.WAITING));
// when & then
RestAssured.given().log().all()
.port(port)
.header("Cookie", adminTokenCookie)
.when().post("/reservations/waiting/{id}/deny", waiting.getId())
.then().log().all()
.statusCode(204);
}
@Test
@DisplayName("본인의 예약이 아니더라도 관리자 권한이 있으면 예약 정보를 삭제할 수 있다.")
void readReservationsSizeAfterPostAndDelete() {
// given
Member member = memberRepository.save(new Member(null, "name", "admin@admin.com", "password", Role.ADMIN));
String accessTokenCookie = getAccessTokenCookieByLogin(member.getEmail(), member.getPassword());
ReservationTime reservationTime = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member anotherMember = memberRepository.save(
new Member(null, "name", "email@email.com", "password", Role.MEMBER));
Reservation reservation = reservationRepository.save(
new Reservation(LocalDate.now(), reservationTime, theme, anotherMember, ReservationStatus.CONFIRMED));
// when & then
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessTokenCookie)
.when().delete("/reservations/" + reservation.getId())
.then().log().all()
.statusCode(204);
}
@ParameterizedTest
@MethodSource("requestValidateSource")
@DisplayName("예약 생성 시, 요청 값에 공백 또는 null이 포함되어 있으면 400 에러를 발생한다.")
void validateBlankRequest(Map<String, String> invalidRequestBody) {
RestAssured.given().log().all()
.contentType(ContentType.JSON)
.port(port)
.body(invalidRequestBody)
.header("Cookie", getAdminAccessTokenCookieByLogin("a@a.a", "a"))
.when().post("/reservations")
.then().log().all()
.statusCode(400);
}
private static Stream<Map<String, String>> requestValidateSource() {
return Stream.of(
Map.of("timeId", "1",
"themeId", "1"),
Map.of("date", LocalDate.now().plusDays(1L).toString(),
"themeId", "1"),
Map.of("date", LocalDate.now().plusDays(1L).toString(),
"timeId", "1"),
Map.of("date", " ",
"timeId", "1",
"themeId", "1"),
Map.of("date", LocalDate.now().plusDays(1L).toString(),
"timeId", " ",
"themeId", "1"),
Map.of("date", LocalDate.now().plusDays(1L).toString(),
"timeId", "1",
"themeId", " ")
);
}
@Test
@DisplayName("예약 생성 시, 정수 요청 데이터에 문자가 입력되어오면 400 에러를 발생한다.")
void validateRequestDataFormat() {
Map<String, String> invalidTypeRequestBody = Map.of(
"date", LocalDate.now().plusDays(1L).toString(),
"timeId", "1",
"themeId", "한글"
);
RestAssured.given().log().all()
.contentType(ContentType.JSON)
.port(port)
.header("Cookie", getAdminAccessTokenCookieByLogin("a@a.a", "a"))
.body(invalidTypeRequestBody)
.when().post("/reservations")
.then().log().all()
.statusCode(400);
}
@ParameterizedTest
@DisplayName("모든 예약 / 대기 중인 예약 / 현재 로그인된 회원의 예약 및 대기를 조회한다.")
@CsvSource(value = {"/reservations, reservations, 2", "/reservations/waiting, reservations, 1",
"/reservations-mine, myReservationResponses, 3"}, delimiter = ',')
void getAllReservations(String requestURI, String responseFieldName, int expectedSize) {
// given
LocalDate date = LocalDate.now().plusDays(1);
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
ReservationTime time = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
ReservationTime time1 = reservationTimeRepository.save(new ReservationTime(LocalTime.of(18, 30)));
ReservationTime time2 = reservationTimeRepository.save(new ReservationTime(LocalTime.of(19, 30)));
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.ADMIN));
String accessToken = getAccessTokenCookieByLogin("email@email.com", "password");
// when : 예약은 2개, 예약 대기는 1개 조회되어야 한다.
reservationRepository.save(new Reservation(date, time, theme, member, ReservationStatus.CONFIRMED));
reservationRepository.save(
new Reservation(date, time1, theme, member, ReservationStatus.CONFIRMED_PAYMENT_REQUIRED));
reservationRepository.save(new Reservation(date, time2, theme, member, ReservationStatus.WAITING));
// then
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessToken)
.when().get(requestURI)
.then().log().all()
.statusCode(200)
.body("data." + responseFieldName + ".size()", is(expectedSize));
}
@Test
@DisplayName("예약을 삭제할 때, 승인되었으나 결제 대기중인 예약은 결제 취소 없이 바로 삭제한다.")
void removeNotPaidReservation() {
// given
LocalDate date = LocalDate.now().plusDays(1);
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
ReservationTime time = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
String accessToken = getAdminAccessTokenCookieByLogin("admin@email.com", "password");
// when
Reservation saved = reservationRepository.save(new Reservation(date, time, theme,
memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER)),
ReservationStatus.CONFIRMED_PAYMENT_REQUIRED));
// then
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessToken)
.when().delete("/reservations/{id}", saved.getId())
.then().log().all()
.statusCode(204);
}
@Test
@DisplayName("이미 결제가 된 예약은 삭제 후 결제 취소를 요청한다.")
void removePaidReservation() {
// given
String accessToken = getAdminAccessTokenCookieByLogin("admin@email.com", "password");
LocalDate date = LocalDate.now().plusDays(1);
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
ReservationTime time = reservationTimeRepository.save(new ReservationTime(LocalTime.of(17, 30)));
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
Reservation saved = reservationRepository.save(
new Reservation(date, time, theme, member, ReservationStatus.CONFIRMED));
PaymentEntity savedPaymentEntity = paymentRepository.save(
new PaymentEntity(null, "pk", "oi", 1000L, saved, OffsetDateTime.now().minusHours(1L)));
// when
when(paymentClient.cancelPayment(any(PaymentCancel.Request.class)))
.thenReturn(new PaymentCancel.Response("pk", "고객 요청", savedPaymentEntity.getTotalAmount(),
OffsetDateTime.now()));
// then
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessToken)
.when().delete("/reservations/{id}", saved.getId())
.then().log().all()
.statusCode(204);
}
@Test
@DisplayName("예약을 추가할 때, 결제 승인 이후에 예외가 발생하면 결제를 취소한 뒤 결제 취소 테이블에 취소 정보를 저장한다.")
void saveReservationWithCancelPayment() {
// given
LocalDateTime localDateTime = LocalDateTime.now().minusHours(1L).withNano(0);
LocalDate date = localDateTime.toLocalDate();
ReservationTime time = reservationTimeRepository.save(new ReservationTime(localDateTime.toLocalTime()));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
String accessToken = getAccessTokenCookieByLogin(member.getEmail(), member.getPassword());
// when : 이전 날짜의 예약을 추가하여 결제 승인 이후 DB 저장 과정에서 예외를 발생시킨다.
String paymentKey = "pk";
OffsetDateTime canceledAt = OffsetDateTime.now().plusHours(1L).withNano(0);
OffsetDateTime approvedAt = OffsetDateTime.of(localDateTime, ZoneOffset.ofHours(9));
when(paymentClient.confirmPayment(any(PaymentApprove.Request.class)))
.thenReturn(new PaymentApprove.Response(paymentKey, "oi", approvedAt, 1000L));
when(paymentClient.cancelPayment(any(PaymentCancel.Request.class)))
.thenReturn(new PaymentCancel.Response(paymentKey, "고객 요청", 1000L, canceledAt));
RestAssured.given().log().all()
.contentType(ContentType.JSON)
.port(port)
.header("Cookie", accessToken)
.body(new ReservationRequest(date, time.getId(), theme.getId(), "pk", "oi", 1000L, "DEFAULT"))
.when().post("/reservations")
.then().log().all()
.statusCode(400);
// then
CanceledPaymentEntity canceledPayment = canceledPaymentRepository.findByPaymentKey(paymentKey);
assertThat(canceledPayment).isNotNull();
assertThat(canceledPayment.getCanceledAt()).isEqualTo(canceledAt);
assertThat(canceledPayment.getCancelReason()).isEqualTo("고객 요청");
assertThat(canceledPayment.getCancelAmount()).isEqualTo(1000L);
assertThat(canceledPayment.getApprovedAt()).isEqualTo(approvedAt);
}
@DisplayName("테마만을 이용하여 예약을 조회한다.")
@ParameterizedTest(name = "테마 ID={0}로 조회 시 {1}개의 예약이 조회된다.")
@CsvSource(value = {"1/4", "2/3"}, delimiter = '/')
@Sql({"/truncate.sql", "/test_search_data.sql"})
void searchByTheme(String themeId, int expectedCount) {
RestAssured.given().log().all()
.port(port)
.param("themeId", themeId)
.param("memberId", "")
.param("dateFrom", "")
.param("dateTo", "")
.header("cookie", getAdminAccessTokenCookieByLogin("admin@email.com", "password"))
.when().get("/reservations/search")
.then().log().all()
.statusCode(HttpStatus.OK.value())
.body("data.reservations.size()", is(expectedCount));
}
@DisplayName("시작 날짜만을 이용하여 예약을 조회한다.")
@ParameterizedTest(name = "오늘 날짜보다 {0}일 전인 날짜를 시작 날짜로 조회 시 {1}개의 예약이 조회된다.")
@CsvSource(value = {"1/1", "7/7"}, delimiter = '/')
@Sql({"/truncate.sql", "/test_search_data.sql"})
void searchByFromDate(int minusDays, int expectedCount) {
RestAssured.given().log().all()
.port(port)
.param("themeId", "")
.param("memberId", "")
.param("dateFrom", LocalDate.now().minusDays(minusDays).toString())
.param("dateTo", "")
.header("cookie", getAdminAccessTokenCookieByLogin("admin@email.com", "password"))
.when().get("/reservations/search")
.then().log().all()
.statusCode(HttpStatus.OK.value())
.body("data.reservations.size()", is(expectedCount));
}
@DisplayName("종료 날짜만을 이용하여 예약을 조회한다..")
@ParameterizedTest(name = "오늘 날짜보다 {0}일 전인 날짜를 종료 날짜로 조회 시 {1}개의 예약이 조회된다.")
@CsvSource(value = {"1/7", "3/5", "7/1"}, delimiter = '/')
@Sql({"/truncate.sql", "/test_search_data.sql"})
void searchByToDate(int minusDays, int expectedCount) {
RestAssured.given().log().all()
.port(port)
.param("themeId", "")
.param("memberId", "")
.param("dateFrom", "")
.param("dateTo", LocalDate.now().minusDays(minusDays).toString())
.header("cookie", getAdminAccessTokenCookieByLogin("admin@email.com", "password"))
.when().get("/reservations/search")
.then().log().all()
.statusCode(HttpStatus.OK.value())
.body("data.reservations.size()", is(expectedCount));
}
@Test
@DisplayName("예약 대기를 추가한다.")
void addWaiting() {
// given
LocalDateTime localDateTime = LocalDateTime.now().plusDays(1L).withNano(0);
LocalDate date = localDateTime.toLocalDate();
ReservationTime time = reservationTimeRepository.save(new ReservationTime(localDateTime.toLocalTime()));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
Member member1 = memberRepository.save(new Member(null, "name1", "email1@email.com", "password", Role.MEMBER));
String accessToken = getAccessTokenCookieByLogin(member.getEmail(), member.getPassword());
reservationRepository.save(new Reservation(date, time, theme, member1, ReservationStatus.CONFIRMED));
// when & then
RestAssured.given().log().all()
.port(port)
.contentType(ContentType.JSON)
.header("Cookie", accessToken)
.body(new WaitingRequest(date, time.getId(), theme.getId()))
.when().post("/reservations/waiting")
.then().log().all()
.statusCode(201)
.body("data.status", is("WAITING"));
}
@Test
@DisplayName("대기중인 예약을 승인한다.")
void approveWaiting() {
// given
LocalDateTime localDateTime = LocalDateTime.now().plusHours(1L);
LocalDate date = localDateTime.toLocalDate();
ReservationTime time = reservationTimeRepository.save(new ReservationTime(localDateTime.toLocalTime()));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
String accessToken = getAdminAccessTokenCookieByLogin("admin@email.com", "password");
Reservation waiting = reservationRepository.save(
new Reservation(date, time, theme, member, ReservationStatus.WAITING));
// when
RestAssured.given().log().all()
.port(port)
.header("Cookie", accessToken)
.when().post("/reservations/waiting/{id}/approve", waiting.getId())
.then().log().all()
.statusCode(200);
// then
reservationRepository.findById(waiting.getId())
.ifPresent(r -> assertThat(r.getReservationStatus()).isEqualTo(
ReservationStatus.CONFIRMED_PAYMENT_REQUIRED));
}
private String getAccessTokenCookieByLogin(final String email, final String password) {
Map<String, String> loginParams = Map.of(
"email", email,
"password", password
);
String accessToken = RestAssured.given().log().all()
.contentType(ContentType.JSON)
.port(port)
.body(loginParams)
.when().post("/login")
.then().log().all().extract().cookie("accessToken");
return "accessToken=" + accessToken;
}
@Test
@DisplayName("관리자가 직접 예약을 추가한다.")
void addReservationByAdmin() {
// given
LocalDateTime localDateTime = LocalDateTime.now().plusDays(1L).withNano(0);
LocalDate date = localDateTime.toLocalDate();
ReservationTime time = reservationTimeRepository.save(new ReservationTime(localDateTime.toLocalTime()));
Theme theme = themeRepository.save(new Theme("테마명", "설명", "썸네일URL"));
Member member = memberRepository.save(new Member(null, "name", "email@email.com", "password", Role.MEMBER));
String adminAccessToken = getAdminAccessTokenCookieByLogin("admin@email.com", "password");
// when & then
RestAssured.given().log().all()
.port(port)
.contentType(ContentType.JSON)
.header("Cookie", adminAccessToken)
.body(new AdminReservationRequest(date, time.getId(), theme.getId(), member.getId()))
.when().post("/reservations/admin")
.then().log().all()
.statusCode(201);
}
private String getAdminAccessTokenCookieByLogin(final String email, final String password) {
memberRepository.save(new Member(null, "이름", email, password, Role.ADMIN));
Map<String, String> loginParams = Map.of(
"email", email,
"password", password
);
String accessToken = RestAssured.given().log().all()
.contentType(ContentType.JSON)
.port(port)
.body(loginParams)
.when().post("/login")
.then().log().all().extract().cookie("accessToken");
return "accessToken=" + accessToken;
}
}