ice/packages/runtime/tests/runServerApp.test.tsx

309 lines
7.1 KiB
TypeScript
Raw Permalink Normal View History

Feat/define data loader (#643) * feat: modify dataLoader * feat: add type * feat: add DataLoaderConfig * feat: modify getData to defineDataLoader * chore: remove defineDataLoader * fix: fetcher shoule return promise * fix: loader may be undefined * fix: err loader config * chore: modify example of pha * feat: modify getData * chore: modify type and mofiy options of init * feat: modify fetcher to dataLoaderFetcher and add dataLoaderImport to entry * chore: modify defaultDataLoaderFetcher * chore: load data by route id * feat: modify serverDataLoader and staticDataLoader * feat: add fetcher when route change * fix: deal with window undefined * chore: modify type * feat: try get data from cache * feat: support useData * feat: add defineStaticDataLoader and defineServerDataLoader * chore: modify getData of example * fix: should load data * fix: fix ssg err * fix: fix dataloader for ssg * test: modify env of test * fix: shoule clear cache when route changed * fix: fix renderMode and add defult remder mode * fix: add window * test: add jsdom * test: modify getData to dataLoader * test: modify test of clientApp * test: clear window after each test * test: remove only * test: remove only * chore: modify appear * fix: Try get data from cache when CSR * chore: update lock * chore: remove unused * refactor: data loader (#685) * refactor: set global fetcher * refactor: set global fetcher * fix: should not build react in data loader * fix: test * test: modify test Co-authored-by: 水澜 <shuilan.cj@taobao.com> Co-authored-by: ZeroLing <i@zeroling.com>
2022-11-14 15:59:22 +08:00
/**
* @vitest-environment jsdom
*/
import React from 'react';
import { expect, it, describe } from 'vitest';
import { renderToHTML, renderToResponse } from '../src/runServerApp';
import { Meta, Title, Links, Main, Scripts, usePageAssets } from '../src/Document';
import { useAppContext } from '../src/';
import {
createRouteLoader,
} from '../src/routes.js';
describe('run server app', () => {
process.env.ICE_CORE_ROUTER = 'true';
const homeItem = {
default: () => <div>home</div>,
pageConfig: () => ({ title: 'home' }),
dataLoader: {
loader: async () => ({ data: 'test' }),
},
};
const basicRoutes = [
{
id: 'home',
path: 'home',
componentName: 'home',
lazy: () => {
return {
Component: homeItem.default,
loader: createRouteLoader({
routeId: 'home',
module: homeItem,
renderMode: 'SSR',
}),
};
},
},
];
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,
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);
});
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,
Document,
renderMode: 'SSR',
});
// @ts-ignore
expect(html?.statusCode).toBe(200);
});
it('render to html basename', async () => {
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',
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,
runtimeModules: { commons: [] },
// @ts-ignore don't need to pass params in test case.
createRoutes: () => basicRoutes,
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,
runtimeModules: { commons: [] },
// @ts-ignore don't need to pass params in test case.
createRoutes: () => basicRoutes,
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,
runtimeModules: { commons: [] },
// @ts-ignore don't need to pass params in test case.
createRoutes: () => basicRoutes,
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,
runtimeModules: { commons: [] },
// @ts-ignore don't need to pass params in test case.
createRoutes: () => [{
id: 'home',
path: 'home',
componentName: 'Home',
lazy: () => {
return {
Component: () => {
throw new Error('err');
return (
<div>home</div>
);
},
loader: () => {
return { data: {}, pageConfig: {} };
},
};
},
}],
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
Feat/define data loader (#643) * feat: modify dataLoader * feat: add type * feat: add DataLoaderConfig * feat: modify getData to defineDataLoader * chore: remove defineDataLoader * fix: fetcher shoule return promise * fix: loader may be undefined * fix: err loader config * chore: modify example of pha * feat: modify getData * chore: modify type and mofiy options of init * feat: modify fetcher to dataLoaderFetcher and add dataLoaderImport to entry * chore: modify defaultDataLoaderFetcher * chore: load data by route id * feat: modify serverDataLoader and staticDataLoader * feat: add fetcher when route change * fix: deal with window undefined * chore: modify type * feat: try get data from cache * feat: support useData * feat: add defineStaticDataLoader and defineServerDataLoader * chore: modify getData of example * fix: should load data * fix: fix ssg err * fix: fix dataloader for ssg * test: modify env of test * fix: shoule clear cache when route changed * fix: fix renderMode and add defult remder mode * fix: add window * test: add jsdom * test: modify getData to dataLoader * test: modify test of clientApp * test: clear window after each test * test: remove only * test: remove only * chore: modify appear * fix: Try get data from cache when CSR * chore: update lock * chore: remove unused * refactor: data loader (#685) * refactor: set global fetcher * refactor: set global fetcher * fix: should not build react in data loader * fix: test * test: modify test Co-authored-by: 水澜 <shuilan.cj@taobao.com> Co-authored-by: ZeroLing <i@zeroling.com>
2022-11-14 15:59:22 +08:00
setHeader: () => { },
// @ts-ignore
end: (content) => {
htmlContent = content;
},
},
}, {
app: {},
assetsManifest,
runtimeModules: { commons: [] },
// @ts-ignore don't need to pass params in test case.
createRoutes: () => basicRoutes,
Document,
renderMode: 'SSR',
routePath: '/',
documentOnly: true,
});
expect(!!htmlContent).toBe(true);
expect(htmlContent.includes('<div>home</div')).toBe(false);
});
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');
});
});