You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

chai-http

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chai-http - npm Package Compare versions

Comparing version

to
5.0.0-alpha2

3

index.js

@@ -1,1 +0,2 @@

module.exports = require('./lib/http');
import fn from './lib/http.js';
export default fn;

@@ -14,20 +14,24 @@ /*!

module.exports = function (chai, _) {
/*!
* Module dependencies.
*/
import net from 'net';
import url from 'url';
import Cookie from 'cookiejar';
import charset from 'charset';
import qs from 'qs';
import * as _request from './request.js';
/**
*
* @param {ChaiStatic} chai
* @param {ChaiUtils} _
*/
export default function (chai, _) {
/*!
* Module dependencies.
*/
var net = require('net');
var qs = require('qs');
var url = require('url');
var Cookie = require('cookiejar');
var charset = require("charset");
/*!
* Aliases.
*/
var Assertion = chai.Assertion
, i = _.inspect;
const Assertion = chai.Assertion;
const i = _.inspect;

@@ -38,3 +42,3 @@ /*!

chai.request = require('./request');
chai.request = _request;

@@ -48,6 +52,6 @@ /*!

var contentTypes = {
json: 'application/json'
, text: 'text/plain'
, html: 'text/html'
const contentTypes = {
json: 'application/json',
text: 'text/plain',
html: 'text/html'
};

@@ -67,3 +71,3 @@

if (obj.headers) return obj.headers[key];
};
}

@@ -85,20 +89,22 @@ /**

Assertion.addMethod('status', function (code) {
var hasStatus = Boolean('status' in this._obj || 'statusCode' in this._obj);
const hasStatus = Boolean(
'status' in this._obj || 'statusCode' in this._obj
);
new Assertion(hasStatus).assert(
hasStatus
, "expected #{act} to have keys 'status', or 'statusCode'"
, null // never negated
, hasStatus // expected
, this._obj // actual
, false // no diff
hasStatus,
"expected #{act} to have keys 'status', or 'statusCode'",
null, // never negated
hasStatus, // expected
this._obj, // actual
false // no diff
);
var status = this._obj.status || this._obj.statusCode;
const status = this._obj.status || this._obj.statusCode;
this.assert(
status == code
, 'expected #{this} to have status code #{exp} but got #{act}'
, 'expected #{this} to not have status code #{act}'
, code
, status
status == code,
'expected #{this} to have status code #{exp} but got #{act}',
'expected #{this} to not have status code #{act}',
code,
status
);

@@ -133,25 +139,40 @@ });

Assertion.addMethod('header', function (key, value) {
var header = getHeader(this._obj, key);
const header = getHeader(this._obj, key);
if (arguments.length < 2) {
this.assert(
'undefined' !== typeof header || null === header
, 'expected header \'' + key + '\' to exist'
, 'expected header \'' + key + '\' to not exist'
'undefined' !== typeof header || null === header,
"expected header '" + key + "' to exist",
"expected header '" + key + "' to not exist"
);
} else if (arguments[1] instanceof RegExp) {
this.assert(
value.test(header)
, 'expected header \'' + key + '\' to match ' + value + ' but got ' + i(header)
, 'expected header \'' + key + '\' not to match ' + value + ' but got ' + i(header)
, value
, header
value.test(header),
"expected header '" +
key +
"' to match " +
value +
' but got ' +
i(header),
"expected header '" +
key +
"' not to match " +
value +
' but got ' +
i(header),
value,
header
);
} else {
this.assert(
header == value
, 'expected header \'' + key + '\' to have value ' + value + ' but got ' + i(header)
, 'expected header \'' + key + '\' to not have value ' + value
, value
, header
header == value,
"expected header '" +
key +
"' to have value " +
value +
' but got ' +
i(header),
"expected header '" + key + "' to not have value " + value,
value,
header
);

@@ -182,5 +203,5 @@ }

this.assert(
this._obj.headers || this._obj.getHeader
, 'expected #{this} to have headers or getHeader method'
, 'expected #{this} to not have headers or getHeader method'
this._obj.headers || this._obj.getHeader,
'expected #{this} to have headers or getHeader method',
'expected #{this} to not have headers or getHeader method'
);

@@ -205,5 +226,5 @@ });

this.assert(
net.isIP(this._obj)
, 'expected #{this} to be an ip'
, 'expected #{this} to not be an ip'
net.isIP(this._obj),
'expected #{this} to be an ip',
'expected #{this} to not be an ip'
);

@@ -229,16 +250,14 @@ });

function checkContentType (name) {
var val = contentTypes[name];
function checkContentType(name) {
const val = contentTypes[name];
Assertion.addProperty(name, function () {
new Assertion(this._obj).to.have.headers;
var ct = getHeader(this._obj, 'content-type')
, ins = i(ct) === 'undefined'
? 'headers'
: i(ct);
const ct = getHeader(this._obj, 'content-type'),
ins = i(ct) === 'undefined' ? 'headers' : i(ct);
this.assert(
ct && ~ct.indexOf(val)
, 'expected ' + ins + ' to include \'' + val + '\''
, 'expected ' + ins + ' to not include \'' + val + '\''
ct && ~ct.indexOf(val),
'expected ' + ins + " to include '" + val + "'",
'expected ' + ins + " to not include '" + val + "'"
);

@@ -248,5 +267,3 @@ });

Object
.keys(contentTypes)
.forEach(checkContentType);
Object.keys(contentTypes).forEach(checkContentType);

@@ -269,4 +286,4 @@ /**

var headers = this._obj.headers;
var cs = charset(headers);
const headers = this._obj.headers;
let cs = charset(headers);

@@ -277,11 +294,11 @@ /*

*/
if (cs === "utf8") {
cs = "utf-8";
if (cs === 'utf8') {
cs = 'utf-8';
}
this.assert(
cs != null && value === cs
, 'expected content type to have ' + value + ' charset'
, 'expected content type to not have ' + value + ' charset'
)
cs != null && value === cs,
'expected content type to have ' + value + ' charset',
'expected content type to not have ' + value + ' charset'
);
});

