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 unit test expansion #772

Merged
merged 26 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
20d46c1
add shadcn init with config
dpgraham4401 Aug 14, 2024
4723197
implement topnav component with tailwind
dpgraham4401 Aug 14, 2024
e6b5b78
add button component
dpgraham4401 Aug 14, 2024
b952a00
move Ht* components to a 'legacyUi' directory
dpgraham4401 Aug 14, 2024
13dee9f
update primary color
dpgraham4401 Aug 14, 2024
0a6dd3c
add dropdown menu
dpgraham4401 Aug 14, 2024
87f7037
add Dropdown menu component, implement in top navigation bar, fix pri…
dpgraham4401 Aug 15, 2024
0254823
add sheet component
dpgraham4401 Aug 15, 2024
a4ff7f5
add separator UI component
dpgraham4401 Aug 15, 2024
2a149e5
add sheet UI component and modify compose and IDE configs, vitest UI …
dpgraham4401 Aug 15, 2024
4c9b069
convert sidebar sheet to use tailwind and our internal component library
dpgraham4401 Aug 15, 2024
05d6147
add dummy test for our dummy charts
dpgraham4401 Aug 15, 2024
58fee41
rename HaztrakSite directory to Site directory
dpgraham4401 Aug 15, 2024
c3d4d23
add RcraProfile unit tests
dpgraham4401 Aug 15, 2024
57082ca
add About feature spec file
dpgraham4401 Aug 15, 2024
b95783f
add spec file for RegisterHero
dpgraham4401 Aug 15, 2024
1023e53
ignore config files in vitest coverage
dpgraham4401 Aug 15, 2024
dc243a3
add router props to renderWithProvider mock
dpgraham4401 Aug 15, 2024
d49106c
add unit test for Private Route
dpgraham4401 Aug 15, 2024
4d35675
add unit tests for useAuth hook
dpgraham4401 Aug 15, 2024
ac98062
WasteLineTable unit tests
dpgraham4401 Aug 15, 2024
6f94490
WasteRowActions test file
dpgraham4401 Aug 15, 2024
97ca5ef
initial manifest details test suite
dpgraham4401 Aug 16, 2024
90dcc60
ManifestList test suite
dpgraham4401 Aug 16, 2024
4506cc6
add initial profile test suite
dpgraham4401 Aug 16, 2024
d3bebb5
siteDetails unit tests
dpgraham4401 Aug 16, 2024
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
15 changes: 0 additions & 15 deletions .idea/runConfigurations/Vitest_Coverage.xml

This file was deleted.

2 changes: 1 addition & 1 deletion .idea/runConfigurations/Vitest_UI.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions client/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ErrorBoundary } from '~/components/Error';
import { Notifications } from '~/components/Notifications/Notifications';
import { HtSpinner } from '~/components/UI';
import { HtSpinner } from 'app/components/legacyUi';
import React, { ReactElement, Suspense } from 'react';
import { Container } from 'react-bootstrap';
import { RouterProvider } from 'react-router-dom';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { ErrorBoundary } from '~/components/Error';
import { Notifications } from '~/components/Notifications/Notifications';
import { router } from '~/routes';
import './App.scss';
import './globals.css';

