UNPKG

stitch-ui

Version:

281 lines (269 loc) 9.01 kB
/* global it, describe, beforeAll, expect */ import React from "react"; // eslint-disable-line no-unused-vars import { Provider } from "react-redux"; import { JSDOM } from "jsdom"; import { MemoryRouter } from "react-router-dom"; import { mount, ReactWrapper } from "enzyme"; import sinon from "sinon"; import { testSetup, noConsoleErrorsAllowed, stubConfirmation } from "../../testutil"; import * as homeActions from "../../home/actions"; import * as actions from "../actions"; import * as serviceActions from "../../services/actions"; // importing both the class and the connected component, // so that we can stub its confirm() method. import Push from "../components/PushNotifications"; import MessageEditor from "../components/MessageEditor"; global.navigator = { userAgent: "node.js" }; const doc = new JSDOM("<!doctype html><html><body></body></html>"); global.document = doc; global.window = doc.defaultView; describe("auth", () => { noConsoleErrorsAllowed(); let store; let testApp; let display; let displaySent; let actionSub; beforeAll(async () => { const testHarness = await testSetup(); store = testHarness.store; actionSub = testHarness.actionSub; testApp = await store.dispatch( homeActions.createApp(testHarness.groupId, "my-test-app") ); await store.dispatch( serviceActions.saveConfig(testApp.groupId, testApp._id, "gcm", { apiKey: "myApiKey", senderId: "123456" }) ); // Mount two 'tabs': one for the sent messages and one for the drafts await new Promise(resolve => { actionSub.subscribe(actions.loadMessagesActions.rcv.getType(), resolve); display = mount( <Provider store={store}> <MemoryRouter initialEntries={[ `/groups/${testHarness.groupId}/apps/${testApp._id}/push/drafts` ]} initialIndex={0} > <Push app={testApp} match={{ url: `/groups/${testHarness.groupId}/apps/${testApp._id}/push` }} /> </MemoryRouter> </Provider> ); }); await new Promise(resolve => { actionSub.subscribe(actions.loadMessagesActions.rcv.getType(), resolve); displaySent = mount( <Provider store={store}> <MemoryRouter initialEntries={[ `/groups/${testHarness.groupId}/apps/${testApp._id}/push/sent` ]} initialIndex={0} > <Push app={testApp} match={{ url: `/groups/${testHarness.groupId}/apps/${testApp._id}/push` }} /> </MemoryRouter> </Provider> ); }); }); it("can save a message as a draft", async () => { display .find("button") .findWhere(x => x.text() === "Send New Notification") .props() .onClick(); const newMsgModalPortal = display.find("MessageEditor").at(0).node.modal .portal; expect(newMsgModalPortal).toBeDefined(); const newMsgModal = new ReactWrapper(newMsgModalPortal, newMsgModalPortal); newMsgModal .find("input[name='message']") .props() .onChange({ target: { value: "test msg text" } }); newMsgModal .find("input[name='label']") .props() .onChange({ target: { value: "test msg label" } }); newMsgModal .find("input[name='topic']") .props() .onChange({ target: { value: "test msg topic" } }); await newMsgModal .find("button") .findWhere(x => x.text() === "Save Draft") .props() .onClick(); expect(display.find("MessageList").props().messages).toHaveLength(1); const msg = display.find("MessageList").props().messages[0]; expect(msg.type).toEqual("draft"); expect(msg.topic).toEqual("test msg topic"); expect(msg.message).toEqual("test msg text"); expect(msg.label).toEqual("test msg label"); }); it("can populate the send form by duplicating a message", async () => { display.find("Message").find("DropdownMenu").props().toggle.props.onClick(); display .find("Message") .find("DropdownMenu") .find("a") .findWhere(x => x.text() === "Duplicate") .props() .onClick(); expect( display.find("MessageEditor").at(0).props().editingMessageId ).toBeFalsy(); const msgModalPortal = display.find("MessageEditor").at(0).node.modal .portal; expect(msgModalPortal).toBeDefined(); const msgModal = new ReactWrapper(msgModalPortal, msgModalPortal); const msg = display.find("MessageList").props().messages[0]; expect(msgModal.find("input[name='message']").props().value).toEqual( msg.message ); expect(msgModal.find("input[name='label']").props().value).toEqual( msg.label ); expect(msgModal.find("input[name='topic']").props().value).toEqual( msg.topic ); display.find("MessageEditor").props().onClose(); }); it("can save edits to a draft", async () => { display.find("Message").find("DropdownMenu").props().toggle.props.onClick(); display .find("Message") .find("DropdownMenu") .find("a") .findWhere(x => x.text() === "Edit") .props() .onClick(); const msg = display.find("MessageList").props().messages[0]; expect( display.find("MessageEditor").at(0).props().editingMessageId ).toEqual(msg._id); const msgModalPortal = display.find("MessageEditor").at(0).node.modal .portal; expect(msgModalPortal).toBeDefined(); const msgModal = new ReactWrapper(msgModalPortal, msgModalPortal); msgModal .find("input[name='message']") .props() .onChange({ target: { value: "updated message" } }); await msgModal .find("button") .findWhere(x => x.text() === "Save Draft") .props() .onClick(); expect(display.find("Message").find("td").at(1).text()).toEqual( "updated message" ); }); it("saving an invalid message displays an error", async () => { expect.assertions(4); display.find("Message").find("DropdownMenu").props().toggle.props.onClick(); display .find("Message") .find("DropdownMenu") .find("a") .findWhere(x => x.text() === "Edit") .props() .onClick(); const msg = display.find("MessageList").props().messages[0]; expect( display.find("MessageEditor").at(0).props().editingMessageId ).toEqual(msg._id); const msgModalPortal = display.find("MessageEditor").at(0).node.modal .portal; expect(msgModalPortal).toBeDefined(); const msgModal = new ReactWrapper(msgModalPortal, msgModalPortal); msgModal .find("input[name='message']") .props() .onChange({ target: { value: "" } }); try { await msgModal .find("button") .findWhere(x => x.text() === "Save Draft") .props() .onClick(); } catch (err) { expect(display.find("MessageEditor").props().open).toBe(true); expect(msgModal.find(".banner-error").text()).toBe( "message must not be blank" ); } }); it("can send the message", async () => { const msgItem = display.find("Message"); msgItem.find("DropdownMenu").props().toggle.props.onClick(); msgItem .find("DropdownMenu") .find("a") .findWhere(x => x.text() === "Edit") .props() .onClick(); const msg = display.find("MessageList").props().messages[0]; expect( display.find("MessageEditor").at(0).props().editingMessageId ).toEqual(msg._id); const msgModalPortal = display.find("MessageEditor").at(0).node.modal .portal; expect(msgModalPortal).toBeDefined(); const msgModal = new ReactWrapper(msgModalPortal, msgModalPortal); msgModal .find("input[name='message']") .props() .onChange({ target: { value: "updated message" } }); const pipelineStub = sinon.stub(MessageEditor, "makeTopicPipeline"); pipelineStub.returns([ { action: "literal", args: { items: [] } } ]); await msgModal .find("button") .findWhere(x => x.text() === "Send Message") .props() .onClick(); // Message should be gone from drafts folder. // Check the 'sent' folder, and the message should appear there await displaySent.find("PushNotifications").find("MessageList").node.load(); expect(displaySent.find("MessageList").find("Message")).toHaveLength(1); }); it("can delete a message from the list", async () => { stubConfirmation(true); displaySent .find("Message") .find("DropdownMenu") .props() .toggle.props.onClick(); await displaySent .find("Message") .find("DropdownMenu") .find("a") .findWhere(x => x.text() === "Delete") .props() .onClick(); expect(displaySent.find("MessageList").find("Message")).toHaveLength(0); }); });