Skip to content

Commit 534feb7

Browse files
committed
Add tests
1 parent 577ef88 commit 534feb7

File tree

11 files changed

+482
-34
lines changed

11 files changed

+482
-34
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React from 'react';
2+
import { renderToString } from 'react-dom/server';
3+
4+
import ResultCardSwatches from '../../../src/components/ResultCardSwatches/ResultCardSwatches';
5+
import { withContext } from '../../__tests__/utils';
6+
import { QuizContextValue } from '../../../src/components/CioQuiz/context';
7+
import * as factories from '../../__tests__/factories';
8+
9+
describe(`${ResultCardSwatches.name} server`, () => {
10+
const onVariationClickMock = jest.fn();
11+
12+
const mockResult = factories.quizResult.build({
13+
data: {
14+
variation_id: 'var1',
15+
image_url: 'test-image.jpg',
16+
option_image_source: 'option-image.jpg',
17+
},
18+
variations: [
19+
{
20+
data: {
21+
variation_id: 'var1',
22+
image_url: 'test-image.jpg',
23+
option_image_source: 'option-image.jpg',
24+
},
25+
value: 'Variation 1',
26+
},
27+
{
28+
data: {
29+
variation_id: 'var2',
30+
image_url: 'test-image-2.jpg',
31+
option_image_source: 'option-image-2.jpg',
32+
},
33+
value: 'Variation 2',
34+
},
35+
],
36+
});
37+
38+
const props = {
39+
faceOutResult: mockResult,
40+
onVariationClick: onVariationClickMock,
41+
};
42+
43+
const getQuizResultSwatchPropsMock = jest
44+
.fn()
45+
.mockImplementation((variation, onVariationClick) => ({
46+
className: 'cio-result-card-swatch',
47+
type: 'button',
48+
onClick: () => onVariationClick(variation),
49+
style: { background: `url(${variation.data.image_url})` },
50+
}));
51+
52+
const contextMocks: Partial<QuizContextValue> = {
53+
getQuizResultSwatchProps: getQuizResultSwatchPropsMock,
54+
};
55+
56+
describe('with context function', () => {
57+
const Subject = withContext(ResultCardSwatches, { contextMocks });
58+
59+
it('renders swatches for each variation', () => {
60+
const view = renderToString(<Subject {...props} />);
61+
expect(view).toContain('cio-result-card-swatch');
62+
expect(getQuizResultSwatchPropsMock).toHaveBeenCalledTimes(2);
63+
});
64+
65+
it('passes swatchImageKey when provided', () => {
66+
const swatchImageKey = 'option_image_source';
67+
renderToString(<Subject {...props} swatchImageKey={swatchImageKey} />);
68+
69+
expect(getQuizResultSwatchPropsMock).toHaveBeenCalledWith(
70+
mockResult?.variations?.[0],
71+
onVariationClickMock,
72+
mockResult,
73+
swatchImageKey
74+
);
75+
});
76+
});
77+
78+
describe('without context function', () => {
79+
const Subject = withContext(ResultCardSwatches, {
80+
contextMocks: { getQuizResultSwatchProps: undefined },
81+
});
82+
83+
it('does not render swatches', () => {
84+
const view = renderToString(<Subject {...props} />);
85+
expect(view).not.toContain('cio-result-card-swatch');
86+
});
87+
});
88+
89+
describe('with no variations', () => {
90+
const Subject = withContext(ResultCardSwatches, { contextMocks });
91+
92+
it('renders no swatches when variations is undefined', () => {
93+
const propsWithoutVariations = {
94+
...props,
95+
faceOutResult: { ...mockResult, variations: undefined },
96+
};
97+
98+
const view = renderToString(<Subject {...propsWithoutVariations} />);
99+
expect(view).not.toContain('cio-result-card-swatch');
100+
});
101+
102+
it('renders no swatches when variations is empty', () => {
103+
const propsWithEmptyVariations = {
104+
...props,
105+
faceOutResult: { ...mockResult, variations: [] },
106+
};
107+
108+
const view = renderToString(<Subject {...propsWithEmptyVariations} />);
109+
expect(view).not.toContain('cio-result-card-swatch');
110+
});
111+
});
112+
});
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import React from 'react';
2+
import { render, screen, fireEvent } from '@testing-library/react';
3+
4+
import ResultCardSwatches from '../../../src/components/ResultCardSwatches/ResultCardSwatches';
5+
import { withContext } from '../../__tests__/utils';
6+
import { QuizContextValue } from '../../../src/components/CioQuiz/context';
7+
import * as factories from '../../__tests__/factories';
8+
9+
describe(`${ResultCardSwatches.name} client`, () => {
10+
beforeEach(() => {
11+
const spy = jest.spyOn(console, 'error');
12+
spy.mockImplementation(() => {});
13+
});
14+
15+
afterAll(() => {
16+
jest.resetAllMocks();
17+
});
18+
19+
const onVariationClickMock = jest.fn();
20+
21+
const mockResult = factories.quizResult.build({
22+
data: {
23+
variation_id: 'var1',
24+
image_url: 'test-image.jpg',
25+
option_image_source: 'option-image.jpg',
26+
},
27+
variations: [
28+
{
29+
data: {
30+
variation_id: 'var1',
31+
image_url: 'test-image.jpg',
32+
option_image_source: 'option-image.jpg',
33+
},
34+
value: 'Variation 1',
35+
},
36+
{
37+
data: {
38+
variation_id: 'var2',
39+
image_url: 'test-image-2.jpg',
40+
option_image_source: 'option-image-2.jpg',
41+
},
42+
value: 'Variation 2',
43+
},
44+
],
45+
});
46+
47+
const props = {
48+
faceOutResult: mockResult,
49+
onVariationClick: onVariationClickMock,
50+
};
51+
52+
const getQuizResultSwatchPropsMock = jest
53+
.fn()
54+
.mockImplementation((variation, onVariationClick) => ({
55+
className: 'cio-result-card-swatch',
56+
type: 'button',
57+
onClick: () => onVariationClick(variation),
58+
style: { background: `url(${variation.data.image_url})` },
59+
}));
60+
61+
const contextMocks: Partial<QuizContextValue> = {
62+
getQuizResultSwatchProps: getQuizResultSwatchPropsMock,
63+
};
64+
65+
afterEach(() => {
66+
jest.clearAllMocks();
67+
});
68+
69+
describe('with context function', () => {
70+
const Subject = withContext(ResultCardSwatches, { contextMocks });
71+
72+
it('renders swatches for each variation', () => {
73+
render(<Subject {...props} />);
74+
75+
const swatches = screen.getAllByRole('button');
76+
expect(swatches).toHaveLength(2);
77+
});
78+
79+
it('calls getQuizResultSwatchProps with correct parameters', () => {
80+
render(<Subject {...props} />);
81+
82+
expect(getQuizResultSwatchPropsMock).toHaveBeenCalledTimes(2);
83+
expect(getQuizResultSwatchPropsMock).toHaveBeenCalledWith(
84+
mockResult?.variations?.[0],
85+
onVariationClickMock,
86+
mockResult,
87+
undefined
88+
);
89+
});
90+
91+
it('passes swatchImageKey when provided', () => {
92+
const swatchImageKey = 'option_image_source';
93+
render(<Subject {...props} swatchImageKey={swatchImageKey} />);
94+
95+
expect(getQuizResultSwatchPropsMock).toHaveBeenCalledWith(
96+
mockResult?.variations?.[0],
97+
onVariationClickMock,
98+
mockResult,
99+
swatchImageKey
100+
);
101+
});
102+
103+
it('calls onVariationClick when a swatch is clicked', () => {
104+
render(<Subject {...props} />);
105+
106+
const swatches = screen.getAllByRole('button');
107+
fireEvent.click(swatches[1]);
108+
109+
expect(onVariationClickMock).toHaveBeenCalledWith(mockResult?.variations?.[1]);
110+
});
111+
});
112+
113+
describe('without context function', () => {
114+
const Subject = withContext(ResultCardSwatches, {
115+
contextMocks: { getQuizResultSwatchProps: undefined },
116+
});
117+
118+
it('does not render swatches', () => {
119+
render(<Subject {...props} />);
120+
121+
const swatches = screen.queryAllByRole('button');
122+
expect(swatches).toHaveLength(0);
123+
});
124+
});
125+
126+
describe('with no variations', () => {
127+
const Subject = withContext(ResultCardSwatches, { contextMocks });
128+
129+
it('renders no swatches when variations is undefined', () => {
130+
const propsWithoutVariations = {
131+
...props,
132+
faceOutResult: { ...mockResult, variations: undefined },
133+
};
134+
135+
render(<Subject {...propsWithoutVariations} />);
136+
137+
const swatches = screen.queryAllByRole('button');
138+
expect(swatches).toHaveLength(0);
139+
});
140+
141+
it('renders no swatches when variations is empty', () => {
142+
const propsWithEmptyVariations = {
143+
...props,
144+
faceOutResult: { ...mockResult, variations: [] },
145+
};
146+
147+
render(<Subject {...propsWithEmptyVariations} />);
148+
149+
const swatches = screen.queryAllByRole('button');
150+
expect(swatches).toHaveLength(0);
151+
});
152+
});
153+
});
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React from 'react';
2+
import { renderToString } from 'react-dom/server';
3+
import * as factories from '../../__tests__/factories';
4+
5+
import useResult from '../../../src/hooks/useResult';
6+
import { QuizResultDataPartial } from '../../../src/types';
7+
8+
const mockUseResult = (result: any) => ({
9+
faceOutResult: {
10+
...result,
11+
...result?.variations?.find(
12+
(variation: any) => variation.data.variation_id === result?.data?.variation_id
13+
),
14+
},
15+
onVariationClick: jest.fn(),
16+
});
17+
18+
jest.mock('../../../src/hooks/useResult', () => ({
19+
__esModule: true,
20+
default: (result: any) => mockUseResult(result),
21+
}));
22+
23+
// Test component that uses the hook
24+
function TestComponent({ result }: { result?: QuizResultDataPartial }) {
25+
const { faceOutResult } = useResult(result || {});
26+
return (
27+
<div>
28+
<div data-testid='variation-id'>{faceOutResult?.data?.variation_id}</div>
29+
<div data-testid='image-url'>{faceOutResult?.data?.image_url}</div>
30+
<div data-testid='value'>{faceOutResult?.value}</div>
31+
</div>
32+
);
33+
}
34+
35+
describe('useResult Hook (Server)', () => {
36+
const mockResult = factories.quizResult.build({
37+
data: {
38+
variation_id: 'var1',
39+
image_url: 'test-image.jpg',
40+
},
41+
variations: [
42+
{
43+
data: {
44+
variation_id: 'var1',
45+
image_url: 'test-image.jpg',
46+
},
47+
value: 'Variation 1',
48+
},
49+
{
50+
data: {
51+
variation_id: 'var2',
52+
image_url: 'test-image-2.jpg',
53+
},
54+
value: 'Variation 2',
55+
},
56+
],
57+
});
58+
59+
it('should render with the correct initial values', () => {
60+
const view = renderToString(<TestComponent result={mockResult} />);
61+
62+
expect(view).toContain('var1');
63+
expect(view).toContain('test-image.jpg');
64+
expect(view).toContain('Variation 1');
65+
});
66+
67+
it('should handle undefined result', () => {
68+
const view = renderToString(<TestComponent result={undefined} />);
69+
70+
expect(view).not.toContain('var1');
71+
expect(view).not.toContain('test-image.jpg');
72+
});
73+
74+
it('should handle result without variations', () => {
75+
const resultWithoutVariations = { ...mockResult, variations: undefined };
76+
const view = renderToString(<TestComponent result={resultWithoutVariations} />);
77+
78+
expect(view).toContain('var1');
79+
expect(view).toContain('test-image.jpg');
80+
});
81+
});

0 commit comments

Comments
 (0)