-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathhubkit.test.js
More file actions
114 lines (106 loc) · 4.35 KB
/
Copy pathhubkit.test.js
File metadata and controls
114 lines (106 loc) · 4.35 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
107
108
109
110
111
112
113
114
'use strict';
const assert = require('node:assert/strict');
const {readFileSync} = require('node:fs');
const test = require('node:test');
const vm = require('node:vm');
const Hubkit = require('./index.js');
const browser = {self: {}, lrucache: require('lru-cache')};
vm.runInNewContext(readFileSync(require.resolve('./hubkit.js'), 'utf8'), browser);
const cases = [
{
message: 'Your account was suspended.',
code: 'account-suspended', category: 'badauth', error: 'GitHub account suspended'
},
{
message: 'Your email address must be verified.',
code: 'email-unverified', category: 'badauth', error: 'Email address not verified'
},
{
message: 'Resource protected by organization SAML enforcement.',
code: 'saml-enforcement', category: 'badauth', error: 'Incomplete SAML authorization'
},
{
message: 'You must have admin rights to this repository.',
code: 'admin-required', category: 'badauth', error: 'No admin rights'
},
{
message: 'You must enable two-factor authentication.',
code: 'two-factor-required', category: 'badauth', error: 'Two-factor authentication not set up'
},
{
message: 'The `example-org` organization has enabled OAuth App access restrictions.',
code: 'oauth-app-restrictions', category: 'thirdparty',
error: 'Third-party app restrictions in effect'
},
{
message: 'Although you appear to have the correct authorization credentials, ' +
'the `example-org` organization has an IP allow list enabled, and your IP address is not ' +
'permitted to access this resource.',
code: 'ip-allow-list', category: 'iprestricted', error: 'GitHub IP allow list blocks access'
},
{
message: 'Repository access blocked.',
code: 'access-blocked', category: 'notfound', error: 'Repository access blocked'
},
{
message: 'You have exceeded a secondary rate limit. Please wait a few minutes.',
code: 'secondary-rate-limit', quota: true
},
{
message: 'API rate limit exceeded for user ID 1234.',
code: 'rate-limit', quota: true
}
];
for (const [environment, implementation] of [['Node', Hubkit], ['browser', browser.self.Hubkit]]) {
for (const {message, ...expected} of cases) {
test(`${environment}: identifies ${expected.code} from raw and wrapped messages`, () => {
for (const prefix of [
'',
'GitHub error 403 on GET https://api.github.com/repos/first/repo: ',
'Internal error: GitHub error 403 on POST https://ghe.example/api/graphql: '
]) {
const text = prefix + message;
for (const input of [text, new Error(text), {message: text}]) {
assert.deepEqual({...implementation.identify403Error(input)}, expected);
}
}
});
}
test(`${environment}: recognizes legacy quota wording and case variants`, () => {
for (const message of [
'API RATE LIMIT EXCEEDED', 'Your request quota is exhausted.',
'You have triggered an abuse detection mechanism.'
]) {
assert.deepEqual(
{...implementation.identify403Error(message)}, {code: 'rate-limit', quota: true});
}
for (const {message, ...expected} of cases.filter(value => [
'admin-required', 'two-factor-required', 'ip-allow-list', 'access-blocked'
].includes(value.code))) {
assert.deepEqual({...implementation.identify403Error(message.toUpperCase())}, expected);
}
});
test(`${environment}: preserves specific causes ahead of generic quota wording`, () => {
for (const {message, ...expected} of cases.filter(value => value.category)) {
assert.deepEqual(
{...implementation.identify403Error(message + ' See rate limit documentation.')}, expected);
}
});
test(`${environment}: leaves unknown causes unidentified`, () => {
for (const message of [
'', 'Forbidden', 'Resource not accessible by integration',
'Your organization has an IP allow list enabled.'
]) {
assert.equal(implementation.identify403Error(message), undefined);
assert.equal(implementation.identify403Error(new Error(message)), undefined);
}
});
test(`${environment}: quota failures cannot be mistaken for broad access errors`, () => {
for (const {message} of cases.slice(-2)) {
const reason = implementation.identify403Error(message);
assert.equal(reason.quota, true);
assert.equal(reason.category, undefined);
assert.equal(reason.error, undefined);
}
});
}