Files
pleno-vue/tests/unit/edge-gateway-logs-redaction.spec.js
T

109 lines
3.8 KiB
JavaScript

// @vitest-environment jsdom
import { mount } from "@vue/test-utils";
import { describe, expect, it, vi } from "vitest";
import EdgeGatewayLogsPage from "@/features/edgeGateways/EdgeGatewayLogsPage.vue";
const flushMicrotasks = async () => {
await Promise.resolve();
await Promise.resolve();
};
describe("EdgeGatewayLogsPage context redaction", () => {
it("redacts sensitive timeline context values before modal display and clipboard copy", async () => {
const writeText = vi.fn(() => Promise.resolve());
Object.defineProperty(navigator, "clipboard", {
configurable: true,
value: { writeText },
});
const wrapper = mount(EdgeGatewayLogsPage, {
props: {
timeline: [
{
type: "log",
level: "INFO",
message: "Connected to broker",
created_at: "2026-06-01T10:00:00Z",
context: {
ws_url: "wss://broker.example/ws?token=raw-token&agentToken=raw-agent-token&connection=42",
installer_token: "raw-installer-token",
broker_shared_secret: "raw-broker-secret",
nested: {
callback: "/edge/callback?agent_token=raw-query-token&visible=true",
safe_label: "visible diagnostic value",
},
},
},
],
},
attachTo: document.body,
});
await wrapper.get('[data-testid="gateway-log-entry-0"]').trigger("click");
await wrapper.get('[data-testid="gateway-log-entry-context-view-0"]').trigger("click");
const modalText = wrapper.get('[data-testid="gateway-context-modal-body"]').text();
expect(modalText).toContain("visible diagnostic value");
expect(modalText).toContain("[REDACTED]");
expect(modalText).not.toContain("raw-token");
expect(modalText).not.toContain("raw-agent-token");
expect(modalText).not.toContain("raw-installer-token");
expect(modalText).not.toContain("raw-broker-secret");
expect(modalText).not.toContain("raw-query-token");
await wrapper.get('[data-testid="gateway-context-modal-copy"]').trigger("click");
await flushMicrotasks();
expect(writeText).toHaveBeenCalledTimes(1);
expect(writeText.mock.calls[0][0]).toBe(modalText);
expect(writeText.mock.calls[0][0]).not.toContain("raw-token");
});
it("redacts sensitive relay context values before direct clipboard copy", async () => {
const writeText = vi.fn(() => Promise.resolve());
Object.defineProperty(navigator, "clipboard", {
configurable: true,
value: { writeText },
});
const wrapper = mount(EdgeGatewayLogsPage, {
props: {
relayLogs: [
{
id: 12,
message: "Relay dispatched",
created_at: "2026-06-01T10:01:00Z",
context: {
handler: "broker",
signal: {
request: { on: true },
},
response: { online: true, on: true },
relay_token: "raw-relay-token",
command_payload: {
authorization: "Bearer raw-auth-token",
target: "machine-1",
},
broker_url: "https://broker.example/relay?secret=raw-url-secret&relay=7",
},
},
],
},
attachTo: document.body,
});
await wrapper.get('[data-testid="gateway-relay-entry-0"]').trigger("click");
await wrapper.get('[data-testid="gateway-relay-entry-context-copy-0"]').trigger("click");
await flushMicrotasks();
expect(writeText).toHaveBeenCalledTimes(1);
const copiedText = writeText.mock.calls[0][0];
expect(copiedText).toContain("machine-1");
expect(copiedText).toContain("[REDACTED]");
expect(copiedText).not.toContain("raw-relay-token");
expect(copiedText).not.toContain("raw-auth-token");
expect(copiedText).not.toContain("raw-url-secret");
});
});