diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 3fc9c18..0580ba9 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -21,18 +21,23 @@ Object.defineProperty(window, 'matchMedia', { }); // Mock fetch -global.fetch = jest.fn((url: string) => { +global.fetch = jest.fn((input: RequestInfo | URL, init?: RequestInit) => { + const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url; if (url.includes('/api/files') && !url.includes('/api/files/')) { return Promise.resolve({ ok: true, + status: 200, + headers: new Headers(), json: () => Promise.resolve({ files: ['test.md'] }), - }); + } as Response); } return Promise.resolve({ ok: true, + status: 200, + headers: new Headers(), json: () => Promise.resolve({}), - }); -}) as jest.Mock; + } as Response); +}) as jest.MockedFunction; describe('App', () => { beforeEach(() => { @@ -54,22 +59,32 @@ describe('App', () => { }); test('opens file when clicked', async () => { - // Mock the file content fetch - fetch.mockImplementationOnce((url: string) => { + // Mock the file content fetch with a custom mock + const mockFetch = jest.fn((input: RequestInfo | URL, init?: RequestInit) => { + const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url; if (url.includes('/api/files')) { return Promise.resolve({ ok: true, + status: 200, + headers: new Headers(), json: () => Promise.resolve({ files: ['test.md'] }), - }); + } as Response); } if (url.includes('test.md')) { return Promise.resolve({ ok: true, + status: 200, + headers: new Headers(), json: () => Promise.resolve({ content: '# Test Content' }), - }); + } as Response); } - return Promise.resolve({ ok: true }); + return Promise.resolve({ + ok: true, + status: 200, + headers: new Headers(), + } as Response); }); + global.fetch = mockFetch; render(); @@ -89,15 +104,23 @@ describe('App', () => { test('creates new file', async () => { // Mock the create file endpoint - fetch.mockImplementationOnce((url: string) => { - if (url.includes('/api/files') && fetch.mock.calls.length === 1) { + const mockFetch = jest.fn((input: RequestInfo | URL, init?: RequestInit) => { + const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url; + if (url.includes('/api/files') && !init?.method) { return Promise.resolve({ ok: true, + status: 200, + headers: new Headers(), json: () => Promise.resolve({ files: [] }), - }); + } as Response); } - return Promise.resolve({ ok: true }); + return Promise.resolve({ + ok: true, + status: 200, + headers: new Headers(), + } as Response); }); + global.fetch = mockFetch; render(); @@ -117,7 +140,7 @@ describe('App', () => { // Verify fetch was called with POST await waitFor(() => { - expect(fetch).toHaveBeenCalledWith('/api/files', { + expect(mockFetch).toHaveBeenCalledWith('/api/files', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f0bff99..644d26b 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import ReactMarkdown from 'react-markdown'; -import { Box, Typography, TextField, Button, List, ListItem, ListItemText, IconButton, Divider, AppBar, Toolbar, Drawer, CssBaseline, useTheme, ThemeProvider, createTheme, Select, MenuItem, FormControl, InputLabel } from '@mui/material'; -import { Delete, Edit, Add, Save, Menu as MenuIcon } from '@mui/icons-material'; +import { Box, Typography, TextField, Button, List, ListItem, ListItemText, IconButton, Divider, AppBar, Toolbar, Drawer, CssBaseline, ThemeProvider, createTheme, Select, MenuItem, FormControl, InputLabel, SelectChangeEvent } from '@mui/material'; +import { Delete, Add, Save, Menu as MenuIcon } from '@mui/icons-material'; interface FileItem { filename: string; @@ -116,7 +116,7 @@ const App: React.FC = () => { }, }); - const handleThemeChange = (event: React.ChangeEvent<{ value: unknown }>) => { + const handleThemeChange = (event: SelectChangeEvent<'light' | 'dark' | 'system'>) => { setThemeMode(event.target.value as 'light' | 'dark' | 'system'); };