Skip to content

Commit 6d60e5b

Browse files
authored
test(CardBase): test for CardBase added (#391)
* test(CardBase): test for CardBase added
1 parent d1ecf3e commit 6d60e5b

File tree

3 files changed

+265
-5
lines changed

3 files changed

+265
-5
lines changed

src/components/CardBase/CardBase.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
WithChildren,
1111
} from '../../models';
1212
import {AnalyticsEventsBase, DefaultEventNames} from '../../models/common';
13-
import {block} from '../../utils';
13+
import {block, getQaAttrubutes} from '../../utils';
1414
import BackgroundImage from '../BackgroundImage/BackgroundImage';
1515
import RouterLink from '../RouterLink/RouterLink';
1616

@@ -25,6 +25,7 @@ export interface CardBaseProps extends AnalyticsEventsBase, CardBaseParams {
2525
target?: HTMLAttributeAnchorTarget;
2626
metrikaGoals?: MetrikaGoal;
2727
pixelEvents?: ButtonPixel;
28+
qa?: string;
2829
}
2930

3031
export interface CardHeaderBaseProps {
@@ -54,10 +55,12 @@ export const Layout = (props: CardBaseProps) => {
5455
url,
5556
target,
5657
border = 'shadow',
58+
qa,
5759
} = props;
5860
const handleMetrika = useMetrika();
5961
const handleAnalytics = useAnalytics(DefaultEventNames.CardBase, url);
6062
let header, content, footer, image, headerClass, footerClass;
63+
const qaAttributes = getQaAttrubutes(qa, 'header', 'footer', 'body', 'content');
6164

6265
function handleChild(child: ReactElement) {
6366
switch (child.type) {
@@ -88,13 +91,20 @@ export const Layout = (props: CardBaseProps) => {
8891
<BackgroundImage
8992
className={b('header', headerClass)}
9093
{...(typeof image === 'string' ? {src: image} : image)}
94+
qa={qaAttributes.header}
9195
>
9296
<div className={b('header-content')}>{header}</div>
9397
</BackgroundImage>
9498
)}
95-
<div className={b('body', bodyClassName)}>
96-
<div className={b('content', contentClassName)}>{content}</div>
97-
{footer && <div className={b('footer', footerClass)}>{footer}</div>}
99+
<div className={b('body', bodyClassName)} data-qa={qaAttributes.body}>
100+
<div className={b('content', contentClassName)} data-qa={qaAttributes.content}>
101+
{content}
102+
</div>
103+
{footer && (
104+
<div className={b('footer', footerClass)} data-qa={qaAttributes.footer}>
105+
{footer}
106+
</div>
107+
)}
98108
</div>
99109
</Fragment>
100110
);
@@ -116,12 +126,15 @@ export const Layout = (props: CardBaseProps) => {
116126
draggable={false}
117127
onDragStart={(e) => e.preventDefault()}
118128
onClick={onClick}
129+
data-qa={qa}
119130
>
120131
{cardContent}
121132
</a>
122133
</RouterLink>
123134
) : (
124-
<div className={fullClassName}>{cardContent}</div>
135+
<div className={fullClassName} data-qa={qa}>
136+
{cardContent}
137+
</div>
125138
);
126139
};
127140

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
import React from 'react';
2+
3+
import {render, screen} from '@testing-library/react';
4+
import userEvent from '@testing-library/user-event';
5+
6+
import {TARGETS} from '../../../../test-utils/constants';
7+
import {testCustomClassName} from '../../../../test-utils/shared/common';
8+
import {PageConstructorProvider} from '../../../containers/PageConstructor';
9+
import {AnalyticsContextProps} from '../../../context/analyticsContext';
10+
import {MetrikaContextProps} from '../../../context/metrikaContext';
11+
import {CardBorder, PixelEventType} from '../../../models';
12+
import {getQaAttrubutes} from '../../../utils';
13+
import CardBase, {CardBaseProps} from '../CardBase';
14+
15+
const qaId = 'card-base-component';
16+
const qaAttributes = getQaAttrubutes(qaId, 'header', 'footer', 'body', 'content');
17+
18+
const url = '#';
19+
20+
const borders: CardBorder[] = ['shadow', 'line', 'none'];
21+
22+
describe('CardBase', () => {
23+
test('render CardBase by default', async () => {
24+
render(
25+
<CardBase qa={qaId}>
26+
<CardBase.Content>Content</CardBase.Content>
27+
</CardBase>,
28+
);
29+
const cardBase = screen.getByTestId(qaId);
30+
31+
expect(cardBase).toBeInTheDocument();
32+
expect(cardBase).toBeVisible();
33+
expect(cardBase).not.toBeDisabled();
34+
35+
const aTag = screen.queryByRole('link');
36+
expect(aTag).not.toBeInTheDocument();
37+
});
38+
39+
test('render CardBase by default as a link', async () => {
40+
render(
41+
<CardBase qa={qaId} url={url}>
42+
<CardBase.Content>Content</CardBase.Content>
43+
</CardBase>,
44+
);
45+
const cardBase = screen.queryByRole('link');
46+
47+
expect(cardBase).toBeInTheDocument();
48+
expect(cardBase).toBeVisible();
49+
expect(cardBase).not.toBeDisabled();
50+
});
51+
52+
test.each(new Array<React.HTMLAttributeAnchorTarget>(...TARGETS))(
53+
'render with given "%s" target',
54+
(target) => {
55+
render(
56+
<CardBase qa={qaId} url={url} target={target}>
57+
<CardBase.Content>Content</CardBase.Content>
58+
</CardBase>,
59+
);
60+
const cardBase = screen.queryByRole('link');
61+
62+
expect(cardBase).toHaveAttribute('target', target);
63+
},
64+
);
65+
66+
test('add className', () => {
67+
const children = <CardBase.Content>text</CardBase.Content>;
68+
testCustomClassName<CardBaseProps>({
69+
component: CardBase,
70+
props: {children, qa: qaId},
71+
});
72+
});
73+
74+
test('render CardBase with header', async () => {
75+
render(
76+
<CardBase qa={qaId}>
77+
<CardBase.Header>Header</CardBase.Header>
78+
</CardBase>,
79+
);
80+
const cardBaseHeader = screen.queryByTestId(qaAttributes.header);
81+
82+
expect(cardBaseHeader).toBeInTheDocument();
83+
expect(cardBaseHeader).toBeVisible();
84+
expect(cardBaseHeader).not.toBeDisabled();
85+
});
86+
87+
test('render CardBase with content', async () => {
88+
render(
89+
<CardBase qa={qaId}>
90+
<CardBase.Content>Content</CardBase.Content>
91+
</CardBase>,
92+
);
93+
const cardBaseContent = screen.queryByTestId(qaAttributes.content);
94+
95+
expect(cardBaseContent).toBeInTheDocument();
96+
expect(cardBaseContent).toBeVisible();
97+
expect(cardBaseContent).not.toBeDisabled();
98+
});
99+
100+
test('render CardBase with footer', async () => {
101+
render(
102+
<CardBase qa={qaId}>
103+
<CardBase.Footer>Footer</CardBase.Footer>
104+
</CardBase>,
105+
);
106+
const cardBaseFooter = screen.queryByTestId(qaAttributes.footer);
107+
108+
expect(cardBaseFooter).toBeInTheDocument();
109+
expect(cardBaseFooter).toBeVisible();
110+
expect(cardBaseFooter).not.toBeDisabled();
111+
});
112+
113+
test('add bodyClassName', async () => {
114+
const bodyClassName = 'body-class-name';
115+
116+
render(
117+
<CardBase bodyClassName={bodyClassName} qa={qaId}>
118+
<CardBase.Content>Content</CardBase.Content>
119+
</CardBase>,
120+
);
121+
const cardBaseBody = screen.queryByTestId(qaAttributes.body);
122+
123+
expect(cardBaseBody).toHaveClass(bodyClassName);
124+
});
125+
126+
test('add contentClassName', async () => {
127+
const contentClassName = 'content-class-name';
128+
129+
render(
130+
<CardBase contentClassName={contentClassName} qa={qaId}>
131+
<CardBase.Content>Content</CardBase.Content>
132+
</CardBase>,
133+
);
134+
const cardBaseContent = screen.queryByTestId(qaAttributes.content);
135+
136+
expect(cardBaseContent).toHaveClass(contentClassName);
137+
});
138+
139+
test('add className to Header', async () => {
140+
const className = 'body-class-name';
141+
142+
render(
143+
<CardBase qa={qaId}>
144+
<CardBase.Header className={className}>Header</CardBase.Header>
145+
</CardBase>,
146+
);
147+
148+
const cardBaseHeader = screen.queryByTestId(qaAttributes.header);
149+
150+
expect(cardBaseHeader).toHaveClass(className);
151+
});
152+
153+
test('add className to Footer', async () => {
154+
const className = 'footer-class-name';
155+
156+
render(
157+
<CardBase qa={qaId}>
158+
<CardBase.Footer className={className}>Footer</CardBase.Footer>
159+
</CardBase>,
160+
);
161+
const cardBaseFooter = screen.getByTestId(qaAttributes.footer);
162+
163+
expect(cardBaseFooter).toHaveClass(className);
164+
});
165+
166+
test.each(new Array<CardBorder>(...borders))('render with given "%s" border', (border) => {
167+
render(
168+
<CardBase border={border} qa={qaId}>
169+
<CardBase.Content>Content</CardBase.Content>
170+
</CardBase>,
171+
);
172+
const button = screen.getByTestId(qaId);
173+
174+
expect(button).toHaveClass(`pc-card-base-block_border_${border}`);
175+
});
176+
177+
test('add metrikaEvent', async () => {
178+
const metrikaContext: MetrikaContextProps = {
179+
metrika: {
180+
reachGoal: jest.fn(),
181+
reachGoals: jest.fn(),
182+
},
183+
};
184+
const user = userEvent.setup();
185+
186+
render(
187+
<PageConstructorProvider metrika={metrikaContext}>
188+
<CardBase url={url} target={'_blank'} qa={qaId} metrikaGoals={'metrika-goal'}>
189+
<CardBase.Content>Content</CardBase.Content>
190+
</CardBase>
191+
</PageConstructorProvider>,
192+
);
193+
const cardBase = screen.getByTestId(qaId);
194+
195+
await user.click(cardBase);
196+
expect(metrikaContext.metrika?.reachGoals).toHaveBeenCalledTimes(1);
197+
});
198+
199+
test('add pixelEvent', async () => {
200+
const metrikaContext: MetrikaContextProps = {
201+
pixel: {
202+
trackStandard: jest.fn(),
203+
trackCustom: jest.fn(),
204+
track: jest.fn(),
205+
},
206+
};
207+
const user = userEvent.setup();
208+
209+
render(
210+
<PageConstructorProvider metrika={metrikaContext}>
211+
<CardBase
212+
url={url}
213+
target={'_blank'}
214+
qa={qaId}
215+
pixelEvents={[{name: PixelEventType.AddToCart}]}
216+
>
217+
<CardBase.Content>Content</CardBase.Content>
218+
</CardBase>
219+
</PageConstructorProvider>,
220+
);
221+
const cardBase = screen.getByTestId(qaId);
222+
223+
await user.click(cardBase);
224+
expect(metrikaContext.pixel?.track).toHaveBeenCalledTimes(1);
225+
});
226+
227+
test('add analyticsEvent', async () => {
228+
const analyticsContext: AnalyticsContextProps = {
229+
sendEvents: jest.fn(),
230+
};
231+
const user = userEvent.setup();
232+
233+
render(
234+
<PageConstructorProvider analytics={analyticsContext}>
235+
<CardBase url={url} target={'_blank'} qa={qaId} analyticsEvents={[{name: 'click'}]}>
236+
<CardBase.Content>Content</CardBase.Content>
237+
</CardBase>
238+
</PageConstructorProvider>,
239+
);
240+
const cardBase = screen.getByTestId(qaId);
241+
242+
await user.click(cardBase);
243+
expect(analyticsContext.sendEvents).toHaveBeenCalledTimes(1);
244+
});
245+
});

test-utils/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
export const TARGETS: React.HTMLAttributeAnchorTarget[] = ['_blank', '_self', '_parent', '_top'];
2+
13
export const ERROR_INPUT_DATA_MESSAGE = 'There are errors in input test data';

0 commit comments

Comments
 (0)