Skip to content

Commit 7aadc5a

Browse files
committed
test: Add test for dynamic segments
1 parent ce0192f commit 7aadc5a

File tree

30 files changed

+648
-74
lines changed

30 files changed

+648
-74
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { testDynamicSegments } from 'e2e-shared/specs/dynamic-segments.cy'
2+
3+
testDynamicSegments({
4+
path: '/app/dynamic-segments/dynamic/segment',
5+
expectedSegments: ['segment'],
6+
nextJsRouter: 'app'
7+
})
8+
9+
testDynamicSegments({
10+
path: '/pages/dynamic-segments/dynamic/segment',
11+
expectedSegments: ['segment'],
12+
nextJsRouter: 'pages'
13+
})
14+
15+
// Catch-all --
16+
17+
testDynamicSegments({
18+
path: '/app/dynamic-segments/catch-all/foo',
19+
expectedSegments: ['foo'],
20+
nextJsRouter: 'app'
21+
})
22+
23+
testDynamicSegments({
24+
path: '/pages/dynamic-segments/catch-all/foo',
25+
expectedSegments: ['foo'],
26+
nextJsRouter: 'pages'
27+
})
28+
29+
testDynamicSegments({
30+
path: '/app/dynamic-segments/catch-all/a/b/c',
31+
expectedSegments: ['a', 'b', 'c'],
32+
nextJsRouter: 'app'
33+
})
34+
35+
testDynamicSegments({
36+
path: '/pages/dynamic-segments/catch-all/a/b/c',
37+
expectedSegments: ['a', 'b', 'c'],
38+
nextJsRouter: 'pages'
39+
})
40+
41+
// Optional catch-all --
42+
43+
testDynamicSegments({
44+
path: '/app/dynamic-segments/optional-catch-all', // no segments
45+
expectedSegments: [],
46+
nextJsRouter: 'app'
47+
})
48+
49+
testDynamicSegments({
50+
path: '/pages/dynamic-segments/optional-catch-all', // no segments
51+
expectedSegments: [],
52+
nextJsRouter: 'pages'
53+
})
54+
55+
testDynamicSegments({
56+
path: '/app/dynamic-segments/optional-catch-all/foo',
57+
expectedSegments: ['foo'],
58+
nextJsRouter: 'app'
59+
})
60+
61+
testDynamicSegments({
62+
path: '/pages/dynamic-segments/optional-catch-all/foo',
63+
expectedSegments: ['foo'],
64+
nextJsRouter: 'pages'
65+
})
66+
67+
testDynamicSegments({
68+
path: '/app/dynamic-segments/optional-catch-all/a/b/c',
69+
expectedSegments: ['a', 'b', 'c'],
70+
nextJsRouter: 'app'
71+
})
72+
73+
testDynamicSegments({
74+
path: '/pages/dynamic-segments/optional-catch-all/a/b/c',
75+
expectedSegments: ['a', 'b', 'c'],
76+
nextJsRouter: 'pages'
77+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use client'
2+
3+
import { DisplaySegments } from 'e2e-shared/specs/dynamic-segments'
4+
import { useParams } from 'next/navigation'
5+
import { ReactNode } from 'react'
6+
7+
export function ClientSegment({ children }: { children?: ReactNode }) {
8+
const params = useParams()
9+
const segments = params?.segments as string[]
10+
return (
11+
<>
12+
{children}
13+
<DisplaySegments environment="client" segments={segments} />
14+
</>
15+
)
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Display } from 'e2e-shared/components/display'
2+
import { DisplaySegments, UrlControls } from 'e2e-shared/specs/dynamic-segments'
3+
import { createLoader, parseAsString, type SearchParams } from 'nuqs/server'
4+
import { Suspense } from 'react'
5+
import { ClientSegment } from './client'
6+
7+
type PageProps = {
8+
params: Promise<{ segments: string[] }>
9+
searchParams: Promise<SearchParams>
10+
}
11+
12+
const loadTest = createLoader({
13+
test: parseAsString
14+
})
15+
16+
export default async function DynamicPage(props: PageProps) {
17+
const searchParams = await props.searchParams
18+
const { segments } = await props.params
19+
const { test: serverState } = loadTest(searchParams)
20+
return (
21+
<>
22+
<Suspense>
23+
<UrlControls>
24+
<Display environment="server" state={serverState} />
25+
</UrlControls>
26+
</Suspense>
27+
<Suspense>
28+
<ClientSegment>
29+
<DisplaySegments environment="server" segments={segments} />
30+
</ClientSegment>
31+
</Suspense>
32+
</>
33+
)
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use client'
2+
3+
import { DisplaySegments } from 'e2e-shared/specs/dynamic-segments'
4+
import { useParams } from 'next/navigation'
5+
import { ReactNode } from 'react'
6+
7+
export function ClientSegment({ children }: { children?: ReactNode }) {
8+
const params = useParams()
9+
const segment = params?.segment as string
10+
return (
11+
<>
12+
{children}
13+
<DisplaySegments environment="client" segments={[segment]} />
14+
</>
15+
)
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Display } from 'e2e-shared/components/display'
2+
import { DisplaySegments, UrlControls } from 'e2e-shared/specs/dynamic-segments'
3+
import { createLoader, parseAsString, type SearchParams } from 'nuqs/server'
4+
import { Suspense } from 'react'
5+
import { ClientSegment } from './client'
6+
7+
type PageProps = {
8+
params: Promise<{ segment: string }>
9+
searchParams: Promise<SearchParams>
10+
}
11+
12+
const loadTest = createLoader({
13+
test: parseAsString
14+
})
15+
16+
export default async function DynamicPage(props: PageProps) {
17+
const searchParams = await props.searchParams
18+
const { segment } = await props.params
19+
const { test: serverState } = loadTest(searchParams)
20+
return (
21+
<>
22+
<Suspense>
23+
<UrlControls>
24+
<Display environment="server" state={serverState} />
25+
</UrlControls>
26+
</Suspense>
27+
<Suspense>
28+
<ClientSegment>
29+
<DisplaySegments environment="server" segments={[segment]} />
30+
</ClientSegment>
31+
</Suspense>
32+
</>
33+
)
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use client'
2+
3+
import { DisplaySegments } from 'e2e-shared/specs/dynamic-segments'
4+
import { useParams } from 'next/navigation'
5+
import { ReactNode } from 'react'
6+
7+
export function ClientSegment({ children }: { children?: ReactNode }) {
8+
const params = useParams()
9+
const segments = params?.segments as string[]
10+
return (
11+
<>
12+
{children}
13+
<DisplaySegments environment="client" segments={segments} />
14+
</>
15+
)
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Display } from 'e2e-shared/components/display'
2+
import { DisplaySegments, UrlControls } from 'e2e-shared/specs/dynamic-segments'
3+
import { createLoader, parseAsString, type SearchParams } from 'nuqs/server'
4+
import { Suspense } from 'react'
5+
import { ClientSegment } from './client'
6+
7+
type PageProps = {
8+
params: Promise<{ segments: string[] }>
9+
searchParams: Promise<SearchParams>
10+
}
11+
12+
const loadTest = createLoader({
13+
test: parseAsString
14+
})
15+
16+
export default async function DynamicPage(props: PageProps) {
17+
const searchParams = await props.searchParams
18+
const { segments } = await props.params
19+
const { test: serverState } = loadTest(searchParams)
20+
return (
21+
<>
22+
<Suspense>
23+
<UrlControls>
24+
<Display environment="server" state={serverState} />
25+
</UrlControls>
26+
</Suspense>
27+
<Suspense>
28+
<ClientSegment>
29+
<DisplaySegments environment="server" segments={segments} />
30+
</ClientSegment>
31+
</Suspense>
32+
</>
33+
)
34+
}

packages/e2e/next/src/app/app/(shared)/shallow/useQueryState/page.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { Display } from 'e2e-shared/components/display'
12
import { ShallowUseQueryState } from 'e2e-shared/specs/shallow'
2-
import { ShallowDisplay } from 'e2e-shared/specs/shallow-display'
33
import {
44
createSearchParamsCache,
55
parseAsString,
@@ -29,7 +29,7 @@ export default async function Page({ searchParams }: PageProps) {
2929
<Suspense>
3030
<ShallowUseQueryState />
3131
</Suspense>
32-
<ShallowDisplay environment="server" state={cache.get('state')} />
32+
<Display environment="server" state={cache.get('state')} />
3333
</>
3434
)
3535
}

packages/e2e/next/src/app/app/(shared)/shallow/useQueryStates/page.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { Display } from 'e2e-shared/components/display'
12
import { ShallowUseQueryStates } from 'e2e-shared/specs/shallow'
2-
import { ShallowDisplay } from 'e2e-shared/specs/shallow-display'
33
import {
44
createSearchParamsCache,
55
parseAsString,
@@ -29,7 +29,7 @@ export default async function Page({ searchParams }: PageProps) {
2929
<Suspense>
3030
<ShallowUseQueryStates />
3131
</Suspense>
32-
<ShallowDisplay environment="server" state={cache.get('state')} />
32+
<Display environment="server" state={cache.get('state')} />
3333
</>
3434
)
3535
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Display } from 'e2e-shared/components/display'
2+
import { DisplaySegments, UrlControls } from 'e2e-shared/specs/dynamic-segments'
3+
import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next'
4+
import { useRouter } from 'next/router'
5+
6+
type Props = {
7+
serverState: string | null
8+
serverSegments: string[]
9+
}
10+
11+
export default function Page({ serverState, serverSegments }: Props) {
12+
const router = useRouter()
13+
return (
14+
<>
15+
<UrlControls>
16+
<Display environment="server" state={serverState} />
17+
</UrlControls>
18+
<DisplaySegments environment="server" segments={serverSegments} />
19+
<DisplaySegments
20+
environment="client"
21+
segments={router.query.segments as string[]}
22+
/>
23+
</>
24+
)
25+
}
26+
27+
export function getServerSideProps(
28+
ctx: GetServerSidePropsContext
29+
): GetServerSidePropsResult<Props> {
30+
const serverState = (ctx.query.test as string) ?? null
31+
const serverSegments = ctx.params?.segments as string[]
32+
return {
33+
props: {
34+
serverState,
35+
serverSegments
36+
}
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Display } from 'e2e-shared/components/display'
2+
import { DisplaySegments, UrlControls } from 'e2e-shared/specs/dynamic-segments'
3+
import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next'
4+
import { useRouter } from 'next/router'
5+
6+
type Props = {
7+
serverState: string | null
8+
serverSegments: string[]
9+
}
10+
11+
export default function Page({ serverState, serverSegments }: Props) {
12+
const router = useRouter()
13+
return (
14+
<>
15+
<UrlControls>
16+
<Display environment="server" state={serverState} />
17+
</UrlControls>
18+
<DisplaySegments environment="server" segments={serverSegments} />
19+
<DisplaySegments
20+
environment="client"
21+
segments={[router.query.segment as string]}
22+
/>
23+
</>
24+
)
25+
}
26+
27+
export function getServerSideProps(
28+
ctx: GetServerSidePropsContext
29+
): GetServerSidePropsResult<Props> {
30+
const serverState = (ctx.query.test as string) ?? null
31+
const serverSegments = [ctx.params?.segment as string]
32+
return {
33+
props: {
34+
serverState,
35+
serverSegments
36+
}
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Display } from 'e2e-shared/components/display'
2+
import { DisplaySegments, UrlControls } from 'e2e-shared/specs/dynamic-segments'
3+
import type { GetServerSidePropsContext, GetServerSidePropsResult } from 'next'
4+
import { useRouter } from 'next/router'
5+
6+
type Props = {
7+
serverState: string | null
8+
serverSegments: string[] | null
9+
}
10+
11+
export default function Page({ serverState, serverSegments }: Props) {
12+
const router = useRouter()
13+
console.dir({ client: router.query.segments, server: serverSegments })
14+
return (
15+
<>
16+
<UrlControls>
17+
<Display environment="server" state={serverState} />
18+
</UrlControls>
19+
<DisplaySegments
20+
environment="server"
21+
segments={serverSegments ?? undefined}
22+
/>
23+
<DisplaySegments
24+
environment="client"
25+
segments={router.query.segments as string[]}
26+
/>
27+
</>
28+
)
29+
}
30+
31+
export function getServerSideProps(
32+
ctx: GetServerSidePropsContext
33+
): GetServerSidePropsResult<Props> {
34+
const serverState = (ctx.query.test as string) ?? null
35+
const serverSegments = (ctx.params?.segments as string[]) ?? null // Can't serialize undefined
36+
return {
37+
props: {
38+
serverState,
39+
serverSegments
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)