UNPKG

@contexts/http

Version:

The Http(s) Testing Context For Super-Test Style Assertions. Includes Standard Assertions (get, set, assert), And Allows To Be Extended With JSDocumented Custom Assertions.

184 lines (175 loc) 5.3 kB
const Http = require('./build/'); const { Tester } = Http; const { equal, ok } = require('assert'); const erotic = require('erotic'); const { c } = require('erte'); const { wasExpectedError, didNotMatchValue, wasNotExpected, parseSetCookie } = require('./build/lib'); /** * Extends _HTTPContext_ to assert on the cookies. */ class Cookies extends Http { constructor() { super() this.TesterConstructor = CookiesTester /** * Parsed cookies. * @private */ this._cookies = null } /** * Creates a server and wraps the supplied listener in the handler that will set status code `500` if the listener threw and the body to the error text. * @param {function(http.IncomingMessage, http.ServerResponse)} fn * @param {boolean} secure */ start(fn, secure) { const tester = /** @type {CookiesTester} */ (super.start(fn, secure)) return tester } /** * Creates a server with the supplied listener. * @param {function(http.IncomingMessage, http.ServerResponse)} fn * @param {boolean} secure */ startPlain(fn, secure) { const tester = /** @type {CookiesTester} */ (super.startPlain(fn, secure)) return tester } getCookies() { if (this._cookies) return this._cookies const setCookies = /** @type {Array<string>} */ (this.tester.res.headers['set-cookie']) || [] const res = setCookies.map(Cookies.parseSetCookie) this._cookies = res return res } /** * Parses the `set-cookie` header. * @param {string} header */ static parseSetCookie(header) { return parseSetCookie(header) } /** * Returns the cookie record for the given name. * @param {string} name */ getCookieForName(name) { const cookies = this.getCookies() return cookies.find(({ name: n }) => { return name == n }) } _reset() { super._reset() this._cookies = null } } /** * The tester for assertion on cookies. */ class CookiesTester extends Tester { constructor() { super() /** @type {import('.').default} */ this.context = null } /** * Assert on the number of times the cookie was set. * @param {number} num The expected count. */ count(num) { const e = erotic(true) this._addLink(() => { const count = this.context.getCookies().length equal(count, num, 'Should set cookie ' + num + ' times, not ' + count + '.') }, e) return this } /** * Asserts on the value of the cookie. * @param {string} name The name of the cookie. * @param {string} val The value of the cookie. */ value(name, val) { const e = erotic(true) this._addLink(() => { const cookie = this.context.getCookieForName(name) ok(cookie, wasExpectedError('Cookie', name, val)) equal(cookie.value, val, didNotMatchValue('Cookie', name, val, cookie.value)) }, e) return this } /** * Asserts on the presence of the cookie. * @param {string} name The name of the cookie. */ name(name) { const e = erotic(true) this._addLink(() => { const cookie = this.context.getCookieForName(name) ok(cookie, wasExpectedError('Cookie', name)) }, e) return this } /** * Asserts on the presence of an attribute in the cookie. * @param {string} name The name of the cookie. * @param {string} attrib The name of the attribute. */ attribute(name, attrib) { const e = erotic(true) this._addLink(() => { const cookie = this.context.getCookieForName(name) assertAttribute(name, cookie, attrib) }, e) return this } /** * Asserts on the value of the cookie's attribute. * @param {string} name The name of the cookie. * @param {string} attrib The name of the attribute. * @param {string} value The value of the attribute. */ attributeAndValue(name, attrib, value) { const e = erotic(true) this._addLink(() => { const cookie = this.context.getCookieForName(name) assertAttribute(name, cookie, attrib) const actual = cookie[attrib.toLowerCase()] equal(actual, value, didNotMatchValue(`Attribute ${c(attrib, 'blue')} of cookie ${c(name, 'yellow')}`, null, value, actual)) }, e) return this } /** * Asserts on the absence of an attribute in the cookie. * @param {string} name The name of the cookie. * @param {string} attrib The name of the attribute. */ noAttribute(name, attrib) { const e = erotic(true) this._addLink(() => { const cookie = this.context.getCookieForName(name) ok(cookie, wasExpectedError('Cookie', name)) const a = attrib.toLowerCase() ok(!(a in cookie), wasNotExpected(`Attribute ${c(attrib, 'blue')} of cookie ${c(name, 'yellow')}`, null, cookie[a])) }, e) return this } } const assertAttribute = (name, cookie, attrib) => { ok(cookie, wasExpectedError('Cookie', name)) ok((attrib.toLowerCase() in cookie), `Attribute ${c(attrib, 'blue')} of cookie ${c(name, 'yellow')} was expected.`) } /** * @typedef {import('http').IncomingMessage} http.IncomingMessage * @typedef {import('http').ServerResponse} http.ServerResponse * @typedef {import('@rqt/aqt').AqtReturn} AqtReturn */ module.exports = Cookies module.exports.CookiesTester = CookiesTester