
######
Helper
######


****
NAME
****


Kernel::System::UnitTest::Helper - unit test helper functions

new()
=====


construct a helper object.


.. code-block:: perl

     use Kernel::System::ObjectManager;
     local $Kernel::OM = Kernel::System::ObjectManager->new(
         'Kernel::System::UnitTest::Helper' => {
             RestoreDatabase => 1,                   # runs the test in a transaction,
                                                     # and roll it back in the destructor
                                                     #
                                                     # NOTE: Rollback does not work for
                                                     # changes in the database layout. If you
                                                     # want to do this in your tests, you cannot
                                                     # use this option and must handle the rollback
                                                     # yourself.
         },
     );
     my $HelperObject = $Kernel::OM->Get('Kernel::System::UnitTest::Helper');



GetRandomID()
=============


creates a random ID that can be used in tests as a unique identifier.

It is guaranteed that within a test this function will never return a duplicate.

Please note that these numbers are not really random and should only be used
to create test data.


.. code-block:: perl

     my $RandomID = $HelperObject->GetRandomID();


Returns:


.. code-block:: perl

     my $RandomID = 'test2735808026700610';



GetRandomNumber()
=================


creates a random Number that can be used in tests as a unique identifier.

It is guaranteed that within a test this function will never return a duplicate.

Please note that these numbers are not really random and should only be used
to create test data.


.. code-block:: perl

     my $RandomNumber = $HelperObject->GetRandomNumber();


Returns:


.. code-block:: perl

     my $RandomNumber = '2735808026700610';



TestUserCreate()
================


creates a test user that can be used in tests. It will
be set to invalid automatically during `DESTROY()`_. Returns
the login name of the new user, the password is the same.


.. code-block:: perl

     my $TestUserLogin = $HelperObject->TestUserCreate(
         Groups    => ['admin', 'users'],         # optional, list of groups to add this user to (rw rights)
         Language  => 'de',                       # optional, defaults to 'en' if not set
         KeepValid => 1,                          # optional, defaults to 0
     );


Returns:


.. code-block:: perl

     my $TestUserLogin = 'test2755008034702000';


To get UserLogin and UserID:


.. code-block:: perl

     my ( $TestUserLogin, $TestUserID ) = $HelperObject->TestUserCreate(
         Groups    => ['admin', 'users'],
         Language  => 'de',
         KeepValid => 1,
     );
 
     my $TestUserLogin = 'test2755008034702000';
     my $TestUserID    = '123';



TestCustomerUserCreate()
========================


creates a test customer user that can be used in tests. It will
be set to invalid automatically during `DESTROY()`_. Returns
the login name of the new customer user, the password is the same.


.. code-block:: perl

     my $TestCustomerUserLogin = $HelperObject->TestCustomerUserCreate(
         Language  => 'de',   # optional, defaults to 'en' if not set
         KeepValid => 1,      # optional, defaults to 0
     );


Returns:


.. code-block:: perl

     my $TestCustomerUserLogin = 'test2735808026700610';



BeginWork()
===========


Starts a database transaction (in order to isolate the test from the static database).


.. code-block:: perl

     $HelperObject->BeginWork();



Rollback()
==========


Rolls back the current database transaction.


.. code-block:: perl

     $HelperObject->Rollback();



GetTestHTTPHostname()
=====================


Returns a host name for HTTP based tests, possibly including the port.


.. code-block:: perl

     my $Hostname = $HelperObject->GetTestHTTPHostname();


Returns:
    my $Hostname = 'localhost';


FixedTimeSet()
==============


makes it possible to override the system time as long as this object lives.
You can pass an optional time parameter that should be used, if not,
the current system time will be used.

All calls to methods of Kernel::System::Time and Kernel::System::DateTime will
use the given time afterwards.


.. code-block:: perl

     # with Timestamp
     my $Timestamp = $HelperObject->FixedTimeSet(366475757);
 
     # with previously created DateTime object
     my $Timestamp = $HelperObject->FixedTimeSet($DateTimeObject);
 
     # set to current date and time
     my $Timestamp = $HelperObject->FixedTimeSet();


