Skip to content

Commit f5c4928

Browse files
committed
test: 💍 upgrade test setup to react@19
1 parent a911de3 commit f5c4928

11 files changed

Lines changed: 536 additions & 141 deletions

File tree

app/tests/layout.test.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ const TestComponent = () => {
3131
}
3232

3333
describe('RootLayout', () => {
34-
beforeAll(() => {
35-
// ? NOTE: This is here because of `validateDOMNesting` warnings that come from testing layout.tsx files. @see https://github.com/testing-library/react-testing-library/issues/1250.
36-
// ? NOTE: Should be able to fix for this in RTL + React 19.
37-
vi.stubGlobal('console', { ...console, warn: vi.fn(), log: vi.fn(), error: vi.fn() })
38-
})
39-
4034
beforeEach(() => {
4135
vi.mocked(usePathname).mockReturnValueOnce('/')
4236
})
@@ -45,25 +39,22 @@ describe('RootLayout', () => {
4539
vi.clearAllMocks()
4640
})
4741

48-
afterAll(() => {
49-
vi.unstubAllGlobals()
50-
})
51-
5242
it('displays the TopNavBar', async () => {
53-
render(await RootLayout({ children: <TestComponent /> }))
43+
render(await RootLayout({ children: <TestComponent /> }), { container: document })
5444

5545
expect(screen.getByRole('navigation')).toBeInTheDocument()
5646
})
5747

5848
it('displays the footer', async () => {
59-
render(await RootLayout({ children: <TestComponent /> }))
49+
render(await RootLayout({ children: <TestComponent /> }), { container: document })
6050

6151
expect(screen.getByRole('contentinfo')).toBeInTheDocument()
6252
})
6353

6454
it('includes ahrefs site verification', async () => {
65-
const { container } = render(await RootLayout({ children: <TestComponent /> }))
55+
const { container } = render(await RootLayout({ children: <TestComponent /> }), { container: document })
6656

67-
expect(container.querySelector('meta[name="ahrefs-site-verification"]')).toBeInTheDocument()
57+
const ahrefsMetaTag = container.querySelector('meta[name="ahrefs-site-verification"]')
58+
expect(ahrefsMetaTag).toBeInTheDocument()
6859
})
6960
})

components/app-shell/mode-toggle-menu.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import { Moon, Sun } from 'lucide-react'
44
import { useTheme } from 'next-themes'
5-
import * as React from 'react'
65

76
import { Button } from '@/components/ui/button'
87
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'

components/app-shell/tests/mobile-menu.test.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
import { render, screen, waitFor } from '@testing-library/react'
22
import userEvent from '@testing-library/user-event'
3+
import { http, HttpResponse } from 'msw'
4+
import { setupServer } from 'msw/node'
35
import { useTheme } from 'next-themes'
6+
import RSS from 'rss'
47

58
import { MobileMenu } from '../mobile-menu'
69

10+
import { SITE_MAP_CATEGORIES } from '@/app/rss.xml/constants'
11+
import { EMAIL, JAMES_WALSH, PRODUCTION_URL, SITE_DESCRIPTION } from '@/lib/constants'
12+
713
const mockSetTheme = vi.fn()
814

