Skip to content

Commit c527b80

Browse files
authored
Merge pull request #706 from postmanlabs/feature/fix-example-accept-header
Fixed issue where Accept header was not present in Example request.
2 parents 9c4dff4 + 4f9dd7b commit c527b80

File tree

5 files changed

+273
-4
lines changed

5 files changed

+273
-4
lines changed

lib/schemaUtils.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,9 +2180,10 @@ module.exports = {
21802180
previewLanguage = 'text',
21812181
responseBodyWrapper,
21822182
header,
2183-
sdkResponse;
2183+
sdkResponse,
2184+
responseMediaTypes;
21842185

2185-
if (!response) {
2186+
if (!_.isObject(response)) {
21862187
return null;
21872188
}
21882189
_.forOwn(response.headers, (value, key) => {
@@ -2215,6 +2216,19 @@ module.exports = {
22152216
code = code.replace(/X|x/g, '0');
22162217
code = code === 'default' ? 500 : _.toSafeInteger(code);
22172218

2219+
responseMediaTypes = _.keys(response.content);
2220+
2221+
if (responseMediaTypes.length > 0) {
2222+
let acceptHeader = new sdk.Header({
2223+
key: 'Accept',
2224+
value: responseMediaTypes[0]
2225+
});
2226+
2227+
if (_.isArray(_.get(originalRequest, 'header'))) {
2228+
originalRequest.header.push(acceptHeader);
2229+
}
2230+
}
2231+
22182232
sdkResponse = new sdk.Response({
22192233
name: response.description,
22202234
code: code || 500,

libV2/schemaUtils.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,9 @@ let QUERYPARAM = 'query',
17851785
reqHeaders = _.clone(request.headers) || [],
17861786
reqQueryParams = _.clone(_.get(request, 'params.queryParams', []));
17871787

1788+
// add Accept header in example's original request headers
1789+
_.isArray(acceptHeader) && (reqHeaders.push(...acceptHeader));
1790+
17881791
if (includeAuthInfoInExample) {
17891792
if (!auth) {
17901793
auth = generateAuthForCollectionFromOpenAPI(context.openapi, context.openapi.security);
@@ -1800,6 +1803,11 @@ let QUERYPARAM = 'query',
18001803
params: _.assign({}, request.params, { queryParams: reqQueryParams })
18011804
});
18021805
}
1806+
else {
1807+
originalRequest = _.assign({}, request, {
1808+
headers: reqHeaders
1809+
});
1810+
}
18031811

18041812
// set accept header value as first found response content's media type
18051813
if (_.isEmpty(requestAcceptHeader)) {
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
{
2+
"openapi": "3.0.2",
3+
"info": {
4+
"title": "svc-activity",
5+
"version": "1.0.0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http:\/\/localhost\/svc\/activity"
10+
}
11+
],
12+
"paths": {
13+
"\/api\/log": {
14+
"post": {
15+
"summary": "Store",
16+
"description": "Create new log item",
17+
"parameters": [
18+
{
19+
"name": "x-hello",
20+
"required": true,
21+
"schema": {
22+
"type": "string"
23+
},
24+
"in": "header"
25+
}
26+
],
27+
"responses": {
28+
"201": {
29+
"description": "201 Created",
30+
"content": {
31+
"application\/json": {
32+
"schema": {
33+
"type": "object",
34+
"properties": {
35+
"success": {
36+
"type": "boolean",
37+
"example": true
38+
}
39+
}
40+
}
41+
}
42+
}
43+
},
44+
"422": {
45+
"description": "422 Validation Errors",
46+
"content": {
47+
"application\/json": {
48+
"schema": {
49+
"$ref": "#\/components\/schemas\/response-validation-errors"
50+
}
51+
}
52+
}
53+
}
54+
}
55+
}
56+
},
57+
"\/api\/logs\/{log}": {
58+
"get": {
59+
"summary": "Show",
60+
"description": "Show one log by id",
61+
"parameters": [
62+
{
63+
"name": "log",
64+
"in": "path",
65+
"description": "Log ID",
66+
"required": true,
67+
"schema": {
68+
"format": "int64",
69+
"type": "integer",
70+
"minimum": 0
71+
},
72+
"example": 1
73+
}
74+
],
75+
"responses": {
76+
"200": {
77+
"description": "200 OK",
78+
"content": {
79+
"application\/json": {
80+
"schema": {
81+
"type": "object",
82+
"required": [
83+
"id",
84+
"metadata",
85+
"timestamp",
86+
"actor",
87+
"action",
88+
"namespace"
89+
],
90+
"properties": {
91+
"id": {
92+
"description": "UUID of the object",
93+
"format": "int64",
94+
"type": "integer",
95+
"example": 12
96+
},
97+
"namespace": {
98+
"description": "Where this actions took, preferably service name. Must be exists before",
99+
"type": "string",
100+
"example": "some-project"
101+
},
102+
"action": {
103+
"description": "What is the action",
104+
"type": "string",
105+
"example": "create_user"
106+
},
107+
"actor": {
108+
"description": "Who took the action, Subject, string, can be id, email, username",
109+
"type": "string",
110+
"example": "email@email.com"
111+
},
112+
"timestamp": {
113+
"format": "date-time",
114+
"type": "string"
115+
},
116+
"metadata": {
117+
"type": "object",
118+
"nullable": true
119+
}
120+
}
121+
}
122+
}
123+
}
124+
},
125+
"404": {
126+
"description": "404 Not Found"
127+
}
128+
}
129+
}
130+
}
131+
},
132+
"components": {
133+
"schemas": {
134+
"response-validation-errors": {
135+
"type": "object",
136+
"properties": {
137+
"message": {
138+
"type": "string",
139+
"example": "The given data was invalid."
140+
},
141+
"errors": {
142+
"type": "object",
143+
"additionalProperties": {
144+
"type": "array",
145+
"items": {
146+
"type": "string"
147+
}
148+
},
149+
"example": {
150+
"field": [
151+
"Something is wrong with this field!"
152+
]
153+
}
154+
}
155+
}
156+
}
157+
}
158+
}
159+
}

test/unit/base.test.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ describe('CONVERT FUNCTION TESTS ', function() {
9090
schemaWithAdditionalProperties =
9191
path.join(__dirname, VALID_OPENAPI_PATH, '/schemaWithAdditionalProperties.yaml'),
9292
specWithNullParams =
93-
path.join(__dirname, VALID_OPENAPI_PATH, '/specWithNullParams.yaml');
93+
path.join(__dirname, VALID_OPENAPI_PATH, '/specWithNullParams.yaml'),
94+
acceptHeaderExample =
95+
path.join(__dirname, VALID_OPENAPI_PATH, '/acceptHeaderExample.json');
9496

9597

9698
it('Should add collection level auth with type as `bearer`' +
@@ -1848,6 +1850,44 @@ describe('CONVERT FUNCTION TESTS ', function() {
18481850
done();
18491851
});
18501852
});
1853+
1854+
it('Should add corresponding Accept header in collection example\'s request correctly', function(done) {
1855+
var openapi = fs.readFileSync(acceptHeaderExample, 'utf8');
1856+
Converter.convertV2({ type: 'string', data: openapi }, {},
1857+
(err, conversionResult) => {
1858+
expect(err).to.be.null;
1859+
expect(conversionResult.result).to.equal(true);
1860+
expect(conversionResult.output.length).to.equal(1);
1861+
expect(conversionResult.output[0].type).to.equal('collection');
1862+
expect(conversionResult.output[0].data).to.have.property('info');
1863+
expect(conversionResult.output[0].data).to.have.property('item');
1864+
expect(conversionResult.output[0].data.item.length).to.equal(1);
1865+
1866+
const item1 = conversionResult.output[0].data.item[0].item[0].item[0].item[0],
1867+
item2 = conversionResult.output[0].data.item[0].item[1].item[0],
1868+
acceptHeader = {
1869+
key: 'Accept',
1870+
value: 'application/json'
1871+
};
1872+
1873+
expect(item1.request.header.length).to.eql(1);
1874+
expect(item1.request.header[0]).to.eql(acceptHeader);
1875+
expect(item1.response[0].originalRequest.header.length).to.eql(1);
1876+
expect(item1.response[0].originalRequest.header[0]).to.eql(acceptHeader);
1877+
expect(item1.response[1].originalRequest.header).to.be.undefined;
1878+
1879+
expect(item2.request.header.length).to.eql(2);
1880+
expect(item2.request.header[0].key).to.eql('x-hello');
1881+
expect(item2.request.header[1]).to.eql(acceptHeader);
1882+
expect(item2.response[0].originalRequest.header.length).to.eql(2);
1883+
expect(item2.response[0].originalRequest.header[0].key).to.eql('x-hello');
1884+
expect(item2.response[0].originalRequest.header[1]).to.eql(acceptHeader);
1885+
expect(item2.response[1].originalRequest.header.length).to.eql(2);
1886+
expect(item2.response[1].originalRequest.header[0].key).to.eql('x-hello');
1887+
expect(item2.response[1].originalRequest.header[1]).to.eql(acceptHeader);
1888+
done();
1889+
});
1890+
});
18511891
});
18521892

18531893
describe('Converting swagger 2.0 files', function() {

test/unit/convertV2.test.js

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ const expect = require('chai').expect,
8585
specWithResponseRef =
8686
path.join(__dirname, VALID_OPENAPI_PATH, '/specWithResponseRef.yaml'),
8787
specWithNullParams =
88-
path.join(__dirname, VALID_OPENAPI_PATH, '/specWithNullParams.yaml');
88+
path.join(__dirname, VALID_OPENAPI_PATH, '/specWithNullParams.yaml'),
89+
acceptHeaderExample =
90+
path.join(__dirname, VALID_OPENAPI_PATH, '/acceptHeaderExample.json');
8991

9092

9193
describe('The convert v2 Function', function() {
@@ -2018,6 +2020,10 @@ describe('The convert v2 Function', function() {
20182020
expect(item.request.header[0].key).to.eql('Accept');
20192021
expect(item.request.header[0].value).to.eql('application/json');
20202022
expect(item.response[0].originalRequest.header[0]).to.be.eql({
2023+
key: 'Accept',
2024+
value: 'application/json'
2025+
});
2026+
expect(item.response[0].originalRequest.header[1]).to.be.eql({
20212027
description: {
20222028
content: 'Added as a part of security scheme: apikey',
20232029
type: 'text/plain'
@@ -2069,6 +2075,10 @@ describe('The convert v2 Function', function() {
20692075
expect(item.request.header[0].key).to.eql('Accept');
20702076
expect(item.request.header[0].value).to.eql('application/json');
20712077
expect(item.response[0].originalRequest.header[0]).to.be.eql({
2078+
key: 'Accept',
2079+
value: 'application/json'
2080+
});
2081+
expect(item.response[0].originalRequest.header[1]).to.be.eql({
20722082
description: {
20732083
content: 'Added as a part of security scheme: oauth1',
20742084
type: 'text/plain'
@@ -2131,4 +2141,42 @@ describe('The convert v2 Function', function() {
21312141
done();
21322142
});
21332143
});
2144+
2145+
it('Should add corresponding Accept header in collection example\'s request correctly', function(done) {
2146+
var openapi = fs.readFileSync(acceptHeaderExample, 'utf8');
2147+
Converter.convertV2({ type: 'string', data: openapi }, {},
2148+
(err, conversionResult) => {
2149+
expect(err).to.be.null;
2150+
expect(conversionResult.result).to.equal(true);
2151+
expect(conversionResult.output.length).to.equal(1);
2152+
expect(conversionResult.output[0].type).to.equal('collection');
2153+
expect(conversionResult.output[0].data).to.have.property('info');
2154+
expect(conversionResult.output[0].data).to.have.property('item');
2155+
expect(conversionResult.output[0].data.item.length).to.equal(1);
2156+
2157+
const item1 = conversionResult.output[0].data.item[0].item[0].item[0].item[0],
2158+
item2 = conversionResult.output[0].data.item[0].item[1].item[0],
2159+
acceptHeader = {
2160+
key: 'Accept',
2161+
value: 'application/json'
2162+
};
2163+
2164+
expect(item1.request.header.length).to.eql(1);
2165+
expect(item1.request.header[0]).to.eql(acceptHeader);
2166+
expect(item1.response[0].originalRequest.header.length).to.eql(1);
2167+
expect(item1.response[0].originalRequest.header[0]).to.eql(acceptHeader);
2168+
expect(item1.response[1].originalRequest.header).to.be.undefined;
2169+
2170+
expect(item2.request.header.length).to.eql(2);
2171+
expect(item2.request.header[0].key).to.eql('x-hello');
2172+
expect(item2.request.header[1]).to.eql(acceptHeader);
2173+
expect(item2.response[0].originalRequest.header.length).to.eql(2);
2174+
expect(item2.response[0].originalRequest.header[0].key).to.eql('x-hello');
2175+
expect(item2.response[0].originalRequest.header[1]).to.eql(acceptHeader);
2176+
expect(item2.response[1].originalRequest.header.length).to.eql(2);
2177+
expect(item2.response[1].originalRequest.header[0].key).to.eql('x-hello');
2178+
expect(item2.response[1].originalRequest.header[1]).to.eql(acceptHeader);
2179+
done();
2180+
});
2181+
});
21342182
});

0 commit comments

Comments
 (0)