addition of new dashboard
This commit is contained in:
131
frontend/tests/e2e/smoke.spec.js
Normal file
131
frontend/tests/e2e/smoke.spec.js
Normal file
@@ -0,0 +1,131 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
|
||||
// API responses mocked in the SAME envelope shapes the real backend returns
|
||||
// (verified against /api/v1/data/dashboard/*). The smoke asserts each panel
|
||||
// consumes the contract and renders DATA — and that interactions (verify) work —
|
||||
// not just that containers exist.
|
||||
const EVENT_ID = "f6a042ca-efbf-4c4d-b99c-dac41373eb63";
|
||||
|
||||
const MOCKS = {
|
||||
"/api/dashboard/whoami": { username: "dev", modules: ["core", "archive"] },
|
||||
"/api/dashboard/summary": {
|
||||
apiUsage: { core: 2005, audit: 2002, total: 4007 },
|
||||
apiKeys: 2,
|
||||
endpoints: 2,
|
||||
storage: {
|
||||
onDisk: { core: 353712, audit: 1321330, total: 1675042 },
|
||||
logical: { core: 349712, audit: 1311320, total: 1661032 },
|
||||
},
|
||||
},
|
||||
"/api/dashboard/usage-series": {
|
||||
series: [
|
||||
{ date: "2026-06-20", core: 76, audit: 0, total: 76 },
|
||||
{ date: "2026-06-21", core: 64, audit: 0, total: 64 },
|
||||
],
|
||||
},
|
||||
"/api/dashboard/storage-series": {
|
||||
series: [
|
||||
{ date: "2026-06-20", coreDisk: 322617, auditDisk: 0, totalDisk: 322617 },
|
||||
{ date: "2026-06-21", coreDisk: 333904, auditDisk: 0, totalDisk: 333904 },
|
||||
],
|
||||
},
|
||||
"/api/dashboard/keys": [],
|
||||
};
|
||||
|
||||
const coreRow = {
|
||||
eventUuid: EVENT_ID,
|
||||
sender: "did:jlinc:sender",
|
||||
receiver: "did:jlinc:receiver",
|
||||
date: "2026-06-23T11:37:40.664Z",
|
||||
agreementUuid: "9ab250b9-b3e3-48aa-1111-222233334444",
|
||||
size: 655,
|
||||
};
|
||||
// Two audit records for ONE event (produce + process): same eventUuid, distinct
|
||||
// auditId. On the audit tab it is auditId — not eventUuid — that identifies a row.
|
||||
const auditRows = [
|
||||
{ ...coreRow, auditId: 9, auditDigest: "572b052a11aa" },
|
||||
{ ...coreRow, auditId: 10, auditDigest: "4029d4a6da22" },
|
||||
];
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.route("**/api/dashboard/**", async (route) => {
|
||||
const url = new URL(route.request().url());
|
||||
const path = url.pathname;
|
||||
if (path === "/api/dashboard/transactions") {
|
||||
const audit = url.searchParams.get("type") === "audit";
|
||||
return route.fulfill({
|
||||
json: audit
|
||||
? { rows: auditRows, total: 2, limit: 50, offset: 0 }
|
||||
: { rows: [coreRow], total: 1, limit: 50, offset: 0 },
|
||||
});
|
||||
}
|
||||
if (path === "/api/dashboard/verify") {
|
||||
const list = (k) => (url.searchParams.get(k) || "").split(",").filter(Boolean);
|
||||
const pass = (extra) => ({ status: "verified", verified: true, signatureCount: 1, auditCount: 1, checks: { validId: true }, ...extra });
|
||||
return route.fulfill({
|
||||
json: {
|
||||
results: [
|
||||
...list("ids").map((eventUuid) => pass({ eventUuid, auditId: null })),
|
||||
// Audit 9 passes, audit 10 fails. Two rows of the SAME event getting
|
||||
// different verdicts is only expressible if each row is its own
|
||||
// verification target.
|
||||
...list("auditIds").map(Number).map((auditId) =>
|
||||
auditId === 9
|
||||
? pass({ eventUuid: EVENT_ID, auditId })
|
||||
: { eventUuid: EVENT_ID, auditId, status: "invalid", verified: false, signatureCount: 1, auditCount: 1, checks: { validAuditHash: false } }),
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
if (Object.prototype.hasOwnProperty.call(MOCKS, path)) return route.fulfill({ json: MOCKS[path] });
|
||||
return route.fulfill({ json: {} });
|
||||
});
|
||||
});
|
||||
|
||||
test("dashboard panels render real data from the API contract", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await expect(page.locator("#api-usage-total")).toHaveText(/\d/, { timeout: 10_000 });
|
||||
await expect(page.locator("#storage-total")).toHaveText(/\d/);
|
||||
await expect(page.locator("#usage-chart svg")).toBeAttached({ timeout: 10_000 });
|
||||
await expect(page.locator("#transaction-rows tr[data-event-id]")).toHaveCount(1);
|
||||
});
|
||||
|
||||
test("Audit tab: verifying one row badges ONLY that row", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await page.locator("#tab-audit").click();
|
||||
// Two audit records share one event UUID; each is its own row.
|
||||
const rows = page.locator("#transaction-rows tr[data-event-id]");
|
||||
await expect(rows).toHaveCount(2);
|
||||
|
||||
// The bug: clicking Verify on one row badged BOTH, because rows were keyed by
|
||||
// the event UUID they share. The request must target the row's audit id.
|
||||
const [request] = await Promise.all([
|
||||
page.waitForRequest((r) => r.url().includes("/api/dashboard/verify")),
|
||||
rows.nth(0).locator(".btn-verify").click(),
|
||||
]);
|
||||
expect(new URL(request.url()).searchParams.get("auditIds")).toBe("9");
|
||||
|
||||
await expect(rows.nth(0).locator(".verify-badge")).toContainText("Verified");
|
||||
await expect(rows.nth(1).locator(".verify-badge")).toBeHidden();
|
||||
});
|
||||
|
||||
test("Audit tab: Validate All gives each audit row its own verdict", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await page.locator("#tab-audit").click();
|
||||
await expect(page.locator("#transaction-rows tr[data-event-id]")).toHaveCount(2);
|
||||
|
||||
await page.locator("#validate-all").click();
|
||||
|
||||
// Same event, different audit records -> independent results. A per-event
|
||||
// verification could not produce two different badges here.
|
||||
const rows = page.locator("#transaction-rows tr[data-event-id]");
|
||||
await expect(rows.nth(0).locator(".verify-badge")).toContainText("Verified");
|
||||
await expect(rows.nth(1).locator(".verify-badge")).toContainText("Invalid");
|
||||
});
|
||||
|
||||
test("sidebar switches to the API Keys view", async ({ page }) => {
|
||||
await page.goto("/");
|
||||
await expect(page.locator("#api-keys-view")).toBeAttached();
|
||||
await page.locator("#nav-api-keys").click();
|
||||
await expect(page.locator("#api-keys-view")).toBeVisible();
|
||||
});
|
||||
Reference in New Issue
Block a user