Skip to content
File

Blob: tests/shared/site-slug.test.ts

typescript38 lines
1import { describe, expect, it } from "vitest";
2 
3import { SITE_RESERVED_SLUGS, sitesSlug } from "@/shared/site-slug";
4 
5describe("sitesSlug validator", () => {
6 it("accepts plain lowercase labels", () => {
7 expect(sitesSlug.safeParse("acme").success).toBe(true);
8 expect(sitesSlug.safeParse("acme-co").success).toBe(true);
9 expect(sitesSlug.safeParse("a1b2c3").success).toBe(true);
10 });
11 
12 it("rejects empty, too-long, or boundary-hyphen slugs", () => {
13 expect(sitesSlug.safeParse("").success).toBe(false);
14 expect(sitesSlug.safeParse("-leading").success).toBe(false);
15 expect(sitesSlug.safeParse("trailing-").success).toBe(false);
16 expect(sitesSlug.safeParse("a".repeat(64)).success).toBe(false);
17 });
18 
19 it("rejects uppercase, underscores, dots, and non-ascii", () => {
20 expect(sitesSlug.safeParse("Acme").success).toBe(false);
21 expect(sitesSlug.safeParse("acme_co").success).toBe(false);
22 expect(sitesSlug.safeParse("acme.co").success).toBe(false);
23 expect(sitesSlug.safeParse("acme!").success).toBe(false);
24 });
25 
26 it("rejects reserved labels", () => {
27 for (const label of ["www", "api", "admin", "bland", "cdn-cgi"]) {
28 expect(sitesSlug.safeParse(label).success).toBe(false);
29 }
30 });
31 
32 it("exposes the reserved set", () => {
33 expect(SITE_RESERVED_SLUGS.has("www")).toBe(true);
34 expect(SITE_RESERVED_SLUGS.has("bland")).toBe(true);
35 expect(SITE_RESERVED_SLUGS.has("acme")).toBe(false);
36 });
37});