n4s
Version:
typed schema validation version of enforce
132 lines (107 loc) • 4.32 kB
text/typescript
import { describe, expect, it } from 'vitest';
import { enforce } from '../../../n4s';
describe('omit', () => {
it('Should successfully validate a schema ignoring omitted keys', () => {
const schema = {
name: enforce.isString(),
age: enforce.isNumber(),
email: enforce.isString(),
};
const omittedSchema = enforce.omit(schema, ['email']);
// Omit email, validating valid inputs for name and age
// @ts-expect-error - partial object, omitted keys missing
const result = omittedSchema.run({ name: 'John Doe', age: 30 });
expect(result.pass).toBe(true);
// Test failing condition in the non-omitted keys
const invalidResult = omittedSchema.run({
name: 'John Doe',
// @ts-expect-error - intentionally passing string instead of number
age: 'thirty',
});
expect(invalidResult.pass).toBe(false);
});
it('Should handle string param for keysToOmit', () => {
const schema = {
id: enforce.isNumber(),
name: enforce.isString(),
};
// omit name
const omittedSchema = enforce.omit(schema, 'name');
// @ts-expect-error - partial object, omitted keys missing
const result = omittedSchema.run({ id: 1 });
expect(result.pass).toBe(true);
const invalidResult = omittedSchema.run({
// @ts-expect-error - intentionally passing string instead of number
id: 'one',
});
expect(invalidResult.pass).toBe(false);
});
it('Should validate schema even if the payload has extra unspecified keys', () => {
const schema = {
id: enforce.isNumber(),
};
// omit nothing
const omittedSchema = enforce.omit(schema, []);
// @ts-expect-error - extra keys not in schema
const result = omittedSchema.run({ id: 1, extra: 'data' });
expect(result.pass).toBe(true);
});
it('Should fail immediately and return false if the value is not an object', () => {
const schema = { name: enforce.isString() };
const omittedSchema = enforce.omit(schema, ['name']);
// @ts-expect-error - testing non-object value
expect(omittedSchema.run('string_value').pass).toBe(false);
// @ts-expect-error - testing non-object value
expect(omittedSchema.run(123).pass).toBe(false);
// @ts-expect-error - testing non-object value
expect(omittedSchema.run(null).pass).toBe(false);
});
it('Should protect against dangerous prototype keys', () => {
const schema = { admin: enforce.isBoolean() };
const omittedSchema = enforce.omit(schema, ['id']);
const dangerousValue = JSON.parse('{"__proto__": {"admin": true}}');
const result = omittedSchema.run(dangerousValue);
expect(result.pass).toBe(false);
});
it('Should fail when schema is not an object', () => {
const schema = 'not_a_schema';
// @ts-expect-error - testing non-object schema
const omittedSchema = enforce.omit(schema, ['id']);
const result = omittedSchema.run({ id: 1 });
expect(result.pass).toBe(false);
});
it('Should omit everything and accept invalid un-checked properties', () => {
const schema = { id: enforce.isNumber() };
const omittedSchema = enforce.omit(schema, ['id']);
const result = omittedSchema.run({
// @ts-expect-error - intentionally passing string instead of number
id: 'invalid_type_but_omitted',
});
expect(result.pass).toBe(true);
});
it('Should pass with valid fields and ignore invalid omitted fields', () => {
const schema = {
name: enforce.isString(),
age: enforce.isNumber(),
email: enforce.isString(),
};
const omittedSchema = enforce.omit(schema, ['email']);
// Should pass since we dropped the invalid email constraint via omit
const result = omittedSchema.run({
name: 'John',
age: 30,
// @ts-expect-error - intentionally passing number instead of string
email: 123,
});
expect(result.pass).toBe(true);
// Should fail because age breaks the remaining shape constraint
const invalidResult = omittedSchema.run({
name: 'John',
// @ts-expect-error - intentionally passing string instead of number
age: 'thirty',
// @ts-expect-error - intentionally passing number instead of string
email: 123,
});
expect(invalidResult.pass).toBe(false);
});
});