From ad7337ad314f3a5d176dce1b3d048a80968d5517 Mon Sep 17 00:00:00 2001 From: Dmytro Pustovit Date: Mon, 20 Jan 2025 17:07:51 +0200 Subject: [PATCH] Fix: fixes request body for swagger --- .eslintrc | 3 +- examples/blog/documentation/swagger.json | 10 ++ examples/chat/app.js | 74 ++++++------- examples/chat/documentation/api-blueprint.md | 7 -- examples/chat/documentation/swagger.json | 26 +++-- examples/chat/test.js | 107 +++++++++---------- src/modules/Action.js | 9 +- src/reporters/Swagger.js | 7 ++ tests/examples/examples-blog.test.js | 2 +- tests/mock/fixtures/reports/swagger.js | 33 ++++++ tests/package/actions.test.js | 7 +- tests/package/seed.test.js | 6 +- tests/reporters/json.test.js | 6 +- 13 files changed, 185 insertions(+), 112 deletions(-) diff --git a/.eslintrc b/.eslintrc index 3ee46c5..aa2cd39 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,8 @@ ], "rules": { "more/no-hardcoded-password": 0, - "unicorn/catch-error-name": 0 + "unicorn/catch-error-name": 0, + "unicorn/text-encoding-identifier-case": 0 }, "overrides": [{ "files": "tests/examples/*test.js", diff --git a/examples/blog/documentation/swagger.json b/examples/blog/documentation/swagger.json index de86197..d4eec62 100644 --- a/examples/blog/documentation/swagger.json +++ b/examples/blog/documentation/swagger.json @@ -26,6 +26,16 @@ "example": "application/json" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "string", + "example": "{\"data\":{\"title\":\"quite cotton although shadow\",\"body\":\"mood income built field throw badly finest seat accurate ago seldom allow invented exactly past garage baseball\",\"thumbnail\":\"http://lakkik.ng/kupa\"}}" + } + } + } + }, "responses": { "201": { "description": "Positive: create blog post", diff --git a/examples/chat/app.js b/examples/chat/app.js index 2531c48..8e52998 100644 --- a/examples/chat/app.js +++ b/examples/chat/app.js @@ -1,37 +1,37 @@ -import jsonServer from 'json-server'; - -const port = process.env.PORT || 3001; -const users = [ { - 'id' : 1, - 'name' : 'Leigh', - 'email' : 'helvy0@feedburner.com' -}, { - 'id' : 2, - 'name' : 'Ancell', - 'email' : 'pancell1@gravatar.com' -}, { - 'id' : 3, - 'name' : 'Conre', - 'email' : 'lconre2@ezinearticles.com' -} ]; - -const messages = [ { - text : 'butter property president flow nodded degree where keep', - sender : 2 -}, { - text : 'cheese tried dig interior watch tone time train living', - sender : 1 -} ]; - -const server = jsonServer.create(); -const router = jsonServer.router({ users, messages }); - -server.use(router); - -if (!process.env.TEST) { - server.listen(port, () => { - console.log(`Chat server is running on ${port}`); - }); -} - -export default server; +import jsonServer from 'json-server'; + +const port = process.env.PORT || 3001; +const users = [ { + 'id' : 1, + 'name' : 'Leigh', + 'email' : 'helvy0@feedburner.com' +}, { + 'id' : 2, + 'name' : 'Ancell', + 'email' : 'pancell1@gravatar.com' +}, { + 'id' : 3, + 'name' : 'Conre', + 'email' : 'lconre2@ezinearticles.com' +} ]; + +const messages = [ { + text : 'butter property president flow nodded degree where keep', + sender : 2 +}, { + text : 'cheese tried dig interior watch tone time train living', + sender : 1 +} ]; + +const server = jsonServer.create(); +const router = jsonServer.router({ users, messages }); + +server.use(router); + +if (!process.env.TEST) { + server.listen(port, () => { + console.log(`Chat server is running on ${port}`); + }); +} + +export default server; diff --git a/examples/chat/documentation/api-blueprint.md b/examples/chat/documentation/api-blueprint.md index 4f02a4c..097968e 100644 --- a/examples/chat/documentation/api-blueprint.md +++ b/examples/chat/documentation/api-blueprint.md @@ -74,18 +74,11 @@ FORMAT: 1A + Headers AUTH: 5NM2p40Z8 - Content-Type: application/json + Parameters sender: 2 limit: 5 - - + Body - - { - "name": "McCoy" - } + Response 200 (application/json) diff --git a/examples/chat/documentation/swagger.json b/examples/chat/documentation/swagger.json index ec77f54..1b5d258 100644 --- a/examples/chat/documentation/swagger.json +++ b/examples/chat/documentation/swagger.json @@ -78,6 +78,24 @@ "example": "application/json" } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "example": { + "name": "McCoy" + }, + "properties": { + "name": { + "type": "string", + "example": "McCoy" + } + } + } + } + } + }, "responses": { "200": { "description": "Positive: change user name", @@ -125,14 +143,6 @@ "type": "string" }, "example": "5NM2p40Z8" - }, - { - "name": "Content-Type", - "in": "header", - "schema": { - "type": "string" - }, - "example": "application/json" } ], "responses": { diff --git a/examples/chat/test.js b/examples/chat/test.js index 92a7aa0..a6d3d30 100644 --- a/examples/chat/test.js +++ b/examples/chat/test.js @@ -1,54 +1,53 @@ -import chronicle, { supertest } from '../../src'; -import app from './app'; - -const request = supertest(app); - -function contextBuilder({ test }) { - return { - title : test.title, - group : test.parent.title - }; -} - -before(async () => { - chronicle.setContextBuilder(contextBuilder); -}); - -suite('Users'); -test('Positive: show user profile', async function () { - await request - .with(this) - .get('/users/:id') - .params({ id: 1 }) - .expect('Content-Type', /json/) - .expect(200); -}); - -test('Positive: change user name', async function () { - await request - .with(this) - .patch('/users/:id') - .params({ id: 2 }) - .set({ 'AUTH': '5NM2p40Z8' }) - .send({ name: 'McCoy' }) - .expect('Content-Type', /json/) - .expect(200); -}); - -suite('Messages'); - -test('Positive: get list of messages', async function () { - await request - .with(this) - .get('/messages?sender=2&limit=5') - .set({ 'AUTH': '5NM2p40Z8' }) - .send({ name: 'McCoy' }) - .expect('Content-Type', /json/) - .expect(200); -}); - -after(async () => { - await chronicle.save('./documentation/swagger.json', { reporter: 'swagger' }); - await chronicle.save('./documentation/api-blueprint.md', { reporter: 'api-blueprint' }); - chronicle.clear(); -}); +import chronicle, { supertest } from '../../src'; +import app from './app'; + +const request = supertest(app); + +function contextBuilder({ test }) { + return { + title : test.title, + group : test.parent.title + }; +} + +before(async () => { + chronicle.setContextBuilder(contextBuilder); +}); + +suite('Users'); +test('Positive: show user profile', async function () { + await request + .with(this) + .get('/users/:id') + .params({ id: 1 }) + .expect('Content-Type', /json/) + .expect(200); +}); + +test('Positive: change user name', async function () { + await request + .with(this) + .patch('/users/:id') + .params({ id: 2 }) + .set({ 'AUTH': '5NM2p40Z8' }) + .send({ name: 'McCoy' }) + .expect('Content-Type', /json/) + .expect(200); +}); + +suite('Messages'); + +test('Positive: get list of messages', async function () { + await request + .with(this) + .get('/messages?sender=2&limit=5') + .set({ 'AUTH': '5NM2p40Z8' }) + .expect('Content-Type', /json/) + .expect(200); +}); + +after(async () => { + await chronicle.save('./documentation/swagger.json', { reporter: 'swagger' }); + await chronicle.save('./documentation/api-blueprint.md', { reporter: 'api-blueprint' }); + chronicle.clear(); +}); diff --git a/src/modules/Action.js b/src/modules/Action.js index f795a0b..c25317c 100644 --- a/src/modules/Action.js +++ b/src/modules/Action.js @@ -165,6 +165,13 @@ export default class Action { return this._request._method || 'GET'; } + get reqContentInfo() { + return { + type : 'application/json', + charset : 'utf-8' + }; + } + get reqHeaders() { return Action.sanitizeHeaders(this._request.headers, this._chronicle.config.headers?.request); } @@ -179,6 +186,7 @@ export default class Action { if (!url) return null; const request = { ...url, + info : this.reqContentInfo, method : this.method, headers : this.reqHeaders }; @@ -214,7 +222,6 @@ export default class Action { get resContentInfo() { return { type : this.info?.type || 'application/json', - // eslint-disable-next-line unicorn/text-encoding-identifier-case charset : this.info?.charset || 'utf-8' }; } diff --git a/src/reporters/Swagger.js b/src/reporters/Swagger.js index 75719a6..93477ba 100644 --- a/src/reporters/Swagger.js +++ b/src/reporters/Swagger.js @@ -61,6 +61,13 @@ export default class SwaggerReporter extends Base { parameters : [ ...this._renderHeaders(request.headers) ], + requestBody : request.body ? { + content : { + [request.info.type] : { + schema : this._renderBody(request.body) + } + } + } : undefined, responses : { [response.status.code] : { description : title, diff --git a/tests/examples/examples-blog.test.js b/tests/examples/examples-blog.test.js index 562e011..57ab36a 100644 --- a/tests/examples/examples-blog.test.js +++ b/tests/examples/examples-blog.test.js @@ -18,7 +18,7 @@ before(async function () { test('blog', async function () { - this.timeout(60*1000) + this.timeout(60 * 1000); await execSync(`npx ava --config ${path.join(exampleFolder, '/ava.config.js ')}`, { env : { ...process.env, diff --git a/tests/mock/fixtures/reports/swagger.js b/tests/mock/fixtures/reports/swagger.js index 401250e..a70c9c6 100644 --- a/tests/mock/fixtures/reports/swagger.js +++ b/tests/mock/fixtures/reports/swagger.js @@ -13,6 +13,39 @@ export const createUserAction = { 'example' : '25NPmT' } ], + 'requestBody' : { + 'content' : { + 'application/json' : { + 'schema' : { + 'type' : 'object', + 'example' : { + 'first_name' : 'Pascal', + 'last_name' : 'Ancell', + 'email' : 'pancell1@gravatar.com', + 'gender' : 'Male' + }, + 'properties' : { + 'first_name' : { + 'type' : 'string', + 'example' : 'Pascal' + }, + 'last_name' : { + 'type' : 'string', + 'example' : 'Ancell' + }, + 'email' : { + 'type' : 'string', + 'example' : 'pancell1@gravatar.com' + }, + 'gender' : { + 'type' : 'string', + 'example' : 'Male' + } + } + } + } + } + }, 'responses' : { '200' : { 'description' : 'create user', diff --git a/tests/package/actions.test.js b/tests/package/actions.test.js index 5f2eee9..c14e83c 100644 --- a/tests/package/actions.test.js +++ b/tests/package/actions.test.js @@ -32,7 +32,12 @@ test('Manually setting required attributes', function () { path : '/api/users', query : { status: 'ACTIVE' }, method : 'GET', - headers : null + headers : null, + 'info' : { + 'charset' : 'utf-8', + 'type' : 'application/json' + } + }); assert.deepOwnInclude(response, { diff --git a/tests/package/seed.test.js b/tests/package/seed.test.js index 438bca9..4d121c2 100644 --- a/tests/package/seed.test.js +++ b/tests/package/seed.test.js @@ -23,7 +23,11 @@ test('POST request', async function () { query : {}, method : 'POST', headers : { Authorization: '25NPmT' }, - body : { + 'info' : { + 'charset' : 'utf-8', + 'type' : 'application/json' + }, + body : { 'first_name' : 'Pascal', 'last_name' : 'Ancell', 'email' : 'pancell1@gravatar.com', diff --git a/tests/reporters/json.test.js b/tests/reporters/json.test.js index d65c812..e5dbc27 100644 --- a/tests/reporters/json.test.js +++ b/tests/reporters/json.test.js @@ -26,7 +26,11 @@ test('Positive: json-reporter with one seed action', async function () { query : {}, method : 'POST', headers : { Authorization: '25NPmT' }, - body : { + 'info' : { + 'charset' : 'utf-8', + 'type' : 'application/json' + }, + body : { 'first_name' : 'Pascal', 'last_name' : 'Ancell', 'email' : 'pancell1@gravatar.com',