Skip to content
This repository was archived by the owner on Nov 28, 2025. It is now read-only.

Commit 19ede74

Browse files
authored
fix: ga check (#8)
1 parent 7b1d9bd commit 19ede74

2 files changed

Lines changed: 39 additions & 19 deletions

File tree

src/analytics/analytics.test.ts

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { validatePageViewEvent, validateGaEvent, gaPageView, gaEvent } from "./analytics";
1+
import { validateGtag, validatePageViewEvent, validateGaEvent, gaPageView, gaEvent } from "./analytics";
22

3-
const consoleSpy = jest.spyOn(console, "error");
3+
const consoleError = jest.spyOn(console, "error");
4+
const consoleWarn = jest.spyOn(console, "warn");
45
const GA_MEASUREMENT_ID = "G-123456789";
56
const mockGaEvent = {
67
action: "TEST_ACTION",
@@ -12,18 +13,28 @@ const mockGaEvent = {
1213
beforeEach(() => {
1314
// eslint-disable-next-line @typescript-eslint/no-empty-function
1415
jest.spyOn(console, "error").mockImplementation(() => {});
16+
// eslint-disable-next-line @typescript-eslint/no-empty-function
17+
jest.spyOn(console, "warn").mockImplementation(() => {});
1518
});
1619

1720
afterEach(() => {
1821
jest.clearAllMocks();
1922
});
2023

24+
describe("validateGtag", () => {
25+
it("warns if gtag is not initialised", () => {
26+
validateGtag();
27+
expect(consoleWarn).toBeCalledTimes(1);
28+
expect(consoleWarn).toHaveBeenCalledWith("gtag is not initialised");
29+
});
30+
});
31+
2132
describe("validateGaPageView", () => {
22-
it("throws if action is missing", () => {
33+
it("errors if action is missing", () => {
2334
// @ts-expect-error we expect this error to be thrown
2435
validatePageViewEvent({});
25-
expect(consoleSpy).toBeCalledTimes(1);
26-
expect(consoleSpy).toHaveBeenCalledWith("Action is required");
36+
expect(consoleError).toBeCalledTimes(1);
37+
expect(consoleError).toHaveBeenCalledWith("Action is required");
2738
});
2839
});
2940

@@ -50,39 +61,39 @@ describe("gaPageView", () => {
5061
});
5162
});
5263

53-
it("throws if there is a validation error", () => {
64+
it("errors if there is a validation error", () => {
5465
const mockGaEventError = { action: 123 };
5566
// @ts-expect-error the mock does not match the signature
5667
gaPageView(mockGaEventError);
57-
expect(consoleSpy).toBeCalledTimes(1);
58-
expect(consoleSpy).toHaveBeenCalledWith("Action must be a string");
68+
expect(consoleError).toBeCalledTimes(1);
69+
expect(consoleError).toHaveBeenCalledWith("Action must be a string");
5970
});
6071
});
6172

6273
describe("validateGaEvent", () => {
63-
it("throws if category is missing", () => {
74+
it("errors if category is missing", () => {
6475
// @ts-expect-error we expect this error to be thrown
6576
validateGaEvent({
6677
action: "foobar_start",
6778
});
68-
expect(consoleSpy).toBeCalledTimes(1);
69-
expect(consoleSpy).toHaveBeenCalledWith("Category is required");
79+
expect(consoleError).toBeCalledTimes(1);
80+
expect(consoleError).toHaveBeenCalledWith("Category is required");
7081
});
7182

72-
it("throws if action is missing", () => {
83+
it("errors if action is missing", () => {
7384
// @ts-expect-error we expect this error to be thrown
7485
validateGaEvent({
7586
category: "foobar",
7687
});
77-
expect(consoleSpy).toBeCalledTimes(1);
78-
expect(consoleSpy).toHaveBeenCalledWith("Action is required");
88+
expect(consoleError).toBeCalledTimes(1);
89+
expect(consoleError).toHaveBeenCalledWith("Action is required");
7990
});
8091

81-
it("throws if value is not number", () => {
92+
it("errors if value is not number", () => {
8293
// @ts-expect-error we expect this error to be thrown
8394
validateGaEvent({ category: "foobar", action: "foobar_start", value: "STRING" });
84-
expect(consoleSpy).toBeCalledTimes(1);
85-
expect(consoleSpy).toHaveBeenCalledWith("Value must be a number");
95+
expect(consoleError).toBeCalledTimes(1);
96+
expect(consoleError).toHaveBeenCalledWith("Value must be a number");
8697
});
8798

8899
it("passes for minimum values", () => {
@@ -135,7 +146,7 @@ describe("gaEvent", () => {
135146
const mockGaEventError = { ...mockGaEvent, value: "STRING" };
136147
// @ts-expect-error the mock does not match the signature
137148
gaEvent(mockGaEventError);
138-
expect(consoleSpy).toBeCalledTimes(1);
139-
expect(consoleSpy).toHaveBeenCalledWith("Value must be a number");
149+
expect(consoleError).toBeCalledTimes(1);
150+
expect(consoleError).toHaveBeenCalledWith("Value must be a number");
140151
});
141152
});

src/analytics/analytics.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,23 @@ interface GaPageViewProps {
1111
action: GaActionDefault;
1212
}
1313

14+
export const validateGtag = (): boolean => {
15+
const isInit = typeof gtag === "function";
16+
if (!isInit) console.warn("gtag is not initialised");
17+
return isInit;
18+
};
19+
1420
export const validatePageViewEvent = (gaEvent: GaPageViewProps): void => {
1521
const { action } = gaEvent;
1622
if (!action) console.error("Action is required");
1723
if (action && typeof action !== "string") console.error("Action must be a string");
1824
};
1925

2026
export const gaPageView = (gaEvent: GaPageViewProps, gaId: string): void => {
27+
if (!validateGtag()) return;
2128
validatePageViewEvent(gaEvent);
2229
const { action } = gaEvent;
30+
2331
gtag("event", action, {
2432
send_to: gaId,
2533
});
@@ -34,6 +42,7 @@ export const validateGaEvent = (gaEvent: GaEventProps): void => {
3442
};
3543

3644
export const gaEvent = (gaEvent: GaEventProps): void => {
45+
if (!validateGtag()) return;
3746
validateGaEvent(gaEvent);
3847
const { action, category, label, value } = gaEvent;
3948

0 commit comments

Comments
 (0)