feat: migrate unit tests to Jest (#6353)

* config(jest): updated setup
* config(jest): update testMatch to include jsx files
* config(jest): add transformIgnorePatterns
* config(jest): update ignore files that do not work in jest yet
* config: add test:unit-jest to test script

* fix(jest): lint with eslint-plugin-jest

* refactor(jest): move unit test directory
* refactor(mocha): restore mocha tests that fail in jest

* docs(jest): update helpful scripts with test:unit-jest
This commit is contained in:
Tim Lai
2020-09-01 10:41:01 -07:00
committed by GitHub
parent 0c60696d26
commit 1a27c0a8bd
70 changed files with 2131 additions and 1704 deletions

View File

@@ -4,6 +4,7 @@ env:
node: true
es6: true
jest: true
jest/globals: true
parserOptions:
ecmaFeatures:
jsx: true
@@ -14,6 +15,7 @@ plugins:
- react
- mocha
- import
- jest
settings:
react:
pragma: React

View File

@@ -0,0 +1,24 @@
const path = require('path');
module.exports = {
rootDir: path.join(__dirname, '..', '..'),
testEnvironment: 'jsdom',
testMatch: [
'**/test/unit/*.js?(x)',
'**/test/unit/**/*.js?(x)',
],
// testMatch: ['**/test/unit/core/plugins/auth/actions.js'],
setupFilesAfterEnv: ['<rootDir>/test/unit/setup.js'],
testPathIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>/test/build-artifacts/',
'<rootDir>/test/mocha',
'<rootDir>/test/unit/setup.js',
'<rootDir>/test/unit/xss/anchor-target-rel/online-validator-badge.jsx',
'<rootDir>/test/unit/components/online-validator-badge.jsx',
'<rootDir>/test/unit/components/live-response.jsx',
],
transformIgnorePatterns: [
'/node_modules/(?!(react-syntax-highlighter)/)'
]
};

View File

@@ -28,6 +28,7 @@ Script name | Description
--- | ---
`test` | Run unit tests in Node, run Cypress end-to-end tests, and run ESLint in errors-only mode.
`just-test-in-node` | Run Mocha unit tests in Node.
`test:unit-jest` | Run Jest unit tests in Node.
`e2e` | Run end-to-end tests (requires JDK and Selenium).
`e2e-cypress` | Run end-to-end browser tests with Cypress.
`dev-e2e-cypress` | Dev mode, open Cypress runner and manually select tests to run.

236
package-lock.json generated
View File

