mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
Fixes: #94821, #92787, #93104 Using `Object.fromEntries` on URLSearchParams, drops repeated keys. ```js const s = '?foo=bar&foo=baz' Object.fromEntries(new URLSearchParams(s)) // { foo: 'baz' } ``` There's already a function, `urlSearchParamsToParsedUrlQuery`, which handles this case. https://github.com/vercel/next.js/blob/40296fe53f40ffe6a0e2184879bd5e294d271ce4/packages/next/src/client/route-params.ts#L235 ```js urlSearchParamsToParsedUrlQuery(new URLSearchParams(s)) // { foo: ['bar', 'baz'] } ``` - [x] The e2e off one of the issue reports, I'll try to simplify it.
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
import { retry } from 'next-test-utils'
|
|
|
|
// Regression test for multi-value (repeated key) search param transitions.
|
|
//
|
|
// Reproductions:
|
|
// - https://github.com/vercel/next.js/issues/94821 (next/form submit)
|
|
// - https://github.com/vercel/next.js/issues/92787 (<Link> navigation)
|
|
// - https://github.com/vercel/next.js/issues/93104 (router.replace)
|
|
//
|
|
// The client built the page segment cache key with
|
|
// `Object.fromEntries(new URLSearchParams(search))`, which only keeps the
|
|
// LAST value of a repeated key. So `?foo=bar&foo=baz` and `?foo=baz`
|
|
// collapsed to the same key, the multi -> single transition was treated as a
|
|
// cache hit, and the page never re-rendered with the new search params.
|
|
describe('multi-value-search-params-stale', () => {
|
|
const { next } = nextTestSetup({
|
|
files: __dirname,
|
|
})
|
|
|
|
it('re-renders when a repeated search param goes from multiple values to one', async () => {
|
|
const browser = await next.browser('/')
|
|
|
|
async function expectParams(expected: unknown) {
|
|
await retry(async () => {
|
|
const text = await browser.elementById('search-params').text()
|
|
expect(JSON.parse(text)).toEqual(expected)
|
|
})
|
|
}
|
|
|
|
await expectParams({})
|
|
|
|
await browser.elementById('to-bar').click()
|
|
await expectParams({ foo: 'bar' })
|
|
|
|
await browser.elementById('to-bar-baz').click()
|
|
await expectParams({ foo: ['bar', 'baz'] })
|
|
|
|
// The buggy transition: multiple values -> a single value.
|
|
await browser.elementById('to-baz').click()
|
|
await expectParams({ foo: 'baz' })
|
|
expect(new URL(await browser.url()).search).toBe('?foo=baz')
|
|
})
|
|
})
|