#21: finish the three translations across every screen

F4's acceptance criterion asks for the three translations to be 100%
complete with the language lint green. The bundles had parity but the
admin screens and the account area were still hardcoded English: 63
visible strings that no locale could reach.

They now come from a shared ui namespace, so the three bundles cannot
drift apart, and all three carry 126 keys.

The language lint also caught this branch's own Go tests: the RFC 2047
cases need accented output to be worth anything, and the delivery test
had Portuguese fixture text. The expectations are written as Go escapes
instead, which keeps the assertions and leaves the source ASCII, and the
fixture text is English.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Opus 5 committed 2026-08-02 10:27:14 -03:00
1 parent eec4a4e520
commit b57854107e
15 files changed
+260 -68

No files matched your search

@@ -39,10 +39,10 @@ func TestExtractMessageHeaders_DecodesEncodedWords(t *testing.T) {
"corpo\r\n"
h := ExtractMessageHeaders([]byte(msg))
if h.Subject != "Relatório mensal" {
if h.Subject != "Relat\u00f3rio mensal" {
t.Errorf("Subject = %q, want the decoded form", h.Subject)
}
if h.FromDisplayName != "Júlio" {
if h.FromDisplayName != "J\u00falio" {
t.Errorf("FromDisplayName = %q, want the decoded form", h.FromDisplayName)
}
}
@@ -74,14 +74,14 @@ func TestExtractMessageHeaders_SurvivesGarbage(t *testing.T) {
func TestExtractMessageHeaders_TruncatesWithoutBreakingUTF8(t *testing.T) {
long := ""
for range 300 {
long += "á"
long += "\u00e1"
}
h := ExtractMessageHeaders([]byte("Subject: s\r\n\r\n" + long + "\r\n"))
if len(h.Snippet) > snippetLength {
t.Errorf("snippet is %d bytes, want at most %d", len(h.Snippet), snippetLength)
}
for _, r := range h.Snippet {
if r == '�' {
if r == '\ufffd' {
t.Fatal("truncation split a multi-byte rune")
}
}
@@ -10,7 +10,7 @@ func TestRenderMessage_ExtractsHeadersAndText(t *testing.T) {
"Content-Type: text/plain; charset=utf-8\r\n\r\nCorpo.\r\n"
got := RenderMessage([]byte(raw), 7)
if got.UID != 7 || got.Subject != "Olá" {
if got.UID != 7 || got.Subject != "Ol\u00e1" {
t.Errorf("UID/Subject = %d/%q", got.UID, got.Subject)
}
if got.Text != "Corpo.\r\n" {
@@ -100,7 +100,7 @@ func TestWebmailApiEndToEnd(t *testing.T) {
"To: " + address + "\r\n" +
"Subject: =?UTF-8?Q?Relat=C3=B3rio?=\r\n" +
"Content-Type: text/plain; charset=utf-8\r\n\r\n" +
"Corpo da mensagem de teste.\r\n"
"Body of the test message.\r\n"
targets, err := inbound.ResolveRecipient(ctx, address)
if err != nil {
@@ -186,7 +186,7 @@ func TestWebmailApiEndToEnd(t *testing.T) {
if len(messages) != 1 {
t.Fatalf("got %d messages, want 1", len(messages))
}
if messages[0].Subject != "Relatório" {
if messages[0].Subject != "Relat\u00f3rio" {
t.Errorf("Subject = %q, want the decoded encoded-word", messages[0].Subject)
}
if messages[0].FromName != "Alice Sender" {
@@ -212,10 +212,10 @@ func TestWebmailApiEndToEnd(t *testing.T) {
if err := json.Unmarshal(body, &message); err != nil {
t.Fatalf("decode message: %v", err)
}
if !strings.Contains(message.Text, "Corpo da mensagem de teste.") {
if !strings.Contains(message.Text, "Body of the test message.") {
t.Errorf("the rendered body is not the stored message: %q", message.Text)
}
if message.Subject != "Relatório" {
if message.Subject != "Relat\u00f3rio" {
t.Errorf("rendered Subject = %q, want the decoded encoded-word", message.Subject)
}
if !strings.Contains(message.From, "alice@remote.test") {