mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 08:13:50 +00:00
73 lines
2.8 KiB
TypeScript
73 lines
2.8 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { authHooks, clearAllHooks } from '@/lib/plugin-hooks';
|
|
import { useAuthStore } from '../auth-store';
|
|
import { useAccountStore } from '../account-store';
|
|
|
|
function listen(bus: { register: (id: string, fn: (...a: unknown[]) => unknown) => unknown }) {
|
|
const fn = vi.fn();
|
|
bus.register('test', fn);
|
|
return fn;
|
|
}
|
|
|
|
const ACCOUNT = {
|
|
label: 'Alice', serverUrl: 'https://mail.example.org', username: 'alice@example.org', authMode: 'basic' as const,
|
|
rememberMe: false, displayName: 'Alice', email: 'alice@example.org', lastLoginAt: 0,
|
|
isConnected: true, hasError: false, isDefault: true,
|
|
};
|
|
|
|
beforeEach(() => {
|
|
vi.restoreAllMocks();
|
|
clearAllHooks();
|
|
useAccountStore.setState({ accounts: [], activeAccountId: null, defaultAccountId: null });
|
|
useAuthStore.setState({ isAuthenticated: false, client: null, activeAccountId: null, username: null });
|
|
});
|
|
|
|
describe('auth hooks', () => {
|
|
it('reports accounts that are added and removed, once each', () => {
|
|
const added = listen(authHooks.onAccountAdd);
|
|
const removed = listen(authHooks.onAccountRemove);
|
|
|
|
const id = useAccountStore.getState().addAccount(ACCOUNT);
|
|
useAccountStore.getState().addAccount(ACCOUNT); // already there: an update
|
|
useAccountStore.getState().removeAccount(id);
|
|
useAccountStore.getState().removeAccount(id); // already gone
|
|
|
|
expect(added.mock.calls).toEqual([[{ accountId: id }]]);
|
|
expect(removed.mock.calls).toEqual([[{ accountId: id }]]);
|
|
});
|
|
|
|
it('says when the session is ready, and when another account becomes active', () => {
|
|
const ready = listen(authHooks.onAuthReady);
|
|
const switched = listen(authHooks.onAccountSwitch);
|
|
const client = {} as never;
|
|
|
|
useAuthStore.setState({ isAuthenticated: true, client, activeAccountId: 'a' });
|
|
useAuthStore.setState({ activeAccountId: 'b' });
|
|
|
|
expect(ready.mock.calls).toEqual([[{ accountId: 'a' }]]);
|
|
expect(switched).toHaveBeenCalledWith({ accountId: 'b', previousAccountId: 'a' });
|
|
});
|
|
|
|
it('reports a renewed access token', async () => {
|
|
const refreshed = listen(authHooks.onTokenRefresh);
|
|
vi.stubGlobal('fetch', vi.fn(async () => ({
|
|
ok: true, status: 200, json: async () => ({ access_token: 'new', expires_in: 3600 }),
|
|
})));
|
|
useAuthStore.setState({ activeAccountId: 'acc', authMode: 'oauth' });
|
|
|
|
await expect(useAuthStore.getState().refreshAccessToken()).resolves.toBe('new');
|
|
|
|
expect(refreshed).toHaveBeenCalledWith({ accountId: 'acc' });
|
|
});
|
|
|
|
it('reports a sign-in', async () => {
|
|
const signedIn = listen(authHooks.onLogin);
|
|
|
|
const ok = await useAuthStore.getState().loginDemo();
|
|
|
|
expect(ok).toBe(true);
|
|
const { activeAccountId, username } = useAuthStore.getState();
|
|
expect(signedIn).toHaveBeenCalledWith({ accountId: activeAccountId, username });
|
|
});
|
|
});
|