Files
webmail/lib/jmap/__tests__/principal-cache.test.ts
T
lucletoffeandClaude Opus 5.5 8cf6783cdb feat(calendar): say whom a calendar is shared with
The sidebar showed the same people icon for any calendar with a share,
labelled "Share calendar", and the settings badge only gave a count, so
there was no way to tell from either who could see the calendar. A share
granted to a service account read like a share with other people.

Both now carry a hint listing the recipients ("Shared with
bot@example.com (Booking robot)"), resolved from the principals the
server lists. Until every recipient is known the hint falls back to the
count. Principals are fetched only when a calendar on screen is shared.

The per-client principal cache of the attendee availability check moves
to lib/jmap/principal-cache.ts so both use it. It no longer keeps an
empty or failed answer: the next caller asks again instead of seeing
no principals for the rest of the session.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-15 22:19:53 +02:00

32 lines
1.3 KiB
TypeScript

import { describe, it, expect, vi } from 'vitest';
import { cachedPrincipals } from '../principal-cache';
import type { IJMAPClient } from '../client-interface';
import type { Principal } from '../types';
const alice: Principal = { id: 'a', type: 'individual', name: 'alice', email: 'alice@example.com' };
describe('cachedPrincipals', () => {
it('asks the server once per client', async () => {
const getPrincipals = vi.fn().mockResolvedValue([alice]);
const client = { getPrincipals } as unknown as IJMAPClient;
expect(await cachedPrincipals(client)).toEqual([alice]);
expect(await cachedPrincipals(client)).toEqual([alice]);
expect(getPrincipals).toHaveBeenCalledTimes(1);
});
it('does not keep an empty or failed answer, so the next caller asks again', async () => {
const getPrincipals = vi.fn()
.mockRejectedValueOnce(new Error('offline'))
.mockResolvedValueOnce([])
.mockResolvedValueOnce([alice]);
const client = { getPrincipals } as unknown as IJMAPClient;
expect(await cachedPrincipals(client)).toEqual([]);
expect(await cachedPrincipals(client)).toEqual([]);
expect(await cachedPrincipals(client)).toEqual([alice]);
expect(await cachedPrincipals(client)).toEqual([alice]);
expect(getPrincipals).toHaveBeenCalledTimes(3);
});
});