diff --git a/src/renderer/inbox/components/NoteCard.tsx b/src/renderer/inbox/components/NoteCard.tsx index b9242e2..5a56721 100644 --- a/src/renderer/inbox/components/NoteCard.tsx +++ b/src/renderer/inbox/components/NoteCard.tsx @@ -332,9 +332,23 @@ export function NoteCard({ note, onDeleted, onUpdated, mode = 'inbox', onRestore )} {local.media.length > 0 && ( -
+
{local.media.map((m) => ( -
+ { void (inboxApi as unknown as { openMedia: (rel: string) => Promise }).openMedia(m.relPath); }} + style={{ + width: 48, + height: 48, + objectFit: 'cover', + borderRadius: 4, + cursor: 'pointer', + border: '1px solid #e0e0e0' + }} + /> ))}
)} diff --git a/tests/unit/NoteCard.test.tsx b/tests/unit/NoteCard.test.tsx new file mode 100644 index 0000000..cff2f66 --- /dev/null +++ b/tests/unit/NoteCard.test.tsx @@ -0,0 +1,81 @@ +// @vitest-environment jsdom +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import '@testing-library/jest-dom/vitest'; +import { render, screen, fireEvent, cleanup } from '@testing-library/react'; +import type { Note } from '@shared/types'; + +const { mockOpenMedia } = vi.hoisted(() => ({ + mockOpenMedia: vi.fn(async () => ({ ok: true })) +})); + +vi.mock('../../src/renderer/inbox/api.js', () => ({ + inboxApi: { + openMedia: mockOpenMedia, + deleteNote: vi.fn(), + restoreNote: vi.fn(), + permanentDeleteNote: vi.fn(), + updateAiFields: vi.fn(), + setDueDate: vi.fn(), + setIntent: vi.fn(), + dismissIntent: vi.fn() + } +})); + +vi.mock('../../src/renderer/inbox/store.js', () => ({ + useInbox: Object.assign( + () => ({}), + { getState: () => ({ setTagFilter: vi.fn() }) } + ) +})); + +import { NoteCard } from '../../src/renderer/inbox/components/NoteCard'; + +const baseNote: Note = { + id: 'n1', + rawText: 'test', + aiTitle: 'T', + aiSummary: 'S', + aiStatus: 'done', + aiError: null, + aiProvider: null, + aiGeneratedAt: '2026-05-09T00:00:00Z', + titleEditedByUser: false, + summaryEditedByUser: false, + userIntent: null, + intentPromptedAt: '2026-05-09T00:00:00Z', + dueDate: null, + dueDateEditedByUser: false, + deletedAt: null, + lastRecalledAt: null, + recallDismissedAt: null, + createdAt: '2026-05-09T00:00:00Z', + updatedAt: '2026-05-09T00:00:00Z', + tags: [], + media: [ + { id: 'm1', kind: 'image', relPath: 'media/n1/img1.png', mime: 'image/png', bytes: 100 }, + { id: 'm2', kind: 'image', relPath: 'media/n1/img2.jpg', mime: 'image/jpeg', bytes: 200 } + ] +}; + +describe('NoteCard — image rendering', () => { + beforeEach(() => { + vi.clearAllMocks(); + cleanup(); + }); + + it('renders for each media item', () => { + render( {}} mode="inbox" />); + const imgs = screen.getAllByRole('presentation'); + expect(imgs).toHaveLength(2); + expect(imgs[0]?.getAttribute('src')).toBe('inkling-media://media/n1/img1.png'); + expect(imgs[1]?.getAttribute('src')).toBe('inkling-media://media/n1/img2.jpg'); + }); + + it('clicking calls inboxApi.openMedia', () => { + render( {}} mode="inbox" />); + const first = screen.getAllByRole('presentation')[0]; + if (first === undefined) throw new Error('expected at least one img'); + fireEvent.click(first); + expect(mockOpenMedia).toHaveBeenCalledWith('media/n1/img1.png'); + }); +});