From 9953dd2111df0b4c182b99ff884acce52375071f Mon Sep 17 00:00:00 2001 From: Quentin BEY Date: Fri, 6 Dec 2024 16:47:28 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84(frontend)=20redirect=20home=20acco?= =?UTF-8?q?rding=20to=20abilities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We try to detect the landing page according to user permissions (abilities) instead of just the configuration setting. This will be improved when the homepage is developed --- CHANGELOG.md | 1 + .../apps/desk/src/__tests__/pages.test.tsx | 87 +++++++++++++++++++ src/frontend/apps/desk/src/pages/index.tsx | 22 ++++- .../e2e/__tests__/app-desk/config.spec.ts | 38 ++++++-- .../__tests__/app-desk/mail-domains.spec.ts | 6 +- 5 files changed, 143 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 570a590..6cf2413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to ### Added +- 💄(frontend) redirect home according to abilities #588 - ✨(maildomain_access) add API endpoint to search users #508 ## [1.8.0] - 2024-12-12 diff --git a/src/frontend/apps/desk/src/__tests__/pages.test.tsx b/src/frontend/apps/desk/src/__tests__/pages.test.tsx index b4798f0..5a2434c 100644 --- a/src/frontend/apps/desk/src/__tests__/pages.test.tsx +++ b/src/frontend/apps/desk/src/__tests__/pages.test.tsx @@ -2,6 +2,7 @@ import '@testing-library/jest-dom'; import { render } from '@testing-library/react'; import { useConfigStore } from '@/core'; +import { useAuthStore } from '@/core/auth'; import { AppWrapper } from '@/tests/utils'; import Page from '../pages'; @@ -20,6 +21,20 @@ describe('Page', () => { afterEach(() => jest.clearAllMocks()); it('checks Page rendering with team feature', () => { + 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 }, + }, + }, + }); + useConfigStore.setState({ config: { RELEASE: '1.0.0', @@ -35,6 +50,20 @@ describe('Page', () => { }); it('checks Page rendering without team feature', () => { + 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 }, + }, + }, + }); + useConfigStore.setState({ config: { RELEASE: '1.0.0', @@ -48,4 +77,62 @@ describe('Page', () => { expect(mockedPush).toHaveBeenCalledWith('/mail-domains/'); }); + + it('checks Page rendering with team permission', () => { + useAuthStore.setState({ + authenticated: true, + userData: { + id: '1', + email: 'test@example.com', + name: 'Test User', + abilities: { + contacts: { can_view: false }, + teams: { can_view: true }, + mailboxes: { can_view: false }, + }, + }, + }); + + useConfigStore.setState({ + config: { + RELEASE: '1.0.0', + COMMIT: 'NA', + FEATURES: { TEAMS_DISPLAY: false }, + LANGUAGES: [], + }, + }); + + render(, { wrapper: AppWrapper }); + + expect(mockedPush).toHaveBeenCalledWith('/teams/'); + }); + + it('checks Page rendering with mailbox permission', () => { + 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: true }, + }, + }, + }); + + useConfigStore.setState({ + config: { + RELEASE: '1.0.0', + COMMIT: 'NA', + FEATURES: { TEAMS_DISPLAY: true }, + LANGUAGES: [], + }, + }); + + render(, { wrapper: AppWrapper }); + + expect(mockedPush).toHaveBeenCalledWith('/mail-domains/'); + }); }); diff --git a/src/frontend/apps/desk/src/pages/index.tsx b/src/frontend/apps/desk/src/pages/index.tsx index 38ec82e..14d51f1 100644 --- a/src/frontend/apps/desk/src/pages/index.tsx +++ b/src/frontend/apps/desk/src/pages/index.tsx @@ -1,16 +1,36 @@ import { useRouter as useNavigate } from 'next/navigation'; import { useEffect } from 'react'; +import { useAuthStore } from '@/core/auth'; import { useConfigStore } from '@/core/config'; import { NextPageWithLayout } from '@/types/next'; const Page: NextPageWithLayout = () => { const { config } = useConfigStore(); + const { userData } = useAuthStore(); const router = useNavigate(); useEffect(() => { + if (!userData) { + router.push('/authenticate/'); + return; + } + + // 1. The user can see teams + if (userData.abilities?.teams?.can_view) { + router.push('/teams/'); + return; + } + + // 2. The user can see mailboxes + if (userData.abilities?.mailboxes?.can_view) { + router.push('/mail-domains/'); + return; + } + + // Fallback to the default route according to global config router.push(config?.FEATURES.TEAMS_DISPLAY ? '/teams/' : '/mail-domains/'); - }, [config?.FEATURES.TEAMS_DISPLAY, router]); + }, [config?.FEATURES.TEAMS_DISPLAY, userData, router]); return null; }; diff --git a/src/frontend/apps/e2e/__tests__/app-desk/config.spec.ts b/src/frontend/apps/e2e/__tests__/app-desk/config.spec.ts index 0c8a87a..a1ed78f 100644 --- a/src/frontend/apps/e2e/__tests__/app-desk/config.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-desk/config.spec.ts @@ -32,14 +32,40 @@ test.describe('Config', () => { }); }); - test('it checks that the config can deactivate the feature "teams"', async ({ + test('it checks that the user abilities display mail domains', async ({ + page, + browserName, + }) => { + await page.goto('/'); + await keyCloakSignIn(page, browserName, 'mail-member'); + + await expect(page.locator('menu')).toBeHidden(); + + await expect(page.getByText('Mail Domains')).toBeVisible(); + }); + + test('it checks that the user abilities display teams', async ({ page, browserName, }) => { await page.goto('/'); - // Login with a user who has the visibility on the groups await keyCloakSignIn(page, browserName, 'team-member'); + await expect(page.locator('menu')).toBeHidden(); + + await expect(page.getByText('Groups')).toBeVisible(); + }); + + test('it checks that the config does not deactivate the feature "teams"', async ({ + page, + browserName, + }) => { + await page.goto('/'); + // Login with a user who has the visibility on the groups should see groups + // It's now the backend that decides if the user can see the group menu and they + // should be redirected to the groups page in such case + await keyCloakSignIn(page, browserName, 'team-administrator'); + await page.route('**/api/v1.0/config/', async (route) => { const request = route.request(); if (request.method().includes('GET')) { @@ -59,12 +85,6 @@ test.describe('Config', () => { await expect(page.locator('menu')).toBeHidden(); - await expect( - page.getByRole('button', { - name: 'Create a new team', - }), - ).toBeHidden(); - - await expect(page.getByText('Mail Domains')).toBeVisible(); + await expect(page.getByText('Groups')).toBeVisible(); }); }); diff --git a/src/frontend/apps/e2e/__tests__/app-desk/mail-domains.spec.ts b/src/frontend/apps/e2e/__tests__/app-desk/mail-domains.spec.ts index 66919fa..e9079aa 100644 --- a/src/frontend/apps/e2e/__tests__/app-desk/mail-domains.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-desk/mail-domains.spec.ts @@ -75,7 +75,11 @@ test.describe('Mail domains', () => { test.describe('checks all the elements are visible', () => { test.beforeEach(async ({ page, browserName }) => { await page.goto('/'); - await keyCloakSignIn(page, browserName, 'mail-member'); + // The user is a team administrator, so they land on the team page + // This allows to prevent the redirection to the mail domains page + // to make the '/api/v1.0/mail-domains/?page=1&ordering=created_at' + // query at login, which will be cached and not called afterward in tests. + await keyCloakSignIn(page, browserName, 'team-administrator-mail-member'); }); test('checks the sort button', async ({ page }) => {