Skip to content

Commit

Permalink
fixes #402 500 on empty body for undeclared content-type (#406)
Browse files Browse the repository at this point in the history
* update chagne log

* (fix) #402 500 on empty request body for undeclared content-type
  • Loading branch information
cdimascio committed Oct 22, 2020
1 parent b90ddc1 commit e10d863
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 43 deletions.
11 changes: 11 additions & 0 deletions CHANGE_HISTORY.md
@@ -1,3 +1,14 @@
## <small>4.2.1 (2020-10-14)</small>

* add readonly required test using allOf ([cbd6292](https://github.com/cdimascio/express-openapi-validator/commit/cbd6292))
* increment patch version ([2231fde](https://github.com/cdimascio/express-openapi-validator/commit/2231fde))
* update change history ([cae389c](https://github.com/cdimascio/express-openapi-validator/commit/cae389c))
* Update README.md ([8e9678d](https://github.com/cdimascio/express-openapi-validator/commit/8e9678d))
* docs: add ownagedj as a contributor (#399) ([1a8779f](https://github.com/cdimascio/express-openapi-validator/commit/1a8779f)), closes [#399](https://github.com/cdimascio/express-openapi-validator/issues/399)
* fix: optional requestBody handling / add tests (#398) ([5b3d32a](https://github.com/cdimascio/express-openapi-validator/commit/5b3d32a)), closes [#398](https://github.com/cdimascio/express-openapi-validator/issues/398)



## 4.2.0 (2020-10-08)

* Create dependabot.yml ([b57116c](https://github.com/cdimascio/express-openapi-validator/commit/b57116c))
Expand Down
19 changes: 6 additions & 13 deletions src/middlewares/parsers/body.parse.ts
Expand Up @@ -68,27 +68,20 @@ export class BodySchemaParser {
}

if (!content) {
if (contentType.contentType !== undefined) {
const msg =
contentType.contentType === 'not_provided'
? 'media type not specified'
: `unsupported media type ${contentType.contentType}`;
throw new UnsupportedMediaType({ path: path, message: msg });
} else {
content = {};
}
const msg =
contentType.contentType === 'not_provided'
? 'media type not specified'
: `unsupported media type ${contentType.contentType}`;
throw new UnsupportedMediaType({ path: path, message: msg });
}

const schema = this.cleanseContentSchema(content);

return schema ?? content.schema ?? {};
}
return {};
}

private cleanseContentSchema(
content: OpenAPIV3.MediaTypeObject
): BodySchema {
private cleanseContentSchema(content: OpenAPIV3.MediaTypeObject): BodySchema {
let contentRefSchema = null;
if (content.schema && '$ref' in content.schema) {
const resolved = this.ajv.getSchema(content.schema.$ref);
Expand Down
3 changes: 2 additions & 1 deletion test/optional-request-body.spec.ts
Expand Up @@ -15,7 +15,7 @@ describe(packageJson.name, () => {
express.Router().post(`/documents`, (req, res) =>
res.status(201).json({
id: 123,
name: req.body ? req.body.name : ''
name: req.body ? req.body.name : '',
}),
),
),
Expand All @@ -29,6 +29,7 @@ describe(packageJson.name, () => {
it('create document should return 201', async () =>
request(app)
.post(`/documents`)
.set('Content-Type', 'application/json')
.expect(201));

it('return 415', async () =>
Expand Down
70 changes: 41 additions & 29 deletions test/request.bodies.ref.spec.ts
Expand Up @@ -17,19 +17,24 @@ describe(packageJson.name, () => {
unknownFormats: ['phone-number'],
},
3005,
app => {
(app) => {
// Define new coercion routes
app.post(`${app.basePath}/request_bodies_ref`, (req, res) => {
if (req.query.bad_body) {
const r = req.body;
r.unexpected_prop = 'bad';
res.json(r);
} else if (req.header('accept')) {
res.type(req.header('accept')).send(req.body);
} else {
res.json(req.body);
}
});
app
.post(`${app.basePath}/415_test`, (req, res) => ({
success: true,
...req,
}))
.post(`${app.basePath}/request_bodies_ref`, (req, res) => {
if (req.query.bad_body) {
const r = req.body;
r.unexpected_prop = 'bad';
res.json(r);
} else if (req.header('accept')) {
res.type(req.header('accept')).send(req.body);
} else {
res.json(req.body);
}
});
},
true,
);
Expand All @@ -39,6 +44,15 @@ describe(packageJson.name, () => {
app.server.close();
});

it('should return 415 for undeclared media type', async () =>
request(app)
.post(`${app.basePath}/415_test`)
.set('accept', 'text/plain')
.expect(415)
.then((r) => {
expect(r.body.message).includes('unsupported media type');
}));

it('should return 200 if text/plain request body is satisfied', async () => {
const stringData = 'my string data';
return request(app)
Expand All @@ -47,7 +61,7 @@ describe(packageJson.name, () => {
.set('accept', 'text/plain')
.send(stringData)
.expect(200)
.then(r => {
.then((r) => {
expect(r.text).equals(stringData);
});
});
Expand All @@ -60,8 +74,8 @@ describe(packageJson.name, () => {
.set('accept', 'text/html')
.send(stringData)
.expect(200)
.then(r => {
expect(r.get('content-type')).to.contain('text/html')
.then((r) => {
expect(r.get('content-type')).to.contain('text/html');
expect(r.text).equals(stringData);
});
});
Expand All @@ -75,9 +89,9 @@ describe(packageJson.name, () => {
testProperty: 'abc',
})
.expect(200)
.then(r => {
.then((r) => {
const { body } = r;
expect(r.get('content-type')).to.contain('application/ld+json')
expect(r.get('content-type')).to.contain('application/ld+json');
expect(body).to.have.property('testProperty');
});
});
Expand All @@ -91,10 +105,10 @@ describe(packageJson.name, () => {
testPropertyTwo: 'abc',
})
.expect(200)
.then(r => {
.then((r) => {
const { body } = r;
expect(r.get('content-type')).to.contain('application/vnd.api+json')
expect(r.get('content-type')).to.contain(' type=two')
expect(r.get('content-type')).to.contain('application/vnd.api+json');
expect(r.get('content-type')).to.contain(' type=two');
expect(body).to.have.property('testPropertyTwo');
});
});
Expand All @@ -104,7 +118,7 @@ describe(packageJson.name, () => {
.post(`${app.basePath}/request_bodies_ref`)
.send({})
.expect(400)
.then(r => {
.then((r) => {
expect(r.body.errors).to.be.an('array');
expect(r.body.errors).to.have.length(1);
const message = r.body.errors[0].message;
Expand All @@ -120,7 +134,7 @@ describe(packageJson.name, () => {
testProperty: 'abc',
})
.expect(200)
.then(r => {
.then((r) => {
const { body } = r;
expect(body).to.have.property('testProperty');
}));
Expand All @@ -134,9 +148,9 @@ describe(packageJson.name, () => {
testProperty: 'abc',
})
.expect(200)
.then(r => {
.then((r) => {
const { body } = r;
expect(r.get('content-type')).to.contain('application/hal+json')
expect(r.get('content-type')).to.contain('application/hal+json');
expect(body).to.have.property('testProperty');
}));

Expand All @@ -150,7 +164,7 @@ describe(packageJson.name, () => {
testProperty: 'abc',
})
.expect(500)
.then(r => {
.then((r) => {
const { body } = r;
expect(body.message).to.include(
'.response should NOT have additional properties',
Expand All @@ -169,11 +183,9 @@ describe(packageJson.name, () => {
invalidProperty2: 'abc',
})
.expect(400)
.then(r => {
.then((r) => {
const errors = r.body.errors;
expect(errors)
.to.be.an('array')
.with.length(2);
expect(errors).to.be.an('array').with.length(2);
expect(errors[0].path).to.equal('.body.invalidProperty');
expect(errors[0].message).to.equal(
'should NOT have additional properties',
Expand Down
14 changes: 14 additions & 0 deletions test/resources/request.bodies.ref.yaml
Expand Up @@ -8,6 +8,20 @@ servers:
- url: /v1/

paths:
/415_test:
post:
requestBody:
content:
application/json:
schema:
properties:
id:
type: string

responses:
'200':
description: OK

/request_bodies_ref:
post:
parameters:
Expand Down

0 comments on commit e10d863

Please sign in to comment.