/
response.validator.spec.ts
154 lines (143 loc) 路 4.22 KB
/
response.validator.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import * as path from 'path';
import * as fs from 'fs';
import * as jsyaml from 'js-yaml';
import { expect } from 'chai';
import { ResponseValidator } from '../src/middlewares/openapi.response.validator';
const packageJson = require('../package.json');
const apiSpecPath = path.join('test', 'resources', 'response.validation.yaml');
const apiSpec = jsyaml.safeLoad(fs.readFileSync(apiSpecPath, 'utf8'));
describe(packageJson.name, () => {
it('should validate the using default (in this case the error object)', async () => {
const v = new ResponseValidator(apiSpec);
const responses = petsResponseSchema();
const validators = v._getOrBuildValidator(null, responses);
try {
expect(
v._validate({
validators,
body: { message: 'some error message', code: 400 },
statusCode: 400,
path: '/some-path',
}),
).to.not.exist;
} catch (e) {
expect(e).to.not.exist;
}
});
it('should throw error when default response is invalid', async () => {
const v = new ResponseValidator(apiSpec);
const responses = petsResponseSchema();
const validators = v._getOrBuildValidator(null, responses);
try {
const message = { note: 'bad message type' };
const code = 400;
expect(
v._validate({
validators,
body: { message, code },
statusCode: code,
path: '/some-path',
}),
).to.not.exist;
} catch (e) {
expect(e.status).to.equal(500);
expect(e.errors).to.be.an('array');
expect(e.errors[0].message).to.equal('should be string');
}
});
it('should return an error if field type is invalid', async () => {
const v = new ResponseValidator(apiSpec);
const responses = petsResponseSchema();
const validators = v._getOrBuildValidator(null, responses);
try {
v._validate({
validators,
body: [{ id: 'bad-id', name: 'test', tag: 'tag' }],
statusCode: 200,
path: '/some-path',
});
} catch (e) {
expect(e).to.be.not.null;
expect(e.message).to.contain('should be integer');
expect(e.message).to.not.contain('additional properties');
}
try {
v._validate({
validators,
body: { id: 1, name: 'test', tag: 'tag' },
statusCode: 200,
path: '/some-path',
});
} catch (e) {
expect(e).to.be.not.null;
expect(e.message).to.contain('should be array');
}
try {
v._validate({
validators,
body: [{ id: 1, name: [], tag: 'tag' }],
statusCode: 200,
path: '/some-path',
});
} catch (e) {
expect(e).to.be.not.null;
expect(e.message).to.contain('should be string');
}
});
// TODO may not be possible to fix
// https://github.com/epoberezkin/ajv/issues/837
it.skip('should fail if additional properties are provided when set false', async () => {
const v = new ResponseValidator(apiSpec);
const responses = petsResponseSchema();
const validators = v._getOrBuildValidator(null, responses);
const statusCode = 200;
const path = '/some-path';
const body = [
{
id: 10,
name: 'test',
tag: 'tag',
additionalProp: 'test',
},
];
try {
expect(v._validate({ validators, body, statusCode, path })).to.not.exist;
expect('here').to.be.null;
} catch (e) {
// TODO include params.additionalProperty: value in error message
// TODO maybe params should be in the response
expect(e.message).to.contain('should NOT have additional properties');
expect(e.status).to.equal(500);
expect(e.errors[0].message).to.contain(
'should NOT have additional properties',
);
}
});
});
function petsResponseSchema() {
return {
'200': {
description: 'pet response',
content: {
'application/json': {
schema: {
type: 'array',
items: {
$ref: '#/components/schemas/Pet',
},
},
},
},
},
'400': {
description: 'unexpected error',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/Error',
},
},
},
},
};
}