mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 08:13:50 +00:00
54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import { forgetEmailPrefetches, prefetchEmailContent, requestEmailContent } from '../email-prefetch';
|
|
import type { IJMAPClient } from '@/lib/jmap/client-interface';
|
|
import type { Email } from '@/lib/jmap/types';
|
|
|
|
// A mouse press on a row starts the body request; the click that follows
|
|
// takes that request over instead of sending a second one.
|
|
|
|
const client = (getEmail = vi.fn(async (id: string) => ({ id }) as Email)) =>
|
|
({ getAccountId: () => 'login', getEmail }) as unknown as IJMAPClient & { getEmail: typeof getEmail };
|
|
|
|
describe('email prefetch', () => {
|
|
afterEach(() => {
|
|
forgetEmailPrefetches();
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it('hands the open the request the press started', async () => {
|
|
const c = client();
|
|
prefetchEmailContent(c, 'e1', 'acct');
|
|
prefetchEmailContent(c, 'e1', 'acct'); // a second press does not ask again
|
|
const email = await requestEmailContent(c, 'e1', 'acct');
|
|
|
|
expect(email?.id).toBe('e1');
|
|
expect(c.getEmail).toHaveBeenCalledTimes(1);
|
|
expect(c.getEmail).toHaveBeenCalledWith('e1', 'acct');
|
|
});
|
|
|
|
it('asks again when the press was for another account or message', async () => {
|
|
const c = client();
|
|
prefetchEmailContent(c, 'e1', 'acct');
|
|
await requestEmailContent(c, 'e1', 'other');
|
|
await requestEmailContent(c, 'e2', 'acct');
|
|
expect(c.getEmail).toHaveBeenCalledTimes(3);
|
|
});
|
|
|
|
it('does not hand out a request older than a few seconds', async () => {
|
|
vi.useFakeTimers();
|
|
const c = client();
|
|
prefetchEmailContent(c, 'e1');
|
|
vi.advanceTimersByTime(6_000);
|
|
await requestEmailContent(c, 'e1');
|
|
expect(c.getEmail).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it('lets the open see a failed prefetch, and an unclaimed one fail quietly', async () => {
|
|
const failing = client(vi.fn(async () => { throw new Error('offline'); }));
|
|
prefetchEmailContent(failing, 'e1');
|
|
await expect(requestEmailContent(failing, 'e1')).rejects.toThrow('offline');
|
|
prefetchEmailContent(failing, 'e2'); // never claimed: no unhandled rejection
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
});
|
|
});
|