Automatically adjust history visibility when making a room private (#30713)

* Refactor StyledRadioButton to provide proper labels.

* Automatically change history settings to members only if room is made private

* Add tests

* lint

* lint further

* Fix clickable buttons

* Revert functional component-ing

* text tweaks

* update snapshots

* Add unit test for history vis changes

* lint

* Update snapshots

* Fix flakes

* lint
This commit is contained in:
Will Hunt
2025-09-08 15:54:15 +01:00
committed by GitHub
parent 6d05bfc4c5
commit 6b510a535b
8 changed files with 239 additions and 25 deletions

View File

@@ -11,6 +11,7 @@ import { fireEvent, render, screen, waitFor, within } from "jest-matrix-react";
import { EventType, GuestAccess, HistoryVisibility, JoinRule, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";
import { mocked } from "jest-mock";
import { type RoomPowerLevelsEventContent } from "matrix-js-sdk/src/types";
import SecurityRoomSettingsTab from "../../../../../../../src/components/views/settings/tabs/room/SecurityRoomSettingsTab";
import MatrixClientContext from "../../../../../../../src/contexts/MatrixClientContext";
@@ -123,6 +124,88 @@ describe("<SecurityRoomSettingsTab />", () => {
);
});
it("handles changing room to private with world_readable history visiblity", async () => {
const room = new Room(roomId, client, userId);
setRoomStateEvents(room, JoinRule.Public, undefined, HistoryVisibility.WorldReadable);
getComponent(room);
fireEvent.click(screen.getByLabelText("Private (invite only)"));
await flushPromises();
expect(client.sendStateEvent).toHaveBeenCalledWith(
room.roomId,
EventType.RoomHistoryVisibility,
{
history_visibility: HistoryVisibility.Shared,
},
"",
);
expect(client.sendStateEvent).toHaveBeenCalledWith(
room.roomId,
EventType.RoomJoinRules,
{
join_rule: JoinRule.Invite,
},
"",
);
});
it("doesn't change room to private when user lacks permissions for history visibility", async () => {
const room = new Room(roomId, client, userId);
setRoomStateEvents(room, JoinRule.Public, undefined, HistoryVisibility.WorldReadable);
room.currentState.setStateEvents([
new MatrixEvent({
type: EventType.RoomPowerLevels,
content: {
users: { [userId]: 50 },
state_default: 50,
events: {
[EventType.RoomJoinRules]: 50,
[EventType.RoomHistoryVisibility]: 100,
},
} as RoomPowerLevelsEventContent,
sender: userId,
state_key: "",
room_id: room.roomId,
}),
]);
getComponent(room);
fireEvent.click(screen.getByLabelText("Private (invite only)"));
await flushPromises();
// Ensure we don't make any changes
expect(client.sendStateEvent).not.toHaveBeenCalled();
});
it("doesn't change room to private when history visibility change fails", async () => {
client.sendStateEvent.mockRejectedValue("Failed");
const room = new Room(roomId, client, userId);
setRoomStateEvents(room, JoinRule.Public, undefined, HistoryVisibility.WorldReadable);
getComponent(room);
fireEvent.click(screen.getByLabelText("Private (invite only)"));
await flushPromises();
expect(client.sendStateEvent).toHaveBeenCalledWith(
room.roomId,
EventType.RoomHistoryVisibility,
{
history_visibility: HistoryVisibility.Shared,
},
"",
);
// Ensure we don't make any changes
expect(client.sendStateEvent).not.toHaveBeenCalledWith(
room.roomId,
EventType.RoomJoinRules,
{
join_rule: JoinRule.Invite,
},
"",
);
});
it("handles error when updating join rule fails", async () => {
const room = new Room(roomId, client, userId);
client.sendStateEvent.mockRejectedValue("oups");

View File

@@ -15,7 +15,7 @@ exports[`<SecurityRoomSettingsTab /> history visibility uses shared as default h
<div
class="mx_SettingsSubsection_text"
>
Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.
The visibility of existing history will not be changed.
</div>
</div>
<div