Returns:


.. code-block:: perl

     # date/time as seconds
     my $Timestamp = 1454420017;



FixedTimeUnset()
================


Restores the regular system time behavior.


.. code-block:: perl

     $HelperObject->FixedTimeUnset();



FixedTimeAddSeconds()
=====================


Adds a number of seconds to the fixed system time which was previously
set by FixedTimeSet(). You can pass a negative value to go back in time.


.. code-block:: perl

     $HelperObject->FixedTimeAddSeconds(5);



DESTROY()
=========


performs various clean-ups.


ConfigSettingChange()
=====================


temporarily change a configuration setting system wide to another value,
both in the current ConfigObject and also in the system configuration on disk.

This will be reset when the Helper object is destroyed.

Please note that this will not work correctly in clustered environments.


.. code-block:: perl

     $HelperObject->ConfigSettingChange(
         Valid => 1,            # (optional) enable or disable setting
         Key   => 'MySetting',  # setting name
         Value => { ... } ,     # setting value
     );



CustomCodeActivate()
====================


Temporarily include custom code in the system. For example, you may use this to redefine a
subroutine from another class. This change will persist for remainder of the test.

All code will be removed when the Helper object is destroyed.

Please note that this will not work correctly in clustered environments.


.. code-block:: perl

     $HelperObject->CustomCodeActivate(
         Code => q^
 sub Kernel::Config::Files::ZZZZUnitTestIdentifier::Load {} # no-op, avoid warning logs
 use Kernel::System::WebUserAgent;
 package Kernel::System::WebUserAgent;
 use strict;
 use warnings;
 {
     no warnings 'redefine';
     sub Request {
         my $JSONString = '{"Results":{},"ErrorMessage":"","Success":1}';
         return (
             Content => \$JSONString,
             Status  => '200 OK',
         );
     }
 }
 1;^,
         Identifier => 'News',   # (optional) Code identifier to include in file name
     );



CustomFileCleanup()
===================


Removes all custom files from \ ``ConfigSettingChange()``\  and \ ``CustomCodeActivate()``\ .


.. code-block:: perl

     $HelperObject->CustomFileCleanup();



UseTmpArticleDir()
==================


Switch the article storage directory to a temporary one to prevent collisions;


.. code-block:: perl

     $HelperObject->UseTmpArticleDir();



DisableAsyncCalls()
===================


Disable scheduling of asynchronous tasks using \ ``AsynchronousExecutor``\  component of System daemon.


.. code-block:: perl

     $HelperObject->DisableAsyncCalls();



_DisableDefaultSysConfigSettings()
==================================


These SysConfig options are disabled by default.


DisableSysConfigs()
===================


Disables SysConfigs for current UnitTest.


.. code-block:: perl

     $HelperObject->DisableSysConfigs(
         DisableSysConfigs => [
             'Ticket::Responsible'
             'DashboardBackend###0442-RSS'
         ],
     );
 
     $Kernel::OM->ObjectParamAdd(
         'Kernel::System::UnitTest::Helper' => {
             DisableSysConfigs => [
                 'Ticket::Responsible'
                 'DashboardBackend###0442-RSS'
             ],
         },
     );



ProvideTestDatabase()
=====================


Provide temporary database for the test. Please first define test database settings in \ ``Config.pm``\ , i.e:


.. code-block:: perl

     $Self->{TestDatabase} = {
         DatabaseDSN  => 'DBI:mysql:database=otrs_test;host=127.0.0.1;',
         DatabaseUser => 'otrs_test',
         DatabasePw   => 'otrs_test',
     };


The method call will override global database configuration for duration of the test, i.e. temporary database will
receive all calls sent over system \ ``DBObject``\ .

All database contents will be automatically dropped when the Helper object is destroyed.


.. code-block:: perl

     $HelperObject->ProvideTestDatabase(
         DatabaseXMLString => $XML,      # (optional) database XML schema to execute
                                         # or
         DatabaseXMLFiles => [           # (optional) List of XML files to load and execute
             '/opt/znuny/scripts/database/schema.xml',
             '/opt/znuny/scripts/database/initial_insert.xml',
         ],
     );


This method returns 'undef' in case the test database is not configured. If it is configured, but the supplied XML cannot be read or executed, this method will \ ``die()``\  to interrupt the test with an error.


TestDatabaseCleanup()
=====================


Clears temporary database used in the test. Always call \ ``ProvideTestDatabase()``\  called first, in
order to set it up.

Please note that all database contents will be dropped, USE WITH CARE!


.. code-block:: perl

     $HelperObject->TestDatabaseCleanup();



DatabaseXMLExecute()
====================


Execute supplied XML against current database. Content of supplied XML or XMLFilename parameter must be valid OTRS
database XML schema.


.. code-block:: perl

     $HelperObject->DatabaseXMLExecute(
         XML => $XML,                 # OTRS database XML schema to execute
     );


Alternatively, it can also load an XML file to execute:


.. code-block:: perl

     $HelperObject->DatabaseXMLExecute(
         XMLFile => '/path/to/file',  # OTRS database XML file to execute
     );



DynamicFieldSet()
=================


This function will set a dynamic field value for a object.


.. code-block:: perl

     my $Success = $HelperObject->DynamicFieldSet(
         Field      => 'DF1',
         ObjectID   => 123,
         Value      => '123',
     );


or


.. code-block:: perl

     my $Success = $HelperObject->DynamicFieldSet(
         Field          => 'DF1',
         ObjectID       => 123,
         Value          => '123',
         UserID         => 123, # optional
     );


Returns:


.. code-block:: perl

     my $Success = 1;



FixedTimeSetByDate()
====================


This function is a convenience wrapper around the FixedTimeSet function of this object which makes it
possible to set a fixed time by using Year, Month, Day and optional Hour, Minute, Second parameters.


.. code-block:: perl

     $HelperObject->FixedTimeSetByDate(
         Year   => 2016,
         Month  => 4,
         Day    => 28,
         Hour   => 10, # default 0
         Minute => 0,  # default 0
         Second => 0,  # default 0
     );



FixedTimeSetByTimeStamp()
=========================


This function is a convenience wrapper around the FixedTimeSet function of this object which makes it
possible to set a fixed time by using parameters for the TimeObject TimeStamp2SystemTime function.


.. code-block:: perl

     $HelperObject->FixedTimeSetByTimeStamp('2004-08-14 22:45:00');



CheckNumberOfEventExecution()
=============================


This function checks the number of executions of an Event via the TicketHistory


.. code-block:: perl

     my $Result = $HelperObject->CheckNumberOfEventExecution(
         TicketID => $TicketID,
         Comment  => 'after article create',
         Events   => {
             AnExampleHistoryEntry      => 2,
             AnotherExampleHistoryEntry => 0,
         },
     );



SetupTestEnvironment()
======================


This function calls a list of other helper functions to setup a test environment with various test data.


.. code-block:: perl

     my $Result = $HelperObject->SetupTestEnvironment(
         # ... # Parameters get passed to the FillTestEnvironment and ConfigureViews function
     );
 
     $Result = {
         # ... # Combined result of the ActivateDefaultDynamicFields, FillTestEnvironment and ConfigureViews functions
     }



ConfigureViews()
================


Toggles settings for a given view like AgentTicketNote or CustomerTicketMessage.


