mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-23 02:45:21 -05:00
92677e1ec0
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
324 lines
10 KiB
TypeScript
324 lines
10 KiB
TypeScript
import { beforeEach, describe, expect, test, vi } from "vitest";
|
|
import { TSurvey, TSurveyWelcomeCard } from "@formbricks/types/surveys/types";
|
|
import { getPublicDomain } from "@/lib/getPublicUrl";
|
|
import { COLOR_DEFAULTS } from "@/lib/styling/constants";
|
|
import { getSurvey } from "@/modules/survey/lib/survey";
|
|
import { getProjectByEnvironmentId } from "@/modules/survey/link/lib/project";
|
|
import {
|
|
getBasicSurveyMetadata,
|
|
getBrandColorForURL,
|
|
getMetadataBrandColor,
|
|
getNameForURL,
|
|
getSurveyOpenGraphMetadata,
|
|
} from "./metadata-utils";
|
|
|
|
// Mock dependencies
|
|
vi.mock("@/modules/survey/lib/survey", () => ({
|
|
getSurvey: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("@/modules/survey/link/lib/project", () => ({
|
|
getProjectByEnvironmentId: vi.fn(),
|
|
}));
|
|
|
|
// Mock constants
|
|
vi.mock("@/lib/constants", () => ({
|
|
IS_FORMBRICKS_CLOUD: false,
|
|
WEBAPP_URL: "https://test.formbricks.com",
|
|
}));
|
|
|
|
vi.mock("@/lib/styling/constants", () => ({
|
|
COLOR_DEFAULTS: {
|
|
brandColor: "#00c4b8",
|
|
},
|
|
}));
|
|
|
|
// Mock recall utility
|
|
vi.mock("@/lib/utils/recall", () => ({
|
|
recallToHeadline: vi.fn((headline) => headline),
|
|
}));
|
|
|
|
// Mock text content extraction
|
|
vi.mock("@formbricks/types/surveys/validation", () => ({
|
|
getTextContent: vi.fn((text) => text),
|
|
}));
|
|
|
|
describe("Metadata Utils", () => {
|
|
// Reset all mocks before each test
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("getNameForURL", () => {
|
|
test("replaces spaces with %20", () => {
|
|
const result = getNameForURL("Hello World");
|
|
expect(result).toBe("Hello%20World");
|
|
});
|
|
|
|
test("handles strings with no spaces correctly", () => {
|
|
const result = getNameForURL("HelloWorld");
|
|
expect(result).toBe("HelloWorld");
|
|
});
|
|
|
|
test("handles strings with multiple spaces", () => {
|
|
const result = getNameForURL("Hello World Test");
|
|
expect(result).toBe("Hello%20%20World%20%20Test");
|
|
});
|
|
});
|
|
|
|
describe("getBrandColorForURL", () => {
|
|
test("replaces # with %23", () => {
|
|
const result = getBrandColorForURL("#ff0000");
|
|
expect(result).toBe("%23ff0000");
|
|
});
|
|
|
|
test("handles strings with no # correctly", () => {
|
|
const result = getBrandColorForURL("ff0000");
|
|
expect(result).toBe("ff0000");
|
|
});
|
|
});
|
|
|
|
describe("getBasicSurveyMetadata", () => {
|
|
const mockSurveyId = "survey-123";
|
|
const mockEnvironmentId = "env-456";
|
|
|
|
test("returns default metadata when survey is not found", async () => {
|
|
const result = await getBasicSurveyMetadata(mockSurveyId);
|
|
|
|
expect(getSurvey).toHaveBeenCalledWith(mockSurveyId);
|
|
expect(result).toEqual({
|
|
title: "Survey",
|
|
description: "Please complete this survey.",
|
|
survey: null,
|
|
ogImage: undefined,
|
|
});
|
|
});
|
|
|
|
test("uses welcome card headline when available", async () => {
|
|
const mockSurvey = {
|
|
id: mockSurveyId,
|
|
environmentId: mockEnvironmentId,
|
|
name: "Test Survey",
|
|
metadata: {},
|
|
welcomeCard: {
|
|
enabled: true,
|
|
timeToFinish: false,
|
|
showResponseCount: false,
|
|
headline: {
|
|
default: "Welcome Headline",
|
|
},
|
|
html: {
|
|
default: "Welcome Description",
|
|
},
|
|
} as TSurveyWelcomeCard,
|
|
} as unknown as TSurvey;
|
|
|
|
vi.mocked(getSurvey).mockResolvedValue(mockSurvey);
|
|
vi.mocked(getProjectByEnvironmentId).mockResolvedValue({ name: "Test Project" } as any);
|
|
|
|
const result = await getBasicSurveyMetadata(mockSurveyId);
|
|
|
|
expect(getSurvey).toHaveBeenCalledWith(mockSurveyId);
|
|
expect(result).toEqual({
|
|
title: "Welcome Headline",
|
|
description: "Please complete this survey.",
|
|
survey: mockSurvey,
|
|
ogImage: undefined,
|
|
});
|
|
});
|
|
|
|
test("falls back to survey name when welcome card is not enabled", async () => {
|
|
const mockSurvey = {
|
|
id: mockSurveyId,
|
|
environmentId: mockEnvironmentId,
|
|
name: "Test Survey",
|
|
metadata: {},
|
|
welcomeCard: {
|
|
enabled: false,
|
|
} as TSurveyWelcomeCard,
|
|
} as unknown as TSurvey;
|
|
|
|
vi.mocked(getSurvey).mockResolvedValue(mockSurvey);
|
|
|
|
const result = await getBasicSurveyMetadata(mockSurveyId);
|
|
|
|
expect(result).toEqual({
|
|
title: "Test Survey",
|
|
description: "Please complete this survey.",
|
|
survey: mockSurvey,
|
|
ogImage: undefined,
|
|
});
|
|
});
|
|
|
|
test("adds Formbricks to title when IS_FORMBRICKS_CLOUD is true", async () => {
|
|
// Temporarily modify the mocked module
|
|
vi.doMock("@/lib/constants", () => ({
|
|
IS_FORMBRICKS_CLOUD: true,
|
|
WEBAPP_URL: "https://test.formbricks.com",
|
|
}));
|
|
|
|
// Re-import the function to use the updated mock
|
|
const { getBasicSurveyMetadata: getBasicSurveyMetadataWithCloudMock } =
|
|
await import("./metadata-utils");
|
|
|
|
const mockSurvey = {
|
|
id: mockSurveyId,
|
|
environmentId: mockEnvironmentId,
|
|
name: "Test Survey",
|
|
metadata: {},
|
|
welcomeCard: {
|
|
enabled: false,
|
|
} as TSurveyWelcomeCard,
|
|
} as unknown as TSurvey;
|
|
|
|
vi.mocked(getSurvey).mockResolvedValue(mockSurvey);
|
|
|
|
const result = await getBasicSurveyMetadataWithCloudMock(mockSurveyId);
|
|
|
|
expect(result.title).toBe("Test Survey | Formbricks");
|
|
|
|
// Reset the mock
|
|
vi.doMock("@/lib/constants", () => ({
|
|
IS_FORMBRICKS_CLOUD: false,
|
|
WEBAPP_URL: "https://test.formbricks.com",
|
|
}));
|
|
});
|
|
|
|
test("handles welcome card headline with HTML content", async () => {
|
|
const { getTextContent } = await import("@formbricks/types/surveys/validation");
|
|
|
|
const mockSurvey = {
|
|
id: mockSurveyId,
|
|
environmentId: mockEnvironmentId,
|
|
name: "Test Survey",
|
|
metadata: {},
|
|
languages: [],
|
|
welcomeCard: {
|
|
enabled: true,
|
|
timeToFinish: false,
|
|
showResponseCount: false,
|
|
headline: {
|
|
default: "<p>Welcome <strong>Headline</strong></p>",
|
|
},
|
|
html: {
|
|
default: "Welcome Description",
|
|
},
|
|
} as TSurveyWelcomeCard,
|
|
} as unknown as TSurvey;
|
|
|
|
vi.mocked(getSurvey).mockResolvedValue(mockSurvey);
|
|
vi.mocked(getTextContent).mockReturnValue("Welcome Headline");
|
|
|
|
const result = await getBasicSurveyMetadata(mockSurveyId);
|
|
|
|
expect(getTextContent).toHaveBeenCalled();
|
|
expect(result.title).toBe("Welcome Headline");
|
|
});
|
|
|
|
test("handles welcome card headline with recall variables", async () => {
|
|
const { recallToHeadline } = await import("@/lib/utils/recall");
|
|
|
|
const mockSurvey = {
|
|
id: mockSurveyId,
|
|
environmentId: mockEnvironmentId,
|
|
name: "Test Survey",
|
|
metadata: {},
|
|
languages: [],
|
|
welcomeCard: {
|
|
enabled: true,
|
|
timeToFinish: false,
|
|
showResponseCount: false,
|
|
headline: {
|
|
default: "Welcome #recall:name/fallback:User#",
|
|
},
|
|
html: {
|
|
default: "Welcome Description",
|
|
},
|
|
} as TSurveyWelcomeCard,
|
|
} as unknown as TSurvey;
|
|
|
|
vi.mocked(getSurvey).mockResolvedValue(mockSurvey);
|
|
vi.mocked(recallToHeadline).mockReturnValue({
|
|
default: "Welcome @User",
|
|
});
|
|
|
|
const result = await getBasicSurveyMetadata(mockSurveyId);
|
|
|
|
expect(recallToHeadline).toHaveBeenCalledWith(
|
|
mockSurvey.welcomeCard.headline,
|
|
mockSurvey,
|
|
false,
|
|
"default"
|
|
);
|
|
expect(result.title).toBe("Welcome @User");
|
|
});
|
|
});
|
|
|
|
describe("getMetadataBrandColor", () => {
|
|
test("returns survey brand color when project allows override and survey overrides theme", () => {
|
|
const projectStyling = { allowStyleOverwrite: true, brandColor: { light: "#ff0000" } };
|
|
const surveyStyling = { overwriteThemeStyling: true, brandColor: { light: "#0000ff" } };
|
|
|
|
expect(getMetadataBrandColor(projectStyling, surveyStyling as any)).toBe("#0000ff");
|
|
});
|
|
|
|
test("returns project brand color when survey does not override theme", () => {
|
|
const projectStyling = { allowStyleOverwrite: true, brandColor: { light: "#ff0000" } };
|
|
const surveyStyling = { overwriteThemeStyling: false, brandColor: { light: "#0000ff" } };
|
|
|
|
expect(getMetadataBrandColor(projectStyling, surveyStyling as any)).toBe("#ff0000");
|
|
});
|
|
|
|
test("returns project brand color when project disallows style overwrite", () => {
|
|
const projectStyling = { allowStyleOverwrite: false, brandColor: { light: "#ff0000" } };
|
|
const surveyStyling = { overwriteThemeStyling: true, brandColor: { light: "#0000ff" } };
|
|
|
|
expect(getMetadataBrandColor(projectStyling, surveyStyling as any)).toBe("#ff0000");
|
|
});
|
|
|
|
test("returns project brand color when survey styling is null", () => {
|
|
const projectStyling = { allowStyleOverwrite: true, brandColor: { light: "#ff0000" } };
|
|
|
|
expect(getMetadataBrandColor(projectStyling, null)).toBe("#ff0000");
|
|
});
|
|
});
|
|
|
|
describe("getSurveyOpenGraphMetadata", () => {
|
|
test("generates correct OpenGraph metadata", () => {
|
|
const surveyId = "survey-123";
|
|
const surveyName = "Test Survey";
|
|
const brandColor = COLOR_DEFAULTS.brandColor.replace("#", "%23");
|
|
const encodedName = surveyName.replace(/ /g, "%20");
|
|
|
|
const result = getSurveyOpenGraphMetadata(surveyId, surveyName);
|
|
|
|
expect(result).toEqual({
|
|
metadataBase: new URL(getPublicDomain() as any),
|
|
openGraph: {
|
|
title: surveyName,
|
|
description: "Thanks a lot for your time 🙏",
|
|
url: `/s/${surveyId}`,
|
|
siteName: "",
|
|
images: [`/api/v1/client/og?brandColor=${brandColor}&name=${encodedName}`],
|
|
locale: "en_US",
|
|
type: "website",
|
|
},
|
|
twitter: {
|
|
card: "summary_large_image",
|
|
title: surveyName,
|
|
description: "Thanks a lot for your time 🙏",
|
|
images: [`/api/v1/client/og?brandColor=${brandColor}&name=${encodedName}`],
|
|
},
|
|
});
|
|
});
|
|
|
|
test("handles survey names with spaces correctly", () => {
|
|
const surveyId = "survey-123";
|
|
const surveyName = "Test Survey With Spaces";
|
|
const result = getSurveyOpenGraphMetadata(surveyId, surveyName);
|
|
|
|
expect((result.openGraph?.images as string[])?.[0]).toContain("name=Test%20Survey%20With%20Spaces");
|
|
});
|
|
});
|
|
});
|