UNPKG

@ogcio/o11y-sdk-react

Version:

Opentelemetry standard instrumentation SDK for React based project

150 lines (131 loc) 4.05 kB
import { LogEvent, LogLevel, TransportItem, TransportItemType, } from "@grafana/faro-web-sdk"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { _beforeSend } from "../../lib/internals/hooks"; // Mock faro.api.pushMeasurement vi.mock("@grafana/faro-web-sdk", async () => { const actual = await vi.importActual<any>("@grafana/faro-web-sdk"); return { ...actual, faro: { api: { pushMeasurement: vi.fn(), }, }, }; }); import { faro } from "@grafana/faro-web-sdk"; describe("_beforeSend", () => { beforeEach(() => { vi.clearAllMocks(); }); it("should deeply redact PII in object", () => { const item = { type: TransportItemType.LOG, payload: { level: LogLevel.INFO, context: {}, timestamp: Date.now().toString(), message: "my email is bob@abc.com", }, meta: { user: { email: "carol@abc.com", attributes: { alternative_email: "foo@xyz.org", }, }, }, } satisfies TransportItem<LogEvent>; const redacted: TransportItem<LogEvent> = _beforeSend( item, ) as TransportItem<LogEvent>; expect(redacted.payload.message).toBe("my email is [REDACTED EMAIL]"); expect(redacted.meta.user).not.toBeNull(); expect(redacted.meta.user!.email).toBe("[REDACTED EMAIL]"); expect(redacted.meta.user!.attributes).toBeDefined(); expect(redacted.meta.user!.attributes!["alternative_email"]).toBe( "[REDACTED EMAIL]", ); expect(faro.api.pushMeasurement).toHaveBeenCalledTimes(3); }); it("should redact email inside arrays of primitives", () => { const item: TransportItem<LogEvent> = { type: TransportItemType.LOG, payload: { message: "start", context: { messages: ["hello", "email: test@abc.com", "ok"], }, timestamp: "123", level: LogLevel.INFO, }, }; const redacted = _beforeSend(item)!; expect(redacted.payload.context.messages[1]).toBe( "email: [REDACTED EMAIL]", ); expect(faro.api.pushMeasurement).toHaveBeenCalledOnce(); }); it("should redact emails in arrays of objects", () => { const item: TransportItem<LogEvent> = { type: TransportItemType.LOG, payload: { message: "checking", context: { events: [ { message: "contact a@b.com" }, { message: "nothing here" }, { note: "try c@d.net" }, ], }, timestamp: "123", level: LogLevel.INFO, }, }; const redacted = _beforeSend(item)!; expect(redacted.payload.context.events[0].message).toBe( "contact [REDACTED EMAIL]", ); expect(redacted.payload.context.events[2].note).toBe( "try [REDACTED EMAIL]", ); expect(faro.api.pushMeasurement).toHaveBeenCalledTimes(2); }); it("should not break on nulls, undefined, numbers, booleans", () => { const item: TransportItem<LogEvent> = { type: TransportItemType.LOG, payload: { message: null as any, count: 123, active: true, description: undefined, } as any, meta: null, }; const redacted = _beforeSend(item)!; expect(redacted.payload.message).toBeNull(); expect(redacted.payload.count).toBe(123); expect(redacted.payload.active).toBe(true); expect("description" in redacted.payload).toBe(true); // still defined as undefined expect(faro.api.pushMeasurement).not.toHaveBeenCalled(); }); it("should decode and redact encoded emails", () => { const item: TransportItem<LogEvent> = { type: TransportItemType.LOG, payload: { message: "contact%20user%40domain.com", level: LogLevel.INFO, context: {}, timestamp: "now", }, }; const redacted = _beforeSend(item)!; expect(redacted.payload.message).toBe("contact [REDACTED EMAIL]"); expect(faro.api.pushMeasurement).toHaveBeenCalledOnce(); }); });