Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚗️(frontend) show username on AccountDropDown #412

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to
- ✨(domains) add endpoint to list and retrieve domain accesses #404
- 🍱(dev) embark dimail-api as container #366
- ✨(dimail) allow la regie to request a token for another user #416
- ⚗️(frontend) show username on AccountDropDown #412

### Changed

Expand Down
33 changes: 18 additions & 15 deletions src/frontend/apps/desk/src/features/header/AccountDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,35 @@ import { useAuthStore } from '@/core/auth';

export const AccountDropdown = () => {
const { t } = useTranslation();
const { logout } = useAuthStore();
const { userData, logout } = useAuthStore();

const userName = userData?.name || t('No Username');
return (
<DropButton
aria-label={t('My account')}
button={
<Box $flex $direction="row" $align="center">
<Text $theme="primary">{t('My account')}</Text>
<Text $theme="primary">{userName}</Text>
<Text className="material-icons" $theme="primary" aria-hidden="true">
arrow_drop_down
</Text>
</Box>
}
>
<Button
onClick={logout}
color="primary-text"
icon={
<span className="material-icons" aria-hidden="true">
logout
</span>
}
aria-label={t('Logout')}
>
<Text $weight="normal">{t('Logout')}</Text>
</Button>
<Box $css="display: flex; direction: column; gap: 0.5rem">
<Button
onClick={logout}
key="logout"
color="primary-text"
icon={
<span className="material-icons" aria-hidden="true">
logout
</span>
}
aria-label={t('Logout')}
>
<Text $weight="normal">{t('Logout')}</Text>
</Button>
</Box>
</DropButton>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { useAuthStore } from '@/core/auth';
import { AppWrapper } from '@/tests/utils';

import { AccountDropdown } from '../AccountDropdown';

describe('AccountDropdown', () => {
const mockLogout = jest.fn();

const renderAccountDropdown = () =>
render(<AccountDropdown />, { wrapper: AppWrapper });

beforeEach(() => {
jest.clearAllMocks();
useAuthStore.setState({
userData: {
id: '1',
email: '[email protected]',
name: 'Test User',
},
logout: mockLogout,
});
});

it('renders the user name correctly', async () => {
renderAccountDropdown();

expect(await screen.findByText('Test User')).toBeInTheDocument();
});

it('renders "No Username" when userData name is missing', () => {
useAuthStore.setState({
userData: {
id: '1',
email: '[email protected]',
},
logout: mockLogout,
});

renderAccountDropdown();
expect(screen.getByText('No Username')).toBeInTheDocument();
});

it('opens the dropdown and shows logout button when clicked', async () => {
renderAccountDropdown();

const dropButton = await screen.findByText('Test User');
await userEvent.click(dropButton);

expect(screen.getByText('Logout')).toBeInTheDocument();
expect(screen.getByLabelText('Logout')).toBeInTheDocument();
});

it('calls logout function when logout button is clicked', async () => {
renderAccountDropdown();

const dropButton = await screen.findByText('Test User');
await userEvent.click(dropButton);

const logoutButton = screen.getByLabelText('Logout');
await userEvent.click(logoutButton);

expect(mockLogout).toHaveBeenCalledTimes(1);
});
});
2 changes: 1 addition & 1 deletion src/frontend/apps/desk/src/i18n/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@
"Member icon": "Icône de membre",
"Member {{name}} added to the team": "Membre {{name}} ajouté au groupe",
"More info?": "Plus d'infos ?",
"My account": "Mon compte",
"Names": "Noms",
"New name...": "Nouveau nom...",
"No Username": "Aucun nom d'utilisateur",
"No domains exist.": "Aucun domaine existant.",
"No mail box was created with this mail domain.": "Aucune boîte mail n'a été créée avec ce nom de domaine.",
"Nothing exceptional, no special privileges related to a .gouv.fr.": "Rien d'exceptionnel, pas de privilèges spéciaux liés à un .gouv.fr.",
Expand Down
10 changes: 6 additions & 4 deletions src/frontend/apps/e2e/__tests__/app-desk/header.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ test.beforeEach(async ({ page, browserName }) => {
});

test.describe('Header', () => {
test('checks all the elements are visible', async ({ page }) => {
test('checks all the elements are visible', async ({ page, browserName }) => {
const header = page.locator('header').first();

await expect(header.getByAltText('Marianne Logo')).toBeVisible();
Expand Down Expand Up @@ -37,13 +37,15 @@ test.describe('Header', () => {
).toBeVisible();

await expect(header.getByRole('combobox').getByText('EN')).toBeVisible();
await expect(header.getByText('My account')).toBeVisible();
await expect(
header.getByText(new RegExp(`E2E ${browserName}`, 'i')),
).toBeVisible();
});

test('checks logout button', async ({ page }) => {
test('checks logout button', async ({ page, browserName }) => {
await page
.getByRole('button', {
name: 'My account',
name: new RegExp(`E2E ${browserName}`, 'i'),
})
.click();

Expand Down
Loading