Skip to content

Commit

Permalink
Merge pull request #122 from JohnsonMao/refactor/unit-test
Browse files Browse the repository at this point in the history
♻️ refactor unit test and minor changes
  • Loading branch information
JohnsonMao authored Dec 23, 2023
2 parents bd9168e + cbaddcb commit c7a2cde
Show file tree
Hide file tree
Showing 37 changed files with 372 additions and 385 deletions.
5 changes: 2 additions & 3 deletions src/app/[lang]/__tests__/card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Article from '../Article';

describe('Article component', () => {
it('should render correct element', () => {
// Arrange
const data: DataFrontmatter = {
id: 'test_id',
title: 'title test',
Expand All @@ -17,13 +18,11 @@ describe('Article component', () => {
tags: ['tag_A', 'tag_B'],
description: 'description test',
};

render(<Article {...data} />);

const article = screen.getByRole('article');
const image = screen.getByRole('img');
const heading = screen.getByRole('heading');

// Assert
expect(article).toBeInTheDocument();
expect(image).toHaveAttribute('src', data.image);
expect(image).toHaveAttribute('alt', `${data.title} cover`);
Expand Down
5 changes: 2 additions & 3 deletions src/app/[lang]/__tests__/footer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ import Footer from '../Footer';

describe('Footer component', () => {
it('should render correct element', () => {
// Arrange
const footerCopyright = 'footer copyright';

render(<Footer copyright={footerCopyright} />);

const footer = screen.getByRole('contentinfo');

// Assert
expect(footer).toBeInTheDocument();
expect(footer).toHaveTextContent(footerCopyright);
});
Expand Down
89 changes: 38 additions & 51 deletions src/app/[lang]/__tests__/header.test.tsx
Original file line number Diff line number Diff line change
@@ -1,89 +1,76 @@
import { act, render, screen, waitFor } from '@testing-library/react';
import Header, { Avatar } from '../Header';

const scrollDownTo = (to: number) => {
act(() => {
window.scrollY = to - 1;
window.dispatchEvent(new Event('scroll'));
window.scrollY = to;
window.dispatchEvent(new Event('scroll'));
});
}
const scrollUpTo = (to: number) => {
act(() => {
window.scrollY = to + 1;
window.dispatchEvent(new Event('scroll'));
window.scrollY = to;
window.dispatchEvent(new Event('scroll'));
});
}

describe('Header component', () => {
const avatar = (
<Avatar src="https://external.com/test.jpg" alt="test avatar image alt" />
);

it('should render correct element', () => {
// Arrange
render(<Header avatar={avatar} />);

const brandLink = screen.getByRole('img');

// Assert
expect(brandLink).toBeInTheDocument();
expect(brandLink.parentElement).toHaveAttribute('href', '/');
});

it('should hide header on scroll down and show on scroll up', async () => {
// Arrange
render(<Header avatar={avatar} scrollThreshold={100} />);

const header = screen.getByRole('banner');

expect(header.tagName).toBe('HEADER');

act(() => {
window.scrollY = 19;
window.dispatchEvent(new Event('scroll'));
window.scrollY = 20;
window.dispatchEvent(new Event('scroll'));
});

// Act
scrollDownTo(20);
// Assert
await waitFor(() => {
expect(header).toHaveStyle({ '--header-translate-y': '0px' });
});

act(() => {
window.scrollY = 98;
window.dispatchEvent(new Event('scroll'));
window.scrollY = 99;
window.dispatchEvent(new Event('scroll'));
});

// Act
scrollDownTo(99);
// Assert
await waitFor(() => {
expect(header).toHaveStyle({ '--header-translate-y': '0px' });
});

act(() => {
window.scrollY = 149;
window.dispatchEvent(new Event('scroll'));
window.scrollY = 150;
window.dispatchEvent(new Event('scroll'));
});

// Act
scrollDownTo(150);
// Assert
await waitFor(() => {
expect(header).toHaveStyle({ '--header-translate-y': '50px' });
});

act(() => {
window.scrollY = 299;
window.dispatchEvent(new Event('scroll'));
window.scrollY = 300;
window.dispatchEvent(new Event('scroll'));
});

// Act
scrollDownTo(800);
// Assert
await waitFor(() => {
expect(header).toHaveStyle({ '--header-translate-y': '50px' });
});

act(() => {
window.scrollY = 501;
window.dispatchEvent(new Event('scroll'));
window.scrollY = 500;
window.dispatchEvent(new Event('scroll'));
});

// Act
scrollUpTo(500);
// Assert
await waitFor(() => {
expect(header).toHaveStyle({ '--header-translate-y': '300px' });
});

act(() => {
window.scrollY = 1;
window.dispatchEvent(new Event('scroll'));
window.scrollY = 0;
window.dispatchEvent(new Event('scroll'));
});

// Act
scrollUpTo(0);
// Assert
await waitFor(() => {
expect(header).toHaveStyle({ '--header-translate-y': '300px' });
});
Expand Down
15 changes: 7 additions & 8 deletions src/app/[lang]/__tests__/layout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,41 @@ import { locales } from '~/i18n';
import mockPathname from '~/tests/navigation';
import Layout, { generateMetadata, generateStaticParams } from '../layout';

describe('I18n layout component', () => {
describe('I18n layout', () => {
it('should render correct element', async () => {
// Arrange
const testText = 'Test layout component';

mockPathname.mockReturnValueOnce('/');

const layout = await Layout({
children: <h2>{testText}</h2>,
params: { lang: 'en' }
});

render(layout);

const testChildren = await screen.findByRole('heading');
const header = await screen.findByRole('banner');
const nav = await screen.findByRole('navigation');
const footer = await screen.findByRole('contentinfo');

// Assert
expect(testChildren).toHaveTextContent(testText);
expect(header).toBeInTheDocument();
expect(nav).toBeInTheDocument();
expect(footer).toBeInTheDocument();
});

it('should generate correct metadata', async () => {
// Arrange
const metadata = await generateMetadata({
params: { lang: 'en' },
});

// Assert
expect(metadata).toBeTruthy();
});

it('should generate correct static params', async () => {
// Arrange
const staticParams = await generateStaticParams();
const expected = locales.map(lang => ({ lang }));

// Assert
expect(staticParams).toStrictEqual(expected);
});
});
49 changes: 22 additions & 27 deletions src/app/[lang]/__tests__/menu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,48 @@ import mockPathname from '~/tests/navigation';
import Menu, { MenuProps } from '../Menu';

describe('Menu component', () => {
const menu: MenuProps['menu'] = [
{ text: 'Home', href: '/' },
{ text: 'Post', href: '/posts' },
];

it('should render correct element', () => {
// Arrange
const menu: MenuProps['menu'] = [
{ text: 'Home', href: '/' },
{ text: 'Post', href: '/posts' },
];
mockPathname.mockReturnValue('/');

render(<Menu menu={menu} />);

const nav = screen.getByRole('navigation');
const linkA = screen.getByRole('link', { name: menu[0].text });
const linkB = screen.getByRole('link', { name: menu[1].text });

// Assert
expect(nav).toBeInTheDocument();
expect(nav.tagName).toBe('NAV');

expect(linkA).toHaveTextContent(menu[0].text);
expect(linkA).toHaveAttribute('href', menu[0].href);

expect(linkB).toHaveTextContent(menu[1].text);
expect(linkB).toHaveAttribute('href', menu[1].href);
});

it.each([
['/', menu[0].text],
['/posts', menu[1].text],
['/en', menu[0].text],
['/en/posts', menu[1].text],
['/en/posts/test', menu[1].text],
['Home', 'Post', '/'],
['Post', 'Home', '/posts'],
['Home', 'Post', '/en'],
['Post', 'Home', '/en/posts'],
['Post', 'Home', '/en/posts/test'],
])(
'should render correct active link based on the pathname "%s"',
(pathname, activeLinkText) => {
(activeLinkText, otherLinkText, pathname) => {
// Arrange
const menu: MenuProps['menu'] = [
{ text: 'Home', href: '/' },
{ text: 'Post', href: '/posts' },
];
mockPathname.mockReturnValue(pathname);

render(<Menu menu={menu} />);

const links = screen.getAllByRole('link');
const activeLink = screen.getByRole('link', { name: activeLinkText });
const otherLink = screen.getByRole('link', { name: otherLinkText });
const activeClassName = 'neon-text';

links.forEach((link) => {
if (link.textContent === activeLinkText) {
expect(link).toHaveClass(activeClassName);
} else {
expect(link).not.toHaveClass(activeClassName);
}
});
// Assert
expect(activeLink).toHaveClass(activeClassName);
expect(otherLink).not.toHaveClass(activeClassName);
}
);
});
14 changes: 6 additions & 8 deletions src/app/[lang]/__tests__/page.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,25 @@ import en from '~/i18n/locales/en';
import Page, { generateMetadata } from '../page';

jest.mock('@/utils/mdx', () => ({
getAllDataFrontmatter: () => []
getAllDataFrontmatter: () => [],
}));

describe('Root page component', () => {
it('should render correct element', async () => {
const page = await Page({
params: { lang: 'en' },
});

// Arrange
const page = await Page({ params: { lang: 'en' } });
render(page);

const heading = await screen.findByRole('heading', { level: 1 });

// Assert
expect(heading).toBeInTheDocument();
});

it('should generate correct metadata', async () => {
// Arrange
const metadata = await generateMetadata({
params: { lang: 'en' },
});

// Assert
expect(metadata).toStrictEqual({ title: en.common.home });
});
});
Loading

0 comments on commit c7a2cde

Please sign in to comment.