Files
calendar/apps/web/lib/__tests__/getThemeProviderProps.test.ts
T

246 lines
7.1 KiB
TypeScript

import type { ReadonlyURLSearchParams } from "next/navigation";
import { describe, expect, it } from "vitest";
import { EmbedTheme } from "@calcom/features/embed/lib/constants";
import { getThemeProviderProps } from "../getThemeProviderProps";
import { getUniqueIdentifierForBookingPage } from "../getThemeProviderProps";
describe("getThemeProviderProps", () => {
const fnArg = {
props: {
isBookingPage: false,
isThemeSupported: true,
nonce: "test-nonce",
},
isEmbedMode: false,
embedNamespace: null,
searchParams: new URLSearchParams() as unknown as ReadonlyURLSearchParams,
};
describe("App Theme Support", () => {
const expectedStorageKey = "app-theme";
const appThemeExpectedProps = {
attribute: "class",
storageKey: expectedStorageKey,
key: expectedStorageKey,
nonce: "test-nonce",
enableColorScheme: false,
};
it("should return app theme configuration when not in booking page or embed mode", () => {
const result = getThemeProviderProps({
...fnArg,
pathname: "/test",
});
expect(result).toEqual({
forcedTheme: undefined,
enableSystem: true,
...appThemeExpectedProps,
});
});
it("should force light theme and no storageKey and system theme support is required when isThemeSupported is false", () => {
const result = getThemeProviderProps({
...fnArg,
pathname: "/test",
props: {
...fnArg.props,
isThemeSupported: false,
},
});
expect(result).toEqual({
...appThemeExpectedProps,
storageKey: "forcedThemeKey",
key: "forcedThemeKey",
forcedTheme: "light",
enableSystem: false,
});
});
it("should not force theme when isThemeSupported is not explicitly set", () => {
const result = getThemeProviderProps({
...fnArg,
pathname: "/test",
props: {
...fnArg.props,
isThemeSupported: undefined,
},
});
expect(result).toEqual({
...appThemeExpectedProps,
forcedTheme: undefined,
enableSystem: true,
});
});
});
describe("Booking Page Theme Support", () => {
const bookingPageExpectedProps = {
attribute: "class",
nonce: "test-nonce",
enableColorScheme: false,
};
it("should handle booking page theme", () => {
const expectedStorageKey = "booking-theme:free";
const result = getThemeProviderProps({
...fnArg,
pathname: "/free/30min",
props: {
...fnArg.props,
isBookingPage: true,
},
});
expect(result).toEqual({
...bookingPageExpectedProps,
storageKey: expectedStorageKey,
key: expectedStorageKey,
forcedTheme: undefined,
enableSystem: true,
});
});
it("should handle team booking page theme configuration", () => {
const result = getThemeProviderProps({
...fnArg,
props: {
...fnArg.props,
isBookingPage: true,
},
pathname: "/team/sales/30min",
});
expect(result.storageKey).toBe("booking-theme:sales");
});
});
describe("Embed Mode Theme Support", () => {
const embedProps = {
...fnArg,
isEmbedMode: true,
};
const embedPageExpectedProps = {
attribute: "class",
nonce: "test-nonce",
enableColorScheme: false,
enableSystem: true,
forcedTheme: undefined,
};
it("should handle embed mode with default theme", () => {
const result = getThemeProviderProps({
...embedProps,
embedNamespace: "ns",
pathname: "/free",
});
const storageKey = "embed-theme-ns:free";
expect(result).toEqual({
...embedPageExpectedProps,
storageKey,
key: storageKey,
});
});
it("should handle embed mode with explicit theme. Must have theme name in storageKey so that different themes for different booking pages under same namespace also work", () => {
const searchParams = new URLSearchParams();
searchParams.set("theme", EmbedTheme.dark);
const result = getThemeProviderProps({
...embedProps,
searchParams: searchParams as unknown as ReadonlyURLSearchParams,
pathname: "/free",
embedNamespace: "ns",
});
const expectedStorageKey = "embed-theme-ns:free:dark";
expect(result).toEqual({
...embedPageExpectedProps,
storageKey: expectedStorageKey,
key: expectedStorageKey,
});
});
it("should not append theme suffix for auto theme as that is kind of default", () => {
const searchParams = new URLSearchParams();
searchParams.set("theme", EmbedTheme.auto);
const result = getThemeProviderProps({
...embedProps,
searchParams: searchParams as unknown as ReadonlyURLSearchParams,
pathname: "/free",
embedNamespace: "ns",
});
expect(result).toEqual({
...embedPageExpectedProps,
storageKey: "embed-theme-ns:free",
key: "embed-theme-ns:free",
});
});
});
});
describe("getUniqueIdentifierForBookingPage", () => {
describe("User Pages", () => {
it.each([
{ path: "/test", expected: "test" },
{ path: "/test/anything", expected: "test" },
])("should return $expected for $path", ({ path, expected }) => {
const result = getUniqueIdentifierForBookingPage({ pathname: path });
expect(result).toBe(expected);
});
it("should return / for root path", () => {
const result = getUniqueIdentifierForBookingPage({ pathname: "/" });
expect(result).toBe("/");
});
});
describe("Team Pages", () => {
it.each([
{ path: "/team/test", expected: "test" },
{ path: "/team/test/anything", expected: "test" },
])("should return $expected for $path", ({ path, expected }) => {
const result = getUniqueIdentifierForBookingPage({ pathname: path });
expect(result).toBe(expected);
});
});
describe("Routing Pages", () => {
it("should return formId for routing pages", () => {
const result = getUniqueIdentifierForBookingPage({
pathname: "/forms/test",
});
expect(result).toBe("test");
});
});
describe("Private Booking Pages", () => {
it.each([
{ path: "/d/private", expected: "private" },
{ path: "/d/private/anything", expected: "private" },
])("should return $expected for $path", ({ path, expected }) => {
const result = getUniqueIdentifierForBookingPage({ pathname: path });
expect(result).toBe(expected);
});
});
describe("Dynamic Booking Pages", () => {
it.each([
{ path: "/john+jane", expected: "john+jane" },
{ path: "/john+jane/", expected: "john+jane" },
{ path: "/john+jane/anything", expected: "john+jane" },
{ path: "/john%2bjane/anything", expected: "john%2bjane" },
])("should return $expected for $path", ({ path, expected }) => {
const result = getUniqueIdentifierForBookingPage({ pathname: path });
expect(result).toBe(expected);
});
});
});