interceptors
interceptors copied to clipboard
test(undici): add interceptor tests for undici
See #159.
I've rebased your feature branch, as well as adjusted it to the latest test structure refactoring (#182). Your newly added undici tests are now under test/third-party/undici
.
Thank you for adding these tests!
The support for unidici will roughly follow these steps:
- Research how
undici
performs requests internally. See what modules it utilizes, what modules can be extended to support interception. - Discuss the findings, assess the support strategy.
- If agreed, create a new
interceptors/undici
interceptor with the barebone implementation to cover the tests you've added. - Ensure sufficient test coverage, merge and release the change.
If you have time, feel free to tackle the first step. Gathering knowledge often takes the most time, and I could definitely use your expertise in that. Thank you!
In my earlier research, undici has its own mocking mechanism:
import { MockAgent, setGlobalDispatcher, } from 'undici'
const mockAgent = new MockAgent();
setGlobalDispatcher(mockAgent);
// Provide the base url to the request
const mockPool = mockAgent.get('http://localhost:3000');
// intercept the request
mockPool.intercept({
path: '/bank-transfer',
method: 'POST',
headers: {
'X-TOKEN-SECRET': 'SuperSecretToken',
},
body: JSON.stringify({
recepient: '1234567890',
ammount: '100'
})
}).reply(200, {
message: 'transaction processed'
})
We should take advantage of this setGlobalDispatcher stuff to implement the interceptor.
@kettanaito, I don't have enough knowledge to experiment and finish all implementation details, but I did a naive and maybe buggy implementation for you to refer: https://github.com/mswjs/interceptors/commit/a7e21d1a929e0914cdd472e73ac68bdce676c75a
That's what I learned:
-
getGlobalDispatcher
andsetGlobalDispatcher
are prefect for mocking and restoring. - undici classes are written in ES2015, so set
compilerOptions.target
toES5
won't work. - The
dispatch
method is synchronous, so have to find a way to inject asynchronous body parsing and response resolving. - Relying on
dispatch
andhandler
seem to be right, because undici uses them:- https://github.com/nodejs/undici/issues/531#issuecomment-784018642
- https://github.com/nodejs/undici/blob/f951002dfb86f502f1129588c021a26d7f2a0afb/lib/mock/mock-utils.js#L168-L174
@chentsulin Thanks for sharing your implementation, it was super helpful. I have been playing with it and seeing an issue where undici expects @types/node to be at least 14.18 (this has the Blob type from buffer) in order to import the Dispatcher.DispatchHandlers type for the resolver.
However, updating this seems to cause issues with other intercepters, such as XML and http.get. Did you run into anything like that? How did you resolve?
@kettanaito, I don't have enough knowledge to experiment and finish all implementation details, but I did a naive and maybe buggy implementation for you to refer: a7e21d1
Thanks for preparing a reference implementation, @chentsulin!
I'm not sure to which extend we can reuse it, as with interceptors we're aiming at low-level request interception. Relying on MockAgent
is a high-level thing, meaning we're going deeper into implementation specifics rather than relying on Node.js primitives.
I'd love to start this feature from research. We should first understand what kind of requests does undici make (it has to make a Socket
connection at least, there are no other ways to request things in Node.js) and, ideally, model our interceptor around that.
I don't think I'll have time to work on this in the foreseeable future, so anybody is welcome to grab the research and implementation if they find this interesting.
We are not going to support Undici directly. Instead, we will support global fetch in Node.js, which is powered by Undicit and is already available since Node 17.