Skip to content

Commit

Permalink
Add tests and make relevant changes
Browse files Browse the repository at this point in the history
  • Loading branch information
nishasy committed Sep 6, 2024
1 parent a187885 commit 3e8002f
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import {Dependencies} from "@khanacademy/perseus";
import {render, screen} from "@testing-library/react";
import {userEvent as userEventLib} from "@testing-library/user-event";
import * as React from "react";

import {testDependencies} from "../../../../../testing/test-dependencies";
import InteractiveGraphDescription from "../interactive-graph-description";

import type {UserEvent} from "@testing-library/user-event";

import "@testing-library/jest-dom"; // Imports custom matchers

function userEventForFakeTimers() {
return userEventLib.setup({
advanceTimers: jest.advanceTimersByTime,
});
}

describe("InteractiveGraphSettings", () => {
let userEvent: UserEvent;
beforeEach(() => {
userEvent = userEventForFakeTimers();
jest.spyOn(Dependencies, "getDependencies").mockReturnValue(
testDependencies,
);
});

test("renders", () => {
// Arrange
render(
<InteractiveGraphDescription
ariaLabelValue="Graph Title"
ariaDescriptionValue="Graph Description"
onChange={jest.fn()}
/>,
);

// Act
const titleInput = screen.getByRole("textbox", {name: "Title"});
const descriptionInput = screen.getByRole("textbox", {
name: "Description",
});

// Assert
expect(titleInput).toBeInTheDocument();
expect(titleInput).toHaveValue("Graph Title");
expect(descriptionInput).toBeInTheDocument();
expect(descriptionInput).toHaveValue("Graph Description");
});

test("calls onChange when the title is changed", async () => {
// Arrange
const onChange = jest.fn();
render(
<InteractiveGraphDescription
ariaLabelValue=""
ariaDescriptionValue=""
onChange={onChange}
/>,
);

// Act
const titleInput = screen.getByRole("textbox", {name: "Title"});
await userEvent.clear(titleInput);
await userEvent.type(titleInput, "Zot");

// Assert
// Calls are not being accumulated because they're mocked.
expect(onChange.mock.calls).toEqual([
[{fullGraphAriaLabel: "Z"}],
[{fullGraphAriaLabel: "o"}],
[{fullGraphAriaLabel: "t"}],
]);
});

test("calls onChange when the description is changed", async () => {
// Arrange
const onChange = jest.fn();
render(
<InteractiveGraphDescription
ariaLabelValue=""
ariaDescriptionValue=""
onChange={onChange}
/>,
);

// Act
const descriptionInput = screen.getByRole("textbox", {
name: "Description",
});
await userEvent.clear(descriptionInput);
await userEvent.type(descriptionInput, "Zot");

// Assert
// Calls are not being accumulated because they're mocked.
expect(onChange.mock.calls).toEqual([
[{fullGraphAriaDescription: "Z"}],
[{fullGraphAriaDescription: "o"}],
[{fullGraphAriaDescription: "t"}],
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function InteractiveGraphDescription(props: Props) {
are used by screen readers to describe content to users
who are visually impaired.
</LabelXSmall>
<LabelLarge>
<LabelLarge tag="label">
Title
<TextField
value={ariaLabelValue}
Expand All @@ -46,7 +46,7 @@ export default function InteractiveGraphDescription(props: Props) {
/>
</LabelLarge>
<Strut size={spacing.xSmall_8} />
<LabelLarge>
<LabelLarge tag="label">
Description
{/* TODO: Change this to a WB TextArea */}
<TextField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1066,4 +1066,28 @@ describe("InteractiveGraphEditor", () => {
}),
).toBeNull();
});

test("shows description section", () => {
// Arrange

// Act
render(
<InteractiveGraphEditor
{...mafsProps}
graph={{type: "segment"}}
correct={{type: "segment"}}
/>,
{
wrapper: RenderStateRoot,
},
);

// Assert
expect(
screen.getByRole("textbox", {name: "Title"}),
).toBeInTheDocument();
expect(
screen.getByRole("textbox", {name: "Description"}),
).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
angleQuestionWithDefaultCorrect,
circleQuestion,
circleQuestionWithDefaultCorrect,
interactiveGraphWithAriaLabel,
linearQuestion,
linearQuestionWithDefaultCorrect,
linearSystemQuestion,
Expand Down Expand Up @@ -911,4 +912,47 @@ describe("locked layer", () => {
top: "240px",
});
});

it("should have an aria-label and description if they are provided", async () => {
// Arrange
const {container} = renderQuestion(interactiveGraphWithAriaLabel, {
flags: {
mafs: {
segment: true,
"interactive-graph-locked-features-labels": true,
},
},
});

// Act
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const graph = container.querySelector(".mafs-graph");

// Assert
expect(graph).toHaveAttribute("aria-label", "Segment Graph Title");
// The aria-describedby attribute is set to the description
// element's ID. This ID is unique to the graph instance, so
// we can't predict it in this test.
expect(graph).toHaveAttribute("aria-describedby");
});

it("should not have an aria-label or description if they are not provided", async () => {
// Arrange
const {container} = renderQuestion(segmentQuestion, {
flags: {
mafs: {
segment: true,
"interactive-graph-locked-features-labels": true,
},
},
});

// Act
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const graph = container.querySelector(".mafs-graph");

// Assert
expect(graph).not.toHaveAttribute("aria-label");
expect(graph).not.toHaveAttribute("aria-describedby");
});
});
28 changes: 16 additions & 12 deletions packages/perseus/src/widgets/interactive-graphs/mafs-graph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,25 @@ export const MafsGraph = (props: MafsGraphProps) => {
}
}}
aria-label={fullGraphAriaLabel}
aria-describedby={descriptionId}
aria-describedby={
fullGraphAriaDescription ? descriptionId : undefined
}
ref={graphRef}
tabIndex={0}
>
<View
id={descriptionId}
tabIndex={-1}
style={{
width: 0,
height: 0,
overflow: "hidden",
}}
>
{fullGraphAriaDescription}
</View>
{fullGraphAriaDescription && (
<View
id={descriptionId}
tabIndex={-1}
style={{
width: 0,
height: 0,
overflow: "hidden",
}}
>
{fullGraphAriaDescription}
</View>
)}
<LegacyGrid
box={props.box}
backgroundImage={props.backgroundImage}
Expand Down

0 comments on commit 3e8002f

Please sign in to comment.