🐛(frontend) Bug manage access role (#449)

* 🐛(frontend) update access role

Currently, when you click on modify a role, the roles displayed are not the
correct ones. We always took the role of the connected user.
Additionally, there was a warning and a ban on changing roles if you were the
last owner, but it was decided that it was the backend that was throwing the
error and the action was allowed.

* (frontend) adapt tests

We adapt the tests. Remove the check if you are the last owner and use the new
props inside the relevant tests
This commit is contained in:
Nathan Panchout
2024-10-08 10:02:15 +02:00
committed by GitHub
parent fe249c5b6f
commit 6b7f00651f
6 changed files with 56 additions and 89 deletions

View File

@@ -8,6 +8,10 @@ and this project adheres to
## [Unreleased]
### Fixed
- 🐛(frontend) fix update accesses form #448
## [1.2.1] - 2024-10-03
### Fixed

View File

@@ -3,8 +3,11 @@ import { useTranslation } from 'react-i18next';
import { Role } from '../../domains';
const ORDERED_ROLES = [Role.VIEWER, Role.ADMIN, Role.OWNER];
interface ChooseRoleProps {
availableRoles: Role[];
roleAccess: Role;
currentRole: Role;
disabled: boolean;
setRole: (role: Role) => void;
@@ -12,55 +15,44 @@ interface ChooseRoleProps {
export const ChooseRole = ({
availableRoles,
roleAccess,
disabled,
currentRole,
setRole,
}: ChooseRoleProps) => {
const { t } = useTranslation();
const rolesToDisplay = Array.from(new Set([currentRole, ...availableRoles]));
const rolesToDisplay: Role[] = Array.from(
new Set([roleAccess, ...availableRoles]),
);
const translations = {
[Role.VIEWER]: t('Viewer'),
[Role.ADMIN]: t('Administrator'),
[Role.OWNER]: t('Owner'),
};
return (
<RadioGroup>
{rolesToDisplay?.map((role) => {
switch (role) {
case Role.VIEWER:
return (
<Radio
key={Role.VIEWER}
label={t('Viewer')}
value={Role.VIEWER}
name="role"
onChange={(evt) => setRole(evt.target.value as Role)}
defaultChecked={currentRole === Role.VIEWER}
disabled={disabled}
/>
);
case Role.ADMIN:
return (
<Radio
key={Role.ADMIN}
label={t('Administrator')}
value={Role.ADMIN}
name="role"
onChange={(evt) => setRole(evt.target.value as Role)}
defaultChecked={currentRole === Role.ADMIN}
disabled={disabled}
/>
);
case Role.OWNER:
return (
<Radio
key={Role.OWNER}
label={t('Owner')}
value={Role.OWNER}
name="role"
onChange={(evt) => setRole(evt.target.value as Role)}
defaultChecked={currentRole === Role.OWNER}
disabled={disabled || currentRole !== Role.OWNER}
/>
);
}
})}
{ORDERED_ROLES.filter((role) => rolesToDisplay.includes(role)).map(
(role) => {
let disableRadio = disabled;
if (role === Role.OWNER) {
disableRadio = disableRadio || currentRole !== Role.OWNER;
}
return (
<Radio
key={role}
label={translations[role]}
value={role}
name="role"
onChange={(evt) => setRole(evt.target.value as Role)}
defaultChecked={roleAccess === role}
disabled={disableRadio}
/>
);
},
)}
</RadioGroup>
);
};

View File

@@ -7,12 +7,11 @@ import {
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Box, Text, TextErrors } from '@/components';
import { Box, TextErrors } from '@/components';
import { Modal } from '@/components/Modal';
import { useUpdateMailDomainAccess } from '@/features/mail-domains/access-management';
import { Role } from '../../domains';
import { useWhoAmI } from '../hooks/useWhoAmI';
import { Access } from '../types';
import { ChooseRole } from './ChooseRole';
@@ -46,13 +45,10 @@ export const ModalRole = ({
onClose();
},
});
const { isLastOwner, isOtherOwner } = useWhoAmI(access);
const isNotAllowed = isOtherOwner || isLastOwner;
return (
<Modal
isOpen
isOpen={true}
leftActions={
<Button
color="secondary"
@@ -77,7 +73,7 @@ export const ModalRole = ({
accessId: access.id,
});
}}
disabled={isNotAllowed || isPending}
disabled={isPending}
>
{t('Validate')}
</Button>
@@ -93,28 +89,11 @@ export const ModalRole = ({
/>
)}
{(isLastOwner || isOtherOwner) && (
<Text
$theme="warning"
$direction="row"
$align="center"
$gap="0.5rem"
$margin={{ bottom: 'tiny' }}
$justify="center"
>
<span className="material-icons">warning</span>
{isLastOwner &&
t(
'You are the sole owner of this domain. Make another member the domain owner, before you can change your own role.',
)}
{isOtherOwner && t('You cannot update the role of other owner.')}
</Text>
)}
<ChooseRole
roleAccess={access.role}
availableRoles={access.can_set_role_to}
currentRole={currentRole}
disabled={isNotAllowed}
disabled={false}
setRole={setLocalRole}
/>
</Box>

View File

@@ -15,6 +15,7 @@ describe('ChooseRole', () => {
) => {
const defaultProps = {
availableRoles: [Role.VIEWER, Role.ADMIN],
roleAccess: Role.ADMIN,
currentRole: Role.ADMIN,
disabled: false,
setRole: mockSetRole,
@@ -28,13 +29,22 @@ describe('ChooseRole', () => {
jest.clearAllMocks();
});
it('renders available roles correctly', () => {
it('renders available roles correctly when we are Administrator', () => {
renderChooseRole();
expect(screen.getByLabelText('Viewer')).toBeInTheDocument();
expect(screen.getByLabelText('Administrator')).toBeInTheDocument();
});
it('renders available roles correctly when we are owner', () => {
renderChooseRole({
currentRole: Role.OWNER,
roleAccess: Role.OWNER,
});
expect(screen.getByLabelText('Viewer')).toBeInTheDocument();
expect(screen.getByLabelText('Administrator')).toBeInTheDocument();
expect(screen.getByLabelText('Owner')).toBeInTheDocument();
});
it('sets default role checked correctly', () => {
renderChooseRole({ currentRole: Role.ADMIN });
@@ -91,6 +101,7 @@ describe('ChooseRole', () => {
it('renders and checks owner role correctly when currentRole is owner', () => {
renderChooseRole({
currentRole: Role.OWNER,
roleAccess: Role.OWNER,
availableRoles: [Role.OWNER, Role.VIEWER, Role.ADMIN],
});

View File

@@ -115,26 +115,6 @@ describe('ModalRole', () => {
);
});
it('disables the Validate button if the user is the last owner', () => {
renderModalRole(true, false); // isLastOwner = true, isOtherOwner = false
const validateButton = screen.getByRole('button', { name: /Validate/i });
expect(validateButton).toBeDisabled();
expect(
screen.getByText(/You are the sole owner of this domain/i),
).toBeInTheDocument();
});
it('disables the Validate button if the user is another owner', () => {
renderModalRole(false, true); // isLastOwner = false, isOtherOwner = true
const validateButton = screen.getByRole('button', { name: /Validate/i });
expect(validateButton).toBeDisabled();
expect(
screen.getByText(/You cannot update the role of other owner/i),
).toBeInTheDocument();
});
it('shows error message when update fails', async () => {
fetchMock.patch(`end:mail-domains/domain-slug/accesses/1-1-1-1-1-1/`, {
status: 400,

View File

@@ -1,4 +1,5 @@
import { UUID } from 'crypto';
export interface MailDomain {
id: UUID;
name: string;