Download frontend/src/lib/session.test.js from kiyer/beacon: direct link, hf CLI and curl.
- Browser
- Download file 3.89 kB
-
https://huggingface.co/spaces/kiyer/beacon/resolve/main/frontend/src/lib/session.test.js
- Command line
-
hf download hf://spaces/kiyer/beacon/frontend/src/lib/session.test.js
-
curl -L -o session.test.js https://huggingface.co/spaces/kiyer/beacon/resolve/main/frontend/src/lib/session.test.js
3.89 kB
| import { describe, it, expect } from 'vitest'; | |
| import { exportSession, importSession } from './session'; | |
| const state = { | |
| fileName: 'm.pdf', | |
| pdfHash: 'abc123', | |
| paper: { title: 'T', authors: 'A', venue: '', arxivId: '', pages: 2, | |
| paragraphs: [{ id: 'p1', section: 'S', firstOfSection: true, text: 'x' }] }, | |
| litPapers: { b1: { id: 'b1', short: 'I22', title: 't', authors: 'a', year: 2022, | |
| journal: '', bibcode: 'b1', arxiv: '', abstract: 'ab', | |
| scores: { embed: 0.9, keywords: 0.5, rank: 1 } } }, | |
| litByPara: { p1: ['b1'] }, | |
| noteModes: { p1: 'explainer' }, | |
| commentary: { 'p1:explainer': { text: 'note', cites: ['b1'], source: 'llm' } }, | |
| figures: [{ id: 'f1', label: 'Figure 1', caption: 'A diagram', page: 2, hasImage: true }], | |
| litByFig: { f1: ['b1'] }, | |
| }; | |
| describe('session', () => { | |
| it('round-trips and never includes API keys', () => { | |
| const json = exportSession({ ...state, annotator: { provider: 'anthropic', model: 'm', key: 'SECRET' } }); | |
| expect(json).not.toContain('SECRET'); | |
| const parsed = JSON.parse(json); | |
| expect(parsed.version).toBe(2); | |
| expect(parsed.savedAt).toMatch(/^\d{4}-\d{2}-\d{2}T/); | |
| const restored = importSession(json); | |
| expect(restored.paper.paragraphs[0].id).toBe('p1'); | |
| expect(restored.commentary['p1:explainer'].text).toBe('note'); | |
| expect(restored.litByPara.p1).toEqual(['b1']); | |
| }); | |
| it('round-trips figures and litByFig', () => { | |
| const json = exportSession(state); | |
| const restored = importSession(json); | |
| expect(restored.figures).toHaveLength(1); | |
| expect(restored.figures[0].id).toBe('f1'); | |
| expect(restored.figures[0].caption).toBe('A diagram'); | |
| expect(restored.litByFig.f1).toEqual(['b1']); | |
| }); | |
| it('tolerates absence of figures/litByFig in older sessions', () => { | |
| // Simulate an old session without these fields | |
| const old = exportSession({ ...state, figures: undefined, litByFig: undefined }); | |
| const parsed = JSON.parse(old); | |
| // Remove them to simulate an old session file | |
| delete parsed.figures; | |
| delete parsed.litByFig; | |
| const restored = importSession(JSON.stringify(parsed)); | |
| expect(restored.figures).toEqual([]); | |
| expect(restored.litByFig).toEqual({}); | |
| }); | |
| it('rejects malformed sessions', () => { | |
| expect(() => importSession('{"version":99}')).toThrow(); | |
| expect(() => importSession('not json')).toThrow(); | |
| }); | |
| it('version 2 exports and imports new fields', () => { | |
| const json = exportSession({ | |
| ...state, | |
| equations: [{ id: 'eq1', page: 2, tag: '(3)', afterPara: 'p1', hasImage: true }], | |
| references: [{ id: 'r1', raw: 'Smith 2020 ApJ 900 1', short: 'Smith 2020', year: 2020, | |
| bibcode: null, arxiv: null, corpusMatch: false }], | |
| citeIndex: { 'smith:2020': ['r1'] }, | |
| userNotes: { p1: { text: 'my note', updatedAt: '2026-06-16T00:00:00Z' } }, | |
| paperNote: 'general note', | |
| }); | |
| const restored = importSession(json); | |
| expect(restored.equations).toHaveLength(1); | |
| expect(restored.references[0].short).toBe('Smith 2020'); | |
| expect(restored.userNotes.p1.text).toBe('my note'); | |
| expect(restored.paperNote).toBe('general note'); | |
| }); | |
| it('v1 session imports tolerantly (all new fields default to empty)', () => { | |
| const v1json = JSON.stringify({ | |
| version: 1, fileName: 'x.pdf', pdfHash: '', | |
| paper: { title: 'T', authors: '', venue: '', arxivId: '', pages: 1, | |
| paragraphs: [{ id: 'p1', section: 'S', firstOfSection: true, text: 'x' }] }, | |
| litPapers: {}, litByPara: {}, noteModes: {}, commentary: {}, | |
| }); | |
| const restored = importSession(v1json); | |
| expect(restored.equations).toEqual([]); | |
| expect(restored.references).toEqual([]); | |
| expect(restored.citeIndex).toEqual({}); | |
| expect(restored.userNotes).toEqual({}); | |
| expect(restored.paperNote).toBe(''); | |
| }); | |
| }); | |