CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history
invites.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.
| febd4f0 | 1 | /** |
| 2 | * Invite token helpers + /invites/:token smoke. | |
| 3 | * | |
| 4 | * We exercise the pure-crypto helpers exhaustively (cheap, deterministic) | |
| 5 | * and hit the route with a bogus token to prove the not-found branch works | |
| 6 | * without needing a DB seeded invite. A DB-seeded happy-path test would | |
| 7 | * require fixture plumbing that the existing collaborators.test.ts also | |
| 8 | * avoids, so we stay consistent. | |
| 9 | */ | |
| 10 | ||
| 11 | import { describe, it, expect } from "bun:test"; | |
| 12 | import { | |
| 13 | generateInviteToken, | |
| 14 | hashInviteToken, | |
| 15 | } from "../lib/invite-tokens"; | |
| 16 | import app from "../app"; | |
| 17 | ||
| 18 | describe("invite-tokens lib", () => { | |
| 19 | it("generateInviteToken emits 32 hex chars and is unique across calls", () => { | |
| 20 | const seen = new Set<string>(); | |
| 21 | for (let i = 0; i < 100; i++) { | |
| 22 | const t = generateInviteToken(); | |
| 23 | expect(t).toMatch(/^[0-9a-f]{32}$/); | |
| 24 | expect(seen.has(t)).toBe(false); | |
| 25 | seen.add(t); | |
| 26 | } | |
| 27 | }); | |
| 28 | ||
| 29 | it("hashInviteToken is deterministic and differs per input", () => { | |
| 30 | const a = generateInviteToken(); | |
| 31 | const b = generateInviteToken(); | |
| 32 | expect(hashInviteToken(a)).toBe(hashInviteToken(a)); | |
| 33 | expect(hashInviteToken(a)).not.toBe(hashInviteToken(b)); | |
| 34 | // sha256 hex is 64 chars. | |
| 35 | expect(hashInviteToken(a)).toMatch(/^[0-9a-f]{64}$/); | |
| 36 | }); | |
| 37 | }); | |
| 38 | ||
| 39 | describe("GET /invites/:token", () => { | |
| 40 | it("returns 404 for a bogus token", async () => { | |
| 41 | const res = await app.request("/invites/not-a-real-token-xxxxxxxxxxxxxxxx"); | |
| 42 | // 404 is the expected path. If the DB is unreachable in the test env the | |
| 43 | // route's try/catch still maps that to not-found, so 404 is the single | |
| 44 | // acceptable status. | |
| 45 | expect(res.status).toBe(404); | |
| 46 | }); | |
| 47 | }); |