forked from akai/readest
c8fabd331c
The sync-conflict dialog had two issues with servers other than KOReader (e.g. Kavita's KOReader-compatible sync endpoint): - "This device" preview rendered a bare "undefined" because reflowable books built the string from `sectionLabel`, which is empty for spine items with no matching TOC entry. It now falls back to the page count. - Choosing "use remote" closed the dialog but never moved the reader: `applyRemoteProgress` only knew how to navigate via CREngine XPointers, so non-XPointer progress strings were silently ignored. It now falls back to `view.goToFraction` using the reported percentage. Also fixes the section-title indentation in the dialog (SectionTitle bakes in `ps-4`, which misaligned the labels against their values). Closes #4200 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
42 lines
1.6 KiB
TypeScript
42 lines
1.6 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
||
import { isXPointerProgress, getRemoteFraction } from '@/app/reader/hooks/kosyncProgress';
|
||
|
||
describe('isXPointerProgress', () => {
|
||
it('accepts CREngine XPointers', () => {
|
||
expect(isXPointerProgress('/body/DocFragment[11]/body/div/p[3]/text().0')).toBe(true);
|
||
});
|
||
|
||
it('rejects non-XPointer progress strings', () => {
|
||
expect(isXPointerProgress('epubcfi(/6/14!/4/2/2)')).toBe(false);
|
||
expect(isXPointerProgress('50')).toBe(false);
|
||
expect(isXPointerProgress('')).toBe(false);
|
||
expect(isXPointerProgress(undefined)).toBe(false);
|
||
});
|
||
});
|
||
|
||
describe('getRemoteFraction', () => {
|
||
it('returns the percentage as a 0–1 fraction', () => {
|
||
expect(getRemoteFraction({ percentage: 0.5 })).toBe(0.5);
|
||
});
|
||
|
||
it('clamps fractions above 1', () => {
|
||
expect(getRemoteFraction({ percentage: 1.5 })).toBe(1);
|
||
});
|
||
|
||
it('returns undefined when there is no usable percentage', () => {
|
||
expect(getRemoteFraction({})).toBeUndefined();
|
||
expect(getRemoteFraction({ percentage: 0 })).toBeUndefined();
|
||
expect(getRemoteFraction({ percentage: -0.2 })).toBeUndefined();
|
||
expect(getRemoteFraction({ percentage: NaN })).toBeUndefined();
|
||
expect(getRemoteFraction({ percentage: Infinity })).toBeUndefined();
|
||
});
|
||
|
||
it('falls back to the percentage for non-XPointer progress (e.g. Kavita)', () => {
|
||
// Kavita's KOReader-compatible endpoint reports progress Readest cannot
|
||
// resolve positionally, but still sends a percentage.
|
||
const remote = { progress: 'page-42', percentage: 0.5 };
|
||
expect(isXPointerProgress(remote.progress)).toBe(false);
|
||
expect(getRemoteFraction(remote)).toBe(0.5);
|
||
});
|
||
});
|