mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
fix(settings): persist complete display preferences
Accept the author display fields already emitted by the client and include them in automatic account sync. Keep older payloads compatible with defaults and cover the client-server contract with regression tests. Fixes #1209
This commit is contained in:
@@ -51,11 +51,15 @@ const validDisplayPreferences: DisplayPreferences = {
|
||||
smartScopeFilterExpanded: true,
|
||||
authorCoverSize: 140,
|
||||
authorCoverShape: 'circle',
|
||||
authorRowDensity: 'comfortable',
|
||||
authorCoverFallback: false,
|
||||
tableZebraStriping: false,
|
||||
tableDensity: 'comfortable',
|
||||
bookSpineOverlay: 'subtle',
|
||||
showSpineOnComics: false,
|
||||
bookShadowStrength: 'strong',
|
||||
bookCoverDisplayMode: 'natural-bottom',
|
||||
bookDetailCoverTint: 'duotone',
|
||||
seriesCardCoverMode: 'stack',
|
||||
gridCardPrimaryLabel: 'hidden',
|
||||
gridCardSecondaryLabel: 'hidden',
|
||||
|
||||
@@ -71,6 +71,8 @@ const validDisplayPreferences: DisplayPreferences = {
|
||||
smartScopeFilterExpanded: true,
|
||||
authorCoverSize: 140,
|
||||
authorCoverShape: 'circle',
|
||||
authorRowDensity: 'comfortable',
|
||||
authorCoverFallback: false,
|
||||
tableZebraStriping: false,
|
||||
tableDensity: 'comfortable',
|
||||
bookSpineOverlay: 'subtle',
|
||||
@@ -404,6 +406,36 @@ describe('UserPreferencesService', () => {
|
||||
expect(repo.upsert).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('upsertDisplayPreferences accepts and persists author display preferences', async () => {
|
||||
const preferences = {
|
||||
...validDisplayPreferences,
|
||||
authorRowDensity: 'compact',
|
||||
authorCoverFallback: true,
|
||||
} satisfies DisplayPreferences;
|
||||
|
||||
await expect(service.upsertDisplayPreferences(11, preferences)).resolves.toBeUndefined();
|
||||
|
||||
expect(repo.upsert).toHaveBeenCalledWith(11, 'display', preferences);
|
||||
});
|
||||
|
||||
it('upsertDisplayPreferences defaults author display preferences omitted by older clients', async () => {
|
||||
const { authorRowDensity, authorCoverFallback, ...olderPreferences } = validDisplayPreferences;
|
||||
void authorRowDensity;
|
||||
void authorCoverFallback;
|
||||
|
||||
await expect(service.upsertDisplayPreferences(11, olderPreferences)).resolves.toBeUndefined();
|
||||
|
||||
expect(repo.upsert).toHaveBeenCalledWith(11, 'display', expect.objectContaining({ authorRowDensity: 'comfortable', authorCoverFallback: false }));
|
||||
});
|
||||
|
||||
it.each([
|
||||
['authorRowDensity', 'dense'],
|
||||
['authorCoverFallback', 'yes'],
|
||||
])('upsertDisplayPreferences rejects invalid %s values', async (field, value) => {
|
||||
await expect(service.upsertDisplayPreferences(11, { ...validDisplayPreferences, [field]: value })).rejects.toBeInstanceOf(BadRequestException);
|
||||
expect(repo.upsert).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('upsertDisplayPreferences rejects invalid cover display modes', async () => {
|
||||
await expect(
|
||||
service.upsertDisplayPreferences(11, { ...validDisplayPreferences, bookCoverDisplayMode: 'stretched' } as never),
|
||||
|
||||
@@ -61,6 +61,8 @@ const DISPLAY_PREFERENCES_SCHEMA = z
|
||||
smartScopeFilterExpanded: z.boolean(),
|
||||
authorCoverSize: z.number().int().min(100).max(400),
|
||||
authorCoverShape: z.enum(AUTHOR_COVER_SHAPES),
|
||||
authorRowDensity: z.enum(TABLE_DENSITIES).default('comfortable'),
|
||||
authorCoverFallback: z.boolean().default(false),
|
||||
tableZebraStriping: z.boolean(),
|
||||
tableDensity: z.enum(TABLE_DENSITIES),
|
||||
bookSpineOverlay: z.enum(BOOK_SPINE_OVERLAYS),
|
||||
@@ -83,7 +85,7 @@ const DISPLAY_PREFERENCES_SCHEMA = z
|
||||
message: 'cardOverlays must not contain duplicate values',
|
||||
});
|
||||
}
|
||||
});
|
||||
}) satisfies z.ZodType<DisplayPreferences>;
|
||||
|
||||
const COVER_SEARCH_PREFERENCES_SCHEMA = z
|
||||
.object({
|
||||
|
||||
Reference in New Issue
Block a user