aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/FeedItem.test.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/FeedItem.test.tsx')
-rw-r--r--frontend/src/components/FeedItem.test.tsx48
1 files changed, 18 insertions, 30 deletions
diff --git a/frontend/src/components/FeedItem.test.tsx b/frontend/src/components/FeedItem.test.tsx
index 1c51dc3..ab2ca45 100644
--- a/frontend/src/components/FeedItem.test.tsx
+++ b/frontend/src/components/FeedItem.test.tsx
@@ -27,66 +27,54 @@ describe('FeedItem Component', () => {
render(<FeedItem item={mockItem} />);
expect(screen.getByText('Test Item')).toBeInTheDocument();
expect(screen.getByText(/Test Feed/)).toBeInTheDocument();
- // Check for relative time or date formatting? For now just check it renders
});
- it('toggles star status', async () => {
- vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: async () => ({}) } as Response);
-
- render(<FeedItem item={mockItem} />);
+ it('calls onToggleStar when star clicked', () => {
+ const onToggleStar = vi.fn();
+ render(<FeedItem item={mockItem} onToggleStar={onToggleStar} />);
const starBtn = screen.getByTitle('Star');
- expect(starBtn).toHaveTextContent('★');
fireEvent.click(starBtn);
- // Optimistic update
- expect(await screen.findByTitle('Unstar')).toHaveTextContent('★');
-
- expect(global.fetch).toHaveBeenCalledWith(
- '/api/item/1',
- expect.objectContaining({
- method: 'PUT',
- body: JSON.stringify({
- _id: 1,
- read: false,
- starred: true,
- }),
- })
- );
+ expect(onToggleStar).toHaveBeenCalledWith(mockItem);
});
it('updates styling when read state changes', () => {
const { rerender } = render(<FeedItem item={{ ...mockItem, read: false }} />);
const link = screen.getByText('Test Item');
- // Initial state: unread (bold)
- // Note: checking computed style might be flaky in jsdom, but we can check the class on the parent
const listItem = link.closest('li');
expect(listItem).toHaveClass('unread');
expect(listItem).not.toHaveClass('read');
- // Update prop to read
rerender(<FeedItem item={{ ...mockItem, read: true }} />);
-
- // Should now be read
expect(listItem).toHaveClass('read');
expect(listItem).not.toHaveClass('unread');
});
- it('loads full content', async () => {
+ it('loads full content and calls onUpdate', async () => {
+ const onUpdate = vi.fn();
vi.mocked(global.fetch).mockResolvedValueOnce({
ok: true,
- json: async () => ({ ...mockItem, full_content: '<p>Full Content Loaded</p>' }),
+ json: async () => ({ full_content: '<p>Full Content Loaded</p>' }),
} as Response);
- render(<FeedItem item={mockItem} />);
+ const { rerender } = render(<FeedItem item={mockItem} onUpdate={onUpdate} />);
const scrapeBtn = screen.getByTitle('Load Full Content');
fireEvent.click(scrapeBtn);
await waitFor(() => {
- expect(screen.getByText('Full Content Loaded')).toBeInTheDocument();
+ expect(global.fetch).toHaveBeenCalledWith('/api/item/1', expect.anything());
+ });
+
+ await waitFor(() => {
+ expect(onUpdate).toHaveBeenCalledWith(expect.objectContaining({
+ full_content: '<p>Full Content Loaded</p>'
+ }));
});
- expect(global.fetch).toHaveBeenCalledWith('/api/item/1', expect.anything());
+ // Simulate parent updating prop
+ rerender(<FeedItem item={{ ...mockItem, full_content: '<p>Full Content Loaded</p>' }} onUpdate={onUpdate} />);
+ expect(screen.getByText('Full Content Loaded')).toBeInTheDocument();
});
});