CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
traffic.test.ts
Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.
| 8f50ed0 | 1 | /** |
| 2 | * Block F1 — Traffic analytics tests. | |
| 3 | * | |
| 4 | * Pure bucketDaily tests + route auth smoke. | |
| 5 | */ | |
| 6 | ||
| 7 | import { describe, it, expect } from "bun:test"; | |
| 8 | import app from "../app"; | |
| 9 | import { bucketDaily } from "../lib/traffic"; | |
| 10 | ||
| 11 | describe("traffic — bucketDaily", () => { | |
| 12 | it("returns empty array for no events", () => { | |
| 13 | expect(bucketDaily([])).toEqual([]); | |
| 14 | }); | |
| 15 | ||
| 16 | it("buckets views and clones separately", () => { | |
| 17 | const buckets = bucketDaily([ | |
| 18 | { createdAt: "2026-04-14T10:00:00Z", kind: "view" }, | |
| 19 | { createdAt: "2026-04-14T12:00:00Z", kind: "view" }, | |
| 20 | { createdAt: "2026-04-14T15:00:00Z", kind: "clone" }, | |
| 21 | { createdAt: "2026-04-15T09:00:00Z", kind: "view" }, | |
| 22 | ]); | |
| 23 | expect(buckets).toEqual([ | |
| 24 | { day: "2026-04-14", views: 2, clones: 1 }, | |
| 25 | { day: "2026-04-15", views: 1, clones: 0 }, | |
| 26 | ]); | |
| 27 | }); | |
| 28 | ||
| 29 | it("counts UI kind as views", () => { | |
| 30 | const buckets = bucketDaily([ | |
| 31 | { createdAt: "2026-04-14T00:00:00Z", kind: "ui" }, | |
| 32 | ]); | |
| 33 | expect(buckets).toEqual([{ day: "2026-04-14", views: 1, clones: 0 }]); | |
| 34 | }); | |
| 35 | ||
| 36 | it("ignores api kind in view/clone buckets", () => { | |
| 37 | const buckets = bucketDaily([ | |
| 38 | { createdAt: "2026-04-14T00:00:00Z", kind: "api" }, | |
| 39 | ]); | |
| 40 | expect(buckets).toEqual([{ day: "2026-04-14", views: 0, clones: 0 }]); | |
| 41 | }); | |
| 42 | ||
| 43 | it("sorts buckets by day ascending", () => { | |
| 44 | const buckets = bucketDaily([ | |
| 45 | { createdAt: "2026-04-15T00:00:00Z", kind: "view" }, | |
| 46 | { createdAt: "2026-04-14T00:00:00Z", kind: "view" }, | |
| 47 | { createdAt: "2026-04-16T00:00:00Z", kind: "view" }, | |
| 48 | ]); | |
| 49 | expect(buckets.map((b) => b.day)).toEqual([ | |
| 50 | "2026-04-14", | |
| 51 | "2026-04-15", | |
| 52 | "2026-04-16", | |
| 53 | ]); | |
| 54 | }); | |
| 55 | }); | |
| 56 | ||
| 57 | describe("traffic — route smoke", () => { | |
| 58 | it("GET /:owner/:repo/traffic without auth → 302 /login", async () => { | |
| 59 | const res = await app.request("/any/repo/traffic"); | |
| 60 | expect(res.status).toBe(302); | |
| 61 | const loc = res.headers.get("location") || ""; | |
| 62 | expect(loc.startsWith("/login")).toBe(true); | |
| 63 | }); | |
| 64 | }); | |
| 65 | ||
| 66 | describe("traffic — lib exports", () => { | |
| 67 | it("exports track + helpers", async () => { | |
| 68 | const mod = await import("../lib/traffic"); | |
| 69 | expect(typeof mod.track).toBe("function"); | |
| 70 | expect(typeof mod.trackView).toBe("function"); | |
| 71 | expect(typeof mod.trackClone).toBe("function"); | |
| 72 | expect(typeof mod.trackByName).toBe("function"); | |
| 73 | expect(typeof mod.summarise).toBe("function"); | |
| 74 | expect(typeof mod.bucketDaily).toBe("function"); | |
| 75 | }); | |
| 76 | }); |