You've already forked matrix-react-sdk
mirror of
https://github.com/matrix-org/matrix-react-sdk.git
synced 2025-08-07 21:23:00 +03:00
[CONFLICT CHUNKS] Merge branch 'develop' into travis/sourcemaps-develop
This commit is contained in:
@@ -36,27 +36,14 @@ const test_utils = require('test-utils');
|
||||
const mockclock = require('mock-clock');
|
||||
|
||||
import Velocity from 'velocity-animate';
|
||||
import MatrixClientContext from "../../../src/contexts/MatrixClientContext";
|
||||
import RoomContext from "../../../src/contexts/RoomContext";
|
||||
|
||||
let client;
|
||||
const room = new Matrix.Room();
|
||||
|
||||
// wrap MessagePanel with a component which provides the MatrixClient in the context.
|
||||
const WrappedMessagePanel = createReactClass({
|
||||
childContextTypes: {
|
||||
matrixClient: PropTypes.object,
|
||||
room: PropTypes.object,
|
||||
},
|
||||
|
||||
getChildContext: function() {
|
||||
return {
|
||||
matrixClient: client,
|
||||
room: {
|
||||
canReact: true,
|
||||
canReply: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return {
|
||||
resizeNotifier: new EventEmitter(),
|
||||
@@ -64,7 +51,11 @@ const WrappedMessagePanel = createReactClass({
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return <MessagePanel room={room} {...this.props} resizeNotifier={this.state.resizeNotifier} />;
|
||||
return <MatrixClientContext.Provider value={client}>
|
||||
<RoomContext.Provider value={{ canReact: true, canReply: true }}>
|
||||
<MessagePanel room={room} {...this.props} resizeNotifier={this.state.resizeNotifier} />
|
||||
</RoomContext.Provider>
|
||||
</MatrixClientContext.Provider>;
|
||||
},
|
||||
});
|
||||
|
||||
|
@@ -115,7 +115,8 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
const renderer = new ShallowRenderer();
|
||||
renderer.render(<MemberEventListSummary {...props} />);
|
||||
const result = renderer.getRenderOutput();
|
||||
const wrapper = renderer.getRenderOutput(); // matrix cli context wrapper
|
||||
const result = wrapper.props.children;
|
||||
|
||||
expect(result.props.children).toEqual([
|
||||
<div className="event_tile" key="event0">Expanded membership</div>,
|
||||
@@ -137,7 +138,8 @@ describe('MemberEventListSummary', function() {
|
||||
|
||||
const renderer = new ShallowRenderer();
|
||||
renderer.render(<MemberEventListSummary {...props} />);
|
||||
const result = renderer.getRenderOutput();
|
||||
const wrapper = renderer.getRenderOutput(); // matrix cli context wrapper
|
||||
const result = wrapper.props.children;
|
||||
|
||||
expect(result.props.children).toEqual([
|
||||
<div className="event_tile" key="event0">Expanded membership</div>,
|
||||
|
272
test/components/views/messages/TextualBody-test.js
Normal file
272
test/components/views/messages/TextualBody-test.js
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
Copyright 2019 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 React from "react";
|
||||
import expect from 'expect';
|
||||
import Adapter from "enzyme-adapter-react-16";
|
||||
import { configure, mount } from "enzyme";
|
||||
|
||||
import sdk from "../../../skinned-sdk";
|
||||
import {mkEvent, mkStubRoom} from "../../../test-utils";
|
||||
import MatrixClientPeg from "../../../../src/MatrixClientPeg";
|
||||
import * as languageHandler from "../../../../src/languageHandler";
|
||||
|
||||
const TextualBody = sdk.getComponent("views.messages.TextualBody");
|
||||
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
describe("<TextualBody />", () => {
|
||||
afterEach(() => {
|
||||
MatrixClientPeg.matrixClient = null;
|
||||
});
|
||||
|
||||
describe("renders m.emote correctly", () => {
|
||||
MatrixClientPeg.matrixClient = {
|
||||
getRoom: () => mkStubRoom("room_id"),
|
||||
getAccountData: () => undefined,
|
||||
};
|
||||
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body: "winks",
|
||||
msgtype: "m.emote",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe("* sender winks");
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe('<span class="mx_EventTile_body" dir="auto">winks</span>');
|
||||
});
|
||||
|
||||
describe("renders m.notice correctly", () => {
|
||||
MatrixClientPeg.matrixClient = {
|
||||
getRoom: () => mkStubRoom("room_id"),
|
||||
getAccountData: () => undefined,
|
||||
};
|
||||
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "bot_sender",
|
||||
content: {
|
||||
body: "this is a notice, probably from a bot",
|
||||
msgtype: "m.notice",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe(ev.getContent().body);
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe(`<span class="mx_EventTile_body" dir="auto">${ ev.getContent().body }</span>`);
|
||||
});
|
||||
|
||||
describe("renders plain-text m.text correctly", () => {
|
||||
MatrixClientPeg.matrixClient = {
|
||||
getRoom: () => mkStubRoom("room_id"),
|
||||
getAccountData: () => undefined,
|
||||
};
|
||||
|
||||
describe("simple message renders as expected", () => {
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body: "this is a plaintext message",
|
||||
msgtype: "m.text",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe(ev.getContent().body);
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe(`<span class="mx_EventTile_body" dir="auto">${ ev.getContent().body }</span>`);
|
||||
});
|
||||
|
||||
// If pills were rendered within a Portal/same shadow DOM then it'd be easier to test
|
||||
describe("linkification get applied correctly into the DOM", () => {
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body: "Visit https://matrix.org/",
|
||||
msgtype: "m.text",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe(ev.getContent().body);
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe('<span class="mx_EventTile_body" dir="auto">' +
|
||||
'Visit <a href="https://matrix.org/" class="linkified" target="_blank" rel="noopener">' +
|
||||
'https://matrix.org/</a></span>');
|
||||
});
|
||||
});
|
||||
|
||||
describe("renders formatted m.text correctly", () => {
|
||||
MatrixClientPeg.matrixClient = {
|
||||
getRoom: () => mkStubRoom("room_id"),
|
||||
getAccountData: () => undefined,
|
||||
getUserId: () => "@me:my_server",
|
||||
getHomeserverUrl: () => "https://my_server/",
|
||||
on: () => undefined,
|
||||
removeListener: () => undefined,
|
||||
};
|
||||
|
||||
describe("italics, bold, underline and strikethrough render as expected", () => {
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body: "foo *baz* __bar__ <del>del</del> <u>u</u>",
|
||||
msgtype: "m.text",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "foo <em>baz</em> <strong>bar</strong> <del>del</del> <u>u</u>",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe("foo baz bar del u");
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe('<span class="mx_EventTile_body markdown-body" dir="auto">' +
|
||||
ev.getContent().formatted_body + '</span>');
|
||||
});
|
||||
|
||||
describe("spoilers get injected properly into the DOM", () => {
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body: "Hey [Spoiler for movie](mxc://someserver/somefile)",
|
||||
msgtype: "m.text",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "Hey <span data-mx-spoiler=\"movie\">the movie was awesome</span>",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe("Hey (movie) the movie was awesome");
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe('<span class="mx_EventTile_body markdown-body" dir="auto">' +
|
||||
'Hey <span>' +
|
||||
'<span class="mx_EventTile_spoiler">' +
|
||||
'<span class="mx_EventTile_spoiler_reason">(movie)</span> ' +
|
||||
'<span class="mx_EventTile_spoiler_content"><span>the movie was awesome</span></span>' +
|
||||
'</span></span></span>');
|
||||
});
|
||||
|
||||
// If pills were rendered within a Portal/same shadow DOM then it'd be easier to test
|
||||
describe("pills get injected correctly into the DOM", () => {
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body: "Hey User",
|
||||
msgtype: "m.text",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "Hey <a href=\"https://matrix.to/#/@user:server\">Member</a>",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe("Hey Member");
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe('<span class="mx_EventTile_body markdown-body" dir="auto">' +
|
||||
'Hey <span>' +
|
||||
'<a class="mx_Pill mx_UserPill" title="@user:server">' +
|
||||
'<img class="mx_BaseAvatar mx_BaseAvatar_image" src="mxc://avatar.url/image.png" ' +
|
||||
'width="16" height="16" title="@member:domain.bla" alt="">Member</a>' +
|
||||
'</span></span>');
|
||||
});
|
||||
});
|
||||
|
||||
describe("renders url previews correctly", () => {
|
||||
languageHandler.setMissingEntryGenerator(key => key.split('|', 2)[1]);
|
||||
|
||||
MatrixClientPeg.matrixClient = {
|
||||
getRoom: () => mkStubRoom("room_id"),
|
||||
getAccountData: () => undefined,
|
||||
getUrlPreview: (url) => new Promise(() => {}),
|
||||
};
|
||||
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body: "Visit https://matrix.org/",
|
||||
msgtype: "m.text",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} showUrlPreview={true} />);
|
||||
expect(wrapper.text()).toBe(ev.getContent().body);
|
||||
|
||||
let widgets = wrapper.find("LinkPreviewWidget");
|
||||
// at this point we should have exactly one widget
|
||||
expect(widgets.length).toBe(1);
|
||||
expect(widgets.at(0).prop("link")).toBe("https://matrix.org/");
|
||||
|
||||
// simulate an event edit and check the transition from the old URL preview to the new one
|
||||
const ev2 = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
"m.new_content": {
|
||||
body: "Visit https://vector.im/ and https://riot.im/",
|
||||
msgtype: "m.text",
|
||||
},
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
ev.makeReplaced(ev2);
|
||||
|
||||
wrapper.setProps({
|
||||
mxEvent: ev,
|
||||
replacingEventId: ev.getId(),
|
||||
}, () => {
|
||||
expect(wrapper.text()).toBe(ev2.getContent()["m.new_content"].body + "(edited)");
|
||||
|
||||
// XXX: this is to give TextualBody enough time for state to settle
|
||||
wrapper.setState({}, () => {
|
||||
widgets = wrapper.find("LinkPreviewWidget");
|
||||
// at this point we should have exactly two widgets (not the matrix.org one anymore)
|
||||
expect(widgets.length).toBe(2);
|
||||
expect(widgets.at(0).prop("link")).toBe("https://vector.im/");
|
||||
expect(widgets.at(1).prop("link")).toBe("https://riot.im/");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -53,9 +53,10 @@ export default async function changeRoomSettings(session, settings) {
|
||||
if (settings.alias) {
|
||||
session.log.step(`sets alias to ${settings.alias}`);
|
||||
const aliasField = await session.query(".mx_RoomSettingsDialog .mx_AliasSettings input[type=text]");
|
||||
await session.replaceInputText(aliasField, settings.alias);
|
||||
await session.replaceInputText(aliasField, settings.alias.substring(1, settings.alias.lastIndexOf(":")));
|
||||
const addButton = await session.query(".mx_RoomSettingsDialog .mx_AliasSettings .mx_AccessibleButton");
|
||||
await addButton.click();
|
||||
await session.delay(10); // delay to give time for the validator to run and check the alias
|
||||
session.log.done();
|
||||
}
|
||||
|
||||
|
@@ -2,13 +2,13 @@
|
||||
|
||||
import sinon from 'sinon';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import peg from '../src/MatrixClientPeg';
|
||||
import dis from '../src/dispatcher';
|
||||
import jssdk from 'matrix-js-sdk';
|
||||
import {makeType} from "../src/utils/TypeUtils";
|
||||
import {ValidatedServerConfig} from "../src/utils/AutoDiscoveryUtils";
|
||||
import ShallowRenderer from 'react-test-renderer/shallow';
|
||||
import MatrixClientContext from "../src/contexts/MatrixClientContext";
|
||||
const MatrixEvent = jssdk.MatrixEvent;
|
||||
|
||||
/**
|
||||
@@ -238,6 +238,7 @@ export function mkStubRoom(roomId = null) {
|
||||
getMember: sinon.stub().returns({
|
||||
userId: '@member:domain.bla',
|
||||
name: 'Member',
|
||||
rawDisplayName: 'Member',
|
||||
roomId: roomId,
|
||||
getAvatarUrl: () => 'mxc://avatar.url/image.png',
|
||||
}),
|
||||
@@ -291,22 +292,16 @@ export function getDispatchForStore(store) {
|
||||
|
||||
export function wrapInMatrixClientContext(WrappedComponent) {
|
||||
class Wrapper extends React.Component {
|
||||
static childContextTypes = {
|
||||
matrixClient: PropTypes.object,
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
matrixClient: this._matrixClient,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this._matrixClient = peg.get();
|
||||
}
|
||||
|
||||
render() {
|
||||
return <WrappedComponent ref={this.props.wrappedRef} {...this.props} />;
|
||||
return <MatrixClientContext.Provider value={this._matrixClient}>
|
||||
<WrappedComponent ref={this.props.wrappedRef} {...this.props} />
|
||||
</MatrixClientContext.Provider>;
|
||||
}
|
||||
}
|
||||
return Wrapper;
|
||||
|
Reference in New Issue
Block a user