915
vi.mock('next-themes', () => ({
@@ -13,7 +19,28 @@ vi.mock('next/router', () => ({
1319
useRouter: vi.fn(),
1420
}))
1521

22+
const server = setupServer(
23+
http.get('/rss.xml', () => {
24+
return HttpResponse.xml(
25+
new RSS({
26+
title: JAMES_WALSH,
27+
description: SITE_DESCRIPTION,
28+
site_url: PRODUCTION_URL,
29+
feed_url: `${PRODUCTION_URL}/feed.xml`,
30+
copyright: `${new Date().getFullYear()} ${JAMES_WALSH}}`,
31+
managingEditor: EMAIL,
32+
webMaster: EMAIL,
33+
language: 'en-us',
34+
pubDate: new Date(),
35+
categories: SITE_MAP_CATEGORIES,
36+
}).xml({ indent: true }),
37+
)
38+
}),
39+
)
40+
1641
describe('components/app-shell/MobileMenu', () => {
42+
beforeAll(() => server.listen())
43+
1744
beforeEach(() => {
1845
vi.mocked(useTheme).mockReturnValue({
1946
theme: 'light',
@@ -24,8 +51,11 @@ describe('components/app-shell/MobileMenu', () => {
2451

2552
afterEach(() => {
2653
vi.clearAllMocks()
54+
server.resetHandlers()
2755
})
2856

57+
afterAll(() => server.close())
58+
2959
it('renders the mobile menu as a sheet', () => {
3060
render(<MobileMenu />)
3161
expect(screen.getByTestId('mobile-menu-trigger')).toBeInTheDocument()
@@ -37,7 +67,7 @@ describe('components/app-shell/MobileMenu', () => {
3767
{ dataTestId: 'about-nav-item', expectedText: /about/i },
3868
{ dataTestId: 'stack-nav-item', expectedText: /stack/i },
3969
{ dataTestId: 'portfolio-nav-item', expectedText: /portfolio/i },
40-
{ dataTestId: 'rss-feed-text-nav-item', expectedText: /get rss feed/i }, // TODO: In the future, using MSW for this would be preferred.
70+
{ dataTestId: 'rss-feed-text-nav-item', expectedText: /get rss feed/i },
4171
{ dataTestId: 'mode-toggle-text-nav-item', expectedText: /toggle light mode|toggle dark mode/i },
4272
])('displays nav item for $expectedText', async ({ dataTestId, expectedText }) => {
4373
const user = userEvent.setup()

components/app-shell/tests/mode-toggle-menu.test.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { render, screen, waitFor, act } from '@testing-library/react'
1+
import { render, screen, waitFor } from '@testing-library/react'
22
import { userEvent } from '@testing-library/user-event'
33
import { useTheme } from 'next-themes'
44

@@ -8,6 +8,7 @@ const mockSetTheme = vi.fn()
88

99
vi.mock('next-themes', () => ({
1010
useTheme: vi.fn(),
11+
setTheme: vi.fn(),
1112
}))
1213

1314
describe('components/app-shell/ModeToggleMenu', () => {
@@ -48,7 +49,7 @@ describe('components/app-shell/ModeToggleMenu', () => {
4849
screen.getByRole('menu')
4950
})
5051

51-
await act(async () => await user.click(screen.getByRole('menuitem', { name: input })))
52+
await user.click(screen.getByRole('menuitem', { name: input }))
5253

5354
expect(mockSetTheme).toHaveBeenCalledOnce()
5455
expect(mockSetTheme).toHaveBeenCalledWith(expected)

components/icons/LinkedIn.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ export const LinkedIn = (props: HTMLAttributes<SVGElement>) => {
1414
viewBox="0 0 24 24"
1515
fill="none"
1616
stroke="currentColor"
17-
stroke-width="2"
18-
stroke-linecap="round"
19-
stroke-linejoin="round"
17+
strokeWidth="2"
18+
strokeLinecap="round"
19+
strokeLinejoin="round"
2020
{...props}
2121
>
2222
<path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path>

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"format": "prettier --write .",
2121
"format:check": "prettier --check .",
2222
"lint": "next lint",
23-
"lint:fix": "pnpm lint -- --fix",
23+
"lint:fix": "pnpm lint --fix",
2424
"precommit": "pnpm spell && pnpm lint && pnpm format",
2525
"prepush": "pnpm typecheck && vitest --run",
2626
"prepare": "husky install",
@@ -67,9 +67,9 @@
6767
"@commitlint/cli": "19.6.0",
6868
"@commitlint/config-conventional": "19.6.0",
6969
"@playwright/test": "1.52.0",
70-
"@testing-library/jest-dom": "6.5.0",
71-
"@testing-library/react": "16.0.1",
72-
"@testing-library/user-event": "14.5.2",
70+
"@testing-library/jest-dom": "6.6.3",
71+
"@testing-library/react": "16.3.0",
72+
"@testing-library/user-event": "14.6.1",
7373
"@types/node": "22.7.5",
7474
"@types/react": "19.1.5",
7575
"@types/react-dom": "19.1.5",
@@ -87,6 +87,7 @@
8787
"git-cz": "4.9.0",
8888
"happy-dom": "^15.11.7",
8989
"husky": "^8.0.3",
90+
"msw": "2.8.4",
9091
"postcss": "^8.4.38",
9192
"prettier": "^3.3.3",
9293
"prettier-plugin-tailwindcss": "^0.6.9",
@@ -99,6 +100,6 @@
99100
"tailwindcss-animate": "^1.0.7",
100101
"typescript": "5.8.3",
101102
"vite-tsconfig-paths": "^5.1.2",
102-
"vitest": "^2.1.3"
103+
"vitest": "3.1.4"
103104
}
104105
}

0 commit comments

Comments
 (0)