Skip to content

Commit

Permalink
add e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
petrjasek committed Dec 10, 2024
1 parent 9b1305c commit 688b12b
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 34 deletions.
4 changes: 4 additions & 0 deletions client/components/Events/EventDateTime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export class EventDateTime extends React.PureComponent<IProps> {
date={start}
{...commonProps}
withTime={false}
testId="event-start-date"
/>
)}
{gettext('All day')}
Expand All @@ -95,9 +96,11 @@ export class EventDateTime extends React.PureComponent<IProps> {
</span>
)}
<DateTime
withTime={!isFullDay}
withDate={showEventStartDate}
withYear={withYear}
date={start}
testId="event-start-date"
{...commonProps}
/>
{showDash && <>&ndash;</>}
Expand All @@ -106,6 +109,7 @@ export class EventDateTime extends React.PureComponent<IProps> {
withYear={withYear}
isEndEventDateTime={true}
date={end}
testId="event-end-date"
{...commonProps}
/>
{isRemoteTimeZone && (
Expand Down
6 changes: 5 additions & 1 deletion client/components/Events/EventDateTimeColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export class EventDateTimeColumn extends React.PureComponent<IProps> {
withYear={!isThisYear}
withTime={false}
date={start}
testId="event-start-date"
{...commonProps}
/>
{!multiDay ? null : (
Expand All @@ -62,13 +63,14 @@ export class EventDateTimeColumn extends React.PureComponent<IProps> {
withYear={!isThisYear}
withTime={false}
date={end}
testId="event-end-date"
{...commonProps}
/>
</React.Fragment>
)}
{!isRemoteTimeZone ? null : (
<span className="sd-margin-l--0-5">(
<span className="EventDateTime__timezone">
<span className="EventDateTime__timezone" data-test-id="event-timezone">
{tzCode}
</span>
)</span>
Expand All @@ -85,13 +87,15 @@ export class EventDateTimeColumn extends React.PureComponent<IProps> {
withDate={false}
withYear={false}
date={start}
testId="event-start-date"
{...commonProps}
/>
&ndash;
<DateTime
withDate={false}
withYear={false}
date={end}
testId="event-end-date"
{...commonProps}
/>
</React.Fragment>
Expand Down
4 changes: 3 additions & 1 deletion client/components/UI/DateTime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface IPropsDateTime {
isEndEventDateTime?: boolean,
noEndTime?: boolean,
multiDay?: boolean,
testId?: string,
}

/**
Expand All @@ -37,6 +38,7 @@ function DateTime({
isEndEventDateTime,
noEndTime,
multiDay,
testId,
}: IPropsDateTime) {
const {gettext} = superdeskApi.localization;
const dateFormat = appConfig.planning.dateformat;
Expand Down Expand Up @@ -78,7 +80,7 @@ function DateTime({
const tz = timeUtils.getTimeZoneAbbreviation(date.format('z')) + ' ';

return (
<time className={!padLeft ? 'Datetime' : null} title={tz + displayDate}>
<time className={!padLeft ? 'Datetime' : null} title={tz + displayDate} data-test-id={testId}>
{displayDate}
</time>
);
Expand Down
45 changes: 18 additions & 27 deletions client/components/fields/editor/EventSchedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class EditorFieldEventSchedule extends React.PureComponent<IProps> {
null;
const changes = {'dates.start': value};

if (this.props.item.dates?.all_day == null) {
if (this.props.item.dates?.all_day == null && this.props.item.dates?.no_end_time == null) {
changes['dates.all_day'] = true;
}

Expand All @@ -60,17 +60,16 @@ export class EditorFieldEventSchedule extends React.PureComponent<IProps> {
.minute(startDate.minute())
.second(startDate.second());
} else {
if (this.props.item.dates?.all_day == null || !this.props.item.dates.all_day) {
value = localDateToUtc(value, this.props.item.dates?.tz);
changes['dates.start'] = value;
changes['dates.all_day'] = true;
}

value.hour(0)
.minute(0)
.second(0);
}

if (this.props.item.dates?.all_day === true || changes['dates.all_day'] === true) {
value = localDateToUtc(value, this.props.item.dates?.tz);
changes['dates.start'] = value;
}

if (endDate == null || endDate.isBefore(value)) {
// If we have an end date set, and the end date is before the new start date
// then set the end date to be the same as this new start date
Expand Down Expand Up @@ -98,26 +97,13 @@ export class EditorFieldEventSchedule extends React.PureComponent<IProps> {
return;
}

const _startTime = this.props.item?._startTime;
const defaultDurationOnChange = this.props.profile?.editor?.dates?.default_duration_on_change ?? 1;
const isAllDay = eventUtils.isEventAllDay(startDate, endDate, true);
const isMultiDay = !isSameDay(startDate, endDate);
const newStartDate = !startDate ? value : combineDateTime(startDate, value, this.props.item.dates?.tz);
const changes = {
'dates.start': newStartDate,
'dates.all_day': false,
'dates.no_end_time': this.props.item.dates.no_end_time ?? true,
};

const changes = {'dates.start': newStartDate, 'dates.all_day': false};

if (this.props.item.dates?.all_day === true) {
changes['dates.no_end_time'] = true;
}

if (((_startTime && isAllDay) || !_startTime) &&
defaultDurationOnChange > 0 &&
!isMultiDay
) {
changes['dates.end'] = newStartDate.clone().add(defaultDurationOnChange, 'h');
changes['_endTime'] = changes['dates.end'].clone();
changes['dates.no_end_time'] = false;
}
changes['_startTime'] = newStartDate;
this.setToBeConfirmed(changes);
this.props.onChange(changes, null);
Expand All @@ -127,14 +113,19 @@ export class EditorFieldEventSchedule extends React.PureComponent<IProps> {
const startDate = this.props.item?.dates?.start;
const changes = {'dates.end': value};

if (this.props.item.dates?.all_day == null && this.props.items.dates?.no_end_time == null) {
changes['dates.all_day'] = true;
}

if (!startDate) {
// If we have a new end date with no start date set
// then set the start date as well
changes['dates.start'] = value.clone().startOf('day');
}

if (this.props.item.dates?.all_day == null) {
changes['dates.all_day'] = true;
if (this.props.item.dates?.all_day === true || changes['dates.all_day'] === true ||
this.props.item.dates?.no_end_time === true || changes['dates.no_end_time'] === true) {
changes['dates.end'] = localDateToUtc(value, this.props.item.dates?.tz);
}

this.props.onChange(changes, null);
Expand Down
111 changes: 111 additions & 0 deletions e2e/cypress/e2e/events/event_all_day.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import moment from 'moment';
import {setup, login, waitForPageLoad, SubNavBar, Workqueue, CLIENT_FORMAT} from '../../support/common';
import {PlanningList, EventEditor} from '../../support/planning';
import {getDateStringFor} from '../../support/utils/time';
import {create} from 'lodash';

describe('Planning.Events: all day', () => {
const editor = new EventEditor();
const subnav = new SubNavBar();
const list = new PlanningList();

const baseEvent = {
'dates.start.date': getDateStringFor.today(),
slugline: 'Event',
name: 'Test',
calendars: ['Sport'],
};

beforeEach(() => {
setup({fixture_profile: 'planning_prepopulate_data'}, '/#/planning');

login();

waitForPageLoad.planning();
subnav.createEvent();
editor.waitTillOpen();
});

const createEvent = (event, expectedEvent, expectedCount: number) => {
editor.openAllToggleBoxes();
editor.type(event);
editor.expect(expectedEvent);
editor.createButton
.should('exist')
.click();
list.expectItemCount(expectedCount);
}

it('can create single day event without start and end time', () => {
const event = {
...baseEvent,
'dates.start.date': moment().format(CLIENT_FORMAT),
};

const expectedEvent = {
...event,
'dates.end.date': event['dates.start.date'],
};

createEvent(event, expectedEvent, 1);

list.item(0).find('[data-test-id="event-start-date"]').should('contain.text', event['dates.start.date']);
list.item(0).find('[data-test-id="event-end-date"]').should('contain.text', '');
});

it('can create multi day event without start and end time', () => {
const event = {
...baseEvent,
'dates.start.date': moment().format(CLIENT_FORMAT),
'dates.end.date': moment().add(1, 'day').format(CLIENT_FORMAT),
};

const expectedEvent = {
...event,
'dates.end.date': event['dates.end.date'],
};

createEvent(event, expectedEvent, 2);

list.item(0).find('[data-test-id="event-start-date"]').should('contain.text', event['dates.start.date']);
list.item(0).find('[data-test-id="event-end-date"]').should('contain.text', event['dates.end.date']);
});

it('can create single day event with start time', () => {
const event = {
...baseEvent,
'dates.start.date': moment().format(CLIENT_FORMAT),
'dates.start.time': '12:00',
};

const expectedEvent = {
...event,
'dates.end.date': event['dates.start.date'],
};

createEvent(event, expectedEvent, 1);

list.item(0).find('[data-test-id="event-start-date"]').should('contain.text', moment().format('DD/MM\xa0[12:00]')); // &nbsp;
list.item(0).find('[data-test-id="event-end-date"]').should('contain.text', '');
});

it('can create multi day event with start time', () => {
const event = {
...baseEvent,
'dates.start.date': moment().format(CLIENT_FORMAT),
'dates.start.time': '12:00',
'dates.end.date': moment().add(1, 'day').format(CLIENT_FORMAT),
};

const expectedEvent = {
...event,
'dates.end.date': event['dates.end.date'],
};

createEvent(event, expectedEvent, 2);

list.item(0).find('[data-test-id="event-start-date"]').should('contain.text', moment().format('DD/MM\xa0[12:00]')); // &nbsp;
list.item(0).find('[data-test-id="event-end-date"]').should('contain.text', event['dates.end.date']);
});

});
2 changes: 1 addition & 1 deletion e2e/server/Procfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
rest: gunicorn -c gunicorn_config.py wsgi
wamp: python3 -u ws.py
web: python3 -m http.server -d ../dist 9000
web: python3 -m http.server -d ../dist 9000
15 changes: 11 additions & 4 deletions server/planning/events/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import logging
import itertools
from copy import deepcopy
from datetime import timedelta
from datetime import datetime, timedelta

import pytz
import re
Expand Down Expand Up @@ -357,13 +357,16 @@ def _validate_dates(self, updates, original=None):
@:param dict event:
"""
event = updates if updates.get("dates") or not original else original
start_date = event.get("dates", {}).get("start")
end_date = event.get("dates", {}).get("end")
dates = event.get("dates", {})
start_date = dates.get("start")
end_date = dates.get("end")

if not start_date or not end_date:
raise SuperdeskApiError(message="Event START DATE and END DATE are mandatory.")

if end_date < start_date:
if dates.get("no_end_time") == True and end_date.date() < get_local_date(dates.get("start"), dates.get("tz")).date():
raise SuperdeskApiError(message="END TIME should be after START TIME")
elif dates.get("no_end_time") != True and end_date < start_date:
raise SuperdeskApiError(message="END TIME should be after START TIME")

if (
Expand Down Expand Up @@ -1031,3 +1034,7 @@ def generate_recurring_events(event, recurrence_id=None):
def set_planning_schedule(event):
if event and event.get("dates") and event["dates"].get("start"):
event["_planning_schedule"] = [{"scheduled": event["dates"]["start"]}]


def get_local_date(date: datetime, tz: str) -> datetime:
return date.astimezone(pytz.timezone(tz))

0 comments on commit 688b12b

Please sign in to comment.