Files
webmail/lib/offline/__tests__/queue-sync.test.ts
T

54 lines
2.4 KiB
TypeScript

import 'fake-indexeddb/auto';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { setStoreBackend } from '@/lib/store/client/api';
import { InProcessStore } from '@/lib/store/__tests__/helpers/in-process-store';
import { getOfflineHooks } from '@/lib/jmap/offline-hooks';
import { usePolicyStore } from '@/stores/policy-store';
import { useAccountStore } from '@/stores/account-store';
import { DEFAULT_ORGANISATION_POLICY } from '@/lib/admin/organisation-policy';
import { queueSend, readQueue } from '../queue';
import { registerOfflineHooks } from '../offline-mode';
import { writeEnabled } from '../state';
// Whatever goes into the outbox asks for a Background Sync, once it's stored.
const seen = vi.hoisted(() => ({ calls: 0, onCall: (() => {}) as () => void }));
vi.mock('@/lib/pwa-notify/outbox-sync', () => ({ requestOutboxSync: () => { seen.calls += 1; seen.onCall(); } }));
let store: InProcessStore;
beforeEach(() => {
store = new InProcessStore();
setStoreBackend(store);
seen.calls = 0;
seen.onCall = () => {};
usePolicyStore.setState({ loaded: true, subject: null, policy: { ...usePolicyStore.getState().policy, organisation: DEFAULT_ORGANISATION_POLICY } });
useAccountStore.setState({ accounts: [{ id: 'acc', serverUrl: 'https://mail.example.org', username: 'alice@example.org' } as never] });
});
afterEach(() => {
setStoreBackend(null);
writeEnabled([]);
});
describe('the outbox', () => {
it('asks for a sync after storing a message, and still returns its id', async () => {
let storedWhenAsked = -1;
seen.onCall = () => { void readQueue('acc').then(({ outbox }) => { storedWhenAsked = outbox.length; }); };
const id = await queueSend('acc', { subject: 'S', to: [] }, { kind: 'email', args: [] });
expect(id).toBe(1);
expect(seen.calls).toBe(1);
await vi.waitFor(() => expect(storedWhenAsked).toBe(1));
});
it('asks for a sync after keeping a change the client made, not after a read', async () => {
writeEnabled(['acc']);
registerOfflineHooks();
const client = { getServerUrl: () => 'https://mail.example.org', getUsername: () => 'alice@example.org', getAccountId: () => 'acc1' };
await getOfflineHooks()?.answer(client, [['Email/set', { update: { m: { 'keywords/$seen': true } } }, '0']]);
expect(seen.calls).toBe(1);
await getOfflineHooks()?.answer(client, [['Email/get', { ids: [] }, '0']]);
expect(seen.calls).toBe(1);
});
});