Skip to content

Commit c1d3ee9

Browse files
committed
MockAgent.prototype.get support ignoreTrailingSlash option
1 parent 81a1102 commit c1d3ee9

2 files changed

Lines changed: 98 additions & 31 deletions

File tree

‎lib/mock/mock-agent.js‎

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@ const {
1717
kMockAgentAddCallHistoryLog,
1818
kMockAgentMockCallHistoryInstance,
1919
kMockAgentAcceptsNonStandardSearchParameters,
20-
kMockCallHistoryAddLog
20+
kMockCallHistoryAddLog,
21+
kIgnoreTrailingSlash
2122
} = require('./mock-symbols')
2223
const MockClient = require('./mock-client')
2324
const MockPool = require('./mock-pool')
24-
const { matchValue, normalizeSearchParams, buildAndValidateMockOptions } = require('./mock-utils')
25+
const {
26+
matchValue,
27+
normalizeSearchParams,
28+
buildAndValidateMockOptions
29+
} = require('./mock-utils')
2530
const { InvalidArgumentError, UndiciError } = require('../core/errors')
2631
const Dispatcher = require('../dispatcher/dispatcher')
2732
const PendingInterceptorsFormatter = require('./pending-interceptors-formatter')
@@ -35,12 +40,17 @@ class MockAgent extends Dispatcher {
3540

3641
this[kNetConnect] = true
3742
this[kIsMockActive] = true
38-
this[kMockAgentIsCallHistoryEnabled] = mockOptions?.enableCallHistory ?? false
39-
this[kMockAgentAcceptsNonStandardSearchParameters] = mockOptions?.acceptNonStandardSearchParameters ?? false
43+
this[kMockAgentIsCallHistoryEnabled] =
44+
mockOptions?.enableCallHistory ?? false
45+
this[kMockAgentAcceptsNonStandardSearchParameters] =
46+
mockOptions?.acceptNonStandardSearchParameters ?? false
47+
this[kIgnoreTrailingSlash] = mockOptions?.ignoreTrailingSlash ?? false
4048

4149
// Instantiate Agent and encapsulate
4250
if (opts?.agent && typeof opts.agent.dispatch !== 'function') {
43-
throw new InvalidArgumentError('Argument opts.agent must implement Agent')
51+
throw new InvalidArgumentError(
52+
'Argument opts.agent must implement Agent'
53+
)
4454
}
4555
const agent = opts?.agent ? opts.agent : new Agent(opts)
4656
this[kAgent] = agent
@@ -54,11 +64,15 @@ class MockAgent extends Dispatcher {
5464
}
5565

5666
get (origin) {
57-
let dispatcher = this[kMockAgentGet](origin)
67+
const originKey = this[kIgnoreTrailingSlash]
68+
? origin.replace(/\/$/, '')
69+
: origin
70+
71+
let dispatcher = this[kMockAgentGet](originKey)
5872

5973
if (!dispatcher) {
60-
dispatcher = this[kFactory](origin)
61-
this[kMockAgentSet](origin, dispatcher)
74+
dispatcher = this[kFactory](originKey)
75+
this[kMockAgentSet](originKey, dispatcher)
6276
}
6377
return dispatcher
6478
}
@@ -69,13 +83,17 @@ class MockAgent extends Dispatcher {
6983

7084
this[kMockAgentAddCallHistoryLog](opts)
7185

72-
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters]
86+
const acceptNonStandardSearchParameters =
87+
this[kMockAgentAcceptsNonStandardSearchParameters]
7388

7489
const dispatchOpts = { ...opts }
7590

7691
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
7792
const [path, searchParams] = dispatchOpts.path.split('?')
78-
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters)
93+
const normalizedSearchParams = normalizeSearchParams(
94+
searchParams,
95+
acceptNonStandardSearchParameters
96+
)
7997
dispatchOpts.path = `${path}?${normalizedSearchParams}`
8098
}
8199

@@ -97,7 +115,11 @@ class MockAgent extends Dispatcher {
97115
}
98116

99117
enableNetConnect (matcher) {
100-
if (typeof matcher === 'string' || typeof matcher === 'function' || matcher instanceof RegExp) {
118+
if (
119+
typeof matcher === 'string' ||
120+
typeof matcher === 'function' ||
121+
matcher instanceof RegExp
122+
) {
101123
if (Array.isArray(this[kNetConnect])) {
102124
this[kNetConnect].push(matcher)
103125
} else {
@@ -106,7 +128,9 @@ class MockAgent extends Dispatcher {
106128
} else if (typeof matcher === 'undefined') {
107129
this[kNetConnect] = true
108130
} else {
109-
throw new InvalidArgumentError('Unsupported matcher. Must be one of String|Function|RegExp.')
131+
throw new InvalidArgumentError(
132+
'Unsupported matcher. Must be one of String|Function|RegExp.'
133+
)
110134
}
111135
}
112136

@@ -185,7 +209,11 @@ class MockAgent extends Dispatcher {
185209

186210
// If we match, create a pool and assign the same dispatches
187211
for (const [keyMatcher, result] of Array.from(this[kClients])) {
188-
if (result && typeof keyMatcher !== 'string' && matchValue(keyMatcher, origin)) {
212+
if (
213+
result &&
214+
typeof keyMatcher !== 'string' &&
215+
matchValue(keyMatcher, origin)
216+
) {
189217
const dispatcher = this[kFactory](origin)
190218
this[kMockAgentSet](origin, dispatcher)
191219
dispatcher[kDispatches] = result.dispatcher[kDispatches]
@@ -202,11 +230,18 @@ class MockAgent extends Dispatcher {
202230
const mockAgentClients = this[kClients]
203231

204232
return Array.from(mockAgentClients.entries())
205-
.flatMap(([origin, result]) => result.dispatcher[kDispatches].map(dispatch => ({ ...dispatch, origin })))
233+
.flatMap(([origin, result]) =>
234+
result.dispatcher[kDispatches].map((dispatch) => ({
235+
...dispatch,
236+
origin
237+
}))
238+
)
206239
.filter(({ pending }) => pending)
207240
}
208241

209-
assertNoPendingInterceptors ({ pendingInterceptorsFormatter = new PendingInterceptorsFormatter() } = {}) {
242+
assertNoPendingInterceptors ({
243+
pendingInterceptorsFormatter = new PendingInterceptorsFormatter()
244+
} = {}) {
210245
const pending = this.pendingInterceptors()
211246

212247
if (pending.length === 0) {

‎test/jest/mock-agent.test.js‎

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const { getResponse } = require('../../lib/mock/mock-utils')
55

66
/* global describe, it, afterEach, expect */
77

8-
describe('MockAgent', () => {
8+
describe('smoking test in jest', () => {
99
let mockAgent
1010

1111
afterEach(() => {
@@ -21,21 +21,30 @@ describe('MockAgent', () => {
2121
setGlobalDispatcher(mockAgent)
2222
const mockClient = mockAgent.get(baseUrl)
2323

24-
mockClient.intercept({
25-
path: '/foo?hello=there&see=ya',
26-
method: 'POST',
27-
body: 'form1=data1&form2=data2'
28-
}).reply(200, { foo: 'bar' }, {
29-
headers: {
30-
'content-type': 'application/json'
31-
},
32-
trailers: { 'Content-MD5': 'test' }
33-
})
34-
35-
const { statusCode, headers, trailers, body } = await request(`${baseUrl}/foo?hello=there&see=ya`, {
36-
method: 'POST',
37-
body: 'form1=data1&form2=data2'
38-
})
24+
mockClient
25+
.intercept({
26+
path: '/foo?hello=there&see=ya',
27+
method: 'POST',
28+
body: 'form1=data1&form2=data2'
29+
})
30+
.reply(
31+
200,
32+
{ foo: 'bar' },
33+
{
34+
headers: {
35+
'content-type': 'application/json'
36+
},
37+
trailers: { 'Content-MD5': 'test' }
38+
}
39+
)
40+
41+
const { statusCode, headers, trailers, body } = await request(
42+
`${baseUrl}/foo?hello=there&see=ya`,
43+
{
44+
method: 'POST',
45+
body: 'form1=data1&form2=data2'
46+
}
47+
)
3948
expect(statusCode).toBe(200)
4049
expect(headers).toEqual({ 'content-type': 'application/json' })
4150
expect(trailers).toEqual({ 'content-md5': 'test' })
@@ -44,3 +53,26 @@ describe('MockAgent', () => {
4453
expect(jsonResponse).toEqual({ foo: 'bar' })
4554
})
4655
})
56+
57+
describe('MockAgent with ignoreTrailingSlash option', () => {
58+
const trailingSlashUrl = 'http://localhost:9999/'
59+
const noTrailingSlashUrl = 'http://localhost:9999'
60+
61+
it('should not remove trailing slash from origin if the option is not enable', async () => {
62+
const mockClient = new MockAgent()
63+
64+
const dispatcherOne = mockClient.get(trailingSlashUrl)
65+
const dispatcherTwo = mockClient.get(noTrailingSlashUrl)
66+
67+
expect(dispatcherOne).not.toBe(dispatcherTwo)
68+
})
69+
70+
it('should remove trailing slash from origin if enabled the option', async () => {
71+
const mockClient = new MockAgent({ ignoreTrailingSlash: true })
72+
73+
const dispatcherOne = mockClient.get(trailingSlashUrl)
74+
const dispatcherTwo = mockClient.get(noTrailingSlashUrl)
75+
76+
expect(dispatcherOne).toBe(dispatcherTwo)
77+
})
78+
})

0 commit comments

Comments
 (0)