import { describe, it, expect } from "vitest"; import { WorkspaceMemberRole } from "@mosaic/shared"; import { isValidEmail, toWorkspaceMemberRole } from "./validation"; describe("isValidEmail", (): void => { describe("valid emails", (): void => { it("should accept a standard email", (): void => { expect(isValidEmail("user@example.com")).toBe(true); }); it("should accept email with dots in local part", (): void => { expect(isValidEmail("first.last@example.com")).toBe(true); }); it("should accept email with plus addressing", (): void => { expect(isValidEmail("user+tag@example.com")).toBe(true); }); it("should accept email with subdomain", (): void => { expect(isValidEmail("user@mail.example.com")).toBe(true); }); it("should accept email with hyphen in domain", (): void => { expect(isValidEmail("user@my-domain.com")).toBe(true); }); it("should accept email with special characters in local part", (): void => { expect(isValidEmail("user!#$%&'*+/=?^_`{|}~@example.com")).toBe(true); }); it("should accept email with numbers", (): void => { expect(isValidEmail("user123@example456.com")).toBe(true); }); it("should accept single-character local part", (): void => { expect(isValidEmail("a@example.com")).toBe(true); }); }); describe("invalid emails", (): void => { it("should reject empty string", (): void => { expect(isValidEmail("")).toBe(false); }); it("should reject email without @", (): void => { expect(isValidEmail("userexample.com")).toBe(false); }); it("should reject email with only @", (): void => { expect(isValidEmail("@")).toBe(false); }); it("should reject email without local part", (): void => { expect(isValidEmail("@example.com")).toBe(false); }); it("should reject email without domain", (): void => { expect(isValidEmail("user@")).toBe(false); }); it("should reject email with spaces", (): void => { expect(isValidEmail("user @example.com")).toBe(false); }); it("should reject email with multiple @ signs", (): void => { expect(isValidEmail("user@@example.com")).toBe(false); }); it("should reject email with domain starting with hyphen", (): void => { expect(isValidEmail("user@-example.com")).toBe(false); }); it("should reject email exceeding 254 characters", (): void => { const longLocal = "a".repeat(243); const longEmail = `${longLocal}@example.com`; expect(longEmail.length).toBeGreaterThan(254); expect(isValidEmail(longEmail)).toBe(false); }); it("should reject email that only contains @", (): void => { expect(isValidEmail("just@")).toBe(false); }); it("should reject plaintext without any structure", (): void => { expect(isValidEmail("not-an-email")).toBe(false); }); }); }); describe("toWorkspaceMemberRole", (): void => { describe("valid roles", (): void => { it("should return OWNER for 'OWNER'", (): void => { expect(toWorkspaceMemberRole("OWNER")).toBe(WorkspaceMemberRole.OWNER); }); it("should return ADMIN for 'ADMIN'", (): void => { expect(toWorkspaceMemberRole("ADMIN")).toBe(WorkspaceMemberRole.ADMIN); }); it("should return MEMBER for 'MEMBER'", (): void => { expect(toWorkspaceMemberRole("MEMBER")).toBe(WorkspaceMemberRole.MEMBER); }); it("should return GUEST for 'GUEST'", (): void => { expect(toWorkspaceMemberRole("GUEST")).toBe(WorkspaceMemberRole.GUEST); }); }); describe("invalid roles", (): void => { it("should fall back to MEMBER for empty string", (): void => { expect(toWorkspaceMemberRole("")).toBe(WorkspaceMemberRole.MEMBER); }); it("should fall back to MEMBER for unknown role", (): void => { expect(toWorkspaceMemberRole("SUPERADMIN")).toBe(WorkspaceMemberRole.MEMBER); }); it("should fall back to MEMBER for lowercase variant", (): void => { expect(toWorkspaceMemberRole("admin")).toBe(WorkspaceMemberRole.MEMBER); }); it("should fall back to MEMBER for mixed case", (): void => { expect(toWorkspaceMemberRole("Admin")).toBe(WorkspaceMemberRole.MEMBER); }); it("should fall back to MEMBER for numeric input", (): void => { expect(toWorkspaceMemberRole("123")).toBe(WorkspaceMemberRole.MEMBER); }); it("should fall back to MEMBER for special characters", (): void => { expect(toWorkspaceMemberRole("