Covers Badge, Divider, EmptyState, Numeric, PriceDelta, Signal, Skeleton, StatusChip, Surface, StatCard, KpiCard, DensityToggle, Footer, MarketIndex, CompactHeader — rendering, variants, props, a11y attributes, className merging. All 1139 web tests pass. Zustand persist store mocked for DensityToggle to avoid jsdom localStorage incompatibility. Co-Authored-By: Paperclip <noreply@paperclip.ing>
88 lines
2.6 KiB
TypeScript
88 lines
2.6 KiB
TypeScript
import { render, screen } from '@testing-library/react';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { Footer, type FooterProps } from '../footer';
|
|
|
|
const renderLink: FooterProps['renderLink'] = ({ href, children, className }) => (
|
|
<a href={href} className={className}>{children}</a>
|
|
);
|
|
|
|
const defaultProps: FooterProps = {
|
|
brand: 'GoodGo',
|
|
description: 'Nền tảng bất động sản',
|
|
copyright: '© 2024 GoodGo',
|
|
linkGroups: [
|
|
{
|
|
title: 'Sản phẩm',
|
|
links: [
|
|
{ label: 'Bán', href: '/ban' },
|
|
{ label: 'Thuê', href: '/thue' },
|
|
],
|
|
},
|
|
],
|
|
renderLink,
|
|
};
|
|
|
|
describe('Footer', () => {
|
|
it('renders brand name', () => {
|
|
render(<Footer {...defaultProps} />);
|
|
expect(screen.getByText('GoodGo')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders description', () => {
|
|
render(<Footer {...defaultProps} />);
|
|
expect(screen.getByText('Nền tảng bất động sản')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders copyright text', () => {
|
|
render(<Footer {...defaultProps} />);
|
|
expect(screen.getByText('© 2024 GoodGo')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders link group title', () => {
|
|
render(<Footer {...defaultProps} />);
|
|
expect(screen.getByText('Sản phẩm')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders link group links', () => {
|
|
render(<Footer {...defaultProps} />);
|
|
expect(screen.getByText('Bán')).toBeInTheDocument();
|
|
expect(screen.getByText('Thuê')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders contact address when provided', () => {
|
|
render(
|
|
<Footer
|
|
{...defaultProps}
|
|
contact={{ address: '123 Nguyễn Huệ, TP.HCM' }}
|
|
/>,
|
|
);
|
|
expect(screen.getByText('123 Nguyễn Huệ, TP.HCM')).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders contact phone with tel link', () => {
|
|
render(<Footer {...defaultProps} contact={{ phone: '0901234567' }} />);
|
|
expect(screen.getByRole('link', { name: '0901234567' })).toHaveAttribute(
|
|
'href',
|
|
'tel:0901234567',
|
|
);
|
|
});
|
|
|
|
it('renders contact email with mailto link', () => {
|
|
render(<Footer {...defaultProps} contact={{ email: 'hello@goodgo.vn' }} />);
|
|
expect(screen.getByRole('link', { name: 'hello@goodgo.vn' })).toHaveAttribute(
|
|
'href',
|
|
'mailto:hello@goodgo.vn',
|
|
);
|
|
});
|
|
|
|
it('renders footer element with role="contentinfo"', () => {
|
|
render(<Footer {...defaultProps} />);
|
|
expect(screen.getByRole('contentinfo')).toBeInTheDocument();
|
|
});
|
|
|
|
it('does not render contact section when omitted', () => {
|
|
render(<Footer {...defaultProps} />);
|
|
expect(screen.queryByText(/Nguyễn Huệ/)).toBeNull();
|
|
});
|
|
});
|