diff --git a/react/src/components/HeaderNavBar/HeaderNavBar.module.css b/react/src/components/HeaderNavBar/HeaderNavBar.module.css index d18d3fab..0991686b 100644 --- a/react/src/components/HeaderNavBar/HeaderNavBar.module.css +++ b/react/src/components/HeaderNavBar/HeaderNavBar.module.css @@ -1,9 +1,12 @@ .root { + background-color: black; + color: white; display: flex; align-items: center; flex-direction: row; justify-content: space-between; height: var(--hazmapper-header-navbar-height); + padding: 5px; } .userName { color: white; diff --git a/react/src/components/HeaderNavBar/HeaderNavBar.test.tsx b/react/src/components/HeaderNavBar/HeaderNavBar.test.tsx new file mode 100644 index 00000000..48da898f --- /dev/null +++ b/react/src/components/HeaderNavBar/HeaderNavBar.test.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { fireEvent } from '@testing-library/react'; +import * as ROUTES from '@hazmapper/constants/routes'; +import { renderInTest } from '@hazmapper/test/testUtil'; +import { HeaderNavBar } from './HeaderNavBar'; + +const mockNavigate = jest.fn(); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => mockNavigate, + useLocation: () => ({ + pathname: '/project-public/cd010f4d-3975-4fde-8bbd-b81ffb87273f', + }), +})); + +const mockAuthenticatedUser = { + data: null, + isLoading: false, + error: null, +}; + +jest.mock('@hazmapper/hooks/user/useAuthenticatedUser', () => { + return { + __esModule: true, + default: () => { + return { ...mockAuthenticatedUser }; + }, + }; +}); + +describe('HeaderNavBar', () => { + beforeEach(() => { + mockNavigate.mockClear(); + mockAuthenticatedUser.data = null; + }); + + test('clicking login button should navigate to login with correct return URL', () => { + const { getByText } = renderInTest(); + + const loginButton = getByText('Login'); + fireEvent.click(loginButton); + + const expectedPath = '/project-public/cd010f4d-3975-4fde-8bbd-b81ffb87273f'; + const expectedUrl = `${ROUTES.LOGIN}?to=${encodeURIComponent( + expectedPath + )}`; + + expect(mockNavigate).toHaveBeenCalledTimes(1); + expect(mockNavigate).toHaveBeenCalledWith(expectedUrl); + expect(mockNavigate).not.toHaveBeenCalledWith(ROUTES.MAIN); + }); + + test('clicking header should navigate to main', () => { + const { getByRole } = renderInTest(); + + const header = getByRole('button', { name: 'return to project listings' }); + fireEvent.click(header); + + expect(mockNavigate).toHaveBeenCalledWith(ROUTES.MAIN); + }); + + test('displays username when user is authenticated', () => { + Object.assign(mockAuthenticatedUser, { + data: { username: 'testUser' }, + }); + + const { getByText, queryByText } = renderInTest(); + + expect(getByText('testUser')).toBeDefined(); + expect(queryByText('Login')).toBeNull(); + }); +}); diff --git a/react/src/components/HeaderNavBar/HeaderNavBar.tsx b/react/src/components/HeaderNavBar/HeaderNavBar.tsx index 93b90a39..ed04f22b 100644 --- a/react/src/components/HeaderNavBar/HeaderNavBar.tsx +++ b/react/src/components/HeaderNavBar/HeaderNavBar.tsx @@ -1,13 +1,13 @@ import React from 'react'; -import { Layout } from 'antd'; import useAuthenticatedUser from '@hazmapper/hooks/user/useAuthenticatedUser'; -import { useNavigate } from 'react-router-dom'; +import { useNavigate, useLocation } from 'react-router-dom'; import { Button, InlineMessage, LoadingSpinner } from '@tacc/core-components'; import styles from './HeaderNavBar.module.css'; +import * as ROUTES from '@hazmapper/constants/routes'; export const HeaderNavBar: React.FC = () => { - const { Header } = Layout; const navigate = useNavigate(); + const location = useLocation(); const { data: userData, @@ -15,8 +15,10 @@ export const HeaderNavBar: React.FC = () => { error: isUserError, } = useAuthenticatedUser(); - const handleLogin = () => { - const url = `/login?to=${encodeURIComponent(location.pathname)}`; + const handleLogin = (e: React.MouseEvent) => { + e.stopPropagation(); + + const url = `${ROUTES.LOGIN}?to=${encodeURIComponent(location.pathname)}`; navigate(url); }; @@ -34,20 +36,27 @@ export const HeaderNavBar: React.FC = () => { } return ( -
+
navigate(ROUTES.MAIN)} + onClick={() => navigate(ROUTES.MAIN)} + role="button" + aria-label="return to project listings" + tabIndex={0} + > Hazmapper Logo - {userData && userData.username ? ( + {userData?.username ? (
{userData.username}
) : ( )} -
+ ); }; export default HeaderNavBar;