✨(frontend) use user abilities to show or not the features
use the abilities to show or not the Teams / Mailbox features as well as the object creation button
This commit is contained in:
committed by
BEY Quentin
parent
6be1b63277
commit
6123e11dd4
@@ -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: { can_view: true },
|
||||
teams: { can_view: true },
|
||||
mailboxes: { can_view: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(<MainLayout />, { 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: { can_view: false },
|
||||
teams: { can_view: false },
|
||||
mailboxes: { can_view: false },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(<MainLayout />, { 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: { can_view: true },
|
||||
teams: { can_view: true },
|
||||
mailboxes: { can_view: true },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(<MainLayout />, { wrapper: AppWrapper });
|
||||
|
||||
|
||||
@@ -9,4 +9,14 @@ export interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
name?: string;
|
||||
abilities?: {
|
||||
mailboxes: UserAbilities;
|
||||
contacts: UserAbilities;
|
||||
teams: UserAbilities;
|
||||
};
|
||||
}
|
||||
|
||||
export type UserAbilities = {
|
||||
can_view?: boolean;
|
||||
can_create?: boolean;
|
||||
};
|
||||
|
||||
@@ -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],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
<Box $padding={{ top: 'large' }} $direction="column" $gap="0.8rem">
|
||||
<MenuItem
|
||||
Icon={IconGroup}
|
||||
label={t('Teams')}
|
||||
href="/teams"
|
||||
alias={['/teams']}
|
||||
/>
|
||||
<MenuItem
|
||||
Icon={IconMailDomains}
|
||||
label={t('Mail Domains')}
|
||||
href="/mail-domains"
|
||||
/>
|
||||
{userData?.abilities?.teams.can_view && (
|
||||
<MenuItem
|
||||
Icon={IconGroup}
|
||||
label={t('Teams')}
|
||||
href="/teams"
|
||||
alias={['/teams']}
|
||||
/>
|
||||
)}
|
||||
{userData?.abilities?.mailboxes.can_view && (
|
||||
<MenuItem
|
||||
Icon={IconMailDomains}
|
||||
label={t('Mail Domains')}
|
||||
href="/mail-domains"
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -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 can_create = userData?.abilities?.mailboxes.can_create;
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<Box $align="center" $justify="center" $height="inherit">
|
||||
<StyledButton onClick={() => void router.push('/mail-domains/add')}>
|
||||
{t('Add a mail domain')}
|
||||
</StyledButton>
|
||||
{can_create && (
|
||||
<StyledButton onClick={() => void router.push('/mail-domains/add')}>
|
||||
{t('Add a mail domain')}
|
||||
</StyledButton>
|
||||
)}
|
||||
{!can_create && <Text>{t('Click on mailbox to view details')}</Text>}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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 can_create = userData?.abilities?.teams.can_create ?? false;
|
||||
|
||||
return (
|
||||
<Box $align="center" $justify="center" $height="inherit">
|
||||
<StyledButton onClick={() => void router.push('/teams/create')}>
|
||||
{t('Create a new team')}
|
||||
</StyledButton>
|
||||
{can_create && (
|
||||
<StyledButton onClick={() => void router.push('/teams/create')}>
|
||||
{t('Create a new team')}
|
||||
</StyledButton>
|
||||
)}
|
||||
{!can_create && <Text>{t('Click on team to view details')}</Text>}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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,94 @@ 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: {
|
||||
can_view: true,
|
||||
can_create: true,
|
||||
},
|
||||
teams: {
|
||||
can_view: true,
|
||||
can_create: false,
|
||||
},
|
||||
mailboxes: {
|
||||
can_view: true,
|
||||
can_create: 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: {
|
||||
can_view: true,
|
||||
can_create: true,
|
||||
},
|
||||
teams: {
|
||||
can_view: true,
|
||||
can_create: true,
|
||||
},
|
||||
mailboxes: {
|
||||
can_view: true,
|
||||
can_create: 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,
|
||||
|
||||
Reference in New Issue
Block a user