declarative-e2e-test
Version:
Declaration driven test generator for REST endpoints
152 lines • 5.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestedRequest = void 0;
const supertest_1 = require("supertest");
const logger_1 = require("./utils/logger");
const logger = logger_1.Logger.getLogger();
class TestedRequest {
constructor(props, globalRequestConfig = {}) {
this.props = props;
this.globalRequestConfig = globalRequestConfig;
}
static buildTestedRequest(props, globalRequestConfig) {
return new TestedRequest(props, globalRequestConfig);
}
setResponse(resp) {
this.response = resp;
}
evaluateRequestProps(context) {
return evaluateRequestDefinition(this.props, this.globalRequestConfig, context);
}
run(context, app) {
return new Promise((resolve, reject) => {
const requestProps = this.evaluateRequestProps(context);
this.initializeAgent(requestProps, app)
.applyHeaders(requestProps)
.applyBody(requestProps)
.applyExpect(requestProps, context, resolve)
.applyErrorHandler(requestProps, context);
});
}
initializeAgent(requestProps, app) {
this.agent = this.createAgent(requestProps, app);
return this;
}
createAgent(requestProps, app) {
const verb = requestProps.verb || 'GET', agt = supertest_1.agent(app || requestProps.url), route = app ? requestProps.url : '';
logger.debug(`${verb} Request to ${requestProps.url} - ${app ? 'app instance provided' : 'no app instance'}`);
switch (verb) {
case 'HEAD':
return agt.head(route);
case 'POST':
return agt.post(route);
case 'PUT':
return agt.put(route);
case 'PATCH':
return agt.patch(route);
case 'DELETE':
return agt.delete(route);
case 'GET':
default:
return agt.get(route);
}
}
applyHeaders(requestProps) {
if (requestProps.headers && Object.keys(requestProps.headers).length !== 0) {
logger.trace('Request headers applied:', requestProps.headers);
this.agent = this.agent.set(requestProps.headers);
}
return this;
}
applyBody(requestProps) {
if (requestProps.body) {
logger.trace('Request body applied:', requestProps.body);
this.agent = this.agent.send(requestProps.body);
}
return this;
}
applyExpect(requestProps, context, done) {
// keep the response for error callback
this.agent = this.agent.expect((resp) => this.setResponse(resp));
this.agent = requestProps.expect
.reduce((agent, expect) => {
switch (typeof expect) {
case 'number':
case 'string':
return agent.expect(expect);
case 'function':
return agent.expect(expect.bind(context));
case 'object':
const hasExpectedHeaders = 'headers' in expect, hasExpectedBody = 'body' in expect;
if (hasExpectedHeaders) {
agent = Object.entries(expect.headers)
.reduce((agt, [key, value]) => {
if (!Array.isArray(value)) {
return agt.expect(key, value);
}
for (const val of value) {
agt = agt.expect(key, val);
}
return agt;
}, agent);
}
if (hasExpectedBody) {
agent = agent.expect(expect.body);
}
if (!hasExpectedHeaders && !hasExpectedBody) {
agent = agent.expect(expect);
}
return agent;
default:
logger.error(`Unsupported type: ${typeof expect} for expect`);
return agent;
}
}, this.agent);
if (done) {
this.agent.then(done);
}
return this;
}
applyErrorHandler(requestProps, context) {
this.agent.catch((error) => {
logger.error(error);
if (requestProps.error) {
requestProps.error.call(context, error, this.response);
return;
}
logger.error(`Error caught, use property "error" in the request definition to access error the object`);
});
return this;
}
}
exports.TestedRequest = TestedRequest;
function evaluateRequestDefinition(props, globalRequestConfig, context) {
const { verb, url, headers, body, expect, error } = props, requestProps = {
verb,
url: evaluateValue(url, context),
headers: evaluateValue(headers, context),
body: evaluateValue(body, context),
expect,
error
};
logger.trace(`Request URL in global config: "${globalRequestConfig.url}", test definition: ${requestProps.url}`);
return {
...requestProps,
url: `${globalRequestConfig.url || ''}${requestProps.url}`,
headers: {
...globalRequestConfig.headers,
...requestProps.headers
},
expect: [requestProps.expect, globalRequestConfig.expect]
.filter(e => e !== undefined)
.flat()
};
}
function evaluateValue(value, context) {
if (typeof value !== 'function') {
return value;
}
const valueGetter = value;
return valueGetter.call(context);
}
//# sourceMappingURL=tested-request.js.map