From 9336e937a4f1f5a1e667ea635648df361ab84fb6 Mon Sep 17 00:00:00 2001 From: kei Date: Thu, 11 Jun 2026 07:13:12 +0200 Subject: [PATCH 1/2] test(calendar): cover event duration updates --- .../event-editor-dialog.component.spec.ts | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/app/calendar-app/event-editor-dialog.component.spec.ts diff --git a/src/app/calendar-app/event-editor-dialog.component.spec.ts b/src/app/calendar-app/event-editor-dialog.component.spec.ts new file mode 100644 index 000000000..ac4fae3d8 --- /dev/null +++ b/src/app/calendar-app/event-editor-dialog.component.spec.ts @@ -0,0 +1,59 @@ +// --------- BEGIN RUNBOX LICENSE --------- +// Copyright (C) 2016-2026 Runbox Solutions AS (runbox.com). +// +// This file is part of Runbox 7. +// +// Runbox 7 is free software: You can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation, either version 3 of the License, or (at your +// option) any later version. +// +// Runbox 7 is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Runbox 7. If not, see . +// ---------- END RUNBOX LICENSE ---------- + +import { CalendarSettings } from './calendar-settings'; +import { EventEditorDialogComponent } from './event-editor-dialog.component'; +import { RunboxCalendar } from './runbox-calendar'; +import { RunboxCalendarEvent } from './runbox-calendar-event'; + +describe('EventEditorDialogComponent', () => { + function createComponent(): EventEditorDialogComponent { + return new EventEditorDialogComponent( + {} as any, + { close: jasmine.createSpy('close') } as any, + { + calendars: [new RunboxCalendar({ id: 'test-calendar', displayname: 'Test Calendar' })], + event: RunboxCalendarEvent.newEmpty(), + is_new: true, + settings: new CalendarSettings({}), + start: new Date(2026, 0, 10), + } + ); + } + + it('should shift the end time by the same amount when the start time changes', () => { + const component = createComponent(); + component.event_start = new Date(2026, 0, 10, 8, 0); + component.event_end = new Date(2026, 0, 10, 9, 30); + + component.updateStart(new Date(2026, 0, 10, 7, 0)); + + expect(component.event_end).toEqual(new Date(2026, 0, 10, 8, 30)); + }); + + it('should keep the event duration when the start date changes', () => { + const component = createComponent(); + component.event_start = new Date(2026, 0, 10, 8, 0); + component.event_end = new Date(2026, 0, 10, 9, 30); + + component.updateStart(new Date(2026, 0, 11, 8, 0)); + + expect(component.event_end).toEqual(new Date(2026, 0, 11, 9, 30)); + }); +}); From 5a5ad4640ffdf57a501d6a1c5d914c556df84b1c Mon Sep 17 00:00:00 2001 From: kei Date: Thu, 11 Jun 2026 07:13:29 +0200 Subject: [PATCH 2/2] fix(calendar): preserve event duration when start changes --- src/app/calendar-app/event-editor-dialog.component.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app/calendar-app/event-editor-dialog.component.ts b/src/app/calendar-app/event-editor-dialog.component.ts index dd5899481..378a1ee47 100644 --- a/src/app/calendar-app/event-editor-dialog.component.ts +++ b/src/app/calendar-app/event-editor-dialog.component.ts @@ -317,6 +317,11 @@ export class EventEditorDialogComponent { // NB: ngModelChange has to be before ngModel (in template) to read // the old value public updateStart(value: Date) { + if (this.event_start && this.event_end) { + const startDeltaMs = value.getTime() - this.event_start.getTime(); + this.event_end = new Date(this.event_end.getTime() + startDeltaMs); + } + // Do this always, in case we fiddle with dates, then // set event_recurs: if (!this.event_recurs) {