mirror of
https://github.com/element-hq/element-web
synced 2024-11-26 03:05:51 +03:00
Store refactor: convert WidgetPermissionStore (#9458)
* Store refactor: convert WidgetPermissionStore Add Jest tests as well. * More tests * Review comments
This commit is contained in:
parent
7d0af1dca4
commit
17c3fb89c1
6 changed files with 129 additions and 17 deletions
|
@ -21,10 +21,11 @@ import { logger } from "matrix-js-sdk/src/logger";
|
|||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import LabelledToggleSwitch from "../elements/LabelledToggleSwitch";
|
||||
import { OIDCState, WidgetPermissionStore } from "../../../stores/widgets/WidgetPermissionStore";
|
||||
import { OIDCState } from "../../../stores/widgets/WidgetPermissionStore";
|
||||
import { IDialogProps } from "./IDialogProps";
|
||||
import BaseDialog from "./BaseDialog";
|
||||
import DialogButtons from "../elements/DialogButtons";
|
||||
import { SdkContextClass } from '../../../contexts/SDKContext';
|
||||
|
||||
interface IProps extends IDialogProps {
|
||||
widget: Widget;
|
||||
|
@ -57,7 +58,7 @@ export default class WidgetOpenIDPermissionsDialog extends React.PureComponent<I
|
|||
if (this.state.rememberSelection) {
|
||||
logger.log(`Remembering ${this.props.widget.id} as allowed=${allowed} for OpenID`);
|
||||
|
||||
WidgetPermissionStore.instance.setOIDCState(
|
||||
SdkContextClass.instance.widgetPermissionStore.setOIDCState(
|
||||
this.props.widget, this.props.widgetKind, this.props.inRoomId,
|
||||
allowed ? OIDCState.Allowed : OIDCState.Denied,
|
||||
);
|
||||
|
|
|
@ -27,6 +27,7 @@ import { RoomViewStore } from "../stores/RoomViewStore";
|
|||
import SpaceStore, { SpaceStoreClass } from "../stores/spaces/SpaceStore";
|
||||
import TypingStore from "../stores/TypingStore";
|
||||
import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore";
|
||||
import { WidgetPermissionStore } from "../stores/widgets/WidgetPermissionStore";
|
||||
import WidgetStore from "../stores/WidgetStore";
|
||||
|
||||
export const SDKContext = createContext<SdkContextClass>(undefined);
|
||||
|
@ -51,6 +52,7 @@ export class SdkContextClass {
|
|||
public client?: MatrixClient;
|
||||
|
||||
// All protected fields to make it easier to derive test stores
|
||||
protected _WidgetPermissionStore?: WidgetPermissionStore;
|
||||
protected _RightPanelStore?: RightPanelStore;
|
||||
protected _RoomNotificationStateStore?: RoomNotificationStateStore;
|
||||
protected _RoomViewStore?: RoomViewStore;
|
||||
|
@ -102,6 +104,12 @@ export class SdkContextClass {
|
|||
}
|
||||
return this._WidgetLayoutStore;
|
||||
}
|
||||
public get widgetPermissionStore(): WidgetPermissionStore {
|
||||
if (!this._WidgetPermissionStore) {
|
||||
this._WidgetPermissionStore = new WidgetPermissionStore(this);
|
||||
}
|
||||
return this._WidgetPermissionStore;
|
||||
}
|
||||
public get widgetStore(): WidgetStore {
|
||||
if (!this._WidgetStore) {
|
||||
this._WidgetStore = WidgetStore.instance;
|
||||
|
|
|
@ -47,7 +47,7 @@ import Modal from "../../Modal";
|
|||
import WidgetOpenIDPermissionsDialog from "../../components/views/dialogs/WidgetOpenIDPermissionsDialog";
|
||||
import WidgetCapabilitiesPromptDialog from "../../components/views/dialogs/WidgetCapabilitiesPromptDialog";
|
||||
import { WidgetPermissionCustomisations } from "../../customisations/WidgetPermissions";
|
||||
import { OIDCState, WidgetPermissionStore } from "./WidgetPermissionStore";
|
||||
import { OIDCState } from "./WidgetPermissionStore";
|
||||
import { WidgetType } from "../../widgets/WidgetType";
|
||||
import { CHAT_EFFECTS } from "../../effects";
|
||||
import { containsEmoji } from "../../effects/utils";
|
||||
|
@ -350,7 +350,7 @@ export class StopGapWidgetDriver extends WidgetDriver {
|
|||
}
|
||||
|
||||
public async askOpenID(observer: SimpleObservable<IOpenIDUpdate>) {
|
||||
const oidcState = WidgetPermissionStore.instance.getOIDCState(
|
||||
const oidcState = SdkContextClass.instance.widgetPermissionStore.getOIDCState(
|
||||
this.forWidget, this.forWidgetKind, this.inRoomId,
|
||||
);
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
import { Widget, WidgetKind } from "matrix-widget-api";
|
||||
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||
import { SettingLevel } from "../../settings/SettingLevel";
|
||||
import { SdkContextClass } from "../../contexts/SDKContext";
|
||||
|
||||
export enum OIDCState {
|
||||
Allowed, // user has set the remembered value as allowed
|
||||
|
@ -27,16 +27,7 @@ export enum OIDCState {
|
|||
}
|
||||
|
||||
export class WidgetPermissionStore {
|
||||
private static internalInstance: WidgetPermissionStore;
|
||||
|
||||
private constructor() {
|
||||
}
|
||||
|
||||
public static get instance(): WidgetPermissionStore {
|
||||
if (!WidgetPermissionStore.internalInstance) {
|
||||
WidgetPermissionStore.internalInstance = new WidgetPermissionStore();
|
||||
}
|
||||
return WidgetPermissionStore.internalInstance;
|
||||
public constructor(private readonly context: SdkContextClass) {
|
||||
}
|
||||
|
||||
// TODO (all functions here): Merge widgetKind with the widget definition
|
||||
|
@ -44,7 +35,7 @@ export class WidgetPermissionStore {
|
|||
private packSettingKey(widget: Widget, kind: WidgetKind, roomId?: string): string {
|
||||
let location = roomId;
|
||||
if (kind !== WidgetKind.Room) {
|
||||
location = MatrixClientPeg.get().getUserId();
|
||||
location = this.context.client?.getUserId();
|
||||
}
|
||||
if (kind === WidgetKind.Modal) {
|
||||
location = '*MODAL*-' + location; // to guarantee differentiation from whatever spawned it
|
||||
|
@ -71,7 +62,10 @@ export class WidgetPermissionStore {
|
|||
public setOIDCState(widget: Widget, kind: WidgetKind, roomId: string, newState: OIDCState) {
|
||||
const settingsKey = this.packSettingKey(widget, kind, roomId);
|
||||
|
||||
const currentValues = SettingsStore.getValue("widgetOpenIDPermissions");
|
||||
let currentValues = SettingsStore.getValue("widgetOpenIDPermissions");
|
||||
if (!currentValues) {
|
||||
currentValues = {};
|
||||
}
|
||||
if (!currentValues.allow) currentValues.allow = [];
|
||||
if (!currentValues.deny) currentValues.deny = [];
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import RightPanelStore from "../src/stores/right-panel/RightPanelStore";
|
|||
import { RoomViewStore } from "../src/stores/RoomViewStore";
|
||||
import { SpaceStoreClass } from "../src/stores/spaces/SpaceStore";
|
||||
import { WidgetLayoutStore } from "../src/stores/widgets/WidgetLayoutStore";
|
||||
import { WidgetPermissionStore } from "../src/stores/widgets/WidgetPermissionStore";
|
||||
import WidgetStore from "../src/stores/WidgetStore";
|
||||
|
||||
/**
|
||||
|
@ -32,6 +33,7 @@ export class TestSdkContext extends SdkContextClass {
|
|||
public _RightPanelStore?: RightPanelStore;
|
||||
public _RoomNotificationStateStore?: RoomNotificationStateStore;
|
||||
public _RoomViewStore?: RoomViewStore;
|
||||
public _WidgetPermissionStore?: WidgetPermissionStore;
|
||||
public _WidgetLayoutStore?: WidgetLayoutStore;
|
||||
public _WidgetStore?: WidgetStore;
|
||||
public _PosthogAnalytics?: PosthogAnalytics;
|
||||
|
|
107
test/stores/widgets/WidgetPermissionStore-test.ts
Normal file
107
test/stores/widgets/WidgetPermissionStore-test.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { mocked } from "jest-mock";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { Widget, WidgetKind } from "matrix-widget-api";
|
||||
|
||||
import { OIDCState, WidgetPermissionStore } from "../../../src/stores/widgets/WidgetPermissionStore";
|
||||
import SettingsStore from "../../../src/settings/SettingsStore";
|
||||
import { TestSdkContext } from "../../TestSdkContext";
|
||||
import { SettingLevel } from "../../../src/settings/SettingLevel";
|
||||
import { SdkContextClass } from "../../../src/contexts/SDKContext";
|
||||
import { stubClient } from "../../test-utils";
|
||||
|
||||
jest.mock("../../../src/settings/SettingsStore");
|
||||
|
||||
describe("WidgetPermissionStore", () => {
|
||||
let widgetPermissionStore: WidgetPermissionStore;
|
||||
let mockClient: MatrixClient;
|
||||
const userId = "@alice:localhost";
|
||||
const roomId = "!room:localhost";
|
||||
const w = new Widget({
|
||||
id: "wid",
|
||||
creatorUserId: userId,
|
||||
type: "m.custom",
|
||||
url: "https://invalid.address.here",
|
||||
});
|
||||
let settings = {}; // key value store
|
||||
|
||||
beforeEach(() => {
|
||||
settings = {}; // clear settings
|
||||
mocked(SettingsStore.getValue).mockImplementation((setting: string) => {
|
||||
return settings[setting];
|
||||
});
|
||||
mocked(SettingsStore.setValue).mockImplementation((settingName: string,
|
||||
roomId: string | null,
|
||||
level: SettingLevel,
|
||||
value: any,
|
||||
): Promise<void> => {
|
||||
// the store doesn't use any specific level or room ID (room IDs are packed into keys in `value`)
|
||||
settings[settingName] = value;
|
||||
return Promise.resolve();
|
||||
});
|
||||
mockClient = stubClient();
|
||||
const context = new TestSdkContext();
|
||||
context.client = mockClient;
|
||||
widgetPermissionStore = new WidgetPermissionStore(context);
|
||||
});
|
||||
|
||||
it("should persist OIDCState.Allowed for a widget", () => {
|
||||
widgetPermissionStore.setOIDCState(w, WidgetKind.Account, null, OIDCState.Allowed);
|
||||
// check it remembered the value
|
||||
expect(
|
||||
widgetPermissionStore.getOIDCState(w, WidgetKind.Account, null),
|
||||
).toEqual(OIDCState.Allowed);
|
||||
});
|
||||
|
||||
it("should persist OIDCState.Denied for a widget", () => {
|
||||
widgetPermissionStore.setOIDCState(w, WidgetKind.Account, null, OIDCState.Denied);
|
||||
// check it remembered the value
|
||||
expect(
|
||||
widgetPermissionStore.getOIDCState(w, WidgetKind.Account, null),
|
||||
).toEqual(OIDCState.Denied);
|
||||
});
|
||||
|
||||
it("should update OIDCState for a widget", () => {
|
||||
widgetPermissionStore.setOIDCState(w, WidgetKind.Account, null, OIDCState.Allowed);
|
||||
widgetPermissionStore.setOIDCState(w, WidgetKind.Account, null, OIDCState.Denied);
|
||||
// check it remembered the latest value
|
||||
expect(
|
||||
widgetPermissionStore.getOIDCState(w, WidgetKind.Account, null),
|
||||
).toEqual(OIDCState.Denied);
|
||||
});
|
||||
|
||||
it("should scope the location for a widget when setting OIDC state", () => {
|
||||
// allow this widget for this room
|
||||
widgetPermissionStore.setOIDCState(w, WidgetKind.Room, roomId, OIDCState.Allowed);
|
||||
// check it remembered the value
|
||||
expect(
|
||||
widgetPermissionStore.getOIDCState(w, WidgetKind.Room, roomId),
|
||||
).toEqual(OIDCState.Allowed);
|
||||
// check this is not the case for the entire account
|
||||
expect(
|
||||
widgetPermissionStore.getOIDCState(w, WidgetKind.Account, roomId),
|
||||
).toEqual(OIDCState.Unknown);
|
||||
});
|
||||
it("is created once in SdkContextClass", () => {
|
||||
const context = new SdkContextClass();
|
||||
const store = context.widgetPermissionStore;
|
||||
expect(store).toBeDefined();
|
||||
const store2 = context.widgetPermissionStore;
|
||||
expect(store2).toStrictEqual(store);
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue