Skip to content

Commit

Permalink
✨(frontend) use user abilities to show or not the features
Browse files Browse the repository at this point in the history
use the abilities to show or not the Teams / Mailbox features as well as the
object creation button
  • Loading branch information
PanchoutNathan committed Nov 12, 2024
1 parent aa7bb87 commit ec47642
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 24 deletions.
61 changes: 61 additions & 0 deletions src/frontend/apps/desk/src/core/__tests__/MainLayout.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => ({
Expand All @@ -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: '[email protected]',
name: 'Test User',
abilities: {
contacts: { canView: true },
teams: { canView: true },
mailboxes: { canView: true },
},
},
});

render(<MainLayout />, { wrapper: AppWrapper });

Expand All @@ -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: '[email protected]',
name: 'Test User',
abilities: {
contacts: { canView: false },
teams: { canView: false },
mailboxes: { canView: 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: '[email protected]',
name: 'Test User',
abilities: {
contacts: { canView: true },
teams: { canView: true },
mailboxes: { canView: true },
},
},
});

render(<MainLayout />, { wrapper: AppWrapper });

Expand Down
16 changes: 16 additions & 0 deletions src/frontend/apps/desk/src/core/auth/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ describe('getMailDomainAccesses', () => {
{
id: '2',
role: Role.VIEWER,
user: { id: '12', name: 'username2', email: '[email protected]' },
user: {
id: '12',
name: 'username2',
email: '[email protected]',
},
can_set_role_to: [Role.VIEWER],
},
],
Expand Down
31 changes: 19 additions & 12 deletions src/frontend/apps/desk/src/features/menu/Menu.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
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';
import IconMailDomains from './assets/icon-mails.svg';

export const Menu = () => {
const { colorsTokens } = useCunninghamTheme();
const { userData } = useAuthStore();

console.log(userData);
const { t } = useTranslation();

return (
Expand All @@ -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.canView && (
<MenuItem
Icon={IconGroup}
label={t('Teams')}
href="/teams"
alias={['/teams']}
/>
)}
{userData?.abilities?.mailboxes.canView && (
<MenuItem
Icon={IconMailDomains}
label={t('Mail Domains')}
href="/mail-domains"
/>
)}
</Box>
</Box>
);
Expand Down
15 changes: 10 additions & 5 deletions src/frontend/apps/desk/src/pages/mail-domains/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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 (
<Box $align="center" $justify="center" $height="inherit">
<StyledButton onClick={() => void router.push('/mail-domains/add')}>
{t('Add a mail domain')}
</StyledButton>
{canCreate && (
<StyledButton onClick={() => void router.push('/mail-domains/add')}>
{t('Add a mail domain')}
</StyledButton>
)}
{!canCreate && <Text>{t('Click on mailbox to view details')}</Text>}
</Box>
);
};
Expand Down
16 changes: 11 additions & 5 deletions src/frontend/apps/desk/src/pages/teams/index.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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 (
<Box $align="center" $justify="center" $height="inherit">
<StyledButton onClick={() => void router.push('/teams/create')}>
{t('Create a new team')}
</StyledButton>
{canCreate && (
<StyledButton onClick={() => void router.push('/teams/create')}>
{t('Create a new team')}
</StyledButton>
)}
{!canCreate && <Text>{t('Click on team to view details')}</Text>}
</Box>
);
};
Expand Down
88 changes: 87 additions & 1 deletion src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ test.describe('Menu', () => {
name: 'Teams',
isDefault: true,
expectedUrl: '/teams/',
expectedText: 'Create a new team',
expectedText: 'Teams',
},
{
name: 'Mail Domains',
Expand Down Expand Up @@ -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": "[email protected]",
"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": "[email protected]",
"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,
Expand Down

0 comments on commit ec47642

Please sign in to comment.