diff --git a/src/frontend/apps/desk/src/features/mail-domains/domains/__tests__/MailDomainView.test.tsx b/src/frontend/apps/desk/src/features/mail-domains/domains/__tests__/MailDomainView.test.tsx new file mode 100644 index 000000000..457b3705e --- /dev/null +++ b/src/frontend/apps/desk/src/features/mail-domains/domains/__tests__/MailDomainView.test.tsx @@ -0,0 +1,95 @@ +import { fireEvent, render, screen } from '@testing-library/react'; +import fetchMock from 'fetch-mock'; + +import { MailDomain } from '@/features/mail-domains/domains'; +import { AppWrapper } from '@/tests/utils'; + +import { MailDomainView } from '../components/MailDomainView'; + +const toast = jest.fn(); +jest.mock('@openfun/cunningham-react', () => ({ + ...jest.requireActual('@openfun/cunningham-react'), + useToastProvider: () => ({ + toast, + }), +})); + +const mockMailDomain: MailDomain = { + id: '123e4567-e89b-12d3-a456-426614174000', + name: 'example.com', + status: 'action_required', + created_at: '2024-01-01T00:00:00Z', + updated_at: '2024-01-01T00:00:00Z', + slug: 'example-com', + support_email: 'support@example.com', + abilities: { + delete: false, + manage_accesses: true, + get: true, + patch: true, + put: true, + post: true, + }, + action_required_details: { + mx: 'Je veux que le MX du domaine soit mx.ox.numerique.gouv.fr....', + }, + expected_config: [ + { target: '', type: 'mx', value: 'mx.ox.numerique.gouv.fr.' }, + { + target: 'dimail._domainkey', + type: 'txt', + value: + 'v=DKIM1; h=sha256; k=rsa; p=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + }, + { target: 'imap', type: 'cname', value: 'imap.ox.numerique.gouv.fr.' }, + { target: 'smtp', type: 'cname', value: 'smtp.ox.numerique.gouv.fr.' }, + { + target: '', + type: 'txt', + value: 'v=spf1 include:_spf.ox.numerique.gouv.fr -all', + }, + { + target: 'webmail', + type: 'cname', + value: 'webmail.ox.numerique.gouv.fr.', + }, + ], +}; + +describe('', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + afterEach(() => { + fetchMock.restore(); + }); + it('display action required button and open modal with information when domain status is action_required', () => { + render(, { + wrapper: AppWrapper, + }); + // Check if action required button is displayed + const actionButton = screen.getByText('Actions required'); + expect(actionButton).toBeInTheDocument(); + + // Click the button and verify modal content + fireEvent.click(actionButton); + + // Verify modal title and content + expect(screen.getByText('Required actions on domain')).toBeInTheDocument(); + expect( + screen.getByText( + /Je veux que le MX du domaine soit mx.ox.numerique.gouv.fr/, + ), + ).toBeInTheDocument(); + + // Verify DNS configuration section + expect( + screen.getByText(/DNS Configuration Required:/i), + ).toBeInTheDocument(); + expect(screen.getByText(/imap.ox.numerique.gouv.fr./i)).toBeInTheDocument(); + expect( + screen.getByText(/webmail.ox.numerique.gouv.fr./i), + ).toBeInTheDocument(); + }); +}); diff --git a/src/frontend/apps/desk/src/features/mail-domains/domains/components/MailDomainView.tsx b/src/frontend/apps/desk/src/features/mail-domains/domains/components/MailDomainView.tsx index 3136db4d5..72f1fd6ec 100644 --- a/src/frontend/apps/desk/src/features/mail-domains/domains/components/MailDomainView.tsx +++ b/src/frontend/apps/desk/src/features/mail-domains/domains/components/MailDomainView.tsx @@ -1,4 +1,9 @@ -import { Modal, ModalSize } from '@openfun/cunningham-react'; +import { + Modal, + ModalSize, + VariantType, + useToastProvider, +} from '@openfun/cunningham-react'; import * as React from 'react'; import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -15,6 +20,7 @@ type Props = { }; export const MailDomainView = ({ mailDomain }: Props) => { const { t } = useTranslation(); + const { toast } = useToastProvider(); const [showModal, setShowModal] = React.useState(false); const currentRole = mailDomain.abilities.delete ? Role.OWNER @@ -46,6 +52,10 @@ export const MailDomainView = ({ mailDomain }: Props) => { const handleShowModal = () => { setShowModal(true); }; + const copyToClipboard = async (text: string) => { + await navigator.clipboard.writeText(text); + toast(t('copy done'), VariantType.SUCCESS); + }; return ( <> @@ -62,18 +72,69 @@ export const MailDomainView = ({ mailDomain }: Props) => { )}

{t('Actions required detail')}

+
             {mailDomain.action_required_details &&
               Object.entries(mailDomain.action_required_details).map(
-                ([check, value]) => (
-                  
    -
  • + ([check, value], index) => ( +
      +
    • {check}: {value}
    ), )}
+ {mailDomain.expected_config && ( + +

{t('DNS Configuration Required:')}

+
+                
+ {t('Add the following DNS values:')} +
    + {mailDomain.expected_config.map((item, index) => ( +
  • + {item.target && ( + <> + {item.target.toUpperCase()} -{' '} + + )} + {item.type.toUpperCase()} {t('with value:')}{' '} + + {item.value} + + +
  • + ))} +
+
+
+
+ )} )} diff --git a/src/frontend/apps/desk/src/features/mail-domains/domains/types.ts b/src/frontend/apps/desk/src/features/mail-domains/domains/types.ts index c97db9c9f..d6c1420bf 100644 --- a/src/frontend/apps/desk/src/features/mail-domains/domains/types.ts +++ b/src/frontend/apps/desk/src/features/mail-domains/domains/types.ts @@ -17,6 +17,11 @@ export interface MailDomain { delete: boolean; manage_accesses: boolean; }; + expected_config?: Array<{ + target: string; + type: string; + value: string; + }>; } export enum Role { diff --git a/src/frontend/apps/desk/src/i18n/translations.json b/src/frontend/apps/desk/src/i18n/translations.json index b9c0255cc..27043115c 100644 --- a/src/frontend/apps/desk/src/i18n/translations.json +++ b/src/frontend/apps/desk/src/i18n/translations.json @@ -32,6 +32,7 @@ "Add a team": "Ajouter un groupe", "Add members to the team": "Ajouter des membres à l'équipe", "Add the domain": "Ajouter le domaine", + "Add the following DNS values:": "Ajouter les valeurs DNS suivantes :", "Add to group": "Ajouter au groupe", "Address: National Agency for Territorial Cohesion - 20, avenue de Ségur TSA 10717 75 334 Paris Cedex 07 Paris": "Adresse : Agence Nationale de la Cohésion des Territoires - 20, avenue de Ségur TSA 10717 75 334 Paris Cedex 07", "Administration": "Administration", @@ -55,6 +56,7 @@ "Content modal to delete the team": "Contenu modal pour supprimer le groupe", "Content modal to update the team": "Contenu modal pour mettre à jour le groupe", "Cookies placed": "Cookies déposés", + "Copy": "Copier", "Copyright": "Copyright", "Create a mailbox": "Créer une boîte mail", "Create a mailbox in {{name}} domain": "Créer une boîte mail dans le domaine {{name}}", @@ -65,6 +67,7 @@ "Create the team": "Créer le groupe", "Create your first team by clicking on the \"Create a new team\" button.": "Créez votre premier groupe en cliquant sur le bouton \"Créer un nouveau groupe\".", "Created at": "Créé le", + "DNS Configuration Required:": "Configuration DNS requise :", "Declaration established on June 25, 2024.": "Établie le 25 juin 2024.", "Defender of Rights - Free response - 71120 75342 Paris CEDEX 07": "Défenseur des droits\nLibre réponse 71120 75342 Paris CEDEX 07", "Delete the team": "Supprimer le groupe", @@ -222,7 +225,9 @@ "[pending]": "[en attente]", "accessibility-contact-defenseurdesdroits": "Contacter le délégué du<1>Défenseur des droits dans votre région", "accessibility-form-defenseurdesdroits": "Écrire un message au<1>Défenseur des droits", + "copy done": "copié", "mail domains list loading": "chargement de la liste des domaines de messagerie", + "with value:": "avec la valeur:", "{{count}} member_many": "{{count}} membres", "{{count}} member_one": "{{count}} membre", "{{count}} member_other": "{{count}} membres",