feat: author support and UI support for multi-category

This commit is contained in:
2026-02-15 16:51:29 +01:00
parent 21ed992727
commit 14be7aa7af
12 changed files with 936 additions and 7 deletions

View File

@@ -582,6 +582,38 @@ describe('MediaEngine', () => {
});
});
describe('Author Field', () => {
beforeEach(() => {
mockFiles.set('/source/author-test.jpg', Buffer.from('image-data'));
});
it('should store author when provided during import', async () => {
const media = await mediaEngine.importMedia('/source/author-test.jpg', {
author: 'John Doe',
});
expect(media.author).toBe('John Doe');
});
it('should handle media without author', async () => {
const media = await mediaEngine.importMedia('/source/author-test.jpg');
expect(media.author).toBeUndefined();
});
it('should include author in database insert', async () => {
await mediaEngine.importMedia('/source/author-test.jpg', {
author: 'Jane Smith',
});
// Check that the database insert was called with author
expect(mockLocalDb.insert).toHaveBeenCalled();
// The mock captures the inserted data in mockMedia
const insertedMedia = Array.from(mockMedia.values()).pop();
expect(insertedMedia?.author).toBe('Jane Smith');
});
});
describe('Date-based folder structure', () => {
beforeEach(() => {
mockFiles.set('/source/dated-image.jpg', Buffer.from('image-data'));

View File

@@ -498,6 +498,58 @@ describe('MetaEngine', () => {
consoleErrorSpy.mockRestore();
});
it('should set and get defaultAuthor in project metadata', async () => {
await metaEngine.setProjectMetadata({
name: 'My Blog',
description: 'A blog',
defaultAuthor: 'John Doe',
});
const metadata = await metaEngine.getProjectMetadata();
expect(metadata?.defaultAuthor).toBe('John Doe');
});
it('should update defaultAuthor only', async () => {
await metaEngine.setProjectMetadata({
name: 'My Blog',
description: 'A blog',
});
await metaEngine.updateProjectMetadata({ defaultAuthor: 'Jane Smith' });
const metadata = await metaEngine.getProjectMetadata();
expect(metadata?.name).toBe('My Blog');
expect(metadata?.defaultAuthor).toBe('Jane Smith');
});
it('should persist defaultAuthor to filesystem', async () => {
await metaEngine.setProjectMetadata({
name: 'Test Project',
defaultAuthor: 'Author Name',
});
const metaDir = metaEngine.getMetaDir();
const projectPath = normalizePath(`${metaDir}/project.json`);
const content = mockFiles.get(projectPath);
const parsed = JSON.parse(content!);
expect(parsed.defaultAuthor).toBe('Author Name');
});
it('should load defaultAuthor from filesystem', async () => {
const metaDir = metaEngine.getMetaDir();
const projectPath = normalizePath(`${metaDir}/project.json`);
mockFiles.set(projectPath, JSON.stringify({
name: 'Loaded Project',
defaultAuthor: 'Loaded Author',
}));
await metaEngine.loadProjectMetadata();
const metadata = await metaEngine.getProjectMetadata();
expect(metadata?.defaultAuthor).toBe('Loaded Author');
});
it('should handle ENOENT error when loading categories (no file)', async () => {
// No file exists, should not throw
await metaEngine.loadCategories();