@opra/testing 0.33.13 → 1.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.convertFilter = exports.ApiExpectCollection = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const rule_judgment_1 = tslib_1.__importDefault(require("rule-judgment"));
6
+ const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
6
7
  const common_1 = require("@opra/common");
7
8
  const api_expect_base_js_1 = require("./api-expect-base.js");
8
9
  // @ts-ignore
@@ -19,8 +20,13 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
19
20
  toReturnItems(min, max) {
20
21
  let msg = '';
21
22
  try {
23
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
24
+ ? this.response.body.payload
25
+ : this.response.body;
26
+ msg += `Payload should be array.`;
27
+ this._expect(Array.isArray(data)).toBeTruthy();
22
28
  msg += `The length of payload array do not match. `;
23
- const l = this.response.body.payload.length;
29
+ const l = data.length;
24
30
  this._expect(l).toBeGreaterThanOrEqual(min || 1);
25
31
  if (max)
26
32
  this._expect(l).toBeLessThanOrEqual(max);
@@ -57,7 +63,12 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
57
63
  toMatch(expected) {
58
64
  try {
59
65
  expected = (0, common_1.omitNullish)(expected);
60
- this._expect(this.response.body.payload).toEqual(expect.arrayContaining([expect.objectContaining(expected)]));
66
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
67
+ ? this.response.body.payload
68
+ : this.response.body;
69
+ for (const x of data) {
70
+ this._expect(x).toMatchObject(expected);
71
+ }
61
72
  }
62
73
  catch (e) {
63
74
  Error.captureStackTrace(e, this.toMatch);
@@ -72,7 +83,10 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
72
83
  toContainFields(fields) {
73
84
  try {
74
85
  fields = Array.isArray(fields) ? fields : [fields];
75
- for (const item of this.response.body.payload) {
86
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
87
+ ? this.response.body.payload
88
+ : this.response.body;
89
+ for (const item of data) {
76
90
  this._expect(Object.keys(item)).toEqual(expect.arrayContaining(fields));
77
91
  }
78
92
  }
@@ -89,7 +103,10 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
89
103
  toContainAllFields(fields) {
90
104
  try {
91
105
  fields = Array.isArray(fields) ? fields : [fields];
92
- for (const item of this.response.body.payload) {
106
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
107
+ ? this.response.body.payload
108
+ : this.response.body;
109
+ for (const item of data) {
93
110
  this._expect(Object.keys(item)).toEqual(fields);
94
111
  }
95
112
  }
@@ -106,8 +123,10 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
106
123
  toBeSortedBy(fields) {
107
124
  try {
108
125
  fields = Array.isArray(fields) ? fields : [fields];
109
- this._expect(this.response.body.payload)
110
- .opraCollectionToBeSortedBy(fields);
126
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
127
+ ? this.response.body.payload
128
+ : this.response.body;
129
+ this._expect(data).opraCollectionToBeSortedBy(fields);
111
130
  }
112
131
  catch (e) {
113
132
  Error.captureStackTrace(e, this.toBeSortedBy);
@@ -123,9 +142,12 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
123
142
  const f = convertFilter(filter);
124
143
  if (f) {
125
144
  const j = ruleJudgment(f);
126
- const filtered = this.response.body.payload.filter(j);
145
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
146
+ ? this.response.body.payload
147
+ : this.response.body;
148
+ const filtered = data.filter(j);
127
149
  try {
128
- this._expect(this.response.body.payload).toStrictEqual(filtered);
150
+ this._expect(data).toStrictEqual(filtered);
129
151
  }
130
152
  catch (e) {
131
153
  Error.captureStackTrace(e, this.toBeFilteredBy);
@@ -173,7 +195,7 @@ expect.extend({
173
195
  return {
174
196
  actual: received,
175
197
  message,
176
- pass
198
+ pass,
177
199
  };
178
200
  },
179
201
  });
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ApiExpectObject = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
4
6
  const common_1 = require("@opra/common");
5
7
  const api_expect_base_js_1 = require("./api-expect-base.js");
6
8
  class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
@@ -14,7 +16,10 @@ class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
14
16
  toMatch(expected) {
15
17
  try {
16
18
  expected = (0, common_1.omitNullish)(expected);
17
- this._expect(this.response.body.payload).toEqual(expect.objectContaining(expected));
19
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
20
+ ? this.response.body.payload
21
+ : this.response.body;
22
+ this._expect(data).toEqual(expect.objectContaining(expected));
18
23
  }
19
24
  catch (e) {
20
25
  Error.captureStackTrace(e, this.toMatch);
@@ -29,8 +34,10 @@ class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
29
34
  toContainFields(fields) {
30
35
  try {
31
36
  fields = Array.isArray(fields) ? fields : [fields];
32
- this._expect(Object.keys(this.response.body.payload))
33
- .toEqual(expect.arrayContaining(fields));
37
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
38
+ ? this.response.body.payload
39
+ : this.response.body;
40
+ this._expect(Object.keys(data)).toEqual(expect.arrayContaining(fields));
34
41
  }
35
42
  catch (e) {
36
43
  Error.captureStackTrace(e, this.toContainFields);
@@ -45,8 +52,10 @@ class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
45
52
  toContainAllFields(fields) {
46
53
  try {
47
54
  fields = Array.isArray(fields) ? fields : [fields];
48
- this._expect(Object.keys(this.response.body.payload))
49
- .toEqual(fields);
55
+ const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
56
+ ? this.response.body.payload
57
+ : this.response.body;
58
+ this._expect(Object.keys(data)).toEqual(fields);
50
59
  }
51
60
  catch (e) {
52
61
  Error.captureStackTrace(e, this.toContainAllFields);
@@ -4,6 +4,7 @@ exports.ApiExpect = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  require("../jest-extend/index.js");
6
6
  const ansi_colors_1 = tslib_1.__importDefault(require("ansi-colors"));
7
+ const common_1 = require("@opra/common");
7
8
  const api_expect_base_js_1 = require("./api-expect-base.js");
8
9
  const api_expect_collection_js_1 = require("./api-expect-collection.js");
9
10
  const api_expect_error_js_1 = require("./api-expect-error.js");
@@ -27,16 +28,17 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
27
28
  }
28
29
  }
29
30
  catch (e) {
30
- e.message = 'Request didn\'t succeeded as expected. ' + msg + '\n\n' + e.message;
31
+ e.message = "Request didn't succeeded as expected. " + msg + '\n\n' + e.message;
31
32
  const issues = this.response.body?.errors;
32
33
  if (issues) {
33
34
  e.message += '\n\n';
34
35
  issues.forEach((issue, i) => {
35
- const stack = Array.isArray(issue.stack)
36
- ? issue.stack.join('\n') : issue.stack;
37
- e.message += ansi_colors_1.default.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
38
- issue.message + '\n' +
39
- (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
36
+ const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
37
+ e.message +=
38
+ ansi_colors_1.default.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
39
+ issue.message +
40
+ '\n' +
41
+ (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
40
42
  });
41
43
  }
42
44
  Error.captureStackTrace(e, this.toSuccess);
@@ -61,16 +63,17 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
61
63
  }
62
64
  }
63
65
  catch (e) {
64
- e.message = 'Request didn\'t failed as expected. ' + msg + '\n\n' + e.message;
66
+ e.message = "Request didn't failed as expected. " + msg + '\n\n' + e.message;
65
67
  const issues = this.response.body?.errors;
66
68
  if (issues) {
67
69
  e.message += '\n\n';
68
70
  issues.forEach((issue, i) => {
69
- const stack = Array.isArray(issue.stack)
70
- ? issue.stack.join('\n') : issue.stack;
71
- e.message += ansi_colors_1.default.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
72
- issue.message + '\n' +
73
- (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
71
+ const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
72
+ e.message +=
73
+ ansi_colors_1.default.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
74
+ issue.message +
75
+ '\n' +
76
+ (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
74
77
  });
75
78
  }
76
79
  Error.captureStackTrace(e, this.toSuccess);
@@ -85,7 +88,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
85
88
  let msg = '';
86
89
  try {
87
90
  msg = 'Content-Type header value is not valid. ';
88
- expect(this.response.contentType).toEqual('application/opra+json');
91
+ expect(this.response.contentType).toEqual('application/opra.response+json');
89
92
  msg = 'Type of response "body" is not valid. ';
90
93
  expect(typeof this.response.body).toEqual('object');
91
94
  msg = 'Type of "payload" is not an Array. ';
@@ -93,7 +96,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
93
96
  expect(Array.isArray(payload) ? 'array' : typeof payload).toEqual('array');
94
97
  }
95
98
  catch (e) {
96
- e.message = 'Api didn\'t returned a Collection. ' + msg + '\n\n' + e.message;
99
+ e.message = "Api didn't returned a Collection. " + msg + '\n\n' + e.message;
97
100
  if (msg)
98
101
  e.message = msg + '\n\n' + e.message;
99
102
  Error.captureStackTrace(e, this.toReturnCollection);
@@ -104,11 +107,11 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
104
107
  /**
105
108
  * Tests if API returns an Object
106
109
  */
107
- toReturnObject() {
110
+ toReturnObject(contentType) {
108
111
  let msg = '';
109
112
  try {
110
113
  msg = 'Content-Type header value is not valid. ';
111
- expect(this.response.contentType).toEqual('application/opra+json');
114
+ expect(this.response.contentType).toEqual(contentType || common_1.MimeTypes.opra_response_json);
112
115
  msg = 'Type of response "body" is not valid. ';
113
116
  expect(typeof this.response.body).toEqual('object');
114
117
  msg = 'Type of "payload" is not an Object. ';
@@ -116,7 +119,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
116
119
  expect(typeof payload).toEqual('object');
117
120
  }
118
121
  catch (e) {
119
- e.message = 'Api didn\'t returned an Object. ' + msg + '\n\n' + e.message;
122
+ e.message = "Api didn't returned an Object. " + msg + '\n\n' + e.message;
120
123
  if (msg)
121
124
  e.message = msg + '\n\n' + e.message;
122
125
  Error.captureStackTrace(e, this.toReturnCollection);
@@ -131,7 +134,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
131
134
  let msg = '';
132
135
  try {
133
136
  msg = 'Content-Type header value is not valid. ';
134
- expect(this.response.contentType).toEqual('application/opra+json');
137
+ expect(this.response.contentType).toEqual(common_1.MimeTypes.opra_response_json);
135
138
  msg = 'Type of response "body" is not valid. ';
136
139
  expect(typeof this.response.body).toEqual('object');
137
140
  msg = 'The response has payload. ';
@@ -139,7 +142,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
139
142
  expect(typeof payload).toEqual('undefined');
140
143
  }
141
144
  catch (e) {
142
- e.message = 'Api didn\'t returned a OperationResult. ' + msg + '\n\n' + e.message;
145
+ e.message = "Api didn't returned a OperationResult. " + msg + '\n\n' + e.message;
143
146
  if (msg)
144
147
  e.message = msg + '\n\n' + e.message;
145
148
  Error.captureStackTrace(e, this.toReturnCollection);
@@ -23,8 +23,9 @@ expect.extend({
23
23
  const pass = !filteredKeys.length === !this.isNot;
24
24
  if (!pass) {
25
25
  const message = () => `${!this.isNot ? 'Do not expects' : 'Expects'} additional keys other than: ${ansi_colors_1.default.yellow('' + expectedKeys)}\n` +
26
- (filteredKeys ? `Additional keys received: ${ansi_colors_1.default.yellow('' + filteredKeys)}\n` :
27
- 'No additional keys received\n');
26
+ (filteredKeys
27
+ ? `Additional keys received: ${ansi_colors_1.default.yellow('' + filteredKeys)}\n`
28
+ : 'No additional keys received\n');
28
29
  return { message, pass };
29
30
  }
30
31
  return { actual: received, pass: !this.isNot, message: () => '' };
@@ -35,33 +36,33 @@ expect.extend({
35
36
  }
36
37
  return {
37
38
  pass: false,
38
- message: () => 'Value is not an array'
39
+ message: () => 'Value is not an array',
39
40
  };
40
41
  },
41
42
  toBeGreaterThanAny(received, expected) {
42
43
  return compare('toBeGreaterThan', {
43
44
  isNot: this.isNot,
44
- promise: this.promise
45
+ promise: this.promise,
45
46
  }, received, expected, '>', () => received > expected);
46
47
  },
47
48
  toBeGreaterThanOrEqualAny(received, expected) {
48
49
  return compare('toBeGreaterThanOrEqual', {
49
50
  isNot: this.isNot,
50
- promise: this.promise
51
+ promise: this.promise,
51
52
  }, received, expected, '>=', () => received >= expected);
52
53
  },
53
54
  toBeLessThanAny(received, expected) {
54
55
  return compare('toBeLessThan', {
55
56
  isNot: this.isNot,
56
- promise: this.promise
57
+ promise: this.promise,
57
58
  }, received, expected, '<', () => received < expected);
58
59
  },
59
60
  toBeLessThanOrEqualAny(received, expected) {
60
61
  return compare('toBeLessThanOrEqual', {
61
62
  isNot: this.isNot,
62
- promise: this.promise
63
+ promise: this.promise,
63
64
  }, received, expected, '<=', () => received <= expected);
64
- }
65
+ },
65
66
  });
66
67
  function compare(matcherName, options, received, expected, operator, fn) {
67
68
  const pass = fn(received, expected);
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TestBackend = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const http_1 = require("http");
6
+ const path = tslib_1.__importStar(require("node:path"));
5
7
  const client_1 = require("@opra/client");
6
- const common_1 = require("@opra/common");
7
8
  const api_expect_js_1 = require("./api-expect/api-expect.js");
8
9
  /**
9
10
  *
@@ -11,34 +12,37 @@ const api_expect_js_1 = require("./api-expect/api-expect.js");
11
12
  */
12
13
  class TestBackend extends client_1.FetchBackend {
13
14
  constructor(app, options) {
14
- super('http://tempuri.org', options);
15
+ super(options?.basePath ? path.join('http://tempuri.org', options.basePath) : 'http://tempuri.org', options);
15
16
  this._server = app instanceof http_1.Server ? app : (0, http_1.createServer)(app);
16
17
  }
17
18
  send(req) {
18
19
  return new Promise((resolve, reject) => {
19
- const url = new common_1.OpraURL(req.url);
20
+ const url = new URL(req.url);
20
21
  // Set protocol to HTTP
21
22
  url.protocol = 'http';
22
23
  // Apply original host to request header
23
24
  if (url.host !== 'opra.test' && req.headers.get('host') == null)
24
25
  req.headers.set('host', url.host);
25
- new Promise((subResolve) => {
26
+ new Promise(subResolve => {
26
27
  if (this._server.listening)
27
28
  subResolve();
28
29
  else
29
30
  this._server.listen(0, '127.0.0.1', () => subResolve());
30
- }).then(() => {
31
+ })
32
+ .then(() => {
31
33
  const address = this._server.address();
32
34
  url.host = '127.0.0.1';
33
35
  url.port = address.port.toString();
34
36
  return fetch(url.toString(), req);
35
- }).then(res => {
37
+ })
38
+ .then(res => {
36
39
  if (!this._server.listening)
37
40
  return resolve(res);
38
41
  this._server.once('close', () => resolve(res));
39
42
  this._server.close();
40
43
  this._server.unref();
41
- }).then()
44
+ })
45
+ .then()
42
46
  .catch(error => {
43
47
  if (!this._server.listening)
44
48
  return reject(error);
@@ -1,5 +1,6 @@
1
1
  import ruleJudgmentLib from 'rule-judgment';
2
- import { omitNullish, OpraFilter } from '@opra/common';
2
+ import typeIs from '@browsery/type-is';
3
+ import { MimeTypes, omitNullish, OpraFilter } from '@opra/common';
3
4
  import { ApiExpectBase } from './api-expect-base.js';
4
5
  // @ts-ignore
5
6
  const ruleJudgment = typeof ruleJudgmentLib === 'object' ? ruleJudgmentLib.default : ruleJudgmentLib;
@@ -15,8 +16,13 @@ export class ApiExpectCollection extends ApiExpectBase {
15
16
  toReturnItems(min, max) {
16
17
  let msg = '';
17
18
  try {
19
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
20
+ ? this.response.body.payload
21
+ : this.response.body;
22
+ msg += `Payload should be array.`;
23
+ this._expect(Array.isArray(data)).toBeTruthy();
18
24
  msg += `The length of payload array do not match. `;
19
- const l = this.response.body.payload.length;
25
+ const l = data.length;
20
26
  this._expect(l).toBeGreaterThanOrEqual(min || 1);
21
27
  if (max)
22
28
  this._expect(l).toBeLessThanOrEqual(max);
@@ -53,7 +59,12 @@ export class ApiExpectCollection extends ApiExpectBase {
53
59
  toMatch(expected) {
54
60
  try {
55
61
  expected = omitNullish(expected);
56
- this._expect(this.response.body.payload).toEqual(expect.arrayContaining([expect.objectContaining(expected)]));
62
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
63
+ ? this.response.body.payload
64
+ : this.response.body;
65
+ for (const x of data) {
66
+ this._expect(x).toMatchObject(expected);
67
+ }
57
68
  }
58
69
  catch (e) {
59
70
  Error.captureStackTrace(e, this.toMatch);
@@ -68,7 +79,10 @@ export class ApiExpectCollection extends ApiExpectBase {
68
79
  toContainFields(fields) {
69
80
  try {
70
81
  fields = Array.isArray(fields) ? fields : [fields];
71
- for (const item of this.response.body.payload) {
82
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
83
+ ? this.response.body.payload
84
+ : this.response.body;
85
+ for (const item of data) {
72
86
  this._expect(Object.keys(item)).toEqual(expect.arrayContaining(fields));
73
87
  }
74
88
  }
@@ -85,7 +99,10 @@ export class ApiExpectCollection extends ApiExpectBase {
85
99
  toContainAllFields(fields) {
86
100
  try {
87
101
  fields = Array.isArray(fields) ? fields : [fields];
88
- for (const item of this.response.body.payload) {
102
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
103
+ ? this.response.body.payload
104
+ : this.response.body;
105
+ for (const item of data) {
89
106
  this._expect(Object.keys(item)).toEqual(fields);
90
107
  }
91
108
  }
@@ -102,8 +119,10 @@ export class ApiExpectCollection extends ApiExpectBase {
102
119
  toBeSortedBy(fields) {
103
120
  try {
104
121
  fields = Array.isArray(fields) ? fields : [fields];
105
- this._expect(this.response.body.payload)
106
- .opraCollectionToBeSortedBy(fields);
122
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
123
+ ? this.response.body.payload
124
+ : this.response.body;
125
+ this._expect(data).opraCollectionToBeSortedBy(fields);
107
126
  }
108
127
  catch (e) {
109
128
  Error.captureStackTrace(e, this.toBeSortedBy);
@@ -119,9 +138,12 @@ export class ApiExpectCollection extends ApiExpectBase {
119
138
  const f = convertFilter(filter);
120
139
  if (f) {
121
140
  const j = ruleJudgment(f);
122
- const filtered = this.response.body.payload.filter(j);
141
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
142
+ ? this.response.body.payload
143
+ : this.response.body;
144
+ const filtered = data.filter(j);
123
145
  try {
124
- this._expect(this.response.body.payload).toStrictEqual(filtered);
146
+ this._expect(data).toStrictEqual(filtered);
125
147
  }
126
148
  catch (e) {
127
149
  Error.captureStackTrace(e, this.toBeFilteredBy);
@@ -168,7 +190,7 @@ expect.extend({
168
190
  return {
169
191
  actual: received,
170
192
  message,
171
- pass
193
+ pass,
172
194
  };
173
195
  },
174
196
  });
@@ -1,4 +1,5 @@
1
- import { omitNullish } from '@opra/common';
1
+ import typeIs from '@browsery/type-is';
2
+ import { MimeTypes, omitNullish } from '@opra/common';
2
3
  import { ApiExpectBase } from './api-expect-base.js';
3
4
  export class ApiExpectObject extends ApiExpectBase {
4
5
  get not() {
@@ -11,7 +12,10 @@ export class ApiExpectObject extends ApiExpectBase {
11
12
  toMatch(expected) {
12
13
  try {
13
14
  expected = omitNullish(expected);
14
- this._expect(this.response.body.payload).toEqual(expect.objectContaining(expected));
15
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
16
+ ? this.response.body.payload
17
+ : this.response.body;
18
+ this._expect(data).toEqual(expect.objectContaining(expected));
15
19
  }
16
20
  catch (e) {
17
21
  Error.captureStackTrace(e, this.toMatch);
@@ -26,8 +30,10 @@ export class ApiExpectObject extends ApiExpectBase {
26
30
  toContainFields(fields) {
27
31
  try {
28
32
  fields = Array.isArray(fields) ? fields : [fields];
29
- this._expect(Object.keys(this.response.body.payload))
30
- .toEqual(expect.arrayContaining(fields));
33
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
34
+ ? this.response.body.payload
35
+ : this.response.body;
36
+ this._expect(Object.keys(data)).toEqual(expect.arrayContaining(fields));
31
37
  }
32
38
  catch (e) {
33
39
  Error.captureStackTrace(e, this.toContainFields);
@@ -42,8 +48,10 @@ export class ApiExpectObject extends ApiExpectBase {
42
48
  toContainAllFields(fields) {
43
49
  try {
44
50
  fields = Array.isArray(fields) ? fields : [fields];
45
- this._expect(Object.keys(this.response.body.payload))
46
- .toEqual(fields);
51
+ const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
52
+ ? this.response.body.payload
53
+ : this.response.body;
54
+ this._expect(Object.keys(data)).toEqual(fields);
47
55
  }
48
56
  catch (e) {
49
57
  Error.captureStackTrace(e, this.toContainAllFields);
@@ -1,5 +1,6 @@
1
1
  import '../jest-extend/index.js';
2
2
  import colors from 'ansi-colors';
3
+ import { MimeTypes } from '@opra/common';
3
4
  import { ApiExpectBase } from './api-expect-base.js';
4
5
  import { ApiExpectCollection } from './api-expect-collection.js';
5
6
  import { ApiExpectError } from './api-expect-error.js';
@@ -23,16 +24,17 @@ export class ApiExpect extends ApiExpectBase {
23
24
  }
24
25
  }
25
26
  catch (e) {
26
- e.message = 'Request didn\'t succeeded as expected. ' + msg + '\n\n' + e.message;
27
+ e.message = "Request didn't succeeded as expected. " + msg + '\n\n' + e.message;
27
28
  const issues = this.response.body?.errors;
28
29
  if (issues) {
29
30
  e.message += '\n\n';
30
31
  issues.forEach((issue, i) => {
31
- const stack = Array.isArray(issue.stack)
32
- ? issue.stack.join('\n') : issue.stack;
33
- e.message += colors.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
34
- issue.message + '\n' +
35
- (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
32
+ const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
33
+ e.message +=
34
+ colors.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
35
+ issue.message +
36
+ '\n' +
37
+ (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
36
38
  });
37
39
  }
38
40
  Error.captureStackTrace(e, this.toSuccess);
@@ -57,16 +59,17 @@ export class ApiExpect extends ApiExpectBase {
57
59
  }
58
60
  }
59
61
  catch (e) {
60
- e.message = 'Request didn\'t failed as expected. ' + msg + '\n\n' + e.message;
62
+ e.message = "Request didn't failed as expected. " + msg + '\n\n' + e.message;
61
63
  const issues = this.response.body?.errors;
62
64
  if (issues) {
63
65
  e.message += '\n\n';
64
66
  issues.forEach((issue, i) => {
65
- const stack = Array.isArray(issue.stack)
66
- ? issue.stack.join('\n') : issue.stack;
67
- e.message += colors.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
68
- issue.message + '\n' +
69
- (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
67
+ const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
68
+ e.message +=
69
+ colors.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
70
+ issue.message +
71
+ '\n' +
72
+ (stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
70
73
  });
71
74
  }
72
75
  Error.captureStackTrace(e, this.toSuccess);
@@ -81,7 +84,7 @@ export class ApiExpect extends ApiExpectBase {
81
84
  let msg = '';
82
85
  try {
83
86
  msg = 'Content-Type header value is not valid. ';
84
- expect(this.response.contentType).toEqual('application/opra+json');
87
+ expect(this.response.contentType).toEqual('application/opra.response+json');
85
88
  msg = 'Type of response "body" is not valid. ';
86
89
  expect(typeof this.response.body).toEqual('object');
87
90
  msg = 'Type of "payload" is not an Array. ';
@@ -89,7 +92,7 @@ export class ApiExpect extends ApiExpectBase {
89
92
  expect(Array.isArray(payload) ? 'array' : typeof payload).toEqual('array');
90
93
  }
91
94
  catch (e) {
92
- e.message = 'Api didn\'t returned a Collection. ' + msg + '\n\n' + e.message;
95
+ e.message = "Api didn't returned a Collection. " + msg + '\n\n' + e.message;
93
96
  if (msg)
94
97
  e.message = msg + '\n\n' + e.message;
95
98
  Error.captureStackTrace(e, this.toReturnCollection);
@@ -100,11 +103,11 @@ export class ApiExpect extends ApiExpectBase {
100
103
  /**
101
104
  * Tests if API returns an Object
102
105
  */
103
- toReturnObject() {
106
+ toReturnObject(contentType) {
104
107
  let msg = '';
105
108
  try {
106
109
  msg = 'Content-Type header value is not valid. ';
107
- expect(this.response.contentType).toEqual('application/opra+json');
110
+ expect(this.response.contentType).toEqual(contentType || MimeTypes.opra_response_json);
108
111
  msg = 'Type of response "body" is not valid. ';
109
112
  expect(typeof this.response.body).toEqual('object');
110
113
  msg = 'Type of "payload" is not an Object. ';
@@ -112,7 +115,7 @@ export class ApiExpect extends ApiExpectBase {
112
115
  expect(typeof payload).toEqual('object');
113
116
  }
114
117
  catch (e) {
115
- e.message = 'Api didn\'t returned an Object. ' + msg + '\n\n' + e.message;
118
+ e.message = "Api didn't returned an Object. " + msg + '\n\n' + e.message;
116
119
  if (msg)
117
120
  e.message = msg + '\n\n' + e.message;
118
121
  Error.captureStackTrace(e, this.toReturnCollection);
@@ -127,7 +130,7 @@ export class ApiExpect extends ApiExpectBase {
127
130
  let msg = '';
128
131
  try {
129
132
  msg = 'Content-Type header value is not valid. ';
130
- expect(this.response.contentType).toEqual('application/opra+json');
133
+ expect(this.response.contentType).toEqual(MimeTypes.opra_response_json);
131
134
  msg = 'Type of response "body" is not valid. ';
132
135
  expect(typeof this.response.body).toEqual('object');
133
136
  msg = 'The response has payload. ';
@@ -135,7 +138,7 @@ export class ApiExpect extends ApiExpectBase {
135
138
  expect(typeof payload).toEqual('undefined');
136
139
  }
137
140
  catch (e) {
138
- e.message = 'Api didn\'t returned a OperationResult. ' + msg + '\n\n' + e.message;
141
+ e.message = "Api didn't returned a OperationResult. " + msg + '\n\n' + e.message;
139
142
  if (msg)
140
143
  e.message = msg + '\n\n' + e.message;
141
144
  Error.captureStackTrace(e, this.toReturnCollection);
@@ -1,4 +1,4 @@
1
- import colors from "ansi-colors";
1
+ import colors from 'ansi-colors';
2
2
  import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils';
3
3
  expect.extend({
4
4
  toHaveFields(received, expected) {
@@ -20,8 +20,9 @@ expect.extend({
20
20
  const pass = !filteredKeys.length === !this.isNot;
21
21
  if (!pass) {
22
22
  const message = () => `${!this.isNot ? 'Do not expects' : 'Expects'} additional keys other than: ${colors.yellow('' + expectedKeys)}\n` +
23
- (filteredKeys ? `Additional keys received: ${colors.yellow('' + filteredKeys)}\n` :
24
- 'No additional keys received\n');
23
+ (filteredKeys
24
+ ? `Additional keys received: ${colors.yellow('' + filteredKeys)}\n`
25
+ : 'No additional keys received\n');
25
26
  return { message, pass };
26
27
  }
27
28
  return { actual: received, pass: !this.isNot, message: () => '' };
@@ -32,33 +33,33 @@ expect.extend({
32
33
  }
33
34
  return {
34
35
  pass: false,
35
- message: () => 'Value is not an array'
36
+ message: () => 'Value is not an array',
36
37
  };
37
38
  },
38
39
  toBeGreaterThanAny(received, expected) {
39
40
  return compare('toBeGreaterThan', {
40
41
  isNot: this.isNot,
41
- promise: this.promise
42
+ promise: this.promise,
42
43
  }, received, expected, '>', () => received > expected);
43
44
  },
44
45
  toBeGreaterThanOrEqualAny(received, expected) {
45
46
  return compare('toBeGreaterThanOrEqual', {
46
47
  isNot: this.isNot,
47
- promise: this.promise
48
+ promise: this.promise,
48
49
  }, received, expected, '>=', () => received >= expected);
49
50
  },
50
51
  toBeLessThanAny(received, expected) {
51
52
  return compare('toBeLessThan', {
52
53
  isNot: this.isNot,
53
- promise: this.promise
54
+ promise: this.promise,
54
55
  }, received, expected, '<', () => received < expected);
55
56
  },
56
57
  toBeLessThanOrEqualAny(received, expected) {
57
58
  return compare('toBeLessThanOrEqual', {
58
59
  isNot: this.isNot,
59
- promise: this.promise
60
+ promise: this.promise,
60
61
  }, received, expected, '<=', () => received <= expected);
61
- }
62
+ },
62
63
  });
63
64
  function compare(matcherName, options, received, expected, operator, fn) {
64
65
  const pass = fn(received, expected);
@@ -1,6 +1,6 @@
1
1
  import { createServer, Server } from 'http';
2
+ import * as path from 'node:path';
2
3
  import { FetchBackend, HttpResponse } from '@opra/client';
3
- import { OpraURL } from '@opra/common';
4
4
  import { ApiExpect } from './api-expect/api-expect.js';
5
5
  /**
6
6
  *
@@ -8,34 +8,37 @@ import { ApiExpect } from './api-expect/api-expect.js';
8
8
  */
9
9
  export class TestBackend extends FetchBackend {
10
10
  constructor(app, options) {
11
- super('http://tempuri.org', options);
11
+ super(options?.basePath ? path.join('http://tempuri.org', options.basePath) : 'http://tempuri.org', options);
12
12
  this._server = app instanceof Server ? app : createServer(app);
13
13
  }
14
14
  send(req) {
15
15
  return new Promise((resolve, reject) => {
16
- const url = new OpraURL(req.url);
16
+ const url = new URL(req.url);
17
17
  // Set protocol to HTTP
18
18
  url.protocol = 'http';
19
19
  // Apply original host to request header
20
20
  if (url.host !== 'opra.test' && req.headers.get('host') == null)
21
21
  req.headers.set('host', url.host);
22
- new Promise((subResolve) => {
22
+ new Promise(subResolve => {
23
23
  if (this._server.listening)
24
24
  subResolve();
25
25
  else
26
26
  this._server.listen(0, '127.0.0.1', () => subResolve());
27
- }).then(() => {
27
+ })
28
+ .then(() => {
28
29
  const address = this._server.address();
29
30
  url.host = '127.0.0.1';
30
31
  url.port = address.port.toString();
31
32
  return fetch(url.toString(), req);
32
- }).then(res => {
33
+ })
34
+ .then(res => {
33
35
  if (!this._server.listening)
34
36
  return resolve(res);
35
37
  this._server.once('close', () => resolve(res));
36
38
  this._server.close();
37
39
  this._server.unref();
38
- }).then()
40
+ })
41
+ .then()
39
42
  .catch(error => {
40
43
  if (!this._server.listening)
41
44
  return reject(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opra/testing",
3
- "version": "0.33.13",
3
+ "version": "1.0.0-alpha.1",
4
4
  "description": "Opra testing package",
5
5
  "author": "Panates",
6
6
  "license": "MIT",
@@ -17,6 +17,7 @@
17
17
  "build:esm": "tsc -b tsconfig-build-esm.json",
18
18
  "postbuild": "cp README.md package.json ../../LICENSE ../../build/testing && cp ../../package.cjs.json ../../build/testing/cjs/package.json",
19
19
  "lint": "eslint . --max-warnings=0",
20
+ "format": "prettier . --write --log-level=warn",
20
21
  "test": "jest",
21
22
  "cover": "jest --collect-coverage",
22
23
  "clean": "npm run clean:src && npm run clean:test && npm run clean:dist && npm run clean:cover",
@@ -51,4 +52,4 @@
51
52
  "opra",
52
53
  "testing"
53
54
  ]
54
- }
55
+ }
@@ -10,5 +10,5 @@ export interface MatchingErrorIssue {
10
10
  [index: string]: any;
11
11
  }
12
12
  export declare class ApiExpectError extends ApiExpectBase {
13
- toMatch(expected: (string | RegExp | MatchingErrorIssue)): this;
13
+ toMatch(expected: string | RegExp | MatchingErrorIssue): this;
14
14
  }
@@ -22,7 +22,7 @@ export declare class ApiExpect extends ApiExpectBase {
22
22
  /**
23
23
  * Tests if API returns an Object
24
24
  */
25
- toReturnObject(): ApiExpectObject;
25
+ toReturnObject(contentType?: string): ApiExpectObject;
26
26
  /**
27
27
  * Tests if API returns an OperationResult
28
28
  */
@@ -2,6 +2,7 @@
2
2
  import { IncomingMessage, Server, ServerResponse } from 'http';
3
3
  import { FetchBackend, HttpResponse } from '@opra/client';
4
4
  import { ApiExpect } from './api-expect/api-expect.js';
5
+ import type { OpraTestClient } from './test-client.js';
5
6
  declare type RequestListener = (req: IncomingMessage, res: ServerResponse) => void;
6
7
  export type ResponseExt = {
7
8
  expect: ApiExpect;
@@ -12,7 +13,7 @@ export type ResponseExt = {
12
13
  */
13
14
  export declare class TestBackend extends FetchBackend {
14
15
  protected _server: Server;
15
- constructor(app: Server | RequestListener, options?: TestBackend.Options);
16
+ constructor(app: Server | RequestListener, options?: OpraTestClient.Options);
16
17
  protected send(req: Request): Promise<Response>;
17
18
  protected createResponse(init: HttpResponse.Initiator): HttpResponse<any> & ResponseExt;
18
19
  }
@@ -8,9 +8,13 @@ export declare const kContext: unique symbol;
8
8
  export type ResponseExt = {
9
9
  expect: ApiExpect;
10
10
  };
11
+ export declare namespace OpraTestClient {
12
+ interface Options extends FetchBackend.Options {
13
+ basePath?: string;
14
+ }
15
+ }
11
16
  export declare class OpraTestClient extends HttpClientBase<FetchBackend.RequestOptions, ResponseExt> {
12
- protected _server: Server;
13
17
  [kBackend]: TestBackend;
14
- constructor(app: Server | RequestListener, options?: FetchBackend.Options);
18
+ constructor(app: Server | RequestListener, options?: OpraTestClient.Options);
15
19
  }
16
20
  export {};