Skip to content

[FEAT] restaurant-service 배포환경 API 시나리오 테스트 추가 - #62

Merged
jihxonx merged 3 commits into
devfrom
feat/61-restaurant-service-prod-api-scenario-test
May 19, 2026
Merged

jihxonx merged 3 commits into
devfrom
feat/61-restaurant-service-prod-api-scenario-test

Conversation

@jihxonx

@jihxonx jihxonx commented May 19, 2026

Copy link
Copy Markdown
Contributor

📝 작업 내용

이번 PR에서 작업한 내용을 설명해주세요.

  • restaurant-service 배포환경 API 시나리오 테스트용 HTTP Client 파일을 추가

  • API Gateway를 통해 restaurant-service 주요 API와 체크인 E2E 흐름을 검증할 수 있도록 구성

🚀 주요 변경 사항

완료한 이슈 번호
Close #61
관련된 이슈 번호 (닫고 싶지 않은 경우)
Related to #

✅ 자체 체크리스트 (필수)

  • ./gradlew build 실행 결과 정상 (인증샷 첨부)
  • IntelliJ HTTP Client 테스트 완료 (인증샷 첨부)
  • 팀 내 컨벤션 준수 및 불필요한 로그, import 제거
  • 중요한 변경 사항이 팀에 공유되었는지

📸 테스트 인증샷

빌드 결과 및 IntelliJ HTTP Client 실행 화면을 여기에 첨부해 주세요.

스크린샷 2026-05-19 105846

💬 리뷰어 전달사항 (선택)

특별히 봐주었으면 하는 부분이나 논의가 필요한 점을 적어주세요.

  • 논의점


📎 참고 자료

관련 문서, 레퍼런스 링크 등이 있다면 여기에 첨부해주세요.

Summary by CodeRabbit

  • Tests
    • E2E 테스트 시나리오 추가로 전체 체크인 흐름에 대한 테스트 커버리지 확대

Review Change Stack

@jihxonx jihxonx self-assigned this May 19, 2026
@jihxonx jihxonx added the test 테스트 코드 및 검증 작업 label May 19, 2026
@jihxonx jihxonx linked an issue May 19, 2026 that may be closed by this pull request
10 tasks
@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@jihxonx has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 53 minutes and 13 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d57f66f3-f1f5-463a-8fc1-d1ffba5e644f

📥 Commits

Reviewing files that changed from the base of the PR and between d6093dc and bf35e68.

📒 Files selected for processing (1)
  • src/test/mvp/prod-full-checkin-e2e.http
📝 Walkthrough

개요

프로덕션 환경의 API Gateway를 통해 restaurant-service가 회원가입부터 체크인까지 완전히 동작하는지 검증하는 HTTP 기반 E2E 테스트 시나리오를 추가했다. 14단계의 순차 테스트로 인증, 식당 설정, 대기열 관리, 예약, 체크인 흐름을 커버한다.

변경 사항

E2E 체크인 시나리오 테스트

계층 / 파일 설명
설정 및 게이트웨이 확인
src/test/mvp/prod-full-checkin-e2e.http
게이트웨이 URL, 테스트 계정, 식당·코스명, 예약 날짜·시간, 타임슬롯 생성 범위 등 전역 변수를 정의하고 health 엔드포인트로 가용성을 확인한다.
회원가입 및 로그인 인증
src/test/mvp/prod-full-checkin-e2e.http
OWNER/USER 회원가입(200/201/409), 로그인 후 JWT payload 디코딩으로 userId/ownerId를 추출하고, accessToken/token 필드를 우선순위로 탐색해 인증 토큰을 저장한다.
식당·코스·타임슬롯 준비
src/test/mvp/prod-full-checkin-e2e.http
OWNER 권한으로 레스토랑, 코스를 생성해 ID를 저장하고, 오늘 기준 30분 이내 슬롯을 bulk 생성한 후 조회 결과에서 일치하는 timeSlotId를 선택해 저장한다.
대기열 및 예약 생성
src/test/mvp/prod-full-checkin-e2e.http
USER 권한으로 타임슬롯 기반 대기열에 입장해 queueToken/waitingId를 저장하고, 상태 조회 시 ACTIVE 상태의 accessToken을 waitingAccessToken으로 저장한 후, Idempotency-Key와 함께 예약을 생성한다.
예약 조회 및 체크인 실행
src/test/mvp/prod-full-checkin-e2e.http
예약 상세 조회로 데이터 일관성을 검증하고, 체크인을 수행해 success=true를 확인하며, 중복 체크인으로 멱등성(200/400/409)을 테스트한다.

예상 코드 리뷰 노력

🎯 2 (Simple) | ⏱️ ~12분

관련 PR

  • Miche-Let/restaurant-service#22: 신규 E2E 시나리오가 PR #22의 OWNER/USER 회원가입·로그인 흐름 및 역할 기반 RestaurantController/RestaurantCourseController 인증 요구사항을 직접 활용하여 엔드-투-엔드 검증을 구성한다.

