import { describe, it, expect } from "vitest"; import { suggestUsername, safeRedirectTo } from "../onboarding"; import { USERNAME_RE } from "~/models/user"; describe("suggestUsername", () => { it("returns empty string for null", () => { expect(suggestUsername(null)).toBe(""); }); it("returns empty string for empty string", () => { expect(suggestUsername("")).toBe(""); }); it("lowercases and strips spaces", () => { expect(suggestUsername("John Smith")).toBe("johnsmith"); }); it("strips special characters", () => { expect(suggestUsername("Jane O'Brien!")).toBe("janeobrien"); }); it("preserves underscores and hyphens", () => { expect(suggestUsername("cool_user-name")).toBe("cool_user-name"); }); it("slices to 20 characters", () => { expect(suggestUsername("averylongdisplaynamethatexceedstwenty")).toBe("averylongdisplayname"); expect(suggestUsername("averylongdisplaynamethatexceedstwenty").length).toBeLessThanOrEqual(20); }); it("returns empty string when cleaned result is shorter than 3 characters", () => { expect(suggestUsername("Jo")).toBe(""); expect(suggestUsername("AB")).toBe(""); }); it("returns the suggestion when cleaned result is exactly 3 characters", () => { expect(suggestUsername("abc")).toBe("abc"); }); it("returns empty string for non-ASCII display names that strip to nothing", () => { expect(suggestUsername("小林")).toBe(""); }); }); describe("safeRedirectTo", () => { it("returns / for null", () => { expect(safeRedirectTo(null)).toBe("/"); }); it("returns / for empty string", () => { expect(safeRedirectTo("")).toBe("/"); }); it("returns / for bare slash", () => { expect(safeRedirectTo("/")).toBe("/"); }); it("allows a root-relative path", () => { expect(safeRedirectTo("/leagues/123/draft/456")).toBe("/leagues/123/draft/456"); }); it("rejects an absolute URL", () => { expect(safeRedirectTo("https://evil.com")).toBe("/"); }); it("rejects a protocol-relative URL", () => { expect(safeRedirectTo("//evil.com")).toBe("/"); }); }); describe("USERNAME_RE", () => { it("allows 3-character usernames", () => { expect(USERNAME_RE.test("abc")).toBe(true); }); it("allows 30-character usernames", () => { expect(USERNAME_RE.test("a".repeat(30))).toBe(true); }); it("allows letters, numbers, underscores, and hyphens", () => { expect(USERNAME_RE.test("Cool_User-123")).toBe(true); }); it("rejects usernames shorter than 3 characters", () => { expect(USERNAME_RE.test("ab")).toBe(false); expect(USERNAME_RE.test("")).toBe(false); }); it("rejects usernames longer than 30 characters", () => { expect(USERNAME_RE.test("a".repeat(31))).toBe(false); }); it("rejects special characters", () => { expect(USERNAME_RE.test("user!")).toBe(false); expect(USERNAME_RE.test("user name")).toBe(false); expect(USERNAME_RE.test("user@host")).toBe(false); }); });