Call Guest Access, give user the option to change the acces level so they can generate a call link. (#12401)
* Ask the user to change the room access settings if they click the create link button. Signed-off-by: Timo K <toger5@hotmail.de> * disable call button if appropriate. Signed-off-by: Timo K <toger5@hotmail.de> * Add tests Refactor tests to be in CallGuestLinkButton-test instead of the RoomHeader Signed-off-by: Timo K <toger5@hotmail.de> * add test for: no button if cannot change join rule and room not public nor knock Signed-off-by: Timo K <toger5@hotmail.de> * fix tests Signed-off-by: Timo K <toger5@hotmail.de> * add JoinRuleDialog tests Signed-off-by: Timo K <toger5@hotmail.de> * move spy into before each Signed-off-by: Timo K <toger5@hotmail.de> * Update src/i18n/strings/en_EN.json Co-authored-by: Robin <robin@robin.town> * remove inline css and update modal style Signed-off-by: Timo K <toger5@hotmail.de> * Update src/i18n/strings/en_EN.json Co-authored-by: Robin <robin@robin.town> * Update src/i18n/strings/en_EN.json Co-authored-by: Robin <robin@robin.town> * Invite state was not reactive. Changing power level did not update the ui. Signed-off-by: Timo K <toger5@hotmail.de> * linter Signed-off-by: Timo K <toger5@hotmail.de> * make useGuestAccessInformation use useRoomState Signed-off-by: Timo K <toger5@hotmail.de> * fix tests and simplify logic * fix tests * review Signed-off-by: Timo K <toger5@hotmail.de> --------- Signed-off-by: Timo K <toger5@hotmail.de> Co-authored-by: Robin <robin@robin.town>
This commit is contained in:
parent
59395abb6b
commit
d35fce198c
11 changed files with 588 additions and 175 deletions
|
@ -61,8 +61,7 @@ import { _t } from "../../../../src/languageHandler";
|
|||
import * as UseCall from "../../../../src/hooks/useCall";
|
||||
import { SdkContextClass } from "../../../../src/contexts/SDKContext";
|
||||
import WidgetStore, { IApp } from "../../../../src/stores/WidgetStore";
|
||||
import ShareDialog from "../../../../src/components/views/dialogs/ShareDialog";
|
||||
import Modal from "../../../../src/Modal";
|
||||
|
||||
jest.mock("../../../../src/utils/ShieldUtils");
|
||||
|
||||
function getWrapper(): RenderOptions {
|
||||
|
@ -382,10 +381,32 @@ describe("RoomHeader", () => {
|
|||
it("can call if you have no friends but can invite friends", () => {
|
||||
mockRoomMembers(room, 1);
|
||||
// go through all the different `canInvite` and `getJoinRule` combinations
|
||||
|
||||
// check where we can't do anything but can upgrade
|
||||
jest.spyOn(room.currentState, "maySendStateEvent").mockReturnValue(true);
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Invite);
|
||||
jest.spyOn(room, "canInvite").mockReturnValue(false);
|
||||
const guestSpaUrlMock = jest.spyOn(SdkConfig, "get").mockImplementation((key) => {
|
||||
return { guest_spa_url: "https://guest_spa_url.com", url: "https://spa_url.com" };
|
||||
});
|
||||
const { container: containerNoInviteNotPublicCanUpgradeAccess } = render(
|
||||
<RoomHeader room={room} />,
|
||||
getWrapper(),
|
||||
);
|
||||
expect(
|
||||
queryAllByLabelText(containerNoInviteNotPublicCanUpgradeAccess, "There's no one here to call"),
|
||||
).toHaveLength(0);
|
||||
|
||||
// dont allow upgrading anymore and go through the other combinations
|
||||
jest.spyOn(room.currentState, "maySendStateEvent").mockReturnValue(false);
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Invite);
|
||||
jest.spyOn(room, "canInvite").mockReturnValue(false);
|
||||
jest.spyOn(SdkConfig, "get").mockImplementation((key) => {
|
||||
return { guest_spa_url: "https://guest_spa_url.com", url: "https://spa_url.com" };
|
||||
});
|
||||
const { container: containerNoInviteNotPublic } = render(<RoomHeader room={room} />, getWrapper());
|
||||
expect(queryAllByLabelText(containerNoInviteNotPublic, "There's no one here to call")).toHaveLength(2);
|
||||
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Knock);
|
||||
jest.spyOn(room, "canInvite").mockReturnValue(false);
|
||||
const { container: containerNoInvitePublic } = render(<RoomHeader room={room} />, getWrapper());
|
||||
|
@ -400,6 +421,13 @@ describe("RoomHeader", () => {
|
|||
jest.spyOn(room, "canInvite").mockReturnValue(true);
|
||||
const { container: containerInvitePublic } = render(<RoomHeader room={room} />, getWrapper());
|
||||
expect(queryAllByLabelText(containerInvitePublic, "There's no one here to call")).toHaveLength(0);
|
||||
|
||||
// last we can allow everything but without guest_spa_url nothing will work
|
||||
guestSpaUrlMock.mockRestore();
|
||||
const { container: containerAllAllowedButNoGuestSpaUrl } = render(<RoomHeader room={room} />, getWrapper());
|
||||
expect(
|
||||
queryAllByLabelText(containerAllAllowedButNoGuestSpaUrl, "There's no one here to call"),
|
||||
).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("calls using legacy or jitsi", async () => {
|
||||
|
@ -516,39 +544,12 @@ describe("RoomHeader", () => {
|
|||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
getByLabelText(container, "Close lobby");
|
||||
});
|
||||
});
|
||||
|
||||
describe("External conference", () => {
|
||||
const oldGet = SdkConfig.get;
|
||||
beforeEach(() => {
|
||||
jest.spyOn(SdkConfig, "get").mockImplementation((key) => {
|
||||
if (key === "element_call") {
|
||||
return { guest_spa_url: "https://guest_spa_url.com", url: "https://spa_url.com" };
|
||||
}
|
||||
return oldGet(key);
|
||||
});
|
||||
mockRoomMembers(room, 3);
|
||||
jest.spyOn(SdkContextClass.instance.roomViewStore, "isViewingCall").mockReturnValue(true);
|
||||
});
|
||||
|
||||
it("shows the external conference if the room has public join rules", () => {
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Public);
|
||||
|
||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
expect(getByLabelText(container, _t("voip|get_call_link"))).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows the external conference if the room has Knock join rules", () => {
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Knock);
|
||||
|
||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
expect(getByLabelText(container, _t("voip|get_call_link"))).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("don't show external conference button if the call is not shown", () => {
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Public);
|
||||
jest.spyOn(SdkContextClass.instance.roomViewStore, "isViewingCall").mockReturnValue(false);
|
||||
|
||||
jest.spyOn(SdkConfig, "get").mockImplementation((key) => {
|
||||
return { guest_spa_url: "https://guest_spa_url.com", url: "https://spa_url.com" };
|
||||
});
|
||||
let { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
expect(screen.queryByLabelText(_t("voip|get_call_link"))).not.toBeInTheDocument();
|
||||
|
||||
|
@ -558,69 +559,6 @@ describe("RoomHeader", () => {
|
|||
|
||||
expect(getByLabelText(container, _t("voip|get_call_link"))).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("don't show external conference button if now guest spa link is configured", () => {
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Public);
|
||||
jest.spyOn(SdkContextClass.instance.roomViewStore, "isViewingCall").mockReturnValue(true);
|
||||
|
||||
jest.spyOn(SdkConfig, "get").mockImplementation((key) => {
|
||||
if (key === "element_call") {
|
||||
return { url: "https://example2.com" };
|
||||
}
|
||||
return oldGet(key);
|
||||
});
|
||||
|
||||
render(<RoomHeader room={room} />, getWrapper());
|
||||
|
||||
// We only change the SdkConfig and show that this everything else is
|
||||
// configured so that the call link button is shown.
|
||||
|
||||
jest.spyOn(SdkConfig, "get").mockImplementation((key) => {
|
||||
if (key === "element_call") {
|
||||
return { guest_spa_url: "https://guest_spa_url.com", url: "https://example2.com" };
|
||||
}
|
||||
return oldGet(key);
|
||||
});
|
||||
|
||||
expect(screen.queryByLabelText(_t("voip|get_call_link"))).not.toBeInTheDocument();
|
||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
expect(getByLabelText(container, _t("voip|get_call_link"))).toBeInTheDocument();
|
||||
});
|
||||
it("opens the share dialog with the correct share link in an encrypted room", () => {
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Public);
|
||||
jest.spyOn(SdkContextClass.instance.roomViewStore, "isViewingCall").mockReturnValue(true);
|
||||
jest.spyOn(room, "hasEncryptionStateEvent").mockReturnValue(true);
|
||||
|
||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
const modalSpy = jest.spyOn(Modal, "createDialog");
|
||||
fireEvent.click(getByLabelText(container, _t("voip|get_call_link")));
|
||||
const target =
|
||||
"https://guest_spa_url.com/room/#/!1:example.org?roomId=%211%3Aexample.org&perParticipantE2EE=true&viaServers=example.org";
|
||||
expect(modalSpy).toHaveBeenCalled();
|
||||
const arg0 = modalSpy.mock.calls[0][0];
|
||||
const arg1 = modalSpy.mock.calls[0][1] as any;
|
||||
expect(arg0).toEqual(ShareDialog);
|
||||
const { customTitle, subtitle } = arg1;
|
||||
expect({ customTitle, subtitle }).toEqual({
|
||||
customTitle: "Conference invite link",
|
||||
subtitle: _t("share|share_call_subtitle"),
|
||||
});
|
||||
expect(arg1.target.toString()).toEqual(target);
|
||||
});
|
||||
|
||||
it("share dialog has correct link in an unencrypted room", () => {
|
||||
jest.spyOn(room, "getJoinRule").mockReturnValue(JoinRule.Public);
|
||||
jest.spyOn(room, "hasEncryptionStateEvent").mockReturnValue(false);
|
||||
jest.spyOn(SdkContextClass.instance.roomViewStore, "isViewingCall").mockReturnValue(true);
|
||||
|
||||
const { container } = render(<RoomHeader room={room} />, getWrapper());
|
||||
const modalSpy = jest.spyOn(Modal, "createDialog");
|
||||
fireEvent.click(getByLabelText(container, _t("voip|get_call_link")));
|
||||
const target =
|
||||
"https://guest_spa_url.com/room/#/!1:example.org?roomId=%211%3Aexample.org&viaServers=example.org";
|
||||
const arg1 = modalSpy.mock.calls[0][1] as any;
|
||||
expect(arg1.target.toString()).toEqual(target);
|
||||
});
|
||||
});
|
||||
|
||||
describe("public room", () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue