1# --
2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
3# --
4# This software comes with ABSOLUTELY NO WARRANTY. For details, see
5# the enclosed file COPYING for license information (GPL). If you
6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
7# --
8
9use strict;
10use warnings;
11use utf8;
12
13use vars (qw($Self));
14
15use Kernel::System::VariableCheck qw(:all);
16
17$Kernel::OM->ObjectParamAdd(
18    'Kernel::System::UnitTest::Helper' => {
19        RestoreDatabase => 1,
20    },
21);
22my $Helper = $Kernel::OM->Get('Kernel::System::UnitTest::Helper');
23
24my $CalendarObject    = $Kernel::OM->Get('Kernel::System::Calendar');
25my $AppointmentObject = $Kernel::OM->Get('Kernel::System::Calendar::Appointment');
26my $GroupObject       = $Kernel::OM->Get('Kernel::System::Group');
27my $UserObject        = $Kernel::OM->Get('Kernel::System::User');
28my $MailQueueObject   = $Kernel::OM->Get('Kernel::System::MailQueue');
29
30my $RandomID = $Helper->GetRandomID();
31
32my %MailQueueCurrentItems = map { $_->{ID} => $_ } @{ $MailQueueObject->List() || [] };
33my $MailQueueClean        = sub {
34    my $Items = $MailQueueObject->List();
35    MAIL_QUEUE_ITEM:
36    for my $Item ( @{$Items} ) {
37        next MAIL_QUEUE_ITEM if $MailQueueCurrentItems{ $Item->{ID} };
38        $MailQueueObject->Delete(
39            ID => $Item->{ID},
40        );
41    }
42
43    return;
44};
45
46my $MailQueueProcess = sub {
47    my %Param = @_;
48
49    my $EmailObject = $Kernel::OM->Get('Kernel::System::Email');
50
51    # Process all items except the ones already present before the tests.
52    my $Items = $MailQueueObject->List();
53    MAIL_QUEUE_ITEM:
54    for my $Item ( @{$Items} ) {
55        next MAIL_QUEUE_ITEM if $MailQueueCurrentItems{ $Item->{ID} };
56        $MailQueueObject->Send( %{$Item} );
57    }
58
59    # Clean any garbage.
60    $MailQueueClean->();
61
62    return;
63};
64
65# Make sure we start with a clean mail queue.
66$MailQueueClean->();
67
68# Do not check RichText.
69$Helper->ConfigSettingChange(
70    Valid => 1,
71    Key   => 'Frontend::RichText',
72    Value => 0,
73);
74
75$Helper->ConfigSettingChange(
76    Valid => 1,
77    Key   => 'AgentSelfNotifyOnAction',
78    Value => 1,
79);
80
81$Helper->ConfigSettingChange(
82    Valid => 1,
83    Key   => 'SendmailModule',
84    Value => 'Kernel::System::Email::Test',
85);
86
87$Helper->ConfigSettingChange(
88    Key   => 'CheckEmailAddresses',
89    Value => 0,
90);
91
92# create test group
93my $GroupName = 'test-calendar-group-' . $RandomID;
94my $GroupID   = $GroupObject->GroupAdd(
95    Name    => $GroupName,
96    ValidID => 1,
97    UserID  => 1,
98);
99
100$Self->True(
101    $GroupID,
102    "Test group $GroupID created",
103);
104
105# Create test user and add it to the test group.
106my ( $UserLogin, $UserID ) = $Helper->TestUserCreate(
107    Groups => [$GroupName],
108);
109
110$Self->True(
111    $UserID,
112    "Test user $UserID created",
113);
114
115# Create Appointment notification with AppointmentDelete event.
116my $AppointmentName = "AppointmetDelete$RandomID";
117my $NotificationID  = $Kernel::OM->Get('Kernel::System::NotificationEvent')->NotificationAdd(
118    Name       => $AppointmentName,
119    Transports => 'Email',
120    UserID     => $UserID,
121    Data       => {
122        LanguageID => [
123            'en'
124        ],
125        NotificationType => [
126            'Appointment'
127        ],
128        TransportEmailTemplate => [
129            'Alert'
130        ],
131        Transports => [
132            'Email'
133        ],
134        Events => [
135            'AppointmentDelete'
136        ],
137        Recipients => [
138            'AppointmentAgentWritePermissions',
139            'All agents with (at least) read permission for the appointment (calendar)'
140        ],
141
142        AgentEnabledByDefault => [
143            'Email'
144        ],
145    },
146    ValidID => 1,
147    Message => {
148        en => {
149            Body        => 'appointment "<OTRS_APPOINTMENT_TITLE>" has reached its notification time.',
150            Subject     => 'Reminder: <OTRS_APPOINTMENT_TITLE> DELETE',
151            ContentType => 'text/html'
152        }
153    },
154);
155$Self->True(
156    $NotificationID,
157    "Appointment Notification ID $NotificationID is created",
158);
159
160# create test calendar
161my %Calendar = $CalendarObject->CalendarCreate(
162    CalendarName => "Calendar-$RandomID",
163    Color        => '#3A87AD',
164    GroupID      => $GroupID,
165    UserID       => $UserID,
166);
167
168$Self->True(
169    $Calendar{CalendarID},
170    "CalendarCreate - $Calendar{CalendarID}",
171);
172
173#
174# Tests for AppointmentCreate(), AppointmentGet() and AppointmentUpdate()
175#
176my @Tests = (
177    {
178        Name    => 'AppointmentCreate - No params',
179        Config  => {},
180        Success => 0,
181    },
182    {
183        Name   => 'AppointmentCreate - No CalendarID',
184        Config => {
185            Title     => "Appointment-$RandomID",
186            StartTime => '2016-01-01 16:00:00',
187            EndTime   => '2016-01-01 17:00:00',
188            UserID    => $UserID,
189        },
190        Success => 0,
191    },
192    {
193        Name   => 'AppointmentCreate - No Title',
194        Config => {
195            CalendarID => $Calendar{CalendarID},
196            StartTime  => '2016-01-01 16:00:00',
197            EndTime    => '2016-01-01 17:00:00',
198            UserID     => $UserID,
199        },
200        Success => 0,
201    },
202    {
203        Name   => 'AppointmentCreate - No StartTime',
204        Config => {
205            CalendarID => $Calendar{CalendarID},
206            Title      => "Appointment-$RandomID",
207            EndTime    => '2016-01-01 17:00:00',
208            UserID     => $UserID,
209        },
210        Success => 0,
211    },
212    {
213        Name   => 'AppointmentCreate - No EndTime',
214        Config => {
215            CalendarID => $Calendar{CalendarID},
216            Title      => "Appointment-$RandomID",
217            StartTime  => '2016-01-01 16:00:00',
218            UserID     => $UserID,
219        },
220        Success => 0,
221    },
222    {
223        Name   => 'AppointmentCreate - No UserID',
224        Config => {
225            CalendarID => $Calendar{CalendarID},
226            Title      => "Appointment-$RandomID",
227            StartTime  => '2016-01-01 16:00:00',
228            EndTime    => '2016-01-01 17:00:00',
229        },
230        Success => 0,
231    },
232    {
233        Name   => 'AppointmentCreate - All required params',
234        Config => {
235            CalendarID => $Calendar{CalendarID},
236            Title      => "Appointment-$RandomID",
237            StartTime  => '2016-01-01 16:00:00',
238            EndTime    => '2016-01-01 17:00:00',
239            UserID     => $UserID,
240        },
241        Success => 1,
242    },
243    {
244        Name   => 'AppointmentCreate - Description, Location and AllDay',
245        Config => {
246            CalendarID  => $Calendar{CalendarID},
247            Title       => "Appointment2-$RandomID",
248            Description => 'Calendar Appointment',
249            Location    => 'Germany',
250            StartTime   => '2016-01-02 00:00:00',
251            EndTime     => '2016-01-02 00:00:00',
252            AllDay      => 1,
253            UserID      => $UserID,
254        },
255        Update => {
256            CalendarID  => $Calendar{CalendarID},
257            Title       => "Appointment2-$RandomID",
258            Description => 'Some description',
259            Location    => 'USA',
260            StartTime   => '2016-01-03 16:00:00',
261            EndTime     => '2016-01-03 17:00:00',
262            AllDay      => 0,
263            UserID      => $UserID,
264        },
265        Success => 1,
266    },
267);
268
269for my $Test (@Tests) {
270
271    # make the call
272    my $AppointmentID = $AppointmentObject->AppointmentCreate(
273        %{ $Test->{Config} },
274    );
275
276    if ( $Test->{Success} ) {
277        $Self->True(
278            $AppointmentID,
279            "$Test->{Name} - Success",
280        );
281
282        my %Appointment = $AppointmentObject->AppointmentGet(
283            AppointmentID => $AppointmentID,
284        );
285
286        KEY:
287        for my $Key ( sort keys %{ $Test->{Config} } ) {
288            next KEY if $Key eq 'UserID';
289
290            $Self->Is(
291                $Appointment{$Key},
292                $Test->{Config}->{$Key},
293                "$Test->{Name} - Returned data",
294            );
295        }
296
297        if ( $Test->{Update} ) {
298            my $Success = $AppointmentObject->AppointmentUpdate(
299                %{ $Test->{Update} },
300                AppointmentID => $AppointmentID,
301            );
302            $Self->True(
303                $Success,
304                "$Test->{Name} - Updated appointment",
305            );
306
307            %Appointment = $AppointmentObject->AppointmentGet(
308                AppointmentID => $AppointmentID,
309            );
310
311            KEY:
312            for my $Key ( sort keys %{ $Test->{Update} } ) {
313                next KEY if $Key eq 'UserID';
314
315                $Self->Is(
316                    $Appointment{$Key},
317                    $Test->{Update}->{$Key},
318                    "$Test->{Name} - Updated data",
319                );
320            }
321        }
322    }
323    else {
324        $Self->False(
325            $AppointmentID,
326            "$Test->{Name} - No success",
327        );
328    }
329}
330
331#
332# Tests for AppointmentList()
333#
334@Tests = (
335    {
336        Name    => 'AppointmentList - No params',
337        Config  => {},
338        Success => 0,
339    },
340    {
341        Name   => 'AppointmentList - CalendarID',
342        Config => {
343            CalendarID => $Calendar{CalendarID},
344        },
345        Count   => 2,
346        Success => 1,
347    },
348    {
349        Name   => 'AppointmentList - StartTime and EndTime',
350        Config => {
351            CalendarID => $Calendar{CalendarID},
352            StartTime  => '2016-01-01 00:00:00',
353            EndTime    => '2016-01-04 00:00:00',
354        },
355        Count   => 2,
356        Success => 1,
357    },
358    {
359        Name   => 'AppointmentList - Before appointments',
360        Config => {
361            CalendarID => $Calendar{CalendarID},
362            EndTime    => '2015-12-31 00:00:00',
363        },
364        Count   => 0,
365        Success => 1,
366    },
367    {
368        Name   => 'AppointmentList - After appointments',
369        Config => {
370            CalendarID => $Calendar{CalendarID},
371            StartTime  => '2016-01-04 00:00:00',
372        },
373        Count   => 0,
374        Success => 1,
375    },
376    {
377        Name   => 'AppointmentList - Title search',
378        Config => {
379            CalendarID => $Calendar{CalendarID},
380            Title      => "Appointment*-$RandomID",    # wildcard
381        },
382        Count   => 2,
383        Success => 1,
384    },
385    {
386        Name   => 'AppointmentList - Description search',
387        Config => {
388            CalendarID  => $Calendar{CalendarID},
389            Description => 'foobar',                   # non-existent
390        },
391        Count   => 0,
392        Success => 1,
393    },
394    {
395        Name   => 'AppointmentList - Location search',
396        Config => {
397            CalendarID => $Calendar{CalendarID},
398            Location   => 'usa',                       # lowercase
399        },
400        Count   => 1,
401        Success => 1,
402    },
403);
404
405for my $Test (@Tests) {
406
407    # make the call
408    my @Appointments = $AppointmentObject->AppointmentList(
409        %{ $Test->{Config} },
410    );
411
412    if ( $Test->{Success} ) {
413        $Self->Is(
414            scalar @Appointments,
415            $Test->{Count},
416            "$Test->{Name} - Result count",
417        );
418
419        if ( $Test->{Config}->{Result} && $Test->{Config}->{Result} eq 'ARRAY' ) {
420
421        }
422        else {
423            for my $Appointment (@Appointments) {
424                for my $Key (qw(AppointmentID CalendarID UniqueID Title StartTime EndTime)) {
425                    $Self->True(
426                        $Appointment->{$Key},
427                        "$Test->{Name} - $Key exists",
428                    );
429                }
430            }
431        }
432    }
433    else {
434        $Self->IsDeeply(
435            \@Appointments,
436            [],
437            "$Test->{Name} - No success",
438        );
439    }
440}
441
442#
443# Tests for recurring appointments
444#
445@Tests = (
446    {
447        Name   => 'Recurring - Once per day',
448        Config => {
449            CalendarID         => $Calendar{CalendarID},
450            Title              => 'Recurring appointment',
451            StartTime          => '2016-03-01 16:00:00',
452            EndTime            => '2016-03-01 17:00:00',
453            AllDay             => 1,
454            Recurring          => 1,
455            RecurrenceType     => 'Daily',
456            RecurrenceInterval => 1,                         # once per day
457            RecurrenceUntil    => '2016-03-06 00:00:00',     # included last day
458            UserID             => $UserID,
459        },
460        List => {
461            CalendarID => $Calendar{CalendarID},
462            StartTime  => '2016-03-01 00:00:00',
463            EndTime    => '2016-03-06 00:00:00',
464            Count      => 5,
465        },
466        Result => {
467            StartTime => [
468                '2016-03-01 16:00:00',
469                '2016-03-02 16:00:00',
470                '2016-03-03 16:00:00',
471                '2016-03-04 16:00:00',
472                '2016-03-05 16:00:00',
473            ],
474            EndTime => [
475                '2016-03-01 17:00:00',
476                '2016-03-02 17:00:00',
477                '2016-03-03 17:00:00',
478                '2016-03-04 17:00:00',
479                '2016-03-05 17:00:00',
480            ],
481        },
482        Success => 1,
483    },
484    {
485        Name   => 'Recurring - Once per month',
486        Config => {
487            CalendarID         => $Calendar{CalendarID},
488            Title              => 'Recurring appointment',
489            StartTime          => '2012-01-31 15:00:00',
490            EndTime            => '2012-01-31 16:00:00',
491            Recurring          => 1,
492            RecurrenceType     => 'Monthly',
493            RecurrenceInterval => 1,                         # once per month
494            RecurrenceUntil    => '2013-01-03 16:00:00',     # included last day
495            UserID             => $UserID,
496        },
497        List => {
498            CalendarID => $Calendar{CalendarID},
499            StartTime  => '2012-01-31 00:00:00',
500            EndTime    => '2013-01-04 00:00:00',
501            Count      => 12,
502        },
503        Result => {
504            StartTime => [
505                '2012-01-31 15:00:00',
506                '2012-02-29 15:00:00',
507                '2012-03-31 15:00:00',
508                '2012-04-30 15:00:00',
509                '2012-05-31 15:00:00',
510                '2012-06-30 15:00:00',
511                '2012-07-31 15:00:00',
512                '2012-08-31 15:00:00',
513                '2012-09-30 15:00:00',
514                '2012-10-31 15:00:00',
515                '2012-11-30 15:00:00',
516                '2012-12-31 15:00:00',
517            ],
518            EndTime => [
519                '2012-01-31 16:00:00',
520                '2012-02-29 16:00:00',
521                '2012-03-31 16:00:00',
522                '2012-04-30 16:00:00',
523                '2012-05-31 16:00:00',
524                '2012-06-30 16:00:00',
525                '2012-07-31 16:00:00',
526                '2012-08-31 16:00:00',
527                '2012-09-30 16:00:00',
528                '2012-10-31 16:00:00',
529                '2012-11-30 16:00:00',
530                '2012-12-31 16:00:00',
531            ],
532        },
533        Success => 1,
534    },
535    {
536        Name   => 'Recurring - Every month all-day per month',
537        Config => {
538            CalendarID      => $Calendar{CalendarID},
539            Title           => 'Recurring appointment',
540            StartTime       => '2008-04-30 00:00:00',
541            EndTime         => '2008-05-01 00:00:00',
542            AllDay          => 1,
543            Recurring       => 1,
544            RecurrenceType  => 'Monthly',
545            RecurrenceCount => 3,
546            UserID          => $UserID,
547        },
548        List => {
549            CalendarID => $Calendar{CalendarID},
550            StartTime  => '2008-04-30 00:00:00',
551            EndTime    => '2008-07-01 00:00:00',
552            Count      => 3,
553        },
554        Result => {
555            StartTime => [
556                '2008-04-30 00:00:00',    # on some systems with older date time library
557                '2008-05-30 00:00:00',    # there will be an appointment on 2008-05-31
558                '2008-06-30 00:00:00',    # but not on 2008-06-30
559            ],
560            EndTime => [
561                '2008-05-01 00:00:00',
562                '2008-05-31 00:00:00',
563                '2008-07-01 00:00:00',
564            ],
565        },
566        Success => 1,
567    },
568    {
569        Name   => 'Recurring - Missing RecurrenceType',
570        Config => {
571            CalendarID         => $Calendar{CalendarID},
572            Title              => 'Recurring appointment',
573            StartTime          => '2016-03-01 16:00:00',
574            EndTime            => '2016-03-01 17:00:00',
575            AllDay             => 1,
576            Recurring          => 1,
577            RecurrenceInterval => 1,
578            RecurrenceUntil    => '2016-03-06 00:00:00',
579            UserID             => $UserID,
580        },
581        Success => 0,
582    },
583    {
584        Name   => 'Recurring - Wrong RecurrenceType',
585        Config => {
586            CalendarID         => $Calendar{CalendarID},
587            Title              => 'Recurring appointment',
588            StartTime          => '2016-03-01 16:00:00',
589            EndTime            => '2016-03-01 17:00:00',
590            AllDay             => 1,
591            Recurring          => 1,
592            RecurrenceType     => 'WrongDaily',              # WrongDaily is not supported
593            RecurrenceInterval => 1,
594            RecurrenceUntil    => '2016-03-06 00:00:00',
595            UserID             => $UserID,
596        },
597        Success => 0,
598    },
599    {
600        Name   => 'Recurring - Without RecurrenceFrequency',
601        Config => {
602            CalendarID         => $Calendar{CalendarID},
603            Title              => 'Recurring appointment',
604            StartTime          => '2018-03-01 16:00:00',
605            EndTime            => '2018-03-01 17:00:00',
606            AllDay             => 1,
607            Recurring          => 1,
608            RecurrenceType     => 'CustomDaily',
609            RecurrenceInterval => 1,
610            RecurrenceCount    => 2,
611            UserID             => $UserID,
612        },
613        List => {
614            CalendarID => $Calendar{CalendarID},
615            StartTime  => '2018-03-01 00:00:00',
616            EndTime    => '2018-03-03 00:00:00',
617            Count      => 2,
618        },
619        Result => {
620            StartTime => [
621                '2018-03-01 16:00:00',
622                '2018-03-02 16:00:00',
623            ],
624            EndTime => [
625                '2018-03-01 17:00:00',
626                '2018-03-02 17:00:00',
627            ],
628        },
629        Success => 1,
630    },
631    {
632        Name   => 'Recurring - Missing RecurrenceFrequency (CustomWeekly)',
633        Config => {
634            CalendarID         => $Calendar{CalendarID},
635            Title              => 'Recurring appointment',
636            StartTime          => '2016-03-01 16:00:00',
637            EndTime            => '2016-03-01 17:00:00',
638            AllDay             => 1,
639            Recurring          => 1,
640            RecurrenceType     => 'CustomWeekly',
641            RecurrenceInterval => 1,
642            RecurrenceUntil    => '2016-03-06 00:00:00',
643            UserID             => $UserID,
644        },
645        Success => 0,
646    },
647    {
648        Name   => 'Recurring - Missing RecurrenceFrequency (CustomMonthly)',
649        Config => {
650            CalendarID         => $Calendar{CalendarID},
651            Title              => 'Recurring appointment',
652            StartTime          => '2016-03-01 16:00:00',
653            EndTime            => '2016-03-01 17:00:00',
654            AllDay             => 1,
655            Recurring          => 1,
656            RecurrenceType     => 'CustomMonthly',
657            RecurrenceInterval => 1,
658            RecurrenceUntil    => '2016-03-06 00:00:00',
659            UserID             => $UserID,
660        },
661        Success => 0,
662    },
663    {
664        Name   => 'Recurring - Missing RecurrenceFrequency (CustomYearly)',
665        Config => {
666            CalendarID         => $Calendar{CalendarID},
667            Title              => 'Recurring appointment',
668            StartTime          => '2016-03-01 16:00:00',
669            EndTime            => '2016-03-01 17:00:00',
670            AllDay             => 1,
671            Recurring          => 1,
672            RecurrenceType     => 'CustomYearly',
673            RecurrenceInterval => 1,
674            RecurrenceUntil    => '2016-03-06 00:00:00',
675            UserID             => $UserID,
676        },
677        Success => 0,
678    },
679    {
680        Name   => 'Recurring - Once per week',
681        Config => {
682            CalendarID         => $Calendar{CalendarID},
683            Title              => 'Weekly recurring appointment',
684            StartTime          => '2016-10-01 16:00:00',
685            EndTime            => '2016-10-01 17:00:00',
686            AllDay             => 1,
687            Recurring          => 1,
688            RecurrenceType     => 'Weekly',
689            RecurrenceInterval => 1,                                # each week
690            RecurrenceUntil    => '2016-10-06 00:00:00',            # included last day
691            UserID             => $UserID,
692        },
693        List => {
694            CalendarID => $Calendar{CalendarID},
695            StartTime  => '2016-10-01 00:00:00',
696            EndTime    => '2016-10-07 00:00:00',
697            Count      => 1,
698        },
699        Result => {
700            StartTime => [
701                '2016-10-01 16:00:00',
702            ],
703            EndTime => [
704                '2016-10-01 17:00:00',
705            ],
706        },
707        Success => 1,
708    },
709    {
710        Name   => 'Recurring - Once per month',
711        Config => {
712            CalendarID         => $Calendar{CalendarID},
713            Title              => 'Monthly recurring appointment',
714            StartTime          => '2016-10-07 16:00:00',
715            EndTime            => '2016-10-07 17:00:00',
716            AllDay             => 1,
717            Recurring          => 1,
718            RecurrenceType     => 'Monthly',
719            RecurrenceInterval => 1,                                 # each month
720            RecurrenceCount    => 3,                                 # 3 months
721            UserID             => $UserID,
722        },
723        List => {
724            CalendarID => $Calendar{CalendarID},
725            StartTime  => '2016-10-07 00:00:00',
726            EndTime    => '2017-01-08 00:00:00',
727            Count      => 3,
728        },
729        Result => {
730            StartTime => [
731                '2016-10-07 16:00:00',
732                '2016-11-07 16:00:00',
733                '2016-12-07 16:00:00',
734            ],
735            EndTime => [
736                '2016-10-07 17:00:00',
737                '2016-11-07 17:00:00',
738                '2016-12-07 17:00:00',
739            ],
740        },
741        Success => 1,
742    },
743    {
744        Name   => 'Recurring - Once per year',
745        Config => {
746            CalendarID         => $Calendar{CalendarID},
747            Title              => 'Yearly recurring appointment',
748            StartTime          => '2027-10-10 16:00:00',
749            EndTime            => '2027-10-10 17:00:00',
750            AllDay             => 1,
751            Recurring          => 1,
752            RecurrenceType     => 'Yearly',
753            RecurrenceInterval => 1,                                # each year
754            RecurrenceCount    => 3,                                # 3 years
755            UserID             => $UserID,
756        },
757        List => {
758            CalendarID => $Calendar{CalendarID},
759            StartTime  => '2027-10-10 00:00:00',
760            EndTime    => '2030-10-11 00:00:00',
761            Count      => 3,
762        },
763        Result => {
764            StartTime => [
765                '2027-10-10 16:00:00',
766                '2028-10-10 16:00:00',
767                '2029-10-10 16:00:00',
768            ],
769            EndTime => [
770                '2027-10-10 17:00:00',
771                '2028-10-10 17:00:00',
772                '2029-10-10 17:00:00',
773            ],
774        },
775        Success => 1,
776    },
777    {
778        Name   => 'Recurring - Every two days',
779        Config => {
780            CalendarID         => $Calendar{CalendarID},
781            Title              => 'Custom daily recurring appointment',
782            Description        => 'Description',
783            Location           => 'Germany',
784            StartTime          => '2017-01-01 16:00:00',
785            EndTime            => '2017-01-01 17:00:00',
786            AllDay             => 1,
787            Recurring          => 1,
788            RecurrenceType     => 'CustomDaily',
789            RecurrenceInterval => 2,
790            RecurrenceCount    => 3,                                      # 3 appointments
791            UserID             => $UserID,
792        },
793        List => {
794            CalendarID => $Calendar{CalendarID},
795            StartTime  => '2017-01-01 00:00:00',
796            EndTime    => '2017-01-06 00:00:00',
797            Count      => 3,
798        },
799        Result => {
800            StartTime => [
801                '2017-01-01 16:00:00',
802                '2017-01-03 16:00:00',
803                '2017-01-05 16:00:00',
804            ],
805            EndTime => [
806                '2017-01-01 17:00:00',
807                '2017-01-03 17:00:00',
808                '2017-01-05 17:00:00',
809            ],
810        },
811        Success => 1,
812    },
813    {
814        Name   => 'Recurring - On Wednesday, recurring every two weeks on Monday and Friday',
815        Config => {
816            CalendarID          => $Calendar{CalendarID},
817            Title               => 'Custom weekly recurring appointment',
818            StartTime           => '2016-05-04 16:00:00',                   # wednesday
819            EndTime             => '2016-05-04 17:00:00',
820            AllDay              => 1,
821            Recurring           => 1,
822            RecurrenceType      => 'CustomWeekly',
823            RecurrenceInterval  => 2,                                       # each 2nd
824            RecurrenceFrequency => [ 1, 5 ],                                # Monday and Friday
825            RecurrenceCount     => 3,                                       # 3 appointments
826            UserID              => $UserID,
827        },
828        List => {
829            CalendarID => $Calendar{CalendarID},
830            StartTime  => '2016-05-04 00:00:00',
831            EndTime    => '2016-05-28 00:00:00',
832            Count      => 3,
833        },
834        Result => {
835            StartTime => [
836                '2016-05-04 16:00:00',
837                '2016-05-06 16:00:00',
838                '2016-05-16 16:00:00',
839            ],
840            EndTime => [
841                '2016-05-04 17:00:00',
842                '2016-05-06 17:00:00',
843                '2016-05-16 17:00:00',
844            ],
845        },
846        Success => 1,
847    },
848    {
849        Name   => 'Recurring - Every 2nd month on 5th, 10th and 15th day',
850        Config => {
851            CalendarID          => $Calendar{CalendarID},
852            Title               => 'Custom monthly recurring appointment',
853            StartTime           => '2019-07-05 16:00:00',
854            EndTime             => '2019-07-05 17:00:00',
855            AllDay              => 1,
856            Recurring           => 1,
857            RecurrenceType      => "CustomMonthly",
858            RecurrenceInterval  => 2,                                        # every 2 months
859            RecurrenceFrequency => [ 5, 10, 15 ],                            # days in month
860            RecurrenceCount     => 6,                                        # 3 appointments
861            UserID              => $UserID,
862        },
863        List => {
864            CalendarID => $Calendar{CalendarID},
865            StartTime  => '2019-07-05 00:00:00',
866            EndTime    => '2019-10-16 00:00:00',
867            Count      => 6,
868        },
869        Result => {
870            StartTime => [
871                '2019-07-05 16:00:00',
872                '2019-07-10 16:00:00',
873                '2019-07-15 16:00:00',
874                '2019-09-05 16:00:00',
875                '2019-09-10 16:00:00',
876                '2019-09-15 16:00:00',
877            ],
878            EndTime => [
879                '2019-07-05 17:00:00',
880                '2019-07-10 17:00:00',
881                '2019-07-15 17:00:00',
882                '2019-09-05 17:00:00',
883                '2019-09-10 17:00:00',
884                '2019-09-15 17:00:00',
885            ],
886        },
887        Success => 1,
888    },
889    {
890        Name   => 'Recurring - Every 2nd year on January 5th, February and December',
891        Config => {
892            CalendarID          => $Calendar{CalendarID},
893            Title               => 'Custom yearly recurring appointment',
894            StartTime           => '2022-01-05 16:00:00',
895            EndTime             => '2022-01-05 17:00:00',
896            AllDay              => 1,
897            Recurring           => 1,
898            RecurrenceType      => 'CustomYearly',
899            RecurrenceInterval  => 2,                                       # every 2 years
900            RecurrenceFrequency => [ 1, 2, 12 ],                            # months
901            RecurrenceCount     => 3,                                       # 3 appointments
902            UserID              => $UserID,
903        },
904        List => {
905            CalendarID => $Calendar{CalendarID},
906            StartTime  => '2022-01-05 00:00:00',
907            EndTime    => '2024-12-06 00:00:00',
908            Count      => 3,
909        },
910        Result => {
911            StartTime => [
912                '2022-01-05 16:00:00',
913                '2022-02-05 16:00:00',
914                '2022-12-05 16:00:00',
915            ],
916            EndTime => [
917                '2022-01-05 17:00:00',
918                '2022-02-05 17:00:00',
919                '2022-12-05 17:00:00',
920            ],
921        },
922        Success => 1,
923    },
924    {
925        Name   => 'Recurring - Every 2 weeks, on Mon, Wed, Thu, Fri and Sun',
926        Config => {
927            CalendarID          => $Calendar{CalendarID},
928            Title               => 'Custom recurring appointment',
929            Description         => 'Description',
930            StartTime           => '2025-09-01 00:00:00',
931            EndTime             => '2025-09-01 00:00:00',
932            AllDay              => 1,
933            Recurring           => 1,
934            RecurrenceType      => 'CustomWeekly',
935            RecurrenceInterval  => 2,                                # each 2 weeks
936            RecurrenceFrequency => [ 1, 3, 4, 5, 7 ],                # Mon, Wed, Thu, Fri, Sun
937            RecurrenceUntil     => '2026-10-01 00:00:00',            # october
938            UserID              => $UserID,
939        },
940        List => {
941            CalendarID => $Calendar{CalendarID},
942            StartTime  => '2025-09-01 00:00:00',
943            EndTime    => '2026-10-13 00:00:00',
944            Count      => 143,
945        },
946        Result => {
947            StartTime => [
948                '2025-09-01 00:00:00',
949                '2025-09-03 00:00:00',
950                '2025-09-04 00:00:00',
951                '2025-09-05 00:00:00',
952                '2025-09-07 00:00:00',
953                '2025-09-15 00:00:00',
954                '2025-09-17 00:00:00',
955                '2025-09-18 00:00:00',
956                '2025-09-19 00:00:00',
957                '2025-09-21 00:00:00',
958                '2025-09-29 00:00:00',
959                '2025-10-01 00:00:00',
960                '2025-10-02 00:00:00',
961                '2025-10-03 00:00:00',
962                '2025-10-05 00:00:00',
963                '2025-10-13 00:00:00',
964                '2025-10-15 00:00:00',
965                '2025-10-16 00:00:00',
966                '2025-10-17 00:00:00',
967                '2025-10-19 00:00:00',
968                '2025-10-27 00:00:00',
969                '2025-10-29 00:00:00',
970                '2025-10-30 00:00:00',
971                '2025-10-31 00:00:00',
972                '2025-11-02 00:00:00',
973                '2025-11-10 00:00:00',
974                '2025-11-12 00:00:00',
975                '2025-11-13 00:00:00',
976                '2025-11-14 00:00:00',
977                '2025-11-16 00:00:00',
978                '2025-11-24 00:00:00',
979                '2025-11-26 00:00:00',
980                '2025-11-27 00:00:00',
981                '2025-11-28 00:00:00',
982                '2025-11-30 00:00:00',
983                '2025-12-08 00:00:00',
984                '2025-12-10 00:00:00',
985                '2025-12-11 00:00:00',
986                '2025-12-12 00:00:00',
987                '2025-12-14 00:00:00',
988                '2025-12-22 00:00:00',
989                '2025-12-24 00:00:00',
990                '2025-12-25 00:00:00',
991                '2025-12-26 00:00:00',
992                '2025-12-28 00:00:00',
993                '2026-01-05 00:00:00',
994                '2026-01-07 00:00:00',
995                '2026-01-08 00:00:00',
996                '2026-01-09 00:00:00',
997                '2026-01-11 00:00:00',
998                '2026-01-19 00:00:00',
999                '2026-01-21 00:00:00',
1000                '2026-01-22 00:00:00',
1001                '2026-01-23 00:00:00',
1002                '2026-01-25 00:00:00',
1003                '2026-02-02 00:00:00',
1004                '2026-02-04 00:00:00',
1005                '2026-02-05 00:00:00',
1006                '2026-02-06 00:00:00',
1007                '2026-02-08 00:00:00',
1008                '2026-02-16 00:00:00',
1009                '2026-02-18 00:00:00',
1010                '2026-02-19 00:00:00',
1011                '2026-02-20 00:00:00',
1012                '2026-02-22 00:00:00',
1013                '2026-03-02 00:00:00',
1014                '2026-03-04 00:00:00',
1015                '2026-03-05 00:00:00',
1016                '2026-03-06 00:00:00',
1017                '2026-03-08 00:00:00',
1018                '2026-03-16 00:00:00',
1019                '2026-03-18 00:00:00',
1020                '2026-03-19 00:00:00',
1021                '2026-03-20 00:00:00',
1022                '2026-03-22 00:00:00',
1023                '2026-03-30 00:00:00',
1024                '2026-04-01 00:00:00',
1025                '2026-04-02 00:00:00',
1026                '2026-04-03 00:00:00',
1027                '2026-04-05 00:00:00',
1028                '2026-04-13 00:00:00',
1029                '2026-04-15 00:00:00',
1030                '2026-04-16 00:00:00',
1031                '2026-04-17 00:00:00',
1032                '2026-04-19 00:00:00',
1033                '2026-04-27 00:00:00',
1034                '2026-04-29 00:00:00',
1035                '2026-04-30 00:00:00',
1036                '2026-05-01 00:00:00',
1037                '2026-05-03 00:00:00',
1038                '2026-05-11 00:00:00',
1039                '2026-05-13 00:00:00',
1040                '2026-05-14 00:00:00',
1041                '2026-05-15 00:00:00',
1042                '2026-05-17 00:00:00',
1043                '2026-05-25 00:00:00',
1044                '2026-05-27 00:00:00',
1045                '2026-05-28 00:00:00',
1046                '2026-05-29 00:00:00',
1047                '2026-05-31 00:00:00',
1048                '2026-06-08 00:00:00',
1049                '2026-06-10 00:00:00',
1050                '2026-06-11 00:00:00',
1051                '2026-06-12 00:00:00',
1052                '2026-06-14 00:00:00',
1053                '2026-06-22 00:00:00',
1054                '2026-06-24 00:00:00',
1055                '2026-06-25 00:00:00',
1056                '2026-06-26 00:00:00',
1057                '2026-06-28 00:00:00',
1058                '2026-07-06 00:00:00',
1059                '2026-07-08 00:00:00',
1060                '2026-07-09 00:00:00',
1061                '2026-07-10 00:00:00',
1062                '2026-07-12 00:00:00',
1063                '2026-07-20 00:00:00',
1064                '2026-07-22 00:00:00',
1065                '2026-07-23 00:00:00',
1066                '2026-07-24 00:00:00',
1067                '2026-07-26 00:00:00',
1068                '2026-08-03 00:00:00',
1069                '2026-08-05 00:00:00',
1070                '2026-08-06 00:00:00',
1071                '2026-08-07 00:00:00',
1072                '2026-08-09 00:00:00',
1073                '2026-08-17 00:00:00',
1074                '2026-08-19 00:00:00',
1075                '2026-08-20 00:00:00',
1076                '2026-08-21 00:00:00',
1077                '2026-08-23 00:00:00',
1078                '2026-08-31 00:00:00',
1079                '2026-09-02 00:00:00',
1080                '2026-09-03 00:00:00',
1081                '2026-09-04 00:00:00',
1082                '2026-09-06 00:00:00',
1083                '2026-09-14 00:00:00',
1084                '2026-09-16 00:00:00',
1085                '2026-09-17 00:00:00',
1086                '2026-09-18 00:00:00',
1087                '2026-09-20 00:00:00',
1088                '2026-09-28 00:00:00',
1089                '2026-09-30 00:00:00',
1090                '2026-10-01 00:00:00',
1091            ],
1092            EndTime => [
1093                '2025-09-01 00:00:00',
1094                '2025-09-03 00:00:00',
1095                '2025-09-04 00:00:00',
1096                '2025-09-05 00:00:00',
1097                '2025-09-07 00:00:00',
1098                '2025-09-15 00:00:00',
1099                '2025-09-17 00:00:00',
1100                '2025-09-18 00:00:00',
1101                '2025-09-19 00:00:00',
1102                '2025-09-21 00:00:00',
1103                '2025-09-29 00:00:00',
1104                '2025-10-01 00:00:00',
1105                '2025-10-02 00:00:00',
1106                '2025-10-03 00:00:00',
1107                '2025-10-05 00:00:00',
1108                '2025-10-13 00:00:00',
1109                '2025-10-15 00:00:00',
1110                '2025-10-16 00:00:00',
1111                '2025-10-17 00:00:00',
1112                '2025-10-19 00:00:00',
1113                '2025-10-27 00:00:00',
1114                '2025-10-29 00:00:00',
1115                '2025-10-30 00:00:00',
1116                '2025-10-31 00:00:00',
1117                '2025-11-02 00:00:00',
1118                '2025-11-10 00:00:00',
1119                '2025-11-12 00:00:00',
1120                '2025-11-13 00:00:00',
1121                '2025-11-14 00:00:00',
1122                '2025-11-16 00:00:00',
1123                '2025-11-24 00:00:00',
1124                '2025-11-26 00:00:00',
1125                '2025-11-27 00:00:00',
1126                '2025-11-28 00:00:00',
1127                '2025-11-30 00:00:00',
1128                '2025-12-08 00:00:00',
1129                '2025-12-10 00:00:00',
1130                '2025-12-11 00:00:00',
1131                '2025-12-12 00:00:00',
1132                '2025-12-14 00:00:00',
1133                '2025-12-22 00:00:00',
1134                '2025-12-24 00:00:00',
1135                '2025-12-25 00:00:00',
1136                '2025-12-26 00:00:00',
1137                '2025-12-28 00:00:00',
1138                '2026-01-05 00:00:00',
1139                '2026-01-07 00:00:00',
1140                '2026-01-08 00:00:00',
1141                '2026-01-09 00:00:00',
1142                '2026-01-11 00:00:00',
1143                '2026-01-19 00:00:00',
1144                '2026-01-21 00:00:00',
1145                '2026-01-22 00:00:00',
1146                '2026-01-23 00:00:00',
1147                '2026-01-25 00:00:00',
1148                '2026-02-02 00:00:00',
1149                '2026-02-04 00:00:00',
1150                '2026-02-05 00:00:00',
1151                '2026-02-06 00:00:00',
1152                '2026-02-08 00:00:00',
1153                '2026-02-16 00:00:00',
1154                '2026-02-18 00:00:00',
1155                '2026-02-19 00:00:00',
1156                '2026-02-20 00:00:00',
1157                '2026-02-22 00:00:00',
1158                '2026-03-02 00:00:00',
1159                '2026-03-04 00:00:00',
1160                '2026-03-05 00:00:00',
1161                '2026-03-06 00:00:00',
1162                '2026-03-08 00:00:00',
1163                '2026-03-16 00:00:00',
1164                '2026-03-18 00:00:00',
1165                '2026-03-19 00:00:00',
1166                '2026-03-20 00:00:00',
1167                '2026-03-22 00:00:00',
1168                '2026-03-30 00:00:00',
1169                '2026-04-01 00:00:00',
1170                '2026-04-02 00:00:00',
1171                '2026-04-03 00:00:00',
1172                '2026-04-05 00:00:00',
1173                '2026-04-13 00:00:00',
1174                '2026-04-15 00:00:00',
1175                '2026-04-16 00:00:00',
1176                '2026-04-17 00:00:00',
1177                '2026-04-19 00:00:00',
1178                '2026-04-27 00:00:00',
1179                '2026-04-29 00:00:00',
1180                '2026-04-30 00:00:00',
1181                '2026-05-01 00:00:00',
1182                '2026-05-03 00:00:00',
1183                '2026-05-11 00:00:00',
1184                '2026-05-13 00:00:00',
1185                '2026-05-14 00:00:00',
1186                '2026-05-15 00:00:00',
1187                '2026-05-17 00:00:00',
1188                '2026-05-25 00:00:00',
1189                '2026-05-27 00:00:00',
1190                '2026-05-28 00:00:00',
1191                '2026-05-29 00:00:00',
1192                '2026-05-31 00:00:00',
1193                '2026-06-08 00:00:00',
1194                '2026-06-10 00:00:00',
1195                '2026-06-11 00:00:00',
1196                '2026-06-12 00:00:00',
1197                '2026-06-14 00:00:00',
1198                '2026-06-22 00:00:00',
1199                '2026-06-24 00:00:00',
1200                '2026-06-25 00:00:00',
1201                '2026-06-26 00:00:00',
1202                '2026-06-28 00:00:00',
1203                '2026-07-06 00:00:00',
1204                '2026-07-08 00:00:00',
1205                '2026-07-09 00:00:00',
1206                '2026-07-10 00:00:00',
1207                '2026-07-12 00:00:00',
1208                '2026-07-20 00:00:00',
1209                '2026-07-22 00:00:00',
1210                '2026-07-23 00:00:00',
1211                '2026-07-24 00:00:00',
1212                '2026-07-26 00:00:00',
1213                '2026-08-03 00:00:00',
1214                '2026-08-05 00:00:00',
1215                '2026-08-06 00:00:00',
1216                '2026-08-07 00:00:00',
1217                '2026-08-09 00:00:00',
1218                '2026-08-17 00:00:00',
1219                '2026-08-19 00:00:00',
1220                '2026-08-20 00:00:00',
1221                '2026-08-21 00:00:00',
1222                '2026-08-23 00:00:00',
1223                '2026-08-31 00:00:00',
1224                '2026-09-02 00:00:00',
1225                '2026-09-03 00:00:00',
1226                '2026-09-04 00:00:00',
1227                '2026-09-06 00:00:00',
1228                '2026-09-14 00:00:00',
1229                '2026-09-16 00:00:00',
1230                '2026-09-17 00:00:00',
1231                '2026-09-18 00:00:00',
1232                '2026-09-20 00:00:00',
1233                '2026-09-28 00:00:00',
1234                '2026-09-30 00:00:00',
1235                '2026-10-01 00:00:00',
1236            ],
1237        },
1238        Success => 1,
1239    },
1240    {
1241        Name   => 'Recurring - On Tuesday and Friday, recurring every five weeks.',
1242        Config => {
1243            CalendarID          => $Calendar{CalendarID},
1244            Title               => 'Custom weekly recurring appointment',
1245            StartTime           => '2016-09-04 16:00:00',
1246            EndTime             => '2016-09-04 17:00:00',
1247            AllDay              => 1,
1248            Recurring           => 1,
1249            RecurrenceType      => 'CustomWeekly',
1250            RecurrenceInterval  => 5,                                       # each 5th week
1251            RecurrenceFrequency => [ 2, 5 ],                                # Tuesday and Friday
1252            RecurrenceUntil     => '2021-12-31 23:59:00',
1253            UserID              => $UserID,
1254        },
1255        List => {
1256            CalendarID => $Calendar{CalendarID},
1257            StartTime  => '2016-09-04 00:00:00',
1258            EndTime    => '2022-02-01 00:00:00',
1259            Count      => 127,
1260        },
1261        Result => {
1262            StartTime => [
1263
1264                # dates from previous tests
1265                '2018-03-01 16:00:00',
1266                '2018-03-02 16:00:00',
1267                '2016-10-01 16:00:00',
1268                '2016-10-07 16:00:00',
1269                '2016-11-07 16:00:00',
1270                '2016-12-07 16:00:00',
1271                '2017-01-01 16:00:00',
1272                '2017-01-03 16:00:00',
1273                '2017-01-05 16:00:00',
1274                '2019-07-05 16:00:00',
1275                '2019-07-10 16:00:00',
1276                '2019-07-15 16:00:00',
1277                '2019-09-05 16:00:00',
1278                '2019-09-10 16:00:00',
1279                '2019-09-15 16:00:00',
1280                '2022-01-05 16:00:00',
1281
1282                # here comes dates from this test
1283                '2016-09-04 16:00:00',
1284                '2016-10-04 16:00:00',
1285                '2016-10-07 16:00:00',
1286                '2016-11-08 16:00:00',
1287                '2016-11-11 16:00:00',
1288                '2016-12-13 16:00:00',
1289                '2016-12-16 16:00:00',
1290                '2017-01-17 16:00:00',
1291                '2017-01-20 16:00:00',
1292                '2017-02-21 16:00:00',
1293                '2017-02-24 16:00:00',
1294                '2017-03-28 16:00:00',
1295                '2017-03-31 16:00:00',
1296                '2017-05-02 16:00:00',
1297                '2017-05-05 16:00:00',
1298                '2017-06-06 16:00:00',
1299                '2017-06-09 16:00:00',
1300                '2017-07-11 16:00:00',
1301                '2017-07-14 16:00:00',
1302                '2017-08-15 16:00:00',
1303                '2017-08-18 16:00:00',
1304                '2017-09-19 16:00:00',
1305                '2017-09-22 16:00:00',
1306                '2017-10-24 16:00:00',
1307                '2017-10-27 16:00:00',
1308                '2017-11-28 16:00:00',
1309                '2017-12-01 16:00:00',
1310                '2018-01-02 16:00:00',
1311                '2018-01-05 16:00:00',
1312                '2018-02-06 16:00:00',
1313                '2018-02-09 16:00:00',
1314                '2018-03-13 16:00:00',
1315                '2018-03-16 16:00:00',
1316                '2018-04-17 16:00:00',
1317                '2018-04-20 16:00:00',
1318                '2018-05-22 16:00:00',
1319                '2018-05-25 16:00:00',
1320                '2018-06-26 16:00:00',
1321                '2018-06-29 16:00:00',
1322                '2018-07-31 16:00:00',
1323                '2018-08-03 16:00:00',
1324                '2018-09-04 16:00:00',
1325                '2018-09-07 16:00:00',
1326                '2018-10-09 16:00:00',
1327                '2018-10-12 16:00:00',
1328                '2018-11-13 16:00:00',
1329                '2018-11-16 16:00:00',
1330                '2018-12-18 16:00:00',
1331                '2018-12-21 16:00:00',
1332                '2019-01-22 16:00:00',
1333                '2019-01-25 16:00:00',
1334                '2019-02-26 16:00:00',
1335                '2019-03-01 16:00:00',
1336                '2019-04-02 16:00:00',
1337                '2019-04-05 16:00:00',
1338                '2019-05-07 16:00:00',
1339                '2019-05-10 16:00:00',
1340                '2019-06-11 16:00:00',
1341                '2019-06-14 16:00:00',
1342                '2019-07-16 16:00:00',
1343                '2019-07-19 16:00:00',
1344                '2019-08-20 16:00:00',
1345                '2019-08-23 16:00:00',
1346                '2019-09-24 16:00:00',
1347                '2019-09-27 16:00:00',
1348                '2019-10-29 16:00:00',
1349                '2019-11-01 16:00:00',
1350                '2019-12-03 16:00:00',
1351                '2019-12-06 16:00:00',
1352                '2020-01-07 16:00:00',
1353                '2020-01-10 16:00:00',
1354                '2020-02-11 16:00:00',
1355                '2020-02-14 16:00:00',
1356                '2020-03-17 16:00:00',
1357                '2020-03-20 16:00:00',
1358                '2020-04-21 16:00:00',
1359                '2020-04-24 16:00:00',
1360                '2020-05-26 16:00:00',
1361                '2020-05-29 16:00:00',
1362                '2020-06-30 16:00:00',
1363                '2020-07-03 16:00:00',
1364                '2020-08-04 16:00:00',
1365                '2020-08-07 16:00:00',
1366                '2020-09-08 16:00:00',
1367                '2020-09-11 16:00:00',
1368                '2020-10-13 16:00:00',
1369                '2020-10-16 16:00:00',
1370                '2020-11-17 16:00:00',
1371                '2020-11-20 16:00:00',
1372                '2020-12-22 16:00:00',
1373                '2020-12-25 16:00:00',
1374                '2021-01-26 16:00:00',
1375                '2021-01-29 16:00:00',
1376                '2021-03-02 16:00:00',
1377                '2021-03-05 16:00:00',
1378                '2021-04-06 16:00:00',
1379                '2021-04-09 16:00:00',
1380                '2021-05-11 16:00:00',
1381                '2021-05-14 16:00:00',
1382                '2021-06-15 16:00:00',
1383                '2021-06-18 16:00:00',
1384                '2021-07-20 16:00:00',
1385                '2021-07-23 16:00:00',
1386                '2021-08-24 16:00:00',
1387                '2021-08-27 16:00:00',
1388                '2021-09-28 16:00:00',
1389                '2021-10-01 16:00:00',
1390                '2021-11-02 16:00:00',
1391                '2021-11-05 16:00:00',
1392                '2021-12-07 16:00:00',
1393                '2021-12-10 16:00:00',
1394            ],
1395            EndTime => [
1396                '2018-03-01 17:00:00',
1397                '2018-03-02 17:00:00',
1398                '2016-10-01 17:00:00',
1399                '2016-10-07 17:00:00',
1400                '2016-11-07 17:00:00',
1401                '2016-12-07 17:00:00',
1402                '2017-01-01 17:00:00',
1403                '2017-01-03 17:00:00',
1404                '2017-01-05 17:00:00',
1405                '2019-07-05 17:00:00',
1406                '2019-07-10 17:00:00',
1407                '2019-07-15 17:00:00',
1408                '2019-09-05 17:00:00',
1409                '2019-09-10 17:00:00',
1410                '2019-09-15 17:00:00',
1411                '2022-01-05 17:00:00',
1412                '2016-09-04 17:00:00',
1413                '2016-10-04 17:00:00',
1414                '2016-10-07 17:00:00',
1415                '2016-11-08 17:00:00',
1416                '2016-11-11 17:00:00',
1417                '2016-12-13 17:00:00',
1418                '2016-12-16 17:00:00',
1419                '2017-01-17 17:00:00',
1420                '2017-01-20 17:00:00',
1421                '2017-02-21 17:00:00',
1422                '2017-02-24 17:00:00',
1423                '2017-03-28 17:00:00',
1424                '2017-03-31 17:00:00',
1425                '2017-05-02 17:00:00',
1426                '2017-05-05 17:00:00',
1427                '2017-06-06 17:00:00',
1428                '2017-06-09 17:00:00',
1429                '2017-07-11 17:00:00',
1430                '2017-07-14 17:00:00',
1431                '2017-08-15 17:00:00',
1432                '2017-08-18 17:00:00',
1433                '2017-09-19 17:00:00',
1434                '2017-09-22 17:00:00',
1435                '2017-10-24 17:00:00',
1436                '2017-10-27 17:00:00',
1437                '2017-11-28 17:00:00',
1438                '2017-12-01 17:00:00',
1439                '2018-01-02 17:00:00',
1440                '2018-01-05 17:00:00',
1441                '2018-02-06 17:00:00',
1442                '2018-02-09 17:00:00',
1443                '2018-03-13 17:00:00',
1444                '2018-03-16 17:00:00',
1445                '2018-04-17 17:00:00',
1446                '2018-04-20 17:00:00',
1447                '2018-05-22 17:00:00',
1448                '2018-05-25 17:00:00',
1449                '2018-06-26 17:00:00',
1450                '2018-06-29 17:00:00',
1451                '2018-07-31 17:00:00',
1452                '2018-08-03 17:00:00',
1453                '2018-09-04 17:00:00',
1454                '2018-09-07 17:00:00',
1455                '2018-10-09 17:00:00',
1456                '2018-10-12 17:00:00',
1457                '2018-11-13 17:00:00',
1458                '2018-11-16 17:00:00',
1459                '2018-12-18 17:00:00',
1460                '2018-12-21 17:00:00',
1461                '2019-01-22 17:00:00',
1462                '2019-01-25 17:00:00',
1463                '2019-02-26 17:00:00',
1464                '2019-03-01 17:00:00',
1465                '2019-04-02 17:00:00',
1466                '2019-04-05 17:00:00',
1467                '2019-05-07 17:00:00',
1468                '2019-05-10 17:00:00',
1469                '2019-06-11 17:00:00',
1470                '2019-06-14 17:00:00',
1471                '2019-07-16 17:00:00',
1472                '2019-07-19 17:00:00',
1473                '2019-08-20 17:00:00',
1474                '2019-08-23 17:00:00',
1475                '2019-09-24 17:00:00',
1476                '2019-09-27 17:00:00',
1477                '2019-10-29 17:00:00',
1478                '2019-11-01 17:00:00',
1479                '2019-12-03 17:00:00',
1480                '2019-12-06 17:00:00',
1481                '2020-01-07 17:00:00',
1482                '2020-01-10 17:00:00',
1483                '2020-02-11 17:00:00',
1484                '2020-02-14 17:00:00',
1485                '2020-03-17 17:00:00',
1486                '2020-03-20 17:00:00',
1487                '2020-04-21 17:00:00',
1488                '2020-04-24 17:00:00',
1489                '2020-05-26 17:00:00',
1490                '2020-05-29 17:00:00',
1491                '2020-06-30 17:00:00',
1492                '2020-07-03 17:00:00',
1493                '2020-08-04 17:00:00',
1494                '2020-08-07 17:00:00',
1495                '2020-09-08 17:00:00',
1496                '2020-09-11 17:00:00',
1497                '2020-10-13 17:00:00',
1498                '2020-10-16 17:00:00',
1499                '2020-11-17 17:00:00',
1500                '2020-11-20 17:00:00',
1501                '2020-12-22 17:00:00',
1502                '2020-12-25 17:00:00',
1503                '2021-01-26 17:00:00',
1504                '2021-01-29 17:00:00',
1505                '2021-03-02 17:00:00',
1506                '2021-03-05 17:00:00',
1507                '2021-04-06 17:00:00',
1508                '2021-04-09 17:00:00',
1509                '2021-05-11 17:00:00',
1510                '2021-05-14 17:00:00',
1511                '2021-06-15 17:00:00',
1512                '2021-06-18 17:00:00',
1513                '2021-07-20 17:00:00',
1514                '2021-07-23 17:00:00',
1515                '2021-08-24 17:00:00',
1516                '2021-08-27 17:00:00',
1517                '2021-09-28 17:00:00',
1518                '2021-10-01 17:00:00',
1519                '2021-11-02 17:00:00',
1520                '2021-11-05 17:00:00',
1521                '2021-12-07 17:00:00',
1522                '2021-12-10 17:00:00',
1523            ],
1524        },
1525        Success => 1,
1526    },
1527    {
1528        Name   => 'Recurring - 3 day appointment, Custom weekly(Mon, Wed) with until condition.',
1529        Config => {
1530            CalendarID          => $Calendar{CalendarID},
1531            Title               => 'Custom weekly recurring appointment',
1532            StartTime           => '2015-07-06 23:00:00',
1533            EndTime             => '2015-07-08 01:00:00',
1534            Recurring           => 1,
1535            RecurrenceType      => 'CustomWeekly',
1536            RecurrenceInterval  => 3,
1537            RecurrenceFrequency => [ 1, 3 ],
1538            RecurrenceUntil     => '2015-12-31 23:59:00',
1539            UserID              => $UserID,
1540        },
1541        List => {
1542            CalendarID => $Calendar{CalendarID},
1543            StartTime  => '2015-07-01 00:00:00',
1544            EndTime    => '2016-01-05 00:00:00',
1545            Count      => 20,
1546        },
1547        Result => {
1548            StartTime => [
1549
1550                # previous appointments
1551                '2016-01-01 16:00:00',
1552                '2016-01-03 16:00:00',
1553
1554                # new appointments
1555                '2015-07-06 23:00:00',
1556                '2015-07-08 23:00:00',
1557                '2015-07-27 23:00:00',
1558                '2015-07-29 23:00:00',
1559                '2015-08-17 23:00:00',
1560                '2015-08-19 23:00:00',
1561                '2015-09-07 23:00:00',
1562                '2015-09-09 23:00:00',
1563                '2015-09-28 23:00:00',
1564                '2015-09-30 23:00:00',
1565                '2015-10-19 23:00:00',
1566                '2015-10-21 23:00:00',
1567                '2015-11-09 23:00:00',
1568                '2015-11-11 23:00:00',
1569                '2015-11-30 23:00:00',
1570                '2015-12-02 23:00:00',
1571                '2015-12-21 23:00:00',
1572                '2015-12-23 23:00:00',
1573            ],
1574            EndTime => [
1575
1576                # previous appointments
1577                '2016-01-01 17:00:00',
1578                '2016-01-03 17:00:00',
1579
1580                # new appointments
1581                '2015-07-08 01:00:00',
1582                '2015-07-10 01:00:00',
1583                '2015-07-29 01:00:00',
1584                '2015-07-31 01:00:00',
1585                '2015-08-19 01:00:00',
1586                '2015-08-21 01:00:00',
1587                '2015-09-09 01:00:00',
1588                '2015-09-11 01:00:00',
1589                '2015-09-30 01:00:00',
1590                '2015-10-02 01:00:00',
1591                '2015-10-21 01:00:00',
1592                '2015-10-23 01:00:00',
1593                '2015-11-11 01:00:00',
1594                '2015-11-13 01:00:00',
1595                '2015-12-02 01:00:00',
1596                '2015-12-04 01:00:00',
1597                '2015-12-23 01:00:00',
1598                '2015-12-25 01:00:00',
1599            ],
1600        },
1601        Success => 1,
1602    },
1603    {
1604        Name   => 'Recurring - 3 day appointment, Custom weekly(Mon, Wed), 10 appointments.',
1605        Config => {
1606            CalendarID          => $Calendar{CalendarID},
1607            Title               => 'Custom weekly recurring appointment',
1608            StartTime           => '2014-07-06 23:00:00',
1609            EndTime             => '2014-07-08 01:00:00',
1610            Recurring           => 1,
1611            RecurrenceType      => 'CustomWeekly',
1612            RecurrenceCount     => 10,
1613            RecurrenceFrequency => [ 1, 3 ],
1614            UserID              => $UserID,
1615        },
1616        List => {
1617            CalendarID => $Calendar{CalendarID},
1618            StartTime  => '2014-07-01 00:00:00',
1619            EndTime    => '2015-01-05 00:00:00',
1620            Count      => 10,
1621        },
1622        Result => {
1623            StartTime => [
1624                '2014-07-06 23:00:00',
1625                '2014-07-07 23:00:00',
1626                '2014-07-09 23:00:00',
1627                '2014-07-14 23:00:00',
1628                '2014-07-16 23:00:00',
1629                '2014-07-21 23:00:00',
1630                '2014-07-23 23:00:00',
1631                '2014-07-28 23:00:00',
1632                '2014-07-30 23:00:00',
1633                '2014-08-04 23:00:00',
1634            ],
1635            EndTime => [
1636                '2014-07-08 01:00:00',
1637                '2014-07-09 01:00:00',
1638                '2014-07-11 01:00:00',
1639                '2014-07-16 01:00:00',
1640                '2014-07-18 01:00:00',
1641                '2014-07-23 01:00:00',
1642                '2014-07-25 01:00:00',
1643                '2014-07-30 01:00:00',
1644                '2014-08-01 01:00:00',
1645                '2014-08-06 01:00:00',
1646            ],
1647        },
1648        Success => 1,
1649    },
1650);
1651
1652for my $Test (@Tests) {
1653
1654    # make the call
1655    my $AppointmentID = $AppointmentObject->AppointmentCreate(
1656        %{ $Test->{Config} },
1657    );
1658
1659    if ( $Test->{Success} ) {
1660        $Self->True(
1661            $AppointmentID,
1662            "$Test->{Name} - Success",
1663        );
1664
1665        # check count
1666        my @Appointments = $AppointmentObject->AppointmentList(
1667            %{ $Test->{List} // {} },
1668        );
1669        $Self->Is(
1670            scalar @Appointments,
1671            $Test->{List}->{Count},
1672            "$Test->{Name} - List count",
1673        );
1674
1675        # check start times
1676        my @StartTimes;
1677        for my $Appointment (@Appointments) {
1678            push @StartTimes, $Appointment->{StartTime};
1679        }
1680        $Self->IsDeeply(
1681            \@StartTimes,
1682            $Test->{Result}->{StartTime},
1683            "$Test->{Name} - Start time result",
1684        );
1685
1686        # check end times
1687        my @EndTimes;
1688        for my $Appointment (@Appointments) {
1689            push @EndTimes, $Appointment->{EndTime};
1690        }
1691
1692        $Self->IsDeeply(
1693            \@EndTimes,
1694            $Test->{Result}->{EndTime},
1695            "$Test->{Name} - End time result",
1696        );
1697    }
1698    else {
1699        $Self->False(
1700            $AppointmentID,
1701            "$Test->{Name} - No success",
1702        );
1703    }
1704}
1705
1706#
1707# Tests for AppointmentDays()
1708#
1709@Tests = (
1710    {
1711        Name   => 'AppointmentDays - Missing UserID',
1712        Config => {
1713            StartTime => '2016-01-25 00:00:00',
1714            EndTime   => '2016-02-01 00:00:00',
1715        },
1716        Success => 0,
1717    },
1718    {
1719        Name   => 'AppointmentDays - January',
1720        Config => {
1721            StartTime => '2016-01-01 00:00:00',
1722            EndTime   => '2016-02-01 00:00:00',
1723            UserID    => $UserID,
1724        },
1725        Result => {
1726            '2016-01-01' => 1,
1727            '2016-01-03' => 1,
1728        },
1729        Success => 1,
1730    },
1731    {
1732        Name   => 'AppointmentDays - March',
1733        Config => {
1734            StartTime => '2016-03-01 00:00:00',
1735            EndTime   => '2016-04-01 00:00:00',
1736            UserID    => $UserID,
1737        },
1738        Result => {
1739            '2016-03-01' => 1,
1740            '2016-03-02' => 1,
1741            '2016-03-03' => 1,
1742            '2016-03-04' => 1,
1743            '2016-03-05' => 1,
1744            '2016-03-06' => 1,
1745        },
1746        Success => 1,
1747    },
1748    {
1749        Name   => 'AppointmentDays - May',
1750        Config => {
1751            StartTime => '2016-05-01 00:00:00',
1752            EndTime   => '2016-06-01 00:00:00',
1753            UserID    => $UserID,
1754        },
1755        Result => {
1756            '2016-05-04' => 1,
1757            '2016-05-06' => 1,
1758            '2016-05-16' => 1,
1759        },
1760        Success => 1,
1761    },
1762);
1763
1764for my $Test (@Tests) {
1765
1766    # make the call
1767    my %AppointmentDays = $AppointmentObject->AppointmentDays(
1768        %{ $Test->{Config} },
1769    );
1770
1771    if ( $Test->{Success} ) {
1772
1773        # check dates
1774        $Self->IsDeeply(
1775            \%AppointmentDays,
1776            $Test->{Result},
1777            "$Test->{Name} - Result",
1778        );
1779    }
1780    else {
1781        $Self->IsDeeply(
1782            \%AppointmentDays,
1783            {},
1784            "$Test->{Name} - No success",
1785        );
1786    }
1787}
1788
1789# get a few UniqueIDs in quick succession
1790my @UniqueIDs;
1791for ( 1 .. 10 ) {
1792    push @UniqueIDs, $AppointmentObject->GetUniqueID(
1793        CalendarID => 1,
1794        StartTime  => '2016-01-01 00:00:00',
1795        UserID     => 1,
1796    );
1797}
1798
1799my %Seen;
1800for my $UniqueID (@UniqueIDs) {
1801    $Self->False(
1802        $Seen{$UniqueID}++,
1803        "UniqueID $UniqueID is unique",
1804    );
1805}
1806
1807# create another test group
1808my $GroupName2 = 'test-calendar-group-' . $RandomID . '-2';
1809my $GroupID2   = $GroupObject->GroupAdd(
1810    Name    => $GroupName2,
1811    ValidID => 1,
1812    UserID  => 1,
1813);
1814
1815$Self->True(
1816    $GroupID2,
1817    "Test group $GroupID2 created",
1818);
1819
1820# add test user to test group with ro permissions
1821my $Success = $GroupObject->PermissionGroupUserAdd(
1822    GID        => $GroupID2,
1823    UID        => $UserID,
1824    Permission => {
1825        ro        => 1,
1826        move_into => 0,
1827        create    => 0,
1828        owner     => 0,
1829        priority  => 0,
1830        rw        => 0,
1831    },
1832    UserID => 1,
1833);
1834
1835$Self->True(
1836    $Success,
1837    "Test user $UserID added to test group $GroupID2 with 'ro'",
1838);
1839
1840# create another test calendar
1841my %Calendar2 = $CalendarObject->CalendarCreate(
1842    CalendarName => "Calendar2-$RandomID",
1843    Color        => '#3A87AD',
1844    GroupID      => $GroupID2,
1845    UserID       => $UserID,
1846);
1847
1848$Self->True(
1849    $Calendar2{CalendarID},
1850    "CalendarCreate - $Calendar2{CalendarID}",
1851);
1852
1853#
1854# Tests for AppointmentDelete()
1855#
1856my $AppointmentDeleteTitle = "Appointment-$RandomID";
1857@Tests = (
1858    {
1859        Name    => 'AppointmentDelete - No params',
1860        Config  => {},
1861        Success => 0,
1862    },
1863    {
1864        Name   => 'AppointmentDelete - No AppointmentID',
1865        Config => {
1866            UserID => $UserID,
1867        },
1868        Success => 0,
1869    },
1870    {
1871        Name   => 'AppointmentDelete - No UserID',
1872        Config => {
1873            AppointmentID => 1,
1874        },
1875        Success => 0,
1876    },
1877    {
1878        Name   => 'AppointmentDelete - All params',
1879        Create => {
1880            CalendarID => $Calendar{CalendarID},
1881            Title      => $AppointmentDeleteTitle,
1882            StartTime  => '2016-02-29 00:00:00',
1883            EndTime    => '2016-02-29 00:00:00',
1884            AllDay     => 1,
1885            UserID     => $UserID,
1886        },
1887        Config => {
1888            UserID => $UserID,
1889        },
1890        List => {
1891            CalendarID => $Calendar{CalendarID},
1892            StartTime  => '2016-02-29 00:00:00',
1893            EndTime    => '2016-02-29 00:00:00',
1894        },
1895        Success => 1,
1896    },
1897    {
1898        Name   => 'AppointmentDelete - No permissions',
1899        Create => {
1900            CalendarID => $Calendar2{CalendarID},
1901            Title      => "Appointment-RO-$RandomID",
1902            StartTime  => '2016-07-04 19:45:00',
1903            EndTime    => '2016-07-04 19:45:00',
1904            UserID     => $UserID,
1905        },
1906        Config => {
1907            UserID => $UserID,
1908        },
1909        List => {
1910            CalendarID => $Calendar2{CalendarID},
1911            StartTime  => '2016-07-04 00:00:00',
1912            EndTime    => '2016-07-05 00:00:00',
1913        },
1914        Success => 0,
1915    },
1916
1917);
1918
1919for my $Test (@Tests) {
1920
1921    # create appointment
1922    if ( $Test->{Create} ) {
1923        my $AppointmentID = $AppointmentObject->AppointmentCreate(
1924            %{ $Test->{Create} },
1925        );
1926        $Self->True(
1927            $AppointmentID,
1928            "$Test->{Name} - Appointment created",
1929        );
1930
1931        # save appointment id
1932        $Test->{Config}->{AppointmentID} = $AppointmentID;
1933
1934        # check list
1935        my @AppointmentList = $AppointmentObject->AppointmentList(
1936            %{ $Test->{List} },
1937        );
1938        $Self->Is(
1939            scalar @AppointmentList,
1940            1,
1941            "$Test->{Name} - Appointment list start",
1942        );
1943    }
1944
1945    # make the call
1946    my $Success = $AppointmentObject->AppointmentDelete(
1947        %{ $Test->{Config} },
1948    );
1949
1950    if ( $Test->{Success} ) {
1951        $Self->True(
1952            $Success,
1953            "$Test->{Name} - Success",
1954        );
1955    }
1956    else {
1957        $Self->False(
1958            $Success,
1959            "$Test->{Name} - No success",
1960        );
1961    }
1962
1963    # check list again
1964    if ( $Test->{Create} ) {
1965        my @AppointmentList = $AppointmentObject->AppointmentList(
1966            %{ $Test->{List} },
1967        );
1968        $Self->Is(
1969            scalar @AppointmentList,
1970            $Test->{Success} ? 0 : 1,
1971            "$Test->{Name} - Appointment list end",
1972        );
1973    }
1974}
1975
1976# Check if Appointment notification trigerd on event AppointmentDelete contains data.
1977# See bug#14335
1978my $TestEmailObject = $Kernel::OM->Get('Kernel::System::Email::Test');
1979
1980# Process mail queue items.
1981$MailQueueProcess->();
1982
1983# Check that emailS was sent.
1984my $Emails = $TestEmailObject->EmailsGet();
1985
1986my $Test = "appointment \"$AppointmentDeleteTitle\" has reached its notification=
1987 time.=
1988";
1989
1990# Check if email body data.
1991$Self->Is(
1992    ${ $Emails->[0]{Body} },
1993    $Test,
1994    'Sent email contains correct data',
1995);
1996
1997#
1998# Tests for _TimeCheck()
1999#
2000@Tests = (
2001    {
2002        Name   => 'Missing Time',
2003        Config => {
2004            OriginalTime => '2016-01-01 00:01:00',
2005        },
2006        Success => 0,
2007    },
2008    {
2009        Name   => 'Missing OriginalTime',
2010        Config => {
2011            Time => '2016-02-01 00:02:00',
2012        },
2013        Success => 0,
2014    },
2015    {
2016        Name   => 'All params',
2017        Config => {
2018            OriginalTime => '2016-01-01 00:01:00',
2019            Time         => '2016-02-01 00:02:00',
2020        },
2021        Result  => '2016-02-01 00:01:00',
2022        Success => 1,
2023    },
2024);
2025
2026for my $Test (@Tests) {
2027    my $Result = $AppointmentObject->_TimeCheck(
2028        %{ $Test->{Config} },
2029    );
2030
2031    if ( $Test->{Success} ) {
2032        $Self->Is(
2033            $Result,
2034            $Test->{Result},
2035            "_TimeCheck - $Test->{Name} - Success",
2036        );
2037    }
2038    else {
2039        $Self->False(
2040            $Result,
2041            "_TimeCheck - $Test->{Name} - No success ",
2042        );
2043    }
2044}
2045
2046#
2047# Notifications
2048#
2049
2050# notification creation test definition
2051my @NotificationCreateTests = (
2052
2053    # add appointment with notifications disabled explicitly
2054    {
2055        Data => {
2056            CalendarID           => $Calendar{CalendarID},
2057            Title                => 'Notification appointment 1',
2058            Description          => 'no notification',
2059            Location             => 'Germany',
2060            StartTime            => '2016-09-01 00:00:00',
2061            EndTime              => '2016-09-02 00:00:00',
2062            AllDay               => 1,
2063            TimezoneID           => 1,
2064            NotificationTemplate => 0,
2065            UserID               => $UserID,
2066        },
2067        Result => {
2068            NotificationDate                      => '',
2069            NotificationTemplate                  => '',
2070            NotificationCustom                    => '',
2071            NotificationCustomRelativeUnitCount   => 0,
2072            NotificationCustomRelativeUnit        => '',
2073            NotificationCustomRelativePointOfTime => '',
2074            NotificationCustomDateTime            => '',
2075        },
2076    },
2077
2078    # add appointment with wrong notification template
2079    {
2080        Data => {
2081            CalendarID           => $Calendar{CalendarID},
2082            Title                => 'Notification appointment 2',
2083            Description          => 'wrong notification template',
2084            Location             => 'Germany',
2085            StartTime            => '2016-09-01 00:00:00',
2086            EndTime              => '2016-09-02 00:00:00',
2087            AllDay               => 1,
2088            TimezoneID           => 1,
2089            NotificationTemplate => 'WrongNotificationTemplate',
2090            UserID               => $UserID,
2091        },
2092        Result => {
2093            NotificationDate                      => '',
2094            NotificationTemplate                  => 'WrongNotificationTemplate',
2095            NotificationCustom                    => '',
2096            NotificationCustomRelativeUnitCount   => 0,
2097            NotificationCustomRelativeUnit        => '',
2098            NotificationCustomRelativePointOfTime => '',
2099            NotificationCustomDateTime            => '',
2100        },
2101    },
2102
2103    # add appointment with notification 0 minute template (AppointmentStart)
2104    {
2105        Data => {
2106            CalendarID           => $Calendar{CalendarID},
2107            Title                => 'Notification appointment 3',
2108            Description          => 'notification template start',
2109            Location             => 'Germany',
2110            StartTime            => '2016-09-01 00:00:00',
2111            EndTime              => '2016-09-02 00:00:00',
2112            AllDay               => 1,
2113            TimezoneID           => 1,
2114            NotificationTemplate => 'Start',
2115            UserID               => $UserID,
2116        },
2117        Result => {
2118            NotificationDate                      => '2016-09-01 00:00:00',
2119            NotificationTemplate                  => 'Start',
2120            NotificationCustom                    => '',
2121            NotificationCustomRelativeUnitCount   => 0,
2122            NotificationCustomRelativeUnit        => '',
2123            NotificationCustomRelativePointOfTime => '',
2124            NotificationCustomDateTime            => '',
2125        },
2126    },
2127
2128    # add appointment with notification 30 minutes template
2129    {
2130        Data => {
2131            CalendarID           => $Calendar{CalendarID},
2132            Title                => 'Notification appointment 4',
2133            Description          => 'notification template 30 minutes before start',
2134            Location             => 'Germany',
2135            StartTime            => '2016-09-01 00:00:00',
2136            EndTime              => '2016-09-02 00:00:00',
2137            AllDay               => 1,
2138            TimezoneID           => 1,
2139            NotificationTemplate => 1800,
2140            UserID               => $UserID,
2141        },
2142        Result => {
2143            NotificationDate                      => '2016-08-31 23:30:00',
2144            NotificationTemplate                  => 1800,
2145            NotificationCustom                    => '',
2146            NotificationCustomRelativeUnitCount   => 0,
2147            NotificationCustomRelativeUnit        => '',
2148            NotificationCustomRelativePointOfTime => '',
2149            NotificationCustomDateTime            => '',
2150        },
2151    },
2152
2153    # add appointment with notification 12 hours template
2154    {
2155        Data => {
2156            CalendarID           => $Calendar{CalendarID},
2157            Title                => 'Notification appointment 5',
2158            Description          => 'notification template 12 hours before start',
2159            Location             => 'Germany',
2160            StartTime            => '2016-09-01 00:00:00',
2161            EndTime              => '2016-09-02 00:00:00',
2162            AllDay               => 1,
2163            TimezoneID           => 1,
2164            NotificationTemplate => 43200,
2165            UserID               => $UserID,
2166        },
2167        Result => {
2168            NotificationDate                      => '2016-08-31 12:00:00',
2169            NotificationTemplate                  => 43200,
2170            NotificationCustom                    => '',
2171            NotificationCustomRelativeUnitCount   => 0,
2172            NotificationCustomRelativeUnit        => '',
2173            NotificationCustomRelativePointOfTime => '',
2174            NotificationCustomDateTime            => '',
2175        },
2176    },
2177
2178    # add appointment with notification 2 days template
2179    {
2180        Data => {
2181            CalendarID           => $Calendar{CalendarID},
2182            Title                => 'Notification appointment 6',
2183            Description          => 'notification template 2 days before start',
2184            Location             => 'Germany',
2185            StartTime            => '2016-09-01 00:00:00',
2186            EndTime              => '2016-09-02 00:00:00',
2187            AllDay               => 1,
2188            TimezoneID           => 1,
2189            NotificationTemplate => 172800,
2190            UserID               => $UserID,
2191        },
2192        Result => {
2193            NotificationDate                      => '2016-08-30 00:00:00',
2194            NotificationTemplate                  => 172800,
2195            NotificationCustom                    => '',
2196            NotificationCustomRelativeUnitCount   => 0,
2197            NotificationCustomRelativeUnit        => '',
2198            NotificationCustomRelativePointOfTime => '',
2199            NotificationCustomDateTime            => '',
2200        },
2201    },
2202
2203    # add appointment with notification 1 week template
2204    {
2205        Data => {
2206            CalendarID           => $Calendar{CalendarID},
2207            Title                => 'Notification appointment 7',
2208            Description          => 'notification template 1 week before start',
2209            Location             => 'Germany',
2210            StartTime            => '2016-09-01 00:00:00',
2211            EndTime              => '2016-09-02 00:00:00',
2212            AllDay               => 1,
2213            TimezoneID           => 1,
2214            NotificationTemplate => 604800,
2215            UserID               => $UserID,
2216        },
2217        Result => {
2218            NotificationDate                      => '2016-08-25 00:00:00',
2219            NotificationTemplate                  => 604800,
2220            NotificationCustom                    => '',
2221            NotificationCustomRelativeUnitCount   => 0,
2222            NotificationCustomRelativeUnit        => '',
2223            NotificationCustomRelativePointOfTime => '',
2224            NotificationCustomDateTime            => '',
2225        },
2226    },
2227
2228    # add appointment with custom relative notification 2 minutes before start
2229    {
2230        Data => {
2231            CalendarID                            => $Calendar{CalendarID},
2232            Title                                 => 'Notification appointment 8',
2233            Description                           => 'notification custom 2 minutes before start',
2234            Location                              => 'Germany',
2235            StartTime                             => '2016-09-01 00:00:00',
2236            EndTime                               => '2016-09-02 00:00:00',
2237            AllDay                                => 1,
2238            TimezoneID                            => 1,
2239            NotificationTemplate                  => 'Custom',
2240            NotificationCustom                    => 'relative',
2241            NotificationCustomRelativeUnitCount   => 2,
2242            NotificationCustomRelativeUnit        => 'minutes',
2243            NotificationCustomRelativePointOfTime => 'beforestart',
2244            UserID                                => $UserID,
2245        },
2246        Result => {
2247            NotificationDate                      => '2016-08-31 23:58:00',
2248            NotificationTemplate                  => 'Custom',
2249            NotificationCustom                    => 'relative',
2250            NotificationCustomRelativeUnitCount   => 2,
2251            NotificationCustomRelativeUnit        => 'minutes',
2252            NotificationCustomRelativePointOfTime => 'beforestart',
2253            NotificationCustomDateTime            => '',
2254        },
2255    },
2256
2257    # add appointment with custom relative notification 2 hours before start
2258    {
2259        Data => {
2260            CalendarID                            => $Calendar{CalendarID},
2261            Title                                 => 'Notification appointment 9',
2262            Description                           => 'notification custom 2 hours before start',
2263            Location                              => 'Germany',
2264            StartTime                             => '2016-09-01 00:00:00',
2265            EndTime                               => '2016-09-02 00:00:00',
2266            AllDay                                => 1,
2267            TimezoneID                            => 1,
2268            NotificationTemplate                  => 'Custom',
2269            NotificationCustom                    => 'relative',
2270            NotificationCustomRelativeUnitCount   => 2,
2271            NotificationCustomRelativeUnit        => 'hours',
2272            NotificationCustomRelativePointOfTime => 'beforestart',
2273            UserID                                => $UserID,
2274        },
2275        Result => {
2276            NotificationDate                      => '2016-08-31 22:00:00',
2277            NotificationTemplate                  => 'Custom',
2278            NotificationCustom                    => 'relative',
2279            NotificationCustomRelativeUnitCount   => 2,
2280            NotificationCustomRelativeUnit        => 'hours',
2281            NotificationCustomRelativePointOfTime => 'beforestart',
2282            NotificationCustomDateTime            => '',
2283        },
2284    },
2285
2286    # add appointment with custom relative notification 2 days before start
2287    {
2288        Data => {
2289            CalendarID                            => $Calendar{CalendarID},
2290            Title                                 => 'Notification appointment 10',
2291            Description                           => 'notification custom 2 days before start',
2292            Location                              => 'Germany',
2293            StartTime                             => '2016-09-01 00:00:00',
2294            EndTime                               => '2016-09-02 00:00:00',
2295            AllDay                                => 1,
2296            TimezoneID                            => 1,
2297            NotificationTemplate                  => 'Custom',
2298            NotificationCustom                    => 'relative',
2299            NotificationCustomRelativeUnitCount   => 2,
2300            NotificationCustomRelativeUnit        => 'days',
2301            NotificationCustomRelativePointOfTime => 'beforestart',
2302            UserID                                => $UserID,
2303        },
2304        Result => {
2305            NotificationDate                      => '2016-08-30 00:00:00',
2306            NotificationTemplate                  => 'Custom',
2307            NotificationCustom                    => 'relative',
2308            NotificationCustomRelativeUnitCount   => 2,
2309            NotificationCustomRelativeUnit        => 'days',
2310            NotificationCustomRelativePointOfTime => 'beforestart',
2311            NotificationCustomDateTime            => '',
2312        },
2313    },
2314
2315    # add appointment with custom relative notification 2 minutes after start
2316    {
2317        Data => {
2318            CalendarID                            => $Calendar{CalendarID},
2319            Title                                 => 'Notification appointment 11',
2320            Description                           => 'notification date 2 minutes after start',
2321            Location                              => 'Germany',
2322            StartTime                             => '2016-09-01 00:00:00',
2323            EndTime                               => '2016-09-02 00:00:00',
2324            AllDay                                => 1,
2325            TimezoneID                            => 1,
2326            NotificationTemplate                  => 'Custom',
2327            NotificationCustom                    => 'relative',
2328            NotificationCustomRelativeUnitCount   => 2,
2329            NotificationCustomRelativeUnit        => 'minutes',
2330            NotificationCustomRelativePointOfTime => 'afterstart',
2331            UserID                                => $UserID,
2332        },
2333        Result => {
2334            NotificationDate                      => '2016-09-01 00:02:00',
2335            NotificationTemplate                  => 'Custom',
2336            NotificationCustom                    => 'relative',
2337            NotificationCustomRelativeUnitCount   => 2,
2338            NotificationCustomRelativeUnit        => 'minutes',
2339            NotificationCustomRelativePointOfTime => 'afterstart',
2340            NotificationCustomDateTime            => '',
2341        },
2342    },
2343
2344    # add appointment with custom relative notification 2 hours after start
2345    {
2346        Data => {
2347            CalendarID                            => $Calendar{CalendarID},
2348            Title                                 => 'Notification appointment 12',
2349            Description                           => 'notification date 2 hours after start',
2350            Location                              => 'Germany',
2351            StartTime                             => '2016-09-01 00:00:00',
2352            EndTime                               => '2016-09-02 00:00:00',
2353            AllDay                                => 1,
2354            TimezoneID                            => 1,
2355            NotificationTemplate                  => 'Custom',
2356            NotificationCustom                    => 'relative',
2357            NotificationCustomRelativeUnitCount   => 2,
2358            NotificationCustomRelativeUnit        => 'hours',
2359            NotificationCustomRelativePointOfTime => 'afterstart',
2360            UserID                                => $UserID,
2361        },
2362        Result => {
2363            NotificationDate                      => '2016-09-01 02:00:00',
2364            NotificationTemplate                  => 'Custom',
2365            NotificationCustom                    => 'relative',
2366            NotificationCustomRelativeUnitCount   => 2,
2367            NotificationCustomRelativeUnit        => 'hours',
2368            NotificationCustomRelativePointOfTime => 'afterstart',
2369            NotificationCustomDateTime            => '',
2370        },
2371    },
2372
2373    # add appointment with custom relative notification 2 days after start
2374    {
2375        Data => {
2376            CalendarID                            => $Calendar{CalendarID},
2377            Title                                 => 'Notification appointment 13',
2378            Description                           => 'notification date 2 days after start',
2379            Location                              => 'Germany',
2380            StartTime                             => '2016-09-01 00:00:00',
2381            EndTime                               => '2016-09-02 00:00:00',
2382            AllDay                                => 1,
2383            TimezoneID                            => 1,
2384            NotificationTemplate                  => 'Custom',
2385            NotificationCustom                    => 'relative',
2386            NotificationCustomRelativeUnitCount   => 2,
2387            NotificationCustomRelativeUnit        => 'days',
2388            NotificationCustomRelativePointOfTime => 'afterstart',
2389            UserID                                => $UserID,
2390        },
2391        Result => {
2392            NotificationDate                      => '2016-09-03 00:00:00',
2393            NotificationTemplate                  => 'Custom',
2394            NotificationCustom                    => 'relative',
2395            NotificationCustomRelativeUnitCount   => 2,
2396            NotificationCustomRelativeUnit        => 'days',
2397            NotificationCustomRelativePointOfTime => 'afterstart',
2398            NotificationCustomDateTime            => '',
2399        },
2400    },
2401
2402    # add appointment with custom relative notification 2 minutes before end
2403    {
2404        Data => {
2405            CalendarID                            => $Calendar{CalendarID},
2406            Title                                 => 'Notification appointment 14',
2407            Description                           => 'notification date 2 minutes before end',
2408            Location                              => 'Germany',
2409            StartTime                             => '2016-09-01 00:00:00',
2410            EndTime                               => '2016-09-02 00:00:00',
2411            AllDay                                => 1,
2412            TimezoneID                            => 1,
2413            NotificationTemplate                  => 'Custom',
2414            NotificationCustom                    => 'relative',
2415            NotificationCustomRelativeUnitCount   => 2,
2416            NotificationCustomRelativeUnit        => 'minutes',
2417            NotificationCustomRelativePointOfTime => 'beforeend',
2418            UserID                                => $UserID,
2419        },
2420        Result => {
2421            NotificationDate                      => '2016-09-01 23:58:00',
2422            NotificationTemplate                  => 'Custom',
2423            NotificationCustom                    => 'relative',
2424            NotificationCustomRelativeUnitCount   => 2,
2425            NotificationCustomRelativeUnit        => 'minutes',
2426            NotificationCustomRelativePointOfTime => 'beforeend',
2427            NotificationCustomDateTime            => '',
2428        },
2429    },
2430
2431    # add appointment with custom relative notification 2 hours before end
2432    {
2433        Data => {
2434            CalendarID                            => $Calendar{CalendarID},
2435            Title                                 => 'Notification appointment 15',
2436            Description                           => 'notification date 2 hours before end',
2437            Location                              => 'Germany',
2438            StartTime                             => '2016-09-01 00:00:00',
2439            EndTime                               => '2016-09-02 00:00:00',
2440            AllDay                                => 1,
2441            TimezoneID                            => 1,
2442            NotificationTemplate                  => 'Custom',
2443            NotificationCustom                    => 'relative',
2444            NotificationCustomRelativeUnitCount   => 2,
2445            NotificationCustomRelativeUnit        => 'hours',
2446            NotificationCustomRelativePointOfTime => 'beforeend',
2447            UserID                                => $UserID,
2448        },
2449        Result => {
2450            NotificationDate                      => '2016-09-01 22:00:00',
2451            NotificationTemplate                  => 'Custom',
2452            NotificationCustom                    => 'relative',
2453            NotificationCustomRelativeUnitCount   => 2,
2454            NotificationCustomRelativeUnit        => 'hours',
2455            NotificationCustomRelativePointOfTime => 'beforeend',
2456            NotificationCustomDateTime            => '',
2457        },
2458    },
2459
2460    # add appointment with custom relative notification 2 days before end
2461    {
2462        Data => {
2463            CalendarID                            => $Calendar{CalendarID},
2464            Title                                 => 'Notification appointment 16',
2465            Description                           => 'notification date 2 days before end',
2466            Location                              => 'Germany',
2467            StartTime                             => '2016-09-01 00:00:00',
2468            EndTime                               => '2016-09-02 00:00:00',
2469            AllDay                                => 1,
2470            TimezoneID                            => 1,
2471            NotificationTemplate                  => 'Custom',
2472            NotificationCustom                    => 'relative',
2473            NotificationCustomRelativeUnitCount   => 2,
2474            NotificationCustomRelativeUnit        => 'days',
2475            NotificationCustomRelativePointOfTime => 'beforeend',
2476            UserID                                => $UserID,
2477        },
2478        Result => {
2479            NotificationDate                      => '2016-08-31 00:00:00',
2480            NotificationTemplate                  => 'Custom',
2481            NotificationCustom                    => 'relative',
2482            NotificationCustomRelativeUnitCount   => 2,
2483            NotificationCustomRelativeUnit        => 'days',
2484            NotificationCustomRelativePointOfTime => 'beforeend',
2485            NotificationCustomDateTime            => '',
2486        },
2487    },
2488
2489    # add appointment with custom relative notification 2 minutes after end
2490    {
2491        Data => {
2492            CalendarID                            => $Calendar{CalendarID},
2493            Title                                 => 'Notification appointment 17',
2494            Description                           => 'notification date 2 minutes after end',
2495            Location                              => 'Germany',
2496            StartTime                             => '2016-09-01 00:00:00',
2497            EndTime                               => '2016-09-02 00:00:00',
2498            AllDay                                => 1,
2499            TimezoneID                            => 1,
2500            NotificationTemplate                  => 'Custom',
2501            NotificationCustom                    => 'relative',
2502            NotificationCustomRelativeUnitCount   => 2,
2503            NotificationCustomRelativeUnit        => 'minutes',
2504            NotificationCustomRelativePointOfTime => 'afterend',
2505            UserID                                => $UserID,
2506        },
2507        Result => {
2508            NotificationDate                      => '2016-09-02 00:02:00',
2509            NotificationTemplate                  => 'Custom',
2510            NotificationCustom                    => 'relative',
2511            NotificationCustomRelativeUnitCount   => 2,
2512            NotificationCustomRelativeUnit        => 'minutes',
2513            NotificationCustomRelativePointOfTime => 'afterend',
2514            NotificationCustomDateTime            => '',
2515        },
2516    },
2517
2518    # add appointment with custom relative notification 2 hours after end
2519    {
2520        Data => {
2521            CalendarID                            => $Calendar{CalendarID},
2522            Title                                 => 'Notification appointment 18',
2523            Description                           => 'notification date 2 hours after end',
2524            Location                              => 'Germany',
2525            StartTime                             => '2016-09-01 00:00:00',
2526            EndTime                               => '2016-09-02 00:00:00',
2527            AllDay                                => 1,
2528            TimezoneID                            => 1,
2529            NotificationTemplate                  => 'Custom',
2530            NotificationCustom                    => 'relative',
2531            NotificationCustomRelativeUnitCount   => 2,
2532            NotificationCustomRelativeUnit        => 'hours',
2533            NotificationCustomRelativePointOfTime => 'afterend',
2534            UserID                                => $UserID,
2535        },
2536        Result => {
2537            NotificationDate                      => '2016-09-02 02:00:00',
2538            NotificationTemplate                  => 'Custom',
2539            NotificationCustom                    => 'relative',
2540            NotificationCustomRelativeUnitCount   => 2,
2541            NotificationCustomRelativeUnit        => 'hours',
2542            NotificationCustomRelativePointOfTime => 'afterend',
2543            NotificationCustomDateTime            => '',
2544        },
2545    },
2546
2547    # add appointment with custom relative notification 2 days after end
2548    {
2549        Data => {
2550            CalendarID                            => $Calendar{CalendarID},
2551            Title                                 => 'Notification appointment 19',
2552            Description                           => 'notification date 2 days after end',
2553            Location                              => 'Germany',
2554            StartTime                             => '2016-09-01 00:00:00',
2555            EndTime                               => '2016-09-02 00:00:00',
2556            AllDay                                => 1,
2557            TimezoneID                            => 1,
2558            NotificationTemplate                  => 'Custom',
2559            NotificationCustom                    => 'relative',
2560            NotificationCustomRelativeUnitCount   => 2,
2561            NotificationCustomRelativeUnit        => 'days',
2562            NotificationCustomRelativePointOfTime => 'afterend',
2563            UserID                                => $UserID,
2564        },
2565        Result => {
2566            NotificationDate                      => '2016-09-04 00:00:00',
2567            NotificationTemplate                  => 'Custom',
2568            NotificationCustom                    => 'relative',
2569            NotificationCustomRelativeUnitCount   => 2,
2570            NotificationCustomRelativeUnit        => 'days',
2571            NotificationCustomRelativePointOfTime => 'afterend',
2572            NotificationCustomDateTime            => '',
2573        },
2574    },
2575
2576    # add appointment with custom relative notification 0 minutes before start
2577    {
2578        Data => {
2579            CalendarID                            => $Calendar{CalendarID},
2580            Title                                 => 'Notification appointment 20',
2581            Description                           => 'notification custom 0 minutes before start',
2582            Location                              => 'Germany',
2583            StartTime                             => '2016-09-01 00:00:00',
2584            EndTime                               => '2016-09-02 00:00:00',
2585            AllDay                                => 1,
2586            TimezoneID                            => 1,
2587            NotificationTemplate                  => 'Custom',
2588            NotificationCustom                    => 'relative',
2589            NotificationCustomRelativeUnitCount   => 0,
2590            NotificationCustomRelativeUnit        => 'minutes',
2591            NotificationCustomRelativePointOfTime => 'beforestart',
2592            UserID                                => $UserID,
2593        },
2594        Result => {
2595            NotificationDate                      => '2016-09-01 00:00:00',
2596            NotificationTemplate                  => 'Custom',
2597            NotificationCustom                    => 'relative',
2598            NotificationCustomRelativeUnitCount   => 0,
2599            NotificationCustomRelativeUnit        => 'minutes',
2600            NotificationCustomRelativePointOfTime => 'beforestart',
2601            NotificationCustomDateTime            => '',
2602        },
2603    },
2604
2605    # add appointment with custom relative notification 0 hours before start
2606    {
2607        Data => {
2608            CalendarID                            => $Calendar{CalendarID},
2609            Title                                 => 'Notification appointment 21',
2610            Description                           => 'notification custom 0 hours before start',
2611            Location                              => 'Germany',
2612            StartTime                             => '2016-09-01 00:00:00',
2613            EndTime                               => '2016-09-02 00:00:00',
2614            AllDay                                => 1,
2615            TimezoneID                            => 1,
2616            NotificationTemplate                  => 'Custom',
2617            NotificationCustom                    => 'relative',
2618            NotificationCustomRelativeUnitCount   => 0,
2619            NotificationCustomRelativeUnit        => 'hours',
2620            NotificationCustomRelativePointOfTime => 'beforestart',
2621            UserID                                => $UserID,
2622        },
2623        Result => {
2624            NotificationDate                      => '2016-09-01 00:00:00',
2625            NotificationTemplate                  => 'Custom',
2626            NotificationCustom                    => 'relative',
2627            NotificationCustomRelativeUnitCount   => 0,
2628            NotificationCustomRelativeUnit        => 'hours',
2629            NotificationCustomRelativePointOfTime => 'beforestart',
2630            NotificationCustomDateTime            => '',
2631        },
2632    },
2633
2634    # add appointment with custom relative notification 0 days before start
2635    {
2636        Data => {
2637            CalendarID                            => $Calendar{CalendarID},
2638            Title                                 => 'Notification appointment 22',
2639            Description                           => 'notification custom 0 days before start',
2640            Location                              => 'Germany',
2641            StartTime                             => '2016-09-01 00:00:00',
2642            EndTime                               => '2016-09-02 00:00:00',
2643            AllDay                                => 1,
2644            TimezoneID                            => 1,
2645            NotificationTemplate                  => 'Custom',
2646            NotificationCustom                    => 'relative',
2647            NotificationCustomRelativeUnitCount   => 0,
2648            NotificationCustomRelativeUnit        => 'days',
2649            NotificationCustomRelativePointOfTime => 'beforestart',
2650            UserID                                => $UserID,
2651        },
2652        Result => {
2653            NotificationDate                      => '2016-09-01 00:00:00',
2654            NotificationTemplate                  => 'Custom',
2655            NotificationCustom                    => 'relative',
2656            NotificationCustomRelativeUnitCount   => 0,
2657            NotificationCustomRelativeUnit        => 'days',
2658            NotificationCustomRelativePointOfTime => 'beforestart',
2659            NotificationCustomDateTime            => '',
2660        },
2661    },
2662
2663    # add appointment with custom relative notification 0 minutes after start
2664    {
2665        Data => {
2666            CalendarID                            => $Calendar{CalendarID},
2667            Title                                 => 'Notification appointment 23',
2668            Description                           => 'notification date 0 minutes after start',
2669            Location                              => 'Germany',
2670            StartTime                             => '2016-09-01 00:00:00',
2671            EndTime                               => '2016-09-02 00:00:00',
2672            AllDay                                => 1,
2673            TimezoneID                            => 1,
2674            NotificationTemplate                  => 'Custom',
2675            NotificationCustom                    => 'relative',
2676            NotificationCustomRelativeUnitCount   => 0,
2677            NotificationCustomRelativeUnit        => 'minutes',
2678            NotificationCustomRelativePointOfTime => 'afterstart',
2679            UserID                                => $UserID,
2680        },
2681        Result => {
2682            NotificationDate                      => '2016-09-01 00:00:00',
2683            NotificationTemplate                  => 'Custom',
2684            NotificationCustom                    => 'relative',
2685            NotificationCustomRelativeUnitCount   => 0,
2686            NotificationCustomRelativeUnit        => 'minutes',
2687            NotificationCustomRelativePointOfTime => 'afterstart',
2688            NotificationCustomDateTime            => '',
2689        },
2690    },
2691
2692    # add appointment with custom relative notification 0 hours after start
2693    {
2694        Data => {
2695            CalendarID                            => $Calendar{CalendarID},
2696            Title                                 => 'Notification appointment 24',
2697            Description                           => 'notification date 0 hours after start',
2698            Location                              => 'Germany',
2699            StartTime                             => '2016-09-01 00:00:00',
2700            EndTime                               => '2016-09-02 00:00:00',
2701            AllDay                                => 1,
2702            TimezoneID                            => 1,
2703            NotificationTemplate                  => 'Custom',
2704            NotificationCustom                    => 'relative',
2705            NotificationCustomRelativeUnitCount   => 0,
2706            NotificationCustomRelativeUnit        => 'hours',
2707            NotificationCustomRelativePointOfTime => 'afterstart',
2708            UserID                                => $UserID,
2709        },
2710        Result => {
2711            NotificationDate                      => '2016-09-01 00:00:00',
2712            NotificationTemplate                  => 'Custom',
2713            NotificationCustom                    => 'relative',
2714            NotificationCustomRelativeUnitCount   => 0,
2715            NotificationCustomRelativeUnit        => 'hours',
2716            NotificationCustomRelativePointOfTime => 'afterstart',
2717            NotificationCustomDateTime            => '',
2718        },
2719    },
2720
2721    # add appointment with custom relative notification 0 days after start
2722    {
2723        Data => {
2724            CalendarID                            => $Calendar{CalendarID},
2725            Title                                 => 'Notification appointment 25',
2726            Description                           => 'notification date 0 days after start',
2727            Location                              => 'Germany',
2728            StartTime                             => '2016-09-01 00:00:00',
2729            EndTime                               => '2016-09-02 00:00:00',
2730            AllDay                                => 1,
2731            TimezoneID                            => 1,
2732            NotificationTemplate                  => 'Custom',
2733            NotificationCustom                    => 'relative',
2734            NotificationCustomRelativeUnitCount   => 0,
2735            NotificationCustomRelativeUnit        => 'days',
2736            NotificationCustomRelativePointOfTime => 'afterstart',
2737            UserID                                => $UserID,
2738        },
2739        Result => {
2740            NotificationDate                      => '2016-09-01 00:00:00',
2741            NotificationTemplate                  => 'Custom',
2742            NotificationCustom                    => 'relative',
2743            NotificationCustomRelativeUnitCount   => 0,
2744            NotificationCustomRelativeUnit        => 'days',
2745            NotificationCustomRelativePointOfTime => 'afterstart',
2746            NotificationCustomDateTime            => '',
2747        },
2748    },
2749
2750    # add appointment with custom relative notification 0 minutes before end
2751    {
2752        Data => {
2753            CalendarID                            => $Calendar{CalendarID},
2754            Title                                 => 'Notification appointment 26',
2755            Description                           => 'notification date 0 minutes before end',
2756            Location                              => 'Germany',
2757            StartTime                             => '2016-09-01 00:00:00',
2758            EndTime                               => '2016-09-02 00:00:00',
2759            AllDay                                => 1,
2760            TimezoneID                            => 1,
2761            NotificationTemplate                  => 'Custom',
2762            NotificationCustom                    => 'relative',
2763            NotificationCustomRelativeUnitCount   => 0,
2764            NotificationCustomRelativeUnit        => 'minutes',
2765            NotificationCustomRelativePointOfTime => 'beforeend',
2766            UserID                                => $UserID,
2767        },
2768        Result => {
2769            NotificationDate                      => '2016-09-02 00:00:00',
2770            NotificationTemplate                  => 'Custom',
2771            NotificationCustom                    => 'relative',
2772            NotificationCustomRelativeUnitCount   => 0,
2773            NotificationCustomRelativeUnit        => 'minutes',
2774            NotificationCustomRelativePointOfTime => 'beforeend',
2775            NotificationCustomDateTime            => '',
2776        },
2777    },
2778
2779    # add appointment with custom relative notification 0 hours before end
2780    {
2781        Data => {
2782            CalendarID                            => $Calendar{CalendarID},
2783            Title                                 => 'Notification appointment 27',
2784            Description                           => 'notification date 0 hours before end',
2785            Location                              => 'Germany',
2786            StartTime                             => '2016-09-01 00:00:00',
2787            EndTime                               => '2016-09-02 00:00:00',
2788            AllDay                                => 1,
2789            TimezoneID                            => 1,
2790            NotificationTemplate                  => 'Custom',
2791            NotificationCustom                    => 'relative',
2792            NotificationCustomRelativeUnitCount   => 0,
2793            NotificationCustomRelativeUnit        => 'hours',
2794            NotificationCustomRelativePointOfTime => 'beforeend',
2795            UserID                                => $UserID,
2796        },
2797        Result => {
2798            NotificationDate                      => '2016-09-02 00:00:00',
2799            NotificationTemplate                  => 'Custom',
2800            NotificationCustom                    => 'relative',
2801            NotificationCustomRelativeUnitCount   => 0,
2802            NotificationCustomRelativeUnit        => 'hours',
2803            NotificationCustomRelativePointOfTime => 'beforeend',
2804            NotificationCustomDateTime            => '',
2805        },
2806    },
2807
2808    # add appointment with custom relative notification 0 days before end
2809    {
2810        Data => {
2811            CalendarID                            => $Calendar{CalendarID},
2812            Title                                 => 'Notification appointment 28',
2813            Description                           => 'notification date 0 days before end',
2814            Location                              => 'Germany',
2815            StartTime                             => '2016-09-01 00:00:00',
2816            EndTime                               => '2016-09-02 00:00:00',
2817            AllDay                                => 1,
2818            TimezoneID                            => 1,
2819            NotificationTemplate                  => 'Custom',
2820            NotificationCustom                    => 'relative',
2821            NotificationCustomRelativeUnitCount   => 0,
2822            NotificationCustomRelativeUnit        => 'days',
2823            NotificationCustomRelativePointOfTime => 'beforeend',
2824            UserID                                => $UserID,
2825        },
2826        Result => {
2827            NotificationDate                      => '2016-09-02 00:00:00',
2828            NotificationTemplate                  => 'Custom',
2829            NotificationCustom                    => 'relative',
2830            NotificationCustomRelativeUnitCount   => 0,
2831            NotificationCustomRelativeUnit        => 'days',
2832            NotificationCustomRelativePointOfTime => 'beforeend',
2833            NotificationCustomDateTime            => '',
2834        },
2835    },
2836
2837    # add appointment with custom relative notification 0 minutes after end
2838    {
2839        Data => {
2840            CalendarID                            => $Calendar{CalendarID},
2841            Title                                 => 'Notification appointment 29',
2842            Description                           => 'notification date 0 minutes after end',
2843            Location                              => 'Germany',
2844            StartTime                             => '2016-09-01 00:00:00',
2845            EndTime                               => '2016-09-02 00:00:00',
2846            AllDay                                => 1,
2847            TimezoneID                            => 1,
2848            NotificationTemplate                  => 'Custom',
2849            NotificationCustom                    => 'relative',
2850            NotificationCustomRelativeUnitCount   => 0,
2851            NotificationCustomRelativeUnit        => 'minutes',
2852            NotificationCustomRelativePointOfTime => 'afterend',
2853            UserID                                => $UserID,
2854        },
2855        Result => {
2856            NotificationDate                      => '2016-09-02 00:00:00',
2857            NotificationTemplate                  => 'Custom',
2858            NotificationCustom                    => 'relative',
2859            NotificationCustomRelativeUnitCount   => 0,
2860            NotificationCustomRelativeUnit        => 'minutes',
2861            NotificationCustomRelativePointOfTime => 'afterend',
2862            NotificationCustomDateTime            => '',
2863        },
2864    },
2865
2866    # add appointment with custom relative notification 0 hours after end
2867    {
2868        Data => {
2869            CalendarID                            => $Calendar{CalendarID},
2870            Title                                 => 'Notification appointment 30',
2871            Description                           => 'notification date 0 hours after end',
2872            Location                              => 'Germany',
2873            StartTime                             => '2016-09-01 00:00:00',
2874            EndTime                               => '2016-09-02 00:00:00',
2875            AllDay                                => 1,
2876            TimezoneID                            => 1,
2877            NotificationTemplate                  => 'Custom',
2878            NotificationCustom                    => 'relative',
2879            NotificationCustomRelativeUnitCount   => 0,
2880            NotificationCustomRelativeUnit        => 'hours',
2881            NotificationCustomRelativePointOfTime => 'afterend',
2882            UserID                                => $UserID,
2883        },
2884        Result => {
2885            NotificationDate                      => '2016-09-02 00:00:00',
2886            NotificationTemplate                  => 'Custom',
2887            NotificationCustom                    => 'relative',
2888            NotificationCustomRelativeUnitCount   => 0,
2889            NotificationCustomRelativeUnit        => 'hours',
2890            NotificationCustomRelativePointOfTime => 'afterend',
2891            NotificationCustomDateTime            => '',
2892        },
2893    },
2894
2895    # add appointment with custom relative notification 0 days after end
2896    {
2897        Data => {
2898            CalendarID                            => $Calendar{CalendarID},
2899            Title                                 => 'Notification appointment 31',
2900            Description                           => 'notification date 0 days after end',
2901            Location                              => 'Germany',
2902            StartTime                             => '2016-09-01 00:00:00',
2903            EndTime                               => '2016-09-02 00:00:00',
2904            AllDay                                => 1,
2905            TimezoneID                            => 1,
2906            NotificationTemplate                  => 'Custom',
2907            NotificationCustom                    => 'relative',
2908            NotificationCustomRelativeUnitCount   => 0,
2909            NotificationCustomRelativeUnit        => 'days',
2910            NotificationCustomRelativePointOfTime => 'afterend',
2911            UserID                                => $UserID,
2912        },
2913        Result => {
2914            NotificationDate                      => '2016-09-02 00:00:00',
2915            NotificationTemplate                  => 'Custom',
2916            NotificationCustom                    => 'relative',
2917            NotificationCustomRelativeUnitCount   => 0,
2918            NotificationCustomRelativeUnit        => 'days',
2919            NotificationCustomRelativePointOfTime => 'afterend',
2920            NotificationCustomDateTime            => '',
2921        },
2922    },
2923
2924    # add appointment with custom relative notification -2345 days after end
2925    {
2926        Data => {
2927            CalendarID                            => $Calendar{CalendarID},
2928            Title                                 => 'Notification appointment 32',
2929            Description                           => 'notification date -2345 days after end',
2930            Location                              => 'Germany',
2931            StartTime                             => '2016-09-01 00:00:00',
2932            EndTime                               => '2016-09-02 00:00:00',
2933            AllDay                                => 1,
2934            TimezoneID                            => 1,
2935            NotificationTemplate                  => 'Custom',
2936            NotificationCustom                    => 'relative',
2937            NotificationCustomRelativeUnitCount   => -2345,
2938            NotificationCustomRelativeUnit        => 'days',
2939            NotificationCustomRelativePointOfTime => 'afterend',
2940            UserID                                => $UserID,
2941        },
2942        Result => {
2943            NotificationDate                      => '2016-09-02 00:00:00',
2944            NotificationTemplate                  => 'Custom',
2945            NotificationCustom                    => 'relative',
2946            NotificationCustomRelativeUnitCount   => 0,
2947            NotificationCustomRelativeUnit        => 'days',
2948            NotificationCustomRelativePointOfTime => 'afterend',
2949            NotificationCustomDateTime            => '',
2950        },
2951    },
2952
2953    # add appointment with custom datetime notification 2 minutes before start
2954    {
2955        Data => {
2956            CalendarID                            => $Calendar{CalendarID},
2957            Title                                 => 'Notification appointment 33',
2958            Description                           => 'notification date 2 minutes before start',
2959            Location                              => 'Germany',
2960            StartTime                             => '2016-09-01 00:00:00',
2961            EndTime                               => '2016-09-02 00:00:00',
2962            AllDay                                => 1,
2963            TimezoneID                            => 1,
2964            NotificationTemplate                  => 'Custom',
2965            NotificationCustom                    => 'datetime',
2966            NotificationCustomRelativeUnitCount   => undef,
2967            NotificationCustomRelativeUnit        => undef,
2968            NotificationCustomRelativePointOfTime => undef,
2969            NotificationCustomDateTime            => '2016-08-31 23:58:00',
2970            UserID                                => $UserID,
2971        },
2972        Result => {
2973            NotificationDate                      => '2016-08-31 23:58:00',
2974            NotificationTemplate                  => 'Custom',
2975            NotificationCustom                    => 'datetime',
2976            NotificationCustomRelativeUnitCount   => 0,
2977            NotificationCustomRelativeUnit        => '',
2978            NotificationCustomRelativePointOfTime => '',
2979            NotificationCustomDateTime            => '2016-08-31 23:58:00',
2980        },
2981    },
2982
2983    # add appointment with custom datetime notification 2 hours before start
2984    {
2985        Data => {
2986            CalendarID                            => $Calendar{CalendarID},
2987            Title                                 => 'Notification appointment 34',
2988            Description                           => 'notification date 2 hours before start',
2989            Location                              => 'Germany',
2990            StartTime                             => '2016-09-01 00:00:00',
2991            EndTime                               => '2016-09-02 00:00:00',
2992            AllDay                                => 1,
2993            TimezoneID                            => 1,
2994            NotificationTemplate                  => 'Custom',
2995            NotificationCustom                    => 'datetime',
2996            NotificationCustomRelativeUnitCount   => undef,
2997            NotificationCustomRelativeUnit        => undef,
2998            NotificationCustomRelativePointOfTime => undef,
2999            NotificationCustomDateTime            => '2016-08-31 22:00:00',
3000            UserID                                => $UserID,
3001        },
3002        Result => {
3003            NotificationDate                      => '2016-08-31 22:00:00',
3004            NotificationTemplate                  => 'Custom',
3005            NotificationCustom                    => 'datetime',
3006            NotificationCustomRelativeUnitCount   => 0,
3007            NotificationCustomRelativeUnit        => '',
3008            NotificationCustomRelativePointOfTime => '',
3009            NotificationCustomDateTime            => '2016-08-31 22:00:00',
3010        },
3011    },
3012
3013    # add appointment with custom datetime notification 2 days before start
3014    {
3015        Data => {
3016            CalendarID                            => $Calendar{CalendarID},
3017            Title                                 => 'Notification appointment 35',
3018            Description                           => 'notification date 2 days before start',
3019            Location                              => 'Germany',
3020            StartTime                             => '2016-09-01 00:00:00',
3021            EndTime                               => '2016-09-02 00:00:00',
3022            AllDay                                => 1,
3023            TimezoneID                            => 1,
3024            NotificationTemplate                  => 'Custom',
3025            NotificationCustom                    => 'datetime',
3026            NotificationCustomRelativeUnitCount   => undef,
3027            NotificationCustomRelativeUnit        => undef,
3028            NotificationCustomRelativePointOfTime => undef,
3029            NotificationCustomDateTime            => '2016-08-30 00:00:00',
3030            UserID                                => $UserID,
3031        },
3032        Result => {
3033            NotificationDate                      => '2016-08-30 00:00:00',
3034            NotificationTemplate                  => 'Custom',
3035            NotificationCustom                    => 'datetime',
3036            NotificationCustomRelativeUnitCount   => 0,
3037            NotificationCustomRelativeUnit        => '',
3038            NotificationCustomRelativePointOfTime => '',
3039            NotificationCustomDateTime            => '2016-08-30 00:00:00',
3040        },
3041    },
3042
3043    # add appointment with custom datetime notification 2 minutes after end
3044    {
3045        Data => {
3046            CalendarID                            => $Calendar{CalendarID},
3047            Title                                 => 'Notification appointment 36',
3048            Description                           => 'notification date 2 minutes after end',
3049            Location                              => 'Germany',
3050            StartTime                             => '2016-09-01 00:00:00',
3051            EndTime                               => '2016-09-02 00:00:00',
3052            AllDay                                => 1,
3053            TimezoneID                            => 1,
3054            NotificationTemplate                  => 'Custom',
3055            NotificationCustom                    => 'datetime',
3056            NotificationCustomRelativeUnitCount   => undef,
3057            NotificationCustomRelativeUnit        => undef,
3058            NotificationCustomRelativePointOfTime => undef,
3059            NotificationCustomDateTime            => '2016-09-02 00:02:00',
3060            UserID                                => $UserID,
3061        },
3062        Result => {
3063            NotificationDate                      => '2016-09-02 00:02:00',
3064            NotificationTemplate                  => 'Custom',
3065            NotificationCustom                    => 'datetime',
3066            NotificationCustomRelativeUnitCount   => 0,
3067            NotificationCustomRelativeUnit        => '',
3068            NotificationCustomRelativePointOfTime => '',
3069            NotificationCustomDateTime            => '2016-09-02 00:02:00',
3070        },
3071    },
3072
3073    # add appointment with custom datetime notification 2 hours after end
3074    {
3075        Data => {
3076            CalendarID                            => $Calendar{CalendarID},
3077            Title                                 => 'Notification appointment 37',
3078            Description                           => 'notification date 2 hours after end',
3079            Location                              => 'Germany',
3080            StartTime                             => '2016-09-01 00:00:00',
3081            EndTime                               => '2016-09-02 00:00:00',
3082            AllDay                                => 1,
3083            TimezoneID                            => 1,
3084            NotificationTemplate                  => 'Custom',
3085            NotificationCustom                    => 'datetime',
3086            NotificationCustomRelativeUnitCount   => undef,
3087            NotificationCustomRelativeUnit        => undef,
3088            NotificationCustomRelativePointOfTime => undef,
3089            NotificationCustomDateTime            => '2016-09-02 02:00:00',
3090            UserID                                => $UserID,
3091        },
3092        Result => {
3093            NotificationDate                      => '2016-09-02 02:00:00',
3094            NotificationTemplate                  => 'Custom',
3095            NotificationCustom                    => 'datetime',
3096            NotificationCustomRelativeUnitCount   => 0,
3097            NotificationCustomRelativeUnit        => '',
3098            NotificationCustomRelativePointOfTime => '',
3099            NotificationCustomDateTime            => '2016-09-02 02:00:00',
3100        },
3101    },
3102
3103    # add appointment with custom datetime notification 2 days after end
3104    {
3105        Data => {
3106            CalendarID                            => $Calendar{CalendarID},
3107            Title                                 => 'Notification appointment 38',
3108            Description                           => 'notification date 2 days after end',
3109            Location                              => 'Germany',
3110            StartTime                             => '2016-09-01 00:00:00',
3111            EndTime                               => '2016-09-02 00:00:00',
3112            AllDay                                => 1,
3113            TimezoneID                            => 1,
3114            NotificationTemplate                  => 'Custom',
3115            NotificationCustom                    => 'datetime',
3116            NotificationCustomRelativeUnitCount   => undef,
3117            NotificationCustomRelativeUnit        => undef,
3118            NotificationCustomRelativePointOfTime => undef,
3119            NotificationCustomDateTime            => '2016-09-04 00:00:00',
3120            UserID                                => $UserID,
3121        },
3122        Result => {
3123            NotificationDate                      => '2016-09-04 00:00:00',
3124            NotificationTemplate                  => 'Custom',
3125            NotificationCustom                    => 'datetime',
3126            NotificationCustomRelativeUnitCount   => 0,
3127            NotificationCustomRelativeUnit        => '',
3128            NotificationCustomRelativePointOfTime => '',
3129            NotificationCustomDateTime            => '2016-09-04 00:00:00',
3130        },
3131    },
3132);
3133
3134# notification create test execution
3135for my $Test (@NotificationCreateTests) {
3136
3137    # create appointment
3138    my $AppointmentID = $AppointmentObject->AppointmentCreate(
3139        %{ $Test->{Data} },
3140        UserID => $UserID,
3141    );
3142
3143    # verify appointment creation
3144    $Self->True(
3145        $AppointmentID,
3146        'Notification appointment created - ' . $Test->{Data}->{Description},
3147    );
3148
3149    # retrieve stored appointment information
3150    my %AppointmentData = $AppointmentObject->AppointmentGet(
3151        AppointmentID => $AppointmentID,
3152    );
3153
3154    # verify appointment data get
3155    my $Created = IsHashRefWithData( \%AppointmentData );
3156    $Self->True(
3157        $Created,
3158        'Notification appointment data retrieved - ' . $Test->{Data}->{Description},
3159    );
3160
3161    # verify results
3162    for my $ResultKey ( sort keys %{ $Test->{Result} } ) {
3163
3164        $Self->Is(
3165            $AppointmentData{$ResultKey},
3166            $Test->{Result}->{$ResultKey},
3167            'Notification appointment result: ' . $ResultKey . ' - ' . $Test->{Data}->{Description},
3168        );
3169    }
3170}
3171
3172# notification update test definition
3173my @NotificationUpdateTests = (
3174
3175    # update appointment from no template to wrong template
3176    {
3177        DataBefore => {
3178            CalendarID           => $Calendar{CalendarID},
3179            Title                => 'Update notification appointment 1',
3180            Description          => 'Before update no notification',
3181            Location             => 'Germany',
3182            StartTime            => '2016-09-01 00:00:00',
3183            EndTime              => '2016-09-02 00:00:00',
3184            AllDay               => 1,
3185            TimezoneID           => 1,
3186            NotificationTemplate => 0,
3187            UserID               => $UserID,
3188        },
3189        DataAfter => {
3190            CalendarID           => $Calendar{CalendarID},
3191            Title                => 'Update notification appointment 1',
3192            Description          => 'Update to wrong notification template',
3193            Location             => 'Germany',
3194            StartTime            => '2016-09-01 00:00:00',
3195            EndTime              => '2016-09-02 00:00:00',
3196            AllDay               => 1,
3197            TimezoneID           => 1,
3198            NotificationTemplate => 'WrongNotificationTemplate',
3199            UserID               => $UserID,
3200        },
3201        Result => {
3202            NotificationDate                      => '',
3203            NotificationTemplate                  => 'WrongNotificationTemplate',
3204            NotificationCustom                    => '',
3205            NotificationCustomRelativeUnitCount   => 0,
3206            NotificationCustomRelativeUnit        => '',
3207            NotificationCustomRelativePointOfTime => '',
3208            NotificationCustomDateTime            => '',
3209        },
3210    },
3211
3212    # update appointment from no template to starttime template
3213    {
3214        DataBefore => {
3215            CalendarID           => $Calendar{CalendarID},
3216            Title                => 'Update notification appointment 2',
3217            Description          => 'Before update no notification',
3218            Location             => 'Germany',
3219            StartTime            => '2016-09-01 00:00:00',
3220            EndTime              => '2016-09-02 00:00:00',
3221            AllDay               => 1,
3222            TimezoneID           => 1,
3223            NotificationTemplate => 0,
3224            UserID               => $UserID,
3225        },
3226        DataAfter => {
3227            CalendarID           => $Calendar{CalendarID},
3228            Title                => 'Update notification appointment 2',
3229            Description          => 'Update to notification template start',
3230            Location             => 'Germany',
3231            StartTime            => '2016-09-01 00:00:00',
3232            EndTime              => '2016-09-02 00:00:00',
3233            AllDay               => 1,
3234            TimezoneID           => 1,
3235            NotificationTemplate => 'Start',
3236            UserID               => $UserID,
3237        },
3238        Result => {
3239            NotificationDate                      => '2016-09-01 00:00:00',
3240            NotificationTemplate                  => 'Start',
3241            NotificationCustom                    => '',
3242            NotificationCustomRelativeUnitCount   => 0,
3243            NotificationCustomRelativeUnit        => '',
3244            NotificationCustomRelativePointOfTime => '',
3245            NotificationCustomDateTime            => '',
3246        },
3247    },
3248
3249    # update appointment from starttime template to 30 minutes before start template
3250    {
3251        DataBefore => {
3252
3253            CalendarID           => $Calendar{CalendarID},
3254            Title                => 'Update notification appointment 3',
3255            Description          => 'Update to notification template 30 minutes before start',
3256            Location             => 'Germany',
3257            StartTime            => '2016-09-01 00:00:00',
3258            EndTime              => '2016-09-02 00:00:00',
3259            AllDay               => 1,
3260            TimezoneID           => 1,
3261            NotificationTemplate => 'Start',
3262            UserID               => $UserID,
3263        },
3264        DataAfter => {
3265            CalendarID           => $Calendar{CalendarID},
3266            Title                => 'Update notification appointment 3',
3267            Description          => 'Update to notification template 30 minutes before start',
3268            Location             => 'Germany',
3269            StartTime            => '2016-09-01 00:00:00',
3270            EndTime              => '2016-09-02 00:00:00',
3271            AllDay               => 1,
3272            TimezoneID           => 1,
3273            NotificationTemplate => 1800,
3274            UserID               => $UserID,
3275        },
3276        Result => {
3277            NotificationDate                      => '2016-08-31 23:30:00',
3278            NotificationTemplate                  => 1800,
3279            NotificationCustom                    => '',
3280            NotificationCustomRelativeUnitCount   => 0,
3281            NotificationCustomRelativeUnit        => '',
3282            NotificationCustomRelativePointOfTime => '',
3283            NotificationCustomDateTime            => '',
3284        },
3285    },
3286
3287    # update appointment from 30 minutes before start template to 12 hours before start template
3288    {
3289        DataBefore => {
3290            CalendarID           => $Calendar{CalendarID},
3291            Title                => 'Update notification appointment 4',
3292            Description          => 'Update to notification template 12 hours before start template',
3293            Location             => 'Germany',
3294            StartTime            => '2016-09-01 00:00:00',
3295            EndTime              => '2016-09-02 00:00:00',
3296            AllDay               => 1,
3297            TimezoneID           => 1,
3298            NotificationTemplate => 1800,
3299            UserID               => $UserID,
3300        },
3301        DataAfter => {
3302            CalendarID           => $Calendar{CalendarID},
3303            Title                => 'Update notification appointment 4',
3304            Description          => 'Update to notification template 12 hours before start',
3305            Location             => 'Germany',
3306            StartTime            => '2016-09-01 00:00:00',
3307            EndTime              => '2016-09-02 00:00:00',
3308            AllDay               => 1,
3309            TimezoneID           => 1,
3310            NotificationTemplate => 43200,
3311            UserID               => $UserID,
3312        },
3313        Result => {
3314            NotificationDate                      => '2016-08-31 12:00:00',
3315            NotificationTemplate                  => 43200,
3316            NotificationCustom                    => '',
3317            NotificationCustomRelativeUnitCount   => 0,
3318            NotificationCustomRelativeUnit        => '',
3319            NotificationCustomRelativePointOfTime => '',
3320            NotificationCustomDateTime            => '',
3321        },
3322    },
3323
3324    # update appointment from 12 hours before start template to 2 days before start template
3325    {
3326        DataBefore => {
3327            CalendarID           => $Calendar{CalendarID},
3328            Title                => 'Update notification appointment 5',
3329            Description          => 'Update to notification template 2 days before start template',
3330            Location             => 'Germany',
3331            StartTime            => '2016-09-01 00:00:00',
3332            EndTime              => '2016-09-02 00:00:00',
3333            AllDay               => 1,
3334            TimezoneID           => 1,
3335            NotificationTemplate => 43200,
3336            UserID               => $UserID,
3337        },
3338        DataAfter => {
3339            CalendarID           => $Calendar{CalendarID},
3340            Title                => 'Update notification appointment 5',
3341            Description          => 'Update to notification template 2 days before start',
3342            Location             => 'Germany',
3343            StartTime            => '2016-09-01 00:00:00',
3344            EndTime              => '2016-09-02 00:00:00',
3345            AllDay               => 1,
3346            TimezoneID           => 1,
3347            NotificationTemplate => 172800,
3348            UserID               => $UserID,
3349        },
3350        Result => {
3351            NotificationDate                      => '2016-08-30 00:00:00',
3352            NotificationTemplate                  => 172800,
3353            NotificationCustom                    => '',
3354            NotificationCustomRelativeUnitCount   => 0,
3355            NotificationCustomRelativeUnit        => '',
3356            NotificationCustomRelativePointOfTime => '',
3357            NotificationCustomDateTime            => '',
3358        },
3359    },
3360
3361    # update appointment from 2 days before start template to no notification template
3362    {
3363        DataBefore => {
3364            CalendarID           => $Calendar{CalendarID},
3365            Title                => 'Update notification appointment 6',
3366            Description          => 'Update to no notification template',
3367            Location             => 'Germany',
3368            StartTime            => '2016-09-01 00:00:00',
3369            EndTime              => '2016-09-02 00:00:00',
3370            AllDay               => 1,
3371            TimezoneID           => 1,
3372            NotificationTemplate => 172800,
3373            UserID               => $UserID,
3374        },
3375        DataAfter => {
3376            CalendarID           => $Calendar{CalendarID},
3377            Title                => 'Update notification appointment 6',
3378            Description          => 'Before update to no notification',
3379            Location             => 'Germany',
3380            StartTime            => '2016-09-01 00:00:00',
3381            EndTime              => '2016-09-02 00:00:00',
3382            AllDay               => 1,
3383            TimezoneID           => 1,
3384            NotificationTemplate => 0,
3385            UserID               => $UserID,
3386        },
3387        Result => {
3388            NotificationDate                      => '',
3389            NotificationTemplate                  => '',
3390            NotificationCustom                    => '',
3391            NotificationCustomRelativeUnitCount   => 0,
3392            NotificationCustomRelativeUnit        => '',
3393            NotificationCustomRelativePointOfTime => '',
3394            NotificationCustomDateTime            => '',
3395        },
3396    },
3397
3398    # update appointment from 12 hours before start template to custom 2 minutes before start template
3399    {
3400        DataBefore => {
3401            CalendarID           => $Calendar{CalendarID},
3402            Title                => 'Update notification appointment 7',
3403            Description          => 'Update to notification template custom 2 minutes before start',
3404            Location             => 'Germany',
3405            StartTime            => '2016-09-01 00:00:00',
3406            EndTime              => '2016-09-02 00:00:00',
3407            AllDay               => 1,
3408            TimezoneID           => 1,
3409            NotificationTemplate => 43200,
3410            UserID               => $UserID,
3411        },
3412        DataAfter => {
3413            CalendarID                            => $Calendar{CalendarID},
3414            Title                                 => 'Update notification appointment 7',
3415            Description                           => 'Update to notification custom 2 minutes before start',
3416            Location                              => 'Germany',
3417            StartTime                             => '2016-09-01 00:00:00',
3418            EndTime                               => '2016-09-02 00:00:00',
3419            AllDay                                => 1,
3420            TimezoneID                            => 1,
3421            NotificationTemplate                  => 'Custom',
3422            NotificationCustom                    => 'relative',
3423            NotificationCustomRelativeUnitCount   => 2,
3424            NotificationCustomRelativeUnit        => 'minutes',
3425            NotificationCustomRelativePointOfTime => 'beforestart',
3426            UserID                                => $UserID,
3427        },
3428        Result => {
3429            NotificationDate                      => '2016-08-31 23:58:00',
3430            NotificationTemplate                  => 'Custom',
3431            NotificationCustom                    => 'relative',
3432            NotificationCustomRelativeUnitCount   => 2,
3433            NotificationCustomRelativeUnit        => 'minutes',
3434            NotificationCustomRelativePointOfTime => 'beforestart',
3435            NotificationCustomDateTime            => '',
3436        },
3437    },
3438
3439# update appointment from custom 2 minutes before start template to custom relative notification 2 hours before start template
3440    {
3441        DataBefore => {
3442            CalendarID           => $Calendar{CalendarID},
3443            Title                => 'Update notification appointment 8',
3444            Description          => 'Update to notification custom relative notification 2 hours before start',
3445            Location             => 'Germany',
3446            StartTime            => '2016-09-01 00:00:00',
3447            EndTime              => '2016-09-02 00:00:00',
3448            AllDay               => 1,
3449            TimezoneID           => 1,
3450            NotificationTemplate => 'Custom',
3451            NotificationCustom   => 'relative',
3452            NotificationCustomRelativeUnitCount   => 2,
3453            NotificationCustomRelativeUnit        => 'minutes',
3454            NotificationCustomRelativePointOfTime => 'beforestart',
3455            UserID                                => $UserID,
3456        },
3457        DataAfter => {
3458            CalendarID           => $Calendar{CalendarID},
3459            Title                => 'Update notification appointment 8',
3460            Description          => 'Update to notification custom relative notification 2 hours before start',
3461            Location             => 'Germany',
3462            StartTime            => '2016-09-01 00:00:00',
3463            EndTime              => '2016-09-02 00:00:00',
3464            AllDay               => 1,
3465            TimezoneID           => 1,
3466            NotificationTemplate => 'Custom',
3467            NotificationCustom   => 'relative',
3468            NotificationCustomRelativeUnitCount   => 2,
3469            NotificationCustomRelativeUnit        => 'hours',
3470            NotificationCustomRelativePointOfTime => 'beforestart',
3471            UserID                                => $UserID,
3472        },
3473        Result => {
3474            NotificationDate                      => '2016-08-31 22:00:00',
3475            NotificationTemplate                  => 'Custom',
3476            NotificationCustom                    => 'relative',
3477            NotificationCustomRelativeUnitCount   => 2,
3478            NotificationCustomRelativeUnit        => 'hours',
3479            NotificationCustomRelativePointOfTime => 'beforestart',
3480            NotificationCustomDateTime            => '',
3481        },
3482    },
3483
3484# update appointment from custom relative notification 2 hours before start template to custom relative notification 2 days before start template
3485    {
3486        DataBefore => {
3487            CalendarID           => $Calendar{CalendarID},
3488            Title                => 'Update notification appointment 9',
3489            Description          => 'Update to notification custom relative notification 2 days before start',
3490            Location             => 'Germany',
3491            StartTime            => '2016-09-01 00:00:00',
3492            EndTime              => '2016-09-02 00:00:00',
3493            AllDay               => 1,
3494            TimezoneID           => 1,
3495            NotificationTemplate => 'Custom',
3496            NotificationCustom   => 'relative',
3497            NotificationCustomRelativeUnitCount   => 2,
3498            NotificationCustomRelativeUnit        => 'hours',
3499            NotificationCustomRelativePointOfTime => 'beforestart',
3500            UserID                                => $UserID,
3501        },
3502        DataAfter => {
3503            CalendarID           => $Calendar{CalendarID},
3504            Title                => 'Update notification appointment 9',
3505            Description          => 'Update to notification custom relative notification 2 days before start',
3506            Location             => 'Germany',
3507            StartTime            => '2016-09-01 00:00:00',
3508            EndTime              => '2016-09-02 00:00:00',
3509            AllDay               => 1,
3510            TimezoneID           => 1,
3511            NotificationTemplate => 'Custom',
3512            NotificationCustom   => 'relative',
3513            NotificationCustomRelativeUnitCount   => 2,
3514            NotificationCustomRelativeUnit        => 'days',
3515            NotificationCustomRelativePointOfTime => 'beforestart',
3516            UserID                                => $UserID,
3517        },
3518        Result => {
3519            NotificationDate                      => '2016-08-30 00:00:00',
3520            NotificationTemplate                  => 'Custom',
3521            NotificationCustom                    => 'relative',
3522            NotificationCustomRelativeUnitCount   => 2,
3523            NotificationCustomRelativeUnit        => 'days',
3524            NotificationCustomRelativePointOfTime => 'beforestart',
3525            NotificationCustomDateTime            => '',
3526        },
3527    },
3528
3529# update appointment from custom relative notification 2 days before start template to notification date 2 minutes before start template
3530    {
3531        DataBefore => {
3532            CalendarID                            => $Calendar{CalendarID},
3533            Title                                 => 'Update notification appointment 10',
3534            Description                           => 'Update to notification date 2 minutes before start',
3535            Location                              => 'Germany',
3536            StartTime                             => '2016-09-01 00:00:00',
3537            EndTime                               => '2016-09-02 00:00:00',
3538            AllDay                                => 1,
3539            TimezoneID                            => 1,
3540            NotificationTemplate                  => 'Custom',
3541            NotificationCustom                    => 'relative',
3542            NotificationCustomRelativeUnitCount   => 2,
3543            NotificationCustomRelativeUnit        => 'days',
3544            NotificationCustomRelativePointOfTime => 'beforestart',
3545            UserID                                => $UserID,
3546        },
3547        DataAfter => {
3548            CalendarID                            => $Calendar{CalendarID},
3549            Title                                 => 'Update notification appointment 10',
3550            Description                           => 'Update to notification date 2 minutes before start',
3551            Location                              => 'Germany',
3552            StartTime                             => '2016-09-01 00:00:00',
3553            EndTime                               => '2016-09-02 00:00:00',
3554            AllDay                                => 1,
3555            TimezoneID                            => 1,
3556            NotificationTemplate                  => 'Custom',
3557            NotificationCustom                    => 'datetime',
3558            NotificationCustomRelativeUnitCount   => undef,
3559            NotificationCustomRelativeUnit        => undef,
3560            NotificationCustomRelativePointOfTime => undef,
3561            NotificationCustomDateTime            => '2016-08-31 23:58:00',
3562            UserID                                => $UserID,
3563        },
3564        Result => {
3565            NotificationDate                      => '2016-08-31 23:58:00',
3566            NotificationTemplate                  => 'Custom',
3567            NotificationCustom                    => 'datetime',
3568            NotificationCustomRelativeUnitCount   => 0,
3569            NotificationCustomRelativeUnit        => '',
3570            NotificationCustomRelativePointOfTime => '',
3571            NotificationCustomDateTime            => '2016-08-31 23:58:00',
3572        },
3573    },
3574
3575    # update appointment from custom relative notification 2 hours before start template to no notification template
3576    {
3577        DataBefore => {
3578            CalendarID           => $Calendar{CalendarID},
3579            Title                => 'Update notification appointment 11',
3580            Description          => 'Update to notification custom relative notification 2 days before start',
3581            Location             => 'Germany',
3582            StartTime            => '2016-09-01 00:00:00',
3583            EndTime              => '2016-09-02 00:00:00',
3584            AllDay               => 1,
3585            TimezoneID           => 1,
3586            NotificationTemplate => 'Custom',
3587            NotificationCustom   => 'relative',
3588            NotificationCustomRelativeUnitCount   => 2,
3589            NotificationCustomRelativeUnit        => 'days',
3590            NotificationCustomRelativePointOfTime => 'beforestart',
3591            UserID                                => $UserID,
3592        },
3593        DataAfter => {
3594            CalendarID           => $Calendar{CalendarID},
3595            Title                => 'Update notification appointment 11',
3596            Description          => 'Update to no notification template',
3597            Location             => 'Germany',
3598            StartTime            => '2016-09-01 00:00:00',
3599            EndTime              => '2016-09-02 00:00:00',
3600            AllDay               => 1,
3601            TimezoneID           => 1,
3602            NotificationTemplate => 0,
3603            UserID               => $UserID,
3604        },
3605        Result => {
3606            NotificationDate                      => '',
3607            NotificationTemplate                  => '',
3608            NotificationCustom                    => '',
3609            NotificationCustomRelativeUnitCount   => 0,
3610            NotificationCustomRelativeUnit        => '',
3611            NotificationCustomRelativePointOfTime => '',
3612            NotificationCustomDateTime            => '',
3613        },
3614    },
3615
3616    # update appointment from custom relative notification 2 hours before start template to no notification template
3617    # verify that not needed values are flushed afterwards
3618    {
3619        DataBefore => {
3620            CalendarID           => $Calendar{CalendarID},
3621            Title                => 'Update notification appointment 11',
3622            Description          => 'Update to notification custom relative notification 2 days before start',
3623            Location             => 'Germany',
3624            StartTime            => '2016-09-01 00:00:00',
3625            EndTime              => '2016-09-02 00:00:00',
3626            AllDay               => 1,
3627            TimezoneID           => 1,
3628            NotificationTemplate => 'Custom',
3629            NotificationCustom   => 'relative',
3630            NotificationCustomRelativeUnitCount   => 2,
3631            NotificationCustomRelativeUnit        => 'days',
3632            NotificationCustomRelativePointOfTime => 'beforestart',
3633            UserID                                => $UserID,
3634        },
3635        DataAfter => {
3636            CalendarID                            => $Calendar{CalendarID},
3637            Title                                 => 'Update notification appointment 11',
3638            Description                           => 'Update to no notification template',
3639            Location                              => 'Germany',
3640            StartTime                             => '2016-09-01 00:00:00',
3641            EndTime                               => '2016-09-02 00:00:00',
3642            AllDay                                => 1,
3643            TimezoneID                            => 1,
3644            NotificationTemplate                  => 0,
3645            NotificationCustom                    => 'relative',
3646            NotificationCustomRelativeUnitCount   => 30,
3647            NotificationCustomRelativeUnit        => 'days',
3648            NotificationCustomRelativePointOfTime => 'beforestart',
3649            UserID                                => $UserID,
3650        },
3651        Result => {
3652            NotificationDate                      => '',
3653            NotificationTemplate                  => '',
3654            NotificationCustom                    => '',
3655            NotificationCustomRelativeUnitCount   => 0,
3656            NotificationCustomRelativeUnit        => '',
3657            NotificationCustomRelativePointOfTime => '',
3658            NotificationCustomDateTime            => '',
3659        },
3660    },
3661);
3662
3663# notification update test execution
3664for my $Test (@NotificationUpdateTests) {
3665
3666    # create appointment
3667    my $AppointmentID = $AppointmentObject->AppointmentCreate(
3668        %{ $Test->{DataBefore} },
3669        UserID => $UserID,
3670    );
3671
3672    # verify appointment creation
3673    $Self->True(
3674        $AppointmentID,
3675        'Notification appointment created - ' . $Test->{DataBefore}->{Description},
3676    );
3677
3678    # retrieve stored appointment information
3679    my %AppointmentData = $AppointmentObject->AppointmentGet(
3680        AppointmentID => $AppointmentID,
3681    );
3682
3683    # verify appointment data get
3684    my $Created = IsHashRefWithData( \%AppointmentData );
3685    $Self->True(
3686        $Created,
3687        'Notification appointment data retrieved - ' . $Test->{DataBefore}->{Description},
3688    );
3689
3690    # update appointment
3691    my $Success = $AppointmentObject->AppointmentUpdate(
3692        %{ $Test->{DataAfter} },
3693        AppointmentID => $AppointmentID,
3694        UserID        => $UserID,
3695    );
3696
3697    # verify appointment update
3698    $Self->True(
3699        $Success,
3700        'Notification appointment updated - ' . $Test->{DataAfter}->{Description},
3701    );
3702
3703    # retrieve stored appointment information
3704    %AppointmentData = $AppointmentObject->AppointmentGet(
3705        AppointmentID => $AppointmentID,
3706    );
3707
3708    # verify appointment data get
3709    $Created = IsHashRefWithData( \%AppointmentData );
3710    $Self->True(
3711        $Created,
3712        'Notification appointment data retrieved - ' . $Test->{DataBefore}->{Description},
3713    );
3714
3715    # verify results
3716    for my $ResultKey ( sort keys %{ $Test->{Result} } ) {
3717
3718        $Self->Is(
3719            $AppointmentData{$ResultKey},
3720            $Test->{Result}->{$ResultKey},
3721            'Notification appointment result: ' . $ResultKey . ' - ' . $Test->{DataAfter}->{Description},
3722        );
3723    }
3724}
3725
37261;
3727