diff --git a/internal/site/src/lib/network-monitor-utils.ts b/internal/site/src/lib/network-monitor-utils.ts
index 4f4e49f6c..dcbf2dffc 100644
--- a/internal/site/src/lib/network-monitor-utils.ts
+++ b/internal/site/src/lib/network-monitor-utils.ts
@@ -1,12 +1,16 @@
import type { MonitorCertInfo, MonitorStats, NetworkMonitorRecord, RawMonitorStatsRecord } from "@/types"
+import { toFixedFloat } from "./utils"
/** Derive chart metrics from the counts and response sum stored at every retention tier. */
export function getMonitorStats(record: RawMonitorStatsRecord): MonitorStats {
return {
- res_avg: record.success_count > 0 ? record.res_sum / record.success_count : 0,
+ res_avg: record.success_count > 0 ? toFixedFloat(record.res_sum / record.success_count, 2) : 0,
res_min: record.res_min,
res_max: record.res_max,
- loss: record.total_count > 0 ? ((record.total_count - record.success_count) / record.total_count) * 100 : 0,
+ loss:
+ record.total_count > 0
+ ? toFixedFloat(((record.total_count - record.success_count) / record.total_count) * 100, 2)
+ : 0,
}
}
diff --git a/internal/site/src/lib/utils.ts b/internal/site/src/lib/utils.ts
index f9050c4c5..4860c7060 100644
--- a/internal/site/src/lib/utils.ts
+++ b/internal/site/src/lib/utils.ts
@@ -111,18 +111,17 @@ export const updateFavicon = (() => {
- ${
- downCount > 0 &&
- `
+ ${downCount > 0 &&
+ `
${downCount}
`
- }
+ }
`
const blob = new Blob([svg], { type: "image/svg+xml" })
const url = URL.createObjectURL(blob)
- ;(document.querySelector("link[rel='icon']") as HTMLLinkElement).href = url
+ ; (document.querySelector("link[rel='icon']") as HTMLLinkElement).href = url
}
})()
diff --git a/internal/site/tests/network-monitor-utils.test.ts b/internal/site/tests/network-monitor-utils.test.ts
index 80aeec4fa..f58dd38eb 100644
--- a/internal/site/tests/network-monitor-utils.test.ts
+++ b/internal/site/tests/network-monitor-utils.test.ts
@@ -1,5 +1,11 @@
-import { describe, expect, test } from "bun:test"
-import { getMonitorStats } from "../src/lib/network-monitor-utils"
+import { describe, expect, mock, test } from "bun:test"
+
+mock.module("@lingui/core/macro", () => ({
+ t: (strings: string | TemplateStringsArray) => (typeof strings === "string" ? strings : (strings?.[0] ?? "")),
+ plural: (_count: number, forms: { other?: string }) => forms.other ?? "",
+}))
+
+const { getMonitorStats } = await import("../src/lib/network-monitor-utils")
describe("monitor stats derived from stored counts", () => {
test("retains probe weights and response precision", () => {
@@ -12,12 +18,26 @@ describe("monitor stats derived from stored counts", () => {
success_count: 6,
res_sum: 61,
})
- expect(stats.res_avg).toBeCloseTo(10.1666667)
- expect(stats.loss).toBeCloseTo(14.2857143)
+ expect(stats.res_avg).toBe(10.17)
+ expect(stats.loss).toBe(14.29)
expect(stats.res_min).toBe(5)
expect(stats.res_max).toBe(20)
})
+ test("limits average response and loss to two decimals", () => {
+ const stats = getMonitorStats({
+ monitor: "monitor1",
+ created: 1000,
+ res_min: 3,
+ res_max: 4,
+ total_count: 9,
+ success_count: 3,
+ res_sum: 10,
+ })
+ expect(stats.res_avg).toBe(3.33)
+ expect(stats.loss).toBe(66.67)
+ })
+
test.each([
{ total_count: 3, success_count: 0, loss: 100 },
{ total_count: 0, success_count: 0, loss: 0 },