import { describe, expect, test } from "@jest/globals" import { act, renderHook } from "@testing-library/react" import { type PropsWithChildren } from "react" import { Lang } from "@/constants/languages" import { bedType, booking, breakfastPackage, guestDetailsNonMember, roomRate, } from "@/__mocks__/hotelReservation" import EnterDetailsProvider from "@/providers/EnterDetailsProvider" import { detailsStorageName, useEnterDetailsStore } from "." import { StepEnum } from "@/types/enums/step" import type { PersistedState } from "@/types/stores/enter-details" jest.mock("react", () => ({ ...jest.requireActual("react"), cache: jest.fn(), })) jest.mock("@/server/utils", () => ({ toLang: () => Lang.en, })) jest.mock("@/lib/api", () => ({ fetchRetry: jest.fn((fn) => fn), })) function Wrapper({ children }: PropsWithChildren) { return ( {children} ) } describe("Enter Details Store", () => { beforeEach(() => { window.sessionStorage.clear() }) test("initialize with correct default values", () => { const { result } = renderHook( () => useEnterDetailsStore((state) => state), { wrapper: Wrapper, } ) const state = result.current expect(state.currentStep).toBe(StepEnum.selectBed) expect(state.booking).toEqual(booking) expect(state.bedType).toEqual(undefined) expect(state.breakfast).toEqual(undefined) expect(Object.values(state.guest).every((value) => value === "")) }) test("initialize with correct values from sessionStorage", async () => { const storage: PersistedState = { bedType: { roomTypeCode: bedType.queen.value, description: bedType.queen.description, }, breakfast: breakfastPackage, booking, guest: guestDetailsNonMember, } window.sessionStorage.setItem(detailsStorageName, JSON.stringify(storage)) const { result } = renderHook( () => useEnterDetailsStore((state) => state), { wrapper: Wrapper, } ) const state = result.current expect(state.bedType).toEqual(storage.bedType) expect(state.guest).toEqual(storage.guest) expect(state.booking).toEqual(storage.booking) expect(state.breakfast).toEqual(storage.breakfast) }) test("complete step and navigate to next step", async () => { const { result } = renderHook( () => useEnterDetailsStore((state) => state), { wrapper: Wrapper, } ) expect(result.current.currentStep).toEqual(StepEnum.selectBed) await act(async () => { result.current.actions.updateBedType({ roomTypeCode: bedType.king.value, description: bedType.king.description, }) }) expect(result.current.isValid[StepEnum.selectBed]).toEqual(true) expect(result.current.currentStep).toEqual(StepEnum.breakfast) expect(window.location.pathname.slice(1)).toBe(StepEnum.breakfast) await act(async () => { result.current.actions.updateBreakfast(breakfastPackage) }) expect(result.current.isValid[StepEnum.breakfast]).toEqual(true) expect(result.current.currentStep).toEqual(StepEnum.details) expect(window.location.pathname.slice(1)).toBe(StepEnum.details) await act(async () => { result.current.actions.updateDetails(guestDetailsNonMember) }) expect(result.current.isValid[StepEnum.details]).toEqual(true) expect(result.current.currentStep).toEqual(StepEnum.payment) expect(window.location.pathname.slice(1)).toBe(StepEnum.payment) }) })