// import { describe, expect, test } from "@jest/globals" // import { act, renderHook, waitFor } from "@testing-library/react" // import { type PropsWithChildren } from "react" // import { BedTypeEnum } from "@/constants/booking" // import { Lang } from "@/constants/languages" // import { // bedType, // booking, // breakfastPackage, // guestDetailsMember, // guestDetailsNonMember, // roomPrice, // roomRate, // } from "@/__mocks__/hotelReservation" // import EnterDetailsProvider from "@/providers/EnterDetailsProvider" // import { detailsStorageName, useEnterDetailsStore } from "." // import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType" // import type { BreakfastPackages } from "@/types/components/hotelReservation/enterDetails/breakfast" // import type { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate" // 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), // })) // interface CreateWrapperParams { // bedTypes?: BedTypeSelection[] // bookingParams?: SelectRateSearchParams // breakfastIncluded?: boolean // breakfastPackages?: BreakfastPackages | null // mustBeGuaranteed?: boolean // } // function createWrapper(params: Partial = {}) { // const { // breakfastIncluded = false, // breakfastPackages = null, // mustBeGuaranteed = false, // bookingParams = booking, // bedTypes = [bedType.king, bedType.queen], // } = params // return function Wrapper({ children }: PropsWithChildren) { // return ( // // {children} // // ) // } // } // describe("Enter Details Store", () => { // beforeEach(() => { // window.sessionStorage.clear() // }) // describe("initial state", () => { // test("initialize with correct default values", () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // const state = result.current // expect(state.booking).toEqual(booking) // // room 1 // const room1 = result.current.rooms[0] // expect(room1.currentStep).toBe(StepEnum.selectBed) // expect(room1.room.roomPrice.perNight.local.price).toEqual( // roomRate.publicRate.localPrice.pricePerNight // ) // expect(room1.room.bedType).toEqual(undefined) // expect(Object.values(room1.room.guest).every((value) => value === "")) // // room 2 // const room2 = result.current.rooms[1] // expect(room2.currentStep).toBe(null) // expect(room2.room.roomPrice.perNight.local.price).toEqual( // room2.room.roomRate.publicRate.localPrice.pricePerNight // ) // expect(room2.room.bedType).toEqual(undefined) // expect(Object.values(room2.room.guest).every((value) => value === "")) // }) // test("initialize with correct values from session storage", () => { // const storage: PersistedState = { // activeRoom: 0, // booking: booking, // rooms: [ // { // currentStep: StepEnum.selectBed, // isComplete: false, // room: { // adults: 1, // bedType: { // description: bedType.king.description, // roomTypeCode: bedType.king.value, // }, // bedTypes: [ // { // description: bedType.king.description, // extraBed: undefined, // size: { // min: 100, // max: 120, // }, // type: BedTypeEnum.King, // value: bedType.king.value, // }, // ], // breakfastIncluded: false, // breakfast: breakfastPackage, // cancellationText: "Non-refundable", // childrenInRoom: [], // guest: guestDetailsNonMember, // rateDetails: [], // roomFeatures: null, // roomPrice: roomPrice, // roomRate: roomRate, // roomType: "Classic Double", // roomTypeCode: "QS", // }, // steps: { // [StepEnum.selectBed]: { // step: StepEnum.selectBed, // isValid: true, // }, // [StepEnum.breakfast]: { // step: StepEnum.breakfast, // isValid: true, // }, // [StepEnum.details]: { // step: StepEnum.details, // isValid: true, // }, // }, // }, // ], // } // window.sessionStorage.setItem(detailsStorageName, JSON.stringify(storage)) // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // expect(result.current.booking).toEqual(storage.booking) // expect(result.current.rooms[0]).toEqual(storage.rooms[0]) // }) // }) // test("add bedtype and proceed to next step", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // let room1 = result.current.rooms[0] // expect(room1.currentStep).toEqual(StepEnum.selectBed) // const selectedBedType = { // roomTypeCode: bedType.king.value, // description: bedType.king.description, // } // await act(async () => { // result.current.actions.updateBedType(0)(selectedBedType) // }) // room1 = result.current.rooms[0] // expect(room1.steps[StepEnum.selectBed].isValid).toEqual(true) // expect(room1.room.bedType).toEqual(selectedBedType) // expect(room1.currentStep).toEqual(StepEnum.breakfast) // }) // test("complete step and navigate to next step", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // // Room 1 // expect(result.current.activeRoom).toEqual(0) // let room1 = result.current.rooms[0] // expect(room1.currentStep).toEqual(StepEnum.selectBed) // await act(async () => { // result.current.actions.updateBedType(0)({ // roomTypeCode: bedType.king.value, // description: bedType.king.description, // }) // }) // room1 = result.current.rooms[0] // expect(room1.steps[StepEnum.selectBed].isValid).toEqual(true) // expect(room1.currentStep).toEqual(StepEnum.breakfast) // await act(async () => { // result.current.actions.updateBreakfast(0)(breakfastPackage) // }) // room1 = result.current.rooms[0] // expect(room1.steps[StepEnum.breakfast]?.isValid).toEqual(true) // expect(room1.currentStep).toEqual(StepEnum.details) // await act(async () => { // result.current.actions.updateDetails(0)(guestDetailsNonMember) // }) // expect(result.current.canProceedToPayment).toBe(false) // // Room 2 // expect(result.current.activeRoom).toEqual(1) // let room2 = result.current.rooms[1] // expect(room2.currentStep).toEqual(StepEnum.selectBed) // await act(async () => { // const selectedBedType = { // roomTypeCode: bedType.king.value, // description: bedType.king.description, // } // result.current.actions.updateBedType(1)(selectedBedType) // }) // room2 = result.current.rooms[1] // expect(room2.steps[StepEnum.selectBed].isValid).toEqual(true) // expect(room2.currentStep).toEqual(StepEnum.breakfast) // await act(async () => { // result.current.actions.updateBreakfast(1)(breakfastPackage) // }) // room2 = result.current.rooms[1] // expect(room2.steps[StepEnum.breakfast]?.isValid).toEqual(true) // expect(room2.currentStep).toEqual(StepEnum.details) // await act(async () => { // result.current.actions.updateDetails(1)(guestDetailsNonMember) // }) // expect(result.current.canProceedToPayment).toBe(true) // }) // test("all steps needs to be completed before going to next room", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // await act(async () => { // result.current.actions.updateDetails(0)(guestDetailsNonMember) // }) // expect(result.current.activeRoom).toEqual(1) // await act(async () => { // result.current.actions.setStep(StepEnum.breakfast) // }) // expect(result.current.activeRoom).toEqual(1) // }) // test("can go back and modify room 1 after completion", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // await act(async () => { // result.current.actions.updateBedType(0)({ // roomTypeCode: bedType.king.value, // description: bedType.king.description, // }) // result.current.actions.updateBreakfast(0)(breakfastPackage) // result.current.actions.updateDetails(0)(guestDetailsNonMember) // }) // // now we are at room 2 // expect(result.current.activeRoom).toEqual(1) // await act(async () => { // result.current.actions.setStep(StepEnum.breakfast) // click "modify" // }) // expect(result.current.activeRoom).toEqual(1) // await act(async () => { // result.current.actions.updateBreakfast(1)(breakfastPackage) // }) // // going back to room 2 // expect(result.current.activeRoom).toEqual(1) // }) // test("breakfast step should be hidden when breakfast is included", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper({ breakfastPackages: null }), // } // ) // const room1 = result.current.rooms[0] // expect(Object.keys(room1.steps)).not.toContain(StepEnum.breakfast) // const room2 = result.current.rooms[1] // expect(Object.keys(room2.steps)).not.toContain(StepEnum.breakfast) // }) // test("select bed step should be skipped when there is only one bedtype", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper({ // bedTypes: [bedType.queen], // breakfastPackages: [ // { // code: "TEST", // description: "Description", // localPrice: { // currency: "SEK", // price: "100", // totalPrice: "100", // }, // requestedPrice: { // currency: "SEK", // price: "100", // totalPrice: "100", // }, // packageType: PackageTypeEnum.BreakfastAdult, // }, // ], // }), // } // ) // const room1 = result.current.rooms[0] // expect(room1.steps[StepEnum.selectBed].isValid).toEqual(true) // expect(room1.currentStep).toEqual(StepEnum.breakfast) // const room2 = result.current.rooms[1] // expect(room2.steps[StepEnum.selectBed].isValid).toEqual(true) // expect(room2.currentStep).toEqual(null) // }) // describe("price calculation", () => { // test("total price should be set properly", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // const publicRate = roomRate.publicRate.localPrice.pricePerStay // const memberRate = roomRate.memberRate?.localPrice.pricePerStay ?? 0 // const initialTotalPrice = publicRate * result.current.rooms.length // expect(result.current.totalPrice.local.price).toEqual(initialTotalPrice) // // room 1 // await act(async () => { // result.current.actions.updateBedType(0)({ // roomTypeCode: bedType.king.value, // description: bedType.king.description, // }) // result.current.actions.updateBreakfast(0)(breakfastPackage) // }) // let expectedTotalPrice = // initialTotalPrice + Number(breakfastPackage.localPrice.price) // expect(result.current.totalPrice.local.price).toEqual(expectedTotalPrice) // await act(async () => { // result.current.actions.updateDetails(0)(guestDetailsMember) // }) // expectedTotalPrice = // memberRate + publicRate + Number(breakfastPackage.localPrice.price) // expect(result.current.totalPrice.local.price).toEqual(expectedTotalPrice) // // room 2 // await act(async () => { // result.current.actions.updateBedType(1)({ // roomTypeCode: bedType.king.value, // description: bedType.king.description, // }) // result.current.actions.updateBreakfast(1)(breakfastPackage) // }) // expectedTotalPrice = // memberRate + publicRate + Number(breakfastPackage.localPrice.price) * 2 // expect(result.current.totalPrice.local.price).toEqual(expectedTotalPrice) // await act(async () => { // result.current.actions.updateDetails(1)(guestDetailsNonMember) // }) // expect(result.current.totalPrice.local.price).toEqual(expectedTotalPrice) // }) // test("room price should be set properly", async () => { // const { result } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper(), // } // ) // const publicRate = roomRate.publicRate.localPrice.pricePerStay // const memberRate = roomRate.memberRate?.localPrice.pricePerStay ?? 0 // let room1 = result.current.rooms[0] // expect(room1.room.roomPrice.perStay.local.price).toEqual(publicRate) // let room2 = result.current.rooms[0] // expect(room2.room.roomPrice.perStay.local.price).toEqual(publicRate) // await act(async () => { // result.current.actions.updateDetails(0)(guestDetailsMember) // }) // room1 = result.current.rooms[0] // expect(room1.room.roomPrice.perStay.local.price).toEqual(memberRate) // }) // }) // describe("change room", () => { // test("changing to room with new bedtypes requires selecting bed again", async () => { // const { result: firstRun } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper({ bedTypes: [bedType.king, bedType.queen] }), // } // ) // const selectedBedType = { // roomTypeCode: bedType.king.value, // description: bedType.king.description, // } // // add bedtype // await act(async () => { // firstRun.current.actions.updateBedType(0)(selectedBedType) // }) // await act(async () => { // firstRun.current.actions.updateBreakfast(0)(false) // 'no breakfast' selected // }) // await act(async () => { // firstRun.current.actions.updateDetails(0)(guestDetailsNonMember) // }) // const updatedBooking = { // ...booking, // rooms: booking.rooms.map((r) => ({ // ...r, // roomTypeCode: "NEW", // })), // } // // render again to change the bedtypes // const { result: secondRun } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper({ // bookingParams: updatedBooking, // bedTypes: [bedType.single, bedType.queen], // }), // } // ) // await waitFor(() => { // const secondRunRoom = secondRun.current.rooms[0] // // bed type should be unset since the bed types have changed // expect(secondRunRoom.room.bedType).toEqual(undefined) // // bed step should be unselected // expect(secondRunRoom.currentStep).toBe(StepEnum.selectBed) // expect(secondRunRoom.steps[StepEnum.selectBed].isValid).toBe(false) // // other steps should still be selected // expect(secondRunRoom.room.breakfast).toBe(false) // expect(secondRunRoom.steps[StepEnum.breakfast]?.isValid).toBe(true) // expect(secondRunRoom.room.guest).toEqual(guestDetailsNonMember) // expect(secondRunRoom.steps[StepEnum.details].isValid).toBe(true) // }) // }) // test("changing to room with single bedtype option should skip step", async () => { // const { result: firstRun } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper({ bedTypes: [bedType.king, bedType.queen] }), // } // ) // const selectedBedType = { // roomTypeCode: bedType.king.value, // description: bedType.king.description, // } // // add bedtype // await act(async () => { // firstRun.current.actions.updateBedType(0)(selectedBedType) // }) // await act(async () => { // firstRun.current.actions.updateBreakfast(0)(breakfastPackage) // }) // const updatedBooking = { // ...booking, // rooms: booking.rooms.map((r) => ({ // ...r, // roomTypeCode: "NEW", // })), // } // // render again to change the bedtypes // const { result: secondRun } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper({ // bookingParams: updatedBooking, // bedTypes: [bedType.queen], // }), // } // ) // await waitFor(() => { // const secondRunRoom = secondRun.current.rooms[0] // expect(secondRunRoom.room.bedType).toEqual({ // roomTypeCode: bedType.queen.value, // description: bedType.queen.description, // }) // expect(secondRunRoom.steps[StepEnum.selectBed].isValid).toBe(true) // expect(secondRunRoom.steps[StepEnum.breakfast]?.isValid).toBe(true) // expect(secondRunRoom.steps[StepEnum.details].isValid).toBe(false) // expect(secondRunRoom.currentStep).toBe(StepEnum.details) // }) // }) // test("if booking has changed, stored values should be discarded", async () => { // const { result: firstRun } = renderHook( // () => useEnterDetailsStore((state) => state), // { // wrapper: createWrapper({ bedTypes: [bedType.king, bedType.queen] }), // } // ) // const selectedBedType = { // roomTypeCode: bedType.king.value, // description: bedType.king.description, // } // // add bedtype // await act(async () => { // firstRun.current.actions.updateBedType(0)(selectedBedType) // }) // await act(async () => { // firstRun.current.actions.updateBreakfast(0)(breakfastPackage) // }) // const updatedBooking = { // ...booking, // hotelId: "0001", // fromDate: "2030-01-01", // toDate: "2030-01-02", // } // renderHook(() => useEnterDetailsStore((state) => state), { // wrapper: createWrapper({ // bookingParams: updatedBooking, // bedTypes: [bedType.queen], // }), // }) // await waitFor(() => { // const storageItem = window.sessionStorage.getItem(detailsStorageName) // expect(storageItem).toBe(null) // }) // }) // }) // })