UNPKG

@opra/testing

Version:
273 lines (272 loc) 9.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApiExpectCollection = void 0; exports.convertFilter = convertFilter; const tslib_1 = require("tslib"); const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is")); const objects_1 = require("@jsopen/objects"); const common_1 = require("@opra/common"); const expect_1 = require("expect"); const rule_judgment_1 = tslib_1.__importDefault(require("rule-judgment")); const api_expect_base_js_1 = require("./api-expect-base.js"); const ruleJudgment = typeof rule_judgment_1.default === 'object' ? rule_judgment_1.default.default : rule_judgment_1.default; class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase { get not() { return new ApiExpectCollection(this.response, !this.isNot); } /** * Tests if Collection have number of items in payload * @param min Minimum number of items. Default 1 * @param max Maximum number of items */ toReturnItems(min, max) { let msg = ''; try { const data = type_is_1.default.is(this.response.contentType, [ common_1.MimeTypes.opra_response_json, ]) ? this.response.body.payload : this.response.body; msg += `Payload should be array.`; this._expect(Array.isArray(data)).toBeTruthy(); msg += `The length of payload array do not match. `; const l = data.length; this._expect(l).toBeGreaterThanOrEqual(min || 1); if (max) this._expect(l).toBeLessThanOrEqual(max); } catch (e) { if (msg) e.message = msg + '\n\n' + e.message; Error.captureStackTrace(e, this.toReturnItems); throw e; } return this; } toContainTotalMatches(min, max) { let msg = ''; try { msg += `The value of "totalMatches" do not match. `; const l = this.response.body.totalMatches; this._expect(l).toBeGreaterThanOrEqual(min || 1); if (max) this._expect(l).toBeLessThanOrEqual(max); } catch (e) { if (msg) e.message = msg + '\n\n' + e.message; Error.captureStackTrace(e, this.toReturnItems); throw e; } return this; } /** * Tests if Collection items matches given object * @param expected */ toMatch(expected) { try { expected = (0, objects_1.omitNullish)(expected); const data = type_is_1.default.is(this.response.contentType, [ common_1.MimeTypes.opra_response_json, ]) ? this.response.body.payload : this.response.body; for (const x of data) { this._expect(x).toMatchObject(expected); } } catch (e) { Error.captureStackTrace(e, this.toMatch); throw e; } return this; } /** * Tests if Collection items has all of provided fields. * @param fields */ toContainFields(fields) { try { fields = Array.isArray(fields) ? fields : [fields]; const data = type_is_1.default.is(this.response.contentType, [ common_1.MimeTypes.opra_response_json, ]) ? this.response.body.payload : this.response.body; for (const item of data) { this._expect(Object.keys(item)).toEqual(expect_1.expect.arrayContaining(fields)); } } catch (e) { Error.captureStackTrace(e, this.toContainFields); throw e; } return this; } /** * Tests if Collection items only contains all of provided fields. * @param fields */ toContainAllFields(fields) { try { fields = Array.isArray(fields) ? fields : [fields]; const data = type_is_1.default.is(this.response.contentType, [ common_1.MimeTypes.opra_response_json, ]) ? this.response.body.payload : this.response.body; for (const item of data) { this._expect(Object.keys(item)).toEqual(fields); } } catch (e) { Error.captureStackTrace(e, this.toContainAllFields); throw e; } return this; } /** * Tests if Collection is sorted by given field(s). * @param fields */ toBeSortedBy(fields) { try { fields = Array.isArray(fields) ? fields : [fields]; const data = type_is_1.default.is(this.response.contentType, [ common_1.MimeTypes.opra_response_json, ]) ? this.response.body.payload : this.response.body; this._expect(data).opraCollectionToBeSortedBy(fields); } catch (e) { Error.captureStackTrace(e, this.toBeSortedBy); throw e; } return this; } /** * Tests if Collection is filtered by given condition. * @param filter */ toBeFilteredBy(filter) { const f = convertFilter(filter); if (f) { const j = ruleJudgment(f); const data = type_is_1.default.is(this.response.contentType, [ common_1.MimeTypes.opra_response_json, ]) ? this.response.body.payload : this.response.body; const filtered = data.filter(j); try { this._expect(data).toStrictEqual(filtered); } catch (e) { Error.captureStackTrace(e, this.toBeFilteredBy); throw e; } } return this; } } exports.ApiExpectCollection = ApiExpectCollection; expect_1.expect.extend({ opraCollectionToBeSortedBy(received, properties) { const fieldsMap = properties.map(x => x.split('.')); const getValue = (obj, fieldMap) => { let v = obj; let i = 0; while (v && i < fieldMap.length) { v = v[fieldMap[i++]]; } return v; }; let pass = true; let message; if (pass) { const sorted = [...(received || [])]; sorted.sort((a, b) => { for (const sortField of fieldsMap) { const l = getValue(a, sortField); const r = getValue(b, sortField); if (l < r) return -1; if (l > r) return 1; } return 0; }); try { (0, expect_1.expect)(received).toEqual(sorted); } catch { pass = false; message = () => 'Items are not sorted as expected'; } } return { actual: received, message, pass, }; }, }); function convertFilter(str) { const ast = typeof str === 'string' ? common_1.OpraFilter.parse(str) : str; if (!ast) return; if (ast instanceof common_1.OpraFilter.ComparisonExpression) { const left = convertFilter(ast.left); const right = convertFilter(ast.right); switch (ast.op) { case '=': return { $eq: { [left]: right } }; case '!=': return { $ne: { [left]: right } }; case '>': return { $gt: { [left]: right } }; case '>=': return { $gte: { [left]: right } }; case '<': return { $lt: { [left]: right } }; case '<=': return { $lte: { [left]: right } }; case 'in': return { $in: { [left]: right } }; case '!in': return { $nin: { [left]: right } }; default: throw new Error(`ComparisonExpression operator (${ast.op}) not implemented yet`); } } if (ast instanceof common_1.OpraFilter.QualifiedIdentifier) { return ast.value; } if (ast instanceof common_1.OpraFilter.NumberLiteral || ast instanceof common_1.OpraFilter.StringLiteral || ast instanceof common_1.OpraFilter.BooleanLiteral || ast instanceof common_1.OpraFilter.NullLiteral || ast instanceof common_1.OpraFilter.DateLiteral || ast instanceof common_1.OpraFilter.TimeLiteral) { return ast.value; } if (ast instanceof common_1.OpraFilter.ArrayExpression) { return ast.items.map(convertFilter); } if (ast instanceof common_1.OpraFilter.LogicalExpression) { if (ast.op === 'or') return { $or: ast.items.map(convertFilter) }; return { $and: ast.items.map(convertFilter) }; } if (ast instanceof common_1.OpraFilter.ArrayExpression) { return ast.items.map(convertFilter); } if (ast instanceof common_1.OpraFilter.ParenthesizedExpression) { return convertFilter(ast.expression); } throw new Error(`${ast.kind} is not implemented yet`); }