Skip to content

Commit 3a0cfa9

Browse files
authored
test(solid-start): add missing custom-basepath tests (#5641)
1 parent 3b091d0 commit 3a0cfa9

File tree

6 files changed

+158
-3
lines changed

6 files changed

+158
-3
lines changed

e2e/solid-start/custom-basepath/src/routeTree.gen.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
import { Route as rootRouteImport } from './routes/__root'
1212
import { Route as UsersRouteImport } from './routes/users'
1313
import { Route as PostsRouteImport } from './routes/posts'
14+
import { Route as LogoutRouteImport } from './routes/logout'
1415
import { Route as DeferredRouteImport } from './routes/deferred'
1516
import { Route as IndexRouteImport } from './routes/index'
1617
import { Route as UsersIndexRouteImport } from './routes/users.index'
18+
import { Route as RedirectIndexRouteImport } from './routes/redirect.index'
1719
import { Route as PostsIndexRouteImport } from './routes/posts.index'
1820
import { Route as UsersUserIdRouteImport } from './routes/users.$userId'
21+
import { Route as RedirectThrowItRouteImport } from './routes/redirect.throw-it'
1922
import { Route as PostsPostIdRouteImport } from './routes/posts.$postId'
2023
import { Route as ApiUsersRouteImport } from './routes/api/users'
2124
import { Route as PostsPostIdDeepRouteImport } from './routes/posts_.$postId.deep'
@@ -31,6 +34,11 @@ const PostsRoute = PostsRouteImport.update({
3134
path: '/posts',
3235
getParentRoute: () => rootRouteImport,
3336
} as any)
37+
const LogoutRoute = LogoutRouteImport.update({
38+
id: '/logout',
39+
path: '/logout',
40+
getParentRoute: () => rootRouteImport,
41+
} as any)
3442
const DeferredRoute = DeferredRouteImport.update({
3543
id: '/deferred',
3644
path: '/deferred',
@@ -46,6 +54,11 @@ const UsersIndexRoute = UsersIndexRouteImport.update({
4654
path: '/',
4755
getParentRoute: () => UsersRoute,
4856
} as any)
57+
const RedirectIndexRoute = RedirectIndexRouteImport.update({
58+
id: '/redirect/',
59+
path: '/redirect/',
60+
getParentRoute: () => rootRouteImport,
61+
} as any)
4962
const PostsIndexRoute = PostsIndexRouteImport.update({
5063
id: '/',
5164
path: '/',
@@ -56,6 +69,11 @@ const UsersUserIdRoute = UsersUserIdRouteImport.update({
5669
path: '/$userId',
5770
getParentRoute: () => UsersRoute,
5871
} as any)
72+
const RedirectThrowItRoute = RedirectThrowItRouteImport.update({
73+
id: '/redirect/throw-it',
74+
path: '/redirect/throw-it',
75+
getParentRoute: () => rootRouteImport,
76+
} as any)
5977
const PostsPostIdRoute = PostsPostIdRouteImport.update({
6078
id: '/$postId',
6179
path: '/$postId',
@@ -80,23 +98,29 @@ const ApiUsersUserIdRoute = ApiUsersUserIdRouteImport.update({
8098
export interface FileRoutesByFullPath {
8199
'/': typeof IndexRoute
82100
'/deferred': typeof DeferredRoute
101+
'/logout': typeof LogoutRoute
83102
'/posts': typeof PostsRouteWithChildren
84103
'/users': typeof UsersRouteWithChildren
85104
'/api/users': typeof ApiUsersRouteWithChildren
86105
'/posts/$postId': typeof PostsPostIdRoute
106+
'/redirect/throw-it': typeof RedirectThrowItRoute
87107
'/users/$userId': typeof UsersUserIdRoute
88108
'/posts/': typeof PostsIndexRoute
109+
'/redirect': typeof RedirectIndexRoute
89110
'/users/': typeof UsersIndexRoute
90111
'/api/users/$userId': typeof ApiUsersUserIdRoute
91112
'/posts/$postId/deep': typeof PostsPostIdDeepRoute
92113
}
93114
export interface FileRoutesByTo {
94115
'/': typeof IndexRoute
95116
'/deferred': typeof DeferredRoute
117+
'/logout': typeof LogoutRoute
96118
'/api/users': typeof ApiUsersRouteWithChildren
97119
'/posts/$postId': typeof PostsPostIdRoute
120+
'/redirect/throw-it': typeof RedirectThrowItRoute
98121
'/users/$userId': typeof UsersUserIdRoute
99122
'/posts': typeof PostsIndexRoute
123+
'/redirect': typeof RedirectIndexRoute
100124
'/users': typeof UsersIndexRoute
101125
'/api/users/$userId': typeof ApiUsersUserIdRoute
102126
'/posts/$postId/deep': typeof PostsPostIdDeepRoute
@@ -105,12 +129,15 @@ export interface FileRoutesById {
105129
__root__: typeof rootRouteImport
106130
'/': typeof IndexRoute
107131
'/deferred': typeof DeferredRoute
132+
'/logout': typeof LogoutRoute
108133
'/posts': typeof PostsRouteWithChildren
109134
'/users': typeof UsersRouteWithChildren
110135
'/api/users': typeof ApiUsersRouteWithChildren
111136
'/posts/$postId': typeof PostsPostIdRoute
137+
'/redirect/throw-it': typeof RedirectThrowItRoute
112138
'/users/$userId': typeof UsersUserIdRoute
113139
'/posts/': typeof PostsIndexRoute
140+
'/redirect/': typeof RedirectIndexRoute
114141
'/users/': typeof UsersIndexRoute
115142
'/api/users/$userId': typeof ApiUsersUserIdRoute
116143
'/posts_/$postId/deep': typeof PostsPostIdDeepRoute
@@ -120,36 +147,45 @@ export interface FileRouteTypes {
120147
fullPaths:
121148
| '/'
122149
| '/deferred'
150+
| '/logout'
123151
| '/posts'
124152
| '/users'
125153
| '/api/users'
126154
| '/posts/$postId'
155+
| '/redirect/throw-it'
127156
| '/users/$userId'
128157
| '/posts/'
158+
| '/redirect'
129159
| '/users/'
130160
| '/api/users/$userId'
131161
| '/posts/$postId/deep'
132162
fileRoutesByTo: FileRoutesByTo
133163
to:
134164
| '/'
135165
| '/deferred'
166+
| '/logout'
136167
| '/api/users'
137168
| '/posts/$postId'
169+
| '/redirect/throw-it'
138170
| '/users/$userId'
139171
| '/posts'
172+
| '/redirect'
140173
| '/users'
141174
| '/api/users/$userId'
142175
| '/posts/$postId/deep'
143176
id:
144177
| '__root__'
145178
| '/'
146179
| '/deferred'
180+
| '/logout'
147181
| '/posts'
148182
| '/users'
149183
| '/api/users'
150184
| '/posts/$postId'
185+
| '/redirect/throw-it'
151186
| '/users/$userId'
152187
| '/posts/'
188+
| '/redirect/'
153189
| '/users/'
154190
| '/api/users/$userId'
155191
| '/posts_/$postId/deep'
@@ -158,9 +194,12 @@ export interface FileRouteTypes {
158194
export interface RootRouteChildren {
159195
IndexRoute: typeof IndexRoute
160196
DeferredRoute: typeof DeferredRoute
197+
LogoutRoute: typeof LogoutRoute
161198
PostsRoute: typeof PostsRouteWithChildren
162199
UsersRoute: typeof UsersRouteWithChildren
163200
ApiUsersRoute: typeof ApiUsersRouteWithChildren
201+
RedirectThrowItRoute: typeof RedirectThrowItRoute
202+
RedirectIndexRoute: typeof RedirectIndexRoute
164203
PostsPostIdDeepRoute: typeof PostsPostIdDeepRoute
165204
}
166205

@@ -180,6 +219,13 @@ declare module '@tanstack/solid-router' {
180219
preLoaderRoute: typeof PostsRouteImport
181220
parentRoute: typeof rootRouteImport
182221
}
222+
'/logout': {
223+
id: '/logout'
224+
path: '/logout'
225+
fullPath: '/logout'
226+
preLoaderRoute: typeof LogoutRouteImport
227+
parentRoute: typeof rootRouteImport
228+
}
183229
'/deferred': {
184230
id: '/deferred'
185231
path: '/deferred'
@@ -201,6 +247,13 @@ declare module '@tanstack/solid-router' {
201247
preLoaderRoute: typeof UsersIndexRouteImport
202248
parentRoute: typeof UsersRoute
203249
}
250+
'/redirect/': {
251+
id: '/redirect/'
252+
path: '/redirect'
253+
fullPath: '/redirect'
254+
preLoaderRoute: typeof RedirectIndexRouteImport
255+
parentRoute: typeof rootRouteImport
256+
}
204257
'/posts/': {
205258
id: '/posts/'
206259
path: '/'
@@ -215,6 +268,13 @@ declare module '@tanstack/solid-router' {
215268
preLoaderRoute: typeof UsersUserIdRouteImport
216269
parentRoute: typeof UsersRoute
217270
}
271+
'/redirect/throw-it': {
272+
id: '/redirect/throw-it'
273+
path: '/redirect/throw-it'
274+
fullPath: '/redirect/throw-it'
275+
preLoaderRoute: typeof RedirectThrowItRouteImport
276+
parentRoute: typeof rootRouteImport
277+
}
218278
'/posts/$postId': {
219279
id: '/posts/$postId'
220280
path: '/$postId'
@@ -285,9 +345,12 @@ const ApiUsersRouteWithChildren = ApiUsersRoute._addFileChildren(
285345
const rootRouteChildren: RootRouteChildren = {
286346
IndexRoute: IndexRoute,
287347
DeferredRoute: DeferredRoute,
348+
LogoutRoute: LogoutRoute,
288349
PostsRoute: PostsRouteWithChildren,
289350
UsersRoute: UsersRouteWithChildren,
290351
ApiUsersRoute: ApiUsersRouteWithChildren,
352+
RedirectThrowItRoute: RedirectThrowItRoute,
353+
RedirectIndexRoute: RedirectIndexRoute,
291354
PostsPostIdDeepRoute: PostsPostIdDeepRoute,
292355
}
293356
export const routeTree = rootRouteImport
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { createFileRoute, redirect } from '@tanstack/solid-router'
2+
import { createServerFn } from '@tanstack/solid-start'
3+
4+
const logoutFn = createServerFn({
5+
method: 'POST',
6+
}).handler(async () => {
7+
// do logout stuff here
8+
throw redirect({
9+
to: '/',
10+
})
11+
})
12+
13+
export const Route = createFileRoute('/logout')({
14+
component: Home,
15+
})
16+
17+
function Home() {
18+
return (
19+
<div class="p-2">
20+
<h3>Logout Page</h3>
21+
<p>
22+
This form tests that server function URLs correctly include the app's
23+
basepath. The form action should be '/custom/basepath/_serverFn/...' not
24+
just '/_serverFn/...'
25+
</p>
26+
<form action={logoutFn.url} method="post">
27+
<input type="hidden" name="csrfToken" value="123abc" />
28+
<button type="submit">Logout</button>
29+
</form>
30+
</div>
31+
)
32+
}

e2e/solid-start/custom-basepath/src/routes/posts.$postId.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { ErrorComponent, Link, createFileRoute } from '@tanstack/solid-router'
2-
import type { ErrorComponentProps } from '@tanstack/solid-router'
1+
import { Link, createFileRoute } from '@tanstack/solid-router'
32

43
import { fetchPost } from '~/utils/posts'
54
import { NotFound } from '~/components/NotFound'
@@ -18,7 +17,7 @@ function PostComponent() {
1817
const post = Route.useLoaderData()
1918

2019
return (
21-
<div class="space-y-2">
20+
<div class="space-y-2" data-testid="post-view">
2221
<h4 class="text-xl font-bold underline">{post().title}</h4>
2322
<div class="text-sm">{post().body}</div>
2423
<Link
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Link, createFileRoute } from '@tanstack/solid-router'
2+
3+
export const Route = createFileRoute('/redirect/')({
4+
component: RouteComponent,
5+
})
6+
7+
function RouteComponent() {
8+
return (
9+
<div class="p-2 flex gap-2">
10+
<Link to="/redirect/throw-it">
11+
<div data-testid="link-to-throw-it">Throw It</div>
12+
</Link>
13+
</div>
14+
)
15+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { createFileRoute, redirect } from '@tanstack/solid-router'
2+
3+
export const Route = createFileRoute('/redirect/throw-it')({
4+
beforeLoad: () => {
5+
throw redirect({
6+
to: '/posts/$postId',
7+
params: { postId: '1' },
8+
})
9+
},
10+
})

e2e/solid-start/custom-basepath/tests/navigation.spec.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,39 @@ test('Should change title on client side navigation', async ({ page }) => {
3232

3333
await expect(page).toHaveTitle('Posts page')
3434
})
35+
36+
test('Server function URLs correctly include app basepath', async ({
37+
page,
38+
}) => {
39+
await page.goto('/logout')
40+
41+
const form = page.locator('form')
42+
const actionUrl = await form.getAttribute('action')
43+
44+
expect(actionUrl).toMatch(/^\/custom\/basepath\/_serverFn\//)
45+
})
46+
47+
test('client-side redirect', async ({ page, baseURL }) => {
48+
await page.goto('/redirect')
49+
await page.getByTestId('link-to-throw-it').click()
50+
await page.waitForLoadState('networkidle')
51+
52+
expect(await page.getByTestId('post-view').isVisible()).toBe(true)
53+
expect(page.url()).toBe(`${baseURL}/posts/1`)
54+
})
55+
56+
test('server-side redirect', async ({ page, baseURL }) => {
57+
await page.goto('/redirect/throw-it')
58+
await page.waitForLoadState('networkidle')
59+
60+
expect(await page.getByTestId('post-view').isVisible()).toBe(true)
61+
expect(page.url()).toBe(`${baseURL}/posts/1`)
62+
63+
// do not follow redirects since we want to test the Location header
64+
await page.request
65+
.get('/redirect/throw-it', { maxRedirects: 0 })
66+
.then((res) => {
67+
const headers = new Headers(res.headers())
68+
expect(headers.get('location')).toBe('/custom/basepath/posts/1')
69+
})
70+
})

0 commit comments

Comments
 (0)