Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/fix/17529

 Conflicts:
	package.json
	yarn.lock
This commit is contained in:
Michael Telatynski 2021-06-15 13:59:54 +01:00
commit a52dd57eb2
156 changed files with 3529 additions and 2124 deletions

View file

@ -23,8 +23,9 @@ import dis from '../src/dispatcher/dispatcher';
import { CallEvent, CallState } from 'matrix-js-sdk/src/webrtc/call';
import DMRoomMap from '../src/utils/DMRoomMap';
import EventEmitter from 'events';
import { Action } from '../src/dispatcher/actions';
import SdkConfig from '../src/SdkConfig';
import { ActionPayload } from '../src/dispatcher/payloads';
import { Action } from '../src/dispatcher/actions';
const REAL_ROOM_ID = '$room1:example.org';
const MAPPED_ROOM_ID = '$room2:example.org';
@ -75,6 +76,18 @@ class FakeCall extends EventEmitter {
}
}
function untilDispatch(waitForAction: string): Promise<ActionPayload> {
let dispatchHandle;
return new Promise<ActionPayload>(resolve => {
dispatchHandle = dis.register(payload => {
if (payload.action === waitForAction) {
dis.unregister(dispatchHandle);
resolve(payload);
}
});
});
}
describe('CallHandler', () => {
let dmRoomMap;
let callHandler;
@ -94,6 +107,21 @@ describe('CallHandler', () => {
callHandler = new CallHandler();
callHandler.start();
const realRoom = mkStubDM(REAL_ROOM_ID, '@user1:example.org');
const mappedRoom = mkStubDM(MAPPED_ROOM_ID, '@user2:example.org');
const mappedRoom2 = mkStubDM(MAPPED_ROOM_ID_2, '@user3:example.org');
MatrixClientPeg.get().getRoom = roomId => {
switch (roomId) {
case REAL_ROOM_ID:
return realRoom;
case MAPPED_ROOM_ID:
return mappedRoom;
case MAPPED_ROOM_ID_2:
return mappedRoom2;
}
};
dmRoomMap = {
getUserIdForRoomId: roomId => {
if (roomId === REAL_ROOM_ID) {
@ -134,38 +162,34 @@ describe('CallHandler', () => {
SdkConfig.unset();
});
it('should look up the correct user and open the room when a phone number is dialled', async () => {
MatrixClientPeg.get().getThirdpartyUser = jest.fn().mockResolvedValue([{
userid: '@user2:example.org',
protocol: "im.vector.protocol.sip_native",
fields: {
is_native: true,
lookup_success: true,
},
}]);
dis.dispatch({
action: Action.DialNumber,
number: '01818118181',
}, true);
const viewRoomPayload = await untilDispatch('view_room');
expect(viewRoomPayload.room_id).toEqual(MAPPED_ROOM_ID);
});
it('should move calls between rooms when remote asserted identity changes', async () => {
const realRoom = mkStubDM(REAL_ROOM_ID, '@user1:example.org');
const mappedRoom = mkStubDM(MAPPED_ROOM_ID, '@user2:example.org');
const mappedRoom2 = mkStubDM(MAPPED_ROOM_ID_2, '@user3:example.org');
MatrixClientPeg.get().getRoom = roomId => {
switch (roomId) {
case REAL_ROOM_ID:
return realRoom;
case MAPPED_ROOM_ID:
return mappedRoom;
case MAPPED_ROOM_ID_2:
return mappedRoom2;
}
};
dis.dispatch({
action: 'place_call',
type: PlaceCallType.Voice,
room_id: REAL_ROOM_ID,
}, true);
let dispatchHandle;
// wait for the call to be set up
await new Promise<void>(resolve => {
dispatchHandle = dis.register(payload => {
if (payload.action === 'call_state') {
resolve();
}
});
});
dis.unregister(dispatchHandle);
await untilDispatch('call_state');
// should start off in the actual room ID it's in at the protocol level
expect(callHandler.getCallForRoom(REAL_ROOM_ID)).toBe(fakeCall);

View file

@ -15,7 +15,6 @@ limitations under the License.
*/
import { isKeyComboMatch, KeyCombo } from '../src/KeyBindingsManager';
const assert = require('assert');
function mockKeyEvent(key: string, modifiers?: {
ctrlKey?: boolean,
@ -28,7 +27,7 @@ function mockKeyEvent(key: string, modifiers?: {
ctrlKey: modifiers?.ctrlKey ?? false,
altKey: modifiers?.altKey ?? false,
shiftKey: modifiers?.shiftKey ?? false,
metaKey: modifiers?.metaKey ?? false
metaKey: modifiers?.metaKey ?? false,
} as KeyboardEvent;
}
@ -37,9 +36,8 @@ describe('KeyBindingsManager', () => {
const combo1: KeyCombo = {
key: 'k',
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k'), combo1, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n'), combo1, false), false);
expect(isKeyComboMatch(mockKeyEvent('k'), combo1, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n'), combo1, false)).toBe(false);
});
it('should match key + modifier key combo', () => {
@ -47,38 +45,38 @@ describe('KeyBindingsManager', () => {
key: 'k',
ctrlKey: true,
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true }), combo, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true }), combo, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k'), combo, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true }), combo, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true, metaKey: true }), combo, false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true }), combo, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true }), combo, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k'), combo, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true }), combo, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true, metaKey: true }), combo, false)).toBe(false);
const combo2: KeyCombo = {
key: 'k',
metaKey: true,
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { metaKey: true }), combo2, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { metaKey: true }), combo2, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k'), combo2, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { altKey: true, metaKey: true }), combo2, false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { metaKey: true }), combo2, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n', { metaKey: true }), combo2, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k'), combo2, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { altKey: true, metaKey: true }), combo2, false)).toBe(false);
const combo3: KeyCombo = {
key: 'k',
altKey: true,
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { altKey: true }), combo3, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { altKey: true }), combo3, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k'), combo3, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true }), combo3, false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { altKey: true }), combo3, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n', { altKey: true }), combo3, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k'), combo3, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true }), combo3, false)).toBe(false);
const combo4: KeyCombo = {
key: 'k',
shiftKey: true,
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true }), combo4, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { shiftKey: true }), combo4, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k'), combo4, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true, ctrlKey: true }), combo4, false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true }), combo4, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n', { shiftKey: true }), combo4, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k'), combo4, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { shiftKey: true, ctrlKey: true }), combo4, false)).toBe(false);
});
it('should match key + multiple modifiers key combo', () => {
@ -87,11 +85,11 @@ describe('KeyBindingsManager', () => {
ctrlKey: true,
altKey: true,
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, altKey: true }), combo, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true, altKey: true }), combo, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true }), combo, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true, shiftKey: true }), combo,
false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, altKey: true }), combo, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true, altKey: true }), combo, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true }), combo, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true, shiftKey: true }), combo,
false)).toBe(false);
const combo2: KeyCombo = {
key: 'k',
@ -99,13 +97,13 @@ describe('KeyBindingsManager', () => {
shiftKey: true,
altKey: true,
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, shiftKey: true, altKey: true }), combo2,
false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true, shiftKey: true, altKey: true }), combo2,
false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true }), combo2, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k',
{ ctrlKey: true, shiftKey: true, altKey: true, metaKey: true }), combo2, false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, shiftKey: true, altKey: true }), combo2,
false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true, shiftKey: true, altKey: true }), combo2,
false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, metaKey: true }), combo2, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k',
{ ctrlKey: true, shiftKey: true, altKey: true, metaKey: true }), combo2, false)).toBe(false);
const combo3: KeyCombo = {
key: 'k',
@ -114,12 +112,12 @@ describe('KeyBindingsManager', () => {
altKey: true,
metaKey: true,
};
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k',
{ ctrlKey: true, shiftKey: true, altKey: true, metaKey: true }), combo3, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n',
{ ctrlKey: true, shiftKey: true, altKey: true, metaKey: true }), combo3, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k',
{ ctrlKey: true, shiftKey: true, altKey: true }), combo3, false), false);
expect(isKeyComboMatch(mockKeyEvent('k',
{ ctrlKey: true, shiftKey: true, altKey: true, metaKey: true }), combo3, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('n',
{ ctrlKey: true, shiftKey: true, altKey: true, metaKey: true }), combo3, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('k',
{ ctrlKey: true, shiftKey: true, altKey: true }), combo3, false)).toBe(false);
});
it('should match ctrlOrMeta key combo', () => {
@ -128,13 +126,13 @@ describe('KeyBindingsManager', () => {
ctrlOrCmd: true,
};
// PC:
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true }), combo, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { metaKey: true }), combo, false), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true }), combo, false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true }), combo, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('k', { metaKey: true }), combo, false)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true }), combo, false)).toBe(false);
// MAC:
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { metaKey: true }), combo, true), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true }), combo, true), false);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true }), combo, true), false);
expect(isKeyComboMatch(mockKeyEvent('k', { metaKey: true }), combo, true)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true }), combo, true)).toBe(false);
expect(isKeyComboMatch(mockKeyEvent('n', { ctrlKey: true }), combo, true)).toBe(false);
});
it('should match advanced ctrlOrMeta key combo', () => {
@ -144,10 +142,10 @@ describe('KeyBindingsManager', () => {
altKey: true,
};
// PC:
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, altKey: true }), combo, false), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { metaKey: true, altKey: true }), combo, false), false);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, altKey: true }), combo, false)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('k', { metaKey: true, altKey: true }), combo, false)).toBe(false);
// MAC:
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { metaKey: true, altKey: true }), combo, true), true);
assert.strictEqual(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, altKey: true }), combo, true), false);
expect(isKeyComboMatch(mockKeyEvent('k', { metaKey: true, altKey: true }), combo, true)).toBe(true);
expect(isKeyComboMatch(mockKeyEvent('k', { ctrlKey: true, altKey: true }), combo, true)).toBe(false);
});
});

