import { describe, expect, it } from 'vitest'; import { pagesRead, parseProgress } from './progress'; import { parsePdfLocator, pdfLocator } from './shared'; describe('progress payload', () => { it('accepts a reader save and rounds the percent', () => { expect( parseProgress({ fileId: 3, locator: 'epubcfi(/6/4!/4/2)', percent: 12.34567, sessionId: null }) ).toMatchObject({ fileId: 3, locator: 'epubcfi(/6/4!/4/2)', percent: 12.35 }); }); it.each([ null, 'nope', {}, { percent: -1 }, { percent: 101 }, { percent: 'ten' }, { percent: 10, page: 1.5 }, { percent: 10, fileId: -2 }, { percent: 10, locator: 'x'.repeat(2001) } ])('rejects %j', (body) => { expect(parseProgress(body)).toBeNull(); }); }); describe('pages read', () => { it('uses the page delta when pages are known', () => { expect(pagesRead({ startPage: 10, endPage: 34 })).toBe(24); }); it('scales the percent delta by the page count', () => { expect(pagesRead({ startPercent: 10, endPercent: 20, pageCount: 300 })).toBe(30); }); it('never goes negative and needs enough data', () => { expect(pagesRead({ startPage: 50, endPage: 20 })).toBe(0); expect(pagesRead({ startPercent: 40, endPercent: 30, pageCount: 100 })).toBe(0); expect(pagesRead({ startPercent: 10, endPercent: 20 })).toBeNull(); }); }); describe('pdf locators', () => { it('round-trips pages and rects', () => { const loc = pdfLocator(12, [{ x: 0.1, y: 0.2, w: 0.3333333, h: 0.02 }]); expect(loc).toBe('page:12#r=0.1,0.2,0.3333,0.02'); expect(parsePdfLocator(loc)).toEqual({ page: 12, rects: [{ x: 0.1, y: 0.2, w: 0.3333, h: 0.02 }] }); expect(parsePdfLocator('page:3')).toEqual({ page: 3, rects: [] }); expect(parsePdfLocator('epubcfi(/6/2)')).toBeNull(); }); });