246 lines
7.1 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|