60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import fc from "fast-check";
|
|
import { PrincipalSchema } from "../src/schemas/principal.js";
|
|
|
|
const principalArb = fc.record(
|
|
{
|
|
id: fc.string({ minLength: 1, maxLength: 64 }),
|
|
email: fc.option(
|
|
fc
|
|
.tuple(
|
|
fc.string({ minLength: 1, maxLength: 16 }),
|
|
fc.string({ minLength: 1, maxLength: 16 })
|
|
)
|
|
.map(
|
|
([l, r]) =>
|
|
`${l.replace(/[^A-Za-z0-9]/g, "a")}@${r.replace(
|
|
/[^A-Za-z0-9]/g,
|
|
"a"
|
|
)}.test`
|
|
),
|
|
{ nil: undefined }
|
|
),
|
|
emailVerified: fc.boolean(),
|
|
roles: fc.array(fc.string({ minLength: 1, maxLength: 16 }), {
|
|
maxLength: 5,
|
|
}),
|
|
tenantId: fc.option(fc.string({ minLength: 1, maxLength: 32 }), {
|
|
nil: undefined,
|
|
}),
|
|
metadata: fc.option(
|
|
fc.dictionary(
|
|
fc.string({ minLength: 1, maxLength: 8 }),
|
|
fc.oneof(fc.string(), fc.integer(), fc.boolean())
|
|
),
|
|
{ nil: undefined }
|
|
),
|
|
},
|
|
{ requiredKeys: ["id", "emailVerified", "roles"] }
|
|
);
|
|
|
|
describe("PrincipalSchema fast-check round-trip", () => {
|
|
it("accepts arbitrary valid principals (200 runs)", {
|
|
timeout: 30_000,
|
|
}, () => {
|
|
fc.assert(
|
|
fc.property(principalArb, (sample) => {
|
|
const result = PrincipalSchema.safeParse(sample);
|
|
if (!result.success) {
|
|
throw new Error(
|
|
`unexpected reject: ${JSON.stringify(result.error.issues)}`
|
|
);
|
|
}
|
|
expect(result.data.id).toBe(sample.id);
|
|
expect(result.data.emailVerified).toBe(sample.emailVerified);
|
|
}),
|
|
{ numRuns: 200 }
|
|
);
|
|
});
|
|
});
|