feat(rsvp): sync reading position to cloud via book_configs (#3801)
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { transformBookNoteToDB, transformBookNoteFromDB } from '@/utils/transform';
|
||||
import { BookNote } from '@/types/book';
|
||||
import { DBBookNote } from '@/types/records';
|
||||
import {
|
||||
transformBookNoteToDB,
|
||||
transformBookNoteFromDB,
|
||||
transformBookConfigToDB,
|
||||
transformBookConfigFromDB,
|
||||
} from '@/utils/transform';
|
||||
import { BookConfig, BookNote } from '@/types/book';
|
||||
import { DBBookConfig, DBBookNote } from '@/types/records';
|
||||
|
||||
describe('transformBookNoteToDB with xpointer fields', () => {
|
||||
it('passes through xpointer0 and xpointer1', () => {
|
||||
@@ -112,3 +117,59 @@ describe('transformBookNoteFromDB with xpointer fields', () => {
|
||||
expect(note.xpointer1).toBe('/body/DocFragment[1]/body/p[1]/text().20');
|
||||
});
|
||||
});
|
||||
|
||||
describe('transformBookConfigToDB / transformBookConfigFromDB rsvpPosition', () => {
|
||||
const baseConfig: BookConfig = {
|
||||
bookHash: 'hash1',
|
||||
updatedAt: 1700000000000,
|
||||
};
|
||||
|
||||
it('serializes rsvpPosition to JSON string in DB record', () => {
|
||||
const config: BookConfig = {
|
||||
...baseConfig,
|
||||
rsvpPosition: { cfi: 'epubcfi(/6/4!/4/2/1:0)', wordText: 'hello' },
|
||||
};
|
||||
const db = transformBookConfigToDB(config, 'user1');
|
||||
expect(db.rsvp_position).toBe(
|
||||
JSON.stringify({ cfi: 'epubcfi(/6/4!/4/2/1:0)', wordText: 'hello' }),
|
||||
);
|
||||
});
|
||||
|
||||
it('omits rsvp_position when rsvpPosition is undefined', () => {
|
||||
const db = transformBookConfigToDB(baseConfig, 'user1');
|
||||
expect(db.rsvp_position).toBeUndefined();
|
||||
});
|
||||
|
||||
it('deserializes rsvp_position from DB record', () => {
|
||||
const dbConfig: DBBookConfig = {
|
||||
user_id: 'user1',
|
||||
book_hash: 'hash1',
|
||||
rsvp_position: JSON.stringify({ cfi: 'epubcfi(/6/4!/4/2/1:0)', wordText: 'hello' }),
|
||||
updated_at: '2023-11-14T22:13:20.000Z',
|
||||
};
|
||||
const config = transformBookConfigFromDB(dbConfig);
|
||||
expect(config.rsvpPosition).toEqual({ cfi: 'epubcfi(/6/4!/4/2/1:0)', wordText: 'hello' });
|
||||
});
|
||||
|
||||
it('leaves rsvpPosition undefined when rsvp_position is absent from DB', () => {
|
||||
const dbConfig: DBBookConfig = {
|
||||
user_id: 'user1',
|
||||
book_hash: 'hash1',
|
||||
updated_at: '2023-11-14T22:13:20.000Z',
|
||||
};
|
||||
const config = transformBookConfigFromDB(dbConfig);
|
||||
expect(config.rsvpPosition).toBeUndefined();
|
||||
});
|
||||
|
||||
it('round-trips rsvpPosition through DB transform', () => {
|
||||
const config: BookConfig = {
|
||||
...baseConfig,
|
||||
rsvpPosition: { cfi: 'epubcfi(/6/8!/4/2/3:5)', wordText: 'world' },
|
||||
};
|
||||
const db = transformBookConfigToDB(config, 'user1');
|
||||
// Simulate what DB returns (updated_at as ISO string)
|
||||
const dbRecord: DBBookConfig = { ...db, updated_at: new Date(config.updatedAt).toISOString() };
|
||||
const restored = transformBookConfigFromDB(dbRecord);
|
||||
expect(restored.rsvpPosition).toEqual(config.rsvpPosition);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user