validata
Version:
Type safe data validation and sanitization
325 lines • 15.9 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const json_date_parser_1 = require("json-date-parser");
const date_1 = require("./date");
const number_1 = require("./number");
const object_1 = require("./object");
const string_1 = require("./string");
const test_helpers_1 = require("./test-helpers");
const types_1 = require("./types");
describe('isObject', () => {
it('will fail non-object', () => {
const fut = (0, object_1.isObject)();
(0, test_helpers_1.expectIssue)(fut, null, 'not-defined');
(0, test_helpers_1.expectIssue)(fut, undefined, 'not-defined');
(0, test_helpers_1.expectIssue)(fut, 0, 'incorrect-type');
(0, test_helpers_1.expectIssue)(fut, new Date(), 'incorrect-type');
(0, test_helpers_1.expectIssue)(fut, [], 'incorrect-type');
(0, test_helpers_1.expectIssue)(fut, 'test', 'incorrect-type');
});
it('will accept object', () => {
const fut = (0, object_1.isObject)();
(0, test_helpers_1.expectSuccess)(fut, {});
(0, test_helpers_1.expectSuccess)(fut, { a: 47 });
});
it('will process children', () => {
const fut = (0, object_1.isObject)({
a: (0, number_1.asNumber)({ coerceMin: 25 }),
b: (0, string_1.asString)(),
});
(0, test_helpers_1.expectValue)(fut, { a: 47, b: 'asd' }, { a: 47, b: 'asd' });
(0, test_helpers_1.expectValue)(fut, { a: '47', b: 12 }, { a: 47, b: '12' });
(0, test_helpers_1.expectValue)(fut, { a: '7', b: 12 }, { a: 25, b: '12' });
});
it('will process nested children', () => {
const fut = (0, object_1.isObject)({
o: (0, object_1.isObject)({
a: (0, number_1.isNumber)(),
b: (0, string_1.asString)(),
}),
s: (0, string_1.asString)(),
});
(0, test_helpers_1.runTests)(fut, {
input: { o: 47, s: 'asd' },
issues: [{ reason: 'incorrect-type', path: ['o'] }],
}, {
input: { o: {}, s: 'asd' },
issues: [{ reason: 'not-defined', path: ['o', 'a'] }],
}, {
input: { o: { a: 'hello', b: 'hello' }, s: 'asd' },
issues: [{ reason: 'incorrect-type', path: ['o', 'a'] }],
}, {
expect: { o: { a: 12, b: '12' }, s: 'asd' },
input: { o: { a: 12, b: 12 }, s: 'asd' },
});
});
it('will process children', () => {
const fut = (0, object_1.isObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
});
(0, test_helpers_1.expectValue)(fut, { a: 47, b: 'asd' }, { a: 47, b: 'asd' });
(0, test_helpers_1.expectIssue)(fut, { a: '47', b: 'asd' }, 'incorrect-type', ['a']);
(0, test_helpers_1.expectIssue)(fut, { a: 47, b: 'asd', c: 234 }, 'unexpected-property', ['c']);
(0, test_helpers_1.expectIssue)(fut, {}, 'not-defined', ['a']);
(0, test_helpers_1.expectIssue)(fut, {}, 'not-defined', ['b']);
});
it('will handle optional property', () => {
const fut = (0, object_1.isObject)({
a: (0, number_1.isNumber)(),
b: (0, string_1.maybeString)(),
});
(0, test_helpers_1.expectIssue)(fut, {}, 'not-defined', ['a']);
(0, test_helpers_1.expectIssue)(fut, { b: 'asd' }, 'not-defined', ['a']);
{
const result = (0, test_helpers_1.expectSuccess)(fut, { a: 42 });
expect(result.value).not.toHaveProperty('b');
}
{
const result = (0, test_helpers_1.expectSuccess)(fut, { a: 42, b: undefined });
expect(result.value).toHaveProperty('b');
expect(result.value.b).toEqual(undefined);
}
{
const result = (0, test_helpers_1.expectSuccess)(fut, { a: 42, b: null });
expect(result.value).toHaveProperty('b');
expect(result.value.b).toEqual(undefined);
}
});
it('will error on unexpected properties', () => {
const fut = (0, object_1.isObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
});
(0, test_helpers_1.expectIssue)(fut, { a: 47, b: 'asd', c: 234 }, 'unexpected-property', ['c']);
});
it('will strip unexpected properties', () => {
const fut = (0, object_1.isObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
}, { stripExtraProperties: true });
(0, test_helpers_1.expectValue)(fut, { a: 47, b: 'asd', c: 345, d: 'hello' }, { a: 47, b: 'asd' });
});
it('will ignore unexpected properties', () => {
const fut = (0, object_1.isObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
}, { ignoreExtraProperties: true });
(0, test_helpers_1.expectValue)(fut, { a: 47, b: 'asd', c: 345, d: 'hello' }, { a: 47, b: 'asd', c: 345, d: 'hello' });
});
it('will check with custom validator returning custom issues', () => {
const fut = (0, object_1.isObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)({ validator: (value, _options, path) => value === 'triggerCustom' ? [types_1.Issue.forPath(path !== null && path !== void 0 ? path : [], value, 'custom')] : true }),
});
(0, test_helpers_1.expectIssue)(fut, { a: 47, b: 'triggerCustom' }, 'custom', ['b']);
});
});
describe('maybeObject', () => {
it('will coerce null and undefined', () => {
const fut = (0, object_1.maybeObject)();
(0, test_helpers_1.expectValue)(fut, null, undefined);
(0, test_helpers_1.expectValue)(fut, undefined, undefined);
});
it('will fail non-object', () => {
const fut = (0, object_1.maybeObject)();
(0, test_helpers_1.expectIssue)(fut, 0, 'incorrect-type');
(0, test_helpers_1.expectIssue)(fut, new Date(), 'incorrect-type');
(0, test_helpers_1.expectIssue)(fut, [], 'incorrect-type');
(0, test_helpers_1.expectIssue)(fut, 'test', 'incorrect-type');
});
it('will accept non-object if requested', () => {
const fut = (0, object_1.maybeObject)({}, { incorrectTypeToUndefined: true });
(0, test_helpers_1.expectValue)(fut, 0, undefined);
(0, test_helpers_1.expectValue)(fut, new Date(), undefined);
(0, test_helpers_1.expectValue)(fut, [], undefined);
(0, test_helpers_1.expectValue)(fut, 'test', undefined);
});
it('will accept object', () => {
const fut = (0, object_1.maybeObject)();
(0, test_helpers_1.expectSuccess)(fut, {});
(0, test_helpers_1.expectSuccess)(fut, { a: 47 });
});
});
describe('asObject', () => {
it('will fail non-object', () => {
const fut = (0, object_1.asObject)();
(0, test_helpers_1.expectIssue)(fut, null, 'not-defined');
(0, test_helpers_1.expectIssue)(fut, undefined, 'not-defined');
(0, test_helpers_1.expectIssue)(fut, 0, 'no-conversion');
(0, test_helpers_1.expectIssue)(fut, new Date(), 'no-conversion');
(0, test_helpers_1.expectIssue)(fut, [], 'no-conversion');
(0, test_helpers_1.expectIssue)(fut, 'test', 'no-conversion');
});
it('will use default', () => {
const fut = (0, object_1.asObject)({
a: (0, number_1.asNumber)(),
b: (0, string_1.asString)(),
}, { default: { a: 47, b: 'default' } });
(0, test_helpers_1.expectValue)(fut, null, { a: 47, b: 'default' });
(0, test_helpers_1.expectValue)(fut, undefined, { a: 47, b: 'default' });
});
it('will accept object', () => {
const fut = (0, object_1.asObject)();
(0, test_helpers_1.expectSuccess)(fut, {});
(0, test_helpers_1.expectSuccess)(fut, { a: 47 });
});
it('will process children', () => {
const fut = (0, object_1.asObject)({
a: (0, number_1.asNumber)({ coerceMin: 25 }),
b: (0, string_1.asString)(),
});
(0, test_helpers_1.expectValue)(fut, { a: 47, b: 'asd' }, { a: 47, b: 'asd' });
(0, test_helpers_1.expectValue)(fut, { a: '47', b: 12 }, { a: 47, b: '12' });
(0, test_helpers_1.expectValue)(fut, { a: '7', b: 12 }, { a: 25, b: '12' });
});
it('will process nested children', () => {
const fut = (0, object_1.asObject)({
o: (0, object_1.isObject)({
a: (0, number_1.isNumber)(),
b: (0, string_1.asString)(),
}),
s: (0, string_1.asString)(),
});
(0, test_helpers_1.runTests)(fut, {
input: { o: 47, s: 'asd' },
issues: [{ reason: 'incorrect-type', path: ['o'] }],
}, {
input: { o: {}, s: 'asd' },
issues: [{ reason: 'not-defined', path: ['o', 'a'] }],
}, {
input: { o: { a: 'hello', b: 'hello' }, s: 'asd' },
issues: [{ reason: 'incorrect-type', path: ['o', 'a'] }],
}, {
expect: { o: { a: 12, b: '12' }, s: 'asd' },
input: { o: { a: 12, b: 12 }, s: 'asd' },
});
});
it('will process children', () => {
const fut = (0, object_1.asObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
});
(0, test_helpers_1.expectValue)(fut, { a: 47, b: 'asd' }, { a: 47, b: 'asd' });
(0, test_helpers_1.expectIssue)(fut, { a: '47', b: 'asd' }, 'incorrect-type', ['a']);
(0, test_helpers_1.expectIssue)(fut, { a: 47, b: 'asd', c: 234 }, 'unexpected-property', ['c']);
(0, test_helpers_1.expectIssue)(fut, {}, 'not-defined', ['a']);
(0, test_helpers_1.expectIssue)(fut, {}, 'not-defined', ['b']);
});
it('will error on unexpected properties', () => {
const fut = (0, object_1.asObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
});
(0, test_helpers_1.expectIssue)(fut, { a: 47, b: 'asd', c: 234 }, 'unexpected-property', ['c']);
});
it('will strip unexpected properties', () => {
const fut = (0, object_1.asObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
}, { stripExtraProperties: true });
(0, test_helpers_1.expectValue)(fut, { a: 47, b: 'asd', c: 345, d: 'hello' }, { a: 47, b: 'asd' });
});
describe('string parsing', () => {
const fut = (0, object_1.asObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
});
it('will fail empty string', () => {
(0, test_helpers_1.expectIssue)(fut, '', 'no-conversion');
});
it('will fail nonJSON string', () => {
(0, test_helpers_1.expectIssue)(fut, 'testing', 'no-conversion');
});
it('will fail invalid JSON string', () => {
(0, test_helpers_1.expectIssue)(fut, '{testing=12}', 'no-conversion');
(0, test_helpers_1.expectIssue)(fut, '{testing:12}', 'no-conversion');
});
it('will parse valid JSON string that matches requirements', () => {
(0, test_helpers_1.expectValue)(fut, '{"a": 123, "b": "test"}', { a: 123, b: 'test' });
});
it('will parse valid JSON string that doesn\'t match requirements', () => {
(0, test_helpers_1.expectIssue)(fut, '{}', 'not-defined', ['a']);
(0, test_helpers_1.expectIssue)(fut, '{}', 'not-defined', ['b']);
(0, test_helpers_1.expectIssue)(fut, '{"a": "123", "b": "test"}', 'incorrect-type', ['a']);
});
});
});
describe('maybeAsObject', () => {
it('will coerce null and undefined', () => {
const fut = (0, object_1.maybeAsObject)();
(0, test_helpers_1.expectValue)(fut, null, undefined);
(0, test_helpers_1.expectValue)(fut, undefined, undefined);
});
it('will use default', () => {
const fut = (0, object_1.maybeAsObject)({
a: (0, number_1.asNumber)(),
b: (0, string_1.asString)(),
}, { default: { a: 47, b: 'default' } });
(0, test_helpers_1.expectValue)(fut, null, { a: 47, b: 'default' });
(0, test_helpers_1.expectValue)(fut, undefined, { a: 47, b: 'default' });
});
it('will convert non-object to undefined', () => {
const fut = (0, object_1.maybeAsObject)();
(0, test_helpers_1.expectValue)(fut, 0, undefined);
(0, test_helpers_1.expectValue)(fut, new Date(), undefined);
(0, test_helpers_1.expectValue)(fut, [], undefined);
(0, test_helpers_1.expectValue)(fut, 'test', undefined);
});
it('will fail invalid JSON string when parsing is strict', () => {
const fut = (0, object_1.maybeAsObject)({}, { strictParsing: true });
(0, test_helpers_1.expectIssue)(fut, 0, 'no-conversion');
(0, test_helpers_1.expectIssue)(fut, 'test', 'no-conversion');
(0, test_helpers_1.expectIssue)(fut, '{testing=12}', 'no-conversion');
(0, test_helpers_1.expectIssue)(fut, '{testing:12}', 'no-conversion');
});
it('will accept non-object if requested', () => {
const fut = (0, object_1.maybeAsObject)({}, { incorrectTypeToUndefined: true });
(0, test_helpers_1.expectValue)(fut, 0, undefined);
(0, test_helpers_1.expectValue)(fut, new Date(), undefined);
(0, test_helpers_1.expectValue)(fut, [], undefined);
(0, test_helpers_1.expectValue)(fut, 'test', undefined);
});
it('will accept object', () => {
const fut = (0, object_1.maybeAsObject)();
(0, test_helpers_1.expectSuccess)(fut, {});
(0, test_helpers_1.expectSuccess)(fut, { a: 47 });
});
describe('string parsing', () => {
const fut = (0, object_1.maybeAsObject)({
a: (0, number_1.isNumber)({ min: 25 }),
b: (0, string_1.isString)(),
});
it('will convert empty string to undefined', () => {
(0, test_helpers_1.expectValue)(fut, '', undefined);
});
it('will convert nonJSON string to undefined', () => {
(0, test_helpers_1.expectValue)(fut, 'testing', undefined);
});
it('will convert invalid JSON string to undefined', () => {
(0, test_helpers_1.expectValue)(fut, '{testing=12}', undefined);
(0, test_helpers_1.expectValue)(fut, '{testing:12}', undefined);
});
it('will use custom converter', () => {
const fut = (0, object_1.asObject)({ d: (0, date_1.isDate)() }, { converter: (value) => typeof value !== 'string' ? undefined : JSON.parse(value, json_date_parser_1.jsonDateParser) });
(0, test_helpers_1.expectIssue)(fut, '{"d":12}', 'incorrect-type', ['d']);
const date = '2021-01-13T20:23:36.164Z';
const r = fut.process(`{"d":"${date}"}`);
expect(r).toBeDefined();
if ((0, types_1.isIssue)(r)) {
fail(`Unexpected issue: ${JSON.stringify(r)}`);
}
expect(r.value.d.constructor.name).toEqual('Date');
expect(r.value.d.getTime()).toEqual(new Date(date).getTime());
});
it('will parse valid JSON string that matches requirements', () => {
(0, test_helpers_1.expectValue)(fut, '{"a": 123, "b": "test"}', { a: 123, b: 'test' });
});
it('will parse valid JSON string that doesn\'t match requirements', () => {
(0, test_helpers_1.expectIssue)(fut, '{}', 'not-defined', ['a']);
(0, test_helpers_1.expectIssue)(fut, '{}', 'not-defined', ['b']);
(0, test_helpers_1.expectIssue)(fut, '{"a": "123", "b": "test"}', 'incorrect-type', ['a']);
});
});
});
//# sourceMappingURL=object.test.js.map
;