View file

@ -16,7 +16,7 @@ limitations under the License.
import '../skinned-sdk'; // Must be first for skinning to work
import React from "react";
import Adapter from "enzyme-adapter-react-16";
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
import { configure, mount } from "enzyme";
import {

View file

@ -32,7 +32,7 @@ import Matrix from 'matrix-js-sdk';
const test_utils = require('../../test-utils');
const mockclock = require('../../mock-clock');
import Adapter from "enzyme-adapter-react-16";
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
import { configure, mount } from "enzyme";
import MatrixClientContext from "../../../src/contexts/MatrixClientContext";
@ -51,8 +51,20 @@ class WrappedMessagePanel extends React.Component {
};
render() {
const roomContext = {
room,
roomId: room.roomId,
canReact: true,
canReply: true,
showReadReceipts: true,
showRedactions: false,
showJoinLeaves: false,
showAvatarChanges: false,
showDisplaynameChanges: true,
};
return <MatrixClientContext.Provider value={client}>
<RoomContext.Provider value={{ canReact: true, canReply: true, room, roomId: room.roomId }}>
<RoomContext.Provider value={roomContext}>
<MessagePanel room={room} {...this.props} resizeNotifier={this.state.resizeNotifier} />
</RoomContext.Provider>
</MatrixClientContext.Provider>;
@ -77,7 +89,7 @@ describe('MessagePanel', function() {
DMRoomMap.makeShared();
});
afterEach(function () {
afterEach(function() {
clock.uninstall();
});
@ -270,7 +282,7 @@ describe('MessagePanel', function() {
it('should show the events', function() {
const res = TestUtils.renderIntoDocument(
<WrappedMessagePanel className="cls" events={events} />,
<WrappedMessagePanel className="cls" events={events} />,
);
// just check we have the right number of tiles for now
@ -298,8 +310,8 @@ describe('MessagePanel', function() {
it('should insert the read-marker in the right place', function() {
const res = TestUtils.renderIntoDocument(
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
readMarkerVisible={true} />,
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
readMarkerVisible={true} />,
);
const tiles = TestUtils.scryRenderedComponentsWithType(
@ -309,15 +321,15 @@ describe('MessagePanel', function() {
const rm = TestUtils.findRenderedDOMComponentWithClass(res, 'mx_RoomView_myReadMarker_container');
// it should follow the <li> which wraps the event tile for event 4
const eventContainer = ReactDOM.findDOMNode(tiles[4]).parentNode;
const eventContainer = ReactDOM.findDOMNode(tiles[4]);
expect(rm.previousSibling).toEqual(eventContainer);
});
it('should show the read-marker that fall in summarised events after the summary', function() {
const melsEvents = mkMelsEvents();
const res = TestUtils.renderIntoDocument(
<WrappedMessagePanel className="cls" events={melsEvents} readMarkerEventId={melsEvents[4].getId()}
readMarkerVisible={true} />,
<WrappedMessagePanel className="cls" events={melsEvents} readMarkerEventId={melsEvents[4].getId()}
readMarkerVisible={true} />,
);
const summary = TestUtils.findRenderedDOMComponentWithClass(res, 'mx_EventListSummary');
@ -334,8 +346,8 @@ describe('MessagePanel', function() {
it('should hide the read-marker at the end of summarised events', function() {
const melsEvents = mkMelsEventsOnly();
const res = TestUtils.renderIntoDocument(
<WrappedMessagePanel className="cls" events={melsEvents} readMarkerEventId={melsEvents[9].getId()}
readMarkerVisible={true} />,
<WrappedMessagePanel className="cls" events={melsEvents} readMarkerEventId={melsEvents[9].getId()}
readMarkerVisible={true} />,
);
const summary = TestUtils.findRenderedDOMComponentWithClass(res, 'mx_EventListSummary');
@ -358,14 +370,14 @@ describe('MessagePanel', function() {
// first render with the RM in one place
let mp = ReactDOM.render(
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
readMarkerVisible={true}
/>, parentDiv);
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
readMarkerVisible={true}
/>, parentDiv);
const tiles = TestUtils.scryRenderedComponentsWithType(
mp, sdk.getComponent('rooms.EventTile'));
const tileContainers = tiles.map(function(t) {
return ReactDOM.findDOMNode(t).parentNode;
return ReactDOM.findDOMNode(t);
});
// find the <li> which wraps the read marker
@ -374,9 +386,9 @@ describe('MessagePanel', function() {
// now move the RM
mp = ReactDOM.render(
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
readMarkerVisible={true}
/>, parentDiv);
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
readMarkerVisible={true}
/>, parentDiv);
// now there should be two RM containers
const found = TestUtils.scryRenderedDOMComponentsWithClass(mp, 'mx_RoomView_myReadMarker_container');
@ -451,7 +463,7 @@ describe('MessagePanel', function() {
expect(isReadMarkerVisible(rm)).toBeFalsy();
});
it('should render Date separators for the events', function () {
it('should render Date separators for the events', function() {
const events = mkOneDayEvents();
const res = mount(
<WrappedMessagePanel
@ -460,7 +472,7 @@ describe('MessagePanel', function() {
/>,
);
const Dates = res.find(sdk.getComponent('messages.DateSeparator'));
expect(Dates.length).toEqual(1);
});
});

View file

@ -0,0 +1,163 @@
/*
Copyright 2021 Robin Townsend <robin@robin.town>
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 "../../../skinned-sdk";
import React from "react";
import {configure, mount} from "enzyme";
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
import {act} from "react-dom/test-utils";
import * as TestUtils from "../../../test-utils";
import {MatrixClientPeg} from "../../../../src/MatrixClientPeg";
import DMRoomMap from "../../../../src/utils/DMRoomMap";
import {RoomPermalinkCreator} from "../../../../src/utils/permalinks/Permalinks";
import ForwardDialog from "../../../../src/components/views/dialogs/ForwardDialog";
configure({ adapter: new Adapter() });
describe("ForwardDialog", () => {
const sourceRoom = "!111111111111111111:example.org";
const defaultMessage = TestUtils.mkMessage({
room: sourceRoom,
user: "@alice:example.org",
msg: "Hello world!",
event: true,
});
const defaultRooms = ["a", "A", "b"].map(name => TestUtils.mkStubRoom(name, name));
const mountForwardDialog = async (message = defaultMessage, rooms = defaultRooms) => {
const client = MatrixClientPeg.get();
client.getVisibleRooms = jest.fn().mockReturnValue(rooms);
let wrapper;
await act(async () => {
wrapper = mount(
<ForwardDialog
matrixClient={client}
event={message}
permalinkCreator={new RoomPermalinkCreator(undefined, sourceRoom)}
onFinished={jest.fn()}
/>,
);
// Wait one tick for our profile data to load so the state update happens within act
await new Promise(resolve => setImmediate(resolve));
});
return wrapper;
};
beforeEach(() => {
TestUtils.stubClient();
DMRoomMap.makeShared();
MatrixClientPeg.get().getUserId = jest.fn().mockReturnValue("@bob:example.org");
});
it("shows a preview with us as the sender", async () => {
const wrapper = await mountForwardDialog();
const previewBody = wrapper.find(".mx_EventTile_body");
expect(previewBody.text()).toBe("Hello world!");
// We would just test SenderProfile for the user ID, but it's stubbed
const previewAvatar = wrapper.find(".mx_EventTile_avatar .mx_BaseAvatar_image");
expect(previewAvatar.prop("title")).toBe("@bob:example.org");
});
it("filters the rooms", async () => {
const wrapper = await mountForwardDialog();
expect(wrapper.find("Entry")).toHaveLength(3);
const searchInput = wrapper.find("SearchBox input");
searchInput.instance().value = "a";
searchInput.simulate("change");
expect(wrapper.find("Entry")).toHaveLength(2);
});
it("tracks message sending progress across multiple rooms", async () => {
const wrapper = await mountForwardDialog();
// Make sendEvent require manual resolution so we can see the sending state
let finishSend;
let cancelSend;
MatrixClientPeg.get().sendEvent = jest.fn(() => new Promise((resolve, reject) => {
finishSend = resolve;
cancelSend = reject;
}));
const firstButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").first();
expect(firstButton.render().is(".mx_ForwardList_canSend")).toBe(true);
act(() => { firstButton.simulate("click"); });
expect(firstButton.render().is(".mx_ForwardList_sending")).toBe(true);
await act(async () => {
cancelSend();
// Wait one tick for the button to realize the send failed
await new Promise(resolve => setImmediate(resolve));
});
expect(firstButton.render().is(".mx_ForwardList_sendFailed")).toBe(true);
const secondButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").at(1);
expect(secondButton.render().is(".mx_ForwardList_canSend")).toBe(true);
act(() => { secondButton.simulate("click"); });
expect(secondButton.render().is(".mx_ForwardList_sending")).toBe(true);
await act(async () => {
finishSend();
// Wait one tick for the button to realize the send succeeded
await new Promise(resolve => setImmediate(resolve));
});
expect(secondButton.render().is(".mx_ForwardList_sent")).toBe(true);
});
it("can render replies", async () => {
const replyMessage = TestUtils.mkEvent({
type: "m.room.message",
room: "!111111111111111111:example.org",
user: "@alice:example.org",
content: {
"msgtype": "m.text",
"body": "> <@bob:example.org> Hi Alice!\n\nHi Bob!",
"m.relates_to": {
"m.in_reply_to": {
event_id: "$2222222222222222222222222222222222222222222",
},
},
},
event: true,
});
const wrapper = await mountForwardDialog(replyMessage);
expect(wrapper.find("ReplyThread")).toBeTruthy();
});
it("disables buttons for rooms without send permissions", async () => {
const readOnlyRoom = TestUtils.mkStubRoom("a", "a");
readOnlyRoom.maySendMessage = jest.fn().mockReturnValue(false);
const rooms = [readOnlyRoom, TestUtils.mkStubRoom("b", "b")];
const wrapper = await mountForwardDialog(undefined, rooms);
const firstButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").first();
expect(firstButton.prop("disabled")).toBe(true);
const secondButton = wrapper.find("AccessibleButton.mx_ForwardList_sendButton").last();
expect(secondButton.prop("disabled")).toBe(false);
});
});

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import React from "react";
import Adapter from "enzyme-adapter-react-16";
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
import { configure, mount } from "enzyme";
import sdk from "../../../skinned-sdk";

View file

@ -9,6 +9,8 @@ import sdk from '../../../skinned-sdk';
import {Room, RoomMember, User} from 'matrix-js-sdk';
import { compare } from "../../../../src/utils/strings";
function generateRoomId() {
return '!' + Math.random().toString().slice(2, 10) + ':domain';
}
@ -173,7 +175,7 @@ describe('MemberList', () => {
if (!groupChange) {
const nameA = memberA.name[0] === '@' ? memberA.name.substr(1) : memberA.name;
const nameB = memberB.name[0] === '@' ? memberB.name.substr(1) : memberB.name;
const nameCompare = nameB.localeCompare(nameA);
const nameCompare = compare(nameB, nameA);
console.log("Comparing name");
expect(nameCompare).toBeGreaterThanOrEqual(0);
} else {

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import '../../../skinned-sdk'; // Must be first for skinning to work
import Adapter from "enzyme-adapter-react-16";
import Adapter from "@wojtekmaj/enzyme-adapter-react-17";
import { configure, mount } from "enzyme";
import React from "react";
import {act} from "react-dom/test-utils";

View file

@ -122,7 +122,7 @@ function getAllEventTiles(session) {
}
async function getMessageFromEventTile(eventTile) {
const senderElement = await eventTile.$(".mx_SenderProfile_name");
const senderElement = await eventTile.$(".mx_SenderProfile_displayName");
const className = await (await eventTile.getProperty("className")).jsonValue();
const classNames = className.split(" ");
const bodyElement = await eventTile.$(".mx_EventTile_body");

View file

@ -760,9 +760,9 @@ wrappy@1:
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
ws@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb"
integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==
version "6.2.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e"
integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==
dependencies:
async-limiter "~1.0.0"

View file

@ -1,6 +1,12 @@
import * as languageHandler from "../src/languageHandler";
import { TextEncoder, TextDecoder } from 'util';
languageHandler.setLanguage('en');
languageHandler.setMissingEntryGenerator(key => key.split("|", 2)[1]);
require('jest-fetch-mock').enableMocks();
// polyfilling TextEncoder as it is not available on JSDOM
// view https://github.com/facebook/jest/issues/9983
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;

View file

@ -21,7 +21,7 @@ import "../skinned-sdk"; // Must be first for skinning to work
import SpaceStore, {
UPDATE_INVITED_SPACES,
UPDATE_SELECTED_SPACE,
UPDATE_TOP_LEVEL_SPACES
UPDATE_TOP_LEVEL_SPACES,
} from "../../src/stores/SpaceStore";
import { resetAsyncStoreWithClient, setupAsyncStoreWithClient } from "../utils/test-utils";
import { mkEvent, mkStubRoom, stubClient } from "../test-utils";

View file

@ -90,7 +90,7 @@ export function createTestClient() {
}),
// Used by various internal bits we aren't concerned with (yet)
_sessionStore: {
sessionStore: {
store: {
getItem: jest.fn(),
},
@ -219,7 +219,7 @@ export function mkMessage(opts) {
return mkEvent(opts);
}
export function mkStubRoom(roomId = null) {
export function mkStubRoom(roomId = null, name) {
const stubTimeline = { getEvents: () => [] };
return {
roomId,
@ -238,6 +238,7 @@ export function mkStubRoom(roomId = null) {
getPendingEvents: () => [],
getLiveTimeline: () => stubTimeline,
getUnfilteredTimelineSet: () => null,
findEventById: () => null,
getAccountData: () => null,
hasMembershipState: () => null,
getVersion: () => '1',
@ -255,13 +256,17 @@ export function mkStubRoom(roomId = null) {
tags: {},
setBlacklistUnverifiedDevices: jest.fn(),
on: jest.fn(),
off: jest.fn(),
removeListener: jest.fn(),
getDMInviter: jest.fn(),
name,
getAvatarUrl: () => 'mxc://avatar.url/room.png',
getMxcAvatarUrl: () => 'mxc://avatar.url/room.png',
isSpaceRoom: jest.fn(() => false),
getUnreadNotificationCount: jest.fn(() => 0),
getEventReadUpTo: jest.fn(() => null),
getCanonicalAlias: jest.fn(),
getAltAliases: jest.fn().mockReturnValue([]),
timeline: [],
};
}

View file

@ -34,7 +34,7 @@ function mockRoom(roomId, members, serverACL) {
return {
roomId,
getCanonicalAlias: () => roomId,
getCanonicalAlias: () => null,
getJoinedMembers: () => members,
getMember: (userId) => members.find(m => m.userId === userId),
currentState: {