[FEAT] 예약 서버 인증 및 공통 응답 정의 (#279)#280
Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughreservation 모듈에 authorization-shared 의존성을 추가하고, ResultCode/ResultResponse 기반 표준 응답·에러 모델, Passport 기반 인증·인가 인터셉터(및 설정), 글로벌 예외 처리기와 관련 테스트/테스트 헬퍼를 추가했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant DispatcherServlet
participant Interceptor as AbstractAuthInterceptor
participant PassportHandler
participant Controller
participant GlobalExceptionHandler
Client->>DispatcherServlet: HTTP 요청 (X-Passport 헤더)
DispatcherServlet->>Interceptor: preHandle(request, response, handler)
rect rgba(200, 150, 255, 0.5)
Note over Interceptor: 핸들러에 대상 애노테이션 존재 여부 검사
Interceptor->>Interceptor: 애노테이션 확인
end
rect rgba(150, 200, 255, 0.5)
Note over Interceptor: Passport 검증 흐름
Interceptor->>PassportHandler: parse(X-Passport)
alt 파싱 실패 (Invalid/Expired)
PassportHandler-->>Interceptor: Exception
Interceptor->>GlobalExceptionHandler: PresentationException(요류코드) 발생
else 파싱 성공
PassportHandler-->>Interceptor: Passport
Interceptor->>Interceptor: 권한 비교(allowedAuthorities)
alt 권한 부족
Interceptor->>GlobalExceptionHandler: PresentationException(FORBIDDEN) 발생
else 권한 허용
Interceptor-->>DispatcherServlet: true (요청 계속)
end
end
end
rect rgba(200, 255, 200, 0.5)
Controller->>Controller: 비즈니스 처리
Controller-->>Client: ResponseEntity<ResultResponse>
end
rect rgba(255, 150, 150, 0.5)
Note over GlobalExceptionHandler: 예외 수신 및 ResultResponse 변환
GlobalExceptionHandler-->>Client: ResponseEntity<ResultResponse> (상태, 코드, 메시지)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Test Results (reservation)131 tests 131 ✅ 2s ⏱️ Results for commit 90fbac1. ♻️ This comment has been updated with latest results. |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR wires the reservation service into the shared authorization/Passport mechanism and introduces a unified ResultCode-based response and error-handling layer for the reservation API.
Changes:
- Integrates the
authorization-sharedmodule and configures aPassportHandlerbean plus HTTP interceptors for role-based access control using Passport headers. - Introduces a unified
ResultCodeabstraction with reservation-specific success and error code enums, plus aResultResponsewrapper and global exception handler. - Adds comprehensive unit tests for interceptors, result/exception handling, error/success codes, and Passport test utilities.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 12 comments.
Show a summary per file
| File | Description |
|---|---|
| reservation/build.gradle | Adds dependency on the shared authorization module so reservation can use Passport and auth-related types. |
| reservation/src/test/resources/application.yml | Provides a test-only passport.secret-key property so the PassportHandler bean can be instantiated in tests. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/ResultCode.java | Defines a common interface for HTTP status, business code, and message; used by success/error enums and exceptions. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainErrorCode.java | Adds domain-layer error codes (e.g., ED000 for domain constraint violations) implementing ResultCode. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainException.java | Introduces a domain-layer base exception that carries a ResultCode and standardizes messages. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationErrorCode.java | Adds presentation-layer error codes for HTTP/API and auth failures (EA0xx / EA1xx) implementing ResultCode. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationException.java | Adds a presentation-layer base exception carrying a ResultCode for API-facing errors. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/success/PresentationSuccessCode.java | Defines common success codes (SA0xx) for CRUD operations on the presentation layer. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/response/ResultResponse.java | Introduces a generic response wrapper and static factories to build ResponseEntity from ResultCode and optional data. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/GlobalExceptionHandler.java | Adds a @RestControllerAdvice that maps framework, domain, and presentation exceptions to ResultResponse using PresentationErrorCode. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/config/PassportConfig.java | Configures a BinaryPassportHandler bean, injecting the Passport secret key from configuration. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/config/WebMvcConfig.java | Registers all auth-related interceptors (admin, any user, specific roles) with Spring MVC. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AbstractAuthInterceptor.java | Implements the shared preHandle logic: detect target annotations, parse Passport header, check allowed authorities, and map Passport exceptions to PresentationErrorCode. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AdminInterceptor.java | Specializes AbstractAuthInterceptor for @Admin, allowing only ADMIN authority. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AnyUserInterceptor.java | Specializes AbstractAuthInterceptor for @AnyUser, allowing all authorities but still requiring a valid Passport header. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginUserInterceptor.java | Specializes AbstractAuthInterceptor for @LoginUser, allowing MODEL, PHOTOGRAPHER, ADMIN but not ANONYMOUS. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginPhotographerInterceptor.java | Specializes AbstractAuthInterceptor for @LoginPhotographer, allowing PHOTOGRAPHER and ADMIN only. |
| reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginModelInterceptor.java | Specializes AbstractAuthInterceptor for @LoginModel, allowing MODEL and ADMIN only. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AdminInterceptorTest.java | Verifies @Admin interception: pass with ADMIN, UNAUTHORIZED for missing header, FORBIDDEN for non-admin, INVALID_PASSPORT mapping. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AnyUserInterceptorTest.java | Tests @AnyUser interception: all authorities including ANONYMOUS are allowed, but missing headers yield UNAUTHORIZED. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginUserInterceptorTest.java | Tests @LoginUser interception: MODEL/PHOTOGRAPHER/ADMIN allowed, ANONYMOUS -> FORBIDDEN, missing header -> UNAUTHORIZED, methods without annotation bypassed. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginPhotographerInterceptorTest.java | Tests @LoginPhotographer interception: PHOTOGRAPHER/ADMIN allowed, MODEL -> FORBIDDEN, missing header -> UNAUTHORIZED, no-annotation bypass. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginModelInterceptorTest.java | Tests @LoginModel interception: MODEL/ADMIN allowed, PHOTOGRAPHER -> FORBIDDEN, missing header -> UNAUTHORIZED, no-annotation bypass. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/success/PresentationSuccessCodeTest.java | Ensures all PresentationSuccessCode values have codes starting with S, non-null HttpStatus, and non-blank messages. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/response/ResultResponseTest.java | Verifies ResultResponse.of builds correct HTTP status, code, message, and data with and without payload. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationExceptionTest.java | Tests all PresentationException constructors and messages, including specific authentication/authorization codes. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationErrorCodeTest.java | Asserts all presentation error codes follow EA-prefix conventions and are grouped by API vs auth categories. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/GlobalExceptionHandlerTest.java | Covers most exception handlers in GlobalExceptionHandler (framework, presentation, domain, generic) and their mapped codes/statuses. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainExceptionTest.java | Tests all DomainException constructors and message behavior with DomainErrorCode. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainErrorCodeTest.java | Verifies all DomainErrorCode values start with ED, have an HttpStatus, and non-blank messages. |
| reservation/src/test/java/net/catsnap/CatsnapReservation/shared/fixture/PassportTestHelper.java | Adds a @TestComponent utility to attach signed or invalid Passport headers to MockMvc requests for different authorities. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
reservation/src/main/java/net/catsnap/CatsnapReservation/shared/ResultCode.java
Show resolved
Hide resolved
.../catsnap/CatsnapReservation/shared/presentation/web/interceptor/AbstractAuthInterceptor.java
Show resolved
Hide resolved
...src/main/java/net/catsnap/CatsnapReservation/shared/presentation/GlobalExceptionHandler.java
Show resolved
Hide resolved
...vation/src/main/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainErrorCode.java
Show resolved
Hide resolved
...vation/src/main/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainErrorCode.java
Show resolved
Hide resolved
...ain/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationErrorCode.java
Show resolved
Hide resolved
...ain/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationErrorCode.java
Show resolved
Hide resolved
...java/net/catsnap/CatsnapReservation/shared/presentation/success/PresentationSuccessCode.java
Show resolved
Hide resolved
...java/net/catsnap/CatsnapReservation/shared/presentation/success/PresentationSuccessCode.java
Show resolved
Hide resolved
...java/net/catsnap/CatsnapReservation/shared/presentation/success/PresentationSuccessCode.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Actionable comments posted: 21
🤖 Fix all issues with AI agents
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainErrorCode.java`:
- Around line 9-26: Add specific domain error enum members to DomainErrorCode to
replace the single generic DOMAIN_CONSTRAINT_VIOLATION for reservation
scenarios: define DUPLICATE_RESERVATION, UNAVAILABLE_TIME_SLOT, and
ALREADY_CANCELLED_RESERVATION in the DomainErrorCode enum (use appropriate
HttpStatus values such as CONFLICT or BAD_REQUEST), assign unique codes like
"ED001"/"ED002"/"ED003" and clear messages (e.g. "예약이 중복되었습니다.", "해당 시간대에는 예약할 수
없습니다.", "이미 취소된 예약입니다."). Update any code paths that throw
DOMAIN_CONSTRAINT_VIOLATION in reservation-related logic to throw the new
specific enum values (refer to DomainErrorCode and the enum constant names) so
clients can handle errors more granularly.
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/domain/error/DomainException.java`:
- Around line 14-49: DomainException and PresentationException duplicate the
same ResultCode field and three constructors; extract a common superclass (e.g.,
ResultCodeException or AbstractDomainException) that holds private final
ResultCode resultCode and the three constructors (ResultCode), (ResultCode,
Throwable), and (ResultCode, String) delegating to super(...) and then have
DomainException and PresentationException extend that new base class (removing
their duplicate fields/constructors); update any code that constructs or catches
DomainException/PresentationException to reference the new superclass where
appropriate.
- Around line 45-48: The DomainException constructor currently appends
additionalMessage directly which yields "... - null" when null; update the
constructor (DomainException(ResultCode, String)) to only append the separator
and additionalMessage when additionalMessage is non-null/non-empty (or replace
null with an empty string), mirroring PresentationException behavior so the
resulting super(message) never contains "null".
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationException.java`:
- Around line 46-49: The PresentationException constructor currently
concatenates resultCode.getMessage() with " - " + additionalMessage which yields
" - null" when additionalMessage is null; update the constructor
(PresentationException(ResultCode, String)) to defensively handle null/blank
additionalMessage by checking it and only appending the separator and
additionalMessage when non-null/non-empty (or use a default like empty string),
then assign this.resultCode as before to avoid NPEs and unintended "null" text
in the exception message.
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/GlobalExceptionHandler.java`:
- Around line 79-91: The handler
GlobalExceptionHandler.handleMethodArgumentNotValidException computes a detailed
errorMessage but returns
ResultResponse.of(PresentationErrorCode.INVALID_REQUEST_BODY) without including
it; change the return to include the message (and field name if available) via
ResultResponse's API so the client sees the failure reason — e.g. extract
fieldName = fieldError != null ? fieldError.getField() : null and pass
errorMessage (and fieldName) into ResultResponse (for example
ResultResponse.of(PresentationErrorCode.INVALID_REQUEST_BODY, errorMessage) or
ResultResponse.of(..., fieldName, errorMessage) depending on the existing
ResultResponse factory/builder).
- Around line 29-37: The NoHandlerFoundException handler in
GlobalExceptionHandler (method handleNoHandlerFoundException) will never be
invoked unless Spring is configured to throw this exception; add the MVC/web
resource properties to the application configuration so Spring raises
NoHandlerFoundException and disables default resource mappings: set
spring.mvc.throw-exception-if-no-handler-found: true and
spring.web.resources.add-mappings: false in your application configuration file
(e.g., application.yml) so the existing handler can be reached.
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/response/ResultResponse.java`:
- Around line 32-49: The of(ResultCode resultCode) overload currently delegates
to of(resultCode, null) which builds a body even for NO_CONTENT, but Spring
strips bodies for 204 so clients won't receive code/message; update handling in
ResultResponse.of (the generic static factory) to explicitly detect
PresentationSuccessCode.NO_CONTENT (or resultCode.getHttpStatus() ==
HttpStatus.NO_CONTENT) and either return
ResponseEntity.status(HttpStatus.NO_CONTENT).build() for a true no-body
response, or normalize the contract by mapping NO_CONTENT to a 200/201
resultCode before building the body; modify ResultResponse.of(ResultCode, T) or
add a new ofNoContent(ResultCode) method accordingly and adjust callers to use
the new behavior.
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/config/WebMvcConfig.java`:
- Around line 21-33: The explicit constructor in WebMvcConfig duplicates
boilerplate for injecting AdminInterceptor, AnyUserInterceptor,
LoginUserInterceptor, LoginPhotographerInterceptor, and LoginModelInterceptor;
replace it by annotating the WebMvcConfig class with Lombok's
`@RequiredArgsConstructor`, make the corresponding fields final (e.g.,
adminInterceptor, anyUserInterceptor, loginUserInterceptor,
loginPhotographerInterceptor, loginModelInterceptor), remove the manual
constructor, and add the Lombok import (lombok.RequiredArgsConstructor) so
Spring will still perform constructor injection without the boilerplate.
- Around line 35-42: addInterceptors currently registers adminInterceptor,
anyUserInterceptor, loginUserInterceptor, loginPhotographerInterceptor, and
loginModelInterceptor globally which causes preHandle to run for all requests;
update each registry.addInterceptor(...) call in
addInterceptors(InterceptorRegistry registry) to exclude infrastructure paths by
chaining .excludePathPatterns("/", "/actuator/**", "/swagger-ui/**",
"/v3/api-docs/**") so health, actuator and swagger endpoints are omitted from
interceptor execution.
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AbstractAuthInterceptor.java`:
- Around line 139-149: The caught exceptions thrown from passportHandler.parse
(PassportParsingException, InvalidPassportException, ExpiredPassportException)
should be chained into the new PresentationException so the original stack trace
is preserved; update the catch blocks in AbstractAuthInterceptor to pass the
caught exception (e) as the cause when constructing PresentationException with
PresentationErrorCode.INVALID_PASSPORT and
PresentationErrorCode.EXPIRED_PASSPORT, and likewise consider including a cause
when throwing PresentationException for the authority check failure (where you
throw new PresentationException(PresentationErrorCode.FORBIDDEN)) so all
PresentationException instances preserve original exception context.
- Around line 129-150: validateUserAuthority currently parses the Passport only
to check authority and drops it; persist the parsed Passport for downstream
reuse by storing the result of passportHandler.parse(signedPassport) as a
request attribute (e.g., request.setAttribute("passport", passport)) after
successful parsing and before authority checks so controllers can retrieve
Passport (type Passport) without re-parsing.
In
`@reservation/src/main/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AdminInterceptor.java`:
- Line 4: The import of AbstractAuthInterceptor is redundant because
AdminInterceptor is in the same package; remove the unnecessary import line that
references AbstractAuthInterceptor so AdminInterceptor.java relies on
package-level visibility and avoids an unused import.
In
`@reservation/src/test/java/net/catsnap/CatsnapReservation/shared/fixture/PassportTestHelper.java`:
- Around line 57-83: Add two no-argument-overload helper methods for
photographer and model: implement withPhotographer(MockHttpServletRequestBuilder
builder) and withModel(MockHttpServletRequestBuilder builder) that delegate to
withAuthority(builder, DEFAULT_ADMIN_USER_ID, CatsnapAuthority.PHOTOGRAPHER) and
withAuthority(builder, DEFAULT_ADMIN_USER_ID, CatsnapAuthority.MODEL)
respectively so tests can omit the userId similar to withAdmin.
In
`@reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/error/PresentationErrorCodeTest.java`:
- Around line 39-59: The tests explicitly list PresentationErrorCode enum
members, which risks missing newly added codes; change the
API_요청_에러는_EA0XX_코드를_가진다 and 인증_인가_에러는_EA1XX_코드를_가진다 tests to verify prefixes
dynamically by iterating over PresentationErrorCode.values() and asserting codes
that belong to the respective category start with "EA0" or "EA1" (use each
enum's name or a maintained category predicate to decide membership); update the
tests to build the membership check from a set/list of names or a helper method
so adding new enum entries is caught automatically.
In
`@reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/GlobalExceptionHandlerTest.java`:
- Around line 44-46: The test in GlobalExceptionHandlerTest calls
response.getBody() without null-check which can cause an NPE; update the
assertion to first assert the body is not null (e.g.,
assertThat(response.getBody()).isNotNull()) and then assert the code by
extracting ResultResponse::getCode (or perform an explicit null check and then
assertEquals on getCode) so the failure message is clearer when
response.getBody() is null; keep the existing HttpStatus assertion and assert
the code equals PresentationErrorCode.NOT_FOUND_API.getCode().
In
`@reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/success/PresentationSuccessCodeTest.java`:
- Around line 15-37: Replace the three for-loop based tests in
PresentationSuccessCodeTest (methods 모두_SuccessCode는_S로_시작하는_코드를_가진다,
모두_SuccessCode는_HttpStatus를_가진다, 모두_SuccessCode는_메시지를_가진다) with JUnit 5
parameterized tests using `@ParameterizedTest` and
`@EnumSource`(PresentationSuccessCode.class) so each test receives a single
PresentationSuccessCode and failures report the specific enum constant; keep the
same assertions (getCode().startsWith("S"), getHttpStatus() != null,
getMessage() not blank) but change the test signatures to accept a
PresentationSuccessCode parameter for clearer failure diagnostics.
In
`@reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/AnyUserInterceptorTest.java`:
- Around line 57-119: Tests repeat Passport creation across
ANONYMOUS/MODEL/PHOTOGRAPHER/ADMIN cases; extract that logic into a private
helper like createPassport(Long userId, CatsnapAuthority authority) that builds
the Instant now/exp and returns new Passport(...), then replace each test's
repeated Instant/Passport block with a call to createPassport and keep the rest
(when(passportHandler.parse(...)), request.addHeader("X-Passport", ...),
createHandlerMethod("anyUserMethod"), and
assertTrue(anyUserInterceptor.preHandle(...))) unchanged.
- Around line 121-133: Add tests to AnyUserInterceptorTest covering
INVALID_PASSPORT and EXPIRED_PASSPORT flows: simulate the token-parsing failures
that cause AbstractAuthInterceptor.validateUserAuthority to throw
InvalidPassportException and ExpiredPassportException and assert that
anyUserInterceptor.preHandle(request, response, handler) throws a
PresentationException with PresentationErrorCode.UNAUTHORIZED (or the expected
code for each case). Use the same pattern as the existing
인증_헤더가_없으면_UNAUTHORIZED_예외가_발생한다() test, reusing
createHandlerMethod("anyUserMethod") and arranging the request/authorization
header to trigger
PassportParsingException/InvalidPassportException/ExpiredPassportException paths
(or mock the underlying passport parsing to throw those exceptions) and validate
the resulting PresentationException.getResultCode().
In
`@reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginModelInterceptorTest.java`:
- Around line 89-122: Add three tests to LoginModelInterceptorTest: (1) test
ANONYMOUS 권한 is treated as forbidden: mock Passport with
CatsnapAuthority.ANONYMOUS and have passportHandler.parse(...) return it, set
X-Passport header and call loginModelInterceptor.preHandle(request, response,
handler) then assert a PresentationException with
PresentationErrorCode.FORBIDDEN; (2) test expired passport: mock
passportHandler.parse(...) to throw ExpiredPassportException, add X-Passport
header, call preHandle and assert a PresentationException with
PresentationErrorCode.EXPIRED_PASSPORT; (3) test invalid passport parsing: mock
passportHandler.parse(...) to throw PassportParsingException (or
InvalidPassportException), add X-Passport header, call preHandle and assert a
PresentationException with PresentationErrorCode.INVALID_PASSPORT; use the
existing createHandlerMethod("modelMethod") and request/response fixtures and
the same assertThatThrownBy pattern as other tests.
In
`@reservation/src/test/java/net/catsnap/CatsnapReservation/shared/presentation/web/interceptor/LoginUserInterceptorTest.java`:
- Around line 105-124: Add a unit test that verifies
loginUserInterceptor.preHandle throws ExpiredPassportException when
Passport.authority() detects an expired passport: create an expired Passport
instance (set issued and exp so exp < now), stub passportHandler.parse(...) to
return that expired Passport, add the "X-Passport" header and a HandlerMethod
via createHandlerMethod("loginUserMethod"), then assert that calling
loginUserInterceptor.preHandle(request, response, handler) results in an
ExpiredPassportException; reference Passport, Passport.authority(),
passportHandler.parse, loginUserInterceptor.preHandle, and
ExpiredPassportException when implementing the test method.
In `@reservation/src/test/resources/application.yml`:
- Around line 21-22: Fix the minor typo in the passport secret value: replace
the misspelled "secreykey" substring in the passport.secret-key value (e.g.,
"itstestsecreykey123123123...") with "secretkey" so the value reads
"itstestsecretkey..."; update the value in the application.yml entry for
passport.secret-key to correct the spelling.
📌 관련 이슈
✨ PR 세부 내용
예약 서버 인증 및 공통 응답 정의했습니다.
Summary by CodeRabbit
릴리스 노트
새로운 기능
테스트
✏️ Tip: You can customize this high-level summary in your review settings.