215 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			215 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
| /*
 | |
| Copyright 2016 OpenMarket Ltd
 | |
| 
 | |
| 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 SettingsStore from "../../../src/settings/SettingsStore";
 | |
| 
 | |
| const React = require('react');
 | |
| const ReactDOM = require("react-dom");
 | |
| const TestUtils = require('react-addons-test-utils');
 | |
| const expect = require('expect');
 | |
| import sinon from 'sinon';
 | |
| 
 | |
| const sdk = require('matrix-react-sdk');
 | |
| 
 | |
| const MessagePanel = sdk.getComponent('structures.MessagePanel');
 | |
| import MatrixClientPeg from '../../../src/MatrixClientPeg';
 | |
| 
 | |
| const test_utils = require('test-utils');
 | |
| const mockclock = require('mock-clock');
 | |
| 
 | |
| let client;
 | |
| 
 | |
| // wrap MessagePanel with a component which provides the MatrixClient in the context.
 | |
| const WrappedMessagePanel = React.createClass({
 | |
|     childContextTypes: {
 | |
|         matrixClient: React.PropTypes.object,
 | |
|     },
 | |
| 
 | |
|     getChildContext: function() {
 | |
|         return {
 | |
|             matrixClient: client,
 | |
|         };
 | |
|     },
 | |
| 
 | |
|     render: function() {
 | |
|         return <MessagePanel {...this.props} />;
 | |
|     },
 | |
| });
 | |
| 
 | |
| describe('MessagePanel', function() {
 | |
|     const clock = mockclock.clock();
 | |
|     const realSetTimeout = window.setTimeout;
 | |
|     const events = mkEvents();
 | |
|     let sandbox = null;
 | |
| 
 | |
|     beforeEach(function() {
 | |
|         test_utils.beforeEach(this);
 | |
|         sandbox = test_utils.stubClient();
 | |
|         client = MatrixClientPeg.get();
 | |
|         client.credentials = {userId: '@me:here'};
 | |
| 
 | |
|         // HACK: We assume all settings want to be disabled
 | |
|         SettingsStore.getValue = sinon.stub().returns(false);
 | |
|     });
 | |
| 
 | |
|     afterEach(function() {
 | |
|         clock.uninstall();
 | |
|         sandbox.restore();
 | |
|     });
 | |
| 
 | |
|     function mkEvents() {
 | |
|         const events = [];
 | |
|         const ts0 = Date.now();
 | |
|         for (let i = 0; i < 10; i++) {
 | |
|             events.push(test_utils.mkMessage(
 | |
|                 {
 | |
|                     event: true, room: "!room:id", user: "@user:id",
 | |
|                     ts: ts0 + i*1000,
 | |
|                 }));
 | |
|         }
 | |
|         return events;
 | |
|     }
 | |
| 
 | |
|     it('should show the events', function() {
 | |
|         const res = TestUtils.renderIntoDocument(
 | |
|                 <WrappedMessagePanel className="cls" events={events} />,
 | |
|         );
 | |
| 
 | |
|         // just check we have the right number of tiles for now
 | |
|         const tiles = TestUtils.scryRenderedComponentsWithType(
 | |
|             res, sdk.getComponent('rooms.EventTile'));
 | |
|         expect(tiles.length).toEqual(10);
 | |
|     });
 | |
| 
 | |
|     it('should show the read-marker in the right place', function() {
 | |
|         const res = TestUtils.renderIntoDocument(
 | |
|                 <WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[4].getId()}
 | |
|                     readMarkerVisible={true} />,
 | |
|         );
 | |
| 
 | |
|         const tiles = TestUtils.scryRenderedComponentsWithType(
 | |
|             res, sdk.getComponent('rooms.EventTile'));
 | |
| 
 | |
|         // find the <li> which wraps the read marker
 | |
|         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;
 | |
|         expect(rm.previousSibling).toEqual(eventContainer);
 | |
|     });
 | |
| 
 | |
|     it('shows a ghost read-marker when the read-marker moves', function(done) {
 | |
|         // fake the clock so that we can test the velocity animation.
 | |
|         clock.install();
 | |
|         clock.mockDate();
 | |
| 
 | |
|         const parentDiv = document.createElement('div');
 | |
| 
 | |
|         // first render with the RM in one place
 | |
|         let mp = ReactDOM.render(
 | |
|                 <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;
 | |
|         });
 | |
| 
 | |
|         // find the <li> which wraps the read marker
 | |
|         const rm = TestUtils.findRenderedDOMComponentWithClass(mp, 'mx_RoomView_myReadMarker_container');
 | |
|         expect(rm.previousSibling).toEqual(tileContainers[4]);
 | |
| 
 | |
|         // now move the RM
 | |
|         mp = ReactDOM.render(
 | |
|                 <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');
 | |
|         expect(found.length).toEqual(2);
 | |
| 
 | |
|         // the first should be the ghost
 | |
|         expect(found[0].previousSibling).toEqual(tileContainers[4]);
 | |
|         const hr = found[0].children[0];
 | |
| 
 | |
|         // the second should be the real thing
 | |
|         expect(found[1].previousSibling).toEqual(tileContainers[6]);
 | |
| 
 | |
|         // advance the clock, and then let the browser run an animation frame,
 | |
|         // to let the animation start
 | |
|         clock.tick(1500);
 | |
| 
 | |
|         realSetTimeout(() => {
 | |
|             // then advance it again to let it complete
 | |
|             clock.tick(1000);
 | |
|             realSetTimeout(() => {
 | |
|                 // the ghost should now have finished
 | |
|                 expect(hr.style.opacity).toEqual('0');
 | |
|                 done();
 | |
|             }, 100);
 | |
|         }, 100);
 | |
|     });
 | |
| 
 | |
|     it('shows only one ghost when the RM moves twice', function() {
 | |
|         const parentDiv = document.createElement('div');
 | |
| 
 | |
|         // first render with the RM in one place
 | |
|         let mp = ReactDOM.render(
 | |
|                 <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;
 | |
|         });
 | |
| 
 | |
|         // now move the RM
 | |
|         mp = ReactDOM.render(
 | |
|                 <WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[6].getId()}
 | |
|                     readMarkerVisible={true}
 | |
|                 />, parentDiv);
 | |
| 
 | |
|         // now there should be two RM containers
 | |
|         let found = TestUtils.scryRenderedDOMComponentsWithClass(mp, 'mx_RoomView_myReadMarker_container');
 | |
|         expect(found.length).toEqual(2);
 | |
| 
 | |
|         // the first should be the ghost
 | |
|         expect(tileContainers.indexOf(found[0].previousSibling)).toEqual(4);
 | |
| 
 | |
|         // the second should be the real RM
 | |
|         expect(tileContainers.indexOf(found[1].previousSibling)).toEqual(6);
 | |
| 
 | |
|         // and move the RM again
 | |
|         mp = ReactDOM.render(
 | |
|                 <WrappedMessagePanel className="cls" events={events} readMarkerEventId={events[8].getId()}
 | |
|                     readMarkerVisible={true}
 | |
|                 />, parentDiv);
 | |
| 
 | |
|         // still two RM containers
 | |
|         found = TestUtils.scryRenderedDOMComponentsWithClass(mp, 'mx_RoomView_myReadMarker_container');
 | |
|         expect(found.length).toEqual(2);
 | |
| 
 | |
|         // they should have moved
 | |
|         expect(tileContainers.indexOf(found[0].previousSibling)).toEqual(6);
 | |
|         expect(tileContainers.indexOf(found[1].previousSibling)).toEqual(8);
 | |
|     });
 | |
| });
 |