UNPKG

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
"use strict"; 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;