Skip to content

Commit fa9b07f

Browse files
authored
fix: resolve relative URLs against location.href (#2471)
1 parent 827a5dc commit fa9b07f

5 files changed

Lines changed: 90 additions & 48 deletions

File tree

src/browser/utils/getAbsoluteWorkerUrl.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
/**
2-
* @vitest-environment jsdom
3-
*/
1+
// @vitest-environment jsdom
42
import { getAbsoluteWorkerUrl } from './getAbsoluteWorkerUrl'
53

64
const rawLocation = window.location
Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,47 @@
1-
/**
2-
* @vitest-environment jsdom
3-
*/
1+
// @vitest-environment jsdom
42
import { getAbsoluteUrl } from './getAbsoluteUrl'
53

6-
it('rebases a relative URL against the current "baseURI" (default)', () => {
7-
expect(getAbsoluteUrl('/reviews')).toEqual('http://localhost/reviews')
4+
const rawLocation = window.location
5+
6+
afterAll(() => {
7+
Object.defineProperty(window, 'location', {
8+
value: rawLocation,
9+
})
10+
})
11+
12+
it('resolves a relative URL against the current location (default)', () => {
13+
expect(getAbsoluteUrl('/reviews')).toBe('http://localhost/reviews')
14+
})
15+
16+
it('supports relative URLs starting with search parameters', () => {
17+
Object.defineProperty(window, 'location', {
18+
value: {
19+
href: 'http://localhost/nested',
20+
},
21+
})
22+
23+
expect(getAbsoluteUrl('?resourceId=abc-123')).toBe(
24+
'http://localhost/nested?resourceId=abc-123',
25+
)
826
})
927

10-
it('rebases a relative URL against a custom base URL', () => {
11-
expect(getAbsoluteUrl('/user', 'https://api.github.com')).toEqual(
28+
it('resolves a relative URL against a custom base URL', () => {
29+
expect(getAbsoluteUrl('/user', 'https://api.github.com')).toBe(
1230
'https://api.github.com/user',
1331
)
1432
})
1533

1634
it('returns a given absolute URL as-is', () => {
17-
expect(getAbsoluteUrl('https://api.mswjs.io/users')).toEqual(
35+
expect(getAbsoluteUrl('https://api.mswjs.io/users')).toBe(
1836
'https://api.mswjs.io/users',
1937
)
2038
})
2139

2240
it('returns an absolute URL given a relative path without a leading slash', () => {
23-
expect(getAbsoluteUrl('users')).toEqual('http://localhost/users')
41+
expect(getAbsoluteUrl('users')).toBe('http://localhost/users')
2442
})
2543

2644
it('returns a path with a pattern as-is', () => {
27-
expect(getAbsoluteUrl(':api/user')).toEqual('http://localhost/:api/user')
28-
expect(getAbsoluteUrl('*/resource/*')).toEqual('*/resource/*')
45+
expect(getAbsoluteUrl(':api/user')).toBe('http://localhost/:api/user')
46+
expect(getAbsoluteUrl('*/resource/*')).toBe('*/resource/*')
2947
})

src/core/utils/url/getAbsoluteUrl.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ export function getAbsoluteUrl(path: string, baseUrl?: string): string {
1616

1717
// Resolve a relative request URL against a given custom "baseUrl"
1818
// or the document baseURI (in the case of browser/browser-like environments).
19-
const origin =
20-
baseUrl || (typeof document !== 'undefined' && document.baseURI)
19+
const origin = baseUrl || (typeof location !== 'undefined' && location.href)
2120

2221
return origin
2322
? // Encode and decode the path to preserve escaped characters.

test/browser/rest-api/request/matching/uri.mocks.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ const worker = setupWorker(
2323
http.get(`/resource\\('id'\\)`, () => {
2424
return HttpResponse.json({ mocked: true })
2525
}),
26+
27+
http.get('./', ({ request }) => {
28+
const url = new URL(request.url)
29+
30+
if (url.searchParams.has('resourceId')) {
31+
return HttpResponse.json({ mocked: true })
32+
}
33+
}),
2634
)
2735

2836
worker.start()

test/browser/rest-api/request/matching/uri.test.ts

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ test('matches an exact string with the same request URL with a trailing slash',
66
}) => {
77
await loadExample(require.resolve('./uri.mocks.ts'))
88

9-
const res = await fetch('https://api.github.com/made-up/')
9+
const response = await fetch('https://api.github.com/made-up/')
1010

11-
expect(res.status()).toEqual(200)
12-
expect(res.fromServiceWorker()).toBe(true)
13-
expect(await res.json()).toEqual({
11+
expect(response.status()).toEqual(200)
12+
expect(response.fromServiceWorker()).toBe(true)
13+
await expect(response.json()).resolves.toEqual({
1414
mocked: true,
1515
})
1616
})
@@ -22,9 +22,11 @@ test('does not match an exact string with a different request URL with a trailin
2222
}) => {
2323
await loadExample(require.resolve('./uri.mocks.ts'))
2424

25-
const res = await page.evaluate(() => fetch('https://api.github.com/other/'))
25+
const response = await page.evaluate(() =>
26+
fetch('https://api.github.com/other/'),
27+
)
2628

27-
expect(res.status).not.toBe(200)
29+
expect(response.status).not.toBe(200)
2830
})
2931

3032
test('matches an exact string with the same request URL without a trailing slash', async ({
@@ -33,11 +35,11 @@ test('matches an exact string with the same request URL without a trailing slash
3335
}) => {
3436
await loadExample(require.resolve('./uri.mocks.ts'))
3537

36-
const res = await fetch('https://api.github.com/made-up')
38+
const response = await fetch('https://api.github.com/made-up')
3739

38-
expect(res.status()).toEqual(200)
39-
expect(res.fromServiceWorker()).toBe(true)
40-
expect(await res.json()).toEqual({
40+
expect(response.status()).toEqual(200)
41+
expect(response.fromServiceWorker()).toBe(true)
42+
await expect(response.json()).resolves.toEqual({
4143
mocked: true,
4244
})
4345
})
@@ -49,9 +51,11 @@ test('does not match an exact string with a different request URL without a trai
4951
}) => {
5052
await loadExample(require.resolve('./uri.mocks.ts'))
5153

52-
const res = await page.evaluate(() => fetch('https://api.github.com/other'))
54+
const response = await page.evaluate(() =>
55+
fetch('https://api.github.com/other'),
56+
)
5357

54-
expect(res.status).not.toBe(200)
58+
expect(response.status).not.toBe(200)
5559
})
5660

5761
test('matches a mask against a matching request URL', async ({
@@ -60,11 +64,11 @@ test('matches a mask against a matching request URL', async ({
6064
}) => {
6165
await loadExample(require.resolve('./uri.mocks.ts'))
6266

63-
const res = await fetch('https://test.mswjs.io/messages/abc-123')
67+
const response = await fetch('https://test.mswjs.io/messages/abc-123')
6468

65-
expect(res.status()).toEqual(200)
66-
expect(res.fromServiceWorker()).toBe(true)
67-
expect(await res.json()).toEqual({
69+
expect(response.status()).toEqual(200)
70+
expect(response.fromServiceWorker()).toBe(true)
71+
await expect(response.json()).resolves.toEqual({
6872
messageId: 'abc-123',
6973
})
7074
})
@@ -75,13 +79,13 @@ test('ignores query parameters when matching a mask against a matching request U
7579
}) => {
7680
await loadExample(require.resolve('./uri.mocks.ts'))
7781

78-
const res = await fetch(
82+
const response = await fetch(
7983
'https://test.mswjs.io/messages/abc-123/items?hello=true',
8084
)
8185

82-
expect(res.status()).toEqual(200)
83-
expect(res.fromServiceWorker()).toBe(true)
84-
expect(await res.json()).toEqual({
86+
expect(response.status()).toEqual(200)
87+
expect(response.fromServiceWorker()).toBe(true)
88+
await expect(response.json()).resolves.toEqual({
8589
messageId: 'abc-123',
8690
})
8791
})
@@ -93,11 +97,11 @@ test('does not match a mask against a non-matching request URL', async ({
9397
}) => {
9498
await loadExample(require.resolve('./uri.mocks.ts'))
9599

96-
const res = await page.evaluate(() =>
100+
const response = await page.evaluate(() =>
97101
fetch('https://test.mswjs.io/users/def-456').catch(() => null),
98102
)
99103

100-
expect(res).toBeNull()
104+
expect(response).toBeNull()
101105
})
102106

103107
test('matches a RegExp against a matching request URL', async ({
@@ -106,11 +110,11 @@ test('matches a RegExp against a matching request URL', async ({
106110
}) => {
107111
await loadExample(require.resolve('./uri.mocks.ts'))
108112

109-
const res = await fetch('https://mswjs.google.com/path')
113+
const response = await fetch('https://mswjs.google.com/path')
110114

111-
expect(res.status()).toEqual(200)
112-
expect(res.fromServiceWorker()).toBe(true)
113-
expect(await res.json()).toEqual({
115+
expect(response.status()).toEqual(200)
116+
expect(response.fromServiceWorker()).toBe(true)
117+
await expect(response.json()).resolves.toEqual({
114118
mocked: true,
115119
})
116120
})
@@ -122,11 +126,11 @@ test('does not match a RegExp against a non-matching request URL', async ({
122126
}) => {
123127
await loadExample(require.resolve('./uri.mocks.ts'))
124128

125-
const res = await page.evaluate(() =>
129+
const response = await page.evaluate(() =>
126130
fetch('https://mswjs.google.com/other').catch(() => null),
127131
)
128132

129-
expect(res).toBeNull()
133+
expect(response).toBeNull()
130134
})
131135

132136
test('supports escaped parentheses in the request URL', async ({
@@ -135,11 +139,26 @@ test('supports escaped parentheses in the request URL', async ({
135139
}) => {
136140
await loadExample(require.resolve('./uri.mocks.ts'))
137141

138-
const res = await fetch(`/resource('id')`)
142+
const response = await fetch(`/resource('id')`)
143+
144+
expect(response.status()).toEqual(200)
145+
expect(response.fromServiceWorker()).toBe(true)
146+
await expect(response.json()).resolves.toEqual({
147+
mocked: true,
148+
})
149+
})
150+
151+
test('matches a relative URL starting with search parameters', async ({
152+
loadExample,
153+
fetch,
154+
}) => {
155+
await loadExample(require.resolve('./uri.mocks.ts'))
156+
157+
const response = await fetch('?resourceId=abc-123')
139158

140-
expect(res.status()).toEqual(200)
141-
expect(res.fromServiceWorker()).toBe(true)
142-
expect(await res.json()).toEqual({
159+
expect(response.status()).toEqual(200)
160+
expect(response.fromServiceWorker()).toBe(true)
161+
await expect(response.json()).resolves.toEqual({
143162
mocked: true,
144163
})
145164
})

0 commit comments

Comments
 (0)