2022-11-14 15:59:22 +08:00
|
|
|
/**
|
|
|
|
* @vitest-environment jsdom
|
|
|
|
*/
|
2022-09-07 14:49:54 +08:00
|
|
|
import React from 'react';
|
|
|
|
import { expect, it, describe } from 'vitest';
|
|
|
|
import { renderToHTML, renderToResponse } from '../src/runServerApp';
|
2023-06-05 16:01:11 +08:00
|
|
|
import { Meta, Title, Links, Main, Scripts, usePageAssets } from '../src/Document';
|
|
|
|
import { useAppContext } from '../src/';
|
2023-04-13 12:01:16 +08:00
|
|
|
import {
|
|
|
|
createRouteLoader,
|
|
|
|
} from '../src/routes.js';
|
2022-09-07 14:49:54 +08:00
|
|
|
|
|
|
|
describe('run server app', () => {
|
|
|
|
process.env.ICE_CORE_ROUTER = 'true';
|
2023-04-13 12:01:16 +08:00
|
|
|
const homeItem = {
|
|
|
|
default: () => <div>home</div>,
|
|
|
|
pageConfig: () => ({ title: 'home' }),
|
2023-04-25 10:47:40 +08:00
|
|
|
dataLoader: {
|
|
|
|
loader: async () => ({ data: 'test' }),
|
|
|
|
},
|
2023-04-13 12:01:16 +08:00
|
|
|
};
|
2022-09-07 14:49:54 +08:00
|
|
|
const basicRoutes = [
|
|
|
|
{
|
|
|
|
id: 'home',
|
|
|
|
path: 'home',
|
2022-10-12 14:05:00 +08:00
|
|
|
componentName: 'home',
|
2023-04-13 12:01:16 +08:00
|
|
|
lazy: () => {
|
|
|
|
return {
|
|
|
|
Component: homeItem.default,
|
|
|
|
loader: createRouteLoader({
|
|
|
|
routeId: 'home',
|
|
|
|
module: homeItem,
|
|
|
|
renderMode: 'SSR',
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
},
|
2022-09-07 14:49:54 +08:00
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
const assetsManifest = {
|
|
|
|
publicPath: '/',
|
|
|
|
assets: {},
|
|
|
|
entries: [],
|
|
|
|
pages: {
|
|
|
|
home: ['js/home.js'],
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const Document = () => (
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charSet="utf-8" />
|
|
|
|
<meta name="description" content="ICE 3.0 Demo" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
<Meta />
|
|
|
|
<Title />
|
|
|
|
<Links />
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<Main />
|
|
|
|
<Scripts />
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
);
|
|
|
|
|
|
|
|
it('render to html', async () => {
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/home',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
2022-10-24 15:17:16 +08:00
|
|
|
runtimeModules: { commons: [] },
|
2023-04-13 12:01:16 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
2022-09-07 14:49:54 +08:00
|
|
|
Document,
|
|
|
|
renderMode: 'SSR',
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.value?.includes('<div>home</div>')).toBe(true);
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.value?.includes('js/home.js')).toBe(true);
|
|
|
|
});
|
|
|
|
|
2023-05-06 20:49:07 +08:00
|
|
|
it('render with full url', async () => {
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: 'http://some.proxy:9988/home?foo=bar',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
|
|
|
runtimeModules: { commons: [] },
|
|
|
|
routes: basicRoutes,
|
2023-05-10 14:19:30 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
2023-05-06 20:49:07 +08:00
|
|
|
Document,
|
|
|
|
renderMode: 'SSR',
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.statusCode).toBe(200);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2022-09-07 14:49:54 +08:00
|
|
|
it('render to html basename', async () => {
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/home',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
2022-10-24 15:17:16 +08:00
|
|
|
runtimeModules: { commons: [] },
|
2023-04-13 12:01:16 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
2022-09-07 14:49:54 +08:00
|
|
|
Document,
|
|
|
|
renderMode: 'SSR',
|
|
|
|
basename: '/ice',
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.statusCode).toBe(404);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('render to html serverOnlyBasename', async () => {
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/home',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
2022-10-24 15:17:16 +08:00
|
|
|
runtimeModules: { commons: [] },
|
2023-04-13 12:01:16 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
2022-09-07 14:49:54 +08:00
|
|
|
Document,
|
|
|
|
renderMode: 'SSR',
|
|
|
|
serverOnlyBasename: '/',
|
|
|
|
basename: '/ice',
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.statusCode).toBe(200);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('render to 404 html', async () => {
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/about',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
2022-10-24 15:17:16 +08:00
|
|
|
runtimeModules: { commons: [] },
|
2023-04-13 12:01:16 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
2022-09-07 14:49:54 +08:00
|
|
|
Document,
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.statusCode).toBe(404);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('router hash', async () => {
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/home',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {
|
|
|
|
default: {
|
|
|
|
router: {
|
|
|
|
type: 'hash',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
assetsManifest,
|
2022-10-24 15:17:16 +08:00
|
|
|
runtimeModules: { commons: [] },
|
2023-04-13 12:01:16 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
2022-09-07 14:49:54 +08:00
|
|
|
Document,
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.statusCode).toBe(200);
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.value?.includes('<div>home</div>')).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('fallback to csr', async () => {
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/home',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
2022-10-24 15:17:16 +08:00
|
|
|
runtimeModules: { commons: [] },
|
2023-04-13 12:01:16 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => [{
|
2022-09-07 14:49:54 +08:00
|
|
|
id: 'home',
|
|
|
|
path: 'home',
|
|
|
|
componentName: 'Home',
|
2023-04-13 12:01:16 +08:00
|
|
|
lazy: () => {
|
|
|
|
return {
|
|
|
|
Component: () => {
|
|
|
|
throw new Error('err');
|
|
|
|
return (
|
|
|
|
<div>home</div>
|
|
|
|
);
|
|
|
|
},
|
|
|
|
loader: () => {
|
|
|
|
return { data: {}, pageConfig: {} };
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
2022-09-07 14:49:54 +08:00
|
|
|
}],
|
|
|
|
Document,
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.value?.includes('<div>home</div>')).toBe(false);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('render to response', async () => {
|
|
|
|
let htmlContent = '';
|
|
|
|
await renderToResponse({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/home',
|
|
|
|
},
|
|
|
|
res: {
|
|
|
|
destination: {},
|
|
|
|
// @ts-ignore
|
2022-11-14 15:59:22 +08:00
|
|
|
setHeader: () => { },
|
2022-09-07 14:49:54 +08:00
|
|
|
// @ts-ignore
|
|
|
|
end: (content) => {
|
|
|
|
htmlContent = content;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
2022-10-24 15:17:16 +08:00
|
|
|
runtimeModules: { commons: [] },
|
2023-04-13 12:01:16 +08:00
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
2022-09-07 14:49:54 +08:00
|
|
|
Document,
|
|
|
|
renderMode: 'SSR',
|
|
|
|
routePath: '/',
|
|
|
|
documentOnly: true,
|
|
|
|
});
|
|
|
|
expect(!!htmlContent).toBe(true);
|
|
|
|
expect(htmlContent.includes('<div>home</div')).toBe(false);
|
|
|
|
});
|
2023-06-05 16:01:11 +08:00
|
|
|
|
|
|
|
it('render with use scripts', async () => {
|
|
|
|
let scripts;
|
|
|
|
let renderMode;
|
|
|
|
|
|
|
|
const Document = () => {
|
|
|
|
scripts = usePageAssets();
|
|
|
|
const context = useAppContext();
|
|
|
|
renderMode = context.renderMode;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta charSet="utf-8" />
|
|
|
|
<meta name="description" content="ICE 3.0 Demo" />
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
|
|
<Meta />
|
|
|
|
<Title />
|
|
|
|
<Links />
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<Main />
|
|
|
|
<Scripts />
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const html = await renderToHTML({
|
|
|
|
// @ts-ignore
|
|
|
|
req: {
|
|
|
|
url: '/home',
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
app: {},
|
|
|
|
assetsManifest,
|
|
|
|
runtimeModules: { commons: [] },
|
|
|
|
// @ts-ignore don't need to pass params in test case.
|
|
|
|
createRoutes: () => basicRoutes,
|
|
|
|
Document,
|
|
|
|
renderMode: 'SSR',
|
|
|
|
});
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.value?.includes('<div>home</div>')).toBe(true);
|
|
|
|
// @ts-ignore
|
|
|
|
expect(html?.value?.includes('js/home.js')).toBe(true);
|
|
|
|
|
|
|
|
expect(scripts).toStrictEqual(['/js/home.js']);
|
|
|
|
expect(renderMode).toBe('SSR');
|
|
|
|
});
|
2023-04-13 12:01:16 +08:00
|
|
|
});
|