@webex/http-core 3.0.0-beta.7 → 3.0.0-beta.71
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/README.md +0 -1
- package/dist/http-error-subtypes.js +2 -147
- package/dist/http-error-subtypes.js.map +1 -1
- package/dist/http-error.js +9 -38
- package/dist/http-error.js.map +1 -1
- package/dist/index.js +5 -29
- package/dist/index.js.map +1 -1
- package/dist/interceptors/http-status.js +7 -30
- package/dist/interceptors/http-status.js.map +1 -1
- package/dist/lib/detect.js +28 -48
- package/dist/lib/detect.js.map +1 -1
- package/dist/lib/interceptor.js +7 -23
- package/dist/lib/interceptor.js.map +1 -1
- package/dist/lib/xhr.js +44 -93
- package/dist/lib/xhr.js.map +1 -1
- package/dist/progress-event.js +0 -7
- package/dist/progress-event.js.map +1 -1
- package/dist/request/index.js +1 -15
- package/dist/request/index.js.map +1 -1
- package/dist/request/request.js +5 -23
- package/dist/request/request.js.map +1 -1
- package/dist/request/request.shim.js +38 -90
- package/dist/request/request.shim.js.map +1 -1
- package/package.json +10 -10
- package/src/http-error-subtypes.js +1 -1
- package/src/http-error.js +15 -23
- package/src/index.js +4 -9
- package/src/interceptors/http-status.js +7 -5
- package/src/lib/detect.js +0 -1
- package/src/lib/interceptor.js +2 -4
- package/src/lib/xhr.js +197 -194
- package/src/progress-event.js +10 -5
- package/src/request/request.js +16 -14
- package/src/request/request.shim.js +47 -38
- package/test/integration/spec/http-error.js +11 -11
- package/test/integration/spec/interceptor.js +20 -13
- package/test/integration/spec/progress-event.js +8 -8
- package/test/integration/spec/request.js +135 -127
- package/test/unit/spec/interceptors/http-status.js +14 -11
|
@@ -14,33 +14,33 @@ describe('http-core', function () {
|
|
|
14
14
|
this.timeout(30000);
|
|
15
15
|
describe('request()', () => {
|
|
16
16
|
describe('GET', () => {
|
|
17
|
-
it('retrieves html', () =>
|
|
18
|
-
.then((res) => {
|
|
17
|
+
it('retrieves html', () =>
|
|
18
|
+
request({uri: makeLocalUrl('/')}).then((res) => {
|
|
19
19
|
assert.statusCode(res, 200);
|
|
20
20
|
assert.isString(res.body);
|
|
21
21
|
}));
|
|
22
22
|
|
|
23
|
-
it('attaches the request options object to every response', () =>
|
|
24
|
-
.then((res) => {
|
|
23
|
+
it('attaches the request options object to every response', () =>
|
|
24
|
+
request(makeLocalUrl('/')).then((res) => {
|
|
25
25
|
assert.property(res, 'options');
|
|
26
26
|
assert.property(res.options, 'uri');
|
|
27
27
|
assert.equal(res.options.uri, makeLocalUrl('/'));
|
|
28
28
|
}));
|
|
29
29
|
|
|
30
|
-
it('accepts `uri` as a separate parameter from `options`', () =>
|
|
31
|
-
.then((res) => {
|
|
30
|
+
it('accepts `uri` as a separate parameter from `options`', () =>
|
|
31
|
+
request(makeLocalUrl('/')).then((res) => {
|
|
32
32
|
assert.statusCode(res, 200);
|
|
33
33
|
assert.isString(res.body);
|
|
34
34
|
}));
|
|
35
35
|
|
|
36
|
-
it('normalizes `options.url` as `options.uri`', () =>
|
|
37
|
-
.then((res) => {
|
|
36
|
+
it('normalizes `options.url` as `options.uri`', () =>
|
|
37
|
+
request({url: makeLocalUrl('/')}).then((res) => {
|
|
38
38
|
assert.statusCode(res, 200);
|
|
39
39
|
assert.isString(res.body);
|
|
40
40
|
}));
|
|
41
41
|
|
|
42
|
-
it('retrieves JSON', () =>
|
|
43
|
-
.then((res) => {
|
|
42
|
+
it('retrieves JSON', () =>
|
|
43
|
+
request({uri: makeLocalUrl('/json/get')}).then((res) => {
|
|
44
44
|
assert.statusCode(res, 200);
|
|
45
45
|
assert.isObject(res.body);
|
|
46
46
|
assert.deepEqual(res.body, {isObject: true});
|
|
@@ -59,83 +59,95 @@ describe('http-core', function () {
|
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
describe('with responseType="buffer"', () => {
|
|
62
|
-
it('retrieves a file as a buffer', () =>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
.then((res) => {
|
|
62
|
+
it('retrieves a file as a buffer', () =>
|
|
63
|
+
request({
|
|
64
|
+
uri: makeLocalUrl('/sample-image-small-one.png'),
|
|
65
|
+
responseType: 'buffer',
|
|
66
|
+
}).then((res) => {
|
|
67
67
|
assert.isBufferLike(res.body);
|
|
68
68
|
}));
|
|
69
69
|
});
|
|
70
70
|
|
|
71
71
|
describe('with responseType="blob"', () => {
|
|
72
|
-
it('retrieves a file as a file', () =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
.then((res) => {
|
|
72
|
+
it('retrieves a file as a file', () =>
|
|
73
|
+
request({
|
|
74
|
+
uri: makeLocalUrl('/sample-image-small-one.png'),
|
|
75
|
+
responseType: 'blob',
|
|
76
|
+
}).then((res) => {
|
|
77
77
|
assert.isBlobLike(res.body);
|
|
78
78
|
}));
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
it('makes CORS compatible calls', () =>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.then((res) => {
|
|
81
|
+
it('makes CORS compatible calls', () =>
|
|
82
|
+
request({
|
|
83
|
+
uri: 'https://ds.ciscospark.com/v1/region/',
|
|
84
|
+
}).then((res) => {
|
|
85
85
|
assert.notEqual(res.statusCode, 0);
|
|
86
86
|
}));
|
|
87
87
|
|
|
88
|
-
it('fails with a subtyped error', () =>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
it('fails with a subtyped error', () =>
|
|
89
|
+
assert
|
|
90
|
+
.isRejected(
|
|
91
|
+
request({
|
|
92
|
+
uri: makeLocalUrl('/not-a-route'),
|
|
93
|
+
})
|
|
94
|
+
)
|
|
95
|
+
.then((err) => {
|
|
96
|
+
assert.instanceOf(err, HttpError);
|
|
97
|
+
assert.instanceOf(err, HttpError.BadRequest);
|
|
98
|
+
}));
|
|
95
99
|
|
|
96
100
|
// This is somewhat difficult to test in web browser, but network errors in
|
|
97
101
|
// browser look like network errors in browsers, so testing it isn`t that
|
|
98
102
|
// critical. That said, moving the error-reformatting logic out of the
|
|
99
103
|
// environment-specific implementations may make this easier to stub.
|
|
100
|
-
nodeOnly(it)('makes network errors look mostly like HTTP errors', () =>
|
|
101
|
-
.then((err) => {
|
|
104
|
+
nodeOnly(it)('makes network errors look mostly like HTTP errors', () =>
|
|
105
|
+
assert.isRejected(request('https://localhost:0/not-a-route')).then((err) => {
|
|
102
106
|
assert.instanceOf(err, HttpError.NetworkOrCORSError);
|
|
103
|
-
})
|
|
107
|
+
})
|
|
108
|
+
);
|
|
104
109
|
|
|
105
|
-
it('passes cookies', () =>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
it('passes cookies', () =>
|
|
111
|
+
request({
|
|
112
|
+
uri: makeLocalUrl('/cookies/set'),
|
|
113
|
+
jar: true,
|
|
114
|
+
})
|
|
115
|
+
.then(() =>
|
|
116
|
+
request({
|
|
117
|
+
uri: makeLocalUrl('/cookies/expect'),
|
|
118
|
+
jar: true,
|
|
119
|
+
})
|
|
120
|
+
)
|
|
121
|
+
.then((res) => {
|
|
122
|
+
assert.statusCode(res, 200);
|
|
123
|
+
}));
|
|
116
124
|
|
|
117
125
|
// this test fails in Safari 8+
|
|
118
126
|
nodeOnly(it)('passes cookies to endpoints on other origins', () => {
|
|
119
127
|
const p1 = request({
|
|
120
128
|
uri: `http://localhost:${process.env.CORS_PORT}/cookies/set`,
|
|
121
|
-
jar: true
|
|
129
|
+
jar: true,
|
|
122
130
|
})
|
|
123
|
-
.then(() =>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
.then(() =>
|
|
132
|
+
request({
|
|
133
|
+
uri: `http://localhost:${process.env.CORS_PORT}/cookies/expect`,
|
|
134
|
+
jar: true,
|
|
135
|
+
})
|
|
136
|
+
)
|
|
127
137
|
.then((res) => {
|
|
128
138
|
assert.statusCode(res, 200);
|
|
129
139
|
});
|
|
130
140
|
|
|
131
141
|
const p2 = request({
|
|
132
142
|
uri: `http://localhost:${process.env.CORS_PORT}/cookies/set`,
|
|
133
|
-
withCredentials: true
|
|
143
|
+
withCredentials: true,
|
|
134
144
|
})
|
|
135
|
-
.then(() =>
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
145
|
+
.then(() =>
|
|
146
|
+
request({
|
|
147
|
+
uri: `http://localhost:${process.env.CORS_PORT}/cookies/expect`,
|
|
148
|
+
withCredentials: true,
|
|
149
|
+
})
|
|
150
|
+
)
|
|
139
151
|
.then((res) => {
|
|
140
152
|
assert.statusCode(res, 200);
|
|
141
153
|
});
|
|
@@ -148,34 +160,32 @@ describe('http-core', function () {
|
|
|
148
160
|
uri: makeLocalUrl('/requires-basic-auth'),
|
|
149
161
|
auth: {
|
|
150
162
|
pass: 'basicpass',
|
|
151
|
-
user: 'basicuser'
|
|
152
|
-
}
|
|
153
|
-
})
|
|
154
|
-
.
|
|
155
|
-
|
|
156
|
-
});
|
|
163
|
+
user: 'basicuser',
|
|
164
|
+
},
|
|
165
|
+
}).then((res) => {
|
|
166
|
+
assert.statusCode(res, 200);
|
|
167
|
+
});
|
|
157
168
|
|
|
158
169
|
const p2 = request({
|
|
159
170
|
uri: makeLocalUrl('/requires-basic-auth'),
|
|
160
171
|
auth: {
|
|
161
172
|
password: 'basicpass',
|
|
162
|
-
username: 'basicuser'
|
|
163
|
-
}
|
|
164
|
-
})
|
|
165
|
-
.
|
|
166
|
-
|
|
167
|
-
});
|
|
173
|
+
username: 'basicuser',
|
|
174
|
+
},
|
|
175
|
+
}).then((res) => {
|
|
176
|
+
assert.statusCode(res, 200);
|
|
177
|
+
});
|
|
168
178
|
|
|
169
179
|
return Promise.all([p1, p2]);
|
|
170
180
|
});
|
|
171
181
|
|
|
172
|
-
it('makes Bearer Auth authenticated requests', () =>
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
.then((res) => {
|
|
182
|
+
it('makes Bearer Auth authenticated requests', () =>
|
|
183
|
+
request({
|
|
184
|
+
uri: makeLocalUrl('/requires-bearer-auth'),
|
|
185
|
+
auth: {
|
|
186
|
+
bearer: 'bearertoken',
|
|
187
|
+
},
|
|
188
|
+
}).then((res) => {
|
|
179
189
|
assert.statusCode(res, 200);
|
|
180
190
|
}));
|
|
181
191
|
|
|
@@ -187,35 +197,34 @@ describe('http-core', function () {
|
|
|
187
197
|
object: {
|
|
188
198
|
string: 'this is a another string',
|
|
189
199
|
boolean: 'true',
|
|
190
|
-
integer: '5'
|
|
191
|
-
}
|
|
200
|
+
integer: '5',
|
|
201
|
+
},
|
|
192
202
|
};
|
|
193
203
|
|
|
194
204
|
return request({
|
|
195
205
|
uri: makeLocalUrl('/return-qs-as-object'),
|
|
196
|
-
qs
|
|
197
|
-
})
|
|
198
|
-
.
|
|
199
|
-
|
|
200
|
-
});
|
|
206
|
+
qs,
|
|
207
|
+
}).then((res) => {
|
|
208
|
+
assert.deepEqual(res.body, qs);
|
|
209
|
+
});
|
|
201
210
|
});
|
|
202
211
|
});
|
|
203
212
|
|
|
204
213
|
flaky(it, process.env.SKIP_FLAKY_TESTS)('submits files as multipart form data', () => {
|
|
205
|
-
file.fetch('sample-powerpoint-two-page.ppt')
|
|
206
|
-
|
|
214
|
+
file.fetch('sample-powerpoint-two-page.ppt').then((f) =>
|
|
215
|
+
request({
|
|
207
216
|
method: 'POST',
|
|
208
217
|
uri: makeLocalUrl('/files/metadata'),
|
|
209
218
|
formData: {
|
|
210
|
-
files: [f]
|
|
219
|
+
files: [f],
|
|
211
220
|
},
|
|
212
|
-
json: true
|
|
221
|
+
json: true,
|
|
222
|
+
}).then((res) => {
|
|
223
|
+
// This asserts that the server received the file and was able to
|
|
224
|
+
// decode its filename.
|
|
225
|
+
assert.equal(res.body[0].originalname, f.name);
|
|
213
226
|
})
|
|
214
|
-
|
|
215
|
-
// This asserts that the server received the file and was able to
|
|
216
|
-
// decode its filename.
|
|
217
|
-
assert.equal(res.body[0].originalname, f.name);
|
|
218
|
-
}));
|
|
227
|
+
);
|
|
219
228
|
});
|
|
220
229
|
|
|
221
230
|
['PUT', 'PATCH', 'POST'].forEach((method) => {
|
|
@@ -226,19 +235,18 @@ describe('http-core', function () {
|
|
|
226
235
|
object: {
|
|
227
236
|
string: 'this is a another string',
|
|
228
237
|
boolean: 'true',
|
|
229
|
-
integer: '5'
|
|
230
|
-
}
|
|
238
|
+
integer: '5',
|
|
239
|
+
},
|
|
231
240
|
};
|
|
232
241
|
|
|
233
242
|
return request({
|
|
234
243
|
method,
|
|
235
244
|
uri: makeLocalUrl('/json/set'),
|
|
236
|
-
body: payload
|
|
237
|
-
})
|
|
238
|
-
.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
});
|
|
245
|
+
body: payload,
|
|
246
|
+
}).then((res) => {
|
|
247
|
+
assert.statusCode(res, 200);
|
|
248
|
+
assert.deepEqual(res.body, payload);
|
|
249
|
+
});
|
|
242
250
|
});
|
|
243
251
|
|
|
244
252
|
it('submits urlencoded form data', () =>
|
|
@@ -249,41 +257,40 @@ describe('http-core', function () {
|
|
|
249
257
|
uri: makeLocalUrl('/form/reflect'),
|
|
250
258
|
form: {
|
|
251
259
|
a: 1,
|
|
252
|
-
b: 2
|
|
253
|
-
}
|
|
254
|
-
})
|
|
255
|
-
.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
.then((res) => {
|
|
260
|
+
b: 2,
|
|
261
|
+
},
|
|
262
|
+
}).then((res) => {
|
|
263
|
+
assert.statusCode(res, 200);
|
|
264
|
+
assert.deepEqual(res.body, {
|
|
265
|
+
a: '1',
|
|
266
|
+
b: '2',
|
|
267
|
+
});
|
|
268
|
+
}));
|
|
269
|
+
|
|
270
|
+
it('submits files', () =>
|
|
271
|
+
file.fetch('/sample-image-small-one.png').then((f) =>
|
|
272
|
+
request({
|
|
273
|
+
method,
|
|
274
|
+
uri: makeLocalUrl('/files/reflect'),
|
|
275
|
+
body: f,
|
|
276
|
+
json: false,
|
|
277
|
+
// Note: setting response type so the `reflect()ed` response is in
|
|
278
|
+
// a form we can use, this is not needed for normal file uploads.
|
|
279
|
+
responseType: 'blob',
|
|
280
|
+
}).then((res) => {
|
|
274
281
|
assert.equal(res.body.type, f.type);
|
|
275
282
|
|
|
276
|
-
return file.isMatchingFile(res.body, f)
|
|
277
|
-
|
|
278
|
-
|
|
283
|
+
return file.isMatchingFile(res.body, f).then((result) => assert.isTrue(result));
|
|
284
|
+
})
|
|
285
|
+
));
|
|
279
286
|
|
|
280
|
-
(inBrowser ? it : it.skip)('emits upload progress events', () =>
|
|
281
|
-
.then((f) => {
|
|
287
|
+
(inBrowser ? it : it.skip)('emits upload progress events', () =>
|
|
288
|
+
file.fetch('/sample-image-small-one.png').then((f) => {
|
|
282
289
|
const options = {
|
|
283
290
|
method,
|
|
284
291
|
uri: makeLocalUrl('/files/reflect'),
|
|
285
292
|
body: f,
|
|
286
|
-
json: false
|
|
293
|
+
json: false,
|
|
287
294
|
};
|
|
288
295
|
|
|
289
296
|
const promise = request(options);
|
|
@@ -295,7 +302,8 @@ describe('http-core', function () {
|
|
|
295
302
|
return promise.then(() => {
|
|
296
303
|
assert.called(spy);
|
|
297
304
|
});
|
|
298
|
-
})
|
|
305
|
+
})
|
|
306
|
+
);
|
|
299
307
|
});
|
|
300
308
|
});
|
|
301
309
|
});
|
|
@@ -11,9 +11,13 @@ describe('http-core', () => {
|
|
|
11
11
|
let interceptor;
|
|
12
12
|
|
|
13
13
|
beforeEach(() => {
|
|
14
|
-
interceptor = Reflect.apply(
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
interceptor = Reflect.apply(
|
|
15
|
+
HttpStatusInterceptor.create,
|
|
16
|
+
{
|
|
17
|
+
sessionId: 'mock-webex_uuid',
|
|
18
|
+
},
|
|
19
|
+
[]
|
|
20
|
+
);
|
|
17
21
|
});
|
|
18
22
|
|
|
19
23
|
describe('#onResponse', () => {
|
|
@@ -21,21 +25,20 @@ describe('http-core', () => {
|
|
|
21
25
|
const response = {
|
|
22
26
|
statusCode: 404,
|
|
23
27
|
body: {
|
|
24
|
-
errorCode: 2000002
|
|
25
|
-
}
|
|
28
|
+
errorCode: 2000002,
|
|
29
|
+
},
|
|
26
30
|
};
|
|
27
31
|
|
|
28
|
-
return interceptor.onResponse({}, response)
|
|
29
|
-
.
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
+
return interceptor.onResponse({}, response).then((result) => {
|
|
33
|
+
assert.equal(result, response);
|
|
34
|
+
});
|
|
32
35
|
});
|
|
33
36
|
it('rejects when locus redirect is not intended', () => {
|
|
34
37
|
const response = {
|
|
35
38
|
statusCode: 404,
|
|
36
39
|
body: {
|
|
37
|
-
errorCode: 2000001
|
|
38
|
-
}
|
|
40
|
+
errorCode: 2000001,
|
|
41
|
+
},
|
|
39
42
|
};
|
|
40
43
|
|
|
41
44
|
assert.isRejected(interceptor.onResponse({}, response));
|