fix(favorites): geaenderte Symbol-Adresse wird sofort angezeigt
- eine neue, ausdruecklich eingetragene Logo-Adresse verdraengt ein frueher hochgeladenes Symbol (Vorrang der Datei liess die Adresse unsichtbar) - iconVersion steigt mit, die Kachel laedt das Bild neu - Regressionstests: Upload wird ersetzt, unveraenderte Adresse laesst Upload stehen Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -859,6 +859,40 @@ describe('FavoritesService — Bindung an forTenant() (260911-gwh)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('update — ausdrueckliche Logo-Adresse verdraengt ein hochgeladenes Symbol (260929-lh3)', () => {
|
||||
const file = { buffer: PNG, originalname: 'x.png', mimetype: 'image/png', size: PNG.length };
|
||||
|
||||
it('neue, abweichende iconUrl bei vorhandenem Upload: Upload-Typ null, Datei weg, iconVersion erneut +1 — die neue Adresse wird angezeigt', async () => {
|
||||
const prisma = makeFakePrisma([baseRow]);
|
||||
const service = new FavoritesService(prisma as any, makeIconDiscovery() as any);
|
||||
await service.uploadIcon('t1', 'f1', 'user-a1', file);
|
||||
expect(fs.existsSync(fileFor('user-a1', 'f1', 'png'))).toBe(true);
|
||||
|
||||
const updated = await service.update('t1', 'f1', 'user-a1', {
|
||||
iconUrl: 'https://neu.invalid/logo.png',
|
||||
} as any);
|
||||
|
||||
expect(updated.iconUrl).toBe('https://neu.invalid/logo.png');
|
||||
expect(updated.uploadedIconMime).toBeNull();
|
||||
expect(updated.iconVersion).toBe(2);
|
||||
expect(fs.existsSync(fileFor('user-a1', 'f1', 'png'))).toBe(false);
|
||||
});
|
||||
|
||||
it('UNVERAENDERTE iconUrl bei vorhandenem Upload (das Formular schickt sie bei jedem Speichern mit): Upload bleibt', async () => {
|
||||
const prisma = makeFakePrisma([baseRow]);
|
||||
const service = new FavoritesService(prisma as any, makeIconDiscovery() as any);
|
||||
await service.uploadIcon('t1', 'f1', 'user-a1', file);
|
||||
|
||||
const updated = await service.update('t1', 'f1', 'user-a1', {
|
||||
iconUrl: baseRow.iconUrl,
|
||||
} as any);
|
||||
|
||||
expect(updated.uploadedIconMime).toBe('image/png');
|
||||
expect(updated.iconVersion).toBe(1);
|
||||
expect(fs.existsSync(fileFor('user-a1', 'f1', 'png'))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove() mit hochgeladenem Symbol', () => {
|
||||
it('Zeile und Datei weg', async () => {
|
||||
const prisma = makeFakePrisma([baseRow]);
|
||||
|
||||
@@ -219,14 +219,34 @@ export class FavoritesService {
|
||||
}
|
||||
}
|
||||
|
||||
if (data.iconUrl !== undefined && data.iconUrl !== link.iconUrl) {
|
||||
// 260929-lh3: eine NEUE, ausdruecklich eingetragene Logo-Adresse muss
|
||||
// Vorrang vor einem frueher hochgeladenen Symbol haben. `getIconBytes`
|
||||
// liefert bei gesetztem `uploadedIconMime` IMMER die Datei — ohne diesen
|
||||
// Schritt blieb die neue Adresse gespeichert, aber unsichtbar (die Kachel
|
||||
// zeigte weiter das alte hochgeladene Bild). Nur bei einer tatsaechlichen
|
||||
// Aenderung: das Formular schickt die unveraenderte Adresse bei jedem
|
||||
// Speichern mit, das darf ein hochgeladenes Symbol nicht verdraengen.
|
||||
const iconUrlChanged = data.iconUrl !== undefined && data.iconUrl !== link.iconUrl;
|
||||
const explicitUrlReplacesUpload =
|
||||
iconUrlChanged && Boolean(dto.iconUrl) && link.uploadedIconMime !== null;
|
||||
if (explicitUrlReplacesUpload) {
|
||||
data.uploadedIconMime = null;
|
||||
}
|
||||
|
||||
if (iconUrlChanged) {
|
||||
data.iconVersion = { increment: 1 };
|
||||
}
|
||||
|
||||
return tenantPrisma.favoriteLink.update({
|
||||
const updated = await tenantPrisma.favoriteLink.update({
|
||||
where: { id },
|
||||
data,
|
||||
});
|
||||
|
||||
if (explicitUrlReplacesUpload && link.uploadedIconMime !== null) {
|
||||
await this.removeIconFile(id, link.userId, link.uploadedIconMime, 'ersetzte');
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user