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

HCBS Footer 2/x - Set up app routes #13

Merged
merged 14 commits into from
Jul 31, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { render, screen } from "@testing-library/react";
import { axe } from "jest-axe";
import { RouterWrappedComponent } from "utils/testing/setupJest";
import { Accordion } from "@chakra-ui/react";
import { AccordionItem } from "components";

const accordionItemComponent = (
<RouterWrappedComponent>
<Accordion>
<AccordionItem data-testid="accordion-item" />
</Accordion>
</RouterWrappedComponent>
);

describe("Test AccordionItem", () => {
beforeEach(() => {
render(accordionItemComponent);
});

test("AccordionItem is visible", () => {
expect(screen.getByTestId("accordion-item")).toBeVisible();
});
});

describe("Test AccordionItem accessibility", () => {
it("Should not have basic accessibility issues", async () => {
const { container } = render(accordionItemComponent);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
59 changes: 59 additions & 0 deletions services/ui-src/src/components/accordions/AccordionItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ReactChild } from "react";
import {
AccordionButton,
AccordionItem as AccordionItemRoot,
AccordionPanel,
Image,
Text,
} from "@chakra-ui/react";
import plusIcon from "assets/icons/icon_plus.png";
import minusIcon from "assets/icons/icon_minus.png";

export const AccordionItem = ({ label, children, ...props }: Props) => {
return (
<AccordionItemRoot sx={sx.root} {...props}>
{({ isExpanded }) => (
<>
<AccordionButton
sx={sx.accordionButton}
aria-label={label}
title="accordion-button"
>
<Text flex="1">{label}</Text>
<Image
src={isExpanded ? minusIcon : plusIcon}
alt={isExpanded ? "Collapse" : "Expand"}
sx={sx.accordionIcon}
/>
</AccordionButton>
<AccordionPanel sx={sx.accordionPanel}>{children}</AccordionPanel>
</>
)}
</AccordionItemRoot>
);
};

interface Props {
children?: ReactChild | ReactChild[];
[key: string]: any;
}

const sx = {
root: {
borderStyle: "none",
},
accordionButton: {
minHeight: "3.5rem",
bg: "palette.gray_lightest",
textAlign: "left",
},
accordionPanel: {
padding: "1.5rem 1rem 0.5rem",
".mobile &": {
padding: "0.5rem 0",
},
},
accordionIcon: {
width: "1rem",
},
};
50 changes: 50 additions & 0 deletions services/ui-src/src/components/accordions/FaqAccordion.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { render, screen } from "@testing-library/react";
import { axe } from "jest-axe";
import userEvent from "@testing-library/user-event";
import { RouterWrappedComponent } from "utils/testing/setupJest";
import { FaqAccordion } from "components";

const accordionItems = [
{
question: "Question?",
answer: "Answer!",
},
];

const faqAccordionComponent = (
<RouterWrappedComponent>
<FaqAccordion accordionItems={accordionItems} />
</RouterWrappedComponent>
);

describe("Test FaqAccordion", () => {
beforeEach(() => {
render(faqAccordionComponent);
});

test("FaqAccordion is visible", () => {
expect(screen.getByText(accordionItems[0].question)).toBeVisible();
});

test("FaqAccordion default closed state only shows the question", () => {
expect(screen.getByText(accordionItems[0].question)).toBeVisible();
expect(screen.getByText(accordionItems[0].answer)).not.toBeVisible();
});

test("FaqAccordion should show answer on click", async () => {
const faqQuestion = screen.getByText(accordionItems[0].question);
expect(faqQuestion).toBeVisible();
expect(screen.getByText(accordionItems[0].answer)).not.toBeVisible();
await userEvent.click(faqQuestion);
expect(faqQuestion).toBeVisible();
expect(screen.getByText(accordionItems[0].answer)).toBeVisible();
});
});

describe("Test FaqAccordion accessibility", () => {
it("Should not have basic accessibility issues", async () => {
const { container } = render(faqAccordionComponent);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
33 changes: 33 additions & 0 deletions services/ui-src/src/components/accordions/FaqAccordion.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Accordion, Box, Text } from "@chakra-ui/react";
import { AccordionItem } from "components";
import { AnyObject } from "types";

export const FaqAccordion = ({ accordionItems, ...props }: Props) => {
return (
<Accordion allowToggle={true} allowMultiple={true} {...props}>
{accordionItems.map((item: AnyObject, index: number) => (
<AccordionItem key={index} label={item.question} sx={sx.item}>
<Box sx={sx.answerBox}>
<Text>{item.answer}</Text>
</Box>
</AccordionItem>
))}
</Accordion>
);
};

interface Props {
accordionItems: AnyObject;
}

const sx = {
item: {
marginBottom: "1.5rem",
borderStyle: "none",
},
answerBox: {
".mobile &": {
paddingLeft: "1rem",
},
},
};
19 changes: 17 additions & 2 deletions services/ui-src/src/components/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { useStore } from "utils";
import { Routes, Route } from "react-router-dom";
import { LoginCognito, LoginIDM, PostLogoutRedirect, Footer } from "components";
import {
AppRoutes,
Error,
LoginCognito,
rocio-desantiago marked this conversation as resolved.
Show resolved Hide resolved
LoginIDM,
PostLogoutRedirect,
Footer,
Timeout,
} from "components";
import { makeMediaQueryClasses } from "utils/other/useBreakpoint";
import { Container, Divider, Flex, Heading, Stack } from "@chakra-ui/react";
import { ErrorBoundary } from "react-error-boundary";

export const App = () => {
const mqClasses = makeMediaQueryClasses();
Expand All @@ -25,7 +34,13 @@ export const App = () => {
const authenticatedRoutes = (
<>
{user && (
<Flex data-testid="app-container" sx={sx.appLayout}>
<Flex sx={sx.appLayout}>
ajaitasaini marked this conversation as resolved.
Show resolved Hide resolved
<Timeout />
<Container sx={sx.appContainer} data-testid="app-container">
<ErrorBoundary FallbackComponent={Error}>
<AppRoutes />
</ErrorBoundary>
</Container>
<Footer />
</Flex>
)}
Expand Down
13 changes: 13 additions & 0 deletions services/ui-src/src/components/app/AppRoutes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Route, Routes } from "react-router-dom";
import { HelpPage } from "components";

export const AppRoutes = () => {
return (
<main id="main-content" tabIndex={-1}>
<Routes>
{/* General Routes */}
<Route path="/help" element={<HelpPage />} />
</Routes>
</main>
);
};
27 changes: 27 additions & 0 deletions services/ui-src/src/components/cards/Card.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { render, screen } from "@testing-library/react";
import { axe } from "jest-axe";
import { Card } from "components";

const cardComponent = (
<Card {...{ "data-testid": "card" }}>
<p>Mock child component</p>
</Card>
);

describe("Test Card", () => {
beforeEach(() => {
render(cardComponent);
});

test("Card is visible", () => {
expect(screen.getByTestId("card")).toBeVisible();
});
});

describe("Test Card accessibility", () => {
it("Should not have basic accessibility issues", async () => {
const { container } = render(cardComponent);
const results = await axe(container);
expect(results).toHaveNoViolations();
});
});
25 changes: 25 additions & 0 deletions services/ui-src/src/components/cards/Card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ReactChild } from "react";
import { Box } from "@chakra-ui/react";

export const Card = ({ children, ...props }: Props) => {
return (
<Box {...props} sx={sx.root}>
{children}
</Box>
);
};

interface Props {
children?: ReactChild | ReactChild[];
[key: string]: any;
}

const sx = {
root: {
width: "100%",
padding: "2rem",
".mobile &": {
padding: "1rem",
},
},
};
45 changes: 45 additions & 0 deletions services/ui-src/src/components/cards/EmailCard.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { render, screen } from "@testing-library/react";
import { axe } from "jest-axe";
import { EmailCard } from "components";
import { createEmailLink } from "utils/other/email";
import verbiage from "verbiage/pages/help";

const emailCardComponent = (
<EmailCard
verbiage={verbiage.cards.helpdesk}
icon="settings"
cardprops={{ "data-testid": "email-card" }}
/>
);

describe("Test EmailCard", () => {
beforeEach(() => {
render(emailCardComponent);
});

test("EmailCard is visible", () => {
expect(screen.getByTestId("email-card")).toBeVisible();
});

test("Email links are created correctly", () => {
const mockEmailData = {
address: "[email protected]",
subject: "the subject",
body: "the body",
};
const expectedEmailLink = "mailto:[email protected]?the%20subject";
expect(createEmailLink(mockEmailData)).toEqual(expectedEmailLink);
});

test("Email links are visible", () => {
expect(screen.getByRole("link")).toBeVisible();
});
});

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