From 23a48e1d498680be769e931f46ddb1fd44f38d1a Mon Sep 17 00:00:00 2001 From: Adam Mathes Date: Fri, 13 Feb 2026 07:46:58 -0800 Subject: Implement Tag View and fix tests --- frontend/src/App.test.tsx | 11 +++-- frontend/src/App.tsx | 16 ++---- frontend/src/components/FeedItems.tsx | 16 +++--- frontend/src/components/FeedList.css | 36 +++++++++++++- frontend/src/components/FeedList.test.tsx | 39 ++++++++++++--- frontend/src/components/FeedList.tsx | 66 ++++++++++++++++--------- frontend/src/components/TagView.test.tsx | 81 +++++++++++++++++++++++++++++++ frontend/src/types.ts | 3 ++ 8 files changed, 215 insertions(+), 53 deletions(-) create mode 100644 frontend/src/components/TagView.test.tsx (limited to 'frontend/src') diff --git a/frontend/src/App.test.tsx b/frontend/src/App.test.tsx index 5614d7d..d0c31fd 100644 --- a/frontend/src/App.test.tsx +++ b/frontend/src/App.test.tsx @@ -20,9 +20,12 @@ describe('App', () => { }); it('renders dashboard when authenticated', async () => { - (global.fetch as any) - .mockResolvedValueOnce({ ok: true }) // /api/auth - .mockResolvedValueOnce({ ok: true, json: async () => [] }); // /api/feed/ + (global.fetch as any).mockImplementation((url: string) => { + if (url.includes('/api/auth')) return Promise.resolve({ ok: true }); + 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.resolve({ ok: true }); // Fallback + }); window.history.pushState({}, 'Test page', '/v2/'); render(); @@ -47,7 +50,7 @@ describe('App', () => { await waitFor(() => { expect(global.fetch).toHaveBeenCalledWith('/api/logout', expect.objectContaining({ method: 'POST' })); - expect(window.location.href).toBe('/login/'); + expect(window.location.href).toBe('/v2/login'); }); }); }); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8c7be19..09148d6 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useState } from 'react'; -import { BrowserRouter, Routes, Route, Navigate, useLocation } from 'react-router-dom'; +import { BrowserRouter, Routes, Route, Navigate, useLocation, useNavigate } from 'react-router-dom'; import Login from './components/Login'; import './App.css'; @@ -36,24 +36,17 @@ import FeedItems from './components/FeedItems'; import Settings from './components/Settings'; function Dashboard() { + const navigate = useNavigate(); return (

Neko Reader