From e3c379d069ffa9661561d25cdbf2f5894a2f8ee8 Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Sat, 14 Feb 2026 08:58:38 -0800 Subject: Refactor: project structure, implement dependency injection, and align v2 UI with v1 --- frontend/src/components/FeedList.test.tsx | 200 ++++++++++++++++-------------- 1 file changed, 106 insertions(+), 94 deletions(-) (limited to 'frontend/src/components/FeedList.test.tsx') diff --git a/frontend/src/components/FeedList.test.tsx b/frontend/src/components/FeedList.test.tsx index d5f49b7..daa4d69 100644 --- a/frontend/src/components/FeedList.test.tsx +++ b/frontend/src/components/FeedList.test.tsx @@ -7,114 +7,126 @@ import FeedList from './FeedList'; import { BrowserRouter } from 'react-router-dom'; describe('FeedList Component', () => { - beforeEach(() => { - vi.resetAllMocks(); - global.fetch = vi.fn(); - }); - - it('renders loading state initially', () => { - (global.fetch as any).mockImplementation(() => new Promise(() => { })); - render( - - {/* @ts-ignore */} - { }} /> - - ); - expect(screen.getByText(/loading feeds/i)).toBeInTheDocument(); - }); - - it('renders list of feeds', async () => { - const mockFeeds = [ - { _id: 1, title: 'Feed One', url: 'http://example.com/rss', web_url: 'http://example.com', category: 'Tech' }, - { _id: 2, title: 'Feed Two', url: 'http://test.com/rss', web_url: 'http://test.com', category: 'News' }, - ]; - - (global.fetch as any).mockImplementation((url: string) => { - if (url.includes('/api/feed/')) { - return Promise.resolve({ - ok: true, - json: async () => mockFeeds, - }); - } - if (url.includes('/api/tag')) { - return Promise.resolve({ - ok: true, - json: async () => [{ title: 'Tech' }], - }); - } - return Promise.reject(new Error(`Unknown URL: ${url}`)); + beforeEach(() => { + vi.resetAllMocks(); + global.fetch = vi.fn(); + }); + + it('renders loading state initially', () => { + (global.fetch as any).mockImplementation(() => new Promise(() => {})); + render( + + {/* @ts-ignore */} + {}} /> + + ); + expect(screen.getByText(/loading feeds/i)).toBeInTheDocument(); + }); + + it('renders list of feeds', async () => { + const mockFeeds = [ + { + _id: 1, + title: 'Feed One', + url: 'http://example.com/rss', + web_url: 'http://example.com', + category: 'Tech', + }, + { + _id: 2, + title: 'Feed Two', + url: 'http://test.com/rss', + web_url: 'http://test.com', + category: 'News', + }, + ]; + + (global.fetch as any).mockImplementation((url: string) => { + if (url.includes('/api/feed/')) { + return Promise.resolve({ + ok: true, + json: async () => mockFeeds, }); + } + if (url.includes('/api/tag')) { + return Promise.resolve({ + ok: true, + json: async () => [{ title: 'Tech' }], + }); + } + return Promise.reject(new Error(`Unknown URL: ${url}`)); + }); - render( - - {/* @ts-ignore */} - { }} /> - - ); + render( + + {/* @ts-ignore */} + {}} /> + + ); - await waitFor(() => { - expect(screen.queryByText(/loading feeds/i)).not.toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.queryByText(/loading feeds/i)).not.toBeInTheDocument(); + }); - // Expand feeds - fireEvent.click(screen.getByText(/feeds/i, { selector: 'h2' })); + // Expand feeds + fireEvent.click(screen.getByText(/feeds/i, { selector: 'h2' })); - await waitFor(() => { - expect(screen.getByText('Feed One')).toBeInTheDocument(); - expect(screen.getByText('Feed Two')).toBeInTheDocument(); - const techElements = screen.getAllByText('Tech'); - expect(techElements.length).toBeGreaterThan(0); - }); + await waitFor(() => { + expect(screen.getByText('Feed One')).toBeInTheDocument(); + expect(screen.getByText('Feed Two')).toBeInTheDocument(); + const techElements = screen.getAllByText('Tech'); + expect(techElements.length).toBeGreaterThan(0); }); + }); - it('handles fetch error', async () => { - (global.fetch as any).mockImplementation(() => Promise.reject(new Error('API Error'))); + it('handles fetch error', async () => { + (global.fetch as any).mockImplementation(() => Promise.reject(new Error('API Error'))); - render( - - {/* @ts-ignore */} - { }} /> - - ); + render( + + {/* @ts-ignore */} + {}} /> + + ); - await waitFor(() => { - expect(screen.getByText(/error: api error/i)).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText(/error: api error/i)).toBeInTheDocument(); }); - - it('handles empty feed list', async () => { - (global.fetch as any).mockImplementation((url: string) => { - if (url.includes('/api/feed/')) { - return Promise.resolve({ - ok: true, - json: async () => [], - }); - } - if (url.includes('/api/tag')) { - return Promise.resolve({ - ok: true, - json: async () => [], - }); - } - return Promise.reject(new Error(`Unknown URL: ${url}`)); + }); + + it('handles empty feed list', async () => { + (global.fetch as any).mockImplementation((url: string) => { + if (url.includes('/api/feed/')) { + return Promise.resolve({ + ok: true, + json: async () => [], + }); + } + if (url.includes('/api/tag')) { + return Promise.resolve({ + ok: true, + json: async () => [], }); + } + return Promise.reject(new Error(`Unknown URL: ${url}`)); + }); - render( - - {/* @ts-ignore */} - { }} /> - - ); + render( + + {/* @ts-ignore */} + {}} /> + + ); - await waitFor(() => { - expect(screen.queryByText(/loading feeds/i)).not.toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.queryByText(/loading feeds/i)).not.toBeInTheDocument(); + }); - // Expand feeds - fireEvent.click(screen.getByText(/feeds/i, { selector: 'h2' })); + // Expand feeds + fireEvent.click(screen.getByText(/feeds/i, { selector: 'h2' })); - await waitFor(() => { - expect(screen.getByText(/no feeds found/i)).toBeInTheDocument(); - }); + await waitFor(() => { + expect(screen.getByText(/no feeds found/i)).toBeInTheDocument(); }); + }); }); -- cgit v1.2.3