import { describe, expect, test } from "@jest/globals" import { act, renderHook } from "@testing-library/react" import { type PropsWithChildren } from "react" import { BedTypeEnum } from "@/constants/booking" import { Lang } from "@/constants/languages" import EnterDetailsProvider from "@/providers/EnterDetailsProvider" import { detailsStorageName, useEnterDetailsStore } from "." import { BreakfastPackageEnum } from "@/types/enums/breakfast" import { CurrencyEnum } from "@/types/enums/currency" import { PackageTypeEnum } from "@/types/enums/packages" 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), })) const booking = { hotel: "123", fromDate: "2100-01-01", toDate: "2100-01-02", rooms: [ { adults: 1, roomTypeCode: "SKS", rateCode: "SAVEEU", counterRateCode: "PLSA2BEU", }, ], } const bedTypes = [ { type: BedTypeEnum.King, description: "King-size bed", value: "SKS", size: { min: 180, max: 200, }, roomTypeCode: "SKS", extraBed: undefined, }, { type: BedTypeEnum.Queen, description: "Queen-size bed", value: "QZ", size: { min: 160, max: 200, }, roomTypeCode: "QZ", extraBed: undefined, }, ] const guest = { countryCode: "SE", dateOfBirth: "", email: "test@test.com", firstName: "Tester", lastName: "Testersson", join: false, membershipNo: "12345678901234", phoneNumber: "+46700000000", zipCode: "", } const breakfastPackages = [ { code: BreakfastPackageEnum.REGULAR_BREAKFAST, description: "Breakfast with reservation", localPrice: { currency: CurrencyEnum.SEK, price: "99", totalPrice: "99", }, requestedPrice: { currency: CurrencyEnum.EUR, price: "9", totalPrice: "9", }, packageType: PackageTypeEnum.BreakfastAdult as const, }, ] 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: bedTypes[1], breakfast: breakfastPackages[0], booking, guest, } 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(bedTypes[0]) }) 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(breakfastPackages[0]) }) 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(guest) }) expect(result.current.isValid[StepEnum.details]).toEqual(true) expect(result.current.currentStep).toEqual(StepEnum.payment) expect(window.location.pathname.slice(1)).toBe(StepEnum.payment) }) })