diff --git a/src/api/__tests__/mailbox-create.test.ts b/src/api/__tests__/mailbox-create.test.ts new file mode 100644 index 00000000..5e2dd566 --- /dev/null +++ b/src/api/__tests__/mailbox-create.test.ts @@ -0,0 +1,46 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + +vi.mock('../jmap-client', () => ({ + jmapClient: { + accountId: 'acc-1', + request: vi.fn(), + }, +})); + +import { jmapClient } from '../jmap-client'; +import { createMailbox } from '../email'; + +const mockRequest = jmapClient.request as ReturnType; + +beforeEach(() => { + vi.clearAllMocks(); + mockRequest.mockResolvedValue({ + methodResponses: [['Mailbox/set', { created: { 'new-mailbox': { id: 'mb-new' } } }, '0']], + }); +}); + +describe('createMailbox', () => { + it('subscribes the new folder so IMAP clients list it (#951)', async () => { + const id = await createMailbox({ name: 'Projects' }); + + expect(id).toBe('mb-new'); + const [[call]] = mockRequest.mock.calls[0]; + expect(call[0]).toBe('Mailbox/set'); + expect(call[1]).toEqual({ + accountId: 'acc-1', + create: { 'new-mailbox': { name: 'Projects', parentId: null, isSubscribed: true } }, + }); + }); + + it('subscribes subfolders created in another account', async () => { + await createMailbox({ name: 'Child', parentId: 'parent-id' }, 'shared-account'); + + const [[call]] = mockRequest.mock.calls[0]; + expect(call[1].accountId).toBe('shared-account'); + expect(call[1].create['new-mailbox']).toEqual({ + name: 'Child', + parentId: 'parent-id', + isSubscribed: true, + }); + }); +}); diff --git a/src/api/email.ts b/src/api/email.ts index 8db93274..db0297a9 100644 --- a/src/api/email.ts +++ b/src/api/email.ts @@ -215,9 +215,13 @@ export async function createMailbox( ): Promise { const accountId = accountIdOverride ?? jmapClient.accountId; const cid = 'new-mailbox'; + // Subscribe explicitly: IMAP clients that list folders via LSUB + // (Thunderbird) hide unsubscribed mailboxes, and the server default is + // not guaranteed to be true. (#951) const create: Record = { name: data.name, parentId: data.parentId ?? null, + isSubscribed: true, }; if (data.role !== undefined) create.role = data.role; const res = await jmapClient.request([