검토 추천자

  • githyj-jang
  • Sehi55
  • qldo
  • ji-circle
  • Jinyoung-Kim96

🐰 축하 시

🐇✨ 게이트웨이 통과, 토큰 지나고,
타임슬롯 찾아 대기열 서서,
예약 생성 후 체크인 완료—
풀 플로우 테스트 성공! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경사항의 주요 내용(restaurant-service 배포환경 API 시나리오 테스트 추가)을 명확하고 간결하게 설명하고 있습니다.
Linked Issues check ✅ Passed 추가된 E2E 테스트 파일은 #61의 API Gateway 라우팅, 여러 엔드포인트 검증, 인증/권한 확인 등 대부분의 기본 요구사항을 다루고 있습니다.
Out of Scope Changes check ✅ Passed 변경사항이 프로덕션 E2E 시나리오 테스트 파일 추가에만 국한되어 있으며, #61의 범위 내에서 벗어나지 않습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/61-restaurant-service-prod-api-scenario-test

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (3)
src/test/mvp/prod-full-checkin-e2e.http (3)

491-491: ⚡ Quick win

waitingAccessToken 설정 여부 검증 권장

Line 491에서 X-Waiting-Token: {{waitingAccessToken}}을 사용하지만, STEP 10에서 대기열 상태가 ACTIVE가 아니거나 accessToken이 없으면 이 변수가 설정되지 않습니다.

변수가 설정되지 않은 상태로 예약 생성을 시도하면 인증 오류가 발생할 수 있으므로, 응답 핸들러에서 변수 존재 여부를 검증하고 명확한 오류 메시지를 제공하는 것이 좋습니다.

♻️ 검증 로직 추가 제안

STEP 11의 응답 핸들러 시작 부분에 추가:

> {%
    const waitingAccessToken = client.global.get("waitingAccessToken");
    if (!waitingAccessToken) {
        throw new Error("waitingAccessToken이 설정되지 않았습니다. STEP 10에서 status=ACTIVE 확인 후 재시도하세요.");
    }
    
    client.global.clear("reservationId");
    // ... 나머지 로직
%}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/mvp/prod-full-checkin-e2e.http` at line 491, Add a presence check
for the waitingAccessToken at the start of the STEP 11 response handler:
retrieve it via client.global.get("waitingAccessToken"), and if falsy throw an
explicit Error like "waitingAccessToken이 설정되지 않았습니다. STEP 10에서 status=ACTIVE 확인
후 재시도하세요." before proceeding to the existing logic (e.g.,
client.global.clear("reservationId") and the rest of the handler); this ensures
the X-Waiting-Token header ({{waitingAccessToken}}) is validated and fails with
a clear message when missing.

160-165: ⚡ Quick win

JWT 디코딩 오류 처리 강화 권장

JWT payload 디코딩 시 토큰 형식이 올바르지 않으면 런타임 오류가 발생할 수 있습니다:

  • token.split(".")[1]undefined일 경우 (토큰이 점으로 구분된 3개 파트가 아닐 때)
  • atob() 또는 JSON.parse()가 실패할 경우

권장사항:

  • 토큰이 3개 파트로 구성되었는지 검증
  • try-catch로 디코딩 오류를 처리하여 명확한 오류 메시지 제공
♻️ 개선 제안
 let payloadBase64 = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/");
+
+if (!payloadBase64) {
+    throw new Error("JWT 토큰 형식이 올바르지 않습니다.");
+}
+
 payloadBase64 += "=".repeat((4 - payloadBase64.length % 4) % 4);

-const payload = JSON.parse(atob(payloadBase64));
+let payload;
+try {
+    payload = JSON.parse(atob(payloadBase64));
+} catch (e) {
+    throw new Error("JWT payload 디코딩 실패: " + e.message);
+}

Also applies to: 212-217

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/mvp/prod-full-checkin-e2e.http` around lines 160 - 165, Validate the
JWT format and add robust error handling around the decoding logic: check that
token.split(".") yields exactly 3 parts before accessing index 1, then wrap the
base64 normalization, atob decoding, and JSON.parse of payloadBase64 in a
try-catch; on error, produce a clear error message (including the original token
or reason) and avoid calling client.global.set("ownerId") when decoding fails.
Target the block that builds payloadBase64, calls atob()/JSON.parse(), and
client.global.set("ownerId") to implement these checks and the try-catch.

492-492: 💤 Low value

Idempotency-Key 고유성 개선 고려

Idempotency-Keyreservation-full-e2e-90212-{{$timestamp}}로 구성되어 있습니다. 고정된 접두사와 타임스탬프 조합은 동일한 밀리초 내에 여러 요청이 발생하거나 병렬 테스트 실행 시 충돌할 가능성이 있습니다.

권장사항:

  • UUID 또는 더 고유한 식별자 사용
  • 또는 접두사에 사용자 식별 정보나 랜덤 값 추가

