import { validateEmail, validatePassword, validateUsername } from "../validation"; describe("validateEmail", () => { it.each(["a@b.co", "user.name+tag@example.com", "x@host.dev"])("accepts %s", (e) => { expect(validateEmail(e)).toBe(true); }); it.each(["", "no-at", "a@b", "a@b.c", "a@@b.co", " a@b.co", "a@b.co "])("rejects %s", (e) => { expect(validateEmail(e)).toBe(false); }); }); describe("validatePassword", () => { it("accepts a strong password", () => { const r = validatePassword("Aa1!2345"); expect(r.valid).toBe(true); expect(r.errors).toEqual([]); }); it("collects every rule violation in a single pass", () => { const r = validatePassword("short"); expect(r.valid).toBe(false); // length, upper, digit, symbol = 4 misses; lowercase is present. expect(r.errors.length).toBe(4); }); it("flags missing symbol only", () => { const r = validatePassword("Aaaaaaa1"); expect(r.valid).toBe(false); expect(r.errors).toHaveLength(1); expect(r.errors[0]).toMatch(/special/i); }); }); describe("validateUsername", () => { it("accepts 3..30 ascii alnum/underscore", () => { expect(validateUsername("abc")).toEqual({ valid: true }); expect(validateUsername("a_1")).toEqual({ valid: true }); expect(validateUsername("a".repeat(30))).toEqual({ valid: true }); }); it("rejects out-of-range length", () => { expect(validateUsername("ab").valid).toBe(false); expect(validateUsername("a".repeat(31)).valid).toBe(false); }); it("rejects non-ascii / special chars", () => { expect(validateUsername("ab-c").valid).toBe(false); expect(validateUsername("ab c").valid).toBe(false); expect(validateUsername("ab.c").valid).toBe(false); }); });