From c7e38af5c9454bd1b9e01f77d2c4198217e3ce06 Mon Sep 17 00:00:00 2001 From: Tobias Johansson Date: Wed, 8 Jan 2025 07:47:51 +0000 Subject: [PATCH] Merged in feat/enter-details-store-tests (pull request #1134) Feat/enter details store tests * test: add unit tests for useEnterDetailsStore and update Jest environment * test: added more useEnterDetailsStore tests Approved-by: Christel Westerberg --- jest.config.ts | 2 +- .../useEnterDetailsStore.test.tsx | 209 ++++++++++++++++++ 2 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 stores/enter-details/useEnterDetailsStore.test.tsx diff --git a/jest.config.ts b/jest.config.ts index 28055b8c6..bf51303a6 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -154,7 +154,7 @@ const config: Config = { // snapshotSerializers: [], // The test environment that will be used for testing - // testEnvironment: "jest-environment-node", + testEnvironment: "jest-environment-jsdom", // Options that will be passed to the testEnvironment // testEnvironmentOptions: {}, diff --git a/stores/enter-details/useEnterDetailsStore.test.tsx b/stores/enter-details/useEnterDetailsStore.test.tsx new file mode 100644 index 000000000..dc6e3b442 --- /dev/null +++ b/stores/enter-details/useEnterDetailsStore.test.tsx @@ -0,0 +1,209 @@ +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 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 = [ + { + description: "King-size bed", + value: "SKS", + size: { + min: 180, + max: 200, + }, + roomTypeCode: "SKS", + }, + { + description: "Queen-size bed", + value: "QZ", + size: { + min: 160, + max: 200, + }, + roomTypeCode: "QZ", + }, +] + +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) + }) +})