mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
fix(books): treat missing read status as unread for sorting
Books without a row in user_book_status returned NULL and sorted differently than books explicitly marked as 'unread'. Coalescing the missing status to 'unread' ensures both explicitly and implicitly unread books are grouped and ordered consistently. Fixes #367
This commit is contained in:
@@ -142,6 +142,36 @@ describe('BookSortBuilder', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('builds readStatus sort that coalesces a missing status row to unread', () => {
|
||||
const raw = (sql as unknown as { raw: vi.Mock }).raw;
|
||||
|
||||
const result = service.build([{ field: 'readStatus', dir: 'asc' }], 42);
|
||||
|
||||
expect(result).toHaveLength(2);
|
||||
expect(result[0]).toMatchObject({
|
||||
type: 'sql',
|
||||
text: expect.stringContaining('COALESCE((SELECT ubs.status FROM user_book_status ubs'),
|
||||
});
|
||||
expect(result[0]?.text).toContain("), 'unread') ");
|
||||
expect(result[0]?.values[0]).toBe(42);
|
||||
expect(raw).toHaveBeenCalledWith('ASC');
|
||||
});
|
||||
|
||||
it('keeps explicit unread and missing-row books in the same sort group when sorted with a secondary author key', () => {
|
||||
const result = service.build(
|
||||
[
|
||||
{ field: 'readStatus', dir: 'asc' },
|
||||
{ field: 'author', dir: 'asc' },
|
||||
],
|
||||
42,
|
||||
);
|
||||
|
||||
expect(result).toHaveLength(3);
|
||||
expect(result[0]?.text).toContain('COALESCE(');
|
||||
expect(result[0]?.text).toContain("'unread'");
|
||||
expect(result[1]?.text).toContain(' NULLS LAST');
|
||||
});
|
||||
|
||||
it('adds series name fallback when sorting by seriesIndex without series sort', () => {
|
||||
const raw = (sql as unknown as { raw: vi.Mock }).raw;
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ export class BookSortBuilder {
|
||||
case 'readStatus':
|
||||
if (userId === undefined) throw new BadRequestException('readStatus sort requires an authenticated user');
|
||||
result.push(
|
||||
sql`(SELECT ubs.status FROM user_book_status ubs WHERE ubs.book_id = books.id AND ubs.user_id = ${userId}) ${sql.raw(D)} NULLS LAST`,
|
||||
sql`COALESCE((SELECT ubs.status FROM user_book_status ubs WHERE ubs.book_id = books.id AND ubs.user_id = ${userId}), 'unread') ${sql.raw(D)} NULLS LAST`,
|
||||
);
|
||||
break;
|
||||
case 'format':
|
||||
|
||||
Reference in New Issue
Block a user