Skip to content

Commit 8f7c678

Browse files
danerylcdimascio
andauthored
pass coerceTypes through (#809)
Co-authored-by: Carmine DiMascio <[email protected]>
1 parent e35a07c commit 8f7c678

File tree

3 files changed

+65
-9
lines changed

3 files changed

+65
-9
lines changed

Diff for: src/middlewares/openapi.request.validator.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,14 @@ export class RequestValidator {
4646
delete this.apiDoc.components?.examples;
4747
this.requestOpts.allowUnknownQueryParameters =
4848
options.allowUnknownQueryParameters;
49-
this.ajv = createRequestAjv(apiDoc, { ...options, coerceTypes: true });
49+
50+
this.ajv = createRequestAjv(
51+
apiDoc,
52+
// This should always be true as it handles query params (everything, but the body)
53+
// This should always be coerced. Note that coerceTypes = 'array` also operates as true
54+
// but also coerces 'array' types
55+
!options.coerceTypes ? { ...options, coerceTypes: true } : options,
56+
);
5057
this.ajvBody = createRequestAjv(apiDoc, options);
5158
}
5259

@@ -220,6 +227,7 @@ export class RequestValidator {
220227
}
221228
}
222229
});
230+
return null;
223231
}
224232

225233
private discriminatorValidator(req, discriminator) {

Diff for: test/coercion.spec.ts

+32-8
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,34 @@ import * as packageJson from '../package.json';
77

88
describe(packageJson.name, () => {
99
let app = null;
10+
let arrayCoercedApp = null;
1011

1112
before(async () => {
1213
// Set up the express app
1314
const apiSpec = path.join('test', 'resources', 'coercion.yaml');
15+
const routes = express
16+
.Router()
17+
.post(`/pets`, (req, res) => res.json(req.body))
18+
.post(`/pets_string_boolean`, (req, res) => res.json(req.body))
19+
.get(`/pets_as_array_parameter`, (req, res) => res.json(req.query));
20+
1421
app = await createApp({ apiSpec }, 3005, (app) =>
15-
app.use(
16-
`${app.basePath}/coercion`,
17-
express
18-
.Router()
19-
.post(`/pets`, (req, res) => res.json(req.body))
20-
.post(`/pets_string_boolean`, (req, res) => res.json(req.body)),
21-
),
22+
app.use(`${app.basePath}/coercion`, routes),
23+
);
24+
arrayCoercedApp = await createApp(
25+
{ apiSpec, validateRequests: { coerceTypes: 'array' } },
26+
3006,
27+
(appWithCoerceTypes) =>
28+
appWithCoerceTypes.use(
29+
`${appWithCoerceTypes.basePath}/coercion`,
30+
routes,
31+
),
2232
);
2333
});
2434

2535
after(() => {
2636
app.server.close();
37+
arrayCoercedApp.server.close();
2738
});
2839

2940
it('should return 400 since is_cat is passed as string not boolean', async () =>
@@ -35,7 +46,9 @@ describe(packageJson.name, () => {
3546
})
3647
.expect(400)
3748
.then((r) => {
38-
expect(r.body.message).to.contain('request/body/is_cat must be boolean');
49+
expect(r.body.message).to.contain(
50+
'request/body/is_cat must be boolean',
51+
);
3952
}));
4053

4154
it('should return 400 when age is passed as string, but number is expected', async () =>
@@ -102,4 +115,15 @@ describe(packageJson.name, () => {
102115
.then((r) => {
103116
expect(r.body.message).to.contain('request/body/is_cat must be string');
104117
}));
118+
119+
it('should return 200 when names is a string and coerce names to be an array', async () =>
120+
request(arrayCoercedApp)
121+
.get(`${arrayCoercedApp.basePath}/coercion/pets_as_array_parameter`)
122+
.query({
123+
filter: { names: 'test' },
124+
})
125+
.expect(200)
126+
.then((r) => {
127+
expect(r.text).to.equal('{"filter":{"names":["test"]}}');
128+
}));
105129
});

Diff for: test/resources/coercion.yaml

+24
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,30 @@ paths:
4646
schema:
4747
$ref: '#/components/schemas/PetStringBoolean'
4848

49+
/coercion/pets_as_array_parameter:
50+
get:
51+
description: Returns pets by name
52+
operationId: addPet
53+
parameters:
54+
- in: query
55+
name: filter
56+
schema:
57+
type: object
58+
additionalProperties: false
59+
properties:
60+
names:
61+
type: array
62+
items:
63+
type: string
64+
responses:
65+
'200':
66+
description: pet response
67+
content:
68+
application/json:
69+
schema:
70+
type: array
71+
items: { $ref: '#/components/schemas/Pet' }
72+
4973
components:
5074
schemas:
5175
Pet:

0 commit comments

Comments
 (0)