.. code-block:: perl

     my $Result = $HelperObject->ConfigureViews(
         AgentTicketNote => {
             Note             => 1,
             NoteMandatory    => 1,
             Owner            => 1,
             OwnerMandatory   => 1,
             Priority         => 1,
             PriorityDefault  => '3 normal',
             Queue            => 1,
             Responsible      => 1,
             Service          => 1,
             ServiceMandatory => 1,
             SLAMandatory     => 1,
             State            => 1,
             StateType        => ['open', 'closed', 'pending reminder', 'pending auto'],
             TicketType       => 1,
             Title            => 1,
         },
         CustomerTicketMessage => {
             Priority         => 1,
             Queue            => 1,
             Service          => 1,
             ServiceMandatory => 1,
             SLA              => 1,
             SLAMandatory     => 1,
             TicketType       => 1,
         },
     );
 
     $Result = {
         AgentTicketNote => {
             Note             => 1,
             NoteMandatory    => 1,
             Owner            => 1,
             OwnerMandatory   => 1,
             Priority         => 1,
             PriorityDefault  => '3 normal',
             Queue            => 1,
             Responsible      => 1,
             Service          => 1,
             ServiceMandatory => 1,
             SLAMandatory     => 1,
             State            => 1,
             StateType        => ['open', 'closed', 'pending reminder', 'pending auto'],
             TicketType       => 1,
             Title            => 1,
             HistoryType      => 'Phone',
             # ...
         },
         CustomerTicketMessage => {
             Priority         => 1,
             Queue            => 1,
             Service          => 1,
             ServiceMandatory => 1,
             SLA              => 1,
             SLAMandatory     => 1,
             TicketType       => 1,
             ArticleType      => 'note-external',
             # ...
         },
     }



ActivateDynamicFields()
=======================


This function activates the given DynamicFields in each agent view.


.. code-block:: perl

     $HelperObject->ActivateDynamicFields(
         'UnitTestDropdown',
         'UnitTestCheckbox',
         'UnitTestText',
         'UnitTestMultiSelect',
         'UnitTestTextArea',
         'UnitTestDate',
         'UnitTestDateTime',
     );



ActivateDefaultDynamicFields()
==============================


This function adds one of each default dynamic fields to the system and activates them for each agent view.


.. code-block:: perl

     my $Result = $HelperObject->ActivateDefaultDynamicFields();
 
     $Result = [
         {
             Name          => 'UnitTestText',
             Label         => "UnitTestText",
             ObjectType    => 'Ticket',
             FieldType     => 'Text',
             InternalField => 0,
             Config        => {
                 DefaultValue => '',
                 Link         => '',
             },
         },
         {
             Name          => 'UnitTestCheckbox',
             Label         => "UnitTestCheckbox",
             ObjectType    => 'Ticket',
             FieldType     => 'Checkbox',
             InternalField => 0,
             Config        => {
                 DefaultValue => "0",
             },
         },
         {
             Name          => 'UnitTestDropdown',
             Label         => "UnitTestDropdown",
             ObjectType    => 'Ticket',
             FieldType     => 'Dropdown',
             InternalField => 0,
             Config        => {
                 PossibleValues => {
                     Key  => "Value",
                     Key1 => "Value1",
                     Key2 => "Value2",
                     Key3 => "Value3",
                 },
                 DefaultValue       => "Key2",
                 TreeView           => '0',
                 PossibleNone       => '0',
                 TranslatableValues => '0',
                 Link               => '',
             },
         },
         {
             Name          => 'UnitTestTextArea',
             Label         => "UnitTestTextArea",
             ObjectType    => 'Ticket',
             FieldType     => 'TextArea',
             InternalField => 0,
             Config        => {
                 DefaultValue => '',
                 Rows         => '',
                 Cols         => '',
             },
         },
         {
             Name          => 'UnitTestMultiSelect',
             Label         => "UnitTestMultiSelect",
             ObjectType    => 'Ticket',
             FieldType     => 'Multiselect',
             InternalField => 0,
             Config        => {
                 PossibleValues => {
                     Key  => "Value",
                     Key1 => "Value1",
                     Key2 => "Value2",
                     Key3 => "Value3",
                 },
                 DefaultValue       => "Key2",
                 TreeView           => '0',
                 PossibleNone       => '0',
                 TranslatableValues => '0',
             },
         },
         {
             Name          => 'UnitTestDate',
             Label         => "UnitTestDate",
             ObjectType    => 'Ticket',
             FieldType     => 'Date',
             InternalField => 0,
             Config        => {
                 DefaultValue  => "0",
                 YearsPeriod   => "0",
                 YearsInFuture => "5",
                 YearsInPast   => "5",
                 Link          => '',
             },
         },
         {
             Name          => 'UnitTestDateTime',
             Label         => "UnitTestDateTime",
             ObjectType    => 'Ticket',
             FieldType     => 'DateTime',
             InternalField => 0,
             Config        => {
                 DefaultValue  => "0",
                 YearsPeriod   => "0",
                 YearsInFuture => "5",
                 YearsInPast   => "5",
                 Link          => '',
             },
         },
     ];



