Merge remote-tracking branch 'origin' into posthog-analytics

This commit is contained in:
James Salter 2021-07-28 11:13:22 +01:00
commit bd7e2dee3d
487 changed files with 11710 additions and 6874 deletions

View file

@ -48,7 +48,7 @@ const button4 = <Button key={4}>d</Button>;
describe("RovingTabIndex", () => {
it("RovingTabIndexProvider renders children as expected", () => {
const wrapper = mount(<RovingTabIndexProvider>
{() => <div><span>Test</span></div>}
{ () => <div><span>Test</span></div> }
</RovingTabIndexProvider>);
expect(wrapper.text()).toBe("Test");
expect(wrapper.html()).toBe('<div><span>Test</span></div>');
@ -56,11 +56,11 @@ describe("RovingTabIndex", () => {
it("RovingTabIndexProvider works as expected with useRovingTabIndex", () => {
const wrapper = mount(<RovingTabIndexProvider>
{() => <React.Fragment>
{ () => <React.Fragment>
{ button1 }
{ button2 }
{ button3 }
</React.Fragment>}
</React.Fragment> }
</RovingTabIndexProvider>);
// should begin with 0th being active
@ -98,15 +98,15 @@ describe("RovingTabIndex", () => {
it("RovingTabIndexProvider works as expected with RovingTabIndexWrapper", () => {
const wrapper = mount(<RovingTabIndexProvider>
{() => <React.Fragment>
{ () => <React.Fragment>
{ button1 }
{ button2 }
<RovingTabIndexWrapper>
{({ onFocus, isActive, ref }) =>
{ ({ onFocus, isActive, ref }) =>
<button onFocus={onFocus} tabIndex={isActive ? 0 : -1} ref={ref}>.</button>
}
</RovingTabIndexWrapper>
</React.Fragment>}
</React.Fragment> }
</RovingTabIndexProvider>);
// should begin with 0th being active

View file

@ -0,0 +1,140 @@
/*
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
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 { stubClient } from '../../test-utils';
import { MatrixClientPeg } from '../../../src/MatrixClientPeg';
import { MatrixClient } from 'matrix-js-sdk';
import { EventType } from "matrix-js-sdk/src/@types/event";
import CallEventGrouper, { CustomCallState } from "../../../src/components/structures/CallEventGrouper";
import { CallState } from "matrix-js-sdk/src/webrtc/call";
const MY_USER_ID = "@me:here";
const THEIR_USER_ID = "@they:here";
let client: MatrixClient;
describe('CallEventGrouper', () => {
beforeEach(() => {
stubClient();
client = MatrixClientPeg.get();
client.getUserId = () => {
return MY_USER_ID;
};
});
it("detects a missed call", () => {
const grouper = new CallEventGrouper();
grouper.add({
getContent: () => {
return {
call_id: "callId",
};
},
getType: () => {
return EventType.CallInvite;
},
sender: {
userId: THEIR_USER_ID,
},
});
expect(grouper.state).toBe(CustomCallState.Missed);
});
it("detects an ended call", () => {
const grouperHangup = new CallEventGrouper();
const grouperReject = new CallEventGrouper();
grouperHangup.add({
getContent: () => {
return {
call_id: "callId",
};
},
getType: () => {
return EventType.CallInvite;
},
sender: {
userId: MY_USER_ID,
},
});
grouperHangup.add({
getContent: () => {
return {
call_id: "callId",
};
},
getType: () => {
return EventType.CallHangup;
},
sender: {
userId: THEIR_USER_ID,
},
});
grouperReject.add({
getContent: () => {
return {
call_id: "callId",
};
},
getType: () => {
return EventType.CallInvite;
},
sender: {
userId: MY_USER_ID,
},
});
grouperReject.add({
getContent: () => {
return {
call_id: "callId",
};
},
getType: () => {
return EventType.CallReject;
},
sender: {
userId: THEIR_USER_ID,
},
});
expect(grouperHangup.state).toBe(CallState.Ended);
expect(grouperReject.state).toBe(CallState.Ended);
});
it("detects call type", () => {
const grouper = new CallEventGrouper();
grouper.add({
getContent: () => {
return {
call_id: "callId",
offer: {
sdp: "this is definitely an SDP m=video",
},
};
},
getType: () => {
return EventType.CallInvite;
},
});
expect(grouper.isVoice).toBe(false);
});
});

View file

@ -312,8 +312,12 @@ 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(
@ -330,8 +334,12 @@ describe('MessagePanel', function() {
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');
@ -348,8 +356,12 @@ 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');
@ -371,7 +383,10 @@ describe('MessagePanel', function() {
// first render with the RM in one place
let mp = ReactDOM.render(
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
<WrappedMessagePanel
className="cls"
events={events}
readMarkerEventId={events[4].getId()}
readMarkerVisible={true}
/>, parentDiv);
@ -387,7 +402,10 @@ describe('MessagePanel', function() {
// now move the RM
mp = ReactDOM.render(
<WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
<WrappedMessagePanel
className="cls"
events={events}
readMarkerEventId={events[6].getId()}
readMarkerVisible={true}
/>, parentDiv);

View file

@ -1,5 +1,5 @@
import './skinned-sdk'; // Must be first for skinning to work
import { _waitForMember, canEncryptToAllUsers } from '../src/createRoom';
import { waitForMember, canEncryptToAllUsers } from '../src/createRoom';
import { EventEmitter } from 'events';
/* Shorter timeout, we've got tests to run */
@ -13,7 +13,7 @@ describe("waitForMember", () => {
});
it("resolves with false if the timeout is reached", (done) => {
_waitForMember(client, "", "", { timeout: 0 }).then((r) => {
waitForMember(client, "", "", { timeout: 0 }).then((r) => {
expect(r).toBe(false);
done();
});
@ -22,7 +22,7 @@ describe("waitForMember", () => {
it("resolves with false if the timeout is reached, even if other RoomState.newMember events fire", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
_waitForMember(client, roomId, userId, { timeout }).then((r) => {
waitForMember(client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(false);
done();
});
@ -32,7 +32,7 @@ describe("waitForMember", () => {
it("resolves with true if RoomState.newMember fires", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
_waitForMember(client, roomId, userId, { timeout }).then((r) => {
waitForMember(client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(true);
expect(client.listeners("RoomState.newMember").length).toBe(0);
done();

View file

@ -25,7 +25,7 @@ module.exports = async function roomDirectoryScenarios(alice, bob) {
console.log(" creating a public room and join through directory:");
const room = 'test';
await createRoom(alice, room);
await changeRoomSettings(alice, { directory: true, visibility: "public_no_guests", alias: "#test" });
await changeRoomSettings(alice, { directory: true, visibility: "public", alias: "#test" });
await join(bob, room); //looks up room in directory
const bobMessage = "hi Alice!";
await sendMessage(bob, bobMessage);

View file

@ -51,7 +51,7 @@ const charlyMsg2 = "how's it going??";
async function setupRoomWithBobAliceAndCharlies(alice, bob, charlies) {
await createRoom(bob, room);
await changeRoomSettings(bob, { directory: true, visibility: "public_no_guests", alias });
await changeRoomSettings(bob, { directory: true, visibility: "public", alias });
// wait for alias to be set by server after clicking "save"
// so the charlies can join it.
await bob.delay(500);

View file

@ -98,18 +98,14 @@ async function checkRoomSettings(session, expectedSettings) {
if (expectedSettings.visibility) {
session.log.step(`checks visibility is ${expectedSettings.visibility}`);
const radios = await session.queryAll(".mx_RoomSettingsDialog input[type=radio]");
assert.equal(radios.length, 7);
const inviteOnly = radios[0];
const publicNoGuests = radios[1];
const publicWithGuests = radios[2];
assert.equal(radios.length, 6);
const [inviteOnlyRoom, publicRoom] = radios;
let expectedRadio = null;
if (expectedSettings.visibility === "invite_only") {
expectedRadio = inviteOnly;
} else if (expectedSettings.visibility === "public_no_guests") {
expectedRadio = publicNoGuests;
} else if (expectedSettings.visibility === "public_with_guests") {
expectedRadio = publicWithGuests;
expectedRadio = inviteOnlyRoom;
} else if (expectedSettings.visibility === "public") {
expectedRadio = publicRoom;
} else {
throw new Error(`unrecognized room visibility setting: ${expectedSettings.visibility}`);
}
@ -165,17 +161,13 @@ async function changeRoomSettings(session, settings) {
if (settings.visibility) {
session.log.step(`sets visibility to ${settings.visibility}`);
const radios = await session.queryAll(".mx_RoomSettingsDialog label");
assert.equal(radios.length, 7);
const inviteOnly = radios[0];
const publicNoGuests = radios[1];
const publicWithGuests = radios[2];
assert.equal(radios.length, 6);
const [inviteOnlyRoom, publicRoom] = radios;
if (settings.visibility === "invite_only") {
await inviteOnly.click();
} else if (settings.visibility === "public_no_guests") {
await publicNoGuests.click();
} else if (settings.visibility === "public_with_guests") {
await publicWithGuests.click();
await inviteOnlyRoom.click();
} else if (settings.visibility === "public") {
await publicRoom.click();
} else {
throw new Error(`unrecognized room visibility setting: ${settings.visibility}`);
}

View file

@ -52,32 +52,6 @@ const emitPromise = (e: EventEmitter, k: string | symbol) => new Promise(r => e.
const testUserId = "@test:user";
let rooms = [];
const mkRoom = (roomId: string) => {
const room = mkStubRoom(roomId);
room.currentState.getStateEvents.mockImplementation(mockStateEventImplementation([]));
rooms.push(room);
return room;
};
const mkSpace = (spaceId: string, children: string[] = []) => {
const space = mkRoom(spaceId);
space.isSpaceRoom.mockReturnValue(true);
space.currentState.getStateEvents.mockImplementation(mockStateEventImplementation(children.map(roomId =>
mkEvent({
event: true,
type: EventType.SpaceChild,
room: spaceId,
user: testUserId,
skey: roomId,
content: { via: [] },
ts: Date.now(),
}),
)));
return space;
};
const getUserIdForRoomId = jest.fn();
// @ts-ignore
DMRoomMap.sharedInstance = { getUserIdForRoomId };
@ -107,6 +81,32 @@ describe("SpaceStore", () => {
const store = SpaceStore.instance;
const client = MatrixClientPeg.get();
let rooms = [];
const mkRoom = (roomId: string) => {
const room = mkStubRoom(roomId, roomId, client);
room.currentState.getStateEvents.mockImplementation(mockStateEventImplementation([]));
rooms.push(room);
return room;
};
const mkSpace = (spaceId: string, children: string[] = []) => {
const space = mkRoom(spaceId);
space.isSpaceRoom.mockReturnValue(true);
space.currentState.getStateEvents.mockImplementation(mockStateEventImplementation(children.map(roomId =>
mkEvent({
event: true,
type: EventType.SpaceChild,
room: spaceId,
user: testUserId,
skey: roomId,
content: { via: [] },
ts: Date.now(),
}),
)));
return space;
};
const viewRoom = roomId => defaultDispatcher.dispatch({ action: "view_room", room_id: roomId }, true);
const run = async () => {

View file

@ -97,6 +97,7 @@ export function createTestClient() {
},
decryptEventIfNeeded: () => Promise.resolve(),
isUserIgnored: jest.fn().mockReturnValue(false),
getCapabilities: jest.fn().mockResolvedValue({}),
};
}
@ -220,7 +221,7 @@ export function mkMessage(opts) {
return mkEvent(opts);
}
export function mkStubRoom(roomId = null, name) {
export function mkStubRoom(roomId = null, name, client) {
const stubTimeline = { getEvents: () => [] };
return {
roomId,
@ -235,6 +236,7 @@ export function mkStubRoom(roomId = null, name) {
}),
getMembersWithMembership: jest.fn().mockReturnValue([]),
getJoinedMembers: jest.fn().mockReturnValue([]),
getJoinedMemberCount: jest.fn().mockReturnValue(1),
getMembers: jest.fn().mockReturnValue([]),
getPendingEvents: () => [],
getLiveTimeline: () => stubTimeline,
@ -269,6 +271,8 @@ export function mkStubRoom(roomId = null, name) {
getCanonicalAlias: jest.fn(),
getAltAliases: jest.fn().mockReturnValue([]),
timeline: [],
getJoinRule: jest.fn().mockReturnValue("invite"),
client,
};
}