mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-18 05:00:02 -06:00
fix: add more validation to cy.intercept() (#16577)
Co-authored-by: Zach Bloomquist <github@chary.us> Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
This commit is contained in:
@@ -1195,6 +1195,7 @@ jobs:
|
||||
|
||||
desktop-gui-component-tests:
|
||||
<<: *defaults
|
||||
resource_class: medium
|
||||
parallelism: 1
|
||||
steps:
|
||||
- restore_cached_workspace
|
||||
|
||||
@@ -680,6 +680,38 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
cy.intercept('/foo', { middleware: true })
|
||||
})
|
||||
|
||||
context('with an unexpected number of arguments', function () {
|
||||
it('cy.intercept(url, handler?)', function (done) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('The `cy.intercept(url, handler?)` signature accepts a maximum of 2 arguments, but 3 arguments were passed.')
|
||||
done()
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
cy.intercept('/url', { forceNetworkError: true }, () => {})
|
||||
})
|
||||
|
||||
it('cy.intercept(url, mergeRouteMatcher, handler)', function (done) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('The `cy.intercept(url, mergeRouteMatcher, handler)` signature accepts a maximum of 3 arguments, but 4 arguments were passed.')
|
||||
done()
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
cy.intercept('/url', { middleware: true }, { forceNetworkError: true }, () => {})
|
||||
})
|
||||
|
||||
it('cy.intercept(method, url, handler?)', function (done) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('The `cy.intercept(method, url, handler?)` signature accepts a maximum of 3 arguments, but 4 arguments were passed.')
|
||||
done()
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
cy.intercept('POST', '/url', { forceNetworkError: true }, () => {})
|
||||
})
|
||||
})
|
||||
|
||||
context('with invalid RouteMatcher', function () {
|
||||
it('requires unique header names', function (done) {
|
||||
testFail((err) => {
|
||||
@@ -737,7 +769,7 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
})
|
||||
|
||||
it('times must be a positive integer', function (done) {
|
||||
cy.on('fail', function (err) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('`times` must be a positive integer.')
|
||||
done()
|
||||
})
|
||||
@@ -745,6 +777,15 @@ describe('network stubbing', { retries: { runMode: 2, openMode: 0 } }, function
|
||||
cy
|
||||
.intercept({ times: 9.75 })
|
||||
})
|
||||
|
||||
it('string hostname must be a valid domain name', function (done) {
|
||||
testFail((err) => {
|
||||
expect(err.message).to.include('`hostname` must be a valid host name or domain name.')
|
||||
done()
|
||||
})
|
||||
|
||||
cy.intercept({ hostname: 'http://website.web' })
|
||||
})
|
||||
})
|
||||
|
||||
context('with invalid handler', function () {
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"errorhandler": "1.5.1",
|
||||
"eventemitter2": "6.4.2",
|
||||
"express": "4.17.1",
|
||||
"is-valid-domain": "0.0.19",
|
||||
"jquery": "3.1.1",
|
||||
"jquery.scrollto": "2.1.3",
|
||||
"js-cookie": "2.2.1",
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
import { registerEvents } from './events'
|
||||
import $errUtils from '../../cypress/error_utils'
|
||||
import $utils from '../../cypress/utils'
|
||||
import isValidDomain from 'is-valid-domain'
|
||||
|
||||
const lowercaseFieldNames = (headers: { [fieldName: string]: any }) => _.mapKeys(headers, (v, k) => _.toLower(k))
|
||||
|
||||
@@ -129,6 +130,10 @@ function validateRouteMatcherOptions (routeMatcher: RouteMatcherOptions): { isVa
|
||||
}
|
||||
}
|
||||
|
||||
if (_.isString(routeMatcher.hostname) && !isValidDomain(routeMatcher.hostname, { allowUnicode: true })) {
|
||||
return err('`hostname` must be a valid host name or domain name.')
|
||||
}
|
||||
|
||||
if (_.has(routeMatcher, 'port') && !isNumberMatcher(routeMatcher.port)) {
|
||||
return err('`port` must be a number or a list of numbers.')
|
||||
}
|
||||
@@ -234,6 +239,17 @@ export function addCommand (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
|
||||
}
|
||||
|
||||
function intercept (matcher: RouteMatcher, handler?: RouteHandler | StringMatcher | RouteMatcherOptions, arg2?: RouteHandler) {
|
||||
const checkExtraArguments = (overload: string[]) => {
|
||||
if (arguments.length > overload.length) {
|
||||
$errUtils.throwErrByPath('net_stubbing.intercept.extra_arguments', {
|
||||
args: {
|
||||
overload,
|
||||
argsLength: arguments.length,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getMatcherOptions (): RouteMatcherOptions {
|
||||
if (isStringMatcher(matcher) && hasOnlyRouteMatcherKeys(handler)) {
|
||||
// url, mergeRouteMatcher, handler
|
||||
@@ -246,6 +262,8 @@ export function addCommand (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
|
||||
return $errUtils.throwErrByPath('net_stubbing.intercept.handler_required')
|
||||
}
|
||||
|
||||
checkExtraArguments(['url', 'mergeRouteMatcher', 'handler'])
|
||||
|
||||
const opts = {
|
||||
url: matcher,
|
||||
...handler as RouteMatcherOptions,
|
||||
@@ -262,6 +280,8 @@ export function addCommand (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
|
||||
|
||||
handler = arg2
|
||||
|
||||
checkExtraArguments(['method', 'url', 'handler?'])
|
||||
|
||||
return {
|
||||
method: matcher,
|
||||
url,
|
||||
@@ -270,6 +290,8 @@ export function addCommand (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy,
|
||||
|
||||
if (isStringMatcher(matcher)) {
|
||||
// url, handler?
|
||||
checkExtraArguments(['url', 'handler?'])
|
||||
|
||||
return {
|
||||
url: matcher,
|
||||
}
|
||||
|
||||
@@ -931,23 +931,29 @@ module.exports = {
|
||||
You passed: ${format(staticResponse)}`, 8)
|
||||
},
|
||||
intercept: {
|
||||
extra_arguments: ({ argsLength, overload }) => {
|
||||
return cyStripIndent(`\
|
||||
The ${cmd('intercept', overload.join(', '))} signature accepts a maximum of ${overload.length} arguments, but ${argsLength} arguments were passed.
|
||||
|
||||
Please refer to the docs for all accepted signatures for ${cmd('intercept')}.`, 10)
|
||||
},
|
||||
invalid_handler: ({ handler }) => {
|
||||
return stripIndent`\
|
||||
return cyStripIndent(`\
|
||||
${cmd('intercept')}'s \`handler\` argument must be a String, StaticResponse, or HttpController function.
|
||||
|
||||
You passed: ${format(handler)}`
|
||||
You passed: ${format(handler)}`, 10)
|
||||
},
|
||||
invalid_middleware_handler: ({ handler }) => {
|
||||
return stripIndent`\
|
||||
return cyStripIndent(`\
|
||||
${cmd('intercept')}'s \`handler\` argument must be an HttpController function when \`middleware\` is set to \`true\`.
|
||||
|
||||
You passed: ${format(handler)}`
|
||||
You passed: ${format(handler)}`, 10)
|
||||
},
|
||||
invalid_route_matcher: ({ message, matcher }) => {
|
||||
return stripIndent`\
|
||||
return cyStripIndent(`\
|
||||
An invalid RouteMatcher was supplied to ${cmd('intercept')}. ${message}
|
||||
|
||||
You passed: ${format(matcher)}`
|
||||
You passed: ${format(matcher)}`, 10)
|
||||
},
|
||||
no_duplicate_url: `When invoking ${cmd('intercept')} with a \`RouteMatcher\` as the second parameter, \`url\` can only be specified as the first parameter.`,
|
||||
handler_required: `When invoking ${cmd('intercept')} with a \`RouteMatcher\` as the second parameter, a handler (function or \`StaticResponse\`) must be specified as the third parameter. If you intended to stub out a response body by passing an object as the 2nd parameter, pass an object with a \`body\` property containing the desired response body instead.`,
|
||||
|
||||
14
yarn.lock
14
yarn.lock
@@ -22873,6 +22873,13 @@ is-utf8@^0.2.0, is-utf8@^0.2.1:
|
||||
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
|
||||
integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
|
||||
|
||||
is-valid-domain@0.0.19:
|
||||
version "0.0.19"
|
||||
resolved "https://registry.npmjs.org/is-valid-domain/-/is-valid-domain-0.0.19.tgz#50ce5ff3ab1cbe85bcb5b155b0fba61f4b9ea668"
|
||||
integrity sha512-NxuZbJABXdGlFNEVphG9bT0YOQE0B75Bv+emGsEjmRnAs9aMUVbdKUafj//yTxApThjqQqRKBd9MJDlnqx8Pmg==
|
||||
dependencies:
|
||||
punycode "^1.4.1"
|
||||
|
||||
is-valid-glob@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-0.3.0.tgz#d4b55c69f51886f9b65c70d6c2622d37e29f48fe"
|
||||
@@ -31369,11 +31376,16 @@ pumpify@1.5.1, pumpify@^1.3.3, pumpify@^1.3.5:
|
||||
inherits "^2.0.3"
|
||||
pump "^2.0.0"
|
||||
|
||||
punycode@1.3.2, punycode@^1.2.4, punycode@^1.3.2:
|
||||
punycode@1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
|
||||
|
||||
punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
||||
|
||||
punycode@^2.1.0, punycode@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
|
||||
Reference in New Issue
Block a user