diff --git a/apps/dashboard/src/components/chat/tool-renderers/list-tables.test.tsx b/apps/dashboard/src/components/chat/tool-renderers/list-tables.test.tsx index a0c966e13..08a247974 100644 --- a/apps/dashboard/src/components/chat/tool-renderers/list-tables.test.tsx +++ b/apps/dashboard/src/components/chat/tool-renderers/list-tables.test.tsx @@ -97,7 +97,7 @@ describe("listPageComponentsTable", () => { it("shows the monitor id, or a placeholder for static components", () => { expect(text(table.rows[0].cells.monitor)).toContain("4"); - expect(text(table.rows[1].cells.monitor)).not.toContain("4"); + expect(text(table.rows[1].cells.monitor).trim()).toBe("-"); }); }); diff --git a/apps/dashboard/src/components/chat/tool-renderers/registry.test.tsx b/apps/dashboard/src/components/chat/tool-renderers/registry.test.tsx index ffb087db2..40e7a274a 100644 --- a/apps/dashboard/src/components/chat/tool-renderers/registry.test.tsx +++ b/apps/dashboard/src/components/chat/tool-renderers/registry.test.tsx @@ -39,7 +39,9 @@ describe("summarizeToolOutput", () => { }); it("prefers the search error over the count", () => { - expect(summarizeToolOutput("search_docs", { error: "down" })).toBe("down"); + expect( + summarizeToolOutput("search_docs", { error: "down", results: [{}] }), + ).toBe("down"); expect(summarizeToolOutput("search_docs", { results: [{}] })).toBe( "1 result", ); diff --git a/apps/dashboard/src/components/command-menu/groups/static.test.ts b/apps/dashboard/src/components/command-menu/groups/static.test.ts index 5150cbf8a..4df096607 100644 --- a/apps/dashboard/src/components/command-menu/groups/static.test.ts +++ b/apps/dashboard/src/components/command-menu/groups/static.test.ts @@ -26,8 +26,19 @@ describe("navigationGroup", () => { }); it("navigates to each item's href", () => { - const overview = navigationGroup().items[0]; - expect(overview.action).toEqual({ type: "navigate", href: "/overview" }); + expect(navigationGroup().items.map((item) => item.action)).toEqual( + [ + "/overview", + "/incidents", + "/monitors", + "/status-pages", + "/notifications", + "/chat", + "/agents/slack", + "/agents/cli", + "/agents/mcp", + ].map((href) => ({ type: "navigate", href })), + ); }); it("keeps values unique", () => { diff --git a/apps/dashboard/src/components/common/status-badge.test.tsx b/apps/dashboard/src/components/common/status-badge.test.tsx index 2cc4b7c9a..e504b0430 100644 --- a/apps/dashboard/src/components/common/status-badge.test.tsx +++ b/apps/dashboard/src/components/common/status-badge.test.tsx @@ -20,7 +20,7 @@ describe("StatusBadge", () => { Up , ); - expect(html).not.toContain("bg-success/10"); + expect(html).not.toMatch(/bg-(?:success|warning|destructive|info)\/10/); expect(html).toMatch(/data-slot="status-dot"[^>]*bg-success/); }); diff --git a/apps/dashboard/src/components/data-table/table-cell-metadata.test.tsx b/apps/dashboard/src/components/data-table/table-cell-metadata.test.tsx index cf2650137..87eb14ab9 100644 --- a/apps/dashboard/src/components/data-table/table-cell-metadata.test.tsx +++ b/apps/dashboard/src/components/data-table/table-cell-metadata.test.tsx @@ -39,6 +39,9 @@ describe("TableCellMetadata", () => { const html = renderToStaticMarkup( , ); + for (const part of ["a", "1", "b", "2"]) { + expect(html).toContain(`>${part}<`); + } expect(html).not.toMatch(/>\+\d+ { statusReportUpdates: [ { id: 10, + message: "Investigating", statusReportUpdateToPageComponents: [ { pageComponentId: 2, impact: "major_outage" as const }, { pageComponentId: 1, impact: "operational" as const }, @@ -22,6 +23,7 @@ describe("updatesWithImpactChanges", () => { }); expect(result).toHaveLength(1); expect(result[0].id).toBe(10); + expect(result[0].message).toBe("Investigating"); expect(result[0].impactChanges).toEqual([ { name: "Dashboard", impact: "major_outage" }, { name: "API", impact: "operational" }, diff --git a/apps/status-page/src/test/next-navigation.mock.ts b/apps/status-page/src/test/next-navigation.mock.ts index c5a9a0bc7..d41c6efd7 100644 --- a/apps/status-page/src/test/next-navigation.mock.ts +++ b/apps/status-page/src/test/next-navigation.mock.ts @@ -39,6 +39,10 @@ export function useSearchParams() { return navigationState.searchParams; } +export function unauthorized(): never { + throw new Error("NEXT_UNAUTHORIZED"); +} + export function notFound(): never { throw new Error("NEXT_NOT_FOUND"); } diff --git a/apps/web/src/lib/checker/utils.ts b/apps/web/src/lib/checker/utils.ts index ffe605602..f649dcc80 100644 --- a/apps/web/src/lib/checker/utils.ts +++ b/apps/web/src/lib/checker/utils.ts @@ -18,7 +18,7 @@ const RAILWAY_CHECKER_URL = // ============================================================================ export function latencyFormatter(value: number) { - return `${new Intl.NumberFormat("us").format(value).toString()}ms`; + return `${new Intl.NumberFormat("en-US").format(value).toString()}ms`; } export function timestampFormatter(timestamp: number) { diff --git a/apps/web/src/lib/monitor/utils.test.ts b/apps/web/src/lib/monitor/utils.test.ts index e4670e4a8..63f24b517 100644 --- a/apps/web/src/lib/monitor/utils.test.ts +++ b/apps/web/src/lib/monitor/utils.test.ts @@ -1,5 +1,6 @@ import { expect } from "@std/expect"; import { describe, test } from "@std/testing/bdd"; +import { FakeTime } from "@std/testing/time"; import { getDateByPeriod, @@ -26,24 +27,39 @@ describe("periodFormatter", () => { }); describe("getDateByPeriod", () => { - test("covers the period's hours and ends at the end of today", () => { + // mid-June, local time, so no DST transition falls inside any period + const now = new Date(2024, 5, 15, 13, 27, 45, 123); + + function at(fn: () => T) { + const time = new FakeTime(now); + try { + return fn(); + } finally { + time.restore(); + } + } + + test("ends every period at the end of today", () => { for (const period of periods) { - const { from, to } = getDateByPeriod(period); - const end = new Date(); - end.setHours(23, 59, 59, 999); - expect(to.getTime()).toBe(end.getTime()); - const hours = (to.getTime() - from.getTime()) / 3_600_000; - expect(hours).toBeGreaterThanOrEqual(getHoursByPeriod(period)); - expect(hours).toBeLessThanOrEqual(getHoursByPeriod(period) + 49); + expect(at(() => getDateByPeriod(period)).to).toEqual( + new Date(2024, 5, 15, 23, 59, 59, 999), + ); } }); - test("starts 1d on an hour boundary and longer periods at midnight", () => { - expect(getDateByPeriod("1d").from.getMinutes()).toBe(0); - for (const period of ["7d", "14d"] as const) { - const { from } = getDateByPeriod(period); - expect([from.getHours(), from.getMinutes()]).toEqual([0, 0]); - } + test("starts 1d a day before the current hour", () => { + expect(at(() => getDateByPeriod("1d")).from).toEqual( + new Date(2024, 5, 14, 13, 0, 0, 0), + ); + }); + + test("starts longer periods at midnight, n days back", () => { + expect(at(() => getDateByPeriod("7d")).from).toEqual( + new Date(2024, 5, 8, 0, 0, 0, 0), + ); + expect(at(() => getDateByPeriod("14d")).from).toEqual( + new Date(2024, 5, 1, 0, 0, 0, 0), + ); }); }); diff --git a/packages/tracker/src/utils.test.ts b/packages/tracker/src/utils.test.ts index c2d9b5a51..6615cc76f 100644 --- a/packages/tracker/src/utils.test.ts +++ b/packages/tracker/src/utils.test.ts @@ -54,8 +54,8 @@ describe("isSameDay", () => { test("compares in UTC regardless of the input offset", () => { expect( isSameDay( - new Date("2024-03-10T23:30:00-05:00"), - new Date("2024-03-11T04:30:00Z"), + new Date("2024-03-10T20:00:00-05:00"), + new Date("2024-03-11T23:30:00Z"), ), ).toBe(true); });