Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ajaitasaini committed Aug 5, 2024
1 parent 04e526a commit 744d142
Show file tree
Hide file tree
Showing 11 changed files with 388 additions and 1 deletion.
3 changes: 2 additions & 1 deletion services/ui-src/src/components/app/AppRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Route, Routes } from "react-router-dom";
import { HelpPage } from "components";
import { HelpPage, ProfilePage } from "components";

export const AppRoutes = () => {
return (
<main id="main-content" tabIndex={-1}>
<Routes>
{/* General Routes */}
<Route path="/profile" element={<ProfilePage />} />
<Route path="/help" element={<HelpPage />} />
</Routes>
</main>
Expand Down
3 changes: 3 additions & 0 deletions services/ui-src/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ export { LoginCognito } from "./logins/LoginCognito";
export { LoginIDM } from "./logins/LoginIDM";
// pages
export { HelpPage } from "./pages/HelpPage/HelpPage";
export { ProfilePage } from "./pages/Profile/ProfilePage";
// menus
export { Menu } from "./menus/Menu";
export { MenuOption } from "./menus/MenuOption";
// Redirects
export { PostLogoutRedirect } from "./PostLogoutRedirect/index";
// tables
export { Table } from "./tables/Table";
15 changes: 15 additions & 0 deletions services/ui-src/src/components/menus/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import {
Box,
Button,
Image,
Link,
Menu as MenuRoot,
MenuButton,
MenuItem,
MenuList,
} from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { MenuOption } from "components";
import { useBreakpoint } from "utils";
import accountCircleIcon from "assets/icons/icon_account_circle.png";
import chevronDownIcon from "assets/icons/icon_arrow_down.png";
import logoutIcon from "assets/icons/icon_arrow_right_square.png";
import editIcon from "assets/icons/icon_edit_square.png";

export const Menu = ({ handleLogout }: Props) => {
const { isMobile } = useBreakpoint();
Expand All @@ -35,6 +38,18 @@ export const Menu = ({ handleLogout }: Props) => {
</MenuButton>
</Box>
<MenuList sx={sx.menuList} data-testid="header-menu-options-list">
<Link as={RouterLink} to="/profile" variant="unstyled">
<MenuItem
sx={sx.menuItem}
data-testid="header-menu-option-manage-account"
>
<MenuOption
icon={editIcon}
altText="Manage account"
text="Manage Account"
/>
</MenuItem>
</Link>
<MenuItem
onClick={handleLogout}
sx={sx.menuItem}
Expand Down
78 changes: 78 additions & 0 deletions services/ui-src/src/components/pages/Profile/ProfilePage.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { fireEvent, render, screen } from "@testing-library/react";
import { axe } from "jest-axe";
// components
import { ProfilePage } from "components";
// utils
import {
mockAdminUserStore,
mockStateUserStore,
RouterWrappedComponent,
} from "utils/testing/setupJest";
import { useStore } from "utils";

const ProfilePageComponent = (
<RouterWrappedComponent>
<ProfilePage />
</RouterWrappedComponent>
);

// MOCKS

jest.mock("utils/state/useStore");
const mockedUseStore = useStore as jest.MockedFunction<typeof useStore>;

// TESTS

describe("Test ProfilePage for admin users", () => {
beforeEach(() => {
mockedUseStore.mockReturnValue(mockAdminUserStore);
render(ProfilePageComponent);
});
test("Check that Profile page renders properly", () => {
expect(screen.getByTestId("profile-view")).toBeVisible();
});

test("Check that there is an banner editor button visible", () => {
expect(screen.getByTestId("banner-admin-button")).toBeVisible();
});

test("Check that the state field is set to N/A", () => {
expect(screen.getByText("State")).toBeVisible();
expect(screen.getByText("N/A")).toBeVisible();
});

test("Check that admin button navigates to /admin on click", () => {
const adminButton = screen.getByTestId("banner-admin-button");
expect(adminButton).toBeVisible();
fireEvent.click(adminButton);
expect(window.location.pathname).toEqual("/admin");
});
});

describe("Test ProfilePage for state users", () => {
beforeEach(() => {
mockedUseStore.mockReturnValue(mockStateUserStore);
render(ProfilePageComponent);
});
test("Check that Profile page renders properly", () => {
expect(screen.getByTestId("profile-view")).toBeVisible();
});

test("Check that state is visible and set accordingly", () => {
expect(screen.getByText("State")).toBeVisible();
expect(screen.getByText("MN")).toBeVisible();
});

test("Check that there is not an banner editor button", () => {
expect(screen.queryByText("Banner Editor")).not.toBeInTheDocument();
});
});

describe("Test ProfilePage accessibility", () => {
it("Should not have basic accessibility issues", async () => {
mockedUseStore.mockReturnValue(mockAdminUserStore);
const { container } = render(ProfilePageComponent);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
80 changes: 80 additions & 0 deletions services/ui-src/src/components/pages/Profile/ProfilePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useNavigate } from "react-router-dom";
// components
import { Button, Heading, Link, Text } from "@chakra-ui/react";
import { PageTemplate, Table } from "components";
//utils
import { createEmailLink, useStore } from "utils";
import verbiage from "verbiage/pages/profile";

export const ProfilePage = () => {
const navigate = useNavigate();

const { email, given_name, family_name, userRole, state, userIsAdmin } =
useStore().user ?? {};

const { intro } = verbiage;

const tableContent = {
caption: "Profile Account Information",
bodyRows: [
["Email", email!],
["First Name", given_name!],
["Last Name", family_name!],
["Role", userRole!],
["State", state! || "N/A"],
],
};

return (
<PageTemplate sx={sx.layout} data-testid="profile-view">
<Heading as="h1" sx={sx.headerText}>
{intro.header}
</Heading>
<Text>
{intro.body}{" "}
<Link href={createEmailLink(intro.email)} isExternal>
{intro.email.address}
</Link>
.
</Text>
<Table content={tableContent} variant="striped" sxOverride={sx.table} />
{userIsAdmin && (
<Button
sx={sx.adminButton}
onClick={() => navigate("/admin")}
data-testid="banner-admin-button"
>
Banner Editor
</Button>
)}
</PageTemplate>
);
};

const sx = {
layout: {
".contentFlex": {
marginTop: "3.5rem",
marginBottom: "5rem !important",
},
},
headerText: {
marginBottom: "2rem",
fontSize: "2rem",
fontWeight: "normal",
},
table: {
marginTop: "2rem",
maxWidth: "100%",
"tr td:first-of-type": {
width: "8rem",
fontWeight: "semibold",
},
td: {
padding: "0.5rem",
},
},
adminButton: {
marginTop: "2rem",
},
};
36 changes: 36 additions & 0 deletions services/ui-src/src/components/tables/Table.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { render, screen } from "@testing-library/react";
import { axe } from "jest-axe";
// utils
import { RouterWrappedComponent } from "utils/testing/setupJest";
//components
import { Table } from "components";

const tableContent = {
caption: "mock caption",
headRow: ["mock header 1", "mock header 2", "mock header 3"],
bodyRows: [],
};

const tableComponent = (
<RouterWrappedComponent>
<Table content={tableContent} variant="striped" />
</RouterWrappedComponent>
);

describe("Test Table", () => {
beforeEach(() => {
render(tableComponent);
});

test("Table is visible", () => {
expect(screen.getByRole("table")).toBeVisible();
});
});

describe("Test Table accessibility", () => {
it("Should not have basic accessibility issues", async () => {
const { container } = render(tableComponent);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
Loading

0 comments on commit 744d142

Please sign in to comment.