FullFeature()
=============


Activates Type, Service and Responsible feature.


.. code-block:: perl

     $HelperObject->FullFeature();



FillTestEnvironment()
=====================


Fills the system with test data. Data creation can be manipulated with own parameters passed.
Default parameters contain various special chars.


.. code-block:: perl

     # would do nothing -> return an empty HashRef
     my $Result = $HelperObject->FillTestEnvironment(
         User         => 0, # optional, default 5
         CustomerUser => 0, # optional, default 5
         Service      => 0, # optional, default 1 (true)
         SLA          => 0, # optional, default 1 (true)
         Type         => 0, # optional, default 1 (true)
         Queue        => 0, # optional, default 1 (true)
     );
 
     # create everything with defaults, except Type
     my $Result = $HelperObject->FillTestEnvironment(
         Type => {
             'Type 1::Sub Type' => 1,
             # ...
         }
     );
 
     # create everything with defaults, except 20 agents
     my $Result = $HelperObject->FillTestEnvironment(
         User => 20,
     );
 
     Return structure looks like this:
 
     $Result = {
         User => [
         ],
         CustomerUser => [
         ],
         Queue => [
         ],
         Service => [
         ],
         SLA => [
         ],
         Type => [
         ]
     };



TestUserDataGet()
=================


Calls TestUserCreate and returns the whole UserData instead only the Login.


.. code-block:: perl

     my %UserData = $HelperObject->TestUserDataGet(
         Groups => ['admin', 'users'],           # optional, list of groups to add this user to (rw rights)
         Language => 'de'                        # optional, defaults to 'en' if not set
     );
 
     %UserData = {
         UserID        => 2,
         UserFirstname => $TestUserLogin,
         UserLastname  => $TestUserLogin,
         UserLogin     => $TestUserLogin,
         UserPw        => $TestUserLogin,
         UserEmail     => $TestUserLogin . '@localunittest.com',
     }



TestCustomerUserDataGet()
=========================


Calls TestCustomerUserCreate and returns the whole CustomerUserData instead only the Login.


.. code-block:: perl

     my %CustomerUserData = $HelperObject->TestCustomerUserDataGet(
         Language => 'de' # optional, defaults to 'en' if not set
     );
 
     %CustomerUserData = {
         CustomerUserID => 1,
         Source         => 'CustomerUser',
         UserFirstname  => $TestUserLogin,
         UserLastname   => $TestUserLogin,
         UserCustomerID => $TestUserLogin,
         UserLogin      => $TestUserLogin,
         UserPassword   => $TestUserLogin,
         UserEmail      => $TestUserLogin . '@localunittest.com',
         ValidID        => 1,
     }



TicketCreate()
==============


Creates a Ticket with dummy data and tests the creation. All Ticket attributes are optional.


.. code-block:: perl

     my $TicketID = $HelperObject->TicketCreate();
 
     is equals:
 
     my $TicketID = $HelperObject->TicketCreate(
         Title        => 'UnitTest ticket',
         Queue        => 'Raw',
         Lock         => 'unlock',
         Priority     => '3 normal',
         State        => 'new',
         CustomerID   => 'UnitTestCustomer',
         CustomerUser => 'customer@example.com',
         OwnerID      => 1,
         UserID       => 1,
     );


To overwrite:


.. code-block:: perl

     my $TicketID = $HelperObject->TicketCreate(
         CustomerUser => 'another_customer@example.com',
     );


Result:


.. code-block:: perl

     $TicketID = 1337;



ArticleCreate()
===============


Creates an Article with dummy data and tests the creation. All Article attributes except the TicketID are optional.


