diff --git a/src/frontend/apps/desk/src/core/__tests__/MainLayout.test.tsx b/src/frontend/apps/desk/src/core/__tests__/MainLayout.test.tsx
index 9ff038c7e..02aec078e 100644
--- a/src/frontend/apps/desk/src/core/__tests__/MainLayout.test.tsx
+++ b/src/frontend/apps/desk/src/core/__tests__/MainLayout.test.tsx
@@ -4,6 +4,7 @@ import { render, screen } from '@testing-library/react';
import { AppWrapper } from '@/tests/utils';
import { MainLayout } from '../MainLayout';
+import { useAuthStore } from '../auth';
import { useConfigStore } from '../config';
jest.mock('next/navigation', () => ({
@@ -19,6 +20,19 @@ describe('MainLayout', () => {
useConfigStore.setState({
config: { RELEASE: '1.0.0', FEATURES: { TEAMS: true }, LANGUAGES: [] },
});
+ useAuthStore.setState({
+ authenticated: true,
+ userData: {
+ id: '1',
+ email: 'test@example.com',
+ name: 'Test User',
+ abilities: {
+ contacts: { canView: true },
+ teams: { canView: true },
+ mailboxes: { canView: true },
+ },
+ },
+ });
render(, { wrapper: AppWrapper });
@@ -35,10 +49,57 @@ describe('MainLayout', () => {
).toBeInTheDocument();
});
+ it('checks menu rendering with no abilities', () => {
+ useConfigStore.setState({
+ config: { RELEASE: '1.0.0', FEATURES: { TEAMS: true }, LANGUAGES: [] },
+ });
+ useAuthStore.setState({
+ authenticated: true,
+ userData: {
+ id: '1',
+ email: 'test@example.com',
+ name: 'Test User',
+ abilities: {
+ contacts: { canView: false },
+ teams: { canView: false },
+ mailboxes: { canView: false },
+ },
+ },
+ });
+
+ render(, { wrapper: AppWrapper });
+
+ expect(
+ screen.queryByRole('button', {
+ // Changé de getByRole à queryByRole
+ name: /Teams button/i,
+ }),
+ ).not.toBeInTheDocument(); //
+
+ expect(
+ screen.queryByRole('button', {
+ name: /Mail Domains button/i,
+ }),
+ ).not.toBeInTheDocument();
+ });
+
it('checks menu rendering without team feature', () => {
useConfigStore.setState({
config: { RELEASE: '1.0.0', FEATURES: { TEAMS: false }, LANGUAGES: [] },
});
+ useAuthStore.setState({
+ authenticated: true,
+ userData: {
+ id: '1',
+ email: 'test@example.com',
+ name: 'Test User',
+ abilities: {
+ contacts: { canView: true },
+ teams: { canView: true },
+ mailboxes: { canView: true },
+ },
+ },
+ });
render(, { wrapper: AppWrapper });
diff --git a/src/frontend/apps/desk/src/core/auth/api/types.ts b/src/frontend/apps/desk/src/core/auth/api/types.ts
index b3836215c..706706f3c 100644
--- a/src/frontend/apps/desk/src/core/auth/api/types.ts
+++ b/src/frontend/apps/desk/src/core/auth/api/types.ts
@@ -9,4 +9,20 @@ export interface User {
id: string;
email: string;
name?: string;
+ abilities?: {
+ mailboxes: UserAbilities;
+ contacts: UserAbilities;
+ teams: UserAbilities;
+ };
}
+
+export type UserAbilities = {
+ canView?: boolean;
+ canCreate?: boolean;
+};
+
+export const getDefaultAbilities = (): User['abilities'] => ({
+ mailboxes: { canView: true, canCreate: true },
+ contacts: { canView: true, canCreate: true },
+ teams: { canView: true, canCreate: true },
+});
diff --git a/src/frontend/apps/desk/src/features/mail-domains/access-management/api/__tests__/useMailDomainAccesses.test.tsx b/src/frontend/apps/desk/src/features/mail-domains/access-management/api/__tests__/useMailDomainAccesses.test.tsx
index 909297c61..e49afa9c3 100644
--- a/src/frontend/apps/desk/src/features/mail-domains/access-management/api/__tests__/useMailDomainAccesses.test.tsx
+++ b/src/frontend/apps/desk/src/features/mail-domains/access-management/api/__tests__/useMailDomainAccesses.test.tsx
@@ -35,7 +35,11 @@ describe('getMailDomainAccesses', () => {
{
id: '2',
role: Role.VIEWER,
- user: { id: '12', name: 'username2', email: 'user2@test.com' },
+ user: {
+ id: '12',
+ name: 'username2',
+ email: 'user2@test.com',
+ },
can_set_role_to: [Role.VIEWER],
},
],
diff --git a/src/frontend/apps/desk/src/features/menu/Menu.tsx b/src/frontend/apps/desk/src/features/menu/Menu.tsx
index d8a622e54..7bac98692 100644
--- a/src/frontend/apps/desk/src/features/menu/Menu.tsx
+++ b/src/frontend/apps/desk/src/features/menu/Menu.tsx
@@ -1,8 +1,8 @@
-import React from 'react';
import { useTranslation } from 'react-i18next';
import IconGroup from '@/assets/icons/icon-group.svg';
import { Box } from '@/components/';
+import { useAuthStore } from '@/core/auth';
import useCunninghamTheme from '@/cunningham/useCunninghamTheme';
import MenuItem from './MenuItems';
@@ -10,6 +10,9 @@ import IconMailDomains from './assets/icon-mails.svg';
export const Menu = () => {
const { colorsTokens } = useCunninghamTheme();
+ const { userData } = useAuthStore();
+
+ console.log(userData);
const { t } = useTranslation();
return (
@@ -22,17 +25,21 @@ export const Menu = () => {
$margin="none"
>
-
-
+ {userData?.abilities?.teams.canView && (
+
+ )}
+ {userData?.abilities?.mailboxes.canView && (
+
+ )}
);
diff --git a/src/frontend/apps/desk/src/pages/mail-domains/index.tsx b/src/frontend/apps/desk/src/pages/mail-domains/index.tsx
index 2b5c4dc04..7878e5554 100644
--- a/src/frontend/apps/desk/src/pages/mail-domains/index.tsx
+++ b/src/frontend/apps/desk/src/pages/mail-domains/index.tsx
@@ -4,7 +4,8 @@ import type { ReactElement } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
-import { Box } from '@/components';
+import { Box, Text } from '@/components';
+import { useAuthStore } from '@/core/auth';
import { MailDomainsLayout } from '@/features/mail-domains/domains';
import { NextPageWithLayout } from '@/types/next';
@@ -14,14 +15,18 @@ const StyledButton = styled(Button)`
const Page: NextPageWithLayout = () => {
const { t } = useTranslation();
-
+ const { userData } = useAuthStore();
+ const canCreate = userData?.abilities?.mailboxes.canCreate;
const router = useRouter();
return (
- void router.push('/mail-domains/add')}>
- {t('Add a mail domain')}
-
+ {canCreate && (
+ void router.push('/mail-domains/add')}>
+ {t('Add a mail domain')}
+
+ )}
+ {!canCreate && {t('Click on mailbox to view details')}}
);
};
diff --git a/src/frontend/apps/desk/src/pages/teams/index.tsx b/src/frontend/apps/desk/src/pages/teams/index.tsx
index 13dfde384..b5d447412 100644
--- a/src/frontend/apps/desk/src/pages/teams/index.tsx
+++ b/src/frontend/apps/desk/src/pages/teams/index.tsx
@@ -1,10 +1,11 @@
import { Button } from '@openfun/cunningham-react';
import { useRouter as useNavigate } from 'next/navigation';
-import type { ReactElement } from 'react';
+import { ReactElement } from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
-import { Box } from '@/components';
+import { Box, Text } from '@/components';
+import { useAuthStore } from '@/core/auth';
import { TeamLayout } from '@/features/teams/team-management';
import { NextPageWithLayout } from '@/types/next';
@@ -15,12 +16,17 @@ const StyledButton = styled(Button)`
const Page: NextPageWithLayout = () => {
const { t } = useTranslation();
const router = useNavigate();
+ const { userData } = useAuthStore();
+ const canCreate = userData?.abilities?.teams.canCreate ?? false;
return (
- void router.push('/teams/create')}>
- {t('Create a new team')}
-
+ {canCreate && (
+ void router.push('/teams/create')}>
+ {t('Create a new team')}
+
+ )}
+ {!canCreate && {t('Click on team to view details')}}
);
};
diff --git a/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts b/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts
index 5c753fc0a..3eb082d2a 100644
--- a/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts
+++ b/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts
@@ -13,7 +13,7 @@ test.describe('Menu', () => {
name: 'Teams',
isDefault: true,
expectedUrl: '/teams/',
- expectedText: 'Create a new team',
+ expectedText: 'Teams',
},
{
name: 'Mail Domains',
@@ -62,6 +62,92 @@ test.describe('Menu', () => {
});
}
+ test(`it checks that the menu is not displaying when no abilities`, async ({
+ page,
+ }) => {
+ await page.route('**/api/v1.0/users/me/', async (route) => {
+ await route.fulfill({
+ json: {
+ "id": "52de4dcf-5ca0-4b7f-9841-3a18e8cb6a95",
+ "email": "user@chromium.e2e",
+ "language": "en-us",
+ "name": "E2E Chromium",
+ "timezone": "UTC",
+ "is_device": false,
+ "is_staff": false,
+ "abilities": {
+ "contacts": {
+ "canView": true,
+ "canCreate": true
+ },
+ "teams": {
+ "canView": true,
+ "canCreate": false
+ },
+ "mailboxes": {
+ "canView": true,
+ "canCreate": false
+ }
+ }
+ }
+ });
+ });
+
+ const menu = page.locator('menu').first();
+
+ let buttonMenu = menu.getByLabel(`Teams button`);
+ await buttonMenu.click();
+ await expect(page.getByText('Click on team to view details').first()).toBeVisible();
+
+ buttonMenu = menu.getByLabel(`Mail Domains`);
+ await buttonMenu.click();
+ await expect(page.getByText('Click on mailbox to view details').first()).toBeVisible();
+
+ });
+
+ test(`it checks that the menu is not displaying when all abilities`, async ({
+ page,
+ }) => {
+ await page.route('**/api/v1.0/users/me/', async (route) => {
+ await route.fulfill({
+ json: {
+ "id": "52de4dcf-5ca0-4b7f-9841-3a18e8cb6a95",
+ "email": "user@chromium.e2e",
+ "language": "en-us",
+ "name": "E2E ChromiumMM",
+ "timezone": "UTC",
+ "is_device": false,
+ "is_staff": false,
+ "abilities": {
+ "contacts": {
+ "canView": true,
+ "canCreate": true
+ },
+ "teams": {
+ "canView": true,
+ "canCreate": true
+ },
+ "mailboxes": {
+ "canView": true,
+ "canCreate": true
+ }
+ }
+ }
+ });
+ });
+
+ const menu = page.locator('menu').first();
+
+ let buttonMenu = menu.getByLabel(`Teams button`);
+ await buttonMenu.click();
+ await expect(page.getByText('Create a new team').first()).toBeVisible();
+
+ buttonMenu = menu.getByLabel(`Mail Domains`);
+ await buttonMenu.click();
+ await expect(page.getByText('Add a mail domain').first()).toBeVisible();
+
+ });
+
test(`it checks that the sub menu is still highlighted`, async ({
page,
browserName,