const GlobalSpinner = () => (
<Container fluid className="d-flex justify-content-center align-items-center vh-100">
Expand Down
22 changes: 3 additions & 19 deletions client/app/components/Auth/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { zodResolver } from '@hookform/resolvers/zod';
import React, { useEffect, useState } from 'react';
import { HtForm, HtSpinner } from 'app/components/legacyUi';
import React from 'react';
import { FloatingLabel, Form } from 'react-bootstrap';
import { useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom';
import { z } from 'zod';
import { HtForm, HtSpinner } from '~/components/UI';
import { useAuth } from '~/hooks/useAuth/useAuth';

const loginSchema = z.object({
Expand All @@ -16,33 +15,18 @@ type LoginSchema = z.infer<typeof loginSchema>;

export function LoginForm() {
const {
user,
login: { login, isLoading, error },
} = useAuth();
const [loginError, setLoginError] = useState<string | undefined>(undefined);
const navigate = useNavigate();
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<LoginSchema>({ resolver: zodResolver(loginSchema) });

useEffect(() => {
if (user) {
navigate('/');
}
}, [user]);

async function onSubmit({ username, password }: LoginSchema) {
login({ username, password });
}

useEffect(() => {
if (error) {
setLoginError('Error logging in');
}
}, [error]);

return (
<HtForm onSubmit={handleSubmit(onSubmit)}>
<HtForm.Group>
Expand Down Expand Up @@ -71,7 +55,7 @@ export function LoginForm() {
<span>Login </span>
{isLoading && <HtSpinner size="lg" className="text-reset" />}
</button>
{loginError && <div className="alert alert-danger mt-3 mb-0">{loginError}</div>}
{error && <div className="alert alert-danger mt-3 mb-0">{error.message}</div>}
</HtForm>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { render } from '@testing-library/react';
import { GeneratorStatusAreaChart } from './GeneratorStatusAreaChart';
import { describe, it } from 'vitest';

// This is a awful, dummy test we're using to run out dummy charts
describe('GeneratorStatusAreaChart', () => {
it('renders without crashing', () => {
render(<GeneratorStatusAreaChart />);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { render } from '@testing-library/react';
import { ManifestCountBarChart } from './ManifestCountBarChart';
import { describe, it } from 'vitest';

// This is a awful, dummy test we're using to run out dummy charts
describe('ManifestCountBarChart', () => {
it('renders without crashing', () => {
render(<ManifestCountBarChart />);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ManifestStatusPieChart } from '~/components/Charts';
import { describe, it } from 'vitest';
import { renderWithProviders } from '~/mocks';

// This is a awful, dummy test we're using to run out dummy charts
describe('ManifestStatusPieChart', () => {
it('renders the pie without crashing', async () => {
renderWithProviders(<ManifestStatusPieChart />);
});
});
2 changes: 1 addition & 1 deletion client/app/components/Help/HaztrakLicense.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { HtCard } from 'app/components/legacyUi';
import React from 'react';
import { HtCard } from '~/components/UI';

export function HaztrakLicense() {
return (
Expand Down
30 changes: 10 additions & 20 deletions client/app/components/Layout/Nav/NavItem.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { faArrowUpRightFromSquare } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import colors from 'tailwindcss/colors';
import { NavContext, NavContextProps } from '~/components/Layout/Root';
import { Route } from '~/components/Layout/Sidebar/SidebarRoutes';
import React, { useContext } from 'react';
import { Link } from 'react-router-dom';
import { NavLink } from 'react-bootstrap';
import { LuExternalLink } from 'react-icons/lu';
import { Button } from '~/components/ui';

interface NavItemProps {
route: Route;
Expand All @@ -19,22 +19,12 @@ export function NavItem({ route, targetBlank }: NavItemProps) {
};

return (
<NavLink
className="text-decoration-none text-dark py-2 d-flex align-items-center "
as={Link}
to={route.url}
target={targetBlank ? '_blank' : undefined}
onClick={toggleSidebar}
>
<FontAwesomeIcon icon={route.icon} className="me-2 text-primary ms-2" size="lg" />
<span className=" mb-0">{route.text}</span>
{route.external && (
<FontAwesomeIcon
icon={faArrowUpRightFromSquare}
className="text-danger pb-2 ms-1"
size="xs"
/>
)}
</NavLink>
<Button asChild variant="link">
<Link to={route.url} target={targetBlank ? '_blank' : undefined} onClick={toggleSidebar}>
<route.icon color={colors.cyan[700]} size={24} className="tw-me-3" />
<span className="tw-text-lg tw-text-black">{route.text}</span>
{route.external && <LuExternalLink className="tw-m-2 tw-text-destructive" />}
</Link>
</Button>
);
}
9 changes: 5 additions & 4 deletions client/app/components/Layout/Nav/NavSection.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { NavItem } from '~/components/Layout/Nav/NavItem';
import { RoutesSection } from '~/components/Layout/Sidebar/SidebarRoutes';
import React from 'react';
import { Separator } from '~/components/ui/Separator/Separator';

interface SidebarSectionProps {
section: RoutesSection;
}

export function NavSection({ section }: SidebarSectionProps) {
return (
<>
<hr className="my-0" />
<p className="text-secondary mt-1 mb-1">{section.name}</p>
<div className="tw-mt-8">
<Separator />
<p className="tw-text-primary">{section.name}</p>
{section.routes.map((route) => {
return (
<div key={route.id}>
<NavItem route={route} />
</div>
);
})}
</>
</div>
);
}
2 changes: 1 addition & 1 deletion client/app/components/Layout/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { HtSpinner } from 'app/components/legacyUi';
import React, { createContext, Dispatch, SetStateAction, Suspense, useState } from 'react';
import { Container } from 'react-bootstrap';
import { Outlet } from 'react-router-dom';
import { ErrorBoundary } from '~/components/Error';
import { HtSpinner } from '~/components/UI';
import { Sidebar } from './Sidebar/Sidebar';
import { TopNav } from './TopNav/TopNav';

Expand Down
57 changes: 26 additions & 31 deletions client/app/components/Layout/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,40 @@ import { NavSection } from '~/components/Layout/Nav/NavSection';
import { NavItem } from '~/components/Layout/Nav/NavItem';
import { NavContext, NavContextProps } from '~/components/Layout/Root';
import React, { ReactElement, useContext } from 'react';
import { Nav, Offcanvas } from 'react-bootstrap';
import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import { RootState } from '~/store';
import { routes } from './SidebarRoutes';
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '~/components/ui';

/** Vertical sidebar for navigation that disappears when the viewport is small*/
export function Sidebar(): ReactElement | null {
const authUser = useSelector((state: RootState) => state.auth.user);
const { showSidebar, setShowSidebar } = useContext<NavContextProps>(NavContext);

if (!authUser) return null;
return (
<Offcanvas show={showSidebar} onHide={setShowSidebar}>
<Offcanvas.Header closeButton>
<Offcanvas.Title>
<Link to="/" className="navbar-brand ps-1 mb-0">
<img
src={logo}
alt="haztrak logo, hazardous waste tracking made easy."
width={200}
height={'auto'}
/>
</Link>
</Offcanvas.Title>
</Offcanvas.Header>
<Offcanvas.Body>
<nav className="sb-sidenav" id="sidenavAccordion">
<Nav className="flex-column">
{routes.map((route) => {
if (typeof route === 'object' && 'routes' in route) {
return <NavSection key={route.id} section={route} />;
} else if (typeof route === 'object' && 'url' in route) {
return <NavItem key={route.id} route={route} />;
}
})}
</Nav>
<Sheet open={showSidebar} onOpenChange={setShowSidebar}>
<SheetContent side="left">
<SheetHeader>
<SheetTitle asChild>
<Link to="/" className="tw-flex tw-justify-center">
<img
src={logo}
alt="haztrak logo, hazardous waste tracking made easy."
width={200}
height={'auto'}
className=""
/>
</Link>
</SheetTitle>
</SheetHeader>
<nav>
{routes.map((route) => {
if (typeof route === 'object' && 'routes' in route) {
return <NavSection key={route.id} section={route} />;
} else if (typeof route === 'object' && 'url' in route) {
return <NavItem key={route.id} route={route} />;
}
})}
</nav>
</Offcanvas.Body>
</Offcanvas>
</SheetContent>
</Sheet>
);
}
34 changes: 15 additions & 19 deletions client/app/components/Layout/Sidebar/SidebarRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { faGithub } from '@fortawesome/free-brands-svg-icons';
import {
faCircleQuestion,
faFileLines,
faLocationDot,
faNetworkWired,
faRecycle,
faTachometerAlt,
} from '@fortawesome/free-solid-svg-icons';
import { LuFactory, LuFileCode2, LuHelpCircle } from 'react-icons/lu';
import { IconType } from 'react-icons';
import { TbBinaryTree } from 'react-icons/tb';
import { RiGovernmentFill } from 'react-icons/ri';
import { IoIosDocument } from 'react-icons/io';
import { FaGithub } from 'react-icons/fa';

export interface Route {
id: string;
icon: IconProp;
icon: IconType;
text: string;
url: string;
description?: string;
Expand All @@ -21,14 +17,14 @@ export interface Route {
export interface RoutesSection {
name: string;
id: string;
icon?: IconProp;
icon?: IconType;
routes: Route[];
}

export const routes: (Route | RoutesSection)[] = [
{
id: 'Dashboard',
icon: faTachometerAlt,
icon: TbBinaryTree,
text: 'Dashboard',
url: '/',
},
Expand All @@ -38,13 +34,13 @@ export const routes: (Route | RoutesSection)[] = [
routes: [
{
id: 'mySites',
icon: faLocationDot,
icon: LuFactory,
text: 'My Sites',
url: '/site',
},
{
id: 'rcraInfo',
icon: faRecycle,
icon: RiGovernmentFill,
text: 'RCRAInfo',
url: import.meta.env.DEV ? 'https://rcrainfopreprod.epa.gov' : 'https://rcrainfo.epa.gov',
description: 'RCRAInfo',
Expand All @@ -58,7 +54,7 @@ export const routes: (Route | RoutesSection)[] = [
routes: [
{
id: 'My Manifests',
icon: faFileLines,
icon: IoIosDocument,
text: 'My Manifests',
url: '/manifest',
description: 'All hazardous waste manifest',
Expand All @@ -71,22 +67,22 @@ export const routes: (Route | RoutesSection)[] = [
routes: [
{
id: 'About',
icon: faCircleQuestion,
icon: LuHelpCircle,
text: 'About',
url: '/about',
description: 'About Haztrak',
},
{
id: 'openApi',
icon: faNetworkWired,
icon: LuFileCode2,
text: 'OpenAPI Docs',
url: `${import.meta.env.VITE_HT_API_URL}/api/schema/swagger-ui`,
description: 'API Documentation',
external: true,
},
{
id: 'reportAnIssue',
icon: faGithub,
icon: FaGithub,
text: 'Report an Issue',
url: `${import.meta.env.VITE_GITHUB_URL}/issues`,
description: 'API Documentation',
Expand Down
Loading
Loading