import _ from 'underscore'
import React from 'react'
import ReactDOM from 'react-dom'
import {PLUGIN_ID} from '../lib/scheduler-constants'
import NewEventCard from '../lib/composer/new-event-card'
import ReactTestUtils from 'react-addons-test-utils';
import NewEventCardContainer from '../lib/composer/new-event-card-container'
import Proposal from '../lib/proposal'
import SchedulerActions from '../lib/scheduler-actions'
import {
Calendar,
Event,
DatabaseStore,
} from 'nylas-exports'
import {
DRAFT_CLIENT_ID,
prepareDraft,
cleanupDraft,
} from './composer-scheduler-spec-helper'
const now = window.testNowMoment
describe("NewEventCard", () => {
beforeEach(() => {
this.session = null
prepareDraft.call(this)
this.eventCardContainer = ReactTestUtils.renderIntoDocument(
);
});
afterEach(() => {
cleanupDraft()
})
const testCalendars = () => [new Calendar({
clientId: "client-1",
servierId: "server-1",
name: "Test Calendar",
})]
const stubCalendars = (calendars = []) => {
jasmine.unspy(DatabaseStore, "run")
spyOn(DatabaseStore, "run").andCallFake((query) => {
if (query.objectClass() === Calendar.name) {
return Promise.resolve(calendars)
}
return Promise.resolve()
})
}
const setNewTestEvent = () => {
if (!this.session) {
throw new Error("Setup test session first")
}
this.session.changes.addPluginMetadata(PLUGIN_ID, {
uid: DRAFT_CLIENT_ID,
pendingEvent: new Event({
calendarId: "TEST_CALENDAR_ID",
title: "",
start: now().unix(),
end: now().add(1, 'hour').unix(),
}).toJSON(),
});
this.eventCardContainer = ReactTestUtils.renderIntoDocument(
);
}
const getPendingEvent = () =>
this.session.draft().metadataForPluginId(PLUGIN_ID).pendingEvent
it("creates a new event card", () => {
const el = ReactTestUtils.findRenderedComponentWithType(this.eventCardContainer,
NewEventCardContainer);
expect(el instanceof NewEventCardContainer).toBe(true)
});
it("doesn't render if there's no event on metadata", () => {
expect(this.eventCardContainer.refs.newEventCard).not.toBeDefined();
});
it("renders the event card when an event is created", () => {
stubCalendars()
setNewTestEvent()
expect(this.eventCardContainer.refs.newEventCard).toBeDefined();
expect(this.eventCardContainer.refs.newEventCard instanceof NewEventCard).toBe(true);
});
it("loads the calendars for email", () => {
stubCalendars(testCalendars())
setNewTestEvent()
waitsFor(() =>
this.eventCardContainer.refs.newEventCard.state.calendars.length > 0
)
runs(() => {
const newEventCard = this.eventCardContainer.refs.newEventCard;
expect(newEventCard.state.calendars).toEqual(testCalendars());
});
});
it("removes the event and clears metadata", () => {
stubCalendars(testCalendars())
setNewTestEvent()
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass,
this.eventCardContainer);
const rmBtn = ReactDOM.findDOMNode($("remove-button")[0]);
// The event is there before clicking remove
expect(this.eventCardContainer.refs.newEventCard).toBeDefined()
expect(this.session.draft().metadataForPluginId(PLUGIN_ID).pendingEvent).toBeDefined()
ReactTestUtils.Simulate.click(rmBtn);
// The event has been removed from metadata
expect(this.session.draft().metadataForPluginId(PLUGIN_ID).pendingEvent).not.toBeDefined()
});
it("properly updates the event", () => {
stubCalendars(testCalendars())
setNewTestEvent()
const $ = _.partial(ReactTestUtils.scryRenderedDOMComponentsWithClass,
this.eventCardContainer);
const title = ReactDOM.findDOMNode($("event-title")[0]);
// The event has the old title
expect(getPendingEvent().title).toBe("")
title.value = "Test"
ReactTestUtils.Simulate.change(title);
// The event has the new title
expect(getPendingEvent().title).toBe("Test")
});
it("updates the day", () => {
stubCalendars(testCalendars())
setNewTestEvent()
const eventCard = this.eventCardContainer.refs.newEventCard;
// The event has the default day
const nowUnix = now().unix()
expect(getPendingEvent()._start).toBe(nowUnix)
// The event has the new day
const newDay = now().add(2, 'days');
eventCard._onChangeDay(newDay.valueOf());
expect(getPendingEvent()._start).toBe(newDay.unix())
});
it("updates the time properly", () => {
stubCalendars(testCalendars())
setNewTestEvent()
const eventCard = this.eventCardContainer.refs.newEventCard;
const oldEnd = now().add(1, 'hour').unix()
expect(getPendingEvent()._start).toBe(now().unix())
expect(getPendingEvent()._end).toBe(oldEnd)
const newStart = now().subtract(1, 'hour');
eventCard._onChangeStartTime(newStart.valueOf());
expect(getPendingEvent()._start).toBe(newStart.unix())
expect(getPendingEvent()._end).toBe(oldEnd)
});
it("adjusts the times to prevent invalid times", () => {
stubCalendars(testCalendars())
setNewTestEvent()
const eventCard = this.eventCardContainer.refs.newEventCard;
const start0 = now();
const end0 = now().add(1, 'hour');
const start1 = now().add(2, 'hours');
const expectedEnd1 = now().add(3, 'hours');
const expectedStart2 = now().subtract(3, 'hours');
const end2 = now().subtract(2, 'hours');
// The event has the start times
expect(getPendingEvent()._start).toBe(start0.unix())
expect(getPendingEvent()._end).toBe(end0.unix())
eventCard._onChangeStartTime(start1.valueOf());
// The event the new start time and also moved the end to match
expect(getPendingEvent()._start).toBe(start1.unix())
expect(getPendingEvent()._end).toBe(expectedEnd1.unix())
eventCard._onChangeEndTime(end2.valueOf());
// The event the new end time and also moved the start to match
expect(getPendingEvent()._start).toBe(expectedStart2.unix())
expect(getPendingEvent()._end).toBe(end2.unix())
});
describe("Inserting proposed times", () => {
beforeEach(() => {
const draft = this.session.draft()
spyOn(DatabaseStore, "find").andReturn(Promise.resolve(draft));
const start = now().add(1, 'hour').unix();
const end = now().add(2, 'hours').unix();
this.proposals = [new Proposal({start, end})]
runs(() => {
SchedulerActions.confirmChoices({
proposals: this.proposals,
draftClientId: DRAFT_CLIENT_ID,
});
})
waitsFor(() => {
const metadata = this.session.draft().metadataForPluginId(PLUGIN_ID);
return (metadata.proposals || []).length > 0;
})
});
it("inserts proposed times on metadata", () => {
const metadata = this.session.draft().metadataForPluginId(PLUGIN_ID);
expect(JSON.stringify(metadata.proposals)).toEqual(JSON.stringify(this.proposals));
});
});
});