diff --git a/src/database/queries/ChapterQueries.ts b/src/database/queries/ChapterQueries.ts index 1bc04835..981ad26b 100644 --- a/src/database/queries/ChapterQueries.ts +++ b/src/database/queries/ChapterQueries.ts @@ -395,10 +395,18 @@ export const getPageChapters = async ( return query.all(); }; -export const getChapterCount = async (novelId: number, page: string = '1') => +export const getChapterCount = async ( + novelId: number, + page: string = '1', + filter?: ChapterFilterKey[], +) => await dbManager.$count( chapterSchema, - and(eq(chapterSchema.novelId, novelId), eq(chapterSchema.page, page)), + and( + eq(chapterSchema.novelId, novelId), + eq(chapterSchema.page, page), + chapterFilterToSQL(filter), + ), ); export const getPageChaptersBatched = async ( diff --git a/src/database/queries/__tests__/ChapterQueries.test.ts b/src/database/queries/__tests__/ChapterQueries.test.ts index 4777f451..005d4c00 100644 --- a/src/database/queries/__tests__/ChapterQueries.test.ts +++ b/src/database/queries/__tests__/ChapterQueries.test.ts @@ -712,6 +712,54 @@ describe('ChapterQueries', () => { expect(result).toBe(2); }); + + it('should return filtered count when filter is provided', async () => { + const testDb = getTestDb(); + const novelId = await insertTestNovel(testDb, { inLibrary: true }); + await insertTestChapter(testDb, novelId, { + page: '1', + unread: true, + }); + await insertTestChapter(testDb, novelId, { + page: '1', + unread: false, + }); + await insertTestChapter(testDb, novelId, { + page: '1', + unread: true, + }); + + const total = await getChapterCount(novelId, '1'); + expect(total).toBe(3); + + const unreadOnly = await getChapterCount(novelId, '1', ['not-read']); + expect(unreadOnly).toBe(2); + + const readOnly = await getChapterCount(novelId, '1', ['read']); + expect(readOnly).toBe(1); + }); + + it('should return total count when no filter is provided', async () => { + const testDb = getTestDb(); + const novelId = await insertTestNovel(testDb, { inLibrary: true }); + await insertTestChapter(testDb, novelId, { + page: '1', + unread: true, + }); + await insertTestChapter(testDb, novelId, { + page: '1', + unread: false, + }); + + const result = await getChapterCount(novelId, '1'); + expect(result).toBe(2); + + const noFilter = await getChapterCount(novelId, '1', undefined); + expect(noFilter).toBe(2); + + const emptyFilter = await getChapterCount(novelId, '1', []); + expect(emptyFilter).toBe(2); + }); }); describe('getPageChaptersBatched', () => { diff --git a/src/database/queries/__tests__/setup.ts b/src/database/queries/__tests__/setup.ts index f7b88c8d..4e114c11 100644 --- a/src/database/queries/__tests__/setup.ts +++ b/src/database/queries/__tests__/setup.ts @@ -115,10 +115,26 @@ jest.mock('expo-document-picker', () => ({ })); // Mock database utilities -jest.mock('@database/utils/parser', () => ({ - chapterFilterToSQL: jest.fn().mockReturnValue(undefined), - chapterOrderToSQL: jest.fn().mockReturnValue(undefined), -})); +jest.mock('@database/utils/parser', () => { + const { sql } = require('drizzle-orm'); + return { + chapterFilterToSQL: jest.fn().mockImplementation(filter => { + if (!filter || !filter.length) return undefined; + const map: Record = { + 'read': '`unread`=0', + 'not-read': '`unread`=1', + 'downloaded': 'isDownloaded=1', + 'not-downloaded': 'isDownloaded=0', + 'bookmarked': 'bookmark=1', + 'not-bookmarked': 'bookmark=0', + }; + const parts = filter.map((f: string) => map[f]).filter(Boolean); + if (!parts.length) return undefined; + return sql.raw(parts.join(' AND ')); + }), + chapterOrderToSQL: jest.fn().mockReturnValue(undefined), + }; +}); // Mock database constants jest.mock('@database/constants', () => ({ diff --git a/src/hooks/persisted/useNovel.ts b/src/hooks/persisted/useNovel.ts index ac46ef03..eee13ca6 100644 --- a/src/hooks/persisted/useNovel.ts +++ b/src/hooks/persisted/useNovel.ts @@ -238,7 +238,7 @@ export const useNovel = (novelOrPath: string | NovelInfo, pluginId: string) => { const config = [novel.id, settingsSort, settingsFilter, page] as const; - let chapterCount = await getChapterCount(novel.id, page); + let chapterCount = await getChapterCount(novel.id, page, settingsFilter); if (chapterCount) { try { @@ -259,7 +259,7 @@ export const useNovel = (novelOrPath: string | NovelInfo, pluginId: string) => { }); await insertChapters(novel.id, sourceChapters); newChapters = await _getPageChapters(...config); - chapterCount = await getChapterCount(novel.id, page); + chapterCount = await getChapterCount(novel.id, page, settingsFilter); } setBatchInformation({ @@ -271,7 +271,7 @@ export const useNovel = (novelOrPath: string | NovelInfo, pluginId: string) => { const unread = await _getFirstUnreadChapter( novel.id, - novelSettings.filter, + settingsFilter, page, ); setFirstUnreadChapter(unread ?? undefined);