Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework evaluation attribute schema validation #441

Merged
merged 4 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions src/schema/evaluatorSchemas.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,52 @@
import {ObjectType, NumberType, JsonObjectType} from '../validation';
denis-rossati marked this conversation as resolved.
Show resolved Hide resolved
import {
ObjectType,
NumberType,
JsonObjectType,
UnionType,
StringType,
NullType,
BooleanType,
TypeSchema,
ArrayType,
} from '../validation';

function createJsonSchema(maximumDepth: number): TypeSchema {
return new UnionType(
new NullType(),
new NumberType(),
new BooleanType(),
new StringType({maxLength: 255}),
...(maximumDepth > 1
? [
new JsonObjectType({
propertyNames: new UnionType(
new NumberType(),
new StringType({
minLength: 1,
maxLength: 50,
}),
),
properties: createJsonSchema(maximumDepth - 1),
}),
new ArrayType({items: createJsonSchema(maximumDepth - 1)}),
]
: []
),
);
}

export const evaluationOptionsSchema = new ObjectType({
properties: {
timeout: new NumberType({
integer: true,
minimum: 0,
}),
attributes: new JsonObjectType(),
attributes: new JsonObjectType({
propertyNames: new StringType({
minLength: 1,
maxLength: 50,
}),
properties: createJsonSchema(5),
}),
},
});
45 changes: 0 additions & 45 deletions test/schemas/evaluationSchemas.test.ts

This file was deleted.

183 changes: 183 additions & 0 deletions test/schemas/evaluatorSchemas.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import {evaluationOptionsSchema} from '../../src/schema';
import {EvaluationOptions} from '../../src/facade/evaluatorFacade';

describe('The evaluator option schema', () => {
marcospassos marked this conversation as resolved.
Show resolved Hide resolved
it.each<EvaluationOptions[]>([
[{}],
[{
timeout: 1,
}],
[{
attributes: {foo: 'bar'},
}],
[{
timeout: 1,
attributes: {foo: 'bar'},
}],
[{
timeout: 1,
attributes: {},
}],
[{
timeout: 1,
attributes: {
['x'.repeat(50)]: 'x'.repeat(255),
'multi-byte character': '♥'.repeat(255),
arr: [
null,
123,
'x'.repeat(255),
true,
false,
],
first: {
second: {
third: {
'nested array': [
null,
123,
'x'.repeat(255),
true,
false,
],
fourth: {
fifth: '',
},
},
},
},
},
}],
])('should allow %s', value => {
function validate(): void {
evaluationOptionsSchema.validate(value);
}

expect(validate).not.toThrow();
});

it.each([
[
{timeout: -1},
'Expected a value greater than or equal to 0 at path \'/timeout\', actual -1.',
],
[
{timeout: 1.2},
'Expected value of type integer at path \'/timeout\', actual number.',
],
[
{attributes: 0},
'Expected a JSON object at path \'/attributes\', actual integer.',
],
[
{
attributes: {
first: {
second: {
third: {
fourth: {
fifth: {},
},
},
},
},
},
},
'Expected value of type null, number, boolean or string'
+ ' at path \'/attributes/first/second/third/fourth/fifth\', actual Object.',
],
[
{
attributes: {
first: [
[
[
[
['fifth level'],
],
],
],
],
},
},
'Expected value of type null, number, boolean or string'
+ ' at path \'/attributes/first/0/0/0/0\', actual array.',
],
[
{
attributes: {
foo: undefined,
},
},
'Expected a JSON object at path \'/attributes\', actual Object.',
],
[
{
attributes: {
'': 'foo',
},
},
'Expected at least 1 character at path \'/attributes/\', actual 0.',
],
[
{
attributes: {
['x'.repeat(51)]: 'foo',
},
},
`Expected at most 50 characters at path '/attributes/${'x'.repeat(51)}', actual 51.`,
],
[
{
attributes: 'foo',
},
'Expected a JSON object at path \'/attributes\', actual string.',
],
[
{
attributes: {
string: 'x'.repeat(256),
},
},
'Expected at most 255 characters at path \'/attributes/string\', actual 256.',
],
[
{
attributes: {
first: {
second: {
third: {
fourth: {
fifth: 'x'.repeat(256),
},
},
},
},
},
},
'Expected at most 255 characters at path \'/attributes/first/second/third/fourth/fifth\', actual 256.',
],
[
{
attributes: {
first: [
[
[
[
'x'.repeat(256),
],
],
],
],
},
},
'Expected at most 255 characters at path \'/attributes/first/0/0/0/0\', actual 256.',
],
])('should not allow %s', (value: Record<string, unknown>, message: string) => {
function validate(): void {
evaluationOptionsSchema.validate(value);
}

expect(validate).toThrowWithMessage(Error, message);
});
});