mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-03-01 02:25:45 +08:00
Summary: Adding tests Test Plan: Tests Reviewers: juan, bengotow Reviewed By: bengotow Differential Revision: https://phab.nylas.com/D2892
342 lines
11 KiB
JavaScript
342 lines
11 KiB
JavaScript
import _ from 'underscore'
|
|
import React from 'react'
|
|
import ReactDOM from 'react-dom'
|
|
import ReactTestUtils from 'react-addons-test-utils'
|
|
import ProposedTimePicker from '../lib/calendar/proposed-time-picker'
|
|
import TestProposalDataSource from './test-proposal-data-source'
|
|
import WeekView from '../../../src/components/nylas-calendar/week-view'
|
|
import ProposedTimeCalendarStore from '../lib/proposed-time-calendar-store'
|
|
|
|
import {NylasCalendar} from 'nylas-component-kit'
|
|
|
|
import {activate, deactivate} from '../lib/main'
|
|
|
|
const now = window.testNowMoment
|
|
|
|
/**
|
|
* This tests the ProposedTimePicker as an integration test of the picker,
|
|
* associated calendar object, the ProposedTimeCalendarStore, and stubbed
|
|
* ProposedTimeCalendarDataSource
|
|
*
|
|
*/
|
|
describe("ProposedTimePicker", () => {
|
|
beforeEach(() => {
|
|
spyOn(NylasEnv, "getWindowType").andReturn("calendar");
|
|
spyOn(WeekView.prototype, "_now").andReturn(now());
|
|
spyOn(NylasCalendar.prototype, "_now").andReturn(now());
|
|
activate()
|
|
|
|
this.testSrc = new TestProposalDataSource()
|
|
spyOn(ProposedTimePicker.prototype, "_dataSource").andReturn(this.testSrc)
|
|
this.picker = ReactTestUtils.renderIntoDocument(
|
|
<ProposedTimePicker />
|
|
)
|
|
this.weekView = ReactTestUtils.findRenderedComponentWithType(this.picker, WeekView);
|
|
});
|
|
|
|
afterEach(() => {
|
|
deactivate()
|
|
})
|
|
|
|
it("renders a proposed time picker in week view", () => {
|
|
const picker = ReactTestUtils.findRenderedComponentWithType(this.picker, ProposedTimePicker);
|
|
const weekView = ReactTestUtils.findRenderedComponentWithType(this.picker, WeekView);
|
|
expect(picker instanceof ProposedTimePicker).toBe(true);
|
|
expect(weekView instanceof WeekView).toBe(true);
|
|
});
|
|
|
|
// NOTE: We manually fire the SchedulerActions since we've tested the
|
|
// mouse click to time conversion in the nylas-calendar
|
|
|
|
it("creates a proposal on click", () => {
|
|
this.picker._onCalendarMouseDown({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
expect(ProposedTimeCalendarStore.proposals().length).toBe(1)
|
|
expect(ProposedTimeCalendarStore.proposalsAsEvents().length).toBe(1)
|
|
const proposals = $("proposal");
|
|
const events = $("calendar-event");
|
|
expect(events.length).toBe(1);
|
|
expect(proposals.length).toBe(1);
|
|
|
|
// It's not an availability block but a full blown proposal
|
|
expect($("availability").length).toBe(0);
|
|
});
|
|
|
|
it("creates the time picker for the correct timespan", () => {
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
const title = $("title");
|
|
expect(ReactDOM.findDOMNode(title[0]).innerHTML).toBe("March 13 - March 19 2016");
|
|
});
|
|
|
|
it("creates a block of proposals on drag down", () => {
|
|
this.picker._onCalendarMouseDown({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseMove({
|
|
time: now().add(30, 'minutes'),
|
|
mouseIsDown: true,
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseMove({
|
|
time: now().add(60, 'minutes'),
|
|
mouseIsDown: true,
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
|
|
// Ensure that we don't see any proposals
|
|
expect(ProposedTimeCalendarStore.proposals().length).toBe(0)
|
|
let proposalEls = $("proposal");
|
|
expect(proposalEls.length).toBe(0);
|
|
|
|
// But we DO see the drag block event
|
|
expect(ProposedTimeCalendarStore.proposalsAsEvents().length).toBe(1)
|
|
let events = $("calendar-event");
|
|
expect($("availability").length).toBe(1);
|
|
expect(events.length).toBe(1);
|
|
|
|
this.picker._onCalendarMouseUp({
|
|
time: now().add(90, 'minutes'),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
// Now that we've moused up, this should convert them into proposals
|
|
const proposals = ProposedTimeCalendarStore.proposals()
|
|
expect(proposals.length).toBe(3)
|
|
expect(ProposedTimeCalendarStore.proposalsAsEvents().length).toBe(3)
|
|
proposalEls = $("proposal");
|
|
events = $("calendar-event");
|
|
expect(events.length).toBe(3);
|
|
expect(proposalEls.length).toBe(3);
|
|
|
|
const times = proposals.map((p) =>
|
|
[p.start, p.end]
|
|
);
|
|
|
|
expect(times).toEqual([
|
|
[now().unix(), now().add(30, 'minutes').unix() - 1],
|
|
[now().add(30, 'minutes').unix(),
|
|
now().add(60, 'minutes').unix() - 1],
|
|
[now().add(60, 'minutes').unix(),
|
|
now().add(90, 'minutes').unix() - 1],
|
|
]);
|
|
});
|
|
|
|
it("creates a block of proposals on drag up", () => {
|
|
this.picker._onCalendarMouseDown({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseMove({
|
|
time: now().subtract(30, 'minutes'),
|
|
mouseIsDown: true,
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseMove({
|
|
time: now().subtract(60, 'minutes'),
|
|
mouseIsDown: true,
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now().subtract(90, 'minutes'),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
const proposals = ProposedTimeCalendarStore.proposals()
|
|
const times = proposals.map((p) =>
|
|
[p.start, p.end]
|
|
);
|
|
|
|
expect(times).toEqual([
|
|
[now().subtract(90, 'minutes').unix(),
|
|
now().subtract(60, 'minutes').unix() - 1],
|
|
[now().subtract(60, 'minutes').unix(),
|
|
now().subtract(30, 'minutes').unix() - 1],
|
|
[now().subtract(30, 'minutes').unix(),
|
|
now().unix() - 1],
|
|
]);
|
|
});
|
|
|
|
it("removes proposals when clicked on", () => {
|
|
// This created a proposal
|
|
this.picker._onCalendarMouseDown({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
// See the proposal is there
|
|
expect(ProposedTimeCalendarStore.proposals().length).toBe(1)
|
|
|
|
// Now let's find and click it.
|
|
// This also tests to make sure it actually rendered
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
const removeBtn = $("rm-time proposal");
|
|
expect(removeBtn.length).toBe(1)
|
|
ReactTestUtils.Simulate.mouseDown(ReactDOM.findDOMNode(removeBtn[0]))
|
|
|
|
// Now see that it's gone!
|
|
expect(ProposedTimeCalendarStore.proposals().length).toBe(0)
|
|
// And gone from the DOM too.
|
|
expect($("proposal").length).toBe(0);
|
|
// And didn't turn into an availability block or something dumb
|
|
expect($("availability").length).toBe(0);
|
|
});
|
|
|
|
it("can clear all of the proposals", () => {
|
|
// This created a proposal
|
|
this.picker._onCalendarMouseDown({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
// See the proposal is there
|
|
expect(ProposedTimeCalendarStore.proposals().length).toBe(1)
|
|
|
|
// Find the clear button
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
const clearBtns = $("clear-proposed-times");
|
|
expect(clearBtns.length).toBe(1);
|
|
|
|
// Click it
|
|
ReactTestUtils.Simulate.click(ReactDOM.findDOMNode(clearBtns[0]))
|
|
|
|
// Ensure no more proposals
|
|
expect(ProposedTimeCalendarStore.proposals().length).toBe(0)
|
|
// And nothing still rendered
|
|
expect($("proposal").length).toBe(0);
|
|
expect($("availability").length).toBe(0);
|
|
});
|
|
|
|
it("can change the duration", () => {
|
|
// Find the duration picker.
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
const pickerEls = $("duration-picker-select");
|
|
expect(pickerEls.length).toBe(1);
|
|
|
|
// Starts with default duration
|
|
const d30Min = ProposedTimeCalendarStore.DURATIONS[0]
|
|
expect(ProposedTimeCalendarStore._duration).toEqual(d30Min)
|
|
|
|
const pickerEl = ReactDOM.findDOMNode(pickerEls[0]);
|
|
pickerEl.value = "1.5|hours|1½ hr"
|
|
ReactTestUtils.Simulate.change(pickerEl)
|
|
|
|
const dHrHalf = ProposedTimeCalendarStore.DURATIONS[2]
|
|
dHrHalf[0] = `${dHrHalf[0]}` // convert to string
|
|
expect(ProposedTimeCalendarStore._duration).toEqual(dHrHalf)
|
|
});
|
|
|
|
it("creates a block of proposals with a longer duration", () => {
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
|
|
// Create a single proposal with the default 30 min duration.
|
|
this.picker._onCalendarMouseDown({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
// It's 30 min long
|
|
const proposals = ProposedTimeCalendarStore.proposals()
|
|
const times = proposals.map((p) => [p.start, p.end]);
|
|
expect(times).toEqual([
|
|
[now().unix(),
|
|
now().add(30, 'minutes').unix() - 1],
|
|
]);
|
|
|
|
// Change duration to 2.5 hours
|
|
const pickerEl = ReactDOM.findDOMNode($("duration-picker-select")[0]);
|
|
pickerEl.value = "2.5|hours|2½ hr"
|
|
ReactTestUtils.Simulate.change(pickerEl)
|
|
|
|
// Click a new event
|
|
this.picker._onCalendarMouseDown({
|
|
time: now().add(2, 'hours'),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now().add(2, 'hours'),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
// It should have added a 2.5 hour long event and left the original
|
|
// event alone
|
|
const p2 = ProposedTimeCalendarStore.proposals()
|
|
const t2 = p2.map((p) => [p.start, p.end]);
|
|
expect(t2).toEqual([
|
|
[now().unix(),
|
|
now().add(30, 'minutes').unix() - 1],
|
|
[now().add(2, 'hours').unix(),
|
|
now().add(4.5, 'hours').unix() - 1],
|
|
]);
|
|
});
|
|
|
|
it("overrides events so they don't overlap", () => {
|
|
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass, this.picker);
|
|
this.picker._onCalendarMouseDown({
|
|
time: now(),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now().add(1, 'hour'),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
// Creates two proposals.
|
|
const proposals = ProposedTimeCalendarStore.proposals()
|
|
const times = proposals.map((p) => [p.start, p.end]);
|
|
expect(times).toEqual([
|
|
[now().unix(),
|
|
now().add(30, 'minutes').unix() - 1],
|
|
[now().add(30, 'minutes').unix(),
|
|
now().add(60, 'minutes').unix() - 1],
|
|
]);
|
|
|
|
// Change the duration to 2 hours
|
|
const pickerEl = ReactDOM.findDOMNode($("duration-picker-select")[0]);
|
|
pickerEl.value = "2|hours|2 hr"
|
|
ReactTestUtils.Simulate.change(pickerEl)
|
|
|
|
// Click and drag overlapping the first of the original events.
|
|
this.picker._onCalendarMouseDown({
|
|
time: now().subtract(1.5, 'hours'),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
this.picker._onCalendarMouseUp({
|
|
time: now().add(20, 'minutes'),
|
|
currentView: NylasCalendar.WEEK_VIEW,
|
|
})
|
|
|
|
// See that there's only 1 new event with the correct time and it
|
|
// exhchanged it with the old one.
|
|
//
|
|
// It left the non overlapping one alone.
|
|
const p2 = ProposedTimeCalendarStore.proposals()
|
|
const t2 = p2.map((p) => [p.start, p.end]);
|
|
expect(t2).toEqual([
|
|
[now().add(30, 'minutes').unix(),
|
|
now().add(60, 'minutes').unix() - 1],
|
|
[now().subtract(1.5, 'hours').unix(),
|
|
now().add(30, 'minutes').unix() - 1],
|
|
]);
|
|
});
|
|
});
|