-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathurlEncoding.spec.ts
165 lines (150 loc) · 5.8 KB
/
urlEncoding.spec.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import { createRouter as newRouter } from '../src/router'
import { components } from './utils'
import { RouteRecordRaw } from '../src/types'
import { createMemoryHistory } from '../src'
import * as encoding from '../src/encoding'
jest.mock('../src/encoding')
const routes: RouteRecordRaw[] = [
{ path: '/', name: 'home', component: components.Home },
{ path: '/%25', name: 'percent', component: components.Home },
{ path: '/to-p/:p', redirect: to => `/p/${to.params.p}` },
{ path: '/p/:p', component: components.Bar, name: 'params' },
{ path: '/p/:p+', component: components.Bar, name: 'repeat' },
{ path: '/optional/:a/:b?', component: components.Bar, name: 'optional' },
]
function createRouter() {
const history = createMemoryHistory()
const router = newRouter({ history, routes })
return router
}
describe('URL Encoding', () => {
beforeEach(() => {
// mock all encoding functions
for (const key in encoding) {
// @ts-expect-error
const value = encoding[key]
// @ts-expect-error
if (typeof value === 'function') encoding[key] = jest.fn((v: string) => v)
// @ts-expect-error
else if (key === 'PLUS_RE') encoding[key] = /\+/g
}
})
it('calls encodeParam with params object', async () => {
const router = createRouter()
await router.push({ name: 'params', params: { p: 'foo' } })
expect(encoding.encodeParam).toHaveBeenCalledTimes(1)
expect(encoding.encodeParam).toHaveBeenCalledWith('foo')
})
it('calls encodeParam with relative location', async () => {
const router = createRouter()
await router.push('/p/bar')
await router.push({ params: { p: 'foo' } })
expect(encoding.encodeParam).toHaveBeenCalledTimes(2)
expect(encoding.encodeParam).toHaveBeenCalledWith('bar')
expect(encoding.encodeParam).toHaveBeenCalledWith('foo')
})
it('calls encodeParam with params object with arrays', async () => {
const router = createRouter()
await router.push({ name: 'repeat', params: { p: ['foo', 'bar'] } })
expect(encoding.encodeParam).toHaveBeenCalledTimes(2)
expect(encoding.encodeParam).toHaveBeenNthCalledWith(1, 'foo', 0, [
'foo',
'bar',
])
expect(encoding.encodeParam).toHaveBeenNthCalledWith(2, 'bar', 1, [
'foo',
'bar',
])
})
it('calls decode with a path', async () => {
const router = createRouter()
await router.push('/p/foo')
// one extra time for hash
expect(encoding.decode).toHaveBeenCalledTimes(2)
expect(encoding.decode).toHaveBeenNthCalledWith(1, 'foo')
})
it('calls decode with a path with repeatable params', async () => {
const router = createRouter()
await router.push('/p/foo/bar')
// one extra time for hash
expect(encoding.decode).toHaveBeenCalledTimes(3)
expect(encoding.decode).toHaveBeenNthCalledWith(1, 'foo', 0, ['foo', 'bar'])
expect(encoding.decode).toHaveBeenNthCalledWith(2, 'bar', 1, ['foo', 'bar'])
})
it('decodes values in params', async () => {
// @ts-expect-error: override to make the difference
encoding.decode = () => 'd'
// @ts-expect-error
encoding.encodeParam = () => 'e'
const router = createRouter()
await router.push({ name: 'optional', params: { a: 'a%' } })
await router.push({ params: { b: 'b%' } })
expect(router.currentRoute.value).toMatchObject({
fullPath: '/optional/e/e',
params: { b: 'd', a: 'd' },
})
})
it('calls encodeQueryProperty with query', async () => {
const router = createRouter()
await router.push({ name: 'home', query: { p: 'foo' } })
expect(encoding.encodeQueryValue).toHaveBeenCalledTimes(1)
expect(encoding.encodeQueryKey).toHaveBeenCalledTimes(1)
expect(encoding.encodeQueryKey).toHaveBeenNthCalledWith(1, 'p')
expect(encoding.encodeQueryValue).toHaveBeenNthCalledWith(1, 'foo')
})
it('calls decode with query', async () => {
const router = createRouter()
await router.push('/?p=foo')
// one extra time for hash
expect(encoding.decode).toHaveBeenCalledTimes(3)
expect(encoding.decode).toHaveBeenNthCalledWith(1, 'p')
expect(encoding.decode).toHaveBeenNthCalledWith(2, 'foo')
})
it('calls encodeQueryProperty with arrays in query', async () => {
const router = createRouter()
await router.push({ name: 'home', query: { p: ['foo', 'bar'] } })
expect(encoding.encodeQueryValue).toHaveBeenCalledTimes(2)
expect(encoding.encodeQueryKey).toHaveBeenCalledTimes(1)
expect(encoding.encodeQueryKey).toHaveBeenNthCalledWith(1, 'p')
expect(encoding.encodeQueryValue).toHaveBeenNthCalledWith(1, 'foo')
expect(encoding.encodeQueryValue).toHaveBeenNthCalledWith(2, 'bar')
})
it('keeps decoded values in query', async () => {
// @ts-expect-error: override to make the difference
encoding.decode = () => 'd'
// @ts-expect-error
encoding.encodeQueryValue = () => 'ev'
// @ts-expect-error
encoding.encodeQueryKey = () => 'ek'
const router = createRouter()
await router.push({ name: 'home', query: { p: '%' } })
expect(router.currentRoute.value).toMatchObject({
fullPath: '/?ek=ev',
query: { p: '%' },
})
})
it('keeps decoded values in hash', async () => {
// @ts-expect-error: override to make the difference
encoding.decode = () => 'd'
// @ts-expect-error
encoding.encodeHash = () => '#e'
const router = createRouter()
await router.push({ name: 'home', hash: '#%' })
expect(router.currentRoute.value).toMatchObject({
fullPath: '/#e',
hash: '#%',
})
})
it('decodes hash', async () => {
// @ts-expect-error: override to make the difference
encoding.decode = () => '#d'
// @ts-expect-error
encoding.encodeHash = () => '#e'
const router = createRouter()
await router.push('#%20')
expect(router.currentRoute.value).toMatchObject({
fullPath: '/#%20',
hash: '#d',
})
})
})