fix: list To and Cc in the header of a message forwarded from the reader

This commit is contained in:
Linus Rath
2026-11-04 09:15:42 +01:00
parent a0dca05585
commit f1266889ed
2 changed files with 16 additions and 4 deletions
@@ -1,5 +1,5 @@
import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import type { Mailbox } from '@/lib/jmap/types';
import { useAuthStore } from '@/stores/auth-store';
@@ -25,9 +25,10 @@ vi.mock('@/components/layout/sidebar', () => ({
vi.mock('@/components/email/email-composer', async () => {
const { useEffect } = await import('react');
return {
EmailComposer: ({ onSaveState, requestCloseRef }: {
EmailComposer: ({ onSaveState, requestCloseRef, replyTo }: {
onSaveState: (data: Record<string, unknown>) => void;
requestCloseRef?: { current: unknown };
replyTo?: { quoteHeaderHtml?: string };
}) => {
useEffect(() => {
if (requestCloseRef && stub.requestClose) requestCloseRef.current = stub.requestClose;
@@ -37,7 +38,7 @@ vi.mock('@/components/email/email-composer', async () => {
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return <div>stub composer</div>;
return <div data-testid="stub-composer" data-quote={replyTo?.quoteHeaderHtml ?? ''}>stub composer</div>;
},
};
});
@@ -142,6 +143,13 @@ describe('a reply in the standard layout', () => {
});
}
// compose-30: a forward says who the message went to.
it('gives a forward a header with To', async () => {
render(<MailApp />);
fireEvent.click(await screen.findByText('stub forward'));
await waitFor(() => expect(screen.getByTestId('stub-composer').getAttribute('data-quote')).toContain('forward_to_label'));
});
it('takes the whole pane for a new message', async () => {
render(<MailApp />);
fireEvent.click(screen.getByText('stub compose'));
+5 -1
View File
@@ -264,6 +264,7 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
const tRemove = useTranslations('email_list.confirm_remove');
const tCommon = useTranslations('common');
const tComposeUx = useTranslations('compose_ux');
const tComposeWords = useTranslations('compose_words');
const appName = productName(useConfig().appName);
const tQuote = useTranslations('quote_header');
const tComposer = useTranslations('email_composer');
@@ -2744,6 +2745,9 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
fromLabel: tQuote('from_label'),
dateLabel: tQuote('date_label'),
subjectLabel: tQuote('subject_label'),
// A forward says who the message went to, as Gmail and Outlook do.
toLabel: tComposeWords('forward_to_label'),
ccLabel: tComposeWords('forward_cc_label'),
},
});
setComposerQuoteHeader(header);
@@ -2751,7 +2755,7 @@ export function MailApp({ linkSegments: routeSegments }: MailAppProps = {}) {
console.warn('[quote-header] plugin transform failed; using default', err);
setComposerQuoteHeader(null);
}
}, [tCommon, tQuote]);
}, [tCommon, tQuote, tComposeWords]);
// Force a clean composer remount on every fresh entry point so prior
// compose state can't bleed into the new session (#329 C). The composer is