@@ -302,11 +319,11 @@

Assertion.addProperty('redirect', function() {
var redirectCodes = [301, 302, 303, 307, 308]
, status = this._obj.status
, redirects = this._obj.redirects;
Assertion.addProperty('redirect', function () {
const redirectCodes = [301, 302, 303, 307, 308],
status = this._obj.status,
redirects = this._obj.redirects;
this.assert(
redirectCodes.indexOf(status) >= 0 || redirects && redirects.length
, "expected redirect with 30X status code but got " + status
, "expected not to redirect but got " + status + " status"
redirectCodes.indexOf(status) >= 0 || (redirects && redirects.length),
'expected redirect with 30X status code but got ' + status,
'expected not to redirect but got ' + status + ' status'
);

@@ -329,13 +346,14 @@ });

Assertion.addMethod('redirectTo', function(destination) {
var redirects = this._obj.redirects;
Assertion.addMethod('redirectTo', function (destination) {
const redirects = this._obj.redirects;
new Assertion(this._obj).to.redirect;
if(redirects && redirects.length) {
var hasRedirected;
if (redirects && redirects.length) {
let hasRedirected;
if (Object.prototype.toString.call(destination) === '[object RegExp]') {
hasRedirected = redirects.some(redirect => destination.test(redirect));
hasRedirected = redirects.some((redirect) =>
destination.test(redirect)
);
} else {

@@ -345,8 +363,14 @@ hasRedirected = redirects.indexOf(destination) > -1;

this.assert(
hasRedirected
, 'expected redirect to ' + destination + ' but got ' + redirects.join(' then ')
, 'expected not to redirect to ' + destination + ' but got ' + redirects.join(' then ')
hasRedirected,
'expected redirect to ' +
destination +
' but got ' +
redirects.join(' then '),
'expected not to redirect to ' +
destination +
' but got ' +
redirects.join(' then ')
);
} else {
var assertion = new Assertion(this._obj);
const assertion = new Assertion(this._obj);
_.transferFlags(this, assertion);

@@ -375,4 +399,4 @@ assertion.with.header('location', destination);

Assertion.addMethod('param', function(name, value) {
var assertion = new Assertion();
Assertion.addMethod('param', function (name, value) {
const assertion = new Assertion();
_.transferFlags(this, assertion);

@@ -408,7 +432,7 @@ assertion._obj = qs.parse(url.parse(this._obj.url).query);

Assertion.addMethod('cookie', function (key, value) {
var header = getHeader(this._obj, 'set-cookie')
, cookie;
let header = getHeader(this._obj, 'set-cookie'),
cookie;
if (!header) {
header = (getHeader(this._obj, 'cookie') || '').split(';');
header = (getHeader(this._obj, 'cookie') || '').split(';');
}

@@ -426,16 +450,16 @@

this.assert(
cookie.value == value
, 'expected cookie \'' + key + '\' to have value #{exp} but got #{act}'
, 'expected cookie \'' + key + '\' to not have value #{exp}'
, value
, cookie.value
cookie.value == value,
"expected cookie '" + key + "' to have value #{exp} but got #{act}",
"expected cookie '" + key + "' to not have value #{exp}",
value,
cookie.value
);
} else {
this.assert(
'undefined' !== typeof cookie || null === cookie
, 'expected cookie \'' + key + '\' to exist'
, 'expected cookie \'' + key + '\' to not exist'
'undefined' !== typeof cookie || null === cookie,
"expected cookie '" + key + "' to exist",
"expected cookie '" + key + "' to not exist"
);
}
});
};
}

@@ -10,6 +10,2 @@ /*!

*/
var isIP = require('is-ip');
exports.isIP = isIP;
exports.isIPv4 = isIP.v4;
exports.isIPv6 = isIP.v6;
export {isIP, isIPv4, isIPv6} from 'is-ip';

@@ -10,10 +10,10 @@ /*!

*/
import superagent from 'superagent';
import http from 'http';
import https from 'https';
import methods from 'methods';
import util from 'util';
var http = require('http')
, https = require('https')
, methods = require('methods')
, superagent = require('superagent')
, Agent = superagent.agent
, Request = superagent.Request
, util = require('util');
const Agent = superagent.agent;
const Request = superagent.Request;

@@ -177,3 +177,3 @@ /**

* }
* var chai = require('chai');
* const chai = require('chai');
* chai.use(require('chai-http'));

@@ -190,3 +190,3 @@ *

* // Log in
* var agent = chai.request.agent(app)
* const agent = chai.request.agent(app)
* agent

@@ -208,4 +208,8 @@ * .post('/session')

module.exports = function (app) {
/**
*
* @param {ChaiHttpRequest} app
* @returns {ChaiHttp.Agent}
*/
function execute(app) {
/*!

@@ -216,35 +220,31 @@ * @param {Mixed} function or server

var server = ('function' === typeof app)
? http.createServer(app)
: app
, obj = {};
let server = 'function' === typeof app ? http.createServer(app) : app,
obj = {};
var keepOpen = false
let keepOpen = false;
if (typeof server !== 'string' && server && server.listen && server.address) {
if (!server.address()) {
server = server.listen(0)
server = server.listen(0);
}
}
obj.keepOpen = function() {
keepOpen = true
return this
}
obj.close = function(callback) {
obj.keepOpen = function () {
keepOpen = true;
return this;
};
obj.close = function (callback) {
if (server && server.close) {
server.close(callback);
}
else if(callback) {
} else if (callback) {
callback();
}
return this
}
return this;
};
methods.forEach(function (method) {
obj[method] = function (path) {
return new Test(server, method, path)
.on('end', function() {
if(keepOpen === false) {
obj.close();
}
});
return new Test(server, method, path).on('end', function () {
if (keepOpen === false) {
obj.close();
}
});
};

@@ -254,8 +254,4 @@ });

return obj;
};
}
module.exports.Test = Test;
module.exports.Request = Test;
module.exports.agent = TestAgent;
/*!

@@ -274,7 +270,7 @@ * Test

function Test (app, method, path) {
function Test(app, method, path) {
Request.call(this, method, path);
this.app = app;
this.url = typeof app === 'string' ? app + path : serverAddress(app, path);
this.ok(function() {
this.ok(function () {
return true;

@@ -285,11 +281,11 @@ });

function serverAddress (app, path) {
function serverAddress(app, path) {
if ('string' === typeof app) {
return app + path;
}
var addr = app.address();
const addr = app.address();
if (!addr) {
throw new Error('Server is not listening')
throw new Error('Server is not listening');
}
var protocol = (app instanceof https.Server) ? 'https' : 'http';
const protocol = app instanceof https.Server ? 'https' : 'http';
// If address is "unroutable" IPv4/6 address, then set to localhost

@@ -302,3 +298,2 @@ if (addr.address === '0.0.0.0' || addr.address === '::') {

/*!

@@ -316,9 +311,16 @@ * agent

function TestAgent(app) {
function TestAgent(app, options = {}) {
if (!(this instanceof TestAgent)) return new TestAgent(app);
if (typeof app === 'function') app = http.createServer(app);
(Agent || Request).call(this);
const agent = new Agent(options);
Object.assign(this, agent);
this.app = app;
if (typeof app !== 'string' && app && app.listen && app.address && !app.address()) {
this.app = app.listen(0)
if (
typeof app !== 'string' &&
app &&
app.listen &&
app.address &&
!app.address()
) {
this.app = app.listen(0);
}

@@ -330,15 +332,15 @@ }

if (this.app && this.app.close) {
this.app.close(callback)
this.app.close(callback);
}
return this
}
return this;
};
TestAgent.prototype.keepOpen = function keepOpen() {
return this
}
return this;
};
// override HTTP verb methods
methods.forEach(function(method){
TestAgent.prototype[method] = function(url){
var req = new Test(this.app, method, url)
, self = this;
methods.forEach(function (method) {
TestAgent.prototype[method] = function (url) {
const req = new Test(this.app, method, url),
self = this;

@@ -348,8 +350,13 @@ if (Agent) {

// `Agent._saveCookies()` and `Agent._attachCookies()`.
req.on('response', function (res) { self._saveCookies(res); });
req.on('redirect', function (res) { self._saveCookies(res); });
req.on('redirect', function () { self._attachCookies(req); });
req.on('response', function (res) {
self._saveCookies(res);
});
req.on('redirect', function (res) {
self._saveCookies(res);
});
req.on('redirect', function () {
self._attachCookies(req);
});
this._attachCookies(req);
}
else {
} else {
// When running in a web browser, cookies are managed via `Request.withCredentials()`.

@@ -366,1 +373,3 @@ // The browser will attach cookies based on same-origin policy.

TestAgent.prototype.del = TestAgent.prototype.delete;
export {execute, Test as Request, TestAgent as agent};
{
"name": "chai-http",
"version": "5.0.0-alpha1",
"version": "5.0.0-alpha2",
"description": "Extend Chai Assertion library with tests for http apis",

@@ -23,3 +23,2 @@ "author": "Jake Luer <jake@alogicalparadox.com>",

"files": [
"dist/chai-http.js",
"lib/*.js",

@@ -36,12 +35,9 @@ "index.js",

"scripts": {
"build": "npm run build:js && npm run build:ts",
"prebuild:js": "rm -rf dist",
"build:js": "simplifyify lib/http.js --outfile dist/chai-http.js --bundle --minify --debug --standalone chaiHttp",
"build": "npm run build:ts",
"build:ts": "cd types && tsc",
"start": "npm-run-all --parallel watch server",
"watch": "npm run build:js -- --watch",
"server": "http-server -o -c-1",
"test": "nyc --reporter=lcovonly --reporter=text-summary mocha",
"coverage": "if [ -z \"$COVERALLS_REPO_TOKEN\" ]; then cat coverage/lcov.info | coveralls; fi",
"release": "npm run build && semantic-release"
"eslint": "eslint"
},

@@ -55,31 +51,32 @@ "browser": {

"dependencies": {
"@types/chai": "4",
"@types/superagent": "^4.1.18",
"charset": "^1.0.1",
"cookiejar": "^2.1.4",
"is-ip": "^3.1.0",
"is-ip": "^5.0.1",
"methods": "^1.1.2",
"qs": "^6.11.2",
"superagent": "^8.0.9"
"qs": "^6.12.1",
"superagent": "^9"
},
"devDependencies": {
"@jsdevtools/simplifyify": "^8.0.4",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^10.0.1",
"@semantic-release/git": "^10.0.1",
"@semantic-release/npm": "^10.0.4",
"@semantic-release/release-notes-generator": "^11.0.3",
"chai": "4",
"@eslint/js": "^9.3.0",
"@types/chai": "^4.3.15",
"@types/superagent": "^8.1.7",
"chai": "^5.1.0",
"coveralls": "^3.1.1",
"es6-shim": "^0.35.8",
"eslint": "^9.3.0",
"eslint-plugin-mocha": "^10.4.3",
"http-server": "^14.1.1",
"mocha": "^10.2.0",
"npm-run-all": "^4.1.5",
"mocha": "^10.4.0",
"npm-run-all2": "^6.2.0",
"nyc": "^15.1.0",
"semantic-release": "^21.0.5",
"typescript": "^5.1.3"
"prettier": "^3.2.5",
"typescript": "^5.4.5"
},
"engines": {
"node": ">=16.20.0"
"node": ">=18.20.0"
},
"type": "module",
"mocha": {
"reporter": "spec",
"require": "./test/bootstrap/index.js"
}
}

@@ -23,18 +23,10 @@ # Chai HTTP [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release) [![NPM version](https://img.shields.io/npm/v/chai-http.svg)](https://img.shields.io/npm/v/chai-http.svg)

```js
const chai = require('chai');
const chaiHttp = require('chai-http');
import chaiModule from "chai";
import chaiHttp from "chai-http";
chai.use(chaiHttp);
const chai = chaiModule.use(chaiHttp);
```
To use Chai HTTP on a web page, just include the [`dist/chai-http.js`](dist/chai-http.js) file:
To use Chai HTTP on a web page, please use the latest v4 version for now.
```html
<script src="chai.js"></script>
<script src="chai-http.js"></script>
<script>
chai.use(chaiHttp);
</script>
```
## Integration Testing

@@ -61,3 +53,3 @@

```js
chai.request(app)
chai.request.execute(app)
.get('/')

@@ -73,3 +65,3 @@ ```

```js
const requester = chai.request(app).keepOpen()
const requester = chai.request.Request(app).keepOpen()

@@ -90,3 +82,3 @@ Promise.all([

```js
chai.request('http://localhost:8080')
chai.request.execute('http://localhost:8080')
.get('/')

@@ -113,3 +105,3 @@ ```

// Set a request header
chai.request(app)
chai.request.execute(app)
.put('/user/me')

@@ -123,3 +115,3 @@ .set('Content-Type', 'application/json')

// Send some JSON
chai.request(app)
chai.request.execute(app)
.put('/user/me')

@@ -132,3 +124,3 @@ .send({ password: '123', confirmPassword: '123' })

// Send some Form Data
chai.request(app)
chai.request.execute(app)
.post('/user/me')

@@ -146,3 +138,3 @@ .type('form')

// Attach a file
chai.request(app)
chai.request.execute(app)
.post('/user/avatar')

@@ -155,3 +147,3 @@ .attach('imageField', fs.readFileSync('avatar.png'), 'avatar.png')

// Authenticate with Basic authentication
chai.request(app)
chai.request.execute(app)
.get('/protected')

@@ -161,3 +153,3 @@ .auth('user', 'pass')

// Authenticate with Bearer Token
chai.request(app)
chai.request.execute(app)
.get('/protected')

@@ -171,3 +163,3 @@ .auth(accessToken, { type: 'bearer' })

// Chain some GET query parameters
chai.request(app)
chai.request.execute(app)
.get('/search')

@@ -188,3 +180,3 @@ .query({name: 'foo', limit: 10}) // /search?name=foo&limit=10

```js
chai.request(app)
chai.request.execute(app)
.put('/user/me')

@@ -212,3 +204,3 @@ .send({ password: '123', confirmPassword: '123' })

it('fails, as expected', function(done) { // <= Pass in done callback
chai.request('http://localhost:8080')
chai.request.execute('http://localhost:8080')
.get('/')

@@ -222,3 +214,3 @@ .end((err, res) => {

it('succeeds silently!', () => { // <= No done callback
chai.request('http://localhost:8080')
chai.request.execute('http://localhost:8080')
.get('/')

@@ -241,3 +233,3 @@ .end((err, res) => {

```js
chai.request(app)
chai.request.execute(app)
.put('/user/me')

@@ -253,19 +245,2 @@ .send({ password: '123', confirmPassword: '123' })

__Note:__ Some older web browsers do not have native promise support. You can use any spec compliant library, such as:
- [kriskowal/q](https://github.com/kriskowal/q)
- [stefanpenner/es6-promise](https://github.com/stefanpenner/es6-promise)
- [petkaantonov/bluebird](https://github.com/petkaantonov/bluebird)
- [then/promise](https://github.com/then/promise)
You will need to set the library you use to `global.Promise`, before
requiring in chai-http. For example:
```js
// Add promise support if this does not exist natively.
if (!global.Promise) {
global.Promise = require('q');
}
const chai = require('chai');
chai.use(require('chai-http'));
```
#### Retaining cookies with each request

@@ -272,0 +247,0 @@

@@ -12,49 +12,47 @@ // Definitions by: Wim Looman <https://github.com/Nemo157>

declare global {
namespace Chai {
interface ChaiStatic {
request: ChaiHttpRequest;
}
namespace Chai {
interface ChaiStatic {
request: ChaiHttpRequest;
}
interface ChaiHttpRequest {
(server: any): ChaiHttp.Agent;
interface ChaiHttpRequest {
agent(server: any): ChaiHttp.Agent;
Request(app: string | any, method: string, path: string): void;
execute: (app: string | any) => ChaiHttp.Agent;
}
agent(server: any): ChaiHttp.Agent;
interface Assertion {
redirectTo(location: string | RegExp): Assertion;
addPromises(promiseConstructor: PromiseConstructorLike): void;
}
param(key: string, value?: string): Assertion;
interface Assertion {
redirectTo(location: string|RegExp): Assertion;
cookie(key: string, value?: string): Assertion;
param(key: string, value?: string): Assertion;
status(code: number): Assertion;
cookie(key: string, value?: string): Assertion;
statusCode(code: number): Assertion;
status(code: number): Assertion;
header(key: string, value?: string | RegExp): Assertion;
statusCode(code: number): Assertion;
charset(charset: string): Assertion;
header(key: string, value?: string | RegExp): Assertion;
headers: Assertion;
json: Assertion;
text: Assertion;
html: Assertion;
redirect: Assertion;
}
charset(charset: string): Assertion;
headers: Assertion;
json: Assertion;
text: Assertion;
html: Assertion;
redirect: Assertion;
}
interface TypeComparison {
ip: Assertion;
}
interface TypeComparison {
ip: Assertion;
}
}
namespace ChaiHttp {
interface Response extends request.Response {}
interface Agent extends request.SuperAgentStatic {
keepOpen(): Agent;
close(callback?: (err: any) => void): Agent;
}
namespace ChaiHttp {
interface Response extends request.Response {}
interface Agent extends request.SuperAgentStatic {
keepOpen(): Agent;
close(callback?: (err: any) => void): Agent;
}
}
}

@@ -64,2 +62,2 @@

export = chaiHttp;
export default chaiHttp;