mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-09-16 02:22:17 +00:00
feat(offline): open entry details from the saved snapshot
Opening an entry while offline needed a request that could not be made. Read it from the snapshot claimed by the signed-in account instead, re-checking ownership after the read so a sign-in mid-read cannot surface another account's data, and let controls marked data-offline-action stay usable in read-only mode.
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||||
vi.mock('$env/static/public', () => ({ PUBLIC_USE_LOCAL_POKEMON_SPRITE_FOLDER: 'true' }));
|
||||
import { readOfflineEntry } from '$lib/stores/offlineSync';
|
||||
|
||||
describe('offline detail snapshots', () => {
|
||||
const row = {
|
||||
pokedexEntry: { _id: '1', catchInformation: 'Full instructions' },
|
||||
catchRecord: { personalNotes: 'Saved note' }
|
||||
};
|
||||
function snapshot(owner = 'owner', ageMs = 0, includeEntry = true) {
|
||||
const meta = {
|
||||
userId: owner,
|
||||
format: 2,
|
||||
dataCache: `livingdex-offline-data-v1-${owner}-copy`,
|
||||
generatedAt: new Date(Date.now() - ageMs).toISOString()
|
||||
};
|
||||
const cache = {
|
||||
keys: async () => ['livingdex-offline-meta-v1', meta.dataCache],
|
||||
open: async (name: string) => ({
|
||||
match: async () =>
|
||||
new Response(
|
||||
JSON.stringify(
|
||||
name === 'livingdex-offline-meta-v1'
|
||||
? meta
|
||||
: {
|
||||
userId: owner,
|
||||
version: 1,
|
||||
pokedexes: [{ pokedex: { _id: 'dex' }, entries: includeEntry ? [row] : [] }]
|
||||
}
|
||||
)
|
||||
)
|
||||
})
|
||||
};
|
||||
vi.stubGlobal('window', { caches: cache });
|
||||
vi.stubGlobal('caches', cache);
|
||||
}
|
||||
afterEach(() => vi.unstubAllGlobals());
|
||||
it.each([0, 60 * 60 * 1000])(
|
||||
'uses a matching full snapshot offline even when %i ms old',
|
||||
async (age) => {
|
||||
snapshot('owner', age);
|
||||
expect(await readOfflineEntry('owner', 'dex', '1')).toEqual(row);
|
||||
}
|
||||
);
|
||||
it('never reads another account snapshot', async () => {
|
||||
snapshot('other');
|
||||
expect(await readOfflineEntry('owner', 'dex', '1')).toBeNull();
|
||||
});
|
||||
it('reports missing entries and dexes without fabricating details', async () => {
|
||||
snapshot('owner', 0, false);
|
||||
expect(await readOfflineEntry('owner', 'dex', '1')).toBeNull();
|
||||
expect(await readOfflineEntry('owner', 'missing', '1')).toBeNull();
|
||||
});
|
||||
it('works without Cache Storage', async () => {
|
||||
vi.stubGlobal('window', {});
|
||||
expect(await readOfflineEntry('owner', 'dex', '1')).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user