feat: rebuild landing experience, content and analytics
This commit is contained in:
1 parent
d24ee12299
commit
9aff4d1035
51 files changed
+3023
-2595
No files matched your search
@@ -0,0 +1,151 @@
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import WhatsAppLink from "./WhatsAppLink";
|
||||
|
||||
const CONSENT_KEY = "evandro.analytics-consent.v1";
|
||||
const DISABLE_KEY = "ga-disable-G-QTT9QT0T3S";
|
||||
|
||||
beforeEach(() => {
|
||||
jest.replaceProperty(process.env, "NODE_ENV", "production");
|
||||
localStorage.clear();
|
||||
window.gtag = jest.fn();
|
||||
delete window[DISABLE_KEY];
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
"/[email protected]#private",
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
delete window.gtag;
|
||||
delete window[DISABLE_KEY];
|
||||
localStorage.clear();
|
||||
window.history.replaceState({}, "", "/");
|
||||
});
|
||||
|
||||
function renderLink() {
|
||||
render(
|
||||
<WhatsAppLink service="Sistemas web" placement="service_hub_hero">
|
||||
Conversar no WhatsApp
|
||||
</WhatsAppLink>,
|
||||
);
|
||||
return screen.getByRole("link", { name: "Conversar no WhatsApp" });
|
||||
}
|
||||
|
||||
it.each([null, "denied", "{malformed", '"granted"'])(
|
||||
"keeps a native destination without collecting or replaying when consent is %s",
|
||||
async (consent) => {
|
||||
if (consent !== null) localStorage.setItem(CONSENT_KEY, consent);
|
||||
const link = renderLink();
|
||||
const url = new URL(link.getAttribute("href") || "");
|
||||
expect(url.origin).toBe("https://wa.me");
|
||||
expect(url.pathname).toMatch(/^\/\d+$/);
|
||||
expect(url.searchParams.get("text")).toContain("Sistemas web");
|
||||
expect(link).toHaveAttribute("target", "_blank");
|
||||
expect(link).toHaveAttribute("rel", "noopener noreferrer");
|
||||
expect(fireEvent.click(link, { button: 0 })).toBe(true);
|
||||
expect(window.gtag).not.toHaveBeenCalled();
|
||||
|
||||
localStorage.setItem(CONSENT_KEY, "granted");
|
||||
await Promise.resolve();
|
||||
expect(window.gtag).not.toHaveBeenCalled();
|
||||
fireEvent.click(link, { button: 0 });
|
||||
expect(window.gtag).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
);
|
||||
|
||||
it("emits one GA4 handoff per primary, middle or keyboard activation without personal URL data", async () => {
|
||||
const user = userEvent.setup();
|
||||
localStorage.setItem(CONSENT_KEY, "granted");
|
||||
const link = renderLink();
|
||||
await user.click(link);
|
||||
expect(window.gtag).toHaveBeenCalledTimes(1);
|
||||
expect(window.gtag).toHaveBeenLastCalledWith("event", "whatsapp_open", {
|
||||
send_to: "G-QTT9QT0T3S",
|
||||
service: "Sistemas web",
|
||||
placement: "service_hub_hero",
|
||||
page_path: "/servicos",
|
||||
page_location: "https://evandro.dev.br/servicos",
|
||||
page_referrer: "",
|
||||
});
|
||||
|
||||
expect(
|
||||
fireEvent(
|
||||
link,
|
||||
new MouseEvent("auxclick", {
|
||||
button: 1,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
}),
|
||||
),
|
||||
).toBe(true);
|
||||
expect(window.gtag).toHaveBeenCalledTimes(2);
|
||||
fireEvent(link, new MouseEvent("auxclick", { button: 2, bubbles: true }));
|
||||
expect(window.gtag).toHaveBeenCalledTimes(2);
|
||||
link.focus();
|
||||
await user.keyboard("{Enter}");
|
||||
expect(window.gtag).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("stops collecting immediately after revocation and honors the GA disabled flag", () => {
|
||||
localStorage.setItem(CONSENT_KEY, "granted");
|
||||
const link = renderLink();
|
||||
fireEvent.click(link, { button: 0 });
|
||||
expect(window.gtag).toHaveBeenCalledTimes(1);
|
||||
|
||||
localStorage.setItem(CONSENT_KEY, "denied");
|
||||
expect(fireEvent.click(link, { button: 0 })).toBe(true);
|
||||
expect(window.gtag).toHaveBeenCalledTimes(1);
|
||||
|
||||
localStorage.setItem(CONSENT_KEY, "granted");
|
||||
window[DISABLE_KEY] = true;
|
||||
expect(fireEvent.click(link, { button: 0 })).toBe(true);
|
||||
expect(window.gtag).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("keeps navigation available when storage, analytics or its loader is blocked", () => {
|
||||
localStorage.setItem(CONSENT_KEY, "granted");
|
||||
const link = renderLink();
|
||||
const storage = jest
|
||||
.spyOn(Storage.prototype, "getItem")
|
||||
.mockImplementation(() => {
|
||||
throw new Error("storage blocked");
|
||||
});
|
||||
expect(fireEvent.click(link, { button: 0 })).toBe(true);
|
||||
expect(window.gtag).not.toHaveBeenCalled();
|
||||
storage.mockRestore();
|
||||
|
||||
delete window.gtag;
|
||||
expect(fireEvent.click(link, { button: 0 })).toBe(true);
|
||||
window.gtag = jest.fn(() => {
|
||||
throw new Error("analytics blocked");
|
||||
});
|
||||
expect(fireEvent.click(link, { button: 0 })).toBe(true);
|
||||
});
|
||||
|
||||
it("does not collect outside production", () => {
|
||||
jest.replaceProperty(process.env, "NODE_ENV", "development");
|
||||
localStorage.setItem(CONSENT_KEY, "granted");
|
||||
expect(fireEvent.click(renderLink(), { button: 0 })).toBe(true);
|
||||
expect(window.gtag).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("uses a route template rather than collecting arbitrary dynamic path segments", () => {
|
||||
localStorage.setItem(CONSENT_KEY, "granted");
|
||||
window.history.replaceState(
|
||||
{},
|
||||
"",
|
||||
"/servicos/ana%40example.com?message=private",
|
||||
);
|
||||
fireEvent.click(renderLink(), { button: 0 });
|
||||
expect(window.gtag).toHaveBeenCalledWith("event", "whatsapp_open", {
|
||||
send_to: "G-QTT9QT0T3S",
|
||||
service: "Sistemas web",
|
||||
placement: "service_hub_hero",
|
||||
page_path: "/servicos/[slug]",
|
||||
page_location: "https://evandro.dev.br/servicos/[slug]",
|
||||
page_referrer: "",
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user