From 6d60e5b6b013c9a9cfadf0e7d004073d7e51d575 Mon Sep 17 00:00:00 2001
From: Nik Tverd <61203447+niktverd@users.noreply.github.com>
Date: Thu, 21 Sep 2023 01:48:45 +0600
Subject: [PATCH] test(CardBase): test for CardBase added (#391)
* test(CardBase): test for CardBase added
---
src/components/CardBase/CardBase.tsx | 23 +-
.../CardBase/__tests__/CardBase.test.tsx | 245 ++++++++++++++++++
test-utils/constants.ts | 2 +
3 files changed, 265 insertions(+), 5 deletions(-)
create mode 100644 src/components/CardBase/__tests__/CardBase.test.tsx
diff --git a/src/components/CardBase/CardBase.tsx b/src/components/CardBase/CardBase.tsx
index 52d3b0e7e..5af8ae8bc 100644
--- a/src/components/CardBase/CardBase.tsx
+++ b/src/components/CardBase/CardBase.tsx
@@ -10,7 +10,7 @@ import {
WithChildren,
} from '../../models';
import {AnalyticsEventsBase, DefaultEventNames} from '../../models/common';
-import {block} from '../../utils';
+import {block, getQaAttrubutes} from '../../utils';
import BackgroundImage from '../BackgroundImage/BackgroundImage';
import RouterLink from '../RouterLink/RouterLink';
@@ -25,6 +25,7 @@ export interface CardBaseProps extends AnalyticsEventsBase, CardBaseParams {
target?: HTMLAttributeAnchorTarget;
metrikaGoals?: MetrikaGoal;
pixelEvents?: ButtonPixel;
+ qa?: string;
}
export interface CardHeaderBaseProps {
@@ -54,10 +55,12 @@ export const Layout = (props: CardBaseProps) => {
url,
target,
border = 'shadow',
+ qa,
} = props;
const handleMetrika = useMetrika();
const handleAnalytics = useAnalytics(DefaultEventNames.CardBase, url);
let header, content, footer, image, headerClass, footerClass;
+ const qaAttributes = getQaAttrubutes(qa, 'header', 'footer', 'body', 'content');
function handleChild(child: ReactElement) {
switch (child.type) {
@@ -88,13 +91,20 @@ export const Layout = (props: CardBaseProps) => {
{header}
)}
-
-
{content}
- {footer &&
{footer}
}
+
+
+ {content}
+
+ {footer && (
+
+ {footer}
+
+ )}
);
@@ -116,12 +126,15 @@ export const Layout = (props: CardBaseProps) => {
draggable={false}
onDragStart={(e) => e.preventDefault()}
onClick={onClick}
+ data-qa={qa}
>
{cardContent}
) : (
-
{cardContent}
+
+ {cardContent}
+
);
};
diff --git a/src/components/CardBase/__tests__/CardBase.test.tsx b/src/components/CardBase/__tests__/CardBase.test.tsx
new file mode 100644
index 000000000..168bdf7a0
--- /dev/null
+++ b/src/components/CardBase/__tests__/CardBase.test.tsx
@@ -0,0 +1,245 @@
+import React from 'react';
+
+import {render, screen} from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+import {TARGETS} from '../../../../test-utils/constants';
+import {testCustomClassName} from '../../../../test-utils/shared/common';
+import {PageConstructorProvider} from '../../../containers/PageConstructor';
+import {AnalyticsContextProps} from '../../../context/analyticsContext';
+import {MetrikaContextProps} from '../../../context/metrikaContext';
+import {CardBorder, PixelEventType} from '../../../models';
+import {getQaAttrubutes} from '../../../utils';
+import CardBase, {CardBaseProps} from '../CardBase';
+
+const qaId = 'card-base-component';
+const qaAttributes = getQaAttrubutes(qaId, 'header', 'footer', 'body', 'content');
+
+const url = '#';
+
+const borders: CardBorder[] = ['shadow', 'line', 'none'];
+
+describe('CardBase', () => {
+ test('render CardBase by default', async () => {
+ render(
+
+ Content
+ ,
+ );
+ const cardBase = screen.getByTestId(qaId);
+
+ expect(cardBase).toBeInTheDocument();
+ expect(cardBase).toBeVisible();
+ expect(cardBase).not.toBeDisabled();
+
+ const aTag = screen.queryByRole('link');
+ expect(aTag).not.toBeInTheDocument();
+ });
+
+ test('render CardBase by default as a link', async () => {
+ render(
+
+ Content
+ ,
+ );
+ const cardBase = screen.queryByRole('link');
+
+ expect(cardBase).toBeInTheDocument();
+ expect(cardBase).toBeVisible();
+ expect(cardBase).not.toBeDisabled();
+ });
+
+ test.each(new Array
(...TARGETS))(
+ 'render with given "%s" target',
+ (target) => {
+ render(
+
+ Content
+ ,
+ );
+ const cardBase = screen.queryByRole('link');
+
+ expect(cardBase).toHaveAttribute('target', target);
+ },
+ );
+
+ test('add className', () => {
+ const children = text;
+ testCustomClassName({
+ component: CardBase,
+ props: {children, qa: qaId},
+ });
+ });
+
+ test('render CardBase with header', async () => {
+ render(
+
+ Header
+ ,
+ );
+ const cardBaseHeader = screen.queryByTestId(qaAttributes.header);
+
+ expect(cardBaseHeader).toBeInTheDocument();
+ expect(cardBaseHeader).toBeVisible();
+ expect(cardBaseHeader).not.toBeDisabled();
+ });
+
+ test('render CardBase with content', async () => {
+ render(
+
+ Content
+ ,
+ );
+ const cardBaseContent = screen.queryByTestId(qaAttributes.content);
+
+ expect(cardBaseContent).toBeInTheDocument();
+ expect(cardBaseContent).toBeVisible();
+ expect(cardBaseContent).not.toBeDisabled();
+ });
+
+ test('render CardBase with footer', async () => {
+ render(
+
+ Footer
+ ,
+ );
+ const cardBaseFooter = screen.queryByTestId(qaAttributes.footer);
+
+ expect(cardBaseFooter).toBeInTheDocument();
+ expect(cardBaseFooter).toBeVisible();
+ expect(cardBaseFooter).not.toBeDisabled();
+ });
+
+ test('add bodyClassName', async () => {
+ const bodyClassName = 'body-class-name';
+
+ render(
+
+ Content
+ ,
+ );
+ const cardBaseBody = screen.queryByTestId(qaAttributes.body);
+
+ expect(cardBaseBody).toHaveClass(bodyClassName);
+ });
+
+ test('add contentClassName', async () => {
+ const contentClassName = 'content-class-name';
+
+ render(
+
+ Content
+ ,
+ );
+ const cardBaseContent = screen.queryByTestId(qaAttributes.content);
+
+ expect(cardBaseContent).toHaveClass(contentClassName);
+ });
+
+ test('add className to Header', async () => {
+ const className = 'body-class-name';
+
+ render(
+
+ Header
+ ,
+ );
+
+ const cardBaseHeader = screen.queryByTestId(qaAttributes.header);
+
+ expect(cardBaseHeader).toHaveClass(className);
+ });
+
+ test('add className to Footer', async () => {
+ const className = 'footer-class-name';
+
+ render(
+
+ Footer
+ ,
+ );
+ const cardBaseFooter = screen.getByTestId(qaAttributes.footer);
+
+ expect(cardBaseFooter).toHaveClass(className);
+ });
+
+ test.each(new Array(...borders))('render with given "%s" border', (border) => {
+ render(
+
+ Content
+ ,
+ );
+ const button = screen.getByTestId(qaId);
+
+ expect(button).toHaveClass(`pc-card-base-block_border_${border}`);
+ });
+
+ test('add metrikaEvent', async () => {
+ const metrikaContext: MetrikaContextProps = {
+ metrika: {
+ reachGoal: jest.fn(),
+ reachGoals: jest.fn(),
+ },
+ };
+ const user = userEvent.setup();
+
+ render(
+
+
+ Content
+
+ ,
+ );
+ const cardBase = screen.getByTestId(qaId);
+
+ await user.click(cardBase);
+ expect(metrikaContext.metrika?.reachGoals).toHaveBeenCalledTimes(1);
+ });
+
+ test('add pixelEvent', async () => {
+ const metrikaContext: MetrikaContextProps = {
+ pixel: {
+ trackStandard: jest.fn(),
+ trackCustom: jest.fn(),
+ track: jest.fn(),
+ },
+ };
+ const user = userEvent.setup();
+
+ render(
+
+
+ Content
+
+ ,
+ );
+ const cardBase = screen.getByTestId(qaId);
+
+ await user.click(cardBase);
+ expect(metrikaContext.pixel?.track).toHaveBeenCalledTimes(1);
+ });
+
+ test('add analyticsEvent', async () => {
+ const analyticsContext: AnalyticsContextProps = {
+ sendEvents: jest.fn(),
+ };
+ const user = userEvent.setup();
+
+ render(
+
+
+ Content
+
+ ,
+ );
+ const cardBase = screen.getByTestId(qaId);
+
+ await user.click(cardBase);
+ expect(analyticsContext.sendEvents).toHaveBeenCalledTimes(1);
+ });
+});
diff --git a/test-utils/constants.ts b/test-utils/constants.ts
index f8d371ea6..c1bfc8fc5 100644
--- a/test-utils/constants.ts
+++ b/test-utils/constants.ts
@@ -1 +1,3 @@
+export const TARGETS: React.HTMLAttributeAnchorTarget[] = ['_blank', '_self', '_parent', '_top'];
+
export const ERROR_INPUT_DATA_MESSAGE = 'There are errors in input test data';