fix: improve mailbox role management by ensuring roles are cleared from all mailboxes when reassigning

This commit is contained in:
Linus Rath
2026-03-19 18:00:09 +01:00
parent 95af61c4be
commit a5c5fa6669
4 changed files with 70 additions and 25 deletions
@@ -226,6 +226,34 @@ describe('email-store folder management', () => {
expect(client.updateMailbox).toHaveBeenCalledWith('trash-1', { role: 'trash' });
});
it('should clear role from ALL mailboxes with that role when reassigning', async () => {
// Simulate server anomaly: two mailboxes with role "trash"
const extraTrash = makeMailbox({ id: 'trash-2', name: 'Deleted Items', role: 'trash' });
useEmailStore.setState({
mailboxes: [inbox, sent, trash, custom, extraTrash],
});
const newMailboxes = [inbox, sent, custom,
makeMailbox({ id: 'trash-1', name: 'Trash', role: undefined }),
makeMailbox({ id: 'trash-2', name: 'Deleted Items', role: undefined }),
];
// custom-1 gets the trash role
newMailboxes[2] = { ...newMailboxes[2], role: 'trash' };
const client = makeMockClient({
getAllMailboxes: vi.fn().mockResolvedValue(newMailboxes),
});
await useEmailStore.getState().setMailboxRole(client, 'custom-1', 'trash');
// Should clear trash role from BOTH trash-1 and trash-2
expect(client.updateMailbox).toHaveBeenCalledWith('trash-1', { role: null });
expect(client.updateMailbox).toHaveBeenCalledWith('trash-2', { role: null });
// Then set trash role on custom-1
expect(client.updateMailbox).toHaveBeenCalledWith('custom-1', { role: 'trash' });
expect(client.updateMailbox).toHaveBeenCalledTimes(3);
});
it('should set error on failure', async () => {
const client = makeMockClient({
updateMailbox: vi.fn().mockRejectedValue(new Error('Role update failed')),
+4 -4
View File
@@ -1298,11 +1298,11 @@ export const useEmailStore = create<EmailStore>((set, get) => ({
setMailboxRole: async (client, mailboxId, role) => {
try {
// If assigning a role, first clear that role from any other mailbox
// If assigning a role, first clear that role from ALL other mailboxes that have it
if (role) {
const existingMailbox = get().mailboxes.find(mb => mb.role === role && !mb.isShared);
if (existingMailbox && existingMailbox.id !== mailboxId) {
await client.updateMailbox(existingMailbox.id, { role: null });
const existingMailboxes = get().mailboxes.filter(mb => mb.role === role && !mb.isShared && mb.id !== mailboxId);
for (const existing of existingMailboxes) {
await client.updateMailbox(existing.id, { role: null });
}
}
await client.updateMailbox(mailboxId, { role });