This commit is contained in:
2026-03-03 15:23:00 +00:00
parent 5e3726de39
commit 8e223bfbec
3689 changed files with 955330 additions and 1011 deletions

23
node_modules/supertest/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca> and other
contributors.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

471
node_modules/supertest/README.md generated vendored Normal file
View File

@@ -0,0 +1,471 @@
# [supertest](https://forwardemail.github.io/superagent/)
[![build status](https://github.com/forwardemail/supertest/actions/workflows/ci.yml/badge.svg)](https://github.com/forwardemail/supertest/actions/workflows/ci.yml)
[![code coverage](https://img.shields.io/codecov/c/github/ladjs/supertest.svg)](https://codecov.io/gh/ladjs/supertest)
[![code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![made with lass](https://img.shields.io/badge/made_with-lass-95CC28.svg)](https://lass.js.org)
[![license](https://img.shields.io/github/license/ladjs/supertest.svg)](LICENSE)
> HTTP assertions made easy via [superagent](http://github.com/ladjs/superagent). Maintained for [Forward Email](https://github.com/forwardemail) and [Lad](https://github.com/ladjs).
## About
The motivation with this module is to provide a high-level abstraction for testing
HTTP, while still allowing you to drop down to the [lower-level API](https://forwardemail.github.io/superagent/) provided by superagent.
## Getting Started
Install supertest as an npm module and save it to your package.json file as a development dependency:
```bash
npm install supertest --save-dev
```
Once installed it can now be referenced by simply calling ```require('supertest');```
## Example
You may pass an `http.Server`, or a `Function` to `request()` - if the server is not
already listening for connections then it is bound to an ephemeral port for you so
there is no need to keep track of ports.
supertest works with any test framework, here is an example without using any
test framework at all:
```js
const request = require('supertest');
const express = require('express');
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'john' });
});
request(app)
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
```
To enable http2 protocol, simply append an options to `request` or `request.agent`:
```js
const request = require('supertest');
const express = require('express');
const app = express();
app.get('/user', function(req, res) {
res.status(200).json({ name: 'john' });
});
request(app, { http2: true })
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
request.agent(app, { http2: true })
.get('/user')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
.end(function(err, res) {
if (err) throw err;
});
```
Here's an example with mocha, note how you can pass `done` straight to any of the `.expect()` calls:
```js
describe('GET /user', function() {
it('responds with json', function(done) {
request(app)
.get('/user')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200, done);
});
});
```
You can use `auth` method to pass HTTP username and password in the same way as in the [superagent](https://forwardemail.github.io/superagent/#authentication):
```js
describe('GET /user', function() {
it('responds with json', function(done) {
request(app)
.get('/user')
.auth('username', 'password')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200, done);
});
});
```
One thing to note with the above statement is that superagent now sends any HTTP
error (anything other than a 2XX response code) to the callback as the first argument if
you do not add a status code expect (i.e. `.expect(302)`).
If you are using the `.end()` method `.expect()` assertions that fail will
not throw - they will return the assertion as an error to the `.end()` callback. In
order to fail the test case, you will need to rethrow or pass `err` to `done()`, as follows:
```js
describe('POST /users', function() {
it('responds with json', function(done) {
request(app)
.post('/users')
.send({name: 'john'})
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200)
.end(function(err, res) {
if (err) return done(err);
return done();
});
});
});
```
You can also use promises:
```js
describe('GET /users', function() {
it('responds with json', function() {
return request(app)
.get('/users')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200)
.then(response => {
expect(response.body.email).toEqual('foo@bar.com');
})
});
});
```
Or async/await syntax:
```js
describe('GET /users', function() {
it('responds with json', async function() {
const response = await request(app)
.get('/users')
.set('Accept', 'application/json')
expect(response.headers["content-type"]).toMatch(/json/);
expect(response.status).toEqual(200);
expect(response.body.email).toEqual('foo@bar.com');
});
});
```
Expectations are run in the order of definition. This characteristic can be used
to modify the response body or headers before executing an assertion.
```js
describe('POST /user', function() {
it('user.name should be an case-insensitive match for "john"', function(done) {
request(app)
.post('/user')
.send('name=john') // x-www-form-urlencoded upload
.set('Accept', 'application/json')
.expect(function(res) {
res.body.id = 'some fixed id';
res.body.name = res.body.name.toLowerCase();
})
.expect(200, {
id: 'some fixed id',
name: 'john'
}, done);
});
});
```
Anything you can do with superagent, you can do with supertest - for example multipart file uploads!
```js
request(app)
.post('/')
.field('name', 'my awesome avatar')
.field('complex_object', '{"attribute": "value"}', {contentType: 'application/json'})
.attach('avatar', 'test/fixtures/avatar.jpg')
...
```
Passing the app or url each time is not necessary, if you're testing
the same host you may simply re-assign the request variable with the
initialization app or url, a new `Test` is created per `request.VERB()` call.
```js
request = request('http://localhost:5555');
request.get('/').expect(200, function(err){
console.log(err);
});
request.get('/').expect('heya', function(err){
console.log(err);
});
```
Here's an example with mocha that shows how to persist a request and its cookies:
```js
const request = require('supertest');
const should = require('should');
const express = require('express');
const cookieParser = require('cookie-parser');
describe('request.agent(app)', function() {
const app = express();
app.use(cookieParser());
app.get('/', function(req, res) {
res.cookie('cookie', 'hey');
res.send();
});
app.get('/return', function(req, res) {
if (req.cookies.cookie) res.send(req.cookies.cookie);
else res.send(':(')
});
const agent = request.agent(app);
it('should save cookies', function(done) {
agent
.get('/')
.expect('set-cookie', 'cookie=hey; Path=/', done);
});
it('should send cookies', function(done) {
agent
.get('/return')
.expect('hey', done);
});
});
```
There is another example that is introduced by the file [agency.js](https://github.com/ladjs/superagent/blob/master/test/node/agency.js)
Here is an example where 2 cookies are set on the request.
```js
agent(app)
.get('/api/content')
.set('Cookie', ['nameOne=valueOne;nameTwo=valueTwo'])
.send()
.expect(200)
.end((err, res) => {
if (err) {
return done(err);
}
expect(res.text).to.be.equal('hey');
return done();
});
```
## API
You may use any [superagent](http://github.com/ladjs/superagent) methods,
including `.write()`, `.pipe()` etc and perform assertions in the `.end()` callback
for lower-level needs.
### .expect(status[, fn])
Assert response `status` code.
### .expect(status, body[, fn])
Assert response `status` code and `body`.
### .expect(body[, fn])
Assert response `body` text with a string, regular expression, or
parsed body object.
### .expect(field, value[, fn])
Assert header `field` `value` with a string or regular expression.
### .expect(function(res) {})
Pass a custom assertion function. It'll be given the response object to check. If the check fails, throw an error.
```js
request(app)
.get('/')
.expect(hasPreviousAndNextKeys)
.end(done);
function hasPreviousAndNextKeys(res) {
if (!('next' in res.body)) throw new Error("missing next key");
if (!('prev' in res.body)) throw new Error("missing prev key");
}
```
### .end(fn)
Perform the request and invoke `fn(err, res)`.
## Cookies
Here is an example of using the `set` and `not` cookie assertions:
```js
// setup super-test
const request = require('supertest');
const express = require('express');
const cookies = request.cookies;
// setup express test service
const app = express();
app.get('/users', function(req, res) {
res.cookie('alpha', 'one', { domain: 'domain.com', path: '/', httpOnly: true });
res.send(200, { name: 'tobi' });
});
// test request to service
request(app)
.get('/users')
.expect('Content-Type', /json/)
.expect('Content-Length', '15')
.expect(200)
// assert 'alpha' cookie is set with domain, path, and httpOnly options
.expect(cookies.set({ name: 'alpha', options: ['domain', 'path', 'httponly'] }))
// assert 'bravo' cookie is NOT set
.expect(cookies.not('set', { name: 'bravo' }))
.end(function(err, res) {
if (err) {
throw err;
}
});
```
It is also possible to chain assertions:
```js
cookies.set({/* ... */}).not('set', {/* ... */})
```
### Cookie assertions
Functions and methods are chainable.
#### cookies([secret], [asserts])
Get assertion function for [super-test](https://github.com/visionmedia/supertest) `.expect()` method.
*Arguments*
- `secret` - String or array of strings. Cookie signature secrets.
- `asserts(req, res)` - Function or array of functions. Failed custom assertions should throw.
#### .set(expects, [assert])
Assert that cookie and options are set.
*Arguments*
- `expects` - Object or array of objects.
- `name` - String name of cookie.
- `options` - *Optional* array of options.
- `assert` - *Optional* boolean "assert true" modifier. Default: `true`.
#### .reset(expects, [assert])
Assert that cookie is set and was already set (in request headers).
*Arguments*
- `expects` - Object or array of objects.
- `name` - String name of cookie.
- `assert` - *Optional* boolean "assert true" modifier. Default: `true`.
#### .new(expects, [assert])
Assert that cookie is set and was NOT already set (NOT in request headers).
*Arguments*
- `expects` - Object or array of objects.
- `name` - String name of cookie.
- `assert` - *Optional* boolean "assert true" modifier. Default: `true`.
#### .renew(expects, [assert])
Assert that cookie is set with a strictly greater `expires` or `max-age` than the given value.
*Arguments*
- `expects` - Object or array of objects.
- `name` - String name of cookie.
- `options` - Object of options. `use one of two options below`
- `options`.`expires` - String UTC expiration for original cookie (in request headers).
- `options`.`max-age` - Integer ttl in seconds for original cookie (in request headers).
- `assert` - *Optional* boolean "assert true" modifier. Default: `true`.
#### .contain(expects, [assert])
Assert that cookie is set with value and contains options.
Requires `cookies(secret)` initialization if cookie is signed.
*Arguments*
- `expects` - Object or array of objects.
- `name` - String name of cookie.
- `value` - *Optional* string unsigned value of cookie.
- `options` - *Optional* object of options.
- `options`.`domain` - *Optional* string domain.
- `options`.`path` - *Optional* string path.
- `options`.`expires` - *Optional* string UTC expiration.
- `options`.`max-age` - *Optional* integer ttl, in seconds.
- `options`.`secure` - *Optional* boolean secure flag.
- `options`.`httponly` - *Optional* boolean httpOnly flag.
- `assert` - *Optional* boolean "assert true" modifier. Default: `true`.
#### .not(method, expects)
Call any cookies assertion method with "assert true" modifier set to `false`.
Syntactic sugar.
*Arguments*
- `method` - String method name. Arguments of method name apply in `expects`.
- `expects` - Object or array of objects.
- `name` - String name of cookie.
- `value` - *Optional* string unsigned value of cookie.
- `options` - *Optional* object of options.
## Notes
Inspired by [api-easy](https://github.com/flatiron/api-easy) minus vows coupling.
## License
MIT
[coverage-badge]: https://img.shields.io/codecov/c/github/ladjs/supertest.svg
[coverage]: https://codecov.io/gh/ladjs/supertest
[travis-badge]: https://travis-ci.org/ladjs/supertest.svg?branch=master
[travis]: https://travis-ci.org/ladjs/supertest
[dependencies-badge]: https://david-dm.org/ladjs/supertest/status.svg
[dependencies]: https://david-dm.org/ladjs/supertest
[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[prs]: http://makeapullrequest.com
[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square
[license]: https://github.com/ladjs/supertest/blob/master/LICENSE

67
node_modules/supertest/index.js generated vendored Normal file
View File

@@ -0,0 +1,67 @@
'use strict';
/**
* Module dependencies.
*/
const methods = require('methods');
let http2;
try {
http2 = require('http2'); // eslint-disable-line global-require
} catch (_) {
// eslint-disable-line no-empty
}
const Test = require('./lib/test.js');
const agent = require('./lib/agent.js');
const cookies = require('./lib/cookies');
/**
* Test against the given `app`,
* returning a new `Test`.
*
* @param {Function|Server|String} app
* @return {Test}
* @api public
*/
module.exports = function(app, options = {}) {
const obj = {};
if (typeof app === 'function') {
if (options.http2) {
if (!http2) {
throw new Error(
'supertest: this version of Node.js does not support http2'
);
}
}
}
methods.forEach(function(method) {
obj[method] = function(url) {
var test = new Test(app, method, url, options.http2);
if (options.http2) {
test.http2();
}
return test;
};
});
// Support previous use of del
obj.del = obj.delete;
return obj;
};
/**
* Expose `Test`
*/
module.exports.Test = Test;
/**
* Expose the agent function
*/
module.exports.agent = agent;
/**
* Expose cookie assertions
*/
module.exports.cookies = cookies;

100
node_modules/supertest/lib/agent.js generated vendored Normal file
View File

@@ -0,0 +1,100 @@
'use strict';
/**
* Module dependencies.
*/
const { agent: Agent } = require('superagent');
const methods = require('methods');
const http = require('http');
let http2;
try {
http2 = require('http2'); // eslint-disable-line global-require
} catch (_) {
// eslint-disable-line no-empty
}
const Test = require('./test.js');
/**
* Initialize a new `TestAgent`.
*
* @param {Function|Server} app
* @param {Object} options
* @api public
*/
function TestAgent(app, options = {}) {
if (!(this instanceof TestAgent)) return new TestAgent(app, options);
const agent = new Agent(options);
Object.assign(this, agent);
this._options = options;
if (typeof app === 'function') {
if (options.http2) {
if (!http2) {
throw new Error(
'supertest: this version of Node.js does not support http2'
);
}
app = http2.createServer(app); // eslint-disable-line no-param-reassign
} else {
app = http.createServer(app); // eslint-disable-line no-param-reassign
}
}
this.app = app;
}
/**
* Inherits from `Agent.prototype`.
*/
Object.setPrototypeOf(TestAgent.prototype, Agent.prototype);
// Preserve the original query method before overriding HTTP methods
const originalQuery = Agent.prototype.query;
// set a host name
TestAgent.prototype.host = function(host) {
this._host = host;
return this;
};
// override HTTP verb methods
methods.forEach(function(method) {
// Skip 'query' method to prevent overwriting superagent's query functionality
if (method === 'query') {
return;
}
TestAgent.prototype[method] = function(url, fn) { // eslint-disable-line no-unused-vars
const req = new Test(this.app, method.toUpperCase(), url);
if (this._options.http2) {
req.http2();
}
if (this._host) {
req.set('host', this._host);
}
req.on('response', this._saveCookies.bind(this));
req.on('redirect', this._saveCookies.bind(this));
req.on('redirect', this._attachCookies.bind(this, req));
this._setDefaults(req);
this._attachCookies(req);
return req;
};
});
// Restore the original query method
TestAgent.prototype.query = originalQuery;
TestAgent.prototype.del = TestAgent.prototype.delete;
/**
* Expose `Agent`.
*/
module.exports = TestAgent;

497
node_modules/supertest/lib/cookies/assertion.js generated vendored Normal file
View File

@@ -0,0 +1,497 @@
/** Copyright 2015 Gregory Langlais. See LICENSE.txt. */
'use strict';
const signature = require('cookie-signature');
/**
* Assert that an object has specific properties (supports array of keys or object)
*
* @param {object} obj
* @param {object|array} props
*/
function assertHasProperties(obj, props) {
if (Array.isArray(props)) {
props.forEach(function (key) {
if (!(key in obj)) {
throw new Error('expected object to have property ' + key);
}
});
} else {
Object.keys(props).forEach(function (key) {
if (!(key in obj)) {
throw new Error('expected object to have property ' + key);
}
});
}
}
/**
* Assert that an object does not have specific properties (supports array of keys or object)
* When checking with empty props, throws if object exists (matches should.js behavior)
*
* @param {object} obj
* @param {object|array} props
*/
function assertNotHasProperties(obj, props) {
if (Array.isArray(props)) {
// When empty array is passed, should.js throws 'false negative fail' if object exists
if (props.length === 0) {
throw new Error('expected object to not have properties (false negative fail)');
}
props.forEach(function (key) {
if (key in obj) {
throw new Error('expected object to not have property ' + key);
}
});
} else {
// When empty object is passed, should.js throws 'false negative fail' if object exists
let keys = Object.keys(props);
if (keys.length === 0) {
throw new Error('expected object to not have properties (false negative fail)');
}
keys.forEach(function (key) {
if (key in obj) {
throw new Error('expected object to not have property ' + key);
}
});
}
}
/**
* Assert that two values are equal
*
* @param {*} actual
* @param {*} expected
*/
function assertEqual(actual, expected) {
if (actual !== expected) {
throw new Error(
'expected ' + JSON.stringify(actual) + ' to equal ' + JSON.stringify(expected)
);
}
}
/**
* Assert that two values are not equal
*
* @param {*} actual
* @param {*} expected
*/
function assertNotEqual(actual, expected) {
if (actual === expected) {
throw new Error(
'expected ' + JSON.stringify(actual) + ' to not equal ' + JSON.stringify(expected)
);
}
}
/**
* Build Assertion function
*
* {object|object[]} expects cookies
* {string} expects.<name> and value of cookie
* {object} expects.options
* {string} [expects.options.domain]
* {string} [expects.options.path]
* {string} [expects.options.expires] UTC string using date.toUTCString()
* {number} [expects.options.max-age]
* {boolean} [expects.options.secure]
* {boolean} [expects.options.httponly]
* {string|string[]} [expects.secret]
*
* @param {null|string|string[]} [secret]
* @param {function|function[]} [asserts]
* @returns {Assertion}
*/
module.exports = function (secret, asserts) {
let assertions = [];
if (typeof secret === 'string') secret = [secret]; // eslint-disable-line no-param-reassign
else if (!Array.isArray(secret)) secret = []; // eslint-disable-line no-param-reassign
if (Array.isArray(asserts)) assertions = asserts;
else if (typeof asserts === 'function') assertions.push(asserts);
/**
* Assertion function with static chainable methods
*
* @param {object} res
* @returns {undefined|string}
* @constructor
*/
function Assertion(res) {
if (typeof res !== 'object') throw new Error('res argument must be object');
// request and response object initialization
let request = {
headers: res.req.getHeaders(),
cookies: []
};
let response = {
headers: res.headers,
cookies: []
};
// build assertions request object
if (request.headers.cookie) {
const cookies = String(request.headers.cookie);
cookies.split(/; */).forEach(function (cookie) {
request.cookies.push(Assertion.parse(cookie));
});
}
// build assertions response object
if (
Array.isArray(response.headers['set-cookie'])
&& response.headers['set-cookie'].length > 0
) {
response.headers['set-cookie'].forEach(function (val) {
response.cookies.push(Assertion.parse(val));
});
}
// run assertions
let result;
assertions.every(function (assertion) {
result = assertion(request, response);
return (typeof (result) !== 'string');
});
return result;
}
/**
* Find cookie in stack/array
*
* @param {string} name
* @param {array} stack
* @returns {object|undefined} cookie
*/
Assertion.find = function (name, stack) {
let cookie;
stack.every(function (val) {
if (name !== val.name) return true;
cookie = val;
return false;
});
return cookie;
};
/**
* Parse cookie string
*
* @param {string} str
* @param {object} [options]
* @param {function} [options.decode] uri
* @param {undefined|boolean} [options.request] headers
* @returns {object}
*/
Assertion.parse = function (str, options) {
if (typeof str !== 'string') throw new TypeError('argument str must be a string');
if (typeof options !== 'object') options = {}; // eslint-disable-line no-param-reassign
let decode = options.decode || decodeURIComponent;
let parts = str.split(/; */);
let cookie = {};
parts.forEach(function (part, i) {
if (i === 1) cookie.options = {};
let equalsIndex = part.indexOf('=');
// things that don't look like key=value get true flag
if (equalsIndex < 0) {
cookie.options[part.trim().toLowerCase()] = true;
return;
}
const key = part.substr(0, equalsIndex).trim().toLowerCase();
// only assign once
if (typeof cookie[key] !== 'undefined') return;
equalsIndex += 1;
let val = part.substr(equalsIndex, part.length).trim();
// quoted values
if (val[0] === '"') val = val.slice(1, -1);
let value;
try {
value = decode(val);
} catch (e) {
value = val;
}
if (i > 0) {
cookie.options[key] = value;
return;
}
cookie.name = key;
cookie.value = decode(val);
});
if (typeof cookie.options === 'undefined') cookie.options = {};
return cookie;
};
/**
* Iterate expects
*
* @param {object|object[]} expects
* @param {boolean|function} hasValues
* @param {function} [cb]
*/
Assertion.expects = function (expects, hasValues, cb) {
if (!Array.isArray(expects) && typeof expects === 'object') expects = [expects]; // eslint-disable-line no-param-reassign
let resolvedCb;
let resolvedHasValues;
if (typeof cb === 'undefined' && typeof hasValues === 'function') {
resolvedCb = hasValues;
resolvedHasValues = false;
} else {
resolvedCb = cb;
resolvedHasValues = hasValues;
}
expects.forEach(function (expect) {
let options = expect.options;
if (typeof options !== 'object' && !Array.isArray(options)) {
options = (resolvedHasValues) ? {} : [];
}
resolvedCb(Object.assign({}, expect, { options }));
});
};
/**
* Assert cookies and options are set
*
* @param {object|object[]} expects cookies
* @param {undefined|boolean} [assert]
* @returns {function} Assertion
*/
Assertion.set = function (expects, assert) {
if (typeof assert === 'undefined') assert = true; // eslint-disable-line no-param-reassign
Assertion.expects(expects, function (expect) {
assertions.push(function (req, res) {
// get expectation cookie
const cookie = Assertion.find(expect.name, res.cookies);
if (assert && !cookie) throw new Error('expected: ' + expect.name + ' cookie to be set');
if (assert) assertHasProperties(cookie.options, expect.options);
else if (cookie) assertNotHasProperties(cookie.options, expect.options);
});
});
return Assertion;
};
/**
* Assert cookies has been reset
*
* @param {object|object[]} expects cookies
* @param {undefined|boolean} [assert]
* @returns {function} Assertion
*/
Assertion.reset = function (expects, assert) {
if (typeof assert === 'undefined') assert = true; // eslint-disable-line no-param-reassign
Assertion.expects(expects, function (expect) {
assertions.push(function (req, res) {
// get sent cookie
const cookieReq = Assertion.find(expect.name, req.cookies);
// get expectation cookie
const cookieRes = Assertion.find(expect.name, res.cookies);
if (assert && (!cookieReq || !cookieRes)) {
throw new Error('expected: ' + expect.name + ' cookie to be set');
} else if (!assert && cookieReq && cookieRes) {
throw new Error('expected: ' + expect.name + ' cookie to be set');
}
});
});
return Assertion;
};
/**
* Assert cookies is set and new
*
* @param {object|object[]} expects cookies
* @param {undefined|boolean} [assert]
* @returns {function} Assertion
*/
Assertion.new = function (expects, assert) {
if (typeof assert === 'undefined') assert = true; // eslint-disable-line no-param-reassign
Assertion.expects(expects, function (expect) {
assertions.push(function (req, res) {
// get sent cookie
const cookieReq = Assertion.find(expect.name, req.cookies);
// get expectation cookie
const cookieRes = Assertion.find(expect.name, res.cookies);
if (assert) {
if (!cookieRes) throw new Error('expected: ' + expect.name + ' cookie to be set');
if (cookieReq && cookieRes) {
throw new Error('expected: ' + expect.name + ' cookie to NOT already be set');
}
} else if (!cookieReq || !cookieRes) {
throw new Error('expected: ' + expect.name + ' cookie to be set');
}
});
});
return Assertion;
};
/**
* Assert cookies expires or max-age has increased
*
* @param {object|object[]} expects cookies
* @param {undefined|boolean} [assert]
* @returns {function} Assertion
*/
Assertion.renew = function (expects, assert) {
if (typeof assert === 'undefined') assert = true; // eslint-disable-line no-param-reassign
Assertion.expects(expects, true, function (expect) {
const expectExpires = new Date(expect.options.expires);
const expectMaxAge = parseFloat(expect.options['max-age']);
let baseMessage = 'expected: ' + expect.name;
if (!expectExpires.getTime() && !expectMaxAge) {
throw new Error(baseMessage + ' expects to have expires or max-age option');
}
assertions.push(function (req, res) {
// get sent cookie
const cookieReq = Assertion.find(expect.name, req.cookies);
// get expectation cookie
const cookieRes = Assertion.find(expect.name, res.cookies);
const cookieMaxAge = (expectMaxAge && cookieRes)
? parseFloat(cookieRes.options['max-age'])
: undefined;
const cookieExpires = (expectExpires.getTime() && cookieRes)
? new Date(cookieRes.options.expires)
: undefined;
if (assert) {
if (!cookieReq || !cookieRes) {
throw new Error(baseMessage + ' cookie to be set');
}
if (expectMaxAge && (!cookieMaxAge || cookieMaxAge <= expectMaxAge)) {
throw new Error(baseMessage + ' cookie max-age to be greater than existing value');
}
if (
expectExpires.getTime()
&& (!cookieExpires.getTime() || cookieExpires <= expectExpires)
) {
throw new Error(baseMessage + ' cookie expires to be greater than existing value');
}
} else if (cookieRes) {
if (expectMaxAge && cookieMaxAge > expectMaxAge) {
throw new Error(
baseMessage + ' cookie max-age to be less than or equal to existing value'
);
}
if (expectExpires.getTime() && cookieExpires > expectExpires) {
throw new Error(
baseMessage + ' cookie expires to be less than or equal to existing value'
);
}
}
});
});
return Assertion;
};
/**
* Assert cookies contains values
*
* @param {object|object[]} expects cookies
* @param {undefined|boolean} [assert]
* @returns {function} Assertion
*/
Assertion.contain = function (expects, assert) {
if (typeof assert === 'undefined') assert = true; // eslint-disable-line no-param-reassign
Assertion.expects(expects, function (expect) {
const keys = Object.keys(expect.options);
assertions.push(function (req, res) {
// get expectation cookie
const cookie = Assertion.find(expect.name, res.cookies);
if (!cookie) throw new Error('expected: ' + expect.name + ' cookie to be set');
// check cookie values are equal
if ('value' in expect) {
try {
if (assert) assertEqual(cookie.value, expect.value);
else assertNotEqual(cookie.value, expect.value);
} catch (e) {
if (secret.length) {
let value;
secret.every(function (sec) {
value = signature.unsign(cookie.value.slice(2), sec);
return !(value && value === expect.value);
});
if (assert && !value) {
throw new Error('expected: ' + expect.name + ' value to equal ' + expect.value);
} else if (!assert && value) {
throw new Error('expected: ' + expect.name + ' value to NOT equal ' + expect.value);
}
} else throw e;
}
}
keys.forEach(function (key) {
const expected = (
key === 'max-age'
? expect.options[key].toString()
: expect.options[key]
);
if (assert) assertEqual(cookie.options[key], expected);
else assertNotEqual(cookie.options[key], expected);
});
});
});
return Assertion;
};
/**
* Assert NOT modifier
*
* @param {function} method
* @param {...*}
*/
Assertion.not = function (method) {
let args = [];
for (let i = 1; i < arguments.length; i += 1) args.push(arguments[i]);
args.push(false);
return Assertion[method].apply(Assertion, args);
};
return Assertion;
};

32
node_modules/supertest/lib/cookies/index.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
/** Copyright 2015 Gregory Langlais. See LICENSE.txt. */
'use strict';
const Assertion = require('./assertion');
/**
* Construct cookies assertion (function)
*
* @param {null|string|string[]} [secret]
* @param {function(req, res)[]} [asserts] ran within returned assertion function
* @returns {function} assertion
* @constructor
*/
function ExpectCookies(secret, asserts) {
return Assertion(secret, asserts);
}
// build ExpectCookies proxy methods
const assertion = Assertion();
const methods = Object.getOwnPropertyNames(assertion);
methods.forEach(function(method) {
if (typeof assertion[method] === 'function' && typeof Function[method] === 'undefined') {
ExpectCookies[method] = function() {
const newAssertion = Assertion();
return newAssertion[method].apply(newAssertion, arguments);
};
}
});
module.exports = ExpectCookies;

403
node_modules/supertest/lib/test.js generated vendored Normal file
View File

@@ -0,0 +1,403 @@
'use strict';
/**
* Module dependencies.
*/
const { inspect } = require('util');
const http = require('http');
const { STATUS_CODES } = require('http');
const { Server } = require('tls');
const { deepStrictEqual } = require('assert');
const { Request } = require('superagent');
let http2;
try {
http2 = require('http2'); // eslint-disable-line global-require
} catch (_) {
// eslint-disable-line no-empty
}
/** @typedef {import('superagent').Response} Response */
class Test extends Request {
/**
* Initialize a new `Test` with the given `app`,
* request `method` and `path`.
*
* @param {Server} app
* @param {String} method
* @param {String} path
* @api public
*/
constructor (app, method, path, optHttp2) {
super(method.toUpperCase(), path);
if (typeof app === 'function') {
if (optHttp2) {
app = http2.createServer(app); // eslint-disable-line no-param-reassign
} else {
app = http.createServer(app); // eslint-disable-line no-param-reassign
}
}
this.redirects(0);
this.buffer();
this.app = app;
this._asserts = [];
this.url = typeof app === 'string'
? app + path
: this.serverAddress(app, path);
}
/**
* Returns a URL, extracted from a server.
*
* @param {Server} app
* @param {String} path
* @returns {String} URL address
* @api private
*/
serverAddress(app, path) {
const addr = app.address();
if (!addr) this._server = app.listen(0);
// } else {
// this._server = app;
// }
const port = app.address().port;
const protocol = app instanceof Server ? 'https' : 'http';
return protocol + '://127.0.0.1:' + port + path;
}
/**
* Expectations:
*
* .expect(200)
* .expect(200, fn)
* .expect(200, body)
* .expect('Some body')
* .expect('Some body', fn)
* .expect(['json array body', { key: 'val' }])
* .expect('Content-Type', 'application/json')
* .expect('Content-Type', 'application/json', fn)
* .expect(fn)
* .expect([200, 404])
*
* @return {Test}
* @api public
*/
expect(a, b, c) {
// callback
if (typeof a === 'function') {
this._asserts.push(wrapAssertFn(a));
return this;
}
if (typeof b === 'function') this.end(b);
if (typeof c === 'function') this.end(c);
// status
if (typeof a === 'number') {
this._asserts.push(wrapAssertFn(this._assertStatus.bind(this, a)));
// body
if (typeof b !== 'function' && arguments.length > 1) {
this._asserts.push(wrapAssertFn(this._assertBody.bind(this, b)));
}
return this;
}
// multiple statuses
if (Array.isArray(a) && a.length > 0 && a.every(val => typeof val === 'number')) {
this._asserts.push(wrapAssertFn(this._assertStatusArray.bind(this, a)));
return this;
}
// header field
if (typeof b === 'string' || typeof b === 'number' || b instanceof RegExp) {
this._asserts.push(wrapAssertFn(this._assertHeader.bind(this, { name: '' + a, value: b })));
return this;
}
// body
this._asserts.push(wrapAssertFn(this._assertBody.bind(this, a)));
return this;
}
/**
* Defer invoking superagent's `.end()` until
* the server is listening.
*
* @param {?Function} fn
* @api public
*/
end(fn) {
const server = this._server;
super.end((err, res) => {
const localAssert = () => {
this.assert(err, res, fn);
};
if (server && server._handle) {
// Handle server closing with error handling for already closed servers
return server.close((closeError) => {
// Ignore ERR_SERVER_NOT_RUNNING errors as the server is already closed
if (closeError && closeError.code === 'ERR_SERVER_NOT_RUNNING') {
return localAssert();
}
// For other errors, pass them through
if (closeError) {
return localAssert();
}
localAssert();
});
}
localAssert();
});
return this;
}
/**
* Perform assertions and invoke `fn(err, res)`.
*
* @param {?Error} resError
* @param {Response} res
* @param {Function} fn
* @api private
*/
assert(resError, res, fn) {
let errorObj;
// check for unexpected network errors or server not running/reachable errors
// when there is no response and superagent sends back a System Error
// do not check further for other asserts, if any, in such case
// https://nodejs.org/api/errors.html#errors_common_system_errors
const sysErrors = {
ECONNREFUSED: 'Connection refused',
ECONNRESET: 'Connection reset by peer',
EPIPE: 'Broken pipe',
ETIMEDOUT: 'Operation timed out'
};
if (!res && resError) {
if (resError instanceof Error && resError.syscall === 'connect'
&& Object.getOwnPropertyNames(sysErrors).indexOf(resError.code) >= 0) {
errorObj = new Error(resError.code + ': ' + sysErrors[resError.code]);
} else {
errorObj = resError;
}
}
// asserts
for (let i = 0; i < this._asserts.length && !errorObj; i += 1) {
errorObj = this._assertFunction(this._asserts[i], res);
}
// set unexpected superagent error if no other error has occurred.
if (!errorObj && resError instanceof Error && (!res || resError.status !== res.status)) {
errorObj = resError;
}
if (fn) {
fn.call(this, errorObj || null, res);
}
}
/*
* Adds a set Authorization Bearer
*
* @param {Bearer} Bearer Token
* Shortcut for .set('Authorization', `Bearer ${token}`)
*/
bearer(token) {
this.set('Authorization', `Bearer ${token}`);
return this;
}
/*
* Adds a set Authorization Bearer
*
* @param {Bearer} Bearer Token
* Shortcut for .set('Authorization', `Bearer ${token}`)
*/
bearer(token) {
this.set('Authorization', `Bearer ${token}`);
return this;
}
/**
* Perform assertions on a response body and return an Error upon failure.
*
* @param {Mixed} body
* @param {Response} res
* @return {?Error}
* @api private
*/// eslint-disable-next-line class-methods-use-this
_assertBody(body, res) {
const isRegexp = body instanceof RegExp;
// parsed
if (typeof body === 'object' && !isRegexp) {
try {
deepStrictEqual(body, res.body);
} catch (err) {
const a = inspect(body);
const b = inspect(res.body);
return error('expected ' + a + ' response body, got ' + b, body, res.body);
}
} else if (body !== res.text) {
// string
const a = inspect(body);
const b = inspect(res.text);
// regexp
if (isRegexp) {
if (!body.test(res.text)) {
return error('expected body ' + b + ' to match ' + body, body, res.body);
}
} else {
return error('expected ' + a + ' response body, got ' + b, body, res.body);
}
}
}
/**
* Perform assertions on a response header and return an Error upon failure.
*
* @param {Object} header
* @param {Response} res
* @return {?Error}
* @api private
*/// eslint-disable-next-line class-methods-use-this
_assertHeader(header, res) {
const field = header.name;
const actual = res.header[field.toLowerCase()];
const fieldExpected = header.value;
if (typeof actual === 'undefined') return new Error('expected "' + field + '" header field');
// This check handles header values that may be a String or single element Array
if ((Array.isArray(actual) && actual.toString() === fieldExpected)
|| fieldExpected === actual) {
return;
}
if (fieldExpected instanceof RegExp) {
if (!fieldExpected.test(actual)) {
return new Error('expected "' + field + '" matching '
+ fieldExpected + ', got "' + actual + '"');
}
} else {
return new Error('expected "' + field + '" of "' + fieldExpected + '", got "' + actual + '"');
}
}
/**
* Perform assertions on the response status and return an Error upon failure.
*
* @param {Number} status
* @param {Response} res
* @return {?Error}
* @api private
*/// eslint-disable-next-line class-methods-use-this
_assertStatus(status, res) {
if (res.status !== status) {
const a = STATUS_CODES[status];
const b = STATUS_CODES[res.status];
return new Error('expected ' + status + ' "' + a + '", got ' + res.status + ' "' + b + '"');
}
}
/**
* Perform assertions on the response status and return an Error upon failure.
*
* @param {Array<Number>} statusArray
* @param {Response} res
* @return {?Error}
* @api private
*/// eslint-disable-next-line class-methods-use-this
_assertStatusArray(statusArray, res) {
if (!statusArray.includes(res.status)) {
const b = STATUS_CODES[res.status];
const expectedList = statusArray.join(', ');
return new Error(
'expected one of "' + expectedList + '", got ' + res.status + ' "' + b + '"'
);
}
}
/**
* Performs an assertion by calling a function and return an Error upon failure.
*
* @param {Function} fn
* @param {Response} res
* @return {?Error}
* @api private
*/// eslint-disable-next-line class-methods-use-this
_assertFunction(fn, res) {
let err;
try {
err = fn(res);
} catch (e) {
err = e;
}
if (err instanceof Error) return err;
}
}
/**
* Wraps an assert function into another.
* The wrapper function edit the stack trace of any assertion error, prepending a more useful stack to it.
*
* @param {Function} assertFn
* @returns {Function} wrapped assert function
*/
function wrapAssertFn(assertFn) {
const savedStack = new Error().stack.split('\n').slice(3);
return function(res) {
let badStack;
let err;
try {
err = assertFn(res);
} catch (e) {
err = e;
}
if (err instanceof Error && err.stack) {
badStack = err.stack.replace(err.message, '').split('\n').slice(1);
err.stack = [err.toString()]
.concat(savedStack)
.concat('----')
.concat(badStack)
.join('\n');
}
return err;
};
}
/**
* Return an `Error` with `msg` and results properties.
*
* @param {String} msg
* @param {Mixed} expected
* @param {Mixed} actual
* @return {Error}
* @api private
*/
function error(msg, expected, actual) {
const err = new Error(msg);
err.expected = expected;
err.actual = actual;
err.showDiff = true;
return err;
}
/**
* Expose `Test`.
*/
module.exports = Test;

57
node_modules/supertest/package.json generated vendored Normal file
View File

@@ -0,0 +1,57 @@
{
"name": "supertest",
"description": "SuperAgent driven library for testing HTTP servers",
"version": "7.2.2",
"author": "TJ Holowaychuk",
"contributors": [],
"dependencies": {
"methods": "^1.1.2",
"superagent": "^10.3.0",
"cookie-signature": "^1.2.2"
},
"devDependencies": {
"@commitlint/cli": "17",
"@commitlint/config-conventional": "17",
"body-parser": "^1.20.3",
"cookie-parser": "^1.4.7",
"eslint": "^8.32.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.27.5",
"express": "^4.18.3",
"mocha": "^10.2.0",
"nock": "^13.3.8",
"nyc": "^15.1.0",
"proxyquire": "^2.1.3",
"should": "^13.2.3",
"sinon": "20.0.0"
},
"engines": {
"node": ">=14.18.0"
},
"files": [
"index.js",
"lib"
],
"keywords": [
"bdd",
"http",
"request",
"superagent",
"tdd",
"test",
"testing"
],
"license": "MIT",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/ladjs/supertest.git"
},
"scripts": {
"coverage": "nyc report --reporter=text-lcov > coverage.lcov",
"lint": "eslint lib/**/*.js test/**/*.js index.js",
"lint:fix": "eslint --fix lib/**/*.js test/**/*.js index.js",
"pretest": "npm run lint --if-present",
"test": "nyc --reporter=html --reporter=text mocha --exit --require should --reporter spec --check-leaks"
}
}