Skip to content

Commit 020660e

Browse files
authored
Convert locals tests to unit tests (#15519)
These test various scenarios where `Astro.locals` is used, such as when passed down from an adapter. Converted to unit tests and removed the fixture.
1 parent b2d547a commit 020660e

File tree

8 files changed

+252
-97
lines changed

8 files changed

+252
-97
lines changed

packages/astro/test/fixtures/ssr-locals/package.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

packages/astro/test/fixtures/ssr-locals/src/pages/404.astro

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/astro/test/fixtures/ssr-locals/src/pages/500.astro

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/astro/test/fixtures/ssr-locals/src/pages/api.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

packages/astro/test/fixtures/ssr-locals/src/pages/foo.astro

Lines changed: 0 additions & 4 deletions
This file was deleted.

packages/astro/test/fixtures/ssr-locals/src/pages/go-to-error-page.astro

Lines changed: 0 additions & 3 deletions
This file was deleted.

packages/astro/test/ssr-locals.test.js

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import assert from 'node:assert/strict';
2+
import { describe, it } from 'node:test';
3+
import { App } from '../../../dist/core/app/app.js';
4+
import { createComponent, render } from '../../../dist/runtime/server/index.js';
5+
6+
function createManifest({ routes, pageMap }) {
7+
const rootDir = new URL('file:///astro-test/');
8+
const buildDir = new URL('file:///astro-test/dist/');
9+
10+
return {
11+
adapterName: 'test-adapter',
12+
routes,
13+
site: undefined,
14+
base: '/',
15+
userAssetsBase: undefined,
16+
trailingSlash: 'ignore',
17+
buildFormat: 'directory',
18+
compressHTML: false,
19+
assetsPrefix: undefined,
20+
renderers: [],
21+
serverLike: true,
22+
clientDirectives: new Map(),
23+
entryModules: {},
24+
inlinedScripts: new Map(),
25+
assets: new Set(),
26+
componentMetadata: new Map(),
27+
pageModule: undefined,
28+
pageMap,
29+
serverIslandMappings: undefined,
30+
key: Promise.resolve(/** @type {CryptoKey} */ ({})),
31+
i18n: undefined,
32+
middleware: undefined,
33+
actions: undefined,
34+
sessionDriver: undefined,
35+
checkOrigin: false,
36+
allowedDomains: undefined,
37+
sessionConfig: undefined,
38+
cacheDir: rootDir,
39+
srcDir: rootDir,
40+
outDir: buildDir,
41+
rootDir,
42+
publicDir: rootDir,
43+
assetsDir: 'assets',
44+
buildClientDir: buildDir,
45+
buildServerDir: buildDir,
46+
csp: undefined,
47+
image: {},
48+
shouldInjectCspMetaTags: false,
49+
devToolbar: {
50+
enabled: false,
51+
latestAstroVersion: undefined,
52+
debugInfoOutput: undefined,
53+
placement: undefined,
54+
},
55+
internalFetchHeaders: undefined,
56+
logLevel: 'silent',
57+
};
58+
}
59+
60+
const fooRouteData = {
61+
route: '/foo',
62+
component: 'src/pages/foo.astro',
63+
params: [],
64+
pathname: '/foo',
65+
distURL: [],
66+
pattern: /^\/foo\/?$/,
67+
segments: [[{ content: 'foo', dynamic: false, spread: false }]],
68+
type: 'page',
69+
prerender: false,
70+
fallbackRoutes: [],
71+
isIndex: false,
72+
origin: 'project',
73+
};
74+
75+
const apiRouteData = {
76+
route: '/api',
77+
component: 'src/pages/api.js',
78+
params: [],
79+
pathname: '/api',
80+
distURL: [],
81+
pattern: /^\/api\/?$/,
82+
segments: [[{ content: 'api', dynamic: false, spread: false }]],
83+
type: 'endpoint',
84+
prerender: false,
85+
fallbackRoutes: [],
86+
isIndex: false,
87+
origin: 'project',
88+
};
89+
90+
const errorRouteData = {
91+
route: '/go-to-error-page',
92+
component: 'src/pages/go-to-error-page.astro',
93+
params: [],
94+
pathname: '/go-to-error-page',
95+
distURL: [],
96+
pattern: /^\/go-to-error-page\/?$/,
97+
segments: [[{ content: 'go-to-error-page', dynamic: false, spread: false }]],
98+
type: 'page',
99+
prerender: false,
100+
fallbackRoutes: [],
101+
isIndex: false,
102+
origin: 'project',
103+
};
104+
105+
const notFoundRouteData = {
106+
route: '/404',
107+
component: 'src/pages/404.astro',
108+
params: [],
109+
pathname: '/404',
110+
distURL: [],
111+
pattern: /^\/404\/?$/,
112+
segments: [[{ content: '404', dynamic: false, spread: false }]],
113+
type: 'page',
114+
prerender: false,
115+
fallbackRoutes: [],
116+
isIndex: false,
117+
origin: 'project',
118+
};
119+
120+
const internalErrorRouteData = {
121+
route: '/500',
122+
component: 'src/pages/500.astro',
123+
params: [],
124+
pathname: '/500',
125+
distURL: [],
126+
pattern: /^\/500\/?$/,
127+
segments: [[{ content: '500', dynamic: false, spread: false }]],
128+
type: 'page',
129+
prerender: false,
130+
fallbackRoutes: [],
131+
isIndex: false,
132+
origin: 'project',
133+
};
134+
135+
const fooPage = createComponent((result, props, slots) => {
136+
const Astro = result.createAstro(props, slots);
137+
return render`<h1 id="foo">${Astro.locals.foo}</h1>`;
138+
});
139+
140+
const notFoundPage = createComponent((result, props, slots) => {
141+
const Astro = result.createAstro(props, slots);
142+
return render`<h1 id="foo">${Astro.locals.foo}</h1>`;
143+
});
144+
145+
const internalErrorPage = createComponent((result, props, slots) => {
146+
const Astro = result.createAstro(props, slots);
147+
return render`<h1 id="foo">${Astro.locals.foo}</h1>`;
148+
});
149+
150+
const pageMap = new Map([
151+
[
152+
fooRouteData.component,
153+
async () => ({
154+
page: async () => ({
155+
default: fooPage,
156+
}),
157+
}),
158+
],
159+
[
160+
apiRouteData.component,
161+
async () => ({
162+
page: async () => ({
163+
GET: async ({ locals }) =>
164+
new Response(JSON.stringify({ ...locals }), {
165+
headers: {
166+
'Content-Type': 'application/json',
167+
},
168+
}),
169+
}),
170+
}),
171+
],
172+
[
173+
errorRouteData.component,
174+
async () => ({
175+
page: async () => ({
176+
default: createComponent(() => {
177+
throw new Error('boom');
178+
}),
179+
}),
180+
}),
181+
],
182+
[
183+
notFoundRouteData.component,
184+
async () => ({
185+
page: async () => ({
186+
default: notFoundPage,
187+
}),
188+
}),
189+
],
190+
[
191+
internalErrorRouteData.component,
192+
async () => ({
193+
page: async () => ({
194+
default: internalErrorPage,
195+
}),
196+
}),
197+
],
198+
]);
199+
200+
const app = new App(
201+
createManifest({
202+
routes: [
203+
{ routeData: fooRouteData },
204+
{ routeData: apiRouteData },
205+
{ routeData: errorRouteData },
206+
{ routeData: notFoundRouteData },
207+
{ routeData: internalErrorRouteData },
208+
],
209+
pageMap,
210+
}),
211+
);
212+
213+
describe('SSR Astro.locals from server', () => {
214+
it('Can access Astro.locals in page', async () => {
215+
const request = new Request('http://example.com/foo');
216+
const locals = { foo: 'bar' };
217+
const response = await app.render(request, { locals });
218+
const html = await response.text();
219+
220+
assert.match(html, /id="foo">bar/);
221+
});
222+
223+
it('Can access Astro.locals in api context', async () => {
224+
const request = new Request('http://example.com/api');
225+
const locals = { foo: 'bar' };
226+
const response = await app.render(request, { routeData: undefined, locals });
227+
assert.equal(response.status, 200);
228+
const body = await response.json();
229+
230+
assert.equal(body.foo, 'bar');
231+
});
232+
233+
it('404.astro can access locals provided to app.render()', async () => {
234+
const request = new Request('http://example.com/slkfnasf');
235+
const locals = { foo: 'par' };
236+
const response = await app.render(request, { locals });
237+
assert.equal(response.status, 404);
238+
239+
const html = await response.text();
240+
assert.match(html, /id="foo">par/);
241+
});
242+
243+
it('500.astro can access locals provided to app.render()', async () => {
244+
const request = new Request('http://example.com/go-to-error-page');
245+
const locals = { foo: 'par' };
246+
const response = await app.render(request, { locals });
247+
assert.equal(response.status, 500);
248+
249+
const html = await response.text();
250+
assert.match(html, /id="foo">par/);
251+
});
252+
});

0 commit comments

Comments
 (0)