@tryghost/express-test 0.4.2 → 0.5.0
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.
- package/lib/expect-request.js +62 -5
- package/lib/request.js +3 -5
- package/lib/utils.js +0 -10
- package/package.json +6 -6
package/lib/expect-request.js
CHANGED
|
@@ -3,9 +3,27 @@ const {Request, RequestOptions} = require('./request');
|
|
|
3
3
|
const {snapshotManager} = require('@tryghost/jest-snapshot');
|
|
4
4
|
const {makeMessageFromMatchMessage} = require('./utils');
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {object} ExpressTestAssertion
|
|
8
|
+
* @prop {function} fn - Wrapped assertion with response context
|
|
9
|
+
* @prop {string} [message] - The message to display if the assertion fails
|
|
10
|
+
* @prop {string} [method] - The method to call on the assertion object
|
|
11
|
+
* @prop {'header' | 'status'} [type] - The type of assertion
|
|
12
|
+
* @prop {import('assert').AssertionError} [error] - The error to throw if the assertion fails
|
|
13
|
+
* @prop {any} [expected]
|
|
14
|
+
* @prop {any} [expectedValue]
|
|
15
|
+
* @prop {string} [expectedField]
|
|
16
|
+
* @prop {object} [properties]
|
|
17
|
+
*/
|
|
18
|
+
|
|
6
19
|
class ExpectRequest extends Request {
|
|
7
20
|
constructor(...args) {
|
|
8
21
|
super(...args);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @property {ExpressTestAssertion[]} assertions
|
|
25
|
+
*/
|
|
26
|
+
this.assertions = [];
|
|
9
27
|
}
|
|
10
28
|
|
|
11
29
|
expect(callback) {
|
|
@@ -36,7 +54,8 @@ class ExpectRequest extends Request {
|
|
|
36
54
|
expectStatus(expected) {
|
|
37
55
|
const assertion = {
|
|
38
56
|
fn: this._assertStatus,
|
|
39
|
-
expected
|
|
57
|
+
expected,
|
|
58
|
+
type: 'status'
|
|
40
59
|
};
|
|
41
60
|
|
|
42
61
|
this._addAssertion(assertion);
|
|
@@ -48,7 +67,8 @@ class ExpectRequest extends Request {
|
|
|
48
67
|
const assertion = {
|
|
49
68
|
fn: this._assertHeader,
|
|
50
69
|
expectedField: expectedField.toLowerCase(),
|
|
51
|
-
expectedValue
|
|
70
|
+
expectedValue,
|
|
71
|
+
type: 'header'
|
|
52
72
|
};
|
|
53
73
|
|
|
54
74
|
this._addAssertion(assertion);
|
|
@@ -72,7 +92,8 @@ class ExpectRequest extends Request {
|
|
|
72
92
|
let assertion = {
|
|
73
93
|
fn: this._assertSnapshot,
|
|
74
94
|
properties: properties,
|
|
75
|
-
field: 'headers'
|
|
95
|
+
field: 'headers',
|
|
96
|
+
type: 'header'
|
|
76
97
|
};
|
|
77
98
|
|
|
78
99
|
this._addAssertion(assertion);
|
|
@@ -87,7 +108,7 @@ class ExpectRequest extends Request {
|
|
|
87
108
|
}
|
|
88
109
|
|
|
89
110
|
try {
|
|
90
|
-
if (this.assertions) {
|
|
111
|
+
if (this.assertions && this.assertions.length) {
|
|
91
112
|
this._assertAll(response);
|
|
92
113
|
}
|
|
93
114
|
return callback(null, response);
|
|
@@ -97,12 +118,49 @@ class ExpectRequest extends Request {
|
|
|
97
118
|
});
|
|
98
119
|
}
|
|
99
120
|
|
|
121
|
+
/**
|
|
122
|
+
* @description Runs through the assertions queue and executes them
|
|
123
|
+
* in following order:
|
|
124
|
+
* 1. Assertions with no type, e.g: body snapshot match, generic assertions
|
|
125
|
+
* 2. Assertions of "header" type
|
|
126
|
+
* 3. Assertions of "status" type
|
|
127
|
+
*
|
|
128
|
+
* The order is here to assert the most informative assertions first and the
|
|
129
|
+
* least informative ones last. For example status code assertions, usually
|
|
130
|
+
* are setup first but give the least amount of information needed to
|
|
131
|
+
* investigate the reason of failure. Same problem with header assertions.
|
|
132
|
+
* By changing the default order of assertions it's expected to improve
|
|
133
|
+
* the developer experience creating/debugging tests.
|
|
134
|
+
*
|
|
135
|
+
* @param {Object} response - HTTP response object
|
|
136
|
+
*/
|
|
100
137
|
_assertAll(response) {
|
|
138
|
+
const statusCodeAssertions = [];
|
|
139
|
+
const headerAssertions = [];
|
|
140
|
+
|
|
101
141
|
for (const assertion of this.assertions) {
|
|
142
|
+
if (!['status', 'header'].includes(assertion.type)) {
|
|
143
|
+
assertion.fn(response, assertion);
|
|
144
|
+
} else if (assertion.type === 'status') {
|
|
145
|
+
statusCodeAssertions.push(assertion);
|
|
146
|
+
} else if (assertion.type === 'header') {
|
|
147
|
+
headerAssertions.push(assertion);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
for (const assertion of headerAssertions) {
|
|
152
|
+
assertion.fn(response, assertion);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
for (const assertion of statusCodeAssertions) {
|
|
102
156
|
assertion.fn(response, assertion);
|
|
103
157
|
}
|
|
104
158
|
}
|
|
105
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Adds assertion to the queue of assertions to be performed
|
|
162
|
+
* @param {ExpressTestAssertion} assertion
|
|
163
|
+
*/
|
|
106
164
|
_addAssertion(assertion) {
|
|
107
165
|
// We create the error here so that we get a useful stack trace
|
|
108
166
|
let error = new assert.AssertionError({
|
|
@@ -114,7 +172,6 @@ class ExpectRequest extends Request {
|
|
|
114
172
|
error.contextString = this.reqOptions.toString();
|
|
115
173
|
assertion.error = error;
|
|
116
174
|
|
|
117
|
-
this.assertions = this.assertions || [];
|
|
118
175
|
this.assertions.push(assertion);
|
|
119
176
|
}
|
|
120
177
|
|
package/lib/request.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
const {default: reqresnext} = require('reqresnext');
|
|
2
2
|
const {CookieAccessInfo} = require('cookiejar');
|
|
3
3
|
const {parse} = require('url');
|
|
4
|
-
const {isJSON
|
|
4
|
+
const {isJSON} = require('./utils');
|
|
5
5
|
|
|
6
6
|
class RequestOptions {
|
|
7
7
|
constructor({method, url, headers, body} = {}) {
|
|
8
8
|
this.method = method || 'GET';
|
|
9
9
|
this.url = url || '/';
|
|
10
|
-
|
|
11
|
-
this.headers = convertKeysToLowerCase(headers) || {};
|
|
10
|
+
this.headers = headers || {};
|
|
12
11
|
this.body = body;
|
|
13
12
|
}
|
|
14
13
|
|
|
@@ -30,8 +29,7 @@ class Request {
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
header(name, value) {
|
|
33
|
-
|
|
34
|
-
this.reqOptions.headers[name.toLowerCase()] = value;
|
|
32
|
+
this.reqOptions.headers[name] = value;
|
|
35
33
|
return this;
|
|
36
34
|
}
|
|
37
35
|
|
package/lib/utils.js
CHANGED
|
@@ -9,13 +9,3 @@ module.exports.makeMessageFromMatchMessage = function makeMessageFromMatchMessag
|
|
|
9
9
|
messageLines.splice(0, 1, errorMessage);
|
|
10
10
|
return messageLines.join('\n');
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
module.exports.convertKeysToLowerCase = function (map) {
|
|
14
|
-
const newMap = {};
|
|
15
|
-
|
|
16
|
-
for (const key in map) {
|
|
17
|
-
newMap[key.toLowerCase()] = map[key];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return newMap;
|
|
21
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tryghost/express-test",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"repository": "https://github.com/TryGhost/framework/tree/main/packages/express-test",
|
|
5
5
|
"author": "Ghost Foundation",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"c8": "7.11.0",
|
|
23
|
-
"express": "
|
|
24
|
-
"express-session": "
|
|
23
|
+
"express": "4.17.2",
|
|
24
|
+
"express-session": "1.17.2",
|
|
25
25
|
"mocha": "9.2.0",
|
|
26
26
|
"sinon": "13.0.1"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@tryghost/jest-snapshot": "^0.3.
|
|
29
|
+
"@tryghost/jest-snapshot": "^0.3.2",
|
|
30
30
|
"cookiejar": "^2.1.3",
|
|
31
|
-
"reqresnext": "^1.
|
|
31
|
+
"reqresnext": "^1.7.0"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "e954893434fda3f8c8de1970aaaa6f6a8b297f5d"
|
|
34
34
|
}
|