@vertisanpro/flowbite-react
Version:
Non-Official React components built for Flowbite and Tailwind CSS
138 lines (137 loc) • 6.89 kB
JavaScript
import { render, screen } from '@testing-library/react';
import React from 'react';
import { describe, expect, it, vi } from 'vitest';
import { Flowbite } from '../Flowbite';
import { Card } from './Card';
describe('Components / Card', () => {
describe('Functionality', () => {
it('should render an image when `imgSrc` is provided', () => {
render(React.createElement(Card, { imgSrc: "https://flowbite.com/docs/images/blog/image-1.jpg" }));
expect(screen.queryAllByTestId('flowbite-card-image')).toHaveLength(1);
expect(screen.queryByTestId('flowbite-card-image')).toHaveAttribute('src', 'https://flowbite.com/docs/images/blog/image-1.jpg');
});
it('should not render an `<img>` given an undefined `imgSrc`', () => {
render(React.createElement(Card, { imgSrc: undefined }));
expect(screen.queryAllByTestId('flowbite-card-image')).toHaveLength(0);
});
it('should render the image from the `renderImage` prop', () => {
render(React.createElement(Card, { renderImage: () => React.createElement("div", { "data-testid": "dummy-div" }) }));
expect(screen.queryAllByTestId('dummy-div')).toHaveLength(1);
});
it('should use the `renderImage` prop even if the user provides an `imgSrc`', () => {
render(
/* @ts-expect-error should be illegal to use `renderImage` and `imgSrc` at the same time */
React.createElement(Card, { renderImage: () => React.createElement("div", { "data-testid": "dummy-div2" }), imgSrc: "https://flowbite.com/docs/images/blog/image-1.jpg" }));
expect(screen.queryAllByTestId('dummy-div2')).toHaveLength(1);
expect(screen.queryAllByTestId('flowbite-card-image')).toHaveLength(0);
});
it('should provide the theme and horizontal flag to the `renderImage` function', () => {
const spy = vi.fn(() => React.createElement("div", { "data-testid": "dummy-div2" }));
render(React.createElement(Card, { renderImage: spy }));
expect(spy).toHaveBeenCalledWith(expect.any(Object), false);
});
});
describe('A11y', () => {
it('should allow `aria-label`', () => {
render(React.createElement(Card, { "aria-label": "My card" }));
expect(card()).toHaveAccessibleName('My card');
});
it('should provide `<img />` with alternative text given `imgSrc="..."` and `imgAlt="..."`', () => {
render(React.createElement(Card, { imgAlt: "Meaningful alt text for an image that is not purely decorative", imgSrc: "https://flowbite.com/docs/images/blog/image-1.jpg" }));
const img = screen.getByAltText('Meaningful alt text for an image that is not purely decorative');
expect(img).toBeInTheDocument();
});
});
describe('Rendering', () => {
it('should render an `<a>` given `href=".."`', () => {
render(React.createElement(Card, { href: "#" }));
expect(screen.getByRole('link')).toEqual(card());
});
it('should render an `<img>` given `imgSrc=".."`', () => {
render(React.createElement(Card, { imgSrc: "https://flowbite.com/docs/images/blog/image-1.jpg" }));
const img = screen.getByRole('img');
expect(card()).toContainElement(img);
});
});
describe('Theme', () => {
it('should use `base` classes', () => {
const theme = {
card: {
root: {
base: 'text-cyan-100',
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(Card, null)));
expect(card()).toHaveClass('text-cyan-100');
});
it('should use `children` classes', () => {
const theme = {
card: {
root: {
children: 'text-cyan-900',
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(Card, null,
React.createElement("span", { "aria-label": "The content" }, "Some content"))));
const children = screen.getByLabelText('The content');
expect(children.parentElement).toHaveClass('text-cyan-900');
});
it('should use `horizontal` classes', () => {
const theme = {
card: {
root: {
horizontal: {
off: 'text-cyan-200',
on: 'text-cyan-300',
},
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(Card, null),
React.createElement(Card, { horizontal: true })));
const normalCard = cards()[0];
const horizontalCard = cards()[1];
expect(normalCard).toHaveClass('text-cyan-200');
expect(horizontalCard).toHaveClass('text-cyan-300');
});
it('should use `href` classes', () => {
const theme = {
card: {
root: {
href: 'text-cyan-700',
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(Card, { href: "#" }, "My card")));
expect(card()).toHaveClass('text-cyan-700');
});
it('should use `img` classes', () => {
const theme = {
card: {
img: {
base: 'text-cyan-400',
horizontal: {
off: 'bg-cyan-500',
on: 'bg-cyan-600',
},
},
},
};
render(React.createElement(Flowbite, { theme: { theme } },
React.createElement(Card, { imgAlt: "Card with image", imgSrc: "https://flowbite.com/docs/images/blog/image-1.jpg" }),
React.createElement(Card, { horizontal: true, imgAlt: "Horizontal card with image", imgSrc: "https://flowbite.com/docs/images/blog/image-1.jpg" })));
const cardWithImage = screen.getByAltText('Card with image');
const horizontalCardWithImage = screen.getByAltText('Horizontal card with image');
expect(cardWithImage).toHaveClass('text-cyan-400 bg-cyan-500');
expect(horizontalCardWithImage).toHaveClass('bg-cyan-600');
});
});
});
const card = () => screen.getByTestId('flowbite-card');
const cards = () => screen.getAllByTestId('flowbite-card');