1
- import { join , dirname } from ' node:path' ;
2
- import { createServer } from ' node:http' ;
3
- import { createServer as _createServer } from ' node:https' ;
4
- import { promisify } from ' node:util' ;
5
- import { fileURLToPath } from ' node:url' ;
6
-
7
- import { readFile } from 'fs-extra' ;
8
- import test , { serial } from 'ava' ;
9
- import { inRange } from 'lodash-es' ;
10
- import { stub , spy } from 'sinon' ;
11
- import proxyquire from 'proxyquire' ;
12
- import Proxy from 'proxy' ;
13
- import serverDestroy from 'server-destroy' ;
14
- import { Octokit } from '@octokit/rest' ;
15
-
16
- import rateLimit from ' ./helpers/rate-limit.js' ;
1
+ import { join , dirname } from " node:path" ;
2
+ import { createServer } from " node:http" ;
3
+ import { createServer as _createServer } from " node:https" ;
4
+ import { promisify } from " node:util" ;
5
+ import { fileURLToPath } from " node:url" ;
6
+ import { readFile } from "node:fs/promises" ;
7
+
8
+ import { inRange } from "lodash-es" ;
9
+ import { Octokit } from "@octokit/rest" ;
10
+ import Proxy from "proxy" ;
11
+ import quibble from "quibble" ;
12
+ import serverDestroy from "server-destroy" ;
13
+ import sinon from "sinon" ;
14
+ import test from "ava" ;
15
+
16
+ import * as RATE_LIMIT_MOCK from " ./helpers/rate-limit.js" ;
17
17
18
18
const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
19
- const getClient = proxyquire ( '../lib/get-client' , { './definitions/rate-limit' : rateLimit } ) ;
19
+
20
+ await quibble . esm ( "../lib/definitions/rate-limit.js" , RATE_LIMIT_MOCK ) ;
21
+ const getClient = ( await import ( "../lib/get-client.js" ) ) . default ;
20
22
21
23
process . env . NODE_TLS_REJECT_UNAUTHORIZED = 0 ;
22
24
23
- serial ( ' Use a http proxy' , async ( t ) => {
25
+ test . serial ( " Use a http proxy" , async ( t ) => {
24
26
const server = createServer ( ) ;
25
27
await promisify ( server . listen ) . bind ( server ) ( ) ;
26
28
const serverPort = server . address ( ) . port ;
@@ -30,35 +32,35 @@ serial('Use a http proxy', async (t) => {
30
32
const proxyPort = proxy . address ( ) . port ;
31
33
serverDestroy ( proxy ) ;
32
34
33
- const proxyHandler = spy ( ) ;
34
- const serverHandler = spy ( ( request , response ) => {
35
+ const proxyHandler = sinon . spy ( ) ;
36
+ const serverHandler = sinon . spy ( ( request , response ) => {
35
37
response . end ( ) ;
36
38
} ) ;
37
- proxy . on ( ' request' , proxyHandler ) ;
38
- server . on ( ' request' , serverHandler ) ;
39
+ proxy . on ( " request" , proxyHandler ) ;
40
+ server . on ( " request" , serverHandler ) ;
39
41
40
42
const github = getClient ( {
41
- githubToken : ' github_token' ,
43
+ githubToken : " github_token" ,
42
44
githubUrl : `http://localhost:${ serverPort } ` ,
43
- githubApiPathPrefix : '' ,
45
+ githubApiPathPrefix : "" ,
44
46
proxy : `http://localhost:${ proxyPort } ` ,
45
47
} ) ;
46
48
47
- await github . repos . get ( { repo : ' repo' , owner : ' owner' } ) ;
49
+ await github . repos . get ( { repo : " repo" , owner : " owner" } ) ;
48
50
49
- t . is ( proxyHandler . args [ 0 ] [ 0 ] . headers . accept , ' application/vnd.github.v3+json' ) ;
50
- t . is ( serverHandler . args [ 0 ] [ 0 ] . headers . accept , ' application/vnd.github.v3+json' ) ;
51
+ t . is ( proxyHandler . args [ 0 ] [ 0 ] . headers . accept , " application/vnd.github.v3+json" ) ;
52
+ t . is ( serverHandler . args [ 0 ] [ 0 ] . headers . accept , " application/vnd.github.v3+json" ) ;
51
53
t . regex ( serverHandler . args [ 0 ] [ 0 ] . headers . via , / p r o x y / ) ;
52
- t . truthy ( serverHandler . args [ 0 ] [ 0 ] . headers [ ' x-forwarded-for' ] ) ;
54
+ t . truthy ( serverHandler . args [ 0 ] [ 0 ] . headers [ " x-forwarded-for" ] ) ;
53
55
54
56
await promisify ( proxy . destroy ) . bind ( proxy ) ( ) ;
55
57
await promisify ( server . destroy ) . bind ( server ) ( ) ;
56
58
} ) ;
57
59
58
- serial ( ' Use a https proxy' , async ( t ) => {
60
+ test . serial ( " Use a https proxy" , async ( t ) => {
59
61
const server = _createServer ( {
60
- key : await readFile ( join ( __dirname , ' /fixtures/ssl/ssl-cert-snakeoil.key' ) ) ,
61
- cert : await readFile ( join ( __dirname , ' /fixtures/ssl/ssl-cert-snakeoil.pem' ) ) ,
62
+ key : await readFile ( join ( __dirname , " /fixtures/ssl/ssl-cert-snakeoil.key" ) ) ,
63
+ cert : await readFile ( join ( __dirname , " /fixtures/ssl/ssl-cert-snakeoil.pem" ) ) ,
62
64
} ) ;
63
65
await promisify ( server . listen ) . bind ( server ) ( ) ;
64
66
const serverPort = server . address ( ) . port ;
@@ -68,66 +70,73 @@ serial('Use a https proxy', async (t) => {
68
70
const proxyPort = proxy . address ( ) . port ;
69
71
serverDestroy ( proxy ) ;
70
72
71
- const proxyHandler = spy ( ) ;
72
- const serverHandler = spy ( ( request , response ) => {
73
+ const proxyHandler = sinon . spy ( ) ;
74
+ const serverHandler = sinon . spy ( ( request , response ) => {
73
75
response . end ( ) ;
74
76
} ) ;
75
- proxy . on ( ' connect' , proxyHandler ) ;
76
- server . on ( ' request' , serverHandler ) ;
77
+ proxy . on ( " connect" , proxyHandler ) ;
78
+ server . on ( " request" , serverHandler ) ;
77
79
78
80
const github = getClient ( {
79
- githubToken : ' github_token' ,
81
+ githubToken : " github_token" ,
80
82
githubUrl : `https://localhost:${ serverPort } ` ,
81
- githubApiPathPrefix : '' ,
82
- proxy : { host : ' localhost' , port : proxyPort , headers : { foo : ' bar' } } ,
83
+ githubApiPathPrefix : "" ,
84
+ proxy : { host : " localhost" , port : proxyPort , headers : { foo : " bar" } } ,
83
85
} ) ;
84
86
85
- await github . repos . get ( { repo : ' repo' , owner : ' owner' } ) ;
87
+ await github . repos . get ( { repo : " repo" , owner : " owner" } ) ;
86
88
87
89
t . is ( proxyHandler . args [ 0 ] [ 0 ] . url , `localhost:${ serverPort } ` ) ;
88
- t . is ( proxyHandler . args [ 0 ] [ 0 ] . headers . foo , ' bar' ) ;
89
- t . is ( serverHandler . args [ 0 ] [ 0 ] . headers . accept , ' application/vnd.github.v3+json' ) ;
90
+ t . is ( proxyHandler . args [ 0 ] [ 0 ] . headers . foo , " bar" ) ;
91
+ t . is ( serverHandler . args [ 0 ] [ 0 ] . headers . accept , " application/vnd.github.v3+json" ) ;
90
92
91
93
await promisify ( proxy . destroy ) . bind ( proxy ) ( ) ;
92
94
await promisify ( server . destroy ) . bind ( server ) ( ) ;
93
95
} ) ;
94
96
95
- serial ( ' Do not use a proxy if set to false' , async ( t ) => {
97
+ test . serial ( " Do not use a proxy if set to false" , async ( t ) => {
96
98
const server = createServer ( ) ;
97
99
await promisify ( server . listen ) . bind ( server ) ( ) ;
98
100
const serverPort = server . address ( ) . port ;
99
101
serverDestroy ( server ) ;
100
102
101
- const serverHandler = spy ( ( request , response ) => {
103
+ const serverHandler = sinon . spy ( ( request , response ) => {
102
104
response . end ( ) ;
103
105
} ) ;
104
- server . on ( ' request' , serverHandler ) ;
106
+ server . on ( " request" , serverHandler ) ;
105
107
106
108
const github = getClient ( {
107
- githubToken : ' github_token' ,
109
+ githubToken : " github_token" ,
108
110
githubUrl : `http://localhost:${ serverPort } ` ,
109
- githubApiPathPrefix : '' ,
111
+ githubApiPathPrefix : "" ,
110
112
proxy : false ,
111
113
} ) ;
112
114
113
- await github . repos . get ( { repo : ' repo' , owner : ' owner' } ) ;
115
+ await github . repos . get ( { repo : " repo" , owner : " owner" } ) ;
114
116
115
- t . is ( serverHandler . args [ 0 ] [ 0 ] . headers . accept , ' application/vnd.github.v3+json' ) ;
117
+ t . is ( serverHandler . args [ 0 ] [ 0 ] . headers . accept , " application/vnd.github.v3+json" ) ;
116
118
t . falsy ( serverHandler . args [ 0 ] [ 0 ] . headers . via ) ;
117
- t . falsy ( serverHandler . args [ 0 ] [ 0 ] . headers [ ' x-forwarded-for' ] ) ;
119
+ t . falsy ( serverHandler . args [ 0 ] [ 0 ] . headers [ " x-forwarded-for" ] ) ;
118
120
119
121
await promisify ( server . destroy ) . bind ( server ) ( ) ;
120
122
} ) ;
121
123
122
- test ( ' Use the global throttler for all endpoints' , async ( t ) => {
124
+ test . serial ( " Use the global throttler for all endpoints" , async ( t ) => {
123
125
const rate = 150 ;
124
126
125
127
const octokit = new Octokit ( ) ;
126
- octokit . hook . wrap ( 'request' , ( ) => Date . now ( ) ) ;
127
- const github = proxyquire ( '../lib/get-client' , {
128
- '@octokit/rest' : { Octokit : stub ( ) . returns ( octokit ) } ,
129
- './definitions/rate-limit' : { RATE_LIMITS : { search : 1 , core : 1 } , GLOBAL_RATE_LIMIT : rate } ,
130
- } ) ( { githubToken : 'token' } ) ;
128
+ octokit . hook . wrap ( "request" , ( ) => Date . now ( ) ) ;
129
+
130
+ await quibble . reset ( )
131
+ await quibble . esm ( "../lib/definitions/rate-limit.js" , {
132
+ RATE_LIMITS : { search : 1 , core : 1 } ,
133
+ GLOBAL_RATE_LIMIT : rate ,
134
+ RETRY_CONF : { retries : 3 , factor : 1 , minTimeout : 1 , maxTimeout : 1 }
135
+ } ) ;
136
+ await quibble . esm ( "@octokit/rest" , { Octokit : sinon . stub ( ) . returns ( octokit ) } ) ;
137
+ const getClient = ( await import ( "../lib/get-client.js" ) ) . default ;
138
+
139
+ const github = getClient ( { githubToken : "token" } ) ;
131
140
132
141
/* eslint-disable unicorn/prevent-abbreviations */
133
142
@@ -152,16 +161,23 @@ test('Use the global throttler for all endpoints', async (t) => {
152
161
/* eslint-enable unicorn/prevent-abbreviations */
153
162
} ) ;
154
163
155
- test ( ' Use the same throttler for endpoints in the same rate limit group' , async ( t ) => {
164
+ test . serial ( " Use the same throttler for endpoints in the same rate limit group" , async ( t ) => {
156
165
const searchRate = 300 ;
157
166
const coreRate = 150 ;
158
167
159
168
const octokit = new Octokit ( ) ;
160
- octokit . hook . wrap ( 'request' , ( ) => Date . now ( ) ) ;
161
- const github = proxyquire ( '../lib/get-client' , {
162
- '@octokit/rest' : { Octokit : stub ( ) . returns ( octokit ) } ,
163
- './definitions/rate-limit' : { RATE_LIMITS : { search : searchRate , core : coreRate } , GLOBAL_RATE_LIMIT : 1 } ,
164
- } ) ( { githubToken : 'token' } ) ;
169
+ octokit . hook . wrap ( "request" , ( ) => Date . now ( ) ) ;
170
+
171
+ await quibble . reset ( )
172
+ await quibble . esm ( "../lib/definitions/rate-limit.js" , {
173
+ RATE_LIMITS : { search : searchRate , core : coreRate } ,
174
+ GLOBAL_RATE_LIMIT : 1 ,
175
+ RETRY_CONF : { retries : 3 , factor : 1 , minTimeout : 1 , maxTimeout : 1 }
176
+ } ) ;
177
+ await quibble . esm ( "@octokit/rest" , { Octokit : sinon . stub ( ) . returns ( octokit ) } ) ;
178
+ const getClient = ( await import ( "../lib/get-client.js" ) ) . default ;
179
+
180
+ const github = getClient ( { githubToken : "token" } ) ;
165
181
166
182
/* eslint-disable unicorn/prevent-abbreviations */
167
183
@@ -187,16 +203,23 @@ test('Use the same throttler for endpoints in the same rate limit group', async
187
203
/* eslint-enable unicorn/prevent-abbreviations */
188
204
} ) ;
189
205
190
- test ( ' Use different throttler for read and write endpoints' , async ( t ) => {
206
+ test . serial ( " Use different throttler for read and write endpoints" , async ( t ) => {
191
207
const writeRate = 300 ;
192
208
const readRate = 150 ;
193
209
194
210
const octokit = new Octokit ( ) ;
195
- octokit . hook . wrap ( 'request' , ( ) => Date . now ( ) ) ;
196
- const github = proxyquire ( '../lib/get-client' , {
197
- '@octokit/rest' : { Octokit : stub ( ) . returns ( octokit ) } ,
198
- './definitions/rate-limit' : { RATE_LIMITS : { core : { write : writeRate , read : readRate } } , GLOBAL_RATE_LIMIT : 1 } ,
199
- } ) ( { githubToken : 'token' } ) ;
211
+ octokit . hook . wrap ( "request" , ( ) => Date . now ( ) ) ;
212
+
213
+ await quibble . reset ( )
214
+ await quibble . esm ( "../lib/definitions/rate-limit.js" , {
215
+ RATE_LIMITS : { core : { write : writeRate , read : readRate } } ,
216
+ GLOBAL_RATE_LIMIT : 1 ,
217
+ RETRY_CONF : { retries : 3 , factor : 1 , minTimeout : 1 , maxTimeout : 1 }
218
+ } ) ;
219
+ await quibble . esm ( "@octokit/rest" , { Octokit : sinon . stub ( ) . returns ( octokit ) } ) ;
220
+ const getClient = ( await import ( "../lib/get-client.js" ) ) . default ;
221
+
222
+ const github = getClient ( { githubToken : "token" } ) ;
200
223
201
224
const a = await github . repos . get ( ) ;
202
225
const b = await github . repos . get ( ) ;
@@ -209,30 +232,33 @@ test('Use different throttler for read and write endpoints', async (t) => {
209
232
t . true ( inRange ( d - c , writeRate - 50 , writeRate + 50 ) ) ;
210
233
} ) ;
211
234
212
- test ( ' Use the same throttler when retrying' , async ( t ) => {
235
+ test . serial ( " Use the same throttler when retrying" , async ( t ) => {
213
236
const coreRate = 200 ;
214
- const request = stub ( ) . callsFake ( async ( ) => {
237
+ const request = sinon . stub ( ) . callsFake ( async ( ) => {
215
238
const error = new Error ( ) ;
216
239
error . time = Date . now ( ) ;
217
240
error . status = 404 ;
218
241
throw error ;
219
242
} ) ;
220
243
const octokit = new Octokit ( ) ;
221
- octokit . hook . wrap ( 'request' , request ) ;
222
- const github = proxyquire ( '../lib/get-client' , {
223
- '@octokit/rest' : { Octokit : stub ( ) . returns ( octokit ) } ,
224
- './definitions/rate-limit' : {
225
- RETRY_CONF : { retries : 3 , factor : 1 , minTimeout : 1 } ,
226
- RATE_LIMITS : { core : coreRate } ,
227
- GLOBAL_RATE_LIMIT : 1 ,
228
- } ,
229
- } ) ( { githubToken : 'token' } ) ;
244
+ octokit . hook . wrap ( "request" , request ) ;
245
+
246
+ await quibble . reset ( )
247
+ await quibble . esm ( "../lib/definitions/rate-limit.js" , {
248
+ RATE_LIMITS : { core : coreRate } ,
249
+ GLOBAL_RATE_LIMIT : 1 ,
250
+ RETRY_CONF : { retries : 3 , factor : 1 , minTimeout : 1 } ,
251
+ } ) ;
252
+ await quibble . esm ( "@octokit/rest" , { Octokit : sinon . stub ( ) . returns ( octokit ) } ) ;
253
+ const getClient = ( await import ( "../lib/get-client.js" ) ) . default ;
254
+
255
+ const github = getClient ( { githubToken : "token" } ) ;
230
256
231
257
await t . throwsAsync ( github . repos . createRelease ( ) ) ;
232
- const { time : a } = await t . throwsAsync ( request . getCall ( 0 ) . returnValue ) ;
233
- const { time : b } = await t . throwsAsync ( request . getCall ( 1 ) . returnValue ) ;
234
- const { time : c } = await t . throwsAsync ( request . getCall ( 2 ) . returnValue ) ;
235
- const { time : d } = await t . throwsAsync ( request . getCall ( 3 ) . returnValue ) ;
258
+ const { time : a } = await t . throwsAsync ( request . getCall ( 0 ) . returnValue ) ;
259
+ const { time : b } = await t . throwsAsync ( request . getCall ( 1 ) . returnValue ) ;
260
+ const { time : c } = await t . throwsAsync ( request . getCall ( 2 ) . returnValue ) ;
261
+ const { time : d } = await t . throwsAsync ( request . getCall ( 3 ) . returnValue ) ;
236
262
237
263
// Each retry should be done after `coreRate` ms
238
264
t . true ( inRange ( b - a , coreRate - 50 , coreRate + 50 ) ) ;
0 commit comments