From cef0956855473ed2d99ded55121ee139f16142d1 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 20 Jul 2022 16:59:48 -0500 Subject: [PATCH 1/2] Ensure mixed query/hash values are handled correctly --- .../shared/lib/router/utils/parse-path.ts | 12 +++---- .../integration/production/test/index.test.js | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/next/shared/lib/router/utils/parse-path.ts b/packages/next/shared/lib/router/utils/parse-path.ts index 399067291956..78c0e28bca95 100644 --- a/packages/next/shared/lib/router/utils/parse-path.ts +++ b/packages/next/shared/lib/router/utils/parse-path.ts @@ -6,14 +6,14 @@ export function parsePath(path: string) { const hashIndex = path.indexOf('#') const queryIndex = path.indexOf('?') + const hasQuery = queryIndex > -1 && queryIndex < hashIndex - if (queryIndex > -1 || hashIndex > -1) { + if (hasQuery || hashIndex > -1) { return { - pathname: path.substring(0, queryIndex > -1 ? queryIndex : hashIndex), - query: - queryIndex > -1 - ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : undefined) - : '', + pathname: path.substring(0, hasQuery ? queryIndex : hashIndex), + query: hasQuery + ? path.substring(queryIndex, hashIndex > -1 ? hashIndex : undefined) + : '', hash: hashIndex > -1 ? path.slice(hashIndex) : '', } } diff --git a/test/integration/production/test/index.test.js b/test/integration/production/test/index.test.js index 6793805ac45d..99c068df8862 100644 --- a/test/integration/production/test/index.test.js +++ b/test/integration/production/test/index.test.js @@ -88,6 +88,37 @@ describe('Production Usage', () => { await browser.waitForElementByCss('.about-page') }) + it.each([ + { hash: '#hello?' }, + { hash: '#?' }, + { hash: '##' }, + { hash: '##?' }, + { hash: '##hello?' }, + { hash: '##hello' }, + { hash: '#hello?world' }, + { search: '?hello=world', hash: '#a', query: { hello: 'world' } }, + { search: '?hello', hash: '#a', query: { hello: '' } }, + { search: '?hello=', hash: '#a', query: { hello: '' } }, + ])( + 'should handle query/hash correctly during query updating $hash $search', + async ({ hash, search, query }) => { + const browser = await webdriver(appPort, `/${search || ''}${hash || ''}`) + + await check( + () => + browser.eval('window.next.router.isReady ? "ready" : "not ready"'), + 'ready' + ) + expect(await browser.eval('window.location.pathname')).toBe('/') + expect(await browser.eval('window.location.hash')).toBe(hash || '') + expect(await browser.eval('window.location.search')).toBe(search || '') + expect(await browser.eval('next.router.pathname')).toBe('/') + expect( + JSON.parse(await browser.eval('JSON.stringify(next.router.query)')) + ).toEqual(query || {}) + } + ) + it('should not show target deprecation warning', () => { expect(output).not.toContain( 'The `target` config is deprecated and will be removed in a future version' From 7bca38b91612dd1dddcf598afd9f45d861e1a965 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 20 Jul 2022 17:48:51 -0500 Subject: [PATCH 2/2] update check and more tests --- .../shared/lib/router/utils/parse-path.ts | 2 +- test/e2e/basepath.test.ts | 34 +++++++++++++++++++ test/lib/next-test-utils.js | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/next/shared/lib/router/utils/parse-path.ts b/packages/next/shared/lib/router/utils/parse-path.ts index 78c0e28bca95..76faccdf57b7 100644 --- a/packages/next/shared/lib/router/utils/parse-path.ts +++ b/packages/next/shared/lib/router/utils/parse-path.ts @@ -6,7 +6,7 @@ export function parsePath(path: string) { const hashIndex = path.indexOf('#') const queryIndex = path.indexOf('?') - const hasQuery = queryIndex > -1 && queryIndex < hashIndex + const hasQuery = queryIndex > -1 && (hashIndex < 0 || queryIndex < hashIndex) if (hasQuery || hashIndex > -1) { return { diff --git a/test/e2e/basepath.test.ts b/test/e2e/basepath.test.ts index 6d1b660548b6..7ffb321495c3 100644 --- a/test/e2e/basepath.test.ts +++ b/test/e2e/basepath.test.ts @@ -120,6 +120,40 @@ describe('basePath', () => { return } + it.each([ + { hash: '#hello?' }, + { hash: '#?' }, + { hash: '##' }, + { hash: '##?' }, + { hash: '##hello?' }, + { hash: '##hello' }, + { hash: '#hello?world' }, + { search: '?hello=world', hash: '#a', query: { hello: 'world' } }, + { search: '?hello', hash: '#a', query: { hello: '' } }, + { search: '?hello=', hash: '#a', query: { hello: '' } }, + ])( + 'should handle query/hash correctly during query updating $hash $search', + async ({ hash, search, query }) => { + const browser = await webdriver( + next.url, + `${basePath}${search || ''}${hash || ''}` + ) + + await check( + () => + browser.eval('window.next.router.isReady ? "ready" : "not ready"'), + 'ready' + ) + expect(await browser.eval('window.location.pathname')).toBe(basePath) + expect(await browser.eval('window.location.search')).toBe(search || '') + expect(await browser.eval('window.location.hash')).toBe(hash || '') + expect(await browser.eval('next.router.pathname')).toBe('/') + expect( + JSON.parse(await browser.eval('JSON.stringify(next.router.query)')) + ).toEqual(query || {}) + } + ) + it('should navigate back correctly to a dynamic route', async () => { const browser = await webdriver(next.url, `${basePath}`) diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index e239aa3704b2..1bcb877dac75 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -93,6 +93,7 @@ export function getFullUrl(appPortOrUrl, url, hostname) { const parsedUrl = new URL(fullUrl) const parsedPathQuery = new URL(url, fullUrl) + parsedUrl.hash = parsedPathQuery.hash parsedUrl.search = parsedPathQuery.search parsedUrl.pathname = parsedPathQuery.pathname