From 408d9f96f3f1a12708c953ac728c5a2eeaa958ab Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Tue, 6 Feb 2024 01:29:33 +0000 Subject: [PATCH] more unit tests --- src/app/__tests__/page.test.tsx | 5 ++ src/components/Location/Location.tsx | 79 ++++++++++++++++------------ src/lib/getRepos.test.ts | 57 ++++++++++++++++++++ tests/jest.setup.ts | 5 -- 4 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 src/lib/getRepos.test.ts diff --git a/src/app/__tests__/page.test.tsx b/src/app/__tests__/page.test.tsx index 8226bc8..509628a 100644 --- a/src/app/__tests__/page.test.tsx +++ b/src/app/__tests__/page.test.tsx @@ -1,6 +1,11 @@ import { render, screen } from '@testing-library/react' +import reposMock from '../../../tests/__fixtures__/repos.json' import Page from '../page' +jest.mock('../../lib/getRepos', () => ({ + getRepos: jest.fn().mockImplementation(() => reposMock) +})) + describe('app: /page', () => { it('renders correctly', async () => { render(await Page()) diff --git a/src/components/Location/Location.tsx b/src/components/Location/Location.tsx index ed7adf5..cf27f2e 100644 --- a/src/components/Location/Location.tsx +++ b/src/components/Location/Location.tsx @@ -9,8 +9,24 @@ import { Flag } from './Flag' import styles from './Location.module.css' import { UseLocation } from './types' -export default function Location() { +function Animation({ children }: { children: React.ReactNode }) { const shouldReduceMotion = useReducedMotion() + + return ( + + + {children} + + + ) +} + +export default function Location() { const [isPending, startTransition] = useTransition() const [location, setLocation] = useState(null) @@ -27,40 +43,33 @@ export default function Location() { return (
{!isPending && location?.now?.city ? ( - - - - {location.now.city} Now -
- {location?.next?.city && ( - <> - {isDifferentCountry && ( - - )} - {location.next.city}{' '} - - {relativeTime.from(new Date(location.next.date_start))} - - - )} -
-
-
+ + + {location.now.city} Now +
+ {location?.next?.city && ( + <> + {isDifferentCountry && ( + + )} + {location.next.city}{' '} + + {relativeTime.from(new Date(location.next.date_start))} + + + )} +
+
) : null}
) diff --git a/src/lib/getRepos.test.ts b/src/lib/getRepos.test.ts new file mode 100644 index 0000000..b1d8ebc --- /dev/null +++ b/src/lib/getRepos.test.ts @@ -0,0 +1,57 @@ +import * as React from 'react' +import fetch, { FetchMock } from 'jest-fetch-mock' +import repoFilter from '@content/repos.json' +import { getRepos } from './getRepos' + +jest.mock('react', () => ({ + ...jest.requireActual('react'), + cache: (fn) => fn +})) + +describe('getRepos', () => { + beforeEach(() => { + fetch.resetMocks() + }) + + it('should fetch repos data', async () => { + const mockData = { + name: 'test', + full_name: 'test/test', + description: 'test repo', + html_url: 'https://github.com/test/test', + homepage: 'https://test.com', + stargazers_count: 100, + pushed_at: '2022-01-01T00:00:00Z' + } + ;(fetch as FetchMock).mockResponse(JSON.stringify(mockData)) + + const data = await getRepos() + const count = repoFilter.length + + expect(data).toEqual(Array.from({ length: count }, () => mockData)) + expect(fetch).toHaveBeenCalledTimes(count) + }) + + it('should handle network errors', async () => { + let consoleErrorMock: jest.SpyInstance + consoleErrorMock = jest.spyOn(console, 'error').mockImplementation(() => {}) + ;(fetch as FetchMock).mockRejectOnce(new Error('Network error')) + + const data = await getRepos() + + expect(data).toBeUndefined() + expect(fetch).toHaveBeenCalledTimes(1) + + consoleErrorMock.mockRestore() + }) + + it('should handle invalid repo data', async () => { + const mockData = { name: null } + ;(fetch as FetchMock).mockResponseOnce(JSON.stringify(mockData)) + + const data = await getRepos() + + expect(data).toBeUndefined() + expect(fetch).toHaveBeenCalledTimes(1) + }) +}) diff --git a/tests/jest.setup.ts b/tests/jest.setup.ts index b542ce5..20a989d 100644 --- a/tests/jest.setup.ts +++ b/tests/jest.setup.ts @@ -3,7 +3,6 @@ import '@testing-library/jest-dom' import fetchMock from 'jest-fetch-mock' import giphyMock from './__fixtures__/giphy.json' import { dataLocation } from './__fixtures__/location' -import reposMock from './__fixtures__/repos.json' import './__mocks__/matchMedia' fetchMock.enableMocks() @@ -23,10 +22,6 @@ jest.mock('../src/lib/getRandomGif', () => ({ .mockImplementation(() => giphyMock.data.images.original.mp4) })) -jest.mock('../src/lib/getRepos', () => ({ - getRepos: jest.fn().mockImplementation(() => reposMock) -})) - const unmockedFetch = global.fetch const unmockedEnv = process.env