Files
web/apps/scandic-web/stores/enter-details/_useEnterDetailsStore.testing.tsx
2025-02-28 11:10:22 +01:00

658 lines
21 KiB
TypeScript

// 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<CreateWrapperParams> = {}) {
// const {
// breakfastIncluded = false,
// breakfastPackages = null,
// mustBeGuaranteed = false,
// bookingParams = booking,
// bedTypes = [bedType.king, bedType.queen],
// } = params
// return function Wrapper({ children }: PropsWithChildren) {
// return (
// <EnterDetailsProvider
// booking={bookingParams}
// breakfastPackages={breakfastPackages}
// rooms={[
// {
// bedTypes,
// packages: null,
// mustBeGuaranteed,
// breakfastIncluded,
// cancellationText: "",
// rateDetails: [],
// roomType: "Standard",
// roomTypeCode: "QS",
// roomRate: roomRate,
// },
// {
// bedTypes,
// packages: null,
// mustBeGuaranteed,
// breakfastIncluded,
// cancellationText: "",
// rateDetails: [],
// roomType: "Standard",
// roomTypeCode: "QS",
// roomRate: roomRate,
// },
// ]}
// searchParamsStr=""
// user={null}
// vat={0}
// >
// {children}
// </EnterDetailsProvider>
// )
// }
// }
// 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)
// })
// })
// })
// })