This commit is contained in:
2024-05-24 15:27:07 +03:00
parent 17df2ce6a9
commit fc1da2c238
643 changed files with 110185 additions and 231 deletions

View File

@ -0,0 +1,679 @@
module.exports = {
ParameterPrimitiveTestCases,
RequestBodyPrimitiveTestCases,
ResponsePrimitiveTestCases,
}
function ParameterPrimitiveTestCases({
operationDomId,
parameterName,
exampleA, // { value, key }
exampleB, // { value, key }
exampleC,
customUserInput,
customExpectedUrlSubstring,
}) {
it("should render examples options without Modified Value by default", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
.get(operationDomId)
.click()
.get(`tr[data-param-name="${parameterName}"]`)
.find(".examples-select option")
.should("have.length", exampleC ? 3 : 2)
// Ensure the relevant input is disabled
.get(
`tr[data-param-name="${parameterName}"] input, tr[data-param-name="${parameterName}"] textarea`
)
.should("have.attr", "disabled")
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
.get(`.opblock-section-request-body`)
.find(".examples-select option")
.should("have.length", exampleC ? 3 : 2)
})
it("should set default static and Try-It-Out values based on the first member", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Assert on the static docs value
.get(
`tr[data-param-name="${parameterName}"] input,tr[data-param-name="${parameterName}"] textarea`
)
.should("have.value", exampleA.value)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Assert on the Try-It-Out value
.get(
`tr[data-param-name="${parameterName}"] input,tr[data-param-name="${parameterName}"] textarea`
)
.should("have.value", exampleA.value)
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
.get(".request-url")
.contains(
exampleA.serializedValue || `?message=${escape(exampleA.value)}`
)
})
it("should set static and Try-It-Out values based on the second member", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Choose the second example
.get("table.parameters .examples-select > select")
.select(exampleB.key)
// Assert on the static docs value
.get(
`tr[data-param-name="${parameterName}"] input,tr[data-param-name="${parameterName}"] textarea`
)
.should("have.value", exampleB.value)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Assert on the Try-It-Out value
.get(
`tr[data-param-name="${parameterName}"] input,tr[data-param-name="${parameterName}"] textarea`
)
.should("have.value", exampleB.value)
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
.get(".request-url")
.contains(
exampleB.serializedValue
? `?${exampleB.serializedValue}`
: `?message=${escape(exampleB.value)}`
)
})
it("should handle user-entered values correctly", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Modify the input value
.get(
`tr[data-param-name="${parameterName}"] input,tr[data-param-name="${parameterName}"] textarea`
)
.clear()
.type(customUserInput)
// Assert on the active select menu item
.get("table.parameters .examples-select > select")
.find(":selected")
.should("have.text", "[Modified value]")
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
.get(".request-url")
.contains(
customExpectedUrlSubstring || `?message=${escape(customUserInput)}`
)
})
it("should retain user-entered values correctly", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Modify the input value
.get(
`tr[data-param-name="${parameterName}"] input,tr[data-param-name="${parameterName}"] textarea`
)
.clear()
.type(customUserInput)
// Select the first example
.get("table.parameters .examples-select > select")
.select(exampleA.key)
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
.get(".request-url")
.contains(
exampleA.serializedValue
? `?${exampleA.serializedValue}`
: `?message=${escape(exampleA.value)}`
)
// Select the modified value
.get("table.parameters .examples-select > select")
.select("__MODIFIED__VALUE__")
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
.get(".request-url")
.contains(
customExpectedUrlSubstring || `?message=${escape(customUserInput)}`
)
})
}
function RequestBodyPrimitiveTestCases({
operationDomId,
exampleA, // { value, key, summary }
exampleB, // { value, key, summary }
exampleC,
customUserInput,
customUserInputExpectedCurlSubstring,
primaryMediaType = "text/plain",
secondaryMediaType = "text/plain+other",
}) {
it("should render examples options without Modified Value by default", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
.get(operationDomId)
.click()
.get(`.opblock-section-request-body`)
.find(".examples-select option")
.should("have.length", exampleC ? 3 : 2)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
.get(`.opblock-section-request-body`)
.find(".examples-select option")
.should("have.length", exampleC ? 3 : 2)
})
it("should set default static and Try-It-Out values based on the first member", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleA.value)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Assert on the Try-It-Out value
.get(`.opblock-section-request-body textarea`)
.should("have.value", exampleA.value)
// Execute the operation
.get(".execute")
.click()
// Assert on the curl body
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleA.serializedValue || exampleA.value}'`)
})
it("should set default static and Try-It-Out values based on choosing the second member in static mode", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Choose the second example
.get(".opblock-section-request-body .examples-select > select")
.select(exampleB.key)
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleB.value)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Assert on the Try-It-Out value
.get(`.opblock-section-request-body textarea`)
.should("have.value", exampleB.value)
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleB.serializedValue || exampleB.value}'`)
})
it("should set default static and Try-It-Out values based on choosing the second member in Try-It-Out mode", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Choose the second example
.get(".opblock-section-request-body .examples-select > select")
.select(exampleB.key)
// Assert on the Try-It-Out value
.get(`.opblock-section-request-body textarea`)
.should("have.value", exampleB.value)
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleB.serializedValue || exampleB.value}'`)
// Switch to static docs
.get(".try-out__btn")
.click()
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleB.value)
})
it("should return the dropdown entry for an example when manually returning to its value", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleA.value)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Assert on the Try-It-Out value
.get(`.opblock-section-request-body textarea`)
.should("have.value", exampleA.value)
// Clear the Try-It-Out value, replace it with custom value
.clear()
.type(customUserInput)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("have.text", "[Modified value]")
// Modify the value again, going back to the example value
.get(`.opblock-section-request-body textarea`)
.clear()
.type(exampleA.value)
// Assert on the dropdown value returning to the example value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
})
it("should retain choosing a member in static docs when changing the media type", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Choose the second example
.get(".opblock-section-request-body .examples-select > select")
.select(exampleB.key)
// Change the media type
.get(".opblock-section-request-body .content-type")
.select(secondaryMediaType)
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleB.value)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Assert on the Try-It-Out value
.get(`.opblock-section-request-body textarea`)
.should("have.value", exampleB.value)
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleB.serializedValue || exampleB.value}'`)
})
it("should use the first example for the media type when changing the media type without prior interactions with the value", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Change the media type
.get(".opblock-section-request-body .content-type")
.select(secondaryMediaType)
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleA.value)
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Assert on the Try-It-Out value
.get(`.opblock-section-request-body textarea`)
.should("have.value", exampleA.value)
// Execute the operation
.get(".execute")
.click()
// Assert on the request URL
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleA.serializedValue || exampleA.value}'`)
})
it("static mode toggling: mediaType -> example -> mediaType -> example", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Change the media type
.get(".opblock-section-request-body .content-type")
.select(secondaryMediaType)
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleA.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
// Choose exampleB
.get(".opblock-section-request-body .examples-select > select")
.select(exampleB.key)
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleB.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleB.summary)
// Change the media type
.get(".opblock-section-request-body .content-type")
.select(primaryMediaType)
// Assert that the static docs value didn't change
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleB.value)
// Assert that the dropdown value didn't change
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleB.summary)
// Choose exampleA
.get(".opblock-section-request-body .examples-select > select")
.select(exampleA.key)
// Assert on the static docs value
.get(`.opblock-section-request-body .microlight`)
.should("include.text", exampleA.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
})
it("Try-It-Out toggling: mediaType -> example -> mediaType -> example", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Change the media type
.get(".opblock-section-request-body .content-type")
.select(secondaryMediaType)
// Assert on the static docs value
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleA.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
// Choose exampleB
.get(".opblock-section-request-body .examples-select > select")
.select(exampleB.key)
// Assert on the static docs value
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleB.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleB.summary)
// Change the media type
.get(".opblock-section-request-body .content-type")
.select(primaryMediaType)
// Assert that the static docs value didn't change
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleB.value)
// Assert that the dropdown value didn't change
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleB.summary)
// Choose exampleA
.get(".opblock-section-request-body .examples-select > select")
.select(exampleA.key)
// Assert on the static docs value
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleA.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
})
it("Try-It-Out toggling and execution with modified values: mediaType -> modified value -> example -> mediaType -> example", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
// Expand the operation
.get(operationDomId)
.click()
// Switch to Try-It-Out
.get(".try-out__btn")
.click()
// Change the media type
.get(".opblock-section-request-body .content-type")
.select(secondaryMediaType)
// Assert on the static docs value
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleA.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
// Modify the value
.get(`.opblock-section-request-body textarea`)
.clear()
.type(customUserInput)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("have.text", "[Modified value]")
// Fire the operation
.get(".execute")
.click()
// Assert on the curl body
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(
`-d '${customUserInputExpectedCurlSubstring || customUserInput}'`
)
// Choose exampleB
.get(".opblock-section-request-body .examples-select > select")
.select(exampleB.key)
// Assert on the static docs value
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleB.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleB.summary)
// Fire the operation
.get(".execute")
.click()
// Assert on the curl body
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleB.serializedValue || exampleB.value}'`)
// Ensure the modified value is still accessible
.get(".opblock-section-request-body .examples-select > select")
.contains("[Modified value]")
// Change the media type to text/plain
.get(".opblock-section-request-body .content-type")
.select(primaryMediaType)
// Assert that the static docs value didn't change
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleB.value)
// Assert that the dropdown value didn't change
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleB.summary)
// Fire the operation
.get(".execute")
.click()
// Assert on the curl body
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleB.serializedValue || exampleB.value}'`)
// Ensure the modified value is still accessible
.get(".opblock-section-request-body .examples-select > select")
.contains("[Modified value]")
// Choose exampleA
.get(".opblock-section-request-body .examples-select > select")
.select(exampleA.key)
// Assert on the static docs value
.get(`.opblock-section-request-body textarea`)
.should("include.text", exampleA.value)
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
// Fire the operation
.get(".execute")
.click()
// Assert on the curl body
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(`-d '${exampleA.serializedValue || exampleA.value}'`)
// Ensure the modified value is still the same value
.get(".opblock-section-request-body .examples-select > select")
.select("__MODIFIED__VALUE__")
// Assert on the static docs value
.get(`.opblock-section-request-body textarea`)
.should("have.text", customUserInput.replace(/{{}/g, "{"))
// Assert on the dropdown value
.get(".opblock-section-request-body .examples-select > select")
.find(":selected")
.should("have.text", "[Modified value]")
// Fire the operation
.get(".execute")
.click()
// Assert on the curl body
// TODO: use an interceptor instead of curl
.get(".curl")
.contains(
`-d '${customUserInputExpectedCurlSubstring || customUserInput}'`
)
})
// TODO: Try-It-Out + Try-It-Out media type changes
}
function ResponsePrimitiveTestCases({
operationDomId,
exampleA, // { value, key, summary }
exampleB, // { value, key, summary }
exampleC, // { value, key, summary }
}) {
it("should render the first example by default", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
.get(operationDomId)
.click()
.get(".responses-wrapper")
.within(() => {
cy.get(".examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
.get(".microlight")
.should("include.text", exampleA.value)
})
})
it("should render the second example", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
.get(operationDomId)
.click()
.get(".responses-wrapper")
.within(() => {
cy.get(".examples-select > select")
.select(exampleB.key)
.find(":selected")
.should("include.text", exampleB.summary)
.get(".microlight")
.should("include.text", exampleB.value)
})
})
it("should retain an example choice across media types if they share the same example", () => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
.get(operationDomId)
.click()
.get(".responses-wrapper")
.within(() => {
cy
// Change examples
.get(".examples-select > select")
.select(exampleB.key)
// Assert against dropdown value
.find(":selected")
.should("include.text", exampleB.summary)
// Assert against example value
.get(".microlight")
.should("include.text", exampleB.value)
// Change media types
.get(".content-type")
.select("text/plain+other")
// Assert against dropdown value
.get(".examples-select > select")
.find(":selected")
.should("include.text", exampleB.summary)
// Assert against example value
.get(".microlight")
.should("include.text", exampleB.value)
})
})
;(exampleC ? it : it.skip)(
"should reset to the first example if the new media type lacks the current example",
() => {
cy.visit("/?url=/documents/features/multiple-examples-core.openapi.yaml")
.get(operationDomId)
.click()
.get(".responses-wrapper")
.within(() => {
cy
// Change media types
.get(".content-type")
.select("text/plain+other")
// Change examples
.get(".examples-select > select")
.select(exampleC.key)
// Assert against dropdown value
.find(":selected")
.should("include.text", exampleC.summary || exampleC.key)
// Assert against example value
.get(".microlight")
.should("include.text", exampleC.value)
// Change media types
.get(".content-type")
.select("text/plain")
// Assert against dropdown value
.get(".examples-select > select")
.find(":selected")
.should("include.text", exampleA.summary)
// Assert against example value
.get(".microlight")
.should("include.text", exampleA.value)
})
}
)
}