.. code-block:: perl

     my $ArticleID = $HelperObject->ArticleCreate(
         TicketID => 1337,
     );
 
     is equals:
 
     my $ArticleID = $HelperObject->ArticleCreate(
         TicketID       => 1337,
         ArticleType    => 'note-internal',
         SenderType     => 'agent',
         Subject        => 'UnitTest subject test',
         Body           => 'UnitTest body test',
         ContentType    => 'text/plain; charset=ISO-8859-15',
         HistoryType    => 'OwnerUpdate',
         HistoryComment => 'Some free text!',
         UserID         => 1,
         NoAgentNotify  => 1,
     );


To overwrite:


.. code-block:: perl

     my $ArticleID = $HelperObject->ArticleCreate(
         TicketID   => 1337,
         SenderType => 'customer',
     );


Result:


.. code-block:: perl

     $ArticleID = 1337;



TestUserPreferencesSet()
========================


Sets preferences for a given Login or UserID


.. code-block:: perl

     my $Success = $HelperObject->TestUserPreferencesSet(
         UserID      => 123,
         Preferences => {                  # "Preferences" hashref is required
             OutOfOffice  => 1,            # example Key -> Value pair for User Preferences
             UserMobile   => undef,        # example for deleting a UserPreferences Key's value
             UserLanguage => '',           # example for deleting a UserPreferences Key's value
         },
     );



PostMaster()
============


This functions reads in a given file and calls the PostMaster on it. It returns the result of the PostMaster.


.. code-block:: perl

     my @Result = $HelperObject->PostMaster(
         Location => $ConfigObject->Get('Home') . '/scripts/test/sample/Sample-1.box',
     );
 
     @Result = (1, $TicketID);



DatabaseXML()
=============


This function takes a file location of a XML file, generates and executes the SQL


.. code-block:: perl

     my $Success = $HelperObject->DatabaseXML(
         Location => $ConfigObject->Get('Home') . '/scripts/development/db/schema.xml',
     );


or string


.. code-block:: perl

     my $Success = $HelperObject->DatabaseXML(
         String => '...',
     );


Returns:


.. code-block:: perl

     my $Success = 1;



ConsoleCommand()
================


This is a helper function for executing ConsoleCommands without the hassle.


.. code-block:: perl

     my $Result = $HelperObject->ConsoleCommand(
         CommandModule => 'Kernel::System::Console::Command::Maint::Cache::Delete',
     );
 
     # or
 
     my $Result = $HelperObject->ConsoleCommand(
         CommandModule => 'Kernel::System::Console::Command::Maint::Cache::Delete',
         Parameter     => [ '--type', 'Znuny' ],
     );
 
     # or
 
     my $Result = $HelperObject->ConsoleCommand(
         CommandModule => 'Kernel::System::Console::Command::Help',
         Parameter     => 'Lis',
     );
 
     $Result = {
         ExitCode => 0,      # or 1 in case of an error
         STDOUT   => '...',
         STDERR   => undef,
     }



ACLValuesGet()
==============


This is a helper function get shown values of fields or actions after ACL restrictions

Examples:


.. code-block:: perl

     my %Result = $HelperObject->ACLValuesGet(
         Check    => 'Action',
         UserID   => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );
 
     my %Result = $HelperObject->ACLValuesGet(
         Check    => 'DynamicField_Test',
         UserID   => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );
 
     my %Result = $HelperObject->ACLValuesGet(
         Check  => 'Queue',
         UserID => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );
 
     my %Result = $HelperObject->ACLValuesGet(
         Check  => 'Type',
         UserID => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );
 
     my %Result = $HelperObject->ACLValuesGet(
         Check  => 'State',
         UserID => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );
 
     my %Result = $HelperObject->ACLValuesGet(
         Check  => 'Service',
         UserID => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );
 
     my %Result = $HelperObject->ACLValuesGet(
         Check  => 'Priority',
         UserID => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );
 
     my %Result = $HelperObject->ACLValuesGet(
         Check  => 'SLA',
         UserID => $UserID,
         %TicketACLParams,   # see TicketACL.pm
     );



UnitTestObjectGet()
===================


Returns the correct unit test object.

OTRS 4.0.27 introduced a new module Kernel::System::UnitTest::Driver.
The unit test functions like True, False, etc. were moved to this module.




