UNPKG

rxrest-assert

Version:

Assert library for RxRest

210 lines 8.36 kB
"use strict"; /// <reference path="../node-status-code.d.ts" /> Object.defineProperty(exports, "__esModule", { value: true }); const rxjs_1 = require("rxjs"); const nodeStatusCodes = require("node-status-codes"); class RxRestAssertionError extends TypeError { } exports.RxRestAssertionError = RxRestAssertionError; class RxRestAssert { constructor(config, options = { log: false }) { this.$expectations = []; this.$whens = new Map(); this.$requestInterceptorIndex = 0; this.$responseInterceptorIndex = 0; this.$requestCount = 0; this.log = options.log; this.config = config; this.$requestInterceptorIndex = config.requestInterceptors.push((request) => { this.$requestCount++; let expect = this.$expectations[this.$expectations.length - 1]; let requestURL = this.$getRequestURL(request); if (expect) { this.$current = 'expectation'; return; } for (let key of this.$whens.keys()) { if (key.method === request.method && this.$matchURL(key.url, requestURL)) { this.$current = key; return; } } this.$current = null; }); config.fetch = (request) => { const defaultResponse = new Response('{}', { status: 200, statusText: 'OK', headers: new Headers() }); this.$log(`Doing a request ${request.method} ${request.url}`); if (this.$current === null) { return rxjs_1.of(defaultResponse); } let expectation; if (this.$current === 'expectation') { expectation = this.$expectations.shift(); } else if (this.$current !== null) { expectation = this.$whens.get(this.$current); } if (expectation !== undefined) { expectation(request); this.$requestCount--; } else { this.$throw(`Request ${request.method} ${request.url} not expected`); } let response = expectation.response ? expectation.response : defaultResponse; return rxjs_1.of(response); }; this.$responseInterceptorIndex = config.responseInterceptors.push((response) => { if (this.$current !== null && this.$current !== 'expectation') { this.$whens.delete(this.$current); } }); } $expectation(method, url, data, assertion = true) { const self = this; this.$log(`Preparing expectation on ${method} ${url}`); const assert = function (request) { if (assertion === false) { return; } if (request.method !== method) { self.$throw(`Method should be "${method}", got "${request.method}"`); } let requestURL = self.$getRequestURL(request); if (!self.$matchURL(url, requestURL)) { self.$throw(`URL should ${url instanceof RegExp ? `match "${url.toString()}"` : `be "${url}"`}, got "${requestURL}"`); } if (typeof data === 'function' && !data(request)) { self.$throw('The request test failed'); } else if (data instanceof Request) { for (let header of data.headers) { let requestHeaderValue = request.headers.get(header[0]); if (requestHeaderValue !== header[1]) { self.$throw(`Header "${header[0]}" does not match on Request, found "${requestHeaderValue}" but "${header[1]}" was expected`); } } let expectedQueryParamsString = data.url.match(/\?(.+)/); let expectedQueryParams = expectedQueryParamsString === null ? new URLSearchParams() : new URLSearchParams(expectedQueryParamsString[1]); let requestQueryParamsString = request.url.match(/\?(.+)/); let requestQueryParams = requestQueryParamsString === null ? new URLSearchParams() : new URLSearchParams(requestQueryParamsString[1]); if (expectedQueryParams.toString().length) { for (let param of expectedQueryParams) { let requestQueryParam = requestQueryParams.get(param[0]); if (requestQueryParam !== param[1]) { self.$throw(`Query param "${param[0]}" does not match on Request, found "${requestQueryParam}" but "${param[1]}" was expected`); } } } } }; assert.url = url; assert.method = method; assert.respond = (response) => { let statusCode = response; if (!isNaN(statusCode) && isFinite(statusCode)) { assert.response = new Response('{}', { status: statusCode, statusText: nodeStatusCodes[statusCode], headers: new Headers() }); return; } assert.response = response instanceof Response ? response : new Response(JSON.stringify(response), { status: 200, statusText: 'OK', headers: new Headers() }); }; return assert; } $log(message) { if (this.log === false) { return; } console.error(message); } $throw(message) { this.$requestCount--; throw new RxRestAssertionError(message); } $getRequestURL(request) { return request.url.replace(this.config.baseURL, '').replace(/\?.+/, '').replace(/\/$/, ''); } $matchURL(url, requestURL) { return (url instanceof RegExp && url.test(requestURL)) || url === requestURL; } expect(method, url, data) { method = method.toUpperCase(); let expect = this.$expectation(method, url, data); let index = this.$expectations.push(expect); return { respond: expect.respond }; } expectGET(url, data) { return this.expect('GET', url, data); } expectPOST(url, data) { return this.expect('POST', url, data); } expectPUT(url, data) { return this.expect('PUT', url, data); } expectHEAD(url, data) { return this.expect('HEAD', url, data); } expectPATCH(url, data) { return this.expect('PATCH', url, data); } expectDELETE(url, data) { return this.expect('DELETE', url, data); } when(method, url, data) { method = method.toUpperCase(); let expect = this.$expectation(method, url, data, false); this.$whens.set({ url: url, method: method }, expect); return { respond: expect.respond }; } whenGET(url, data) { return this.when('GET', url, data); } whenPOST(url, data) { return this.when('POST', url, data); } whenPUT(url, data) { return this.when('PUT', url, data); } whenHEAD(url, data) { return this.when('HEAD', url, data); } whenPATCH(url, data) { return this.when('PATCH', url, data); } whenDELETE(url, data) { return this.when('DELETE', url, data); } resetExpectations() { this.$expectations.length = 0; } verifyNoOutstandingExpectation() { if (this.$expectations.length) { throw new RxRestAssertionError(`There is ${this.$expectations.length} pending expectation`); } } verifyNoOutstandingRequest() { if (this.$requestCount > 0) { throw new RxRestAssertionError(`There is ${this.$requestCount} pending request`); } } destroy() { this.resetExpectations(); this.$whens = new Map(); this.$requestCount = 0; this.config.fetch = null; this.config.requestInterceptors = this.config.requestInterceptors .filter((e, i) => { return i === this.$requestInterceptorIndex; }); this.config.responseInterceptors = this.config.responseInterceptors .filter((e, i) => { return i === this.$responseInterceptorIndex; }); } } exports.RxRestAssert = RxRestAssert; //# sourceMappingURL=index.js.map