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
9## no critic (Modules::RequireExplicitPackage)
10use strict;
11use warnings;
12use utf8;
13
14use vars (qw($Self));
15
16use Kernel::System::VariableCheck qw(:all);
17
18# get needed objects
19my $CacheObject    = $Kernel::OM->Get('Kernel::System::Cache');
20my $ActivityObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Activity');
21my $ProcessObject  = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Process');
22
23# get helper object
24$Kernel::OM->ObjectParamAdd(
25    'Kernel::System::UnitTest::Helper' => {
26        RestoreDatabase => 1,
27    },
28);
29my $Helper = $Kernel::OM->Get('Kernel::System::UnitTest::Helper');
30
31# set fixed time
32$Helper->FixedTimeSet();
33
34# define needed variables
35my $RandomID          = $Helper->GetRandomID();
36my $UserID            = 1;
37my $ActivityEntityID1 = 'A1-' . $RandomID;
38my $ActivityEntityID2 = 'A2-' . $RandomID;
39my $ActivityEntityID3 = 'A3-' . $RandomID;
40my $ActivityName1     = 'Activity1';
41my $ActivityName2     = 'Activity2';
42my $ActivityName3     = 'Activity3';
43
44my $EntityID = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::Entity')->EntityIDGenerate(
45    EntityType => 'Process',
46    UserID     => 1,
47);
48
49my %ActivityLookup = (
50    $ActivityEntityID1 => $ActivityName1,
51    $ActivityEntityID2 => $ActivityName2,
52    $ActivityEntityID3 => $ActivityName3,
53);
54
55my $AcitivityID1 = $ActivityObject->ActivityAdd(
56    EntityID => $ActivityEntityID1,
57    Name     => $ActivityName1,
58    Config   => {},
59    UserID   => $UserID,
60);
61
62# sanity test
63$Self->IsNot(
64    $AcitivityID1,
65    undef,
66    "ActivityAdd Test1: EntityID '$ActivityEntityID1', Name '$ActivityName1' | Should not be undef",
67);
68my $AcitivityID2 = $ActivityObject->ActivityAdd(
69    EntityID => $ActivityEntityID2,
70    Name     => $ActivityName2,
71    Config   => {},
72    UserID   => $UserID,
73);
74
75# sanity test
76$Self->IsNot(
77    $AcitivityID2,
78    undef,
79    "ActivityAdd Test2: EntityID '$ActivityEntityID2', Name '$ActivityName2' | Should not be undef",
80);
81my $AcitivityID3 = $ActivityObject->ActivityAdd(
82    EntityID => $ActivityEntityID3,
83    Name     => $ActivityName3,
84    Config   => {},
85    UserID   => $UserID,
86);
87
88# sanity test
89$Self->IsNot(
90    $AcitivityID3,
91    undef,
92    "ActivityAdd Test3: EntityID '$ActivityEntityID3', Name '$ActivityName3' | Should not be undef",
93);
94
95my @AddedActivities = ( $AcitivityID1, $AcitivityID2, $AcitivityID3 );
96my $ActivityList    = $ActivityObject->ActivityList(
97    UseEntities => 1,
98    UserID      => $UserID,
99);
100
101# get original process list
102my $OriginalProcessList = $ProcessObject->ProcessList( UserID => $UserID ) || {};
103
104#
105# Tests for ProcessAdd
106#
107my @Tests = (
108    {
109        Name    => 'ProcessAdd Test 1: No Params',
110        Config  => {},
111        Success => 0,
112    },
113    {
114        Name   => 'ProcessAdd Test 2: No EntityID',
115        Config => {
116            EntityID      => undef,
117            Name          => 'Process-$RandomID',
118            StateEntityID => 'S1',
119            Layout        => {},
120            Config        => {
121                Description => 'a Description',
122            },
123            UserID => $UserID,
124        },
125        Success => 0,
126
127    },
128    {
129        Name   => 'ProcessAdd Test 3: No Name',
130        Config => {
131            EntityID      => $RandomID,
132            Name          => undef,
133            StateEntityID => 'S1',
134            Layout        => {},
135            Config        => {
136                Description => 'a Description',
137            },
138            UserID => $UserID,
139        },
140        Success => 0,
141
142    },
143    {
144        Name   => 'ProcessAdd Test 4: No StateEntityID',
145        Config => {
146            EntityID      => $RandomID,
147            Name          => "Process-$RandomID",
148            StateEntityID => undef,
149            Layout        => {},
150            Config        => {
151                Description => 'a Description',
152            },
153            UserID => $UserID,
154        },
155        Success => 0,
156    },
157    {
158        Name   => 'ProcessAdd Test 5: No Layout',
159        Config => {
160            EntityID      => $RandomID,
161            Name          => "Process-$RandomID",
162            StateEntityID => 'S1',
163            Layout        => undef,
164            Config        => {
165                Description => 'a Description',
166            },
167            UserID => $UserID,
168        },
169        Success => 0,
170    },
171    {
172        Name   => 'ProcessAdd Test 6: No Config',
173        Config => {
174            EntityID      => $RandomID,
175            Name          => "Process-$RandomID",
176            StateEntityID => 'S1',
177            Layout        => {},
178            Config        => undef,
179            UserID        => $UserID,
180        },
181        Success => 0,
182    },
183    {
184        Name   => 'ProcessAdd Test 7: No Config Description',
185        Config => {
186            EntityID      => $RandomID,
187            Name          => "Process-$RandomID",
188            StateEntityID => 'S1',
189            Layout        => {},
190            Config        => {
191                Data => 1,
192            },
193            UserID => $UserID,
194        },
195        Success => 0,
196    },
197    {
198        Name   => 'ProcessAdd Test 8: No UserID',
199        Config => {
200            EntityID      => $RandomID,
201            Name          => "Process-$RandomID",
202            StateEntityID => 'S1',
203            Layout        => {},
204            Config        => {
205                Description => 'a Description',
206            },
207            UserID => undef,
208        },
209        Success => 0,
210    },
211    {
212        Name   => 'ProcessAdd Test 9: Wrong Config format',
213        Config => {
214            EntityID      => $RandomID,
215            Name          => "Process-$RandomID",
216            StateEntityID => 'S1',
217            Layout        => {},
218            Config        => {},
219            UserID        => $UserID,
220        },
221        Success => 0,
222    },
223    {
224        Name   => 'ProcessAdd Test 10: Wrong Config format 2',
225        Config => {
226            EntityID      => $RandomID,
227            Name          => "Process-$RandomID",
228            StateEntityID => 'S1',
229            Layout        => {},
230            Config        => 'Config',
231            UserID        => $UserID,
232        },
233        Success => 0,
234    },
235    {
236        Name   => 'ProcessAdd Test 11: Correct ASCII',
237        Config => {
238            EntityID      => $RandomID,
239            Name          => "Process-$RandomID",
240            StateEntityID => 'S1',
241            Layout        => {},
242            Config        => {
243                Description => 'a Description',
244                Path        => {
245                    $ActivityEntityID1 => {},
246                }
247            },
248            UserID => $UserID,
249        },
250        Success => 1,
251    },
252    {
253        Name   => 'ProcessAdd Test 12: Duplicated EntityID',
254        Config => {
255            EntityID      => $RandomID,
256            Name          => "Process-$RandomID",
257            StateEntityID => 'S1',
258            Layout        => {},
259            Config        => {
260                Description => 'a Description',
261            },
262            UserID => $UserID,
263        },
264        Success => 0,
265    },
266    {
267        Name   => 'ProcessAdd Test 13: Correct UTF8',
268        Config => {
269            EntityID      => "$RandomID-1",
270            Name          => "Process-$RandomID-!§\$%&/()=?Ü*ÄÖL:L@,.-",
271            StateEntityID => 'S1',
272            Layout        => {},
273            Config        => {
274                Description => 'a Description §$%&/()=?Ü*ÄÖL:L@,.-',
275                Path        => {
276                    $ActivityEntityID1 => {},
277                    $ActivityEntityID2 => {},
278                }
279            },
280            UserID => $UserID,
281        },
282        Success => 1,
283    },
284    {
285        Name   => 'ProcessAdd Test 14: Correct UTF8 2',
286        Config => {
287            EntityID      => "$RandomID-2",
288            Name          => "Process-$RandomID-äöüßÄÖÜ€исáéíúóúÁÉÍÓÚñÑ",
289            StateEntityID => 'S1',
290            Layout        => {},
291            Config        => {
292                Description => 'a Description äöüßÄÖÜ€исáéíúóúÁÉÍÓÚñÑ',
293                Path        => {
294                    $ActivityEntityID1 => {},
295                    $ActivityEntityID2 => {},
296                    $ActivityEntityID3 => {},
297                }
298            },
299            UserID => $UserID,
300        },
301        Success => 1,
302    },
303    {
304        Name   => 'ProcessAdd Test 15: EntityID Full Length',
305        Config => {
306            EntityID      => $EntityID,
307            Name          => $EntityID,
308            StateEntityID => 'S1',
309            Layout        => {},
310            Config        => {
311                Description => 'a Description äöüßÄÖÜ€исáéíúóúÁÉÍÓÚñÑ',
312                Path        => {
313                    $ActivityEntityID1 => {},
314                    $ActivityEntityID2 => {},
315                    $ActivityEntityID3 => {},
316                }
317            },
318            UserID => $UserID,
319        },
320        Success => 1,
321    },
322);
323
324my %AddedProcess;
325for my $Test (@Tests) {
326    my $ProcessID = $ProcessObject->ProcessAdd( %{ $Test->{Config} } );
327
328    if ( $Test->{Success} ) {
329        $Self->IsNot(
330            $ProcessID,
331            0,
332            "$Test->{Name} | ProcessID should not be 0",
333        );
334        $AddedProcess{$ProcessID} = $Test->{Config};
335    }
336    else {
337        $Self->Is(
338            $ProcessID,
339            undef,
340            "$Test->{Name} | ProcessID should be undef",
341        );
342    }
343}
344
345my @AddedProcessList = map {$_} sort keys %AddedProcess;
346
347#
348# ProcessSearch() tests
349#
350
351@Tests = (
352    {
353        Name        => "ProcessSearch Test1 - Correct ASCII",
354        ProcessName => $RandomID,
355        Result      => [
356            $RandomID,
357            "$RandomID-1",
358            "$RandomID-2",
359        ],
360        Count => 3,
361    },
362    {
363        Name        => "ProcessSearch Test1 - Correct ASCII with asterisk",
364        ProcessName => $RandomID,
365        Result      => [
366            $RandomID,
367            "$RandomID-1",
368            "$RandomID-2",
369        ],
370        Count => 3,
371    },
372    {
373        Name        => "ProcessSearch Test2 - Correct UTF8 1",
374        ProcessName => "Process-$RandomID-!§\$%&/()=?Ü*ÄÖL:L@,.-",
375        Result      => ["$RandomID-1"],
376        Count       => 1,
377    },
378    {
379        Name        => "ProcessSearch Test3 - - Correct UTF8 1",
380        ProcessName => "Process-$RandomID-äöüßÄÖÜ€исáéíúóúÁÉÍÓÚñÑ",
381        Result      => ["$RandomID-2"],
382        Count       => 1,
383    },
384    {
385        Name        => "ProcessSearch Test4 - EntityID Full Length",
386        ProcessName => $EntityID,
387        Result      => [$EntityID],
388        Count       => 1,
389    },
390);
391
392for my $Test (@Tests) {
393
394    my $ProcessList = $ProcessObject->ProcessSearch( ProcessName => $Test->{ProcessName} );
395
396    $Self->Is(
397        scalar keys @{$ProcessList},
398        $Test->{Count},
399        "$Test->{Name} | Number of processes List is as expected: $Test->{Count}.",
400    );
401
402    $Self->IsDeeply(
403        $ProcessList,
404        $Test->{Result},
405        "$Test->{Name} | Result of process search is as expected.",
406    );
407
408}
409
410#
411# ProcessGet()
412#
413
414@Tests = (
415    {
416        Name    => 'ProcessGet Test 1: No params',
417        Config  => {},
418        Success => 0,
419    },
420    {
421        Name   => 'ProcessGet Test 2: No ID and EntityID',
422        Config => {
423            ID            => undef,
424            EntityID      => undef,
425            ActivityNames => 0,
426            UserID        => $UserID,
427        },
428        Success => 0,
429    },
430    {
431        Name   => 'ProcessGet Test 3: No UserID',
432        Config => {
433            ID            => 1,
434            EntityID      => undef,
435            ActivityNames => 0,
436            UserID        => undef,
437        },
438        Success => 0,
439    },
440    {
441        Name   => 'ProcessGet Test 4: Wrong ID',
442        Config => {
443            ID            => '9999999',
444            EntityID      => undef,
445            ActivityNames => 0,
446            UserID        => $UserID,
447        },
448        Success => 0,
449    },
450    {
451        Name   => 'ProcessGet Test 5: Wrong EntityID',
452        Config => {
453            ID            => undef,
454            EntityID      => '9999999',
455            ActivityNames => 0,
456            UserID        => $UserID,
457        },
458        Success => 0,
459    },
460    {
461        Name   => 'ProcessGet Test 6: Correct ASCII, W/ID, WO/ActivityNames ',
462        Config => {
463            ID            => $AddedProcessList[0],
464            EntityID      => undef,
465            ActivityNames => 0,
466            UserID        => $UserID,
467        },
468        Success => 1,
469    },
470    {
471        Name   => 'ProcessGet Test 7: Correct ASCII, W/ID, W/ActivityNames ',
472        Config => {
473            ID            => $AddedProcessList[0],
474            EntityID      => undef,
475            ActivityNames => 1,
476            UserID        => $UserID,
477        },
478        Success => 1,
479    },
480    {
481        Name   => 'ProcessGet Test 8: Correct UTF8, W/ID, WO/ActivityNames ',
482        Config => {
483            ID            => $AddedProcessList[1],
484            EntityID      => undef,
485            ActivityNames => 0,
486            UserID        => $UserID,
487        },
488        Success => 1,
489    },
490    {
491        Name   => 'ProcessGet Test 9: Correct UTF8, W/ID, W/ActivityNames ',
492        Config => {
493            ID            => $AddedProcessList[1],
494            EntityID      => undef,
495            ActivityNames => 1,
496            UserID        => $UserID,
497        },
498        Success => 1,
499    },
500    {
501        Name   => 'ProcessGet Test 11: Correct UTF82, W/ID, WO/ActivityNames ',
502        Config => {
503            ID            => $AddedProcessList[2],
504            EntityID      => undef,
505            ActivityNames => 0,
506            UserID        => $UserID,
507        },
508        Success => 1,
509    },
510    {
511        Name   => 'ProcessGet Test 12: Correct UTF82, W/ID, W/ActivityNames ',
512        Config => {
513            ID            => $AddedProcessList[2],
514            EntityID      => undef,
515            ActivityNames => 1,
516            UserID        => $UserID,
517        },
518        Success => 1,
519    },
520    {
521        Name   => 'ProcessGet Test 13: Correct ASCII, W/EntityID, WO/ActivityNames ',
522        Config => {
523            ID            => undef,
524            EntityID      => $AddedProcess{ $AddedProcessList[0] }->{EntityID},
525            ActivityNames => 0,
526            UserID        => $UserID,
527        },
528        Success => 1,
529    },
530    {
531        Name   => 'ProcessGet Test 14: Correct ASCII, W/EntityID, W/ActivityNames ',
532        Config => {
533            ID            => undef,
534            EntityID      => $AddedProcess{ $AddedProcessList[0] }->{EntityID},
535            ActivityNames => 1,
536            UserID        => $UserID,
537        },
538        Success => 1,
539    },
540    {
541        Name   => 'ProcessGet Test 15: Correct UTF8, W/EntityID, WO/ActivityNames ',
542        Config => {
543            ID            => undef,
544            EntityID      => $AddedProcess{ $AddedProcessList[1] }->{EntityID},
545            ActivityNames => 0,
546            UserID        => $UserID,
547        },
548        Success => 1,
549    },
550    {
551        Name   => 'ProcessGet Test 16: Correct UTF8, W/EntityID, W/ActivityNames ',
552        Config => {
553            ID            => undef,
554            EntityID      => $AddedProcess{ $AddedProcessList[1] }->{EntityID},
555            ActivityNames => 1,
556            UserID        => $UserID,
557        },
558        Success => 1,
559    },
560    {
561        Name   => 'ProcessGet Test 17: Correct UTF82, W/EntityID, WO/ActivityNames ',
562        Config => {
563            ID            => undef,
564            EntityID      => $AddedProcess{ $AddedProcessList[2] }->{EntityID},
565            ActivityNames => 0,
566            UserID        => $UserID,
567        },
568        Success => 1,
569    },
570    {
571        Name   => 'ProcessGet Test 18: Correct UTF82, W/EntityID, W/ActivityNames ',
572        Config => {
573            ID            => undef,
574            EntityID      => $AddedProcess{ $AddedProcessList[2] }->{EntityID},
575            ActivityNames => 1,
576            UserID        => $UserID,
577        },
578        Success => 1,
579    },
580);
581
582for my $Test (@Tests) {
583    my $Process = $ProcessObject->ProcessGet( %{ $Test->{Config} } );
584
585    if ( $Test->{Success} ) {
586        $Self->Is(
587            ref $Process,
588            'HASH',
589            "$Test->{Name} | Process structure is HASH",
590        );
591        $Self->True(
592            IsHashRefWithData($Process),
593            "$Test->{Name} | Process structure is non empty HASH",
594        );
595        if ( $Test->{Config}->{ActivityNames} ) {
596            $Self->Is(
597                ref $Process->{Activities},
598                'HASH',
599                "$Test->{Name} | Process Activities structure is HASH",
600            );
601
602            my %ExpectedActivities = map { $_ => $ActivityLookup{$_} }
603                sort keys %{ $AddedProcess{ $Process->{ID} }->{Config}->{Path} };
604            $Self->IsDeeply(
605                $Process->{Activities},
606                \%ExpectedActivities,
607                "$Test->{Name} | Process Activities"
608            );
609        }
610        else {
611            $Self->Is(
612                ref $Process->{Activities},
613                'ARRAY',
614                "$Test->{Name} | Process Activities structure is ARRAY",
615            );
616
617            my @ExpectedActivities = map {$_} sort keys %{ $AddedProcess{ $Process->{ID} }->{Config}->{Path} };
618            $Self->IsDeeply(
619                $Process->{Activities},
620                \@ExpectedActivities,
621                "$Test->{Name} | Process Activities"
622            );
623        }
624
625        my $ActivityNames = 0;
626        if ( defined $Test->{Config}->{ActivityNames} && $Test->{Config}->{ActivityNames} == 1 ) {
627            $ActivityNames = 1;
628        }
629
630        my $TransitionNames = 0;
631        if ( defined $Test->{Config}->{TransitionNames} && $Test->{Config}->{TransitionNames} == 1 )
632        {
633            $TransitionNames = 1;
634        }
635
636        my $TransitionActionNames = 0;
637        if (
638            defined $Test->{Config}->{TransitionActionNames}
639            && $Test->{Config}->{TransitionActionNames} == 1
640            )
641        {
642            $TransitionActionNames = 1;
643        }
644
645        # check cache
646        my $CacheKey;
647        if ( $Test->{Config}->{ID} ) {
648            $CacheKey = join '::', 'ProcessGet::ID', $Test->{Config}->{ID}, 'ActivityNames',
649                $ActivityNames,
650                'TransitionNames',
651                $TransitionNames,
652                'TransitionActionNames',
653                $TransitionActionNames;
654        }
655        else {
656            $CacheKey = join '::', 'ProcessGet::EntityID', $Test->{Config}->{EntityID},
657                'ActivityNames',
658                $ActivityNames,
659                'TransitionNames',
660                $TransitionNames,
661                'TransitionActionNames',
662                $TransitionActionNames;
663        }
664
665        my $Cache = $CacheObject->Get(
666            Type => 'ProcessManagement_Process',
667            Key  => $CacheKey,
668        );
669
670        $Self->IsDeeply(
671            $Cache,
672            $Process,
673            "$Test->{Name} | Process cache"
674        );
675
676        # remove not need parameters
677        my %ExpectedProcess = %{ $AddedProcess{ $Process->{ID} } };
678        delete $ExpectedProcess{UserID};
679
680        # create a variable copy otherwise the cache will be altered
681        my %ProcessCopy = %{$Process};
682
683        for my $Attribute (
684            qw(ID Activities Transitions TransitionActions CreateTime ChangeTime State)
685            )
686        {
687            $Self->IsNot(
688                $ProcessCopy{$Attribute},
689                undef,
690                "$Test->{Name} | Process->{$Attribute} should not be undef",
691            );
692            delete $ProcessCopy{$Attribute};
693        }
694
695        $Self->IsDeeply(
696            \%ProcessCopy,
697            \%ExpectedProcess,
698            "$Test->{Name} | Process"
699        );
700    }
701    else {
702        $Self->False(
703            ref $Process eq 'HASH',
704            "$Test->{Name} | Process structure is not HASH",
705        );
706        $Self->Is(
707            $Process,
708            undef,
709            "$Test->{Name} | Process should be undefined",
710        );
711    }
712}
713
714#
715# ProcessUpdate() tests
716#
717@Tests = (
718    {
719        Name    => 'ProcessUpdate Test 1: No params',
720        Config  => {},
721        Success => 0,
722    },
723    {
724        Name   => 'ProcessUpdate Test 2: No ID',
725        Config => {
726            ID            => undef,
727            EntityID      => $RandomID . '-U',
728            Name          => "Process-$RandomID",
729            StateEntityID => 'S1',
730            Layout        => {},
731            Config        => {
732                Description => 'a Description',
733            },
734            UserID => $UserID,
735        },
736        Success => 0,
737    },
738    {
739        Name   => 'ProcessUpdate Test 3: No EntityID',
740        Config => {
741            ID            => 1,
742            EntityID      => undef,
743            Name          => "Process-$RandomID",
744            StateEntityID => 'S1',
745            Layout        => {},
746            Config        => {
747                Description => 'a Description',
748            },
749            UserID => $UserID,
750        },
751        Success => 0,
752    },
753    {
754        Name   => 'ProcessUpdate Test 5: No Name',
755        Config => {
756            ID            => 1,
757            EntityID      => $RandomID . '-U',
758            Name          => undef,
759            StateEntityID => 'S1',
760            Layout        => {},
761            Config        => {
762                Description => 'a Description',
763            },
764            UserID => $UserID,
765        },
766        Success => 0,
767    },
768    {
769        Name   => 'ProcessUpdate Test 6: No StateEntityID',
770        Config => {
771            ID            => 1,
772            EntityID      => $RandomID . '-U',
773            Name          => "Process-$RandomID",
774            StateEntityID => undef,
775            Layout        => {},
776            Config        => {
777                Description => 'a Description',
778            },
779            UserID => $UserID,
780        },
781        Success => 0,
782    },
783    {
784        Name   => 'ProcessUpdate Test 7: No Layout',
785        Config => {
786            ID            => 1,
787            EntityID      => $RandomID . '-U',
788            Name          => "Process-$RandomID",
789            StateEntityID => 'S1',
790            Layout        => undef,
791            Config        => {
792                Description => 'a Description',
793            },
794            UserID => $UserID,
795        },
796        Success => 0,
797    },
798    {
799        Name   => 'ProcessUpdate Test 7: No Layout',
800        Config => {
801            ID            => 1,
802            EntityID      => $RandomID . '-U',
803            Name          => "Process-$RandomID",
804            StateEntityID => 'S1',
805            Layout        => undef,
806            Config        => {
807                Description => 'a Description',
808            },
809            UserID => $UserID,
810        },
811        Success => 0,
812    },
813    {
814        Name   => 'ProcessUpdate Test 9: No Config',
815        Config => {
816            ID            => 1,
817            EntityID      => $RandomID . '-U',
818            Name          => "Process-$RandomID",
819            StateEntityID => 'S1',
820            Layout        => {},
821            Config        => undef,
822            UserID        => $UserID,
823        },
824        Success => 0,
825    },
826    {
827        Name   => 'ProcessUpdate Test 10: No UserID',
828        Config => {
829            ID            => 1,
830            EntityID      => $RandomID . '-U',
831            Name          => "Process-$RandomID",
832            StateEntityID => 'S1',
833            Layout        => {},
834            Config        => {
835                Description => 'a Description',
836            },
837            UserID => undef,
838        },
839        Success => 0,
840    },
841    {
842        Name   => 'ProcessUpdate Test 11: Correct ASCII',
843        Config => {
844            ID            => $AddedProcessList[0],
845            EntityID      => $RandomID . '-U',
846            Name          => "Process-$RandomID -U",
847            StateEntityID => 'S1',
848            Layout        => {},
849            Config        => {
850                Description => 'a Description-U',
851            },
852            UserID => $UserID,
853        },
854        Success  => 1,
855        UpdateDB => 1
856    },
857    {
858        Name   => 'ProcessUpdate Test 12: Correct UTF8',
859        Config => {
860            ID            => $AddedProcessList[1],
861            EntityID      => $RandomID . '-1-U',
862            Name          => "Process-$RandomID -!§$%&/()=?Ü*ÄÖL:L@,.--U",
863            StateEntityID => 'S1',
864            Layout        => {},
865            Config        => {
866                Description => 'a Description §$%&/()=?Ü*ÄÖL:L@,.--U',
867            },
868            UserID => $UserID,
869        },
870        Success  => 1,
871        UpdateDB => 1
872    },
873    {
874        Name   => 'ProcessUpdate Test 13: Correct UTF8 2',
875        Config => {
876            ID            => $AddedProcessList[1],
877            EntityID      => $RandomID . '-2-U',
878            Name          => "Process-$RandomID -äöüßÄÖÜ€исáéíúóúÁÉÍÓÚñÑ-U",
879            StateEntityID => 'S1',
880            Layout        => {},
881            Config        => {
882                Description => 'a Description -äöüßÄÖÜ€исáéíúóúÁÉÍÓÚñÑ-U',
883            },
884            UserID => $UserID,
885        },
886        Success  => 1,
887        UpdateDB => 1
888    },
889    {
890        Name   => 'ProcessUpdate Test 14: Correct ASCII No DBUpdate',
891        Config => {
892            ID            => $AddedProcessList[0],
893            EntityID      => $RandomID . '-U',
894            Name          => "Process-$RandomID -U",
895            StateEntityID => 'S1',
896            Layout        => {},
897            Config        => {
898                Description => 'a Description-U',
899            },
900            UserID => $UserID,
901        },
902        Success  => 1,
903        UpdateDB => 0,
904    },
905);
906
907for my $Test (@Tests) {
908
909    # get the old process (if any)
910    my $OldProcess = $ProcessObject->ProcessGet(
911        ID     => $Test->{Config}->{ID} || 0,
912        UserID => $Test->{Config}->{UserID},
913    );
914
915    if ( $Test->{Success} ) {
916
917        # try to update the process
918        print "Force a gap between create and update process, Waiting 2s\n";
919
920        # wait 2 seconds
921        $Helper->FixedTimeAddSeconds(2);
922
923        my $Success = $ProcessObject->ProcessUpdate( %{ $Test->{Config} } );
924
925        $Self->IsNot(
926            $Success,
927            0,
928            "$Test->{Name} | Result should be 1"
929        );
930
931        # check cache
932        my $CacheKey = 'ProcessGet::ID::'
933            . $Test->{Config}->{ID}
934            . '::ActivityNames::0::TransitionNames::0::TransitionActionNames::0';
935
936        my $Cache = $CacheObject->Get(
937            Type => 'ProcessManagement_Process',
938            Key  => $CacheKey,
939        );
940
941        if ( $Test->{UpdateDB} ) {
942            $Self->Is(
943                $Cache,
944                undef,
945                "$Test->{Name} | Cache should be deleted after update, should be undef",
946            );
947        }
948        else {
949            $Self->IsNot(
950                $Cache,
951                undef,
952                "$Test->{Name} | Cache should not be deleted after update, since no update needed",
953            );
954        }
955
956        # get the new process
957        my $NewProcess = $ProcessObject->ProcessGet(
958            ID     => $Test->{Config}->{ID},
959            UserID => $Test->{Config}->{UserID},
960        );
961
962        # check cache
963        $Cache = $CacheObject->Get(
964            Type => 'ProcessManagement_Process',
965            Key  => $CacheKey,
966        );
967
968        $Self->IsDeeply(
969            $Cache,
970            $NewProcess,
971            "$Test->{Name} | Cache is equal to updated process",
972        );
973
974        if ( $Test->{UpdateDB} ) {
975            $Self->IsNotDeeply(
976                $NewProcess,
977                $OldProcess,
978                "$Test->{Name} | Updated process is different than original",
979            );
980
981            # check create and change times
982            $Self->Is(
983                $NewProcess->{CreateTime},
984                $OldProcess->{CreateTime},
985                "$Test->{Name} | Updated process create time should not change",
986            );
987            $Self->IsNot(
988                $NewProcess->{ChangeTime},
989                $OldProcess->{ChangeTime},
990                "$Test->{Name} | Updated process change time should be different",
991            );
992
993            # remove not need parameters
994            my %ExpectedProcess = %{ $Test->{Config} };
995            delete $ExpectedProcess{UserID};
996
997            # create a variable copy otherwise the cache will be altered
998            my %NewProcessCopy = %{$NewProcess};
999
1000            for my $Attribute (
1001                qw( Activities Transitions TransitionActions CreateTime ChangeTime State)
1002                )
1003            {
1004                delete $NewProcessCopy{$Attribute};
1005            }
1006
1007            $Self->IsDeeply(
1008                \%NewProcessCopy,
1009                \%ExpectedProcess,
1010                "$Test->{Name} | Process"
1011            );
1012        }
1013        else {
1014            $Self->IsDeeply(
1015                $NewProcess,
1016                $OldProcess,
1017                "$Test->{Name} | Updated process is equal than original",
1018            );
1019        }
1020    }
1021    else {
1022        my $Success = $ProcessObject->ProcessUpdate( %{ $Test->{Config} } );
1023
1024        $Self->False(
1025            $Success,
1026            "$Test->{Name} | Result should fail",
1027        );
1028    }
1029}
1030
1031#
1032# ProcessList() tests
1033#
1034
1035# no params
1036my $TestProcessList = $ProcessObject->ProcessList();
1037
1038$Self->Is(
1039    $TestProcessList,
1040    undef,
1041    "ProcessList Test 1: No Params | Should be undef",
1042);
1043
1044# normal process list
1045$TestProcessList = $ProcessObject->ProcessList( UserID => $UserID );
1046
1047$Self->Is(
1048    ref $TestProcessList,
1049    'HASH',
1050    "ProcessList Test 2: All Process | Should be a HASH",
1051);
1052
1053$Self->True(
1054    IsHashRefWithData($TestProcessList),
1055    "ProcessList Test 2: All Process | Should be not empty HASH",
1056);
1057
1058$Self->IsNotDeeply(
1059    $TestProcessList,
1060    $OriginalProcessList,
1061    "ProcessList Test 2: All Process | Should be different than the original",
1062);
1063
1064# create a variable copy otherwise the cache will be altered
1065my %TestProcessListCopy = %{$TestProcessList};
1066
1067# delete original process
1068for my $ProcessID ( sort keys %{$OriginalProcessList} ) {
1069    delete $TestProcessListCopy{$ProcessID};
1070}
1071
1072$Self->Is(
1073    scalar keys %TestProcessListCopy,
1074    scalar @AddedProcessList,
1075    "ProcessList Test 2: All Process | Number of processes match added processes",
1076);
1077
1078my $Counter = 0;
1079for my $ProcessID ( sort { $a cmp $b } keys %TestProcessListCopy ) {
1080    $Self->Is(
1081        $ProcessID,
1082        $AddedProcessList[$Counter],
1083        "ProcessList Test 2: All Process | ProcessID match AddedProcessID",
1084    );
1085    $Counter++;
1086}
1087
1088# prepare process for listing
1089my $Process = $ProcessObject->ProcessGet(
1090    ID     => $AddedProcessList[0],
1091    UserID => $UserID,
1092);
1093my $Success = $ProcessObject->ProcessUpdate(
1094    ID => $AddedProcessList[0],
1095    %{$Process},
1096    StateEntityID => 'S1',
1097    UserID        => 1,
1098);
1099
1100$Self->IsNot(
1101    $Success,
1102    0,
1103    "ProcessList | Updated process for ProcessID:'$AddedProcessList[0]' result should be 1",
1104);
1105
1106for my $Index ( 1, 2 ) {
1107
1108    my $Process = $ProcessObject->ProcessGet(
1109        ID     => $AddedProcessList[$Index],
1110        UserID => $UserID,
1111    );
1112    my $Success = $ProcessObject->ProcessUpdate(
1113        ID => $AddedProcessList[$Index],
1114        %{$Process},
1115        StateEntityID => 'S2',
1116        UserID        => 1,
1117    );
1118
1119    $Self->IsNot(
1120        $Success,
1121        0,
1122        "ProcessList | Updated process for ProcessID:'$AddedProcessList[$Index]' result should be 1",
1123    );
1124}
1125
1126@Tests = (
1127    {
1128        Name   => 'ProcessList Test3: State S1',
1129        Config => {
1130            UseEntities    => 0,
1131            StateEntityIDs => ['S1'],
1132            UserID         => $UserID,
1133        },
1134    },
1135    {
1136        Name   => 'ProcessList Test3: State S2',
1137        Config => {
1138            UseEntities    => 0,
1139            StateEntityIDs => ['S2'],
1140            UserID         => $UserID,
1141        },
1142    },
1143    {
1144        Name   => 'ProcessList Test4: State S3',
1145        Config => {
1146            UseEntities    => 0,
1147            StateEntityIDs => ['S3'],
1148            UserID         => $UserID,
1149        },
1150    },
1151    {
1152        Name   => 'ProcessList Test5: State S1, State S2, State S3',
1153        Config => {
1154            UseEntities    => 0,
1155            StateEntityIDs => [ 'S1', 'S2', 'S3' ],
1156            UserID         => $UserID,
1157        },
1158        AllProcess => 1,
1159    },
1160    {
1161        Name   => 'ProcessList Test6: Empty list',
1162        Config => {
1163            UseEntities    => 0,
1164            StateEntityIDs => [$RandomID],
1165            UserID         => $UserID,
1166        },
1167        EmptyList => 1,
1168    },
1169);
1170
1171for my $Test (@Tests) {
1172    my $ProcessList = $ProcessObject->ProcessList( %{ $Test->{Config} } );
1173
1174    # create a variable copy otherwise the cache will be altered
1175    my %ProcessListCopy = %{$ProcessList};
1176
1177    # remove original processes
1178    PROCESSID:
1179    for my $ProcessID ( sort keys %{$OriginalProcessList} ) {
1180        next PROCESSID if !$ProcessListCopy{$ProcessID};
1181        delete $ProcessListCopy{$ProcessID};
1182    }
1183
1184    # special case for empty list
1185    if ( $Test->{EmptyList} ) {
1186        $Self->False(
1187            scalar keys %ProcessListCopy,
1188            "$Test->{Name} | List is empty",
1189        );
1190    }
1191    else {
1192
1193        # special case for all process
1194        if ( $Test->{AllProcess} ) {
1195            $Self->IsDeeply(
1196                \%ProcessListCopy,
1197                \%TestProcessListCopy,
1198                "$Test->{Name} | List is identical as in no State filter",
1199            );
1200        }
1201        else {
1202            $Self->IsNotDeeply(
1203                \%ProcessListCopy,
1204                \%TestProcessListCopy,
1205                "$Test->{Name} | List is different as in no State filter",
1206            );
1207
1208            $Self->IsNot(
1209                scalar keys %ProcessListCopy,
1210                scalar keys %TestProcessListCopy,
1211                "$Test->{Name} | Number of processes List is different as in no State filter",
1212            );
1213        }
1214    }
1215}
1216
1217#
1218# ProcessDelete() (test for fail, test for success are done by removing processes at the end)
1219#
1220@Tests = (
1221    {
1222        Name    => 'ProcessDelete Test 1: No params',
1223        Config  => {},
1224        Success => 0,
1225    },
1226    {
1227        Name   => 'ProcessDelete Test 2: No process ID',
1228        Config => {
1229            ID     => undef,
1230            UserID => $RandomID,
1231        },
1232        Success => 0,
1233    },
1234    {
1235        Name   => 'ProcessDelete Test 3: No UserID',
1236        Config => {
1237            ID     => $RandomID,
1238            UserID => undef,
1239        },
1240        Success => 0,
1241    },
1242    {
1243        Name   => 'ProcessDelete Test 4: Wrong process ID',
1244        Config => {
1245            ID     => '9999999',
1246            UserID => $UserID,
1247        },
1248        Success => 0,
1249    },
1250);
1251
1252for my $Test (@Tests) {
1253    my $Success = $ProcessObject->ProcessDelete( %{ $Test->{Config} } );
1254
1255    if ( $Test->{Success} ) {
1256        $Self->True(
1257            $Success,
1258            "$Test->{Name} | Process deleted with true",
1259        );
1260    }
1261    else {
1262        $Self->False(
1263            $Success,
1264            "$Test->{Name} | Process delete with false",
1265        );
1266    }
1267}
1268
1269#
1270# ProcessListGet() tests
1271#
1272
1273my $FullList = $ProcessObject->ProcessListGet(
1274    UserID => undef,
1275);
1276
1277$Self->IsNot(
1278    ref $FullList,
1279    'ARRAY',
1280    "ProcessListGet Test 1: No UserID | List Should not be an array",
1281);
1282
1283# get the List of processes with all details
1284$FullList = $ProcessObject->ProcessListGet(
1285    UserID => $UserID,
1286);
1287
1288# get simple list of processes
1289my $List = $ProcessObject->ProcessList(
1290    UserID => $UserID,
1291);
1292
1293# create the list of processes with details manually
1294my $ExpectedProcessList;
1295for my $ProcessID ( sort { int $a <=> int $b } keys %{$List} ) {
1296
1297    my $ProcessData = $ProcessObject->ProcessGet(
1298        ID     => $ProcessID,
1299        UserID => $UserID,
1300    );
1301    push @{$ExpectedProcessList}, $ProcessData;
1302}
1303
1304$Self->Is(
1305    ref $FullList,
1306    'ARRAY',
1307    "ProcessListGet Test 2: Correct List | Should be an array",
1308);
1309
1310$Self->True(
1311    IsArrayRefWithData($FullList),
1312    "ProcessListGet Test 2: Correct List | The list is not empty",
1313);
1314
1315$Self->IsDeeply(
1316    $FullList,
1317    $ExpectedProcessList,
1318    "ProcessListGet Test 2: Correct List | Process List",
1319);
1320
1321# check cache
1322my $CacheKey = 'ProcessListGet';
1323
1324my $Cache = $CacheObject->Get(
1325    Type => 'ProcessManagement_Process',
1326    Key  => $CacheKey,
1327);
1328
1329$Self->IsDeeply(
1330    $Cache,
1331    $FullList,
1332    "ProcessListGet Test 2: Correct List | Cache",
1333);
1334
1335# cleanup is done by RestoreDatabase
1336
13371;
1338