/** * #545 — 해외 식당 상세에서 테이블링/캐치테이블 예약 버튼 숨김 회귀 테스트. * 좌표 기반(isKoreaRestaurant) 판정으로 국내/해외 식당에서 버튼 노출 여부가 * 올바르게 갈리는지 검증한다. */ import { act, render, screen } from "@testing-library/react"; import RestaurantDetail from "@/components/RestaurantDetail"; import type { Restaurant } from "@/lib/api"; // 컴포넌트 마운트 시 발생하는 비동기 데이터 로딩(영상/리뷰 등)을 플러시해 // act() 경고 없이 안정적으로 렌더 결과를 검증한다. async function flush() { await act(async () => { await Promise.resolve(); }); } jest.mock("@/lib/api", () => ({ getToken: jest.fn(() => null), api: { getRestaurantVideos: jest.fn(() => Promise.resolve([])), getFavoriteStatus: jest.fn(() => Promise.resolve({ favorited: false })), getReviews: jest.fn(() => Promise.resolve({ reviews: [], avg_rating: null, review_count: 0 }) ), getMemo: jest.fn(() => Promise.resolve(null)), }, })); function makeRestaurant(overrides: Partial): Restaurant { return { id: "r1", name: "테스트 식당", address: null, region: null, latitude: 37.5, longitude: 127.0, cuisine_type: null, price_range: null, google_place_id: null, tabling_url: null, catchtable_url: null, business_status: null, rating: null, rating_count: null, phone: null, website: null, ...overrides, }; } describe("RestaurantDetail — #545 해외 식당 예약 버튼 숨김", () => { it("국내 식당(좌표 기반)이면 테이블링/캐치테이블 버튼이 보인다", async () => { const restaurant = makeRestaurant({ latitude: 37.5665, longitude: 126.978, // 서울 tabling_url: "https://tabling.example.com/1", catchtable_url: "https://catchtable.example.com/1", }); render( {}} />); await flush(); expect(screen.getByText("테이블링에서 줄서기")).toBeInTheDocument(); expect(screen.getByText("캐치테이블에서 예약하기")).toBeInTheDocument(); }); it("해외 식당(좌표가 KR bbox 밖)이면 두 버튼 모두 숨겨진다 (대표 발견 케이스)", async () => { const restaurant = makeRestaurant({ latitude: 13.7563, longitude: 100.5018, // 방콕 tabling_url: "https://tabling.example.com/1", catchtable_url: "https://catchtable.example.com/1", }); render( {}} />); await flush(); expect(screen.queryByText("테이블링에서 줄서기")).not.toBeInTheDocument(); expect(screen.queryByText("캐치테이블에서 예약하기")).not.toBeInTheDocument(); }); it("해외 식당이어도 예약 URL이 없으면 애초에 버튼이 없다 (회귀 없음 확인)", async () => { const restaurant = makeRestaurant({ latitude: 35.6762, longitude: 139.6503, // 도쿄 tabling_url: null, catchtable_url: null, }); render( {}} />); await flush(); expect(screen.queryByText("테이블링에서 줄서기")).not.toBeInTheDocument(); expect(screen.queryByText("캐치테이블에서 예약하기")).not.toBeInTheDocument(); }); it("좌표 없는 구 데이터는 region으로 fallback되어 국내로 간주된다 (기존 동작 유지)", async () => { const restaurant = makeRestaurant({ latitude: undefined as unknown as number, longitude: undefined as unknown as number, region: null, tabling_url: "https://tabling.example.com/1", catchtable_url: null, }); render( {}} />); await flush(); expect(screen.getByText("테이블링에서 줄서기")).toBeInTheDocument(); }); it("예약 URL이 'NONE' 문자열이면 국내 식당이어도 버튼이 없다 (기존 게이트 유지)", async () => { const restaurant = makeRestaurant({ latitude: 37.5665, longitude: 126.978, tabling_url: "NONE", catchtable_url: "NONE", }); render( {}} />); await flush(); expect(screen.queryByText("테이블링에서 줄서기")).not.toBeInTheDocument(); expect(screen.queryByText("캐치테이블에서 예약하기")).not.toBeInTheDocument(); }); });