Mailspring/internal_packages/composer-scheduler/spec/proposed-time-picker-spec.jsx
Evan Morikawa 7e3e3a6015 tests(calendar): adding calendar and scheduler tests
Summary: Adding tests

Test Plan: Tests

Reviewers: juan, bengotow

Reviewed By: bengotow

Differential Revision: https://phab.nylas.com/D2892
2016-04-19 11:54:15 -07:00

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],
]);
});
});