Skip to content

Commit 7b8dfc2

Browse files
convert serverRenderReactComponent test to TS
1 parent 9be97b8 commit 7b8dfc2

File tree

1 file changed

+118
-30
lines changed

1 file changed

+118
-30
lines changed
Lines changed: 118 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,177 @@
1-
/* eslint-disable react/jsx-filename-extension */
2-
/* eslint-disable no-unused-vars */
1+
/* eslint-disable @typescript-eslint/no-unused-vars */
32

43
import * as React from 'react';
5-
64
import serverRenderReactComponent from '../src/serverRenderReactComponent';
75
import ComponentRegistry from '../src/ComponentRegistry';
6+
import type {
7+
RenderParams,
8+
RenderResult,
9+
RailsContext,
10+
RenderFunction,
11+
RenderFunctionResult,
12+
ServerRenderResult,
13+
} from '../src/types';
14+
15+
const assertIsString: (value: unknown) => asserts value is string = (value: unknown) => {
16+
if (typeof value !== 'string') {
17+
throw new Error(`Expected value to be of type 'string', but received type '${typeof value}'`);
18+
}
19+
};
20+
21+
const assertIsPromise: <T>(value: null | string | Promise<T>) => asserts value is Promise<T> = <T>(
22+
value: null | string | Promise<T>,
23+
) => {
24+
if (!value || typeof (value as Promise<T>).then !== 'function') {
25+
throw new Error(`Expected value to be of type 'Promise', but received type '${typeof value}'`);
26+
}
27+
};
28+
29+
// This function is used to ensure type safety when matching objects in TypeScript tests
30+
const expectMatchObject = <T extends object>(actual: T, expected: T) => {
31+
expect(actual).toMatchObject(expected);
32+
};
833

