fix: route all counter updates to the email's own account in aggregate views
Extend the counter-routing fix beyond markAsRead to every optimistic mailbox counter update, so a different account's email never adjusts the active account's folder counters (JMAP ids can collide across accounts). - Add applyBatchMailboxCounterUpdate() + applyDeleteCounters() and apply the per-account routing to: deleteEmail (trash + permanent), moveToMailbox, moveEmailsToMailbox, batchMarkAsRead, batchDelete, and markThreadAsRead. - markAsSpam/batchMarkAsSpam/batchMoveToMailbox don't touch counters (rely on refresh) and folder-level ops (rename/empty/markMailboxAsRead) are already account-scoped — left as-is. - Test: batchMarkAsRead adjusts each account's counter in its own list.
This commit is contained in:
@@ -53,6 +53,7 @@ function makeClient() {
|
||||
markAsRead: vi.fn().mockResolvedValue(undefined),
|
||||
toggleStar: vi.fn().mockResolvedValue(undefined),
|
||||
moveEmail: vi.fn().mockResolvedValue(undefined),
|
||||
batchMarkAsRead: vi.fn().mockResolvedValue(undefined),
|
||||
} as unknown as IJMAPClient;
|
||||
}
|
||||
|
||||
@@ -146,6 +147,27 @@ describe('unified-view single-email action routing (#281)', () => {
|
||||
expect(s.accountMailboxes['account-a'][0].unreadEmails).toBe(5); // active list untouched
|
||||
});
|
||||
|
||||
it('batchMarkAsRead adjusts each email’s own account counter (cross-account)', async () => {
|
||||
useEmailStore.setState({
|
||||
mailboxes: [makeMailbox({ id: 'inbox', role: 'inbox', unreadEmails: 5 })],
|
||||
accountMailboxes: {
|
||||
'account-a': [makeMailbox({ id: 'inbox', role: 'inbox', unreadEmails: 5 })],
|
||||
'account-b': [makeMailbox({ id: 'inbox', role: 'inbox', unreadEmails: 3 })],
|
||||
},
|
||||
emails: [
|
||||
makeEmail({ id: 'a1', sourceClientAccountId: 'account-a', sourceAccountId: 'account-a', keywords: {}, mailboxIds: { inbox: true } }),
|
||||
makeEmail({ id: 'b1', sourceClientAccountId: 'account-b', sourceAccountId: 'account-b', keywords: {}, mailboxIds: { inbox: true } }),
|
||||
],
|
||||
selectedEmailIds: new Set(['a1', 'b1']),
|
||||
});
|
||||
|
||||
await useEmailStore.getState().batchMarkAsRead(activeClient, true);
|
||||
|
||||
const s = useEmailStore.getState();
|
||||
expect(s.mailboxes[0].unreadEmails).toBe(4); // active account: -1
|
||||
expect(s.accountMailboxes['account-b'][0].unreadEmails).toBe(2); // account-b: -1
|
||||
});
|
||||
|
||||
it('routes a shared/group email through the delegating login client + owner accountId', async () => {
|
||||
await useEmailStore.getState().markAsRead(activeClient, 'email-shared', true);
|
||||
// Reached via account-a's client (the active one), targeting the owner account.
|
||||
|
||||
Reference in New Issue
Block a user