diff --git a/src/components/ImageCard/ImageCard.test.tsx b/src/components/ImageCard/ImageCard.test.tsx new file mode 100644 index 0000000..21c381f --- /dev/null +++ b/src/components/ImageCard/ImageCard.test.tsx @@ -0,0 +1,63 @@ +import { describe, expect, it } from 'vitest' +import { screen } from '@testing-library/react' +import { render } from '@/tests/customRender' +import ImageCard from './ImageCard' + +describe('ImageCard', () => { + it('should render ImageCard component correctly with basic props', async () => { + render( + + ) + const image = await screen.findByRole('img') + expect(image).toHaveAttribute('src', 'Krizza.jpg') + expect(image).toHaveAttribute('alt', 'Cat 🐱') + expect(image).toBeVisible() + }) + + it('should apply custom width and height when provided', () => { + const testWidth = 300 + const testHeight = 200 + + render( + + ) + + const image = screen.getByRole('img') + expect(image).toHaveAttribute('width', testWidth.toString()) + expect(image).toHaveAttribute('height', testHeight.toString()) + expect(image).toBeVisible() + }) + + it('should handle string-based width and height', () => { + const testWidth = '50%' + const testHeight = 'auto' + + render( + + ) + + const image = screen.getByRole('img') + expect(image).toHaveAttribute('width', testWidth) + expect(image).toHaveAttribute('height', testHeight) + expect(image).toBeVisible() + }) + + it('should render even when width and height are not provided', () => { + render() + + const image = screen.getByRole('img') + expect(image).not.toHaveAttribute('width') + expect(image).not.toHaveAttribute('height') + expect(image).toBeVisible() + }) +}) diff --git a/src/components/TextBlock/Body1.test.tsx b/src/components/TextBlock/Body1.test.tsx new file mode 100644 index 0000000..764d5dc --- /dev/null +++ b/src/components/TextBlock/Body1.test.tsx @@ -0,0 +1,12 @@ +import { describe, expect, it } from 'vitest' +import { screen } from '@testing-library/react' +import { render } from '@/tests/customRender' +import Body1 from './Body1' + +describe('Body', () => { + it('should render Body component correctly', async () => { + render(Test) + const text = await screen.findByText('Test') + expect(text).toBeVisible() + }) +}) diff --git a/src/routes/CodeOfConduct/CodeOfConduct.test.tsx b/src/routes/CodeOfConduct/CodeOfConduct.test.tsx new file mode 100644 index 0000000..a5affbb --- /dev/null +++ b/src/routes/CodeOfConduct/CodeOfConduct.test.tsx @@ -0,0 +1,64 @@ +import { describe, expect, it, beforeEach } from 'vitest' +import { render } from '@/tests/customRender' +import { screen } from '@testing-library/react' +import CodeOfConduct from './CodeOfConduct' +import i18next from 'i18next' + +describe('CodeOfConduct Route', () => { + const changeLanguage = async (language: string) => { + await i18next.changeLanguage(language) + } + + describe('English Language', () => { + beforeEach(async () => { + await changeLanguage('en') + }) + + it('should display the Code of Conduct heading in English', async () => { + render() + const heading = await screen.findByRole('heading', { + name: 'Code of Conduct', + }) + expect(heading).toBeVisible() + }) + + it('should display all expected headings in English', async () => { + render() + const headings = await screen.findAllByRole('heading') + expect(headings).toHaveLength(5) + + expect(headings[0]).toHaveTextContent('Code of Conduct') + expect(headings[1]).toHaveTextContent('Women in Software Engineering Japan Statement of Intent') + expect(headings[2]).toHaveTextContent('Code of Conduct for Women in Software Engineering Japan Events') + expect(headings[3]).toHaveTextContent('How to Report Harassment and Discrimination') + expect(headings[4]).toHaveTextContent('Periodic Review') + }) + }) + + describe('Japanese Language', () => { + beforeEach(async () => { + await changeLanguage('ja') + }) + + it('should display the Code of Conduct heading in Japanese', async () => { + render() + const heading = await screen.findByRole('heading', { + name: '行動規範', + }) + expect(heading).toBeVisible() + }) + + it('should display all expected headings in Japanese', async () => { + render() + const headings = await screen.findAllByRole('heading') + expect(headings).toHaveLength(5) + + expect(headings[0]).toHaveTextContent('行動規範') + // FIXME: The other headings are have not been translated yet, testing the English headings for now + expect(headings[1]).toHaveTextContent('Women in Software Engineering Japan Statement of Intent') + expect(headings[2]).toHaveTextContent('Code of Conduct for Women in Software Engineering Japan Events') + expect(headings[3]).toHaveTextContent('How to Report Harassment and Discrimination') + expect(headings[4]).toHaveTextContent('Periodic Review') + }) + }) +}) diff --git a/src/routes/__test__/BaseLayout.test.tsx b/src/routes/__test__/BaseLayout.test.tsx new file mode 100644 index 0000000..941a90d --- /dev/null +++ b/src/routes/__test__/BaseLayout.test.tsx @@ -0,0 +1,79 @@ +import { lazy } from 'react' +import { Route, Routes } from 'react-router-dom' +import { describe, expect, it, vi } from 'vitest' +import { screen } from '@testing-library/react' +import { render } from '@/tests/customRender' +import BaseLayout from '../BaseLayout' +import '@/i18n/config' + +vi.mock('@/components/Header/Header', () => ({ + default: () =>
Header Component
, +})) + +vi.mock('@/components/Footer/Footer', () => ({ + default: () =>
Footer Component
, +})) + +const MockChildComponent = () => { + return
Child Content
+} + +const MockLazyChildComponent = lazy(() => + new Promise(() => {}) +) + +describe('BaseLayout', () => { + it('should render header, outlet, and footer components', () => { + render( + + }> + } /> + + + ) + + expect(screen.getByTestId('header')).toBeInTheDocument() + expect(screen.getByTestId('child-content')).toBeInTheDocument() + expect(screen.getByTestId('footer')).toBeInTheDocument() + }) + + it('should render components in correct order', () => { + render( + + }> + } /> + + + ) + + const container = screen.getByTestId('header').parentElement + const children = Array.from(container?.children || []) + + // Check that header comes first + expect(children[0]).toHaveAttribute('data-testid', 'header') + // Check that footer comes last + expect(children[children.length - 1]).toHaveAttribute( + 'data-testid', + 'footer' + ) + }) + + it('should show loading fallback when Suspense is triggered', () => { + render( + + }> + } /> + + + ) + + expect(screen.getByText('Loading...')).toBeInTheDocument() + }) + + it('should render without crashing when no child route is provided', () => { + render() + + expect(screen.getByTestId('header')).toBeInTheDocument() + expect(screen.getByTestId('footer')).toBeInTheDocument() + }) +}) diff --git a/src/routes/__test__/Router.test.tsx b/src/routes/__test__/Router.test.tsx new file mode 100644 index 0000000..1308ccf --- /dev/null +++ b/src/routes/__test__/Router.test.tsx @@ -0,0 +1,24 @@ +import { describe, expect, it, vi } from 'vitest' +import { render, screen } from '@testing-library/react' +import Router from '../Router' +import '@/i18n/config' + +vi.mock('../BaseLayout', () => ({ + default: ({ children }: { children: React.ReactNode }) => ( +
+
Header
+ {children} +
Footer
+
+ ) +})) + +describe('Router', () => { + it('should render RouterProvider with necessary components', () => { + render() + + expect(screen.getByTestId('base-layout')).toBeInTheDocument() + expect(screen.getByTestId('header')).toBeInTheDocument() + expect(screen.getByTestId('footer')).toBeInTheDocument() + }) +})