934
describe('serverRenderReactComponent', () => {
1035
beforeEach(() => {
1136
ComponentRegistry.components().clear();
1237
});
1338

1439
it('serverRenderReactComponent renders a registered component', () => {
15-
expect.assertions(2);
16-
const X1 = () => <div>HELLO</div>;
40+
const X1: React.FC = () => React.createElement('div', null, 'HELLO');
1741
ComponentRegistry.register({ X1 });
1842

19-
const renderResult = serverRenderReactComponent({ name: 'X1', domNodeId: 'myDomId', trace: false });
20-
const { html, hasErrors } = JSON.parse(renderResult);
43+
const renderParams: RenderParams = {
44+
name: 'X1',
45+
domNodeId: 'myDomId',
46+
trace: false,
47+
throwJsErrors: false,
48+
renderingReturnsPromises: false,
49+
};
50+
51+
const renderResult = serverRenderReactComponent(renderParams);
52+
assertIsString(renderResult);
53+
const { html, hasErrors }: RenderResult = JSON.parse(renderResult) as RenderResult;
2154

22-
const result = html.indexOf('>HELLO</div>') > 0;
55+
const result = html && html.indexOf('>HELLO</div>') > 0;
2356
expect(result).toBeTruthy();
2457
expect(hasErrors).toBeFalsy();
2558
});
2659

2760
it('serverRenderReactComponent renders errors', () => {
28-
expect.assertions(2);
29-
const X2 = () => {
61+
const X2: React.FC = () => {
3062
throw new Error('XYZ');
3163
};
3264

3365
ComponentRegistry.register({ X2 });
3466

35-
// Not testing the consoleReplayScript, as handleError is putting the console to the test
36-
// runner log.
37-
const renderResult = serverRenderReactComponent({ name: 'X2', domNodeId: 'myDomId', trace: false });
38-
const { html, hasErrors } = JSON.parse(renderResult);
67+
const renderParams: RenderParams = {
68+
name: 'X2',
69+
domNodeId: 'myDomId',
70+
trace: false,
71+
throwJsErrors: false,
72+
renderingReturnsPromises: false,
73+
};
74+
75+
const renderResult = serverRenderReactComponent(renderParams);
76+
assertIsString(renderResult);
77+
const { html, hasErrors }: RenderResult = JSON.parse(renderResult) as RenderResult;
3978

40-
const result = html.indexOf('XYZ') > 0 && html.indexOf('Exception in rendering!') > 0;
79+
const result = html && html.indexOf('XYZ') > 0 && html.indexOf('Exception in rendering!') > 0;
4180
expect(result).toBeTruthy();
4281
expect(hasErrors).toBeTruthy();
4382
});
4483

4584
it('serverRenderReactComponent renders html', () => {
46-
expect.assertions(2);
4785
const expectedHtml = '<div>Hello</div>';
48-
const X3 = (props, _railsContext) => ({ renderedHtml: expectedHtml });
86+
const X3: RenderFunction = (_: unknown, __?: RailsContext): { renderedHtml: string } => ({
87+
renderedHtml: expectedHtml,
88+
});
4989

5090
ComponentRegistry.register({ X3 });
5191

52-
const renderResult = serverRenderReactComponent({ name: 'X3', domNodeId: 'myDomId', trace: false });
53-
const { html, hasErrors, renderedHtml } = JSON.parse(renderResult);
92+
const renderParams: RenderParams = {
93+
name: 'X3',
94+
domNodeId: 'myDomId',
95+
trace: false,
96+
throwJsErrors: false,
97+
renderingReturnsPromises: false,
98+
};
99+
100+
const renderResult = serverRenderReactComponent(renderParams);
101+
assertIsString(renderResult);
102+
const { html, hasErrors }: RenderResult = JSON.parse(renderResult) as RenderResult;
54103

55104
expect(html).toEqual(expectedHtml);
56105
expect(hasErrors).toBeFalsy();
57106
});
58107

59108
it('serverRenderReactComponent renders an error if attempting to render a renderer', () => {
60-
expect.assertions(1);
61-
const X4 = (a1, a2, a3) => null;
109+
const X4: RenderFunction = (
110+
_props: unknown,
111+
_railsContext?: RailsContext,
112+
_domNodeId?: string,
113+
): RenderFunctionResult => ({ renderedHtml: '' });
114+
62115
ComponentRegistry.register({ X4 });
63116

64-
const renderResult = serverRenderReactComponent({ name: 'X4', domNodeId: 'myDomId', trace: false });
65-
const { html } = JSON.parse(renderResult);
117+
const renderParams: RenderParams = {
118+
name: 'X4',
119+
domNodeId: 'myDomId',
120+
trace: false,
121+
throwJsErrors: false,
122+
renderingReturnsPromises: false,
123+
};
124+
125+
const renderResult = serverRenderReactComponent(renderParams);
126+
assertIsString(renderResult);
127+
const { html, hasErrors }: RenderResult = JSON.parse(renderResult) as RenderResult;
66128

67-
const result = html.indexOf('renderer') > 0 && html.indexOf('Exception in rendering!') > 0;
129+
const result = html && html.indexOf('renderer') > 0 && html.indexOf('Exception in rendering!') > 0;
68130
expect(result).toBeTruthy();
131+
expect(hasErrors).toBeTruthy();
69132
});
70133

71134
it('serverRenderReactComponent renders promises', async () => {
72-
expect.assertions(2);
73135
const expectedHtml = '<div>Hello</div>';
74-
const X5 = (props, _railsContext) => Promise.resolve(expectedHtml);
136+
const X5: RenderFunction = (_props: unknown, _railsContext?: RailsContext): Promise<string> =>
137+
Promise.resolve(expectedHtml);
75138

76139
ComponentRegistry.register({ X5 });
77140

78-
const renderResult = await serverRenderReactComponent({
141+
const renderParams: RenderParams = {
79142
name: 'X5',
80143
domNodeId: 'myDomId',
81144
trace: false,
145+
throwJsErrors: false,
82146
renderingReturnsPromises: true,
83-
});
84-
const html = await renderResult.html;
147+
};
148+
149+
const renderResult = serverRenderReactComponent(renderParams);
150+
assertIsPromise(renderResult);
151+
const html = await renderResult.then((r) => r.html);
85152

86153
expect(html).toEqual(expectedHtml);
87-
expect(renderResult.hasErrors).toBeFalsy();
154+
await expect(renderResult.then((r) => r.hasErrors)).resolves.toBeFalsy();
155+
});
156+
157+
it('serverRenderReactComponent renders promise of server side hash result', async () => {
158+
const expectedHtml = '<div>Hello</div>';
159+
const X6 = ((_props: unknown, _railsContext?: RailsContext): Promise<ServerRenderResult> =>
160+
Promise.resolve({ renderedHtml: expectedHtml })) as RenderFunction;
161+
162+
ComponentRegistry.register({ X6 });
163+
164+
const renderParams: RenderParams = {
165+
name: 'X6',
166+
domNodeId: 'myDomId',
167+
trace: false,
168+
throwJsErrors: false,
169+
renderingReturnsPromises: true,
170+
};
171+
172+
const renderResult = serverRenderReactComponent(renderParams);
173+
assertIsPromise(renderResult);
174+
const html = (await renderResult.then((r) => r.html)) as ServerRenderResult;
175+
expectMatchObject(html, { renderedHtml: expectedHtml });
88176
});
89177
});

0 commit comments

Comments
 (0)