-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: don't mock client under test (#442)
* test: don't mock client under test * test: check that the http client handles multiple requests
- Loading branch information
Showing
6 changed files
with
256 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,94 @@ | ||
import { test } from 'node:test'; | ||
import { rejects } from 'node:assert'; | ||
import tap from 'tap'; | ||
import express from 'express'; | ||
import HTTP from '../lib/http.js'; | ||
|
||
test('should abort the request if it takes longer than the timeout', async () => { | ||
// Mock the undici.Client's request method | ||
const mockRequestFn = async (url, { signal }) => { | ||
return new Promise((resolve, reject) => { | ||
// Simulate a delay longer than the timeout | ||
tap.test( | ||
'should abort the request if it takes longer than the timeout', | ||
(t) => { | ||
const app = express(); | ||
app.get('/', (req, res) => { | ||
setTimeout(() => { | ||
if (signal.aborted) { | ||
const abortError = new Error( | ||
'Request aborted due to timeout', | ||
); | ||
abortError.name = 'AbortError'; | ||
reject(abortError); | ||
} else { | ||
resolve({ | ||
statusCode: 200, | ||
headers: {}, | ||
body: 'OK', | ||
}); | ||
} | ||
}, 2000); // 2 seconds delay | ||
res.send('OK'); | ||
}, 2000); // longer than the default request timeout | ||
}); | ||
}; | ||
|
||
// @ts-ignore | ||
const http = new HTTP(mockRequestFn); | ||
const url = 'https://example.com/test'; | ||
const options = { | ||
method: /** @type {'GET'} */ ('GET'), | ||
timeout: 1000, // 1 second timeout | ||
}; | ||
|
||
// Assert that the request is rejected with an AbortError | ||
await rejects( | ||
http.request(url, options), | ||
(/** @type {Error} */ err) => | ||
err.name === 'AbortError' && | ||
err.message === 'Request aborted due to timeout', | ||
'Expected request to be aborted due to timeout', | ||
); | ||
}); | ||
|
||
const server = app.listen( | ||
{ | ||
host: '0.0.0.0', | ||
port: 0, | ||
}, | ||
() => { | ||
const url = `http://${server.address().address}:${server.address().port}/`; | ||
const options = { | ||
method: /** @type {'GET'} */ ('GET'), | ||
}; | ||
|
||
t.rejects( | ||
async () => { | ||
const http = new HTTP(); | ||
await http.request(url, options); | ||
}, | ||
{ | ||
name: 'AbortError', | ||
message: 'This operation was aborted', | ||
}, | ||
).finally(() => { | ||
server.close(); | ||
t.end(); | ||
}); | ||
}, | ||
); | ||
}, | ||
); | ||
|
||
tap.test( | ||
'should not timeout if there are multiple requests in flight and one of them fails', | ||
(t) => { | ||
const app = express(); | ||
|
||
app.get('/fast', (req, res) => { | ||
res.send('OK'); | ||
}); | ||
|
||
app.get('/slow', (req, res) => { | ||
setTimeout(() => { | ||
res.send('OK'); | ||
}, 2000); // longer than the default request timeout | ||
}); | ||
|
||
const server = app.listen( | ||
{ | ||
host: '0.0.0.0', | ||
port: 0, | ||
}, | ||
() => { | ||
const options = { | ||
method: /** @type {'GET'} */ ('GET'), | ||
}; | ||
|
||
t.rejects( | ||
async () => { | ||
const http = new HTTP(); | ||
await Promise.all([ | ||
http.request( | ||
`http://${server.address().address}:${server.address().port}/slow`, | ||
options, | ||
), | ||
http.request( | ||
`http://${server.address().address}:${server.address().port}/fast`, | ||
options, | ||
), | ||
]); | ||
}, | ||
{ | ||
name: 'AbortError', | ||
message: 'This operation was aborted', | ||
}, | ||
).finally(() => { | ||
server.close(); | ||
t.end(); | ||
}); | ||
}, | ||
); | ||
}, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters