Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 44 additions & 4 deletions test/third-party/axios.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/**
* @vitest-environment jsdom
*/
// @vitest-environment jsdom
import { it, expect, beforeAll, afterEach, afterAll } from 'vitest'
import axios from 'axios'
import { HttpServer } from '@open-draft/test-server/http'
Expand Down Expand Up @@ -114,7 +112,7 @@ it('bypass the interceptor and return the original response', async () => {
/**
* @see https://github.com/mswjs/interceptors/issues/564
*/
it('preserves "auth" (Authorization)', async () => {
it('preserves the "auth" options', async () => {
const getRequestPromise = new DeferredPromise<Request>()

interceptor.on('request', ({ request }) => {
Expand All @@ -141,3 +139,45 @@ it('preserves "auth" (Authorization)', async () => {
`Basic ${btoa('foo@bar.com:secret123')}`
)
})

it('follows a mocked redirect response (xhr)', async () => {
interceptor.on('request', ({ request, controller }) => {
if (request.url.endsWith('/original')) {
return controller.respondWith(
Response.redirect('http://localhost:3000/redirected', 307)
)
}

if (request.url.endsWith('/redirected')) {
controller.respondWith(new Response('redirected response'))
}
})

const response = await axios.get('http://localhost:3000/original', {
adapter: 'xhr',
})

expect(response.status).toBe(200)
expect(response.data).toBe('redirected response')
})

it('follows a mocked redirect response (http)', async () => {
interceptor.on('request', ({ request, controller }) => {
if (request.url.endsWith('/original')) {
return controller.respondWith(
Response.redirect('http://localhost/redirected', 307)
)
}

if (request.url.endsWith('/redirected')) {
controller.respondWith(new Response('redirected response'))
}
})

const response = await axios.get('http://localhost/original', {
adapter: 'http',
})

expect(response.status).toBe(200)
expect(response.data).toBe('redirected response')
})
125 changes: 113 additions & 12 deletions test/third-party/follow-redirect-http.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
// @vitest-environment jsdom
// @vitest-environment node
import { vi, it, expect, beforeAll, afterEach, afterAll } from 'vitest'
import { https } from 'follow-redirects'
import { HttpServer } from '@open-draft/test-server/http'
import { ClientRequestInterceptor } from '../../src/interceptors/ClientRequest'
import type { HttpRequestEventMap } from '../../src/glossary'
import { waitForClientRequest } from '../helpers'

const resolver = vi.fn<HttpRequestEventMap['request']>()

const interceptor = new ClientRequestInterceptor()
interceptor.on('request', resolver)

const server = new HttpServer((app) => {
app.post('/resource', (req, res) => {
Expand All @@ -24,6 +20,14 @@ const server = new HttpServer((app) => {
app.post('/user', (req, res) => {
res.status(200).send('hello from the server')
})

app.get('/original', (req, res) => {
res.writeHead(307, { Location: server.https.url('/redirected') })
})

app.get('/redirected', (req, res) => {
res.status(200).send('redirected response')
})
})

beforeAll(async () => {
Expand All @@ -33,19 +37,23 @@ beforeAll(async () => {

afterEach(() => {
vi.resetAllMocks()
interceptor.removeAllListeners()
})

afterAll(async () => {
interceptor.dispose()
await server.close()
})

it('intercepts a POST request issued by "follow-redirects"', async () => {
it('intercepts a request issued by "follow-redirects"', async () => {
const requestListener = vi.fn<[Request]>()
interceptor.on('request', ({ request }) => requestListener(request))

const { address } = server.https
const payload = JSON.stringify({ todo: 'Buy the milk' })

const catchResponseUrl = vi.fn()
const req = https.request(
const request = https.request(
{
method: 'POST',
hostname: address.host,
Expand All @@ -62,14 +70,16 @@ it('intercepts a POST request issued by "follow-redirects"', async () => {
}
)

req.end(payload)
request.end(payload)

const { text } = await waitForClientRequest(req as any)
const { text } = await waitForClientRequest(request as any)

expect(resolver).toHaveBeenCalledTimes(2)
await vi.waitFor(() => {
expect(requestListener).toHaveBeenCalledTimes(2)
})

// Intercepted initial request.
const [{ request: initialRequest }] = resolver.mock.calls[0]
const [initialRequest] = requestListener.mock.calls[0]

expect(initialRequest.method).toBe('POST')
expect(initialRequest.url).toBe(server.https.url('/resource'))
Expand All @@ -79,7 +89,7 @@ it('intercepts a POST request issued by "follow-redirects"', async () => {
expect(await initialRequest.json()).toEqual({ todo: 'Buy the milk' })

// Intercepted redirect request (issued by "follow-redirects").
const [{ request: redirectedRequest }] = resolver.mock.calls[1]
const [redirectedRequest] = requestListener.mock.calls[1]

expect(redirectedRequest.method).toBe('POST')
expect(redirectedRequest.url).toBe(server.https.url('/user'))
Expand All @@ -92,3 +102,94 @@ it('intercepts a POST request issued by "follow-redirects"', async () => {
expect(catchResponseUrl).toHaveBeenCalledWith(server.https.url('/user'))
expect(await text()).toBe('hello from the server')
})

it('supports mocking a redirect response to the original response', async () => {
const requestListener = vi.fn<[Request]>()

interceptor.once('request', ({ request, controller }) => {
requestListener(request)

if (request.url.endsWith('/original')) {
controller.respondWith(
Response.redirect(server.https.url('/redirected'), 307)
)
}
})

const catchResponseUrl = vi.fn()
const request = https.request(
{
method: 'GET',
hostname: server.https.address.host,
port: server.https.address.port,
path: '/original',
rejectUnauthorized: false,
},
(res) => {
catchResponseUrl(res.responseUrl)
}
)

request.end()

const { text } = await waitForClientRequest(request as any)

// Intercepted redirect request (issued by "follow-redirects").
const [redirectedRequest] = requestListener.mock.calls[0]

expect(redirectedRequest.method).toBe('GET')
expect(redirectedRequest.url).toBe(server.https.url('/original'))

// Response (original).
expect(catchResponseUrl).toHaveBeenCalledWith(server.https.url('/redirected'))
expect(await text()).toBe('redirected response')
})

it('supports mocking a redirect response to a mocked response', async () => {
const requestListener = vi.fn<[Request]>()

interceptor.on('request', ({ request, controller }) => {
requestListener(request)

if (request.url.endsWith('/original')) {
return controller.respondWith(
Response.redirect('https://localhost:3000/redirected', 307)
)
}

if (request.url.endsWith('/redirected')) {
return controller.respondWith(new Response('mocked response'))
}
})

const catchResponseUrl = vi.fn()
const request = https.request(
{
method: 'GET',
hostname: server.https.address.host,
port: server.https.address.port,
path: '/original',
rejectUnauthorized: false,
},

(res) => {
catchResponseUrl(res.responseUrl)
}
)

request.end()

const { text } = await waitForClientRequest(request as any)

// Intercepted redirect request (issued by "follow-redirects").
const [redirectedRequest] = requestListener.mock.calls[0]

expect(redirectedRequest.method).toBe('GET')
expect(redirectedRequest.url).toBe(server.https.url('/original'))

// Response (original).
expect(catchResponseUrl).toHaveBeenCalledWith(
'https://localhost:3000/redirected'
)
expect(await text()).toBe('mocked response')
})