From fb52770b585513daafd16668443b50ff37a83ef0 Mon Sep 17 00:00:00 2001 From: VasilisNtovolos Date: Tue, 27 Oct 2026 15:39:48 +0200 Subject: [PATCH] test: register source clients in cross-account deletion tests --- .../email-selection-cross-account.test.ts | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/stores/__tests__/email-selection-cross-account.test.ts b/stores/__tests__/email-selection-cross-account.test.ts index cedb7a64f..fa5c49d19 100644 --- a/stores/__tests__/email-selection-cross-account.test.ts +++ b/stores/__tests__/email-selection-cross-account.test.ts @@ -1,5 +1,7 @@ -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { useEmailStore } from '../email-store'; +import { useAuthStore } from '../auth-store'; +import type { IJMAPClient } from '@/lib/jmap/client-interface'; import { emailKeyFor } from '@/lib/thread-utils'; import type { Email } from '@/lib/jmap/types'; @@ -17,13 +19,34 @@ const twin = (account: string, subject: string): Email => ({ sourceClientAccountId: account, sourceAccountId: account, } as unknown as Email); +const initialAuthState = useAuthStore.getState(); +const initialEmailState = useEmailStore.getState(); +const makeClient = () => ({ + batchDeleteEmails: vi.fn(async () => {}), + getMailboxes: vi.fn(async () => []), +}) as unknown as IJMAPClient; +let clientA: IJMAPClient; +let clientB: IJMAPClient; + const mine = twin('account-a', 'mia'); const theirs = twin('account-b', 'di un altro account'); beforeEach(() => { + clientA = makeClient(); + clientB = makeClient(); + useAuthStore.setState({ + activeAccountId: 'account-a', client: clientA, + getClientForAccount: (id: string) => (id === 'account-a' ? clientA : id === 'account-b' ? clientB : undefined) as never, + }); + useEmailStore.setState(initialEmailState, true); useEmailStore.setState({ emails: [mine, theirs], selectedEmailKeys: new Set(), lastSelectedEmailKey: null }); }); +afterEach(() => { + useEmailStore.setState(initialEmailState, true); + useAuthStore.setState(initialAuthState, true); +}); + describe('selection across accounts sharing an email id', () => { it('ticks only the row that was clicked', () => { useEmailStore.getState().toggleEmailSelection(mine); @@ -49,14 +72,28 @@ describe('selection across accounts sharing an email id', () => { }); it('deletes only the selected account copy', async () => { - const client = { - batchDeleteEmails: vi.fn(async () => {}), - batchMoveToMailbox: vi.fn(async () => {}), - getMailboxes: vi.fn(async () => []), - } as never; useEmailStore.getState().toggleEmailSelection(theirs); - await useEmailStore.getState().batchDelete(client, true); + expect(await useEmailStore.getState().batchDelete(clientA, true)).toBe(true); const remaining = useEmailStore.getState().emails; expect(remaining.map(e => e.sourceAccountId)).toEqual(['account-a']); + expect(remaining[0]).toBe(mine); + expect(clientB.batchDeleteEmails).toHaveBeenCalledTimes(1); + expect(clientB.batchDeleteEmails).toHaveBeenCalledWith(['eiaaaabc'], 'account-b'); + expect(clientA.batchDeleteEmails).not.toHaveBeenCalled(); + expect(useEmailStore.getState().error).toBeNull(); + }); + + it('retains both copies when the selected source client is unavailable', async () => { + useAuthStore.setState({ + getClientForAccount: (id: string) => (id === 'account-a' ? clientA : undefined) as never, + }); + useEmailStore.getState().toggleEmailSelection(theirs); + expect(await useEmailStore.getState().batchDelete(clientA, true)).toBe(false); + const state = useEmailStore.getState(); + expect(state.error).toBe('Not connected'); + expect(state.emails).toEqual([mine, theirs]); + expect([...state.selectedEmailKeys]).toEqual([emailKeyFor(theirs)]); + expect(clientA.batchDeleteEmails).not.toHaveBeenCalled(); + expect(clientB.batchDeleteEmails).not.toHaveBeenCalled(); }); });