Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 141 additions & 2 deletions frontend/src/components/GoogleAnalyticsWorkaround.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,27 +153,166 @@ describe("GoogleAnalyticsWorkaround", () => {

expect(scriptContent).toContain("gtag('config', 'G-CUSTOM456'");
});

it("sets debug_mode to false when debugMode prop is false", () => {
render(<GoogleAnalyticsWorkaround gaId="G-TEST123" debugMode={false} />);

const initScript = screen.getByTestId("_next-ga-init");
const scriptContent = initScript.innerHTML;

expect(scriptContent).toContain("'debug_mode': false");
});

it("includes gtag function definition in the init script", () => {
render(<GoogleAnalyticsWorkaround gaId="G-TEST123" />);

const initScript = screen.getByTestId("_next-ga-init");
const scriptContent = initScript.innerHTML;

expect(scriptContent).toContain("function gtag()");
expect(scriptContent).toContain(".push(arguments)");
});

it("includes gtag js call with new Date in the init script", () => {
render(<GoogleAnalyticsWorkaround gaId="G-TEST123" />);

const initScript = screen.getByTestId("_next-ga-init");
const scriptContent = initScript.innerHTML;

expect(scriptContent).toContain("gtag('js', new Date())");
});

it("handles nonce being undefined", () => {
render(<GoogleAnalyticsWorkaround gaId="G-TEST123" nonce={undefined} />);

const initScript = screen.getByTestId("_next-ga-init");
const mainScript = screen.getByTestId("_next-ga");

expect(initScript).toBeInTheDocument();
expect(mainScript).toBeInTheDocument();
});

it("renders correctly with all optional props", () => {
render(
<GoogleAnalyticsWorkaround
gaId="G-ALL-PROPS"
dataLayerName="myLayer"
nonce="my-nonce"
debugMode={true}
/>,
);

const initScript = screen.getByTestId("_next-ga-init");
const mainScript = screen.getByTestId("_next-ga");
const scriptContent = initScript.innerHTML;

expect(initScript).toHaveAttribute("data-nonce", "my-nonce");
expect(mainScript).toHaveAttribute("data-nonce", "my-nonce");
expect(scriptContent).toContain("window['myLayer']");
expect(scriptContent).toContain("'debug_mode': true");
expect(scriptContent).toContain("gtag('config', 'G-ALL-PROPS'");
});
});

describe("sendGAEvent", () => {
let consoleWarnSpy: jest.SpyInstance;
let originalEnv: string | undefined;

beforeEach(() => {
consoleWarnSpy = jest.spyOn(console, "warn").mockImplementation();
originalEnv = process.env.NODE_ENV;
});

afterEach(() => {
consoleWarnSpy.mockRestore();
process.env.NODE_ENV = originalEnv;
});

it("returns early in test environment without calling gtag", () => {
const originalEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "test";

sendGAEvent("event", "test_event", { test: "data" });

expect(consoleWarnSpy).not.toHaveBeenCalled();
});

process.env.NODE_ENV = originalEnv;
it("warns when dataLayer does not exist on window", () => {
process.env.NODE_ENV = "production";

render(<GoogleAnalyticsWorkaround gaId="G-TEST123" />);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).dataLayer;

sendGAEvent("event", "click_event", { button: "submit" });

expect(consoleWarnSpy).toHaveBeenCalledWith(
"@next/third-parties: GA dataLayer dataLayer does not exist",
);
});

it("calls window.gtag when dataLayer exists", () => {
process.env.NODE_ENV = "production";
const mockGtag = jest.fn();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).gtag = mockGtag;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).dataLayer = [];

render(<GoogleAnalyticsWorkaround gaId="G-TEST123" />);

sendGAEvent("event", "conversion", { value: 100, currency: "USD" });

expect(mockGtag).toHaveBeenCalledWith("event", "conversion", {
value: 100,
currency: "USD",
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).gtag;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).dataLayer;
});

it("calls gtag with different event names and arguments", () => {
process.env.NODE_ENV = "production";
const mockGtag = jest.fn();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).gtag = mockGtag;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).dataLayer = [];

render(<GoogleAnalyticsWorkaround gaId="G-TEST123" />);

sendGAEvent("event", "page_view", { page: "/home" });

expect(mockGtag).toHaveBeenCalledWith("event", "page_view", {
page: "/home",
});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).gtag;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).dataLayer;
});

it("handles empty event arguments", () => {
process.env.NODE_ENV = "production";
const mockGtag = jest.fn();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).gtag = mockGtag;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).dataLayer = [];

render(<GoogleAnalyticsWorkaround gaId="G-TEST123" />);

sendGAEvent("event", "simple_event", {});

expect(mockGtag).toHaveBeenCalledWith("event", "simple_event", {});

// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).gtag;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
delete (window as any).dataLayer;
});
});
Loading