未验证 提交 ac5b2acd 编写于 作者: J Joe Haddad 提交者: GitHub

Fix dynamic route encoding for NextLinks (#14281)

上级 c9bc101d
...@@ -90,7 +90,7 @@ ...@@ -90,7 +90,7 @@
"loader-utils": "2.0.0", "loader-utils": "2.0.0",
"mini-css-extract-plugin": "0.8.0", "mini-css-extract-plugin": "0.8.0",
"mkdirp": "0.5.3", "mkdirp": "0.5.3",
"native-url": "0.3.3", "native-url": "0.3.4",
"neo-async": "2.6.1", "neo-async": "2.6.1",
"pnp-webpack-plugin": "1.6.4", "pnp-webpack-plugin": "1.6.4",
"postcss": "7.0.29", "postcss": "7.0.29",
......
import Link from 'next/link'
const Home = () => (
<div>
<Link href="/single/[slug]" as={encodeURI('/single/hello world ')}>
<a id="single-spaces">Single: Spaces</a>
</Link>
<br />
<Link href="/single/[slug]" as={encodeURI('/single/hello%world')}>
<a id="single-percent">Single: Percent</a>
</Link>
<br />
<Link
href="/single/[slug]"
as={`/single/hello${encodeURIComponent('/')}world`}
>
<a id="single-slash">Single: Forward Slash</a>
</Link>
<br />
<Link
href="/single/[slug]"
as={`/single/hello${encodeURIComponent('"')}world`}
>
<a id="single-double-quote">Single: "</a>
</Link>
<br />
<Link
href="/single/[slug]"
as={`/single/hello${encodeURIComponent(':')}world`}
>
<a id="single-colon">Single: :</a>
</Link>
</div>
)
export default Home
export function getServerSideProps({ params: { slug } }) {
return { props: { slug } }
}
export default function Single(props) {
return <pre id="query-content">{JSON.stringify(props)}</pre>
}
/* eslint-env jest */
import { findPort, killApp, launchApp, waitFor, check } from 'next-test-utils'
import webdriver from 'next-webdriver'
import { join } from 'path'
jest.setTimeout(1000 * 60 * 2)
const appDir = join(__dirname, '..')
let appPort
let app
describe('Link Component with Encoding', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort)
})
afterAll(() => killApp(app))
describe('spaces', () => {
it('should have correct query on SSR', async () => {
const browser = await webdriver(
appPort,
encodeURI('/single/hello world ')
)
try {
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello world \\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on Router#push', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.eval(
`window.next.router.push(
{ pathname: '/single/[slug]' },
{ pathname: encodeURI('/single/hello world ') }
)`
)
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello world \\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on simple client-side <Link>', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.elementByCss('#single-spaces').click()
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello world \\"}"`)
} finally {
await browser.close()
}
})
})
describe('percent', () => {
it('should have correct query on SSR', async () => {
const browser = await webdriver(appPort, encodeURI('/single/hello%world'))
try {
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello%world\\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on Router#push', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.eval(
`window.next.router.push(
{ pathname: '/single/[slug]' },
{ pathname: encodeURI('/single/hello%world') }
)`
)
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello%world\\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on simple client-side <Link>', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.elementByCss('#single-percent').click()
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello%world\\"}"`)
} finally {
await browser.close()
}
})
})
describe('forward slash', () => {
it('should have correct query on SSR', async () => {
const browser = await webdriver(
appPort,
`/single/hello${encodeURIComponent('/')}world`
)
try {
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello/world\\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on Router#push', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.eval(
`window.next.router.push(
{ pathname: '/single/[slug]' },
{ pathname: '/single/hello${encodeURIComponent('/')}world' }
)`
)
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello/world\\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on simple client-side <Link>', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.elementByCss('#single-slash').click()
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello/world\\"}"`)
} finally {
await browser.close()
}
})
})
describe('double quote', () => {
it('should have correct query on SSR', async () => {
const browser = await webdriver(
appPort,
`/single/hello${encodeURIComponent('"')}world`
)
try {
const text = await browser.elementByCss('#query-content').text()
expect(JSON.parse(text)).toMatchInlineSnapshot(`
Object {
"slug": "hello\\"world",
}
`)
} finally {
await browser.close()
}
})
it('should have correct query on Router#push', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.eval(
`window.next.router.push(
{ pathname: '/single/[slug]' },
{ pathname: '/single/hello${encodeURIComponent('"')}world' }
)`
)
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(JSON.parse(text)).toMatchInlineSnapshot(`
Object {
"slug": "hello\\"world",
}
`)
} finally {
await browser.close()
}
})
it('should have correct query on simple client-side <Link>', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.elementByCss('#single-double-quote').click()
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(JSON.parse(text)).toMatchInlineSnapshot(`
Object {
"slug": "hello\\"world",
}
`)
} finally {
await browser.close()
}
})
})
describe('colon', () => {
it('should have correct query on SSR', async () => {
const browser = await webdriver(
appPort,
`/single/hello${encodeURIComponent(':')}world`
)
try {
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello:world\\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on Router#push', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.eval(
`window.next.router.push(
{ pathname: '/single/[slug]' },
{ pathname: '/single/hello${encodeURIComponent(':')}world' }
)`
)
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello:world\\"}"`)
} finally {
await browser.close()
}
})
it('should have correct query on simple client-side <Link>', async () => {
const browser = await webdriver(appPort, '/')
try {
await waitFor(2000)
await browser.elementByCss('#single-colon').click()
await check(() => browser.hasElementByCssSelector('#query-content'), {
test(val) {
return Boolean(val)
},
})
const text = await browser.elementByCss('#query-content').text()
expect(text).toMatchInlineSnapshot(`"{\\"slug\\":\\"hello:world\\"}"`)
} finally {
await browser.close()
}
})
})
})
...@@ -10648,10 +10648,10 @@ native-or-bluebird@^1.2.0: ...@@ -10648,10 +10648,10 @@ native-or-bluebird@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/native-or-bluebird/-/native-or-bluebird-1.2.0.tgz#39c47bfd7825d1fb9ffad32210ae25daadf101c9" resolved "https://registry.yarnpkg.com/native-or-bluebird/-/native-or-bluebird-1.2.0.tgz#39c47bfd7825d1fb9ffad32210ae25daadf101c9"
native-url@0.3.3: native-url@0.3.4:
version "0.3.3" version "0.3.4"
resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.3.tgz#09300f35416a49f79f6f8ab9e3c05c53c2873666" resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8"
integrity sha512-EEHLiNEIgcTjctwlREZjUT1vdMlrmug+fr0sQ3hoP9+cO3cyhd5fJ0GTnINcnv9LtXL+NdovWNUMDIfW98l2eA== integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==
dependencies: dependencies:
querystring "^0.2.0" querystring "^0.2.0"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册