From 508cc7c94429a6e06a59793a7a87520fd6799848 Mon Sep 17 00:00:00 2001 From: Lucas Rayan Date: Sat, 22 Aug 2026 14:12:27 -0300 Subject: [PATCH] fix(webmail): a lista de destinos deixava de fora as pastas do utilizador MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Encontrado a validar na produção, depois do deploy: o selector de pasta de destino na tela de regras mostrava apenas INBOX, Archive, Junk e Trash - exactamente sem as pastas que o utilizador tinha criado, que são aquelas para que uma regra de arquivo costuma ser escrita. A tela de regras escolhe um destino sem nenhuma mensagem aberta, por isso não tem "pasta actual" para excluir e passava uma string vazia. Uma pasta criada pelo utilizador não tem papel special-use, portanto "role === current" era verdadeiro para todas elas de uma vez. A exclusão passa a só se aplicar quando há de facto uma pasta actual. Co-Authored-By: Claude Opus 5 --- services/webmail/src/lib/mailCounts.ts | 8 +++++++- services/webmail/src/mailCounts.test.ts | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/services/webmail/src/lib/mailCounts.ts b/services/webmail/src/lib/mailCounts.ts index 9c39883..8620119 100644 --- a/services/webmail/src/lib/mailCounts.ts +++ b/services/webmail/src/lib/mailCounts.ts @@ -218,7 +218,13 @@ export function moveTargets( if (role === "sent" || role === "drafts") return false; if (name === "sent" || name === "drafts") return false; // Already here: nothing to do. - if (role === current || name === current) return false; + // + // Guarded on current being non-empty. A folder the user created has no + // special-use role, so with an empty current `role === current` was true + // for every one of them - and the rules screen, which has no open message + // and therefore no current folder, offered a destination list missing + // precisely the folders a filing rule is usually written for. + if (current !== "" && (role === current || name === current)) return false; return Boolean(folder.name); }); } diff --git a/services/webmail/src/mailCounts.test.ts b/services/webmail/src/mailCounts.test.ts index 98dca5e..1a7b4f2 100644 --- a/services/webmail/src/mailCounts.test.ts +++ b/services/webmail/src/mailCounts.test.ts @@ -333,3 +333,28 @@ describe("the folders a user made themselves", () => { expect(customFolders(undefined)).toEqual([]); }); }); + +describe("move targets when there is no current folder", () => { + const folders = [ + { special_use: "inbox", name: "INBOX", unread_count: 0, total_count: 1 }, + { special_use: "sent", name: "Sent", unread_count: 0, total_count: 0 }, + { special_use: "", name: "Faturas", unread_count: 0, total_count: 0 }, + { special_use: "", name: "Reports", unread_count: 0, total_count: 0 }, + ]; + + // The rules screen picks a destination without any message being open, so it + // has no "current folder" to exclude. Passing an empty string made + // `role === current` true for every folder with no special-use role - which + // is exactly the folders the user created - so the destination list silently + // left out the only folders a filing rule is usually written for. + it("offers the custom folders when no folder is excluded", () => { + const names = moveTargets(folders, "").map((f) => f.name); + expect(names).toContain("Faturas"); + expect(names).toContain("Reports"); + expect(names).toContain("INBOX"); + }); + + it("still leaves Sent out", () => { + expect(moveTargets(folders, "").map((f) => f.name)).not.toContain("Sent"); + }); +});