Skip to content

Commit

Permalink
Update function signature for getUserInputFromProps (#1842)
Browse files Browse the repository at this point in the history
## Summary:
In my prior PR [where I updated this function
signature](614425b),
I wasn't aware that it was called outside of the component anywhere. It
turns out in Web App, [there are calls to
getUserInputFromProps](https://github.com/Khan/webapp/blob/master/services/static/javascript/coach-report-package/responses/utils.ts#L75)
and this change to the function signature breaks those calls.


## Test plan:
- Ensure the tests pass
  • Loading branch information
MikeKlemarewski authored Nov 9, 2024
2 parents 1c094ba + 11c1d1c commit 4004642
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/tough-buses-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@khanacademy/perseus": patch
---

Fix function signature of getUserInputFromProps for radio widget
152 changes: 152 additions & 0 deletions packages/perseus/src/__tests__/widgets.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,158 @@ describe("Widget API support", () => {
expect(Widget).toHaveProperty("getUserInputFromProps");
},
);

it("categorizer widget getUserInputFromProps should return the correct user input", () => {
const Widget = Widgets.getWidget("categorizer");

if (Widget && "getUserInputFromProps" in Widget) {
const props = {
values: [0, 1, 0, 1, 2],
};

// @ts-expect-error - TS2339 - Property 'getUserInputFromProps' does not exist on type 'ComponentType<any>'.
const userInput = Widget.getUserInputFromProps(props);
expect(userInput).toEqual({
values: [0, 1, 0, 1, 2],
});
} else {
throw new Error("Widget does not have getUserInputFromProps");
}
});

it("expression widget getUserInputFromProps should return the correct user input", () => {
const Widget = Widgets.getWidget("expression");

if (Widget && "getUserInputFromProps" in Widget) {
const props = {
value: "100 / 45",
};

// @ts-expect-error - TS2339 - Property 'getUserInputFromProps' does not exist on type 'ComponentType<any>'.
const userInput = Widget.getUserInputFromProps(props);
expect(userInput).toEqual("100 / 45");
} else {
throw new Error("Widget does not have getUserInputFromProps");
}
});

it("grapher widget getUserInputFromProps should return the correct user input", () => {
const Widget = Widgets.getWidget("grapher");

if (Widget && "getUserInputFromProps" in Widget) {
const props = {
plot: {
type: "linear",
coords: [
[0, 0],
[1, 1],
],
},
};

// @ts-expect-error - TS2339 - Property 'getUserInputFromProps' does not exist on type 'ComponentType<any>'.
const userInput = Widget.getUserInputFromProps(props);
expect(userInput).toEqual({
type: "linear",
coords: [
[0, 0],
[1, 1],
],
});
} else {
throw new Error("Widget does not have getUserInputFromProps");
}
});

it("input-number widget getUserInputFromProps should return the correct user input", () => {
const Widget = Widgets.getWidget("input-number");

if (Widget && "getUserInputFromProps" in Widget) {
const props = {
currentValue: "42",
};

// @ts-expect-error - TS2339 - Property 'getUserInputFromProps' does not exist on type 'ComponentType<any>'.
const userInput = Widget.getUserInputFromProps(props);
expect(userInput).toEqual({
currentValue: "42",
});
} else {
throw new Error("Widget does not have getUserInputFromProps");
}
});

it("interactive-graph widget getUserInputFromProps should return the correct user input", () => {
const Widget = Widgets.getWidget("interactive-graph");

if (Widget && "getUserInputFromProps" in Widget) {
const props = {
graph: {
type: "circle",
radius: 5,
center: [0, 0],
},
};

// @ts-expect-error - TS2339 - Property 'getUserInputFromProps' does not exist on type 'ComponentType<any>'.
const userInput = Widget.getUserInputFromProps(props);
expect(userInput).toEqual({
type: "circle",
radius: 5,
center: [0, 0],
});
} else {
throw new Error("Widget does not have getUserInputFromProps");
}
});

it("numeric-input widget getUserInputFromProps should return the correct user input", () => {
const Widget = Widgets.getWidget("numeric-input");

if (Widget && "getUserInputFromProps" in Widget) {
const props = {
currentValue: 42,
};

// @ts-expect-error - TS2339 - Property 'getUserInputFromProps' does not exist on type 'ComponentType<any>'.
const userInput = Widget.getUserInputFromProps(props);
expect(userInput).toEqual({
currentValue: 42,
});
} else {
throw new Error("Widget does not have getUserInputFromProps");
}
});

it("radio widget getUserInputFromProps should return the correct user input", () => {
const Widget = Widgets.getWidget("radio");

if (Widget && "getUserInputFromProps" in Widget) {
const props = {
choiceStates: [
{selected: false},
{selected: true},
{selected: false},
],
choices: [
{content: "a", originalIndex: 0},
{content: "b", originalIndex: 1},
{content: "c", originalIndex: 2},
],
};

// @ts-expect-error - TS2339 - Property 'getUserInputFromProps' does not exist on type 'ComponentType<any>'.
const userInput = Widget.getUserInputFromProps(props);
expect(userInput).toEqual({
choicesSelected: [false, true, false],
noneOfTheAboveIndex: null,
noneOfTheAboveSelected: false,
numCorrect: undefined,
});
} else {
throw new Error("Widget does not have getUserInputFromProps");
}
});
});

describe("replaceWidget", () => {
Expand Down
18 changes: 6 additions & 12 deletions packages/perseus/src/widgets/radio/radio-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,10 @@ class Radio extends React.Component<Props> implements Widget {
showSolutions: "none",
};

static getUserInputFromProps({
props,
unshuffle = true,
}: {
props: Props;
unshuffle?: boolean;
}): PerseusRadioUserInput {
static getUserInputFromProps(
props: Props,
unshuffle: boolean = true,
): PerseusRadioUserInput {
// Return checked inputs in the form {choicesSelected: [bool]}. (Dear
// future timeline implementers: this used to be {value: i} before
// multiple select was added)
Expand Down Expand Up @@ -286,14 +283,11 @@ class Radio extends React.Component<Props> implements Widget {
};

getUserInput(): PerseusRadioUserInput {
return Radio.getUserInputFromProps({props: this.props});
return Radio.getUserInputFromProps(this.props);
}

getPromptJSON(): RadioPromptJSON {
const userInput = Radio.getUserInputFromProps({
props: this.props,
unshuffle: false,
});
const userInput = Radio.getUserInputFromProps(this.props, false);
return _getPromptJSON(this.props, userInput);
}

Expand Down

0 comments on commit 4004642

Please sign in to comment.