feat: return hydrated collection after update and refine icon labels

This commit is contained in:
neon
2026-04-03 20:49:11 -06:00
parent 70e76600e0
commit af7df49b02
4 changed files with 37 additions and 3 deletions
@@ -83,7 +83,7 @@ async function handleDelete() {
</div>
<div class="flex flex-col gap-1.5">
<label class="text-sm font-medium text-foreground"> Icon <span class="text-muted-foreground font-normal">(optional)</span> </label>
<label class="text-sm font-medium text-foreground"> Icon </label>
<IconPicker v-model="icon" placeholder="Choose an icon..." />
</div>
@@ -66,7 +66,7 @@ async function submit() {
</div>
<div class="flex flex-col gap-1.5">
<label class="text-sm font-medium text-foreground"> Icon <span class="text-muted-foreground font-normal">(optional)</span> </label>
<label class="text-sm font-medium text-foreground"> Icon </label>
<IconPicker v-model="icon" placeholder="Choose an icon..." />
</div>
@@ -121,6 +121,38 @@ describe('CollectionService', () => {
});
});
describe('update', () => {
it('returns the hydrated collection so derived counts remain available', async () => {
const { service, collectionRepo } = makeService();
const existing = makeCollection({ bookCount: 3 });
const hydrated = makeCollection({ name: 'Updated Favorites', icon: 'FolderHeart', syncToKobo: true, bookCount: 3 });
collectionRepo.findById.mockResolvedValueOnce([existing]).mockResolvedValueOnce([hydrated]);
collectionRepo.update.mockResolvedValue([
{
id: existing.id,
userId: existing.userId,
name: 'Updated Favorites',
icon: 'FolderHeart',
description: existing.description,
syncToKobo: true,
displayOrder: existing.displayOrder,
createdAt: existing.createdAt,
updatedAt: existing.updatedAt,
},
]);
const result = await service.update(existing.id, { name: 'Updated Favorites', icon: 'FolderHeart', syncToKobo: true }, makeUser());
expect(collectionRepo.update).toHaveBeenCalledWith(existing.id, existing.userId, {
name: 'Updated Favorites',
icon: 'FolderHeart',
syncToKobo: true,
});
expect(collectionRepo.findById).toHaveBeenCalledTimes(2);
expect(result).toEqual(hydrated);
});
});
describe('addBooks', () => {
it('verifies collection ownership and library access before adding books', async () => {
const { service, collectionRepo, bookReadService, libraryService } = makeService();
@@ -85,12 +85,14 @@ export class CollectionService {
async update(id: number, dto: UpdateCollectionDto, user: RequestUser) {
const existing = await this.findCollectionForUserOrThrow(id, user);
const [updated] = await this.collectionRepo.update(id, existing.userId, {
await this.collectionRepo.update(id, existing.userId, {
...(dto.name !== undefined && { name: dto.name }),
...(dto.icon !== undefined && { icon: dto.icon.trim() || null }),
...(dto.description !== undefined && { description: dto.description }),
...(dto.syncToKobo !== undefined && { syncToKobo: dto.syncToKobo }),
});
const [updated] = await this.collectionRepo.findById(id);
return updated;
}