예: reservation-full-e2e-{{userId}}-{{$timestamp}}-{{$randomInt}}

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/mvp/prod-full-checkin-e2e.http` at line 492, The Idempotency-Key
header uses a fixed prefix plus timestamp ("Idempotency-Key:
reservation-full-e2e-90212-{{$timestamp}}") which can collide under
parallel/millisecond requests; change the header generation to include a
stronger unique component (for example use a UUID or add a random integer and/or
userId) so each request is globally unique—update the Idempotency-Key line to
something like "reservation-full-e2e-{{userId}}-{{$timestamp}}-{{$randomInt}}"
or use a {{$uuid}} token source in the test harness so the header always
contains a UUID.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/test/mvp/prod-full-checkin-e2e.http`:
- Around line 5-7: The SSH tunnel example in the commented block containing the
SSH command (ssh -N -i "...michelet-bastion-key.cer" -L 19000:10.0.11.237:19000
ubuntu@52.79.37.117) exposes sensitive infra details; replace the hardcoded
bastion IP, internal IP and local key path with clear placeholders (e.g.
<BASTION_IP>, <INTERNAL_IP>, <KEY_PATH>) and convert the comment into a generic
usage note pointing readers to environment-specific config or a separate secure
documentation/source of truth for real values.
- Around line 21-33: The test file contains hardcoded plaintext credentials
(`@ownerLoginId`, `@ownerPassword`, `@ownerName`, `@ownerEmail`, `@ownerPhone` and
`@userLoginId`, `@userPassword`, `@userName`, `@userEmail`, `@userPhone`); replace these
hardcoded values with references to environment variables or a separate ignored
config (e.g., use OWNER_LOGIN_ID, OWNER_PASSWORD, USER_LOGIN_ID, USER_PASSWORD,
etc.) and update any code/tests that read those tokens to fall back to safe
defaults only in local/dev. Also add a clear comment/marker that these are
test-only accounts and ensure the new config file is .gitignore'd or
secret-managed so no real credentials are committed.
- Line 10: The header comment string "###    STEP 0 → STEP 1 → ... → STEP 12" is
inaccurate—update that comment in src/test/mvp/prod-full-checkin-e2e.http to
reflect the actual step range (STEP 0 → STEP 1 → ... → STEP 14) or change to a
generic descriptor like "STEP 0 → ... → STEP 14" so the documented range matches
the 15 steps present; locate and edit the exact comment line containing that
arrow sequence to correct the documentation.

---

Nitpick comments:
In `@src/test/mvp/prod-full-checkin-e2e.http`:
- Line 491: Add a presence check for the waitingAccessToken at the start of the
STEP 11 response handler: retrieve it via
client.global.get("waitingAccessToken"), and if falsy throw an explicit Error
like "waitingAccessToken이 설정되지 않았습니다. STEP 10에서 status=ACTIVE 확인 후 재시도하세요."
before proceeding to the existing logic (e.g.,
client.global.clear("reservationId") and the rest of the handler); this ensures
the X-Waiting-Token header ({{waitingAccessToken}}) is validated and fails with
a clear message when missing.
- Around line 160-165: Validate the JWT format and add robust error handling
around the decoding logic: check that token.split(".") yields exactly 3 parts
before accessing index 1, then wrap the base64 normalization, atob decoding, and
JSON.parse of payloadBase64 in a try-catch; on error, produce a clear error
message (including the original token or reason) and avoid calling
client.global.set("ownerId") when decoding fails. Target the block that builds
payloadBase64, calls atob()/JSON.parse(), and client.global.set("ownerId") to
implement these checks and the try-catch.
- Line 492: The Idempotency-Key header uses a fixed prefix plus timestamp
("Idempotency-Key: reservation-full-e2e-90212-{{$timestamp}}") which can collide
under parallel/millisecond requests; change the header generation to include a
stronger unique component (for example use a UUID or add a random integer and/or
userId) so each request is globally unique—update the Idempotency-Key line to
something like "reservation-full-e2e-{{userId}}-{{$timestamp}}-{{$randomInt}}"
or use a {{$uuid}} token source in the test harness so the header always
contains a UUID.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 20802c64-1472-49c7-a3b8-609a74e02925

📥 Commits

Reviewing files that changed from the base of the PR and between 948ca38 and d6093dc.

📒 Files selected for processing (1)
  • src/test/mvp/prod-full-checkin-e2e.http

Comment thread src/test/mvp/prod-full-checkin-e2e.http Outdated
Comment thread src/test/mvp/prod-full-checkin-e2e.http
Comment thread src/test/mvp/prod-full-checkin-e2e.http

@qldo qldo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

확인하였습니다

@jihxonx
jihxonx merged commit f44fb30 into dev May 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test 테스트 코드 및 검증 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] restaurant-service 배포환경 API 시나리오 테스트

2 participants