Files
readest/apps/readest-app/src/__tests__/hooks/kosyncProgress.test.ts
T
Huang Xin c8fabd331c fix(reader): resolve KOReader sync conflict against non-KOReader servers (#4205)
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>
2026-05-17 17:22:34 +02:00

42 lines
1.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 01 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);
});
});