Example (#4730)
* add tests for example feature * refactor ParameterRow value setter logic * aside: fix property access in sampleFromSchema * prioritize media type examples for OAS3 responses * use `example` in schema level example * refactor: move stringify to utils * prioritize media type examples in OAS3 request bodies * modify nightwatch config * fix parameter/response regressions * reorder and broaden default value sources * update lockfile
This commit is contained in:
@@ -19,7 +19,8 @@ describe("bug #4557: default parameter values", function(){
|
||||
specSelectors: {
|
||||
security(){},
|
||||
parameterWithMetaByIdentity(){ return paramValue },
|
||||
isOAS3(){ return false }
|
||||
isOAS3(){ return false },
|
||||
isSwagger2(){ return true }
|
||||
},
|
||||
fn: {},
|
||||
operation: {get: ()=>{}},
|
||||
@@ -52,7 +53,8 @@ describe("bug #4557: default parameter values", function(){
|
||||
specSelectors: {
|
||||
security(){},
|
||||
parameterWithMetaByIdentity(){ return paramValue },
|
||||
isOAS3(){ return true }
|
||||
isOAS3(){ return true },
|
||||
isSwagger2() { return false }
|
||||
},
|
||||
fn: {},
|
||||
operation: {get: ()=>{}},
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
"custom_assertions_path" : "",
|
||||
"page_objects_path" : "test/e2e/pages",
|
||||
"globals_path" : "",
|
||||
"test_workers" : {
|
||||
"enabled" : true,
|
||||
"workers" : "auto"
|
||||
},
|
||||
|
||||
"test_runner" : {
|
||||
"type" : "mocha",
|
||||
|
||||
240
test/e2e/scenarios/features/example.js
Normal file
240
test/e2e/scenarios/features/example.js
Normal file
@@ -0,0 +1,240 @@
|
||||
const dedent = require("dedent")
|
||||
|
||||
describe("feature: `example` field support", function () {
|
||||
|
||||
describe("Swagger 2", function() {
|
||||
|
||||
beforeEach(function (client, done) {
|
||||
client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input:not([disabled])", 5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "/test-specs/features/example.swagger.yaml")
|
||||
.click("button.download-url-button")
|
||||
.waitForElementVisible(".opblock", 10000)
|
||||
.click("#operations-default-put_one")
|
||||
.waitForElementVisible("#operations-default-put_one.is-open", 5000)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
afterEach(function (client, done) {
|
||||
done()
|
||||
})
|
||||
|
||||
// Parameters
|
||||
// Supports complex root `example` values in Schema objects for bodies
|
||||
// Supports nested `example` values in Schema objects for bodies
|
||||
|
||||
describe("primitive parameters", function() {
|
||||
it("should respect a primitive x-example value", function (client) {
|
||||
client
|
||||
.click("button.try-out__btn")
|
||||
.assert.value(
|
||||
`tr[data-param-name="ValidParam"] input[type="text"]`,
|
||||
`12345`
|
||||
)
|
||||
})
|
||||
it("should ignore a primitive example value", function (client) {
|
||||
client
|
||||
.click("button.try-out__btn")
|
||||
.assert.value(
|
||||
`tr[data-param-name="NotValidParam"] input[type="text"]`,
|
||||
``
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("object parameters", function() {
|
||||
it("should correctly consider property-level schema examples", function(client) {
|
||||
client.assert.containsText(`div[data-param-name="body"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"one": "hello!",
|
||||
"two": {
|
||||
"uno": "wow!",
|
||||
"dos": "hey there!"
|
||||
}
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
it("should correctly consider root schema-level schema examples", function(client) {
|
||||
client.assert.containsText(`div[data-param-name="body2"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"foo": "hey",
|
||||
"bar": 123
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
it("should correctly consider nested schema-level schema examples", function(client) {
|
||||
client.assert.containsText(`div[data-param-name="body3"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"one": {
|
||||
"uno": "woohoo!",
|
||||
"dos": "amazing!"
|
||||
}
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("responses", function() {
|
||||
it("should correctly consider schema-level examples", function (client) {
|
||||
client.assert.containsText(`tr.response[data-code="201"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"code": 201,
|
||||
"payload": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "AE2",
|
||||
"name": "Yono"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
it("should correctly consider property-level examples", function (client) {
|
||||
client.assert.containsText(`tr.response[data-code="202"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"code": 202,
|
||||
"payload": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "AE2",
|
||||
"name": "Yono"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("OpenAPI 3.0", function() {
|
||||
beforeEach(function (client, done) {
|
||||
client
|
||||
.url("localhost:3230")
|
||||
.page.main()
|
||||
|
||||
client.waitForElementVisible(".download-url-input:not([disabled])", 5000)
|
||||
.clearValue(".download-url-input")
|
||||
.setValue(".download-url-input", "/test-specs/features/example.openapi.yaml")
|
||||
.click("button.download-url-button")
|
||||
.waitForElementVisible(".opblock-summary-description", 10000)
|
||||
.click("#operations-agent-editAgent")
|
||||
.waitForElementVisible("#operations-agent-editAgent.is-open", 5000)
|
||||
|
||||
done()
|
||||
})
|
||||
|
||||
describe("parameters", function() {
|
||||
it("should respect a primitive example value", function(client) {
|
||||
client
|
||||
.click("button.try-out__btn")
|
||||
.assert.value(
|
||||
`div.parameters-container > div > table > tbody > tr > td.col.parameters-col_description > input[type="text"]`,
|
||||
`12345`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("request bodies", function() {
|
||||
it("should correctly consider media type-level examples", function (client) {
|
||||
client
|
||||
.click(`select.content-type option[value="application/json_media-type-level"]`)
|
||||
.assert.containsText(`pre.body-param__example`,
|
||||
dedent(`
|
||||
{
|
||||
"code": "AE1",
|
||||
"name": "Andrew"
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
it("should correctly consider schema-level examples", function (client) {
|
||||
client
|
||||
.click(`select.content-type option[value="application/json_schema-level"]`)
|
||||
.assert.containsText(`pre.body-param__example`,
|
||||
dedent(`
|
||||
{
|
||||
"code": "AE1",
|
||||
"name": "Andrew"
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
it("should correctly consider property-level examples", function (client) {
|
||||
client
|
||||
.click(`select.content-type option[value="application/json_property-level"]`)
|
||||
.assert.containsText(`pre.body-param__example`,
|
||||
dedent(`
|
||||
{
|
||||
"code": "AE1",
|
||||
"name": "Andrew"
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
})
|
||||
describe("responses", function() {
|
||||
it("should correctly consider media type-level examples", function (client) {
|
||||
client.assert.containsText(`tr.response[data-code="200"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"code": 200,
|
||||
"payload": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "AE2",
|
||||
"name": "Yono"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
it("should correctly consider schema-level examples", function (client) {
|
||||
client.assert.containsText(`tr.response[data-code="201"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"code": 201,
|
||||
"payload": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "AE2",
|
||||
"name": "Yono"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
it("should correctly consider property-level examples", function (client) {
|
||||
client.assert.containsText(`tr.response[data-code="202"] pre`,
|
||||
dedent(`
|
||||
{
|
||||
"code": 202,
|
||||
"payload": [
|
||||
{
|
||||
"id": 1,
|
||||
"code": "AE2",
|
||||
"name": "Yono"
|
||||
}
|
||||
]
|
||||
}
|
||||
`)
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
156
test/e2e/specs/features/example.openapi.yaml
Normal file
156
test/e2e/specs/features/example.openapi.yaml
Normal file
@@ -0,0 +1,156 @@
|
||||
openapi: 3.0.0
|
||||
servers:
|
||||
- url: http://example.com/v1
|
||||
description: Production server version 1
|
||||
- url: http://staging-api.example.com
|
||||
description: Staging server
|
||||
info:
|
||||
description: |
|
||||
This is an API documentation of example.
|
||||
version: "0.1.0"
|
||||
title: Example
|
||||
termsOfService: 'http://www.example.com/terms/'
|
||||
contact:
|
||||
email: developer@example.com
|
||||
license:
|
||||
name: Proprietary license
|
||||
url: 'http://www.example.com/license/'
|
||||
tags:
|
||||
- name: agent
|
||||
description: Access to example
|
||||
paths:
|
||||
/agents/{agentId}:
|
||||
put:
|
||||
tags:
|
||||
- agent
|
||||
summary: Edit agent
|
||||
operationId: editAgent
|
||||
parameters:
|
||||
- in: path
|
||||
name: agentId
|
||||
schema:
|
||||
type: integer
|
||||
example: 12345
|
||||
required: true
|
||||
description: Numeric ID of the paper agent to edit
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json_media-type-level:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
example:
|
||||
code: AE1
|
||||
name: Andrew
|
||||
application/json_schema-level:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
example:
|
||||
code: AE1
|
||||
name: Andrew
|
||||
application/json_property-level:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
example: AE1
|
||||
name:
|
||||
type: string
|
||||
example: Andrew
|
||||
responses:
|
||||
'200':
|
||||
description: media type-level example
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int64
|
||||
payload:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
readOnly: true
|
||||
code:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
example:
|
||||
code: 200
|
||||
payload:
|
||||
- id: 1
|
||||
code: AE2
|
||||
name: Yono
|
||||
'201':
|
||||
description: schema-level example
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int64
|
||||
payload:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
readOnly: true
|
||||
code:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
example:
|
||||
code: 201
|
||||
payload:
|
||||
- id: 1
|
||||
code: AE2
|
||||
name: Yono
|
||||
'202':
|
||||
description: property-level example
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 202
|
||||
payload:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
readOnly: true
|
||||
example: 1
|
||||
code:
|
||||
type: string
|
||||
example: AE2
|
||||
name:
|
||||
type: string
|
||||
example: Yono
|
||||
127
test/e2e/specs/features/example.swagger.yaml
Normal file
127
test/e2e/specs/features/example.swagger.yaml
Normal file
@@ -0,0 +1,127 @@
|
||||
swagger: "2.0"
|
||||
info:
|
||||
description: |
|
||||
This is an API documentation of example.
|
||||
version: "0.1.0"
|
||||
title: Example
|
||||
termsOfService: 'http://www.example.com/terms/'
|
||||
contact:
|
||||
email: developer@example.com
|
||||
license:
|
||||
name: Proprietary license
|
||||
url: 'http://www.example.com/license/'
|
||||
paths:
|
||||
/one:
|
||||
put:
|
||||
parameters:
|
||||
- in: query
|
||||
name: NotValidParam
|
||||
type: integer
|
||||
example: 12345
|
||||
required: true
|
||||
description: This example **should not** have an effect
|
||||
- in: query
|
||||
name: ValidParam
|
||||
type: integer
|
||||
x-example: 12345
|
||||
description: This example **should** have an effect
|
||||
- in: body
|
||||
name: body
|
||||
description: property-level examples
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
one:
|
||||
type: string
|
||||
example: hello!
|
||||
two:
|
||||
type: object
|
||||
properties:
|
||||
uno:
|
||||
type: string
|
||||
example: wow!
|
||||
dos:
|
||||
type: string
|
||||
example: hey there!
|
||||
- in: body
|
||||
name: body2
|
||||
description: root schema-level example
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
foo:
|
||||
type: string
|
||||
bar:
|
||||
type: integer
|
||||
example:
|
||||
foo: hey
|
||||
bar: 123
|
||||
- in: body
|
||||
name: body3
|
||||
description: nested schema-level example
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
one:
|
||||
type: object
|
||||
properties:
|
||||
uno:
|
||||
type: string
|
||||
dos:
|
||||
type: string
|
||||
example:
|
||||
uno: woohoo!
|
||||
dos: amazing!
|
||||
responses:
|
||||
'201':
|
||||
description: schema-level example
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int64
|
||||
payload:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
readOnly: true
|
||||
code:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
example:
|
||||
code: 201
|
||||
payload:
|
||||
- id: 1
|
||||
code: AE2
|
||||
name: Yono
|
||||
'202':
|
||||
description: property-level example
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: integer
|
||||
format: int64
|
||||
example: 202
|
||||
payload:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
format: int64
|
||||
readOnly: true
|
||||
example: 1
|
||||
code:
|
||||
type: string
|
||||
example: AE2
|
||||
name:
|
||||
type: string
|
||||
example: Yono
|
||||
Reference in New Issue
Block a user