@@ -4320,6 +4320,88 @@
"@types/node": "*"
}
},
"@typescript-eslint/experimental-utils": {
"version": "2.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz",
"integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.34.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0"
},
"dependencies": {
"eslint-scope": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
"integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
}
}
},
"@typescript-eslint/typescript-estree": {
"version": "2.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz",
"integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==",
"dev": true,
"requires": {
"debug": "^4.1.1",
"eslint-visitor-keys": "^1.1.0",
"glob": "^7.1.6",
"is-glob": "^4.0.1",
"lodash": "^4.17.15",
"semver": "^7.3.2",
"tsutils": "^3.17.1"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
}
}
},
"@webassemblyjs/ast": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
@@ -10506,6 +10588,15 @@
}
}
},
"eslint-plugin-jest": {
"version": "23.20.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz",
"integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "^2.5.0"
}
},
"eslint-plugin-mocha": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz",
@@ -12400,14 +12491,67 @@
"dev": true
},
"function.prototype.name": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.0.tgz",
"integrity": "sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==",
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.2.tgz",
"integrity": "sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg==",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"function-bind": "^1.1.1",
"is-callable": "^1.1.3"
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1",
"functions-have-names": "^1.2.0"
},
"dependencies": {
"es-abstract": {
"version": "1.17.6",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
"integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.2.0",
"is-regex": "^1.1.0",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimend": "^1.0.1",
"string.prototype.trimstart": "^1.0.1"
}
},
"es-to-primitive": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
"dev": true
},
"is-callable": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
"integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
"dev": true
},
"is-regex": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
"dev": true,
"requires": {
"has-symbols": "^1.0.1"
}
}
}
},
"functional-red-black-tree": {
@@ -13399,9 +13543,9 @@
},
"dependencies": {
"readable-stream": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz",
"integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
@@ -22021,10 +22165,67 @@
"dev": true
},
"object-is": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz",
"integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=",
"dev": true
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
"integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
},
"dependencies": {
"es-abstract": {
"version": "1.17.6",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
"integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1",
"is-callable": "^1.2.0",
"is-regex": "^1.1.0",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimend": "^1.0.1",
"string.prototype.trimstart": "^1.0.1"
}
},
"es-to-primitive": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
"dev": true
},
"is-callable": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
"integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==",
"dev": true
},
"is-regex": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
"integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
"dev": true,
"requires": {
"has-symbols": "^1.0.1"
}
}
}
},
"object-keys": {
"version": "1.1.1",
@@ -28420,6 +28621,15 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
},
"tsutils": {
"version": "3.17.1",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
"integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",

View File

@@ -32,7 +32,7 @@
"lint": "eslint --cache --ext \".js,.jsx\" src test",
"lint-errors": "eslint --cache --quiet --ext \".js,.jsx\" src test",
"lint-fix": "eslint --cache --ext \".js,.jsx\" src test --fix",
"test": "run-s just-test-in-node e2e-cypress lint-errors",
"test": "run-s just-test-in-node test:unit-jest e2e-cypress lint-errors",
"test-in-node": "run-s lint-errors just-test-in-node",
"just-test-in-node": "cross-env BABEL_ENV=test mocha \"test/mocha/**/*.{js,jsx}\"",
"test-e2e-cypress": "cypress run",
@@ -41,6 +41,7 @@
"test:artifact:umd:bundle": "npm run build-bundle && cross-env BABEL_ENV=commonjs jest --config ./config/jest/jest.artifact-umd-bundle.config.js",
"test:artifact:es:bundle": "npm run build:es:bundle && cross-env BABEL_ENV=commonjs jest --config ./config/jest/jest.artifact-es-bundle.config.js",
"test:artifact:es:bundle:core": "npm run build:es:bundle:core && cross-env BABEL_ENV=commonjs jest --config ./config/jest/jest.artifact-es-bundle-core.config.js",
"test:unit-jest": "cross-env BABEL_ENV=test jest --config ./config/jest/jest.unit.config.js",
"e2e-initial-render": "nightwatch test/e2e-selenium/scenarios/ --config test/e2e-selenium/nightwatch.json --group initial-render",
"mock-api": "json-server --watch test/e2e-selenium/db.json --port 3204",
"hot-e2e-cypress-server": "webpack-dev-server --config webpack/dev-e2e.babel.js --content-base test/e2e-cypress/static",
@@ -128,6 +129,7 @@
"enzyme": "^2.7.1",
"eslint": "^4.1.1",
"eslint-plugin-import": "^2.21.1",
"eslint-plugin-jest": "=23.20.0",
"eslint-plugin-mocha": "^6.3.0",
"eslint-plugin-react": "^7.20.0",
"esm": "=3.2.25",

View File

@@ -4,4 +4,4 @@ rules:
"react/prop-types": 1 # bah humbug
"react/require-render-return": 1
"no-unused-vars": 1 # unused vars in tests can be useful for indicating a full signature
"no-global-assign": 1
"no-global-assign": 1

7
test/mocha/.eslinrc Normal file
View File

@@ -0,0 +1,7 @@
env:
mocha: true
rules:
"react/prop-types": 1 # bah humbug
"react/require-render-return": 1
"no-unused-vars": 1 # unused vars in tests can be useful for indicating a full signature
"no-global-assign": 1

View File

@@ -7,7 +7,7 @@ import Curl from "components/curl"
import LiveResponse from "components/live-response"
import ResponseBody from "components/response-body"
describe("<LiveResponse/>", function(){
describe("<LiveResponse/>", function () {
let request = fromJSOrdered({
credentials: "same-origin",
headers: {
@@ -35,8 +35,8 @@ describe("<LiveResponse/>", function(){
{ showMutatedRequest: false, expected: { request: "request", requestForCalls: 1, mutatedRequestForCalls: 0 } }
]
tests.forEach(function(test) {
it("passes " + test.expected.request + " to Curl when showMutatedRequest = " + test.showMutatedRequest, function() {
tests.forEach(function (test) {
it("passes " + test.expected.request + " to Curl when showMutatedRequest = " + test.showMutatedRequest, function () {
// Given
@@ -51,7 +51,7 @@ describe("<LiveResponse/>", function(){
})
let mutatedRequestForSpy = createSpy().andReturn(mutatedRequest)
let requestForSpy = createSpy().andReturn(request)
let requestForSpy = createSpy().andReturn(request)
let components = {
curl: Curl,
@@ -59,12 +59,12 @@ describe("<LiveResponse/>", function(){
}
let props = {
response: response,
response: response,
specSelectors: {
mutatedRequestFor: mutatedRequestForSpy,
requestFor: requestForSpy,
},
pathMethod: [ "/one", "get" ],
pathMethod: ["/one", "get"],
getComponent: (c) => {
return components[c]
},
@@ -73,7 +73,7 @@ describe("<LiveResponse/>", function(){
}
// When
let wrapper = shallow(<LiveResponse {...props}/>)
let wrapper = shallow(<LiveResponse {...props} />)
// Then
expect(mutatedRequestForSpy.calls.length).toEqual(test.expected.mutatedRequestForCalls)

View File

@@ -16,7 +16,7 @@ describe("<OnlineValidatorBadge/>", function () {
}
}
const wrapper = mount(
<OnlineValidatorBadge {...props} />
<OnlineValidatorBadge {...props} />
)
// Then

View File

@@ -1,74 +0,0 @@
/* eslint-env mocha */
import expect, { spyOn } from "expect"
import win from "core/window"
import oauth2Authorize from "core/oauth2-authorize"
import * as utils from "core/utils"
describe("oauth2", function () {
let mockSchema = {
flow: "accessCode",
authorizationUrl: "https://testAuthorizationUrl"
}
let authConfig = {
auth: { schema: { get: (key)=> mockSchema[key] } },
authActions: {},
errActions: {},
configs: { oauth2RedirectUrl: "" },
authConfigs: {}
}
describe("authorize redirect", function () {
it("should build authorize url", function() {
const windowOpenSpy = spyOn(win, "open")
oauth2Authorize(authConfig)
expect(windowOpenSpy.calls.length).toEqual(1)
expect(windowOpenSpy.calls[0].arguments[0]).toMatch("https://testAuthorizationUrl?response_type=code&redirect_uri=&state=")
windowOpenSpy.restore()
})
it("should append query parameters to authorizeUrl with query parameters", function() {
const windowOpenSpy = spyOn(win, "open")
mockSchema.authorizationUrl = "https://testAuthorizationUrl?param=1"
oauth2Authorize(authConfig)
expect(windowOpenSpy.calls.length).toEqual(1)
expect(windowOpenSpy.calls[0].arguments[0]).toMatch("https://testAuthorizationUrl?param=1&response_type=code&redirect_uri=&state=")
windowOpenSpy.restore()
})
it("should send code_challenge when using authorizationCode flow with usePkceWithAuthorizationCodeGrant enabled", function () {
const windowOpenSpy = spyOn(win, "open")
mockSchema.flow = "authorizationCode"
const expectedCodeVerifier = "mock_code_verifier"
const expectedCodeChallenge = "mock_code_challenge"
const generateCodeVerifierSpy = spyOn(utils, "generateCodeVerifier").andReturn(expectedCodeVerifier)
const createCodeChallengeSpy = spyOn(utils, "createCodeChallenge").andReturn(expectedCodeChallenge)
authConfig.authConfigs.usePkceWithAuthorizationCodeGrant = true
oauth2Authorize(authConfig)
expect(win.open.calls.length).toEqual(1)
const actualUrl = new URLSearchParams(win.open.calls[0].arguments[0])
expect(actualUrl.get("code_challenge")).toBe(expectedCodeChallenge)
expect(actualUrl.get("code_challenge_method")).toBe("S256")
expect(createCodeChallengeSpy.calls.length).toEqual(1)
expect(createCodeChallengeSpy.calls[0].arguments[0]).toBe(expectedCodeVerifier)
// The code_verifier should be stored to be able to send in
// on the TokenUrl call
expect(authConfig.auth.codeVerifier).toBe(expectedCodeVerifier)
// Restore spies
windowOpenSpy.restore()
generateCodeVerifierSpy.restore()
createCodeChallengeSpy.restore()
})
})
})

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,7 @@ describe("<OnlineValidatorBadge/> Anchor Target Safety", function () {
}
}
const wrapper = mount(
<OnlineValidatorBadge {...props} />
<OnlineValidatorBadge {...props} />
)
const anchor = wrapper.find("a")

0
test/unit/.eslintrc Normal file
View File

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"

View File

@@ -1,7 +1,7 @@
/* eslint-env mocha */
import React from "react"
import { List, fromJS } from "immutable"
import expect, { createSpy } from "expect"
import { render } from "enzyme"
import ParameterRow from "components/parameter-row"
@@ -24,7 +24,7 @@ describe("bug #4557: default parameter values", function(){
},
fn: {},
operation: {get: ()=>{}},
onChange: createSpy(),
onChange: jest.fn(),
param: paramValue,
rawParam: paramValue,
onChangeConsumes: () => {},
@@ -61,7 +61,7 @@ describe("bug #4557: default parameter values", function(){
},
fn: {},
operation: {get: ()=>{}},
onChange: createSpy(),
onChange: jest.fn(),
param: paramValue,
rawParam: paramValue,
onChangeConsumes: () => {},

View File

@@ -1,7 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { mount } from "enzyme"
import FilterContainer from "containers/filter"
import { Col } from "components/layout-utils"

View File

@@ -1,7 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { mount } from "enzyme"
import { fromJS } from "immutable"
import InfoContainer from "containers/info"

View File

@@ -1,7 +1,5 @@
/* eslint-env mocha */
import React from "react"
import Immutable, { List } from "immutable"
import expect, { createSpy } from "expect"
import { Select, Input, TextArea } from "components/layout-utils"
import { mount, render } from "enzyme"
import * as JsonSchemaComponents from "core/json-schema-components"

View File

@@ -0,0 +1,101 @@
import React from "react"
import { fromJSOrdered } from "core/utils"
import { shallow } from "enzyme"
import Curl from "components/curl"
import LiveResponse from "components/live-response"
import ResponseBody from "components/response-body"
describe("<LiveResponse/>", function(){
let request = fromJSOrdered({
credentials: "same-origin",
headers: {
accept: "application/xml"
},
url: "http://petstore.swagger.io/v2/pet/1"
})
let mutatedRequest = fromJSOrdered({
credentials: "same-origin",
headers: {
accept: "application/xml",
mutated: "header"
},
url: "http://mutated.petstore.swagger.io/v2/pet/1"
})
let requests = {
request: request,
mutatedRequest: mutatedRequest
}
const tests = [
{ showMutatedRequest: true, expected: { request: "mutatedRequest", requestForCalls: 0, mutatedRequestForCalls: 1 } },
{ showMutatedRequest: false, expected: { request: "request", requestForCalls: 1, mutatedRequestForCalls: 0 } }
]
tests.forEach(function(test) {
it("passes " + test.expected.request + " to Curl when showMutatedRequest = " + test.showMutatedRequest, function() {
// Given
let response = fromJSOrdered({
status: 200,
url: "http://petstore.swagger.io/v2/pet/1",
headers: {
"content-type": "application/xml"
},
text: "<response/>",
duration: 50
})
let mutatedRequestForSpy = jest.fn().mockImplementation(function(mutatedRequest) { return mutatedRequest })
let requestForSpy = jest.fn().mockImplementation(function(request) { return request })
let components = {
curl: Curl,
responseBody: ResponseBody
}
let props = {
response: response,
specSelectors: {
mutatedRequestFor: mutatedRequestForSpy,
requestFor: requestForSpy,
},
pathMethod: [ "/one", "get" ],
getComponent: (c) => {
return components[c]
},
displayRequestDuration: true,
getConfigs: () => ({ showMutatedRequest: test.showMutatedRequest })
}
// When
let wrapper = shallow(<LiveResponse {...props}/>)
// Then
expect(mutatedRequestForSpy.calls.length).toEqual(test.expected.mutatedRequestForCalls)
expect(requestForSpy.calls.length).toEqual(test.expected.requestForCalls)
const curl = wrapper.find(Curl)
expect(curl.length).toEqual(1)
expect(curl.props().request).toBe(requests[test.expected.request])
const expectedUrl = requests[test.expected.request].get("url")
expect(wrapper.find("div.request-url pre.microlight").text()).toEqual(expectedUrl)
let duration = wrapper.find("Duration")
expect(duration.length).toEqual(1)
expect(duration.props().duration).toEqual(50)
expect(duration.html())
.toEqual("<div><h5>Request duration</h5><pre class=\"microlight\">50 ms</pre></div>")
let responseHeaders = wrapper.find("Headers")
expect(duration.length).toEqual(1)
expect(responseHeaders.props().headers.length).toEqual(1)
expect(responseHeaders.props().headers[0].key).toEqual("content-type")
expect(responseHeaders.html())
.toEqual("<div><h5>Response headers</h5><pre class=\"microlight\"><span class=\"headerline\"> content-type: application/xml </span></pre></div>")
})
})
})

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"
import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.jsx"

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import ModelExample from "components/model-example"
import ModelComponent from "components/model-wrapper"

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import { fromJS, Map } from "immutable"
import Models from "components/models"
@@ -29,7 +27,7 @@ describe("<Models/>", function(){
specResolvedSubtree: () => {}
},
layoutSelectors: {
isShown: createSpy()
isShown: jest.fn()
},
layoutActions: {},
getConfigs: () => ({

View File

@@ -1,14 +1,13 @@
import React from "react"
import expect from "expect"
import { shallow } from "enzyme"
import { fromJS, List } from "immutable"
import { List } from "immutable"
import ObjectModel from "components/object-model"
import ModelExample from "components/model-example"
// import ModelExample from "components/model-example"
import Immutable from "immutable"
import Model from "components/model"
import ModelCollapse from "components/model-collapse"
import Property from "components/property"
import { inferSchema } from "corePlugins/samples/fn"
// import { inferSchema } from "corePlugins/samples/fn"
describe("<ObjectModel />", function() {
const dummyComponent = () => null

View File

@@ -0,0 +1,76 @@
import React from "react"
import { mount } from "enzyme"
import OnlineValidatorBadge from "components/online-validator-badge"
describe("<OnlineValidatorBadge/>", function () {
it("should render a validator link and image correctly for the default validator", function () {
// When
const props = {
getConfigs: () => ({}),
getComponent: () => null,
specSelectors: {
url: () => "swagger.json"
}
}
const wrapper = mount(
<OnlineValidatorBadge {...props} />
)
// Then
expect(wrapper.find("a").props().href).toEqual(
"https://validator.swagger.io/validator/debug?url=swagger.json"
)
expect(wrapper.find("ValidatorImage").length).toEqual(1)
expect(wrapper.find("ValidatorImage").props().src).toEqual(
"https://validator.swagger.io/validator?url=swagger.json"
)
})
it("should encode a definition URL correctly", function () {
// When
const props = {
getConfigs: () => ({}),
getComponent: () => null,
specSelectors: {
url: () => "http://google.com/swagger.json"
}
}
const wrapper = mount(
<OnlineValidatorBadge {...props} />
)
// Then
expect(wrapper.find("a").props().href).toEqual(
"https://validator.swagger.io/validator/debug?url=http%3A%2F%2Fgoogle.com%2Fswagger.json"
)
expect(wrapper.find("ValidatorImage").length).toEqual(1)
expect(wrapper.find("ValidatorImage").props().src).toEqual(
"https://validator.swagger.io/validator?url=http%3A%2F%2Fgoogle.com%2Fswagger.json"
)
})
it.skip("should resolve a definition URL against the browser's location", function () {
// TODO: mock `window`
// When
const props = {
getConfigs: () => ({}),
getComponent: () => null,
specSelectors: {
url: () => "http://google.com/swagger.json"
}
}
const wrapper = mount(
<OnlineValidatorBadge {...props} />
)
// Then
expect(wrapper.find("a").props().href).toEqual(
"https://validator.swagger.io/validator/debug?url=http%3A%2F%2Fgoogle.com%2Fswagger.json"
)
expect(wrapper.find("ValidatorImage").length).toEqual(1)
expect(wrapper.find("ValidatorImage").props().src).toEqual(
"https://validator.swagger.io/validator?url=http%3A%2F%2Fgoogle.com%2Fswagger.json"
)
})
// should resolve a definition URL against the browser's location
})

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import Operation from "components/operation"
@@ -16,7 +14,7 @@ describe("<Operation/>", function(){
shown: true,
showOpId: "",
showOpIdPrefix: "",
toggleCollapse: createSpy()
toggleCollapse: jest.fn()
}
let wrapper = shallow(<Operation {...props}/>)

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import { fromJS } from "immutable"
import DeepLink from "components/deep-link"

View File

@@ -1,7 +1,5 @@
/* eslint-env mocha */
import React from "react"
import { fromJS } from "immutable"
import expect from "expect"
import { render } from "enzyme"
import ParameterRow from "components/parameter-row"

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { shallow } from "enzyme"
import { fromJS } from "immutable"
import PrimitiveModel from "components/primitive-model"

View File

@@ -1,5 +1,4 @@
import React from "react"
import expect from "expect"
import { shallow } from "enzyme"
import ResponseBody from "components/response-body"

View File

@@ -1,5 +1,4 @@
import React from "react"
import expect from "expect"
import { shallow } from "enzyme"
import { fromJS, List } from "immutable"
import Response from "components/response"

View File

@@ -1,8 +1,5 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { mount, render } from "enzyme"
import { mount } from "enzyme"
import { fromJS } from "immutable"
import SchemesContainer from "containers/schemes"
import Schemes from "components/schemes"

View File

@@ -1,7 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import { fromJS } from "immutable"
import Schemes from "components/schemes"
@@ -9,7 +6,7 @@ import Schemes from "components/schemes"
describe("<Schemes/>", function(){
it("calls props.specActions.setScheme() when no currentScheme is selected", function(){
let setSchemeSpy = createSpy()
let setSchemeSpy = jest.fn()
// Given
let props = {
@@ -43,7 +40,7 @@ describe("<Schemes/>", function(){
it("doesn't call props.specActions.setScheme() when schemes hasn't changed", function(){
let setSchemeSpy = createSpy()
let setSchemeSpy = jest.fn()
// Given
let props = {
@@ -61,12 +58,12 @@ describe("<Schemes/>", function(){
let wrapper = shallow(<Schemes {...props}/>)
// Should be called initially, to set the global state
expect(setSchemeSpy.calls.length).toEqual(1)
expect(setSchemeSpy.mock.calls.length).toEqual(1)
// After an update
wrapper.instance().componentWillReceiveProps(props)
// Should not be called again, since `currentScheme` is in schemes
expect(setSchemeSpy.calls.length).toEqual(1)
expect(setSchemeSpy.mock.calls.length).toEqual(1)
})
})

View File

@@ -1,8 +1,5 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import { fromJS, Map } from "immutable"
import VersionPragmaFilter from "components/version-pragma-filter"
describe("<VersionPragmaFilter/>", function(){

View File

@@ -1,4 +1,3 @@
import expect from "expect"
import Im from "immutable"
import curl from "core/curlify"
import win from "core/window"
@@ -175,9 +174,9 @@ describe("curlify", function () {
})
it("should print a curl with formData and file", function () {
let file = new win.File()
file.name = "file.txt"
file.type = "text/plain"
let file = new win.File([""], "file.txt", { type: "text/plain" })
// file.name = "file.txt"
// file.type = "text/plain"
let req = {
url: "http://example.com",
@@ -195,9 +194,9 @@ describe("curlify", function () {
})
it("should print a curl without form data type if type is unknown", function () {
let file = new win.File()
file.name = "file.txt"
file.type = ""
let file = new win.File([""], "file.txt", { type: "" })
// file.name = "file.txt"
// file.type = ""
let req = {
url: "http://example.com",
@@ -246,12 +245,12 @@ describe("curlify", function () {
expect(curlified).toEqual("curl -X POST \"http://example.com\" -H \"accept: application/json\" -d \"{\\\"id\\\":\\\"foo'bar\\\"}\"")
})
context("given multiple entries with file", function () {
context("and with leading custom header", function () {
describe("given multiple entries with file", function () {
describe("and with leading custom header", function () {
it("should print a proper curl -F", function () {
let file = new win.File()
file.name = "file.txt"
file.type = "text/plain"
let file = new win.File([""], "file.txt", { type: "text/plain" })
// file.name = "file.txt"
// file.type = "text/plain"
let req = {
url: "http://example.com",
@@ -272,11 +271,11 @@ describe("curlify", function () {
})
})
context("and with trailing custom header; e.g. from requestInterceptor appending req.headers", function () {
describe("and with trailing custom header; e.g. from requestInterceptor appending req.headers", function () {
it("should print a proper curl -F", function () {
let file = new win.File()
file.name = "file.txt"
file.type = "text/plain"
let file = new win.File([""], "file.txt", { type: "text/plain" })
// file.name = "file.txt"
// file.type = "text/plain"
let req = {
url: "http://example.com",
@@ -298,11 +297,11 @@ describe("curlify", function () {
})
})
context("POST when header value is 'multipart/form-data' but header name is not 'content-type'", function () {
it("shoud print a proper curl as -d <data>", function () {
let file = new win.File()
file.name = "file.txt"
file.type = "text/plain"
describe("POST when header value is 'multipart/form-data' but header name is not 'content-type'", function () {
it("shoud print a proper curl as -d <data>, when file type is provided", function () {
let file = new win.File([""], "file.txt", { type: "text/plain" })
// file.name = "file.txt"
// file.type = "text/plain"
let req = {
url: "http://example.com",
@@ -318,6 +317,26 @@ describe("curlify", function () {
expect(curlified).toEqual("curl -X POST \"http://example.com\" -H \"x-custom-name: multipart/form-data\" -d {\"id\":\"123\",\"file\":{\"name\":\"file.txt\",\"type\":\"text/plain\"}}")
})
it("shoud print a proper curl as -d <data>, no file type provided", function () {
let file = new win.File([""], "file.txt")
// file.name = "file.txt"
// file.type = "text/plain"
let req = {
url: "http://example.com",
method: "POST",
headers: { "x-custom-name": "multipart/form-data" },
body: {
id: "123",
file
}
}
let curlified = curl(Im.fromJS(req))
expect(curlified).toEqual("curl -X POST \"http://example.com\" -H \"x-custom-name: multipart/form-data\" -d {\"id\":\"123\",\"file\":{\"name\":\"file.txt\"}}")
})
})
it("should escape dollar signs in headers and request body", function () {

View File

@@ -2,7 +2,6 @@
* @prettier
*/
import expect from "expect"
import { fromJS } from "immutable"
import getParameterSchema from "../../../../src/helpers/get-parameter-schema"

View File

@@ -0,0 +1,77 @@
import win from "core/window"
import oauth2Authorize from "core/oauth2-authorize"
import * as utils from "core/utils"
describe("oauth2", () => {
let mockSchema = {
flow: "accessCode",
authorizationUrl: "https://testAuthorizationUrl"
}
let authConfig = {
auth: { schema: { get: (key)=> mockSchema[key] } },
authActions: {},
errActions: {},
configs: { oauth2RedirectUrl: "" },
authConfigs: {}
}
beforeEach(() => {
win.open = jest.fn()
})
describe("authorize redirect", () => {
it("should build authorize url", () => {
const windowOpenSpy = jest.spyOn(win, "open")
oauth2Authorize(authConfig)
expect(windowOpenSpy.mock.calls.length).toEqual(1)
expect(windowOpenSpy.mock.calls[0][0]).toMatch("https://testAuthorizationUrl?response_type=code&redirect_uri=&state=")
windowOpenSpy.mockReset()
})
it("should append query parameters to authorizeUrl with query parameters", () => {
const windowOpenSpy = jest.spyOn(win, "open")
mockSchema.authorizationUrl = "https://testAuthorizationUrl?param=1"
oauth2Authorize(authConfig)
expect(windowOpenSpy.mock.calls.length).toEqual(1)
expect(windowOpenSpy.mock.calls[0][0]).toMatch("https://testAuthorizationUrl?param=1&response_type=code&redirect_uri=&state=")
windowOpenSpy.mockReset()
})
it("should send code_challenge when using authorizationCode flow with usePkceWithAuthorizationCodeGrant enabled", () => {
const windowOpenSpy = jest.spyOn(win, "open")
mockSchema.flow = "authorizationCode"
const expectedCodeVerifier = "mock_code_verifier"
const expectedCodeChallenge = "mock_code_challenge"
const generateCodeVerifierSpy = jest.spyOn(utils, "generateCodeVerifier").mockImplementation(() => expectedCodeVerifier)
const createCodeChallengeSpy = jest.spyOn(utils, "createCodeChallenge").mockImplementation(() => expectedCodeChallenge)
authConfig.authConfigs.usePkceWithAuthorizationCodeGrant = true
oauth2Authorize(authConfig)
expect(win.open.mock.calls.length).toEqual(1)
const actualUrl = new URLSearchParams(win.open.mock.calls[0][0])
expect(actualUrl.get("code_challenge")).toBe(expectedCodeChallenge)
expect(actualUrl.get("code_challenge_method")).toBe("S256")
expect(createCodeChallengeSpy.mock.calls.length).toEqual(1)
expect(createCodeChallengeSpy.mock.calls[0][0]).toBe(expectedCodeVerifier)
// The code_verifier should be stored to be able to send in
// on the TokenUrl call
expect(authConfig.auth.codeVerifier).toBe(expectedCodeVerifier)
// Restore spies
windowOpenSpy.mockReset()
generateCodeVerifierSpy.mockReset()
createCodeChallengeSpy.mockReset()
})
})
})

View File

@@ -1,9 +1,5 @@
/* eslint-env mocha */
import expect, { createSpy } from "expect"
import {
authorizeRequest,
authorizeAccessCodeWithFormParams,
} from "corePlugins/auth/actions"
import { authorizeRequest, authorizeAccessCodeWithFormParams } from "corePlugins/auth/actions"
describe("auth plugin - actions", () => {
@@ -63,7 +59,7 @@ describe("auth plugin - actions", () => {
}
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({}),
authSelectors: {
@@ -85,8 +81,8 @@ describe("auth plugin - actions", () => {
authorizeRequest(data)(system)
// Then
expect(system.fn.fetch.calls.length).toEqual(1)
expect(system.fn.fetch.calls[0].arguments[0]).toInclude({url: expectedFetchUrl})
expect(system.fn.fetch.mock.calls.length).toEqual(1)
expect(system.fn.fetch.mock.calls[0][0]).toEqual(expect.objectContaining({url: expectedFetchUrl}))
})
})
@@ -98,7 +94,7 @@ describe("auth plugin - actions", () => {
}
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({}),
authSelectors: {
@@ -120,9 +116,9 @@ describe("auth plugin - actions", () => {
authorizeRequest(data)(system)
// Then
expect(system.fn.fetch.calls.length).toEqual(1)
expect(system.fn.fetch.mock.calls.length).toEqual(1)
expect(system.fn.fetch.calls[0].arguments[0].url)
expect(system.fn.fetch.mock.calls[0][0].url)
.toEqual("http://google.com/authorize?q=1&myCustomParam=abc123")
})
@@ -134,7 +130,7 @@ describe("auth plugin - actions", () => {
}
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({}),
authSelectors: {
@@ -157,9 +153,9 @@ describe("auth plugin - actions", () => {
authorizeRequest(data)(system)
// Then
expect(system.fn.fetch.calls.length).toEqual(1)
expect(system.fn.fetch.mock.calls.length).toEqual(1)
expect(system.fn.fetch.calls[0].arguments[0].url)
expect(system.fn.fetch.mock.calls[0][0].url)
.toEqual("http://google.com/authorize?q=1&myCustomParam=abc123")
})
})
@@ -177,13 +173,13 @@ describe("auth plugin - actions", () => {
}
const authActions = {
authorizeRequest: createSpy()
authorizeRequest: jest.fn()
}
authorizeAccessCodeWithFormParams(data)({ authActions })
expect(authActions.authorizeRequest.calls.length).toEqual(1)
const actualArgument = authActions.authorizeRequest.calls[0].arguments[0]
expect(authActions.authorizeRequest.mock.calls.length).toEqual(1)
const actualArgument = authActions.authorizeRequest.mock.calls[0][0]
expect(actualArgument.body).toContain("code_verifier=" + data.auth.codeVerifier)
expect(actualArgument.body).toContain("grant_type=authorization_code")
})

View File

@@ -1,5 +1,4 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS } from "immutable"
import { preauthorizeBasic, preauthorizeApiKey } from "corePlugins/auth"
import { authorize } from "corePlugins/auth/actions"

View File

@@ -1,5 +1,4 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS } from "immutable"
import { definitionsToAuthorize, definitionsForRequirements } from "corePlugins/auth/selectors"

View File

@@ -1,5 +1,4 @@
/* eslint-env mocha */
import expect, { createSpy } from "expect"
import { execute } from "corePlugins/auth/spec-wrap-actions"
describe("spec plugin - actions", function(){
@@ -10,18 +9,20 @@ describe("spec plugin - actions", function(){
// Given
const system = {
authSelectors: {
authorized: createSpy().andReturn({some: "security"})
authorized: jest.fn().mockImplementation(() => ({
some: "security"
}))
}
}
const oriExecute = createSpy()
const oriExecute = jest.fn()
// When
let executeFn = execute(oriExecute, system)
executeFn({})
// Then
expect(oriExecute.calls.length).toEqual(1)
expect(oriExecute.calls[0].arguments[0]).toEqual({
expect(oriExecute.mock.calls.length).toEqual(1)
expect(oriExecute.mock.calls[0][0]).toEqual({
extras: {
security: {
some: "security"

View File

@@ -1,12 +1,11 @@
/* eslint-env mocha */
import expect, { createSpy } from "expect"
import { downloadConfig } from "corePlugins/configs/spec-actions"
describe("configs plugin - actions", () => {
describe("downloadConfig", () => {
it("should call the system fetch helper with a provided request", () => {
const fetchSpy = createSpy(async () => {}).andCallThrough()
const fetchSpy = jest.fn(async () => {})
const system = {
fn: {
fetch: fetchSpy

View File

@@ -1,4 +1,3 @@
import expect from "expect"
import { Map, List } from "immutable"
import { transform } from "corePlugins/err/error-transformers/transformers/not-of-type"

View File

@@ -1,5 +1,4 @@
/* eslint-disable no-useless-escape */
import expect from "expect"
import { fromJS } from "immutable"
import { transform } from "corePlugins/err/error-transformers/transformers/parameter-oneof"

View File

@@ -1,6 +1,5 @@
import { Map } from "immutable"
import opsFilter from "corePlugins/filter/opsFilter"
import expect from "expect"
describe("opsFilter", function() {
const taggedOps = Map([["pet"], ["store"], ["user"]])

View File

@@ -1,6 +1,5 @@
import { fromJS } from "immutable"
import { isOAS3, isSwagger2 } from "corePlugins/oas3/helpers"
import expect from "expect"
const isOAS3Shorthand = (version) => isOAS3(fromJS({
openapi: version

View File

@@ -1,5 +1,4 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS } from "immutable"
import reducer from "corePlugins/oas3/reducers"

View File

@@ -1,7 +1,5 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { mount } from "enzyme"
import { fromJS } from "immutable"
import ServersContainer from "core/plugins/oas3/components/servers-container"

View File

@@ -1,4 +1,3 @@
import expect from "expect"
import { fromJS, OrderedMap } from "immutable"
import {

View File

@@ -1,6 +1,5 @@
/* eslint-env mocha */
import expect, { createSpy } from "expect"
import { Map, fromJS } from "immutable"
import { fromJS } from "immutable"
import {
definitionsToAuthorize
} from "corePlugins/oas3/auth-extensions/wrap-selectors"

View File

@@ -1,6 +1,5 @@
/* eslint-env mocha */
import expect, { createSpy } from "expect"
import { Map, fromJS } from "immutable"
import { fromJS } from "immutable"
import {
definitions
} from "corePlugins/oas3/spec-extensions/wrap-selectors"

View File

@@ -1,8 +1,7 @@
import { fromJS } from "immutable"
import { createXMLExample, sampleFromSchema } from "corePlugins/samples/fn"
import expect from "expect"
describe("sampleFromSchema", function() {
describe("sampleFromSchema", () => {
it("handles Immutable.js objects for nested schemas", function () {
let definition = fromJS({
"type": "object",
@@ -238,7 +237,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition, { includeWriteOnly: true })).toEqual(expected)
})
it("returns example value for date-time property", function() {
it("returns example value for date-time property", () => {
let definition = {
type: "string",
format: "date-time"
@@ -249,10 +248,10 @@ describe("sampleFromSchema", function() {
// it would be better to mock Date globally and expect a string - KS 11/18
let expected = new Date().toISOString().substring(0, 20)
expect(sampleFromSchema(definition)).toInclude(expected)
expect(sampleFromSchema(definition)).toContain(expected)
})
it("returns example value for date property", function() {
it("returns example value for date property", () => {
let definition = {
type: "string",
format: "date"
@@ -263,7 +262,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns a UUID for a string with format=uuid", function() {
it("returns a UUID for a string with format=uuid", () => {
let definition = {
type: "string",
format: "uuid"
@@ -274,7 +273,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns a hostname for a string with format=hostname", function() {
it("returns a hostname for a string with format=hostname", () => {
let definition = {
type: "string",
format: "hostname"
@@ -285,7 +284,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns an IPv4 address for a string with format=ipv4", function() {
it("returns an IPv4 address for a string with format=ipv4", () => {
let definition = {
type: "string",
format: "ipv4"
@@ -296,7 +295,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns an IPv6 address for a string with format=ipv6", function() {
it("returns an IPv6 address for a string with format=ipv6", () => {
let definition = {
type: "string",
format: "ipv6"
@@ -307,8 +306,8 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
describe("for array type", function() {
it("returns array with sample of array type", function() {
describe("for array type", () => {
it("returns array with sample of array type", () => {
let definition = {
type: "array",
items: {
@@ -321,7 +320,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of examples for array that has example", function() {
it("returns string for example for array that has example of type string", () => {
let definition = {
type: "array",
items: {
@@ -330,12 +329,12 @@ describe("sampleFromSchema", function() {
example: "dog"
}
let expected = [ "dog" ]
let expected = "dog"
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of examples for array that has examples", function() {
it("returns array of examples for array that has examples", () => {
let definition = {
type: "array",
items: {
@@ -349,7 +348,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of samples for oneOf type", function() {
it("returns array of samples for oneOf type", () => {
let definition = {
type: "array",
items: {
@@ -367,7 +366,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of samples for oneOf types", function() {
it("returns array of samples for oneOf types", () => {
let definition = {
type: "array",
items: {
@@ -388,7 +387,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of samples for oneOf examples", function() {
it("returns array of samples for oneOf examples", () => {
let definition = {
type: "array",
items: {
@@ -411,7 +410,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of samples for anyOf type", function() {
it("returns array of samples for anyOf type", () => {
let definition = {
type: "array",
items: {
@@ -429,7 +428,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of samples for anyOf types", function() {
it("returns array of samples for anyOf types", () => {
let definition = {
type: "array",
items: {
@@ -450,7 +449,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns array of samples for anyOf examples", function() {
it("returns array of samples for anyOf examples", () => {
let definition = {
type: "array",
items: {
@@ -473,7 +472,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns null for a null example", function() {
it("returns null for a null example", () => {
let definition = {
"type": "object",
"properties": {
@@ -492,7 +491,7 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
it("returns null for a null object-level example", function() {
it("returns null for a null object-level example", () => {
let definition = {
"type": "object",
"properties": {

View File

@@ -1,5 +1,4 @@
/* eslint-env mocha */
import expect, { createSpy } from "expect"
import { fromJS } from "immutable"
import { execute, executeRequest, changeParamByIdentity, updateEmptyParamInclusion } from "corePlugins/spec/actions"
@@ -14,7 +13,7 @@ describe("spec plugin - actions", function(){
fetch: 1
},
specActions: {
executeRequest: createSpy()
executeRequest: jest.fn()
},
specSelectors: {
spec: () => fromJS({spec: 1}),
@@ -28,7 +27,7 @@ describe("spec plugin - actions", function(){
executeFn(system)
// Then
expect(system.specActions.executeRequest.calls[0].arguments[0]).toEqual({
expect(system.specActions.executeRequest.calls[0][0]).toEqual({
fetch: 1,
method: "get",
pathName: "/one",
@@ -49,7 +48,7 @@ describe("spec plugin - actions", function(){
const system = {
fn: {},
specActions: {
executeRequest: createSpy()
executeRequest: jest.fn()
},
specSelectors: {
spec: () => fromJS({}),
@@ -63,7 +62,7 @@ describe("spec plugin - actions", function(){
executeFn(system)
// Then
expect(system.specActions.executeRequest.calls[0].arguments[0]).toInclude({hi: "hello"})
expect(system.specActions.executeRequest.calls[0][0]).toContain({hi: "hello"})
})
})
@@ -74,10 +73,10 @@ describe("spec plugin - actions", function(){
const system = {
fn: {
execute: createSpy().andReturn(Promise.resolve())
execute: jest.fn().mockImplementation(() => Promise.resolve({}))
},
specActions: {
setResponse: createSpy()
setResponse: jest.fn()
}
}
@@ -86,9 +85,9 @@ describe("spec plugin - actions", function(){
let res = executeFn(system)
// Then
expect(res).toBeA(Promise)
expect(system.fn.execute.calls.length).toEqual(1)
expect(system.fn.execute.calls[0].arguments[0]).toEqual({
expect(res).toBeInstanceOf(Promise)
expect(system.fn.execute.mock.calls.length).toEqual(1)
expect(system.fn.execute.mock.calls[0][0]).toEqual({
one: 1
})
})
@@ -96,19 +95,19 @@ describe("spec plugin - actions", function(){
it("should pass requestInterceptor/responseInterceptor to fn.execute", async () => {
// Given
let configs = {
requestInterceptor: createSpy(),
responseInterceptor: createSpy()
requestInterceptor: jest.fn(),
responseInterceptor: jest.fn()
}
const system = {
fn: {
buildRequest: createSpy(),
execute: createSpy().andReturn(Promise.resolve())
buildRequest: jest.fn(),
execute: jest.fn().mockImplementation(() => Promise.resolve({}))
},
specActions: {
executeRequest: createSpy(),
setMutatedRequest: createSpy(),
setRequest: createSpy(),
setResponse: createSpy()
executeRequest: jest.fn(),
setMutatedRequest: jest.fn(),
setRequest: jest.fn(),
setResponse: jest.fn()
},
specSelectors: {
spec: () => fromJS({}),
@@ -128,20 +127,20 @@ describe("spec plugin - actions", function(){
await executeFn(system)
// Then
expect(system.fn.execute.calls.length).toEqual(1)
expect(system.fn.execute.calls[0].arguments[0]).toIncludeKey("requestInterceptor")
expect(system.fn.execute.calls[0].arguments[0]).toInclude({
expect(system.fn.execute.mock.calls.length).toEqual(1)
expect(Object.keys(system.fn.execute.mock.calls[0][0])).toContain("requestInterceptor")
expect(system.fn.execute.mock.calls[0][0]).toEqual(expect.objectContaining({
responseInterceptor: configs.responseInterceptor
})
expect(system.specActions.setMutatedRequest.calls.length).toEqual(0)
expect(system.specActions.setRequest.calls.length).toEqual(1)
}))
expect(system.specActions.setMutatedRequest.mock.calls.length).toEqual(0)
expect(system.specActions.setRequest.mock.calls.length).toEqual(1)
let wrappedRequestInterceptor = system.fn.execute.calls[0].arguments[0].requestInterceptor
await wrappedRequestInterceptor(system.fn.execute.calls[0].arguments[0])
expect(configs.requestInterceptor.calls.length).toEqual(1)
expect(system.specActions.setMutatedRequest.calls.length).toEqual(1)
expect(system.specActions.setRequest.calls.length).toEqual(1)
let wrappedRequestInterceptor = system.fn.execute.mock.calls[0][0].requestInterceptor
await wrappedRequestInterceptor(system.fn.execute.mock.calls[0][0])
expect(configs.requestInterceptor.mock.calls.length).toEqual(1)
expect(system.specActions.setMutatedRequest.mock.calls.length).toEqual(1)
expect(system.specActions.setRequest.mock.calls.length).toEqual(1)
})
})
@@ -150,13 +149,13 @@ describe("spec plugin - actions", function(){
const response = {serverResponse: true}
const system = {
fn: {
execute: createSpy().andReturn(Promise.resolve(response))
execute: jest.fn().mockImplementation(() => Promise.resolve(response))
},
specActions: {
setResponse: createSpy()
setResponse: jest.fn()
},
errActions: {
newSpecErr: createSpy()
newSpecErr: jest.fn()
}
}
@@ -178,8 +177,9 @@ describe("spec plugin - actions", function(){
})
})
describe("requestResolvedSubtree", () => {
it("should return a promise ")
describe.skip("requestResolvedSubtree", () => {
it("should return a promise ", function() {
})
})
it.skip("should call errActions.newErr, if the fn.execute rejects", function(){

View File

@@ -1,5 +1,4 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS } from "immutable"
import reducer from "corePlugins/spec/reducers"

File diff suppressed because it is too large Load Diff

View File

@@ -1,56 +1,55 @@
import expect, { createSpy } from "expect"
import { loaded } from "corePlugins/swagger-js/configs-wrap-actions"
describe("swagger-js plugin - withCredentials", () => {
it("should have no effect by default", () => {
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({})
}
const oriExecute = createSpy()
const oriExecute = jest.fn()
const loadedFn = loaded(oriExecute, system)
loadedFn()
expect(oriExecute.calls.length).toBe(1)
expect(oriExecute.mock.calls.length).toBe(1)
expect(system.fn.fetch.withCredentials).toBe(undefined)
})
it("should allow setting flag to true via config", () => {
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({
withCredentials: true
})
}
const oriExecute = createSpy()
const oriExecute = jest.fn()
const loadedFn = loaded(oriExecute, system)
loadedFn()
expect(oriExecute.calls.length).toBe(1)
expect(oriExecute.mock.calls.length).toBe(1)
expect(system.fn.fetch.withCredentials).toBe(true)
})
it("should allow setting flag to false via config", () => {
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({
withCredentials: false
})
}
const oriExecute = createSpy()
const oriExecute = jest.fn()
const loadedFn = loaded(oriExecute, system)
loadedFn()
expect(oriExecute.calls.length).toBe(1)
expect(oriExecute.mock.calls.length).toBe(1)
expect(system.fn.fetch.withCredentials).toBe(false)
})
@@ -58,18 +57,18 @@ describe("swagger-js plugin - withCredentials", () => {
// for query string config
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({
withCredentials: "true"
})
}
const oriExecute = createSpy()
const oriExecute = jest.fn()
const loadedFn = loaded(oriExecute, system)
loadedFn()
expect(oriExecute.calls.length).toBe(1)
expect(oriExecute.mock.calls.length).toBe(1)
expect(system.fn.fetch.withCredentials).toBe(true)
})
@@ -77,18 +76,18 @@ describe("swagger-js plugin - withCredentials", () => {
// for query string config
const system = {
fn: {
fetch: createSpy().andReturn(Promise.resolve())
fetch: jest.fn().mockImplementation(() => Promise.resolve())
},
getConfigs: () => ({
withCredentials: "false"
})
}
const oriExecute = createSpy()
const oriExecute = jest.fn()
const loadedFn = loaded(oriExecute, system)
loadedFn()
expect(oriExecute.calls.length).toBe(1)
expect(oriExecute.mock.calls.length).toBe(1)
expect(system.fn.fetch.withCredentials).toBe(false)
})
})

View File

@@ -1,6 +1,6 @@
/* eslint-env mocha */
import React, { PureComponent } from "react"
import expect from "expect"
import System from "core/system"
import { fromJS } from "immutable"
import { render } from "enzyme"
@@ -755,10 +755,10 @@ describe("bound system", function(){
// When
expect(function() {
expect(() => {
system.register([ThrowyPlugin])
// let resSystem = system.getSystem()
}).toNotThrow()
}).not.toThrow()
})
it("should encapsulate thrown errors in an action creator", function(){
@@ -779,10 +779,10 @@ describe("bound system", function(){
})
expect(function() {
expect(() => {
// TODO: fix existing action error catcher that creates THROWN ERR actions
system.getSystem().throwActions.func()
}).toNotThrow()
}).not.toThrow()
})
it("should encapsulate thrown errors in a reducer", function(){
@@ -811,9 +811,9 @@ describe("bound system", function(){
})
expect(function() {
expect(() => {
system.getSystem().throwActions.func()
}).toNotThrow()
}).not.toThrow()
})
it("should encapsulate thrown errors in a selector", function(){
@@ -834,7 +834,7 @@ describe("bound system", function(){
})
expect(system.getSystem().throwSelectors.func).toNotThrow()
expect(system.getSystem().throwSelectors.func).not.toThrow()
})
it("should encapsulate thrown errors in a complex selector", function(){
@@ -855,7 +855,7 @@ describe("bound system", function(){
})
expect(system.getSystem().throwSelectors.func).toNotThrow()
expect(system.getSystem().throwSelectors.func).not.toThrow()
})
it("should encapsulate thrown errors in a wrapAction", function(){
@@ -884,7 +884,7 @@ describe("bound system", function(){
})
expect(system.getSystem().throwActions.func).toNotThrow()
expect(system.getSystem().throwActions.func).not.toThrow()
})
it("should encapsulate thrown errors in a wrapSelector", function(){
@@ -910,7 +910,7 @@ describe("bound system", function(){
})
expect(system.getSystem().throwSelectors.func).toNotThrow()
expect(system.getSystem().throwSelectors.func).not.toThrow()
})
describe("components", function() {

View File

@@ -1,5 +1,5 @@
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import System from "core/system"

View File

@@ -1,6 +1,5 @@
/* eslint-env mocha */
import expect from "expect"
import { Map, fromJS, OrderedMap } from "immutable"
import { Map, fromJS } from "immutable"
import {
mapToList,
parseSearch,
@@ -41,11 +40,11 @@ import {
import win from "core/window"
describe("utils", function() {
describe("utils", () => {
describe("mapToList", function(){
describe("mapToList", () =>{
it("should convert a map to a list, setting `key`", function(){
it("should convert a map to a list, setting `key`", () =>{
// With
const aMap = fromJS({
a: {
@@ -66,7 +65,7 @@ describe("utils", function() {
])
})
it("should flatten an arbitrarily deep map", function(){
it("should flatten an arbitrarily deep map", () =>{
// With
const aMap = fromJS({
a: {
@@ -96,7 +95,7 @@ describe("utils", function() {
})
it("should handle an empty map", function(){
it("should handle an empty map", () =>{
// With
const aMap = fromJS({})
@@ -109,68 +108,68 @@ describe("utils", function() {
})
describe("extractFileNameFromContentDispositionHeader", function(){
it("should extract quoted filename", function(){
describe("extractFileNameFromContentDispositionHeader", () =>{
it("should extract quoted filename", () =>{
let cdHeader = "attachment; filename=\"file name.jpg\""
let expectedResult = "file name.jpg"
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
})
it("should extract filename", function(){
it("should extract filename", () =>{
let cdHeader = "attachment; filename=filename.jpg"
let expectedResult = "filename.jpg"
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
})
it("should extract quoted filename in utf-8", function(){
it("should extract quoted filename in utf-8", () =>{
let cdHeader = "attachment; filename*=UTF-8''\"%D1%84%D0%B0%D0%B9%D0%BB.txt\""
let expectedResult = "файл.txt"
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
})
it("should extract filename in utf-8", function(){
it("should extract filename in utf-8", () =>{
let cdHeader = "attachment; filename*=utf-8'ru'%D1%84%D0%B0%D0%B9%D0%BB.txt"
let expectedResult = "файл.txt"
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
})
it("should not extract filename and return null", function(){
it("should not extract filename and return null", () =>{
let cdHeader = "attachment; no file name provided"
let expectedResult = null
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
})
})
describe("validateMaximum", function() {
it("doesn't return for valid input", function() {
describe("validateMaximum", () => {
it("doesn't return for valid input", () => {
expect(validateMaximum(9, 10)).toBeFalsy()
expect(validateMaximum(19, 20)).toBeFalsy()
})
it("returns a message for invalid input", function() {
it("returns a message for invalid input", () => {
expect(validateMaximum(1, 0)).toEqual("Value must be less than 0")
expect(validateMaximum(10, 9)).toEqual("Value must be less than 9")
expect(validateMaximum(20, 19)).toEqual("Value must be less than 19")
})
})
describe("validateMinimum", function() {
it("doesn't return for valid input", function() {
describe("validateMinimum", () => {
it("doesn't return for valid input", () => {
expect(validateMinimum(2, 1)).toBeFalsy()
expect(validateMinimum(20, 10)).toBeFalsy()
})
it("returns a message for invalid input", function() {
it("returns a message for invalid input", () => {
expect(validateMinimum(-1, 0)).toEqual("Value must be greater than 0")
expect(validateMinimum(1, 2)).toEqual("Value must be greater than 2")
expect(validateMinimum(10, 20)).toEqual("Value must be greater than 20")
})
})
describe("validateNumber", function() {
describe("validateNumber", () => {
let errorMessage = "Value must be a number"
it("doesn't return for whole numbers", function() {
it("doesn't return for whole numbers", () => {
expect(validateNumber(0)).toBeFalsy()
expect(validateNumber(1)).toBeFalsy()
expect(validateNumber(20)).toBeFalsy()
@@ -182,25 +181,25 @@ describe("utils", function() {
expect(validateNumber(-5000000)).toBeFalsy()
})
it("doesn't return for negative numbers", function() {
it("doesn't return for negative numbers", () => {
expect(validateNumber(-1)).toBeFalsy()
expect(validateNumber(-20)).toBeFalsy()
expect(validateNumber(-5000000)).toBeFalsy()
})
it("doesn't return for decimal numbers", function() {
it("doesn't return for decimal numbers", () => {
expect(validateNumber(1.1)).toBeFalsy()
expect(validateNumber(2.5)).toBeFalsy()
expect(validateNumber(-30.99)).toBeFalsy()
})
it("returns a message for strings", function() {
it("returns a message for strings", () => {
expect(validateNumber("")).toEqual(errorMessage)
expect(validateNumber(" ")).toEqual(errorMessage)
expect(validateNumber("test")).toEqual(errorMessage)
})
it("returns a message for invalid input", function() {
it("returns a message for invalid input", () => {
expect(validateNumber(undefined)).toEqual(errorMessage)
expect(validateNumber(null)).toEqual(errorMessage)
expect(validateNumber({})).toEqual(errorMessage)
@@ -210,10 +209,10 @@ describe("utils", function() {
})
})
describe("validateInteger", function() {
describe("validateInteger", () => {
let errorMessage = "Value must be an integer"
it("doesn't return for positive integers", function() {
it("doesn't return for positive integers", () => {
expect(validateInteger(0)).toBeFalsy()
expect(validateInteger(1)).toBeFalsy()
expect(validateInteger(20)).toBeFalsy()
@@ -225,25 +224,25 @@ describe("utils", function() {
expect(validateInteger(-5000000)).toBeFalsy()
})
it("doesn't return for negative integers", function() {
it("doesn't return for negative integers", () => {
expect(validateInteger(-1)).toBeFalsy()
expect(validateInteger(-20)).toBeFalsy()
expect(validateInteger(-5000000)).toBeFalsy()
})
it("returns a message for decimal values", function() {
it("returns a message for decimal values", () => {
expect(validateInteger(1.1)).toEqual(errorMessage)
expect(validateInteger(2.5)).toEqual(errorMessage)
expect(validateInteger(-30.99)).toEqual(errorMessage)
})
it("returns a message for strings", function() {
it("returns a message for strings", () => {
expect(validateInteger("")).toEqual(errorMessage)
expect(validateInteger(" ")).toEqual(errorMessage)
expect(validateInteger("test")).toEqual(errorMessage)
})
it("returns a message for invalid input", function() {
it("returns a message for invalid input", () => {
expect(validateInteger(undefined)).toEqual(errorMessage)
expect(validateInteger(null)).toEqual(errorMessage)
expect(validateInteger({})).toEqual(errorMessage)
@@ -253,10 +252,10 @@ describe("utils", function() {
})
})
describe("validateFile", function() {
describe("validateFile", () => {
let errorMessage = "Value must be a file"
it("validates against objects which are instances of 'File'", function() {
it("validates against objects which are instances of 'File'", () => {
let fileObj = new win.File([], "Test File")
expect(validateFile(fileObj)).toBeFalsy()
expect(validateFile(null)).toBeFalsy()
@@ -266,23 +265,23 @@ describe("utils", function() {
})
})
describe("validateDateTime", function() {
describe("validateDateTime", () => {
let errorMessage = "Value must be a DateTime"
it("doesn't return for valid dates", function() {
it("doesn't return for valid dates", () => {
expect(validateDateTime("Mon, 25 Dec 1995 13:30:00 +0430")).toBeFalsy()
})
it("returns a message for invalid input'", function() {
it("returns a message for invalid input'", () => {
expect(validateDateTime(null)).toEqual(errorMessage)
expect(validateDateTime("string")).toEqual(errorMessage)
})
})
describe("validateGuid", function() {
describe("validateGuid", () => {
let errorMessage = "Value must be a Guid"
it("doesn't return for valid guid", function() {
it("doesn't return for valid guid", () => {
expect(validateGuid("8ce4811e-cec5-4a29-891a-15d1917153c1")).toBeFalsy()
expect(validateGuid("{8ce4811e-cec5-4a29-891a-15d1917153c1}")).toBeFalsy()
expect(validateGuid("8CE4811E-CEC5-4A29-891A-15D1917153C1")).toBeFalsy()
@@ -291,61 +290,61 @@ describe("utils", function() {
expect(validateGuid("00000000-0000-0000-0000-000000000000")).toBeFalsy()
})
it("returns a message for invalid input'", function() {
it("returns a message for invalid input'", () => {
expect(validateGuid(1)).toEqual(errorMessage)
expect(validateGuid("string")).toEqual(errorMessage)
})
})
describe("validateMaxLength", function() {
it("doesn't return for valid input", function() {
describe("validateMaxLength", () => {
it("doesn't return for valid input", () => {
expect(validateMaxLength("a", 1)).toBeFalsy()
expect(validateMaxLength("abc", 5)).toBeFalsy()
})
it("returns a message for invalid input'", function() {
it("returns a message for invalid input'", () => {
expect(validateMaxLength("abc", 0)).toEqual("Value must be no longer than 0 characters")
expect(validateMaxLength("abc", 1)).toEqual("Value must be no longer than 1 character")
expect(validateMaxLength("abc", 2)).toEqual("Value must be no longer than 2 characters")
})
})
describe("validateMinLength", function() {
it("doesn't return for valid input", function() {
describe("validateMinLength", () => {
it("doesn't return for valid input", () => {
expect(validateMinLength("a", 1)).toBeFalsy()
expect(validateMinLength("abc", 2)).toBeFalsy()
})
it("returns a message for invalid input'", function() {
it("returns a message for invalid input'", () => {
expect(validateMinLength("", 1)).toEqual("Value must be at least 1 character")
expect(validateMinLength("abc", 5)).toEqual("Value must be at least 5 characters")
expect(validateMinLength("abc", 8)).toEqual("Value must be at least 8 characters")
})
})
describe("validatePattern", function() {
describe("validatePattern", () => {
let rxPattern = "^(red|blue)"
let errorMessage = "Value must follow pattern " + rxPattern
it("doesn't return for a match", function() {
it("doesn't return for a match", () => {
expect(validatePattern("red", rxPattern)).toBeFalsy()
expect(validatePattern("blue", rxPattern)).toBeFalsy()
})
it("returns a message for invalid pattern", function() {
it("returns a message for invalid pattern", () => {
expect(validatePattern("pink", rxPattern)).toEqual(errorMessage)
expect(validatePattern("123", rxPattern)).toEqual(errorMessage)
})
it("fails gracefully when an invalid regex value is passed", function() {
expect(() => validatePattern("aValue", "---")).toNotThrow()
expect(() => validatePattern("aValue", 1234)).toNotThrow()
expect(() => validatePattern("aValue", null)).toNotThrow()
expect(() => validatePattern("aValue", [])).toNotThrow()
it("fails gracefully when an invalid regex value is passed", () => {
expect(() => validatePattern("aValue", "---")).not.toThrow()
expect(() => validatePattern("aValue", 1234)).not.toThrow()
expect(() => validatePattern("aValue", null)).not.toThrow()
expect(() => validatePattern("aValue", [])).not.toThrow()
})
})
describe("validateParam", function() {
describe("validateParam", () => {
let param = null
let value = null
let result = null
@@ -377,7 +376,7 @@ describe("utils", function() {
expect( result ).toEqual( expectedError )
}
it("should check the isOAS3 flag when validating parameters", function() {
it("should check the isOAS3 flag when validating parameters", () => {
// This should "skip" validation because there is no `schema` property
// and we are telling `validateParam` this is an OAS3 spec
param = fromJS({
@@ -390,7 +389,7 @@ describe("utils", function() {
expect( result ).toEqual( [] )
})
it("validates required OAS3 objects", function() {
it("validates required OAS3 objects", () => {
// valid object
param = {
required: true,
@@ -436,7 +435,7 @@ describe("utils", function() {
assertValidateOas3Param(param, value, ["Required field is not provided"])
})
it("validates optional OAS3 objects", function() {
it("validates optional OAS3 objects", () => {
// valid object
param = {
schema: {
@@ -478,7 +477,7 @@ describe("utils", function() {
assertValidateOas3Param(param, value, [])
})
it("validates required strings", function() {
it("validates required strings", () => {
// invalid string
param = {
required: true,
@@ -506,7 +505,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("handles OAS3 `Parameter.content`", function() {
it("handles OAS3 `Parameter.content`", () => {
// invalid string
param = {
content: {
@@ -608,7 +607,7 @@ describe("utils", function() {
assertValidateOas3Param(param, value, [])
})
it("validates required strings with min and max length", function() {
it("validates required strings with min and max length", () => {
// invalid string with max length
param = {
required: true,
@@ -637,7 +636,7 @@ describe("utils", function() {
assertValidateParam(param, value, ["Value must be at least 50 characters"])
})
it("validates optional strings", function() {
it("validates optional strings", () => {
// valid (empty) string
param = {
required: false,
@@ -655,7 +654,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("validates required files", function() {
it("validates required files", () => {
// invalid file
param = {
required: true,
@@ -669,11 +668,11 @@ describe("utils", function() {
required: true,
type: "file"
}
value = new win.File()
value = new win.File([""], "file.txt")
assertValidateParam(param, value, [])
})
it("validates optional files", function() {
it("validates optional files", () => {
// invalid file
param = {
required: false,
@@ -695,11 +694,11 @@ describe("utils", function() {
required: false,
type: "file"
}
value = new win.File()
value = new win.File([""], "file.txt")
assertValidateParam(param, value, [])
})
it("validates required arrays", function() {
it("validates required arrays", () => {
// invalid (empty) array
param = {
required: true,
@@ -763,7 +762,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("validates optional arrays", function() {
it("validates optional arrays", () => {
// valid, empty array
param = {
required: false,
@@ -795,7 +794,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("validates required booleans", function() {
it("validates required booleans", () => {
// invalid boolean value
param = {
required: true,
@@ -829,7 +828,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("validates optional booleans", function() {
it("validates optional booleans", () => {
// valid (empty) boolean value
param = {
required: false,
@@ -863,7 +862,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("validates required numbers", function() {
it("validates required numbers", () => {
// invalid number, string instead of a number
param = {
required: true,
@@ -920,7 +919,7 @@ describe("utils", function() {
assertValidateParam(param, value, ["Value must be greater than 0"])
})
it("validates optional numbers", function() {
it("validates optional numbers", () => {
// invalid number, string instead of a number
param = {
required: false,
@@ -946,7 +945,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("validates required integers", function() {
it("validates required integers", () => {
// invalid integer, string instead of an integer
param = {
required: true,
@@ -980,7 +979,7 @@ describe("utils", function() {
assertValidateParam(param, value, [])
})
it("validates optional integers", function() {
it("validates optional integers", () => {
// invalid integer, string instead of an integer
param = {
required: false,
@@ -1131,13 +1130,13 @@ describe("utils", function() {
})
})
describe("createDeepLinkPath", function() {
it("creates a deep link path replacing spaces with underscores", function() {
describe("createDeepLinkPath", () => {
it("creates a deep link path replacing spaces with underscores", () => {
const result = createDeepLinkPath("tag id with spaces")
expect(result).toEqual("tag%20id%20with%20spaces")
})
it("trims input when creating a deep link path", function() {
it("trims input when creating a deep link path", () => {
let result = createDeepLinkPath(" spaces before and after ")
expect(result).toEqual("spaces%20before%20and%20after")
@@ -1145,12 +1144,12 @@ describe("utils", function() {
expect(result).toEqual("")
})
it("creates a deep link path with special characters", function() {
it("creates a deep link path with special characters", () => {
const result = createDeepLinkPath("!@#$%^&*(){}[]")
expect(result).toEqual("!@#$%^&*(){}[]")
})
it("returns an empty string for invalid input", function() {
it("returns an empty string for invalid input", () => {
expect( createDeepLinkPath(null) ).toEqual("")
expect( createDeepLinkPath(undefined) ).toEqual("")
expect( createDeepLinkPath(1) ).toEqual("")
@@ -1159,58 +1158,58 @@ describe("utils", function() {
})
})
describe("escapeDeepLinkPath", function() {
it("creates and escapes a deep link path", function() {
describe("escapeDeepLinkPath", () => {
it("creates and escapes a deep link path", () => {
const result = escapeDeepLinkPath("tag id with spaces?")
expect(result).toEqual("tag_id_with_spaces\\?")
})
it("escapes a deep link path that starts with a number", function() {
it("escapes a deep link path that starts with a number", () => {
const result = escapeDeepLinkPath("123")
expect(result).toEqual("\\31 23")
})
it("escapes a deep link path with a class selector", function() {
it("escapes a deep link path with a class selector", () => {
const result = escapeDeepLinkPath("hello.world")
expect(result).toEqual("hello\\.world")
})
it("escapes a deep link path with an id selector", function() {
it("escapes a deep link path with an id selector", () => {
const result = escapeDeepLinkPath("hello#world")
expect(result).toEqual("hello\\#world")
})
it("escapes a deep link path with a space", function() {
it("escapes a deep link path with a space", () => {
const result = escapeDeepLinkPath("hello world")
expect(result).toEqual("hello_world")
})
it("escapes a deep link path with a percent-encoded space", function() {
it("escapes a deep link path with a percent-encoded space", () => {
const result = escapeDeepLinkPath("hello%20world")
expect(result).toEqual("hello_world")
})
})
describe("getExtensions", function() {
describe("getExtensions", () => {
const objTest = Map([[ "x-test", "a"], ["minimum", "b"]])
it("does not error on empty array", function() {
it("does not error on empty array", () => {
const result1 = getExtensions([])
expect(result1).toEqual([])
const result2 = getCommonExtensions([])
expect(result2).toEqual([])
})
it("gets only the x- keys", function() {
it("gets only the x- keys", () => {
const result = getExtensions(objTest)
expect(result).toEqual(Map([[ "x-test", "a"]]))
})
it("gets the common keys", function() {
it("gets the common keys", () => {
const result = getCommonExtensions(objTest, true)
expect(result).toEqual(Map([[ "minimum", "b"]]))
})
})
describe("deeplyStripKey", function() {
it("should filter out a specified key", function() {
describe("deeplyStripKey", () => {
it("should filter out a specified key", () => {
const input = {
$$ref: "#/this/is/my/ref",
a: {
@@ -1226,7 +1225,7 @@ describe("utils", function() {
})
})
it("should filter out a specified key by predicate", function() {
it("should filter out a specified key by predicate", () => {
const input = {
$$ref: "#/this/is/my/ref",
a: {
@@ -1243,7 +1242,7 @@ describe("utils", function() {
})
})
it("should only call the predicate when the key matches", function() {
it("should only call the predicate when the key matches", () => {
const input = {
$$ref: "#/this/is/my/ref",
a: {
@@ -1261,78 +1260,86 @@ describe("utils", function() {
})
})
describe("parse and serialize search", function() {
afterEach(function() {
describe("parse and serialize search", () => {
beforeEach(() => {
// jsdom in Jest 25+ prevents modifying window.location,
// so we replace with a stubbed version
delete win.location
win.location = {
search: ""
}
})
afterEach(() => {
win.location.search = ""
})
describe("parsing", function() {
it("works with empty search", function() {
describe("parsing", () => {
it("works with empty search", () => {
win.location.search = ""
expect(parseSearch()).toEqual({})
})
it("works with only one key", function() {
it("works with only one key", () => {
win.location.search = "?foo"
expect(parseSearch()).toEqual({foo: ""})
})
it("works with keys and values", function() {
it("works with keys and values", () => {
win.location.search = "?foo=fooval&bar&baz=bazval"
expect(parseSearch()).toEqual({foo: "fooval", bar: "", baz: "bazval"})
})
it("decode url encoded components", function() {
it("decode url encoded components", () => {
win.location.search = "?foo=foo%20bar"
expect(parseSearch()).toEqual({foo: "foo bar"})
})
})
describe("serializing", function() {
it("works with empty map", function() {
describe("serializing", () => {
it("works with empty map", () => {
expect(serializeSearch({})).toEqual("")
})
it("works with multiple keys with and without values", function() {
it("works with multiple keys with and without values", () => {
expect(serializeSearch({foo: "", bar: "barval"})).toEqual("foo=&bar=barval")
})
it("encode url components", function() {
it("encode url components", () => {
expect(serializeSearch({foo: "foo bar"})).toEqual("foo=foo%20bar")
})
})
})
describe("sanitizeUrl", function() {
it("should sanitize a `javascript:` url", function() {
describe("sanitizeUrl", () => {
it("should sanitize a `javascript:` url", () => {
const res = sanitizeUrl("javascript:alert('bam!')")
expect(res).toEqual("about:blank")
})
it("should sanitize a `data:` url", function() {
it("should sanitize a `data:` url", () => {
const res = sanitizeUrl(`data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=`)
expect(res).toEqual("about:blank")
})
it("should not modify a `http:` url", function() {
it("should not modify a `http:` url", () => {
const res = sanitizeUrl(`http://swagger.io/`)
expect(res).toEqual("http://swagger.io/")
})
it("should not modify a `https:` url", function() {
it("should not modify a `https:` url", () => {
const res = sanitizeUrl(`https://swagger.io/`)
expect(res).toEqual("https://swagger.io/")
})
it("should gracefully handle empty strings", function() {
it("should gracefully handle empty strings", () => {
expect(sanitizeUrl("")).toEqual("")
})
it("should gracefully handle non-string values", function() {
it("should gracefully handle non-string values", () => {
expect(sanitizeUrl(123)).toEqual("")
expect(sanitizeUrl(null)).toEqual("")
expect(sanitizeUrl(undefined)).toEqual("")
@@ -1341,9 +1348,9 @@ describe("utils", function() {
})
})
describe("isAbsoluteUrl", function() {
describe("isAbsoluteUrl", () => {
it("check if url is absolute", function() {
it("check if url is absolute", () => {
expect(!!isAbsoluteUrl("http://example.com")).toEqual(true)
expect(!!isAbsoluteUrl("https://secure-example.com")).toEqual(true)
expect(!!isAbsoluteUrl("HTTP://uppercase-example.com")).toEqual(true)
@@ -1353,13 +1360,13 @@ describe("utils", function() {
expect(!!isAbsoluteUrl("//no-protocol.com")).toEqual(true)
})
it("check if url is not absolute", function() {
it("check if url is not absolute", () => {
expect(!!isAbsoluteUrl("/url-relative-to-host/base-path/path")).toEqual(false)
expect(!!isAbsoluteUrl("url-relative-to-base/base-path/path")).toEqual(false)
})
})
describe("buildBaseUrl", function() {
describe("buildBaseUrl", () => {
const specUrl = "https://petstore.swagger.io/v2/swagger.json"
const noServerSelected = ""
@@ -1367,21 +1374,21 @@ describe("utils", function() {
const serverUrlRelativeToBase = "server-example/base-path/path"
const serverUrlRelativeToHost = "/server-example/base-path/path"
it("build base url with no server selected", function() {
it("build base url with no server selected", () => {
expect(buildBaseUrl(noServerSelected, specUrl)).toBe("https://petstore.swagger.io/v2/swagger.json")
})
it("build base url from absolute server url", function() {
it("build base url from absolute server url", () => {
expect(buildBaseUrl(absoluteServerUrl, specUrl)).toBe("https://server-example.com/base-path/path")
})
it("build base url from relative server url", function() {
it("build base url from relative server url", () => {
expect(buildBaseUrl(serverUrlRelativeToBase, specUrl)).toBe("https://petstore.swagger.io/v2/server-example/base-path/path")
expect(buildBaseUrl(serverUrlRelativeToHost, specUrl)).toBe("https://petstore.swagger.io/server-example/base-path/path")
})
})
describe("buildUrl", function() {
describe("buildUrl", () => {
const specUrl = "https://petstore.swagger.io/v2/swagger.json"
const noUrl = ""
@@ -1394,77 +1401,77 @@ describe("utils", function() {
const serverUrlRelativeToBase = "server-example/base-path/path"
const serverUrlRelativeToHost = "/server-example/base-path/path"
it("build no url", function() {
it("build no url", () => {
expect(buildUrl(noUrl, specUrl, { selectedServer: absoluteServerUrl })).toBe(undefined)
expect(buildUrl(noUrl, specUrl, { selectedServer: serverUrlRelativeToBase })).toBe(undefined)
expect(buildUrl(noUrl, specUrl, { selectedServer: serverUrlRelativeToHost })).toBe(undefined)
})
it("build absolute url", function() {
it("build absolute url", () => {
expect(buildUrl(absoluteUrl, specUrl, { selectedServer: absoluteServerUrl })).toBe("https://example.com/base-path/path")
expect(buildUrl(absoluteUrl, specUrl, { selectedServer: serverUrlRelativeToBase })).toBe("https://example.com/base-path/path")
expect(buildUrl(absoluteUrl, specUrl, { selectedServer: serverUrlRelativeToHost })).toBe("https://example.com/base-path/path")
})
it("build relative url with no server selected", function() {
it("build relative url with no server selected", () => {
expect(buildUrl(urlRelativeToBase, specUrl, { selectedServer: noServerSelected })).toBe("https://petstore.swagger.io/v2/relative-url/base-path/path")
expect(buildUrl(urlRelativeToHost, specUrl, { selectedServer: noServerSelected })).toBe("https://petstore.swagger.io/relative-url/base-path/path")
})
it("build relative url with absolute server url", function() {
it("build relative url with absolute server url", () => {
expect(buildUrl(urlRelativeToBase, specUrl, { selectedServer: absoluteServerUrl })).toBe("https://server-example.com/base-path/relative-url/base-path/path")
expect(buildUrl(urlRelativeToHost, specUrl, { selectedServer: absoluteServerUrl })).toBe("https://server-example.com/relative-url/base-path/path")
})
it("build relative url with server url relative to base", function() {
it("build relative url with server url relative to base", () => {
expect(buildUrl(urlRelativeToBase, specUrl, { selectedServer: serverUrlRelativeToBase })).toBe("https://petstore.swagger.io/v2/server-example/base-path/relative-url/base-path/path")
expect(buildUrl(urlRelativeToHost, specUrl, { selectedServer: serverUrlRelativeToBase })).toBe("https://petstore.swagger.io/relative-url/base-path/path")
})
it("build relative url with server url relative to host", function() {
it("build relative url with server url relative to host", () => {
expect(buildUrl(urlRelativeToBase, specUrl, { selectedServer: serverUrlRelativeToHost })).toBe("https://petstore.swagger.io/server-example/base-path/relative-url/base-path/path")
expect(buildUrl(urlRelativeToHost, specUrl, { selectedServer: serverUrlRelativeToHost })).toBe("https://petstore.swagger.io/relative-url/base-path/path")
})
})
describe("requiresValidationURL", function() {
it("Should tell us if we require a ValidationURL", function() {
describe("requiresValidationURL", () => {
it("Should tell us if we require a ValidationURL", () => {
const res = requiresValidationURL("https://example.com")
expect(res).toBe(true)
})
it(".. and localhost is not", function() {
it(".. and localhost is not", () => {
const res = requiresValidationURL("http://localhost")
expect(res).toBe(false)
})
it(".. and neither does 127.0.0.1", function() {
it(".. and neither does 127.0.0.1", () => {
const res = requiresValidationURL("http://127.0.0.1")
expect(res).toBe(false)
})
it(".. even without the proto", function() {
it(".. even without the proto", () => {
const res = requiresValidationURL("127.0.0.1")
expect(res).toBe(false)
})
it(".. and also not with 'none'", function() {
it(".. and also not with 'none'", () => {
const res = requiresValidationURL("none")
expect(res).toBe(false)
})
it(".. and also not with 'none'", function() {
it(".. and also not with 'none'", () => {
const res = requiresValidationURL("none")
expect(res).toBe(false)
})
it(".. and also not with ''", function() {
it(".. and also not with ''", () => {
const res = requiresValidationURL("")
expect(res).toBe(false)
@@ -1472,10 +1479,10 @@ describe("utils", function() {
})
describe("getSampleSchema", function() {
describe("getSampleSchema", () => {
const oriDate = Date
before(function() {
beforeEach(() => {
Date = function () {
this.toISOString = function () {
return "2018-07-07T07:07:05.189Z"
@@ -1483,11 +1490,11 @@ describe("utils", function() {
}
})
after(function() {
afterEach(() => {
Date = oriDate
})
it("should not unnecessarily stringify non-object values", function() {
it("should not unnecessarily stringify non-object values", () => {
// Given
const res = getSampleSchema({
type: "string",
@@ -1499,7 +1506,7 @@ describe("utils", function() {
})
})
describe("paramToIdentifier", function() {
describe("paramToIdentifier", () => {
it("should convert an Immutable parameter map to an identifier", () => {
const param = fromJS({
name: "id",
@@ -1586,13 +1593,13 @@ describe("utils", function() {
error = e
}
expect(error).toBeA(Error)
expect(error.message).toInclude("received a non-Im.Map parameter as input")
expect(error).toBeInstanceOf(Error)
expect(error.message).toContain("received a non-Im.Map parameter as input")
expect(res).toEqual(null)
})
})
describe("paramToValue", function() {
describe("paramToValue", () => {
it("should identify a hash-keyed value", () => {
const param = fromJS({
name: "id",
@@ -1639,16 +1646,16 @@ describe("utils", function() {
})
})
describe("generateCodeVerifier", function() {
describe("generateCodeVerifier", () => {
it("should generate a value of at least 43 characters", () => {
const codeVerifier = generateCodeVerifier()
// Source: https://tools.ietf.org/html/rfc7636#section-4.1
expect(codeVerifier.length).toBeGreaterThanOrEqualTo(43)
expect(codeVerifier.length).toBeGreaterThanOrEqual(43)
})
})
describe("createCodeChallenge", function() {
describe("createCodeChallenge", () => {
it("should hash the input using SHA256 and output the base64 url encoded value", () => {
// The `codeVerifier` has been randomly generated
const codeVerifier = "cY8OJ9MKvZ7hxQeIyRYD7KFmKA5znSFJ2rELysvy2UI"

View File

@@ -1,4 +1,3 @@
const expect = require("expect")
const oauthBlockBuilder = require("../../../docker/configurator/oauth")
const dedent = require("dedent")

View File

@@ -1,4 +1,3 @@
const expect = require("expect")
const translator = require("../../../docker/configurator/translator")
const dedent = require("dedent")
@@ -15,7 +14,7 @@ describe("docker: env translator", function() {
MY_THING: "hey"
}
const onFoundSpy = expect.createSpy()
const onFoundSpy = jest.fn()
const schema = {
MY_THING: {
@@ -29,7 +28,7 @@ describe("docker: env translator", function() {
schema
})
expect(res).toEqual(`myThing: "hey",`)
expect(onFoundSpy.calls.length).toEqual(1)
expect(onFoundSpy.mock.calls.length).toEqual(1)
})

19
test/unit/setup.js Normal file
View File

@@ -0,0 +1,19 @@
import win from "../../src/core/window"
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === "undefined")
.reduce((result, prop) => ({
...result,
[prop]: Object.getOwnPropertyDescriptor(src, prop),
}), {})
Object.defineProperties(target, props)
}
global.window = window
global.document = window.document
global.navigator = {
userAgent: "node.js",
}
copyProps(win, window) // use UI's built-in window wrapper
copyProps(window, global)

View File

@@ -1,5 +1,4 @@
/* eslint-env mocha */
import expect from "expect"
import path from "path"
import getAbsoluteFSPath from "../../../swagger-ui-dist-package/absolute-path"

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import { fromJS } from "immutable"
import Info, { InfoUrl } from "components/info"
@@ -35,8 +33,8 @@ describe("<Info/> Anchor Target Safety", function(){
expect(anchor.html()).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders Contact links with safe `rel` attributes", function () {
@@ -54,8 +52,8 @@ describe("<Info/> Anchor Target Safety", function(){
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders License links with safe `rel` attributes", function () {
@@ -72,8 +70,8 @@ describe("<Info/> Anchor Target Safety", function(){
expect(anchor.attr("href")).toEqual("http://mit.edu/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders termsOfService links with safe `rel` attributes", function () {
@@ -88,8 +86,8 @@ describe("<Info/> Anchor Target Safety", function(){
expect(anchor.attr("href")).toEqual("http://smartbear.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("renders definition URL links with safe `rel` attributes", function () {
@@ -102,7 +100,7 @@ describe("<Info/> Anchor Target Safety", function(){
expect(anchor.attr("href")).toEqual("http://petstore.swagger.io/v2/petstore.json")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
})

View File

@@ -1,8 +1,5 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import { fromJS } from "immutable"
import { Link } from "components/layout-utils"
describe("<Link/> Anchor Target Safety", function () {
@@ -23,8 +20,8 @@ describe("<Link/> Anchor Target Safety", function () {
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("enforces `noreferrer` and `noopener` on target=_blank links", function () {
@@ -38,7 +35,7 @@ describe("<Link/> Anchor Target Safety", function () {
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
})

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"
import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.jsx"
@@ -15,8 +13,8 @@ describe("Markdown Link Anchor Safety", function () {
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("sanitizes raw HTML links", function () {
@@ -26,8 +24,8 @@ describe("Markdown Link Anchor Safety", function () {
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
})
@@ -40,8 +38,8 @@ describe("Markdown Link Anchor Safety", function () {
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("target")).toEqual("_blank")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
it("sanitizes raw HTML links", function () {
@@ -51,8 +49,8 @@ describe("Markdown Link Anchor Safety", function () {
const anchor = wrapper.find("a")
expect(anchor.attr("href")).toEqual("http://google.com/")
expect(anchor.attr("rel") || "").toInclude("noopener")
expect(anchor.attr("rel") || "").toInclude("noreferrer")
expect(anchor.attr("rel") || "").toMatch("noopener")
expect(anchor.attr("rel") || "").toMatch("noreferrer")
})
})
})

View File

@@ -0,0 +1,29 @@
import React from "react"
import { mount } from "enzyme"
import OnlineValidatorBadge from "components/online-validator-badge"
describe("<OnlineValidatorBadge/> Anchor Target Safety", function () {
it("should render a validator link with safe `rel` attributes", function () {
// When
const props = {
getConfigs: () => ({}),
getComponent: () => null,
specSelectors: {
url: () => "swagger.json"
}
}
const wrapper = mount(
<OnlineValidatorBadge {...props} />
)
const anchor = wrapper.find("a")
// Then
expect(anchor.props().href).toEqual(
"https://validator.swagger.io/validator/debug?url=swagger.json"
)
expect(anchor.props().target).toEqual("_blank")
expect(anchor.props().rel || "").toInclude("noopener")
expect(anchor.props().rel || "").toInclude("noreferrer")
})
})

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import { fromJS } from "immutable"
import Info from "components/info"

View File

@@ -1,6 +1,4 @@
/* eslint-env mocha */
import React from "react"
import expect from "expect"
import { render } from "enzyme"
import Markdown from "components/providers/markdown"
import { Markdown as OAS3Markdown } from "corePlugins/oas3/wrap-components/markdown.jsx"