-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathresponse-errors.test.js
More file actions
106 lines (101 loc) · 4.28 KB
/
Copy pathresponse-errors.test.js
File metadata and controls
106 lines (101 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
'use strict';
const assert = require('node:assert/strict');
const {readFileSync} = require('node:fs');
const test = require('node:test');
const vm = require('node:vm');
function createHubkit(status, body, contentType = 'application/json') {
let requests = 0;
const browser = {
self: {}, lrucache: require('lru-cache'), URL, AbortController, setTimeout, clearTimeout,
fetch: async () => {
requests++;
return new globalThis.Response(body, {status, headers: {
'content-type': contentType, 'x-ratelimit-remaining': '0', 'x-github-request-id': 'test-id'
}});
}
};
vm.runInNewContext(readFileSync(require.resolve('./hubkit.js'), 'utf8'), browser);
return {Hubkit: browser.self.Hubkit, requests: () => requests};
}
for (const options of [{}, {media: 'raw'}, {responseType: 'text'},
{media: 'raw', responseType: 'blob'}, {responseType: 'arraybuffer'}]) {
for (const [status, message, code] of [
[403, 'Resource protected by organization SAML enforcement.', 'saml-enforcement'],
[429, 'You have exceeded a secondary rate limit.', 'secondary-rate-limit'],
[404, 'Not Found', undefined]
]) {
test(`JSON HTTP ${status} retains its message with ${JSON.stringify(options)}`, async () => {
const {Hubkit, requests} = createHubkit(status, JSON.stringify({message}));
const metadata = {};
let handledError;
await assert.rejects(new Hubkit().request('/repos/o/r/git/blobs/sha', {
...options, metadata, onError: error => {
handledError = error;
return Hubkit.DONT_RETRY;
}
}), error => {
assert.equal(error.status, status);
assert.ok(error.message.includes(message));
assert.equal(error, handledError);
assert.equal(Hubkit.identify403Error(error)?.code, code);
assert.equal(error.response.data.message, message);
assert.equal(error.response.rawData, JSON.stringify({message}));
assert.equal(error.response.headers['x-github-request-id'], 'test-id');
return true;
});
assert.equal(metadata.rateLimitRemaining, 0);
assert.equal(requests(), 1);
});
}
}
test('successful binary and raw JSON files retain their requested representation', async () => {
const body = '{"message":"this is file content"}';
for (const responseType of ['blob', 'arraybuffer', 'text']) {
const {Hubkit} = createHubkit(200, body, 'text/plain');
const result = await new Hubkit().request('/repos/o/r/git/blobs/sha', {
media: 'raw', responseType
});
if (responseType === 'blob') {
assert.ok(result instanceof globalThis.Blob);
assert.equal(await result.text(), body);
} else if (responseType === 'arraybuffer') {
assert.ok(result instanceof ArrayBuffer);
assert.equal(new globalThis.TextDecoder().decode(result), body);
} else {
assert.equal(result, body);
}
}
});
test('malformed JSON and non-JSON HTTP errors preserve their status and body', async () => {
for (const [contentType, body] of [
['application/json', '{bad json'], ['text/html', '<h1>Unavailable</h1>'], ['text/plain', '']
]) {
const {Hubkit, requests} = createHubkit(503, body, contentType);
await assert.rejects(new Hubkit().request('/repos/o/r/git/blobs/sha', {
media: 'raw', responseType: 'blob', onError: () => Hubkit.DONT_RETRY
}), error => {
assert.equal(error.status, 503);
assert.equal(error.response.data, body);
assert.equal(error.response.rawData, body);
return true;
});
assert.equal(requests(), 1);
}
});
// A JSON file requested as raw data must not be decoded just because of its Content-Type.
test('successful JSON responses with responseType remain raw data', async () => {
const body = '{"message":"this is file content"}';
for (const responseType of ['blob', 'arraybuffer', 'text']) {
const {Hubkit} = createHubkit(200, body);
const result = await new Hubkit().request('/repos/o/r/git/blobs/sha', {responseType});
if (responseType === 'blob') {
assert.ok(result instanceof globalThis.Blob);
assert.equal(await result.text(), body);
} else if (responseType === 'arraybuffer') {
assert.ok(result instanceof ArrayBuffer);
assert.equal(new globalThis.TextDecoder().decode(result), body);
} else {
assert.equal(result, body);
}
}
});