diff --git a/package.json b/package.json index 0410019..5b73b04 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,8 @@ "@commitlint/config-conventional": "^19.2.2", "@rocketseat/eslint-config": "^2.2.2", "@testing-library/jest-dom": "^6.4.5", - "@testing-library/react": "^15.0.7", + "@testing-library/react": "^15.0.7", + "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", "@types/mocha": "^10.0.6", "@types/node": "^20.12.12", diff --git a/src/components/footer/index.test.tsx b/src/components/footer/index.test.tsx index 2f3ae87..eee1cab 100644 --- a/src/components/footer/index.test.tsx +++ b/src/components/footer/index.test.tsx @@ -21,8 +21,6 @@ describe('AppFooter', () => { expect(linkElement).toBeInTheDocument() if (menu.href.startsWith('http')) { expect(linkElement.closest('a')).toHaveAttribute('href', menu.href) - } else { - expect(linkElement.closest('a')).toHaveAttribute('href', menu.href) } }) }) diff --git a/src/components/footer/socials.test.tsx b/src/components/footer/socials.test.tsx new file mode 100644 index 0000000..fb555a1 --- /dev/null +++ b/src/components/footer/socials.test.tsx @@ -0,0 +1,20 @@ +import { socials } from './socials' + +describe('socials', () => { + it('should have at least one social link', () => { + expect(socials.length).toBeGreaterThan(0) + }) + + it('should have valid href values', () => { + socials.forEach((social) => { + expect(social.href).toMatch(/^https?:\/\/[^\s/$.?#].[^\s]*$/) + }) + }) + + it('should have valid icon components', () => { + socials.forEach((social) => { + expect(social.icon).toBeDefined() + expect(typeof social.icon).toBe('object') + }) + }) +}) diff --git a/src/components/header/index.test.tsx b/src/components/header/index.test.tsx new file mode 100644 index 0000000..9b5fd21 --- /dev/null +++ b/src/components/header/index.test.tsx @@ -0,0 +1,65 @@ +import { AppHeader } from '@/components/header' +import '@testing-library/jest-dom' +import { fireEvent, render, screen } from '@testing-library/react' +import { BrowserRouter as Router } from 'react-router-dom' + +jest.mock('@/hooks/useIsMobile', () => ({ + useIsMobile: () => true, +})) + +jest.mock('@uidotdev/usehooks', () => ({ + useWindowScroll: () => [{ y: 0 }], +})) + +describe('AppHeader', () => { + it('renders without crashing', () => { + render( + + + , + ) + }) + it('displays the hamburger menu icon on mobile', () => { + render( + + + , + ) + const hamburgerMenuIcon = screen.getByRole('button') + expect(hamburgerMenuIcon).toBeInTheDocument() + }) + + it('displays the navigation menu when the hamburger menu icon is clicked', () => { + render( + + + , + ) + const hamburgerMenuIcon = screen.getByRole('button') + fireEvent.click(hamburgerMenuIcon) + const navMenu = screen.getByRole('navigation') + expect(navMenu).toBeInTheDocument() + }) + + it('displays the "Voltar à home" link when not on the home page', () => { + window.history.pushState({}, '', '/not-home') + render( + + + , + ) + const link = screen.getByText('Voltar à home') + expect(link).toBeInTheDocument() + }) + + it('displays the "Cadastrar um pet" link when not on the subscription page', () => { + window.history.pushState({}, '', '/not-subscription') + render( + + + , + ) + const link = screen.getByText('Cadastrar um pet') + expect(link).toBeInTheDocument() + }) +}) diff --git a/src/components/join-us/index.test.tsx b/src/components/join-us/index.test.tsx new file mode 100644 index 0000000..b1aa19e --- /dev/null +++ b/src/components/join-us/index.test.tsx @@ -0,0 +1,32 @@ +import '@testing-library/jest-dom' +import { render, screen } from '@testing-library/react' +import { JoinUs } from './index' + +describe('JoinUs component', () => { + beforeEach(() => { + render() + }) + + it('renders without crashing', () => { + const joinUsElement = screen.getByText(/Faça parte da nossa equipe/i) + expect(joinUsElement).toBeInTheDocument() + }) + + it('contains a Paw component', () => { + const pawElement = screen.getByTestId('join-us-paw') + expect(pawElement).toBeInTheDocument() + }) + + it('contains a Button component', () => { + const buttonElement = screen.getByTestId('join-us-button') + expect(buttonElement).toBeInTheDocument() + }) + + it('contains a link to the Discord server', () => { + const linkElement = screen.getByRole('link') + expect(linkElement).toHaveAttribute( + 'href', + 'https://discord.com/invite/Pr2BZmUG', + ) + }) +}) diff --git a/src/components/join-us/index.tsx b/src/components/join-us/index.tsx index 47b1e96..2d4ea72 100644 --- a/src/components/join-us/index.tsx +++ b/src/components/join-us/index.tsx @@ -6,7 +6,10 @@ export function JoinUs() { return (
- +

Faça parte da nossa equipe @@ -20,6 +23,7 @@ export function JoinUs() {

+ + + + , + ) + + expect(screen.findByRole('dialog')).toBeDefined() + }) +}) diff --git a/src/components/ui/image-with-loader.test.tsx b/src/components/ui/image-with-loader.test.tsx new file mode 100644 index 0000000..9a2a9dd --- /dev/null +++ b/src/components/ui/image-with-loader.test.tsx @@ -0,0 +1,25 @@ +import { render } from '@testing-library/react' +import { ImageWithLoader } from './image-with-loader' +import '@testing-library/jest-dom' + +describe('ImageWithLoader', () => { + it('renders without errors', () => { + render() + }) + + it('renders with the correct alt text', () => { + const altText = 'Test Image' + const { getByAltText } = render( + , + ) + expect(getByAltText(altText)).toBeInTheDocument() + }) + + it('applies the provided className', () => { + const className = 'custom-class' + const { container } = render( + , + ) + expect(container.firstChild).toHaveClass(className) + }) +}) diff --git a/src/components/ui/input-masked.test.tsx b/src/components/ui/input-masked.test.tsx new file mode 100644 index 0000000..bc5bb48 --- /dev/null +++ b/src/components/ui/input-masked.test.tsx @@ -0,0 +1,20 @@ +import '@testing-library/jest-dom' +import { render, screen } from '@testing-library/react' +import React from 'react' +import { MaskedInput } from './input-masked' + +describe('MaskedInput', () => { + it('renders without errors', () => { + render() + expect(screen.getByRole('textbox')).toBeInTheDocument() + }) + it('renders with custom class name', () => { + render() + expect(screen.getByRole('textbox')).toHaveClass('custom-input') + }) + it('forwards ref to the input element', () => { + const ref = React.createRef() + render() + expect(ref.current).toBeInstanceOf(HTMLInputElement) + }) +}) diff --git a/src/components/ui/input.test.tsx b/src/components/ui/input.test.tsx new file mode 100644 index 0000000..9d07ba3 --- /dev/null +++ b/src/components/ui/input.test.tsx @@ -0,0 +1,30 @@ +import '@testing-library/jest-dom' +import { fireEvent, render, screen } from '@testing-library/react' +import React from 'react' +import { Input } from './input' + +describe('Input', () => { + test('renders without errors', () => { + render() + expect(screen.getByRole('textbox')).toBeInTheDocument() + }) + + test('renders with custom class name', () => { + render() + expect(screen.getByRole('textbox')).toHaveClass('custom-input') + }) + + test('forwards ref to the input element', () => { + const ref = React.createRef() + render() + expect(ref.current).toBeInstanceOf(HTMLInputElement) + }) + + test('triggers onChange event', () => { + const handleChange = jest.fn() + render() + fireEvent.change(screen.getByRole('textbox'), { target: { value: 'test' } }) + expect(handleChange).toHaveBeenCalledTimes(1) + expect(handleChange).toHaveBeenCalledWith(expect.any(Object)) + }) +}) diff --git a/src/components/ui/textearea.test.tsx b/src/components/ui/textearea.test.tsx new file mode 100644 index 0000000..105cf7a --- /dev/null +++ b/src/components/ui/textearea.test.tsx @@ -0,0 +1,31 @@ +import '@testing-library/jest-dom' +import { render, screen } from '@testing-library/react' +import { Textarea } from './textarea' + +describe('Textarea', () => { + test('renders without errors', () => { + render(