Skip to content

Commit

Permalink
fix: allow optional body for mock reply (nodejs#1536)
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinBeckwith authored and metcoder95 committed Dec 26, 2022
1 parent 5583998 commit 16ba6ca
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 27 deletions.
4 changes: 2 additions & 2 deletions docs/api/MockAgent.md
Expand Up @@ -465,7 +465,7 @@ agent.disableNetConnect()
agent
.get('https://example.com')
.intercept({ method: 'GET', path: '/' })
.reply(200, '')
.reply(200)

const pendingInterceptors = agent.pendingInterceptors()
// Returns [
Expand Down Expand Up @@ -508,7 +508,7 @@ agent.disableNetConnect()
agent
.get('https://example.com')
.intercept({ method: 'GET', path: '/' })
.reply(200, '')
.reply(200)

agent.assertNoPendingInterceptors()
// Throws an UndiciError with the following message:
Expand Down
6 changes: 3 additions & 3 deletions lib/mock/mock-interceptor.js
Expand Up @@ -130,7 +130,7 @@ class MockInterceptor {
throw new InvalidArgumentError('reply options callback must return an object')
}

const { statusCode, data, responseOptions = {} } = resolvedData
const { statusCode, data = '', responseOptions = {} } = resolvedData
this.validateReplyParameters(statusCode, data, responseOptions)
// Since the values can be obtained immediately we return them
// from this higher order function that will be resolved later.
Expand All @@ -145,10 +145,10 @@ class MockInterceptor {
}

// We can have either one or three parameters, if we get here,
// we should have 2-3 parameters. So we spread the arguments of
// we should have 1-3 parameters. So we spread the arguments of
// this function to obtain the parameters, since replyData will always
// just be the statusCode.
const [statusCode, data, responseOptions = {}] = [...arguments]
const [statusCode, data = '', responseOptions = {}] = [...arguments]
this.validateReplyParameters(statusCode, data, responseOptions)

// Send in-already provided data like usual
Expand Down
21 changes: 2 additions & 19 deletions test/mock-interceptor.js
Expand Up @@ -32,14 +32,13 @@ test('MockInterceptor - reply', t => {
})

t.test('should error if passed options invalid', t => {
t.plan(3)
t.plan(2)

const mockInterceptor = new MockInterceptor({
path: '',
method: ''
}, [])
t.throws(() => mockInterceptor.reply(), new InvalidArgumentError('statusCode must be defined'))
t.throws(() => mockInterceptor.reply(200), new InvalidArgumentError('data must be defined'))
t.throws(() => mockInterceptor.reply(200, '', 'hello'), new InvalidArgumentError('responseOptions must be an object'))
})
})
Expand Down Expand Up @@ -113,7 +112,7 @@ test('MockInterceptor - reply options callback', t => {
})

t.test('should error if passed options invalid', async (t) => {
t.plan(4)
t.plan(3)

const baseUrl = 'http://localhost:9999'
const mockAgent = new MockAgent()
Expand All @@ -126,13 +125,6 @@ test('MockInterceptor - reply options callback', t => {
method: 'GET'
}).reply(() => {})

mockPool.intercept({
path: '/test2',
method: 'GET'
}).reply(() => ({
statusCode: 200
}))

mockPool.intercept({
path: '/test3',
method: 'GET'
Expand All @@ -159,15 +151,6 @@ test('MockInterceptor - reply options callback', t => {
onComplete: () => {}
}), new InvalidArgumentError('reply options callback must return an object'))

t.throws(() => mockPool.dispatch({
path: '/test2',
method: 'GET'
}, {
onHeaders: () => {},
onData: () => {},
onComplete: () => {}
}), new InvalidArgumentError('data must be defined'))

t.throws(() => mockPool.dispatch({
path: '/test3',
method: 'GET'
Expand Down
3 changes: 2 additions & 1 deletion test/types/mock-interceptor.test-d.ts
Expand Up @@ -12,6 +12,7 @@ expectAssignable<BodyInit | Dispatcher.DispatchOptions['body']>(mockResponseCall
const mockInterceptorDefaultMethod = mockPool.intercept({ path: '' })

// reply
expectAssignable<MockScope>(mockInterceptor.reply(200))
expectAssignable<MockScope>(mockInterceptor.reply(200, ''))
expectAssignable<MockScope>(mockInterceptor.reply(200, Buffer))
expectAssignable<MockScope>(mockInterceptor.reply(200, {}))
Expand Down Expand Up @@ -55,7 +56,7 @@ expectAssignable<BodyInit | Dispatcher.DispatchOptions['body']>(mockResponseCall

{
const mockPool: MockPool = new MockAgent().get('')
const mockScope = mockPool.intercept({ path: '', method: 'GET' }).reply(200, '')
const mockScope = mockPool.intercept({ path: '', method: 'GET' }).reply(200)

// delay
expectAssignable<MockScope>(mockScope.delay(1))
Expand Down
4 changes: 2 additions & 2 deletions types/mock-interceptor.d.ts
Expand Up @@ -26,7 +26,7 @@ declare class MockInterceptor {
reply<TData extends object = object>(replyOptionsCallback: MockInterceptor.MockReplyOptionsCallback<TData>): MockScope<TData>;
reply<TData extends object = object>(
statusCode: number,
data: TData | Buffer | string | MockInterceptor.MockResponseDataHandler<TData>,
data?: TData | Buffer | string | MockInterceptor.MockResponseDataHandler<TData>,
responseOptions?: MockInterceptor.MockResponseOptions
): MockScope<TData>;
/** Mock an undici request by throwing the defined reply error. */
Expand Down Expand Up @@ -84,7 +84,7 @@ declare namespace MockInterceptor {

export type MockReplyOptionsCallback<TData extends object = object> = (
opts: MockResponseCallbackOptions
) => { statusCode: number, data: TData | Buffer | string, responseOptions?: MockResponseOptions }
) => { statusCode: number, data?: TData | Buffer | string, responseOptions?: MockResponseOptions }
}

interface Interceptable extends Dispatcher {
Expand Down

0 comments on commit 16ba6ca

Please sign in to comment.