Skip to content
This repository has been archived by the owner on Dec 27, 2024. It is now read-only.

Commit

Permalink
feat: response status from test #7
Browse files Browse the repository at this point in the history
Closes #7
  • Loading branch information
joolfe committed Aug 23, 2020
1 parent 0110b59 commit e2afc12
Show file tree
Hide file tree
Showing 5 changed files with 281 additions and 10 deletions.
13 changes: 13 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- Contact and License from variables or by configuration.
- Provide meta-information as a markdown table.
- Path depth configuration.
- Response status code parse from test.

See [Features](#features) section for more details about how to use each of this features.

Expand Down Expand Up @@ -287,6 +288,18 @@ Take into account that `postman-to-openapi` remove from the description all the

Have a look to the collections [PathParams](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/PathParams.json) for examples of how to use this feature.

## Response status code parse from Test

By default the library use the value `200` as the response status code in all the operations, but this can be customize from Postman test "Test" script, if you operation contain a status check in the tests tab as:

```js
pm.response.to.have.status(201)
// or
pm.expect(pm.response.code).to.eql(202)
```

The status code will be automatically parsed and used in the OpenAPI specification.

</div></div>
<div class="tilted-section"><div markdown="1">

Expand Down
29 changes: 20 additions & 9 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async function postmanToOpenApi (input, output, { info = {}, defaultTag = 'defau
}
const {
request: { url: { path, query, protocol, host }, method, body, description: rawDesc, header },
name: summary, tag = defaultTag
name: summary, tag = defaultTag, event: events
} = element
domains.add(calculateDomains(protocol, host))
const joinedPath = calculatePath(path, pathDepth)
Expand All @@ -36,14 +36,7 @@ async function postmanToOpenApi (input, output, { info = {}, defaultTag = 'defau
...(description ? { description } : {}),
...parseBody(body, method),
...parseParameters(query, header, joinedPath, paramsMeta),
responses: {
200: {
description: 'Successful response',
content: {
'application/json': {}
}
}
}
responses: parseResponse(events)
}
}

Expand Down Expand Up @@ -285,4 +278,22 @@ function descriptionParse (description) {
}
}

function parseResponse (events = []) {
let status = 200
const test = events.filter(event => event.listen === 'test')
if (test.length > 0) {
const script = test[0].script.exec.join()
const result = script.match(/\.response\.code\)\.to\.eql\((\d{3})\)|\.to\.have\.status\((\d{3})\)/)
status = (result && result[1] != null) ? result[1] : (result && result[2] != null ? result[2] : status)
}
return {
[status]: {
description: 'Successful response',
content: {
'application/json': {}
}
}
}
}

module.exports = postmanToOpenApi
8 changes: 7 additions & 1 deletion test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const COLLECTION_PATH_PARAMS = './test/resources/input/PathParams.json'
const COLLECTION_MULTIPLE_SERVERS = './test/resources/input/MultipleServers.json'
const COLLECTION_LICENSE_CONTACT = './test/resources/input/LicenseContact.json'
const COLLECTION_DEPTH_PATH_PARAMS = './test/resources/input/DepthPathParams.json'
const COLLECTION_PARSE_STATUS_CODE = './test/resources/input/ParseStatusCode.json'

const EXPECTED_BASIC = readFileSync('./test/resources/output/Basic.yml', 'utf8')
const EXPECTED_INFO_OPTS = readFileSync('./test/resources/output/InfoOpts.yml', 'utf8')
Expand All @@ -40,6 +41,7 @@ const EXPECTED_LICENSE_CONTACT_OPT = readFileSync('./test/resources/output/Licen
const EXPECTED_LICENSE_CONTACT_PARTIAL = readFileSync('./test/resources/output/LicenseContactPartial.yml', 'utf8')
const EXPECTED_LICENSE_CONTACT_PARTIAL_2 = readFileSync('./test/resources/output/LicenseContactPartial2.yml', 'utf8')
const EXPECTED_DEPTH_PATH_PARAMS = readFileSync('./test/resources/output/DepthPathParams.yml', 'utf8')
const EXPECTED_PARSE_STATUS_CODE = readFileSync('./test/resources/output/ParseStatus.yml', 'utf8')

describe('Library specs', function () {
afterEach('remove file', function () {
Expand Down Expand Up @@ -214,7 +216,11 @@ describe('Library specs', function () {

it('should use depth configuration for parse paths', async function () {
const result = await postmanToOpenApi(COLLECTION_DEPTH_PATH_PARAMS, OUTPUT_PATH, { pathDepth: 1 })
console.log(result)
equal(result, EXPECTED_DEPTH_PATH_PARAMS)
})

it('should parse status codes from test', async function () {
const result = await postmanToOpenApi(COLLECTION_PARSE_STATUS_CODE)
equal(result, EXPECTED_PARSE_STATUS_CODE)
})
})
170 changes: 170 additions & 0 deletions test/resources/input/ParseStatusCode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{
"info": {
"_postman_id": "4f3b808c-fc59-4961-b79b-afc95b35fef8",
"name": "Parse Status Code",
"description": "Just a simple collection for test status parsing",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Create new User 201",
"event": [
{
"listen": "test",
"script": {
"id": "671559be-0272-4d09-8d61-44e8862a5311",
"exec": [
"pm.test(\"Status code is 201\", function () {",
" pm.response.to.have.status(201);",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"example\": \"field\",\n \"other\": {\n \"data1\": \"yes\",\n \"data2\": \"no\"\n }\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "https://api.io/users",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"users"
]
},
"description": "Example of a 201 response"
},
"response": []
},
{
"name": "Create new User 202",
"event": [
{
"listen": "test",
"script": {
"id": "2f0b6241-5d9a-4b54-8ed5-b3a2fc61e3b8",
"exec": [
"pm.test(\"Status code is 202\", () => {",
" pm.expect(pm.response.code).to.eql(202);",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"example\": \"field\",\n \"other\": {\n \"data1\": \"yes\",\n \"data2\": \"no\"\n }\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "https://api.io/users/active",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"users",
"active"
]
},
"description": "Example of a 202 response"
},
"response": []
},
{
"name": "Deafult 200",
"event": [
{
"listen": "test",
"script": {
"id": "8e94b168-a75b-4553-9677-a4e22b9cb3d5",
"exec": [
"pm.expect(responseJson.type).to.eql('vip');",
"pm.expect(responseJson.name).to.be.a('string');"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"example\": \"field\",\n \"other\": {\n \"data1\": \"yes\",\n \"data2\": \"no\"\n }\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "https://api.io/users/group",
"protocol": "https",
"host": [
"api",
"io"
],
"path": [
"users",
"group"
]
},
"description": "Example of a 202 response"
},
"response": []
}
],
"event": [
{
"listen": "prerequest",
"script": {
"id": "e886ca61-da78-4ee5-8631-399695de7917",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "6a7981a3-3564-4ef5-83e0-8444f0598f37",
"type": "text/javascript",
"exec": [
""
]
}
}
],
"variable": [
{
"id": "7820b0cd-5643-4df8-881c-f172a6957730",
"key": "version",
"value": "2.3.0"
}
],
"protocolProfileBehavior": {}
}
71 changes: 71 additions & 0 deletions test/resources/output/ParseStatus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
openapi: 3.0.0
info:
title: Parse Status Code
description: Just a simple collection for test status parsing
version: 2.3.0
servers:
- url: 'https://api.io'
paths:
/users:
post:
tags:
- default
summary: Create new User 201
description: Example of a 201 response
requestBody:
content:
application/json:
schema:
type: object
example:
example: field
other:
data1: 'yes'
data2: 'no'
responses:
'201':
description: Successful response
content:
application/json: {}
/users/active:
post:
tags:
- default
summary: Create new User 202
description: Example of a 202 response
requestBody:
content:
application/json:
schema:
type: object
example:
example: field
other:
data1: 'yes'
data2: 'no'
responses:
'202':
description: Successful response
content:
application/json: {}
/users/group:
post:
tags:
- default
summary: Deafult 200
description: Example of a 202 response
requestBody:
content:
application/json:
schema:
type: object
example:
example: field
other:
data1: 'yes'
data2: 'no'
responses:
'200':
description: Successful response
content:
application/json: {}

0 comments on commit e2afc12

Please sign in to comment.