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

[UnlimitedPolygon] Fix open polygon scoring issues. #1999

Merged
merged 10 commits into from
Dec 16, 2024
6 changes: 6 additions & 0 deletions .changeset/weak-pandas-watch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/perseus": patch
"@khanacademy/perseus-editor": patch
---

Fixing open polygon scoring issues within exercises and editors.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
segmentWithStartingCoordsQuestion,
segmentsWithStartingCoordsQuestion,
sinusoidWithStartingCoordsQuestion,
unlimitedPolygonWithStartingCoordsQuestion,
} from "../../../perseus/src/widgets/interactive-graphs/interactive-graph.testdata";
import {registerAllWidgetsAndEditorsForTesting} from "../util/register-all-widgets-and-editors-for-testing";

Expand Down Expand Up @@ -125,6 +126,14 @@ export const InteractiveGraphPolygon = (): React.ReactElement => {
);
};

export const InteractiveGraphUnlimitedPolygon = (): React.ReactElement => {
return (
<EditorPageWithStorybookPreview
question={unlimitedPolygonWithStartingCoordsQuestion}
/>
);
};

export const InteractiveGraphAngle = (): React.ReactElement => {
return (
<EditorPageWithStorybookPreview
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,15 @@ class InteractiveGraphEditor extends React.Component<Props> {
}
}

// Do not save a unlimited polygon that is open (coords is null).
if (
this.props.graph?.type === "polygon" &&
this.props.graph.numSides === "unlimited" &&
this.props.graph.coords === null
) {
issues.push("Polygon must be closed.");
}

return issues;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ const PolygonGraph = (props: Props) => {
}
}, [props.graphState.focusedPointIndex, pointsRef]);

// If the unlimited polygon is rendered with 3 or more coordinates
// Close the polygon, but only on first render.
React.useEffect(() => {
if (numSides === "unlimited" && props.graphState.coords.length > 2) {
dispatch(actions.polygon.closePolygon());
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const statefulProps: StatefulProps = {
...props,
graphConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,19 @@ export const polygonWithStartingCoordsQuestion: PerseusRenderer =
})
.build();

export const unlimitedPolygonWithStartingCoordsQuestion: PerseusRenderer =
interactiveGraphQuestionBuilder()
.withPolygon("grid", {
numSides: "unlimited",
coords: [
[-4.5, -6],
[4.5, -5],
[3.5, 0.5],
[-4.5, 0],
],
})
.build();

export const polygonWithAnglesQuestion: PerseusRenderer =
interactiveGraphQuestionBuilder()
.withContent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ const defaultAngleState: InteractiveGraphState = {
allowReflexAngles: false,
};

const defaultUnlimitedPolygonState: InteractiveGraphState = {
type: "polygon",
closedPolygon: false,
focusedPointIndex: 0,
coords: [[5, 0]],
numSides: "unlimited",
hasBeenInteractedWith: true,
showRemovePointButton: false,
showKeyboardInteractionInvitation: false,
interactionMode: "mouse",
range: [
[-10, 10],
[-10, 10],
],
snapStep: [1, 1],
snapTo: "grid",
showSides: true,
showAngles: true,
};

describe("getGradableGraph", () => {
/**
* Originally `getGradableGraph` was returning a PerseusGraphType with just a
Expand Down Expand Up @@ -117,4 +137,30 @@ describe("getGradableGraph", () => {
[-5, -5],
]);
});

it("returns null coordinates if the unlimited polygon graph is open", () => {
const state: InteractiveGraphState = {
...defaultUnlimitedPolygonState,
closedPolygon: false,
};
const initialGraph: PerseusGraphType = {
type: "polygon",
};
const result = getGradableGraph(state, initialGraph);
invariant(result.type === "polygon");
expect(result.coords).toEqual(null);
});
catandthemachines marked this conversation as resolved.
Show resolved Hide resolved

it("returns coordinates if the unlimited polygon graph is closed", () => {
const state: InteractiveGraphState = {
...defaultUnlimitedPolygonState,
closedPolygon: true,
};
const initialGraph: PerseusGraphType = {
type: "polygon",
};
const result = getGradableGraph(state, initialGraph);
invariant(result.type === "polygon");
expect(result.coords).toEqual([[5, 0]]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ export function getGradableGraph(
}

if (state.type === "polygon" && initialGraph.type === "polygon") {
// Unless the polygon is closed it is not considered score-able.
if (state.numSides === "unlimited" && !state.closedPolygon) {
return {
...initialGraph,
coords: null,
};
}

return {
...initialGraph,
coords: state.coords,
Expand Down
Loading