View File

@ -0,0 +1,50 @@
// from https://github.com/pedroetb/node-oauth2-server-example
let Http = require("http")
let path = require("path")
let express = require("express")
let bodyParser = require("body-parser")
let oauthserver = require("oauth2-server")
let cors = require("cors")
let app = express()
app.use(cors())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
app.oauth = oauthserver({
model: require("./model.js"),
grants: ["password", "client_credentials", "implicit"],
debug: true
})
app.all("/oauth/token", app.oauth.grant())
app.get("/swagger.yaml", function (req, res) {
res.sendFile(path.join(__dirname, "swagger.yaml"))
})
app.get("*", app.oauth.authorise(), function (req, res) {
res.send("Secret secrets are no fun, secret secrets hurt someone.")
})
app.use(app.oauth.errorHandler())
function startServer() {
let httpServer = Http.createServer(app)
httpServer.listen("3231")
return function stopServer() {
httpServer.close()
}
}
module.exports = startServer
if (require.main === module) {
// for debugging
startServer()
}

View File

@ -0,0 +1,141 @@
// from https://github.com/pedroetb/node-oauth2-server-example
let config = {
clients: [{
clientId: "application",
clientSecret: "secret"
}],
confidentialClients: [{
clientId: "confidentialApplication",
clientSecret: "topSecret"
}],
tokens: [],
users: [{
id: "123",
username: "swagger",
password: "password"
}]
}
/**
* Dump the memory storage content (for debug).
*/
let dump = function () {
console.log("clients", config.clients)
console.log("confidentialClients", config.confidentialClients)
console.log("tokens", config.tokens)
console.log("users", config.users)
}
/*
* Methods used by all grant types.
*/
let getAccessToken = function (bearerToken, callback) {
let tokens = config.tokens.filter(function (token) {
return token.accessToken === bearerToken
})
return callback(false, tokens[0])
}
let getClient = function (clientId, clientSecret, callback) {
let clients = config.clients.filter(function (client) {
return client.clientId === clientId && client.clientSecret === clientSecret
})
let confidentialClients = config.confidentialClients.filter(function (client) {
return client.clientId === clientId && client.clientSecret === clientSecret
})
callback(false, clients[0] || confidentialClients[0])
}
let grantTypeAllowed = function (clientId, grantType, callback) {
let clientsSource,
clients = []
if (grantType === "password") {
clientsSource = config.clients
} else if (grantType === "client_credentials") {
clientsSource = config.confidentialClients
}
if (clientsSource) {
clients = clientsSource.filter(function (client) {
return client.clientId === clientId
})
}
callback(false, clients.length)
}
let saveAccessToken = function (accessToken, clientId, expires, user, callback) {
config.tokens.push({
accessToken: accessToken,
expires: expires,
clientId: clientId,
user: user
})
callback(false)
}
/*
* Method used only by password grant type.
*/
let getUser = function (username, password, callback) {
let users = config.users.filter(function (user) {
return user.username === username && user.password === password
})
callback(false, users[0])
}
/*
* Method used only by client_credentials grant type.
*/
let getUserFromClient = function (clientId, clientSecret, callback) {
let clients = config.confidentialClients.filter(function (client) {
return client.clientId === clientId && client.clientSecret === clientSecret
})
let user
if (clients.length) {
user = {
username: clientId
}
}
callback(false, user)
}
/**
* Export model definition object.
*/
module.exports = {
getAccessToken: getAccessToken,
getClient: getClient,
grantTypeAllowed: grantTypeAllowed,
saveAccessToken: saveAccessToken,
getUser: getUser,
getUserFromClient: getUserFromClient
}

View File

@ -0,0 +1,36 @@
swagger: "2.0"
host: localhost:3231
paths:
/password:
get:
summary: OAuth2 Password
security:
- oauthPassword: []
responses:
200:
description: OK
schema:
type: string
/application:
get:
summary: OAuth2 Application
security:
- oauthApplication: []
responses:
200:
description: OK
schema:
type: string
securityDefinitions:
oauthPassword:
type: oauth2
flow: password
tokenUrl: /oauth/token
oauthApplication:
type: oauth2
flow: application
tokenUrl: /oauth/token
oauthImplicit:
type: oauth2
flow: implicit
authorizationUrl: /oauth/token