Reset power selector on API failure to prevent state mismatch (#12319)
* Reset power selector on API failure to prevent state mismatch Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Allow onChange to be sync or async Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Add unmounted check Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Improve coverage Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
ddbc6439ce
commit
42ac873c55
4 changed files with 96 additions and 13 deletions
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
|
||||
import React from "react";
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import PowerSelector from "../../../../src/components/views/elements/PowerSelector";
|
||||
|
||||
|
@ -75,4 +76,25 @@ describe("<PowerSelector />", () => {
|
|||
expect(option.selected).toBeTruthy();
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should reset when onChange promise rejects", async () => {
|
||||
const deferred = defer<void>();
|
||||
render(
|
||||
<PowerSelector
|
||||
value={25}
|
||||
maxValue={100}
|
||||
usersDefault={0}
|
||||
onChange={() => deferred.promise}
|
||||
powerLevelKey="key"
|
||||
/>,
|
||||
);
|
||||
|
||||
const input = screen.getByLabelText("Power level");
|
||||
fireEvent.change(input, { target: { value: 40 } });
|
||||
fireEvent.blur(input);
|
||||
|
||||
await screen.findByDisplayValue(40);
|
||||
deferred.reject("Some error");
|
||||
await screen.findByDisplayValue(25);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,9 +15,10 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
import { fireEvent, render, RenderResult, screen } from "@testing-library/react";
|
||||
import { MatrixClient, EventType, MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
|
||||
import { fireEvent, render, RenderResult, screen, waitFor } from "@testing-library/react";
|
||||
import { MatrixClient, EventType, MatrixEvent, Room, RoomMember, ISendEventResponse } from "matrix-js-sdk/src/matrix";
|
||||
import { mocked } from "jest-mock";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import RolesRoomSettingsTab from "../../../../../../src/components/views/settings/tabs/room/RolesRoomSettingsTab";
|
||||
import { mkStubRoom, withClientContextRenderOptions, stubClient } from "../../../../../test-utils";
|
||||
|
@ -231,4 +232,37 @@ describe("RolesRoomSettingsTab", () => {
|
|||
expect(screen.getByTitle("Banned by Alice")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should roll back power level change on error", async () => {
|
||||
const deferred = defer<ISendEventResponse>();
|
||||
mocked(cli.sendStateEvent).mockReturnValue(deferred.promise);
|
||||
mocked(cli.getRoom).mockReturnValue(room);
|
||||
// @ts-ignore - mocked doesn't support overloads properly
|
||||
mocked(room.currentState.getStateEvents).mockImplementation((type, key) => {
|
||||
if (key === undefined) return [] as MatrixEvent[];
|
||||
if (type === "m.room.power_levels") {
|
||||
return new MatrixEvent({
|
||||
sender: "@sender:server",
|
||||
room_id: roomId,
|
||||
type: "m.room.power_levels",
|
||||
state_key: "",
|
||||
content: {
|
||||
users: {
|
||||
[cli.getUserId()!]: 100,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
return null;
|
||||
});
|
||||
mocked(room.currentState.mayClientSendStateEvent).mockReturnValue(true);
|
||||
const { container } = renderTab();
|
||||
|
||||
const selector = container.querySelector(`[placeholder="${cli.getUserId()}"]`)!;
|
||||
fireEvent.change(selector, { target: { value: "50" } });
|
||||
expect(selector).toHaveValue("50");
|
||||
|
||||
deferred.reject("Error");
|
||||
await waitFor(() => expect(selector).toHaveValue("100"));
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue