thrilled-be-testing
Version:
Testing utilities and helpers package with Jest, Supertest, and database testing support for Express applications
174 lines (173 loc) • 5.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleApiTestRunner = exports.SimpleResponseAssertions = exports.SimpleHttpTestClient = void 0;
const tslib_1 = require("tslib");
const supertest_1 = tslib_1.__importDefault(require("supertest"));
class SimpleHttpTestClient {
app;
baseHeaders;
constructor(app, options = {}) {
this.app = app;
this.baseHeaders = options.headers || {};
}
async get(path, options = {}) {
const req = (0, supertest_1.default)(this.app)
.get(path)
.set({ ...this.baseHeaders, ...options.headers });
if (options.timeout) {
req.timeout(options.timeout);
}
return req;
}
async post(path, body, options = {}) {
const req = (0, supertest_1.default)(this.app)
.post(path)
.set({ ...this.baseHeaders, ...options.headers });
if (body) {
req.send(body);
}
if (options.timeout) {
req.timeout(options.timeout);
}
return req;
}
async put(path, body, options = {}) {
const req = (0, supertest_1.default)(this.app)
.put(path)
.set({ ...this.baseHeaders, ...options.headers });
if (body) {
req.send(body);
}
if (options.timeout) {
req.timeout(options.timeout);
}
return req;
}
async delete(path, options = {}) {
const req = (0, supertest_1.default)(this.app)
.delete(path)
.set({ ...this.baseHeaders, ...options.headers });
if (options.timeout) {
req.timeout(options.timeout);
}
return req;
}
withAuth(token) {
return new SimpleHttpTestClient(this.app, {
headers: {
...this.baseHeaders,
'Authorization': `Bearer ${token}`
}
});
}
withHeaders(headers) {
return new SimpleHttpTestClient(this.app, {
headers: {
...this.baseHeaders,
...headers
}
});
}
}
exports.SimpleHttpTestClient = SimpleHttpTestClient;
class SimpleResponseAssertions {
response;
constructor(response) {
this.response = response;
}
static assert(response) {
return new SimpleResponseAssertions(response);
}
hasStatus(status) {
if (this.response.status !== status) {
throw new Error(`Expected status ${status}, got ${this.response.status}`);
}
return this;
}
hasSuccessStatus() {
if (this.response.status < 200 || this.response.status >= 300) {
throw new Error(`Expected success status (200-299), got ${this.response.status}`);
}
return this;
}
hasErrorStatus() {
if (this.response.status < 400) {
throw new Error(`Expected error status (400+), got ${this.response.status}`);
}
return this;
}
hasContentType(contentType) {
const actualContentType = this.response.headers['content-type'];
if (!actualContentType || !actualContentType.includes(contentType)) {
throw new Error(`Expected content-type to include ${contentType}, got ${actualContentType}`);
}
return this;
}
hasJsonBody() {
return this.hasContentType('application/json');
}
hasBodyProperty(property, value) {
const body = this.response.body;
if (!body || typeof body !== 'object') {
throw new Error('Response body is not an object');
}
if (!(property in body)) {
throw new Error(`Expected body to have property '${property}'`);
}
if (value !== undefined && body[property] !== value) {
throw new Error(`Expected body.${property} to be ${value}, got ${body[property]}`);
}
return this;
}
hasBodyMatching(expectedBody) {
const body = this.response.body;
if (JSON.stringify(body) !== JSON.stringify(expectedBody)) {
throw new Error(`Expected body to match ${JSON.stringify(expectedBody)}, got ${JSON.stringify(body)}`);
}
return this;
}
}
exports.SimpleResponseAssertions = SimpleResponseAssertions;
class SimpleApiTestRunner {
client;
constructor(client) {
this.client = client;
}
async runTestCase(testCase) {
let client = this.client;
if (testCase.auth) {
client = client.withAuth(testCase.auth);
}
if (testCase.headers) {
client = client.withHeaders(testCase.headers);
}
let response;
switch (testCase.method) {
case 'GET':
response = await client.get(testCase.path);
break;
case 'POST':
response = await client.post(testCase.path, testCase.body);
break;
case 'PUT':
response = await client.put(testCase.path, testCase.body);
break;
case 'DELETE':
response = await client.delete(testCase.path);
break;
default:
throw new Error(`Unsupported method: ${testCase.method}`);
}
const assertions = SimpleResponseAssertions.assert(response);
assertions.hasStatus(testCase.expectedStatus);
if (testCase.expectedBody) {
assertions.hasBodyMatching(testCase.expectedBody);
}
}
async runTestCases(testCases) {
for (const testCase of testCases) {
await this.runTestCase(testCase);
}
}
}
exports.SimpleApiTestRunner = SimpleApiTestRunner;