diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts index fbb0db78..a4445ff9 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-member-create.spec.ts @@ -111,6 +111,9 @@ test.describe('Document create member', () => { await expect(page.getByText(`Invitation sent to ${email}`)).toBeVisible(); const responseCreateInvitation = await responsePromiseCreateInvitation; expect(responseCreateInvitation.ok()).toBeTruthy(); + expect( + responseCreateInvitation.request().headers()['content-language'], + ).toBe('en-us'); // Check user added await expect( @@ -209,4 +212,44 @@ test.describe('Document create member', () => { await responsePromiseCreateInvitationFail; expect(responseCreateInvitationFail.ok()).toBeFalsy(); }); + + test('The invitation endpoint get the language of the website', async ({ + page, + browserName, + }) => { + await createDoc(page, 'user-invitation', browserName, 1); + + const header = page.locator('header').first(); + await header.getByRole('combobox').getByText('EN').click(); + await header.getByRole('option', { name: 'FR' }).click(); + + await page.getByRole('button', { name: 'Partager' }).click(); + + const inputSearch = page.getByLabel( + /Trouver un membre à ajouter au document/, + ); + + const email = randomName('test@test.fr', browserName, 1)[0]; + await inputSearch.fill(email); + await page.getByRole('option', { name: email }).click(); + + // Choose a role + await page.getByRole('combobox', { name: /Choisissez un rôle/ }).click(); + await page.getByRole('option', { name: 'Administrateur' }).click(); + + const responsePromiseCreateInvitation = page.waitForResponse( + (response) => + response.url().includes('/invitations/') && response.status() === 201, + ); + + await page.getByRole('button', { name: 'Valider' }).click(); + + // Check invitation sent + await expect(page.getByText(`Invitation envoyée à ${email}`)).toBeVisible(); + const responseCreateInvitation = await responsePromiseCreateInvitation; + expect(responseCreateInvitation.ok()).toBeTruthy(); + expect( + responseCreateInvitation.request().headers()['content-language'], + ).toBe('fr-fr'); + }); }); diff --git a/src/frontend/apps/impress/src/features/docs/members/members-add/api/useCreateDocInvitation.tsx b/src/frontend/apps/impress/src/features/docs/members/members-add/api/useCreateDocInvitation.tsx index cc26f4e3..c443a112 100644 --- a/src/frontend/apps/impress/src/features/docs/members/members-add/api/useCreateDocInvitation.tsx +++ b/src/frontend/apps/impress/src/features/docs/members/members-add/api/useCreateDocInvitation.tsx @@ -3,6 +3,7 @@ import { useMutation } from '@tanstack/react-query'; import { APIError, errorCauses, fetchAPI } from '@/api'; import { User } from '@/core/auth'; import { Doc, Role } from '@/features/docs/doc-management'; +import { ContentLanguage } from '@/i18n/types'; import { DocInvitation, OptionType } from '../types'; @@ -10,15 +11,20 @@ interface CreateDocInvitationParams { email: User['email']; role: Role; docId: Doc['id']; + contentLanguage: ContentLanguage; } export const createDocInvitation = async ({ email, role, docId, + contentLanguage, }: CreateDocInvitationParams): Promise => { const response = await fetchAPI(`documents/${docId}/invitations/`, { method: 'POST', + headers: { + 'Content-Language': contentLanguage, + }, body: JSON.stringify({ email, role, diff --git a/src/frontend/apps/impress/src/features/docs/members/members-add/components/AddMembers.tsx b/src/frontend/apps/impress/src/features/docs/members/members-add/components/AddMembers.tsx index d33a5082..51d183c1 100644 --- a/src/frontend/apps/impress/src/features/docs/members/members-add/components/AddMembers.tsx +++ b/src/frontend/apps/impress/src/features/docs/members/members-add/components/AddMembers.tsx @@ -9,6 +9,7 @@ import { useTranslation } from 'react-i18next'; import { APIError } from '@/api'; import { Box, Card, IconBG } from '@/components'; import { Doc, Role } from '@/features/docs/doc-management'; +import { useLanguage } from '@/i18n/hooks/useLanguage'; import { useCreateDocAccess, useCreateInvitation } from '../api'; import { @@ -33,6 +34,7 @@ interface ModalAddMembersProps { } export const AddMembers = ({ currentRole, doc }: ModalAddMembersProps) => { + const { contentLanguage } = useLanguage(); const { t } = useTranslation(); const [selectedUsers, setSelectedUsers] = useState([]); const [selectedRole, setSelectedRole] = useState(); @@ -51,6 +53,7 @@ export const AddMembers = ({ currentRole, doc }: ModalAddMembersProps) => { email: selectedUser.value.email, role: selectedRole, docId: doc.id, + contentLanguage, }); break; diff --git a/src/frontend/apps/impress/src/i18n/hooks/useLanguage.tsx b/src/frontend/apps/impress/src/i18n/hooks/useLanguage.tsx new file mode 100644 index 00000000..4879bda8 --- /dev/null +++ b/src/frontend/apps/impress/src/i18n/hooks/useLanguage.tsx @@ -0,0 +1,15 @@ +import { useTranslation } from 'react-i18next'; + +import { ContentLanguage } from '../types'; + +export const useLanguage = (): { + language: string; + contentLanguage: ContentLanguage; +} => { + const { i18n } = useTranslation(); + + return { + language: i18n.language, + contentLanguage: i18n.language === 'fr' ? 'fr-fr' : 'en-us', + }; +}; diff --git a/src/frontend/apps/impress/src/i18n/types.ts b/src/frontend/apps/impress/src/i18n/types.ts new file mode 100644 index 00000000..d9b0064a --- /dev/null +++ b/src/frontend/apps/impress/src/i18n/types.ts @@ -0,0 +1,2 @@ +// See: https://github.com/numerique-gouv/impress/blob/ac58341984c99c10ebfac7f8bbe1e8756c48e4d4/src/backend/impress/settings.py#L156-L161 +export type ContentLanguage = 'en-us' | 'fr-fr';