From a8d88e01fb0b54cc1cf97106269342c477ddcdc9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 7 Oct 2020 00:10:40 +0100 Subject: [PATCH] Write Enzyme tests for SendMessageComposer state/history persistence behaviour Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../views/rooms/SendMessageComposer-test.js | 155 +++++++++++++++++- 1 file changed, 152 insertions(+), 3 deletions(-) diff --git a/test/components/views/rooms/SendMessageComposer-test.js b/test/components/views/rooms/SendMessageComposer-test.js index d5a143a1fb..fc3193711e 100644 --- a/test/components/views/rooms/SendMessageComposer-test.js +++ b/test/components/views/rooms/SendMessageComposer-test.js @@ -14,16 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. */ -import RoomViewStore from "../../../../src/stores/RoomViewStore"; -import {createMessageContent} from "../../../../src/components/views/rooms/SendMessageComposer"; +import Adapter from "enzyme-adapter-react-16"; +import { configure, mount } from "enzyme"; +import React from "react"; +import {act} from "react-dom/test-utils"; + +import SendMessageComposer, {createMessageContent} from "../../../../src/components/views/rooms/SendMessageComposer"; +import MatrixClientContext from "../../../../src/contexts/MatrixClientContext"; import EditorModel from "../../../../src/editor/model"; import {createPartCreator, createRenderer} from "../../../editor/mock"; +import {createTestClient, mkEvent, mkStubRoom} from "../../../test-utils"; +import BasicMessageComposer from "../../../../src/components/views/rooms/BasicMessageComposer"; +import {MatrixClientPeg} from "../../../../src/MatrixClientPeg"; +import {sleep} from "../../../../src/utils/promise"; +import SpecPermalinkConstructor from "../../../../src/utils/permalinks/SpecPermalinkConstructor"; +import defaultDispatcher from "../../../../src/dispatcher/dispatcher"; jest.mock("../../../../src/stores/RoomViewStore"); +configure({ adapter: new Adapter() }); + describe('', () => { describe("createMessageContent", () => { - RoomViewStore.getQuotingEvent.mockReturnValue(false); const permalinkCreator = jest.fn(); it("sends plaintext messages correctly", () => { @@ -78,6 +90,143 @@ describe('', () => { }); }); }); + + describe("functions correctly mounted", () => { + const mockClient = MatrixClientPeg.matrixClient = createTestClient(); + const mockRoom = mkStubRoom(); + const mockEvent = mkEvent({ + type: "m.room.message", + content: "Replying to this", + event: true, + }); + mockRoom.findEventById = jest.fn(eventId => { + return eventId === mockEvent.getId() ? mockEvent : null; + }); + + const spyDispatcher = jest.spyOn(defaultDispatcher, "dispatch"); + + beforeEach(() => { + localStorage.clear(); + spyDispatcher.mockReset(); + }); + + it("renders text and placeholder correctly", () => { + const wrapper = mount( + + ); + + expect(wrapper.find('[aria-label="placeholder string"]')).toHaveLength(1); + + act(() => { + wrapper.find(BasicMessageComposer).instance().insertText("Test Text"); + wrapper.update(); + }); + + expect(wrapper.text()).toBe("Test Text"); + }); + + it("correctly persists state to and from localStorage", () => { + const wrapper = mount( + + ); + + act(() => { + wrapper.find(BasicMessageComposer).instance().insertText("Test Text"); + wrapper.update(); + }); + + const key = wrapper.find(SendMessageComposer).instance()._editorStateKey; + + expect(wrapper.text()).toBe("Test Text"); + expect(localStorage.getItem(key)).toBeNull(); + + // ensure the right state was persisted to localStorage + wrapper.unmount(); + expect(JSON.parse(localStorage.getItem(key))).toStrictEqual({ + parts: [{"type": "plain", "text": "Test Text"}], + replyEventId: mockEvent.getId(), + }); + + // ensure the correct model is re-loaded + wrapper.mount(); + expect(wrapper.text()).toBe("Test Text"); + expect(spyDispatcher).toHaveBeenCalledWith({ + action: "reply_to_event", + event: mockEvent, + }); + + // now try with localStorage wiped out + wrapper.unmount(); + localStorage.removeItem(key); + wrapper.mount(); + expect(wrapper.text()).toBe(""); + }); + + it("persists state correctly without replyToEvent onbeforeunload", () => { + const wrapper = mount( + + ); + + act(() => { + wrapper.find(BasicMessageComposer).instance().insertText("Hello World"); + wrapper.update(); + }); + + const key = wrapper.find(SendMessageComposer).instance()._editorStateKey; + + expect(wrapper.text()).toBe("Hello World"); + expect(localStorage.getItem(key)).toBeNull(); + + // ensure the right state was persisted to localStorage + window.dispatchEvent(new Event('beforeunload')); + expect(JSON.parse(localStorage.getItem(key))).toStrictEqual({ + parts: [{"type": "plain", "text": "Hello World"}], + }); + }); + + it("persists to session history upon sending", async () => { + const wrapper = mount( + + ); + + act(() => { + wrapper.find(BasicMessageComposer).instance().insertText("This is a message"); + wrapper.find(".mx_SendMessageComposer").simulate("keydown", { key: "Enter" }); + wrapper.update(); + }); + await sleep(10); // await the async _sendMessage + wrapper.update(); + expect(spyDispatcher).toHaveBeenCalledWith({ + action: "reply_to_event", + event: null, + }); + + expect(wrapper.text()).toBe(""); + const str = sessionStorage.getItem(`mx_cider_composer_history_${mockRoom.roomId}[0]`); + expect(JSON.parse(str)).toStrictEqual({ + parts: [{"type": "plain", "text": "This is a message"}], + replyEventId: mockEvent.getId(), + }); + }); + }); });