diff --git a/.atoum.php b/.atoum.php new file mode 100644 index 0000000000..b692eb3eed --- /dev/null +++ b/.atoum.php @@ -0,0 +1,18 @@ +setRootUrl('file://' . realpath($coverage_dir)); +$script + ->addDefaultReport() + ->addField($coverageField); + +$runner->addTestsFromDirectory(__DIR__ . '/inc'); \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..57872d0f1e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000..5c81043b7a --- /dev/null +++ b/composer.json @@ -0,0 +1,14 @@ +{ + "name": "infotel/moreticket", + "type": "project", + "license": "LGPL2", + "authors": [ + { + "name": "Mathieu Templier", + "email": "mathieu.templier@infotel.com" + } + ], + "require": { + "atoum/atoum": "^3.3" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000000..faec7f96d0 --- /dev/null +++ b/composer.lock @@ -0,0 +1,101 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "44d653552982138444f97cb5b7cd3d8a", + "packages": [ + { + "name": "atoum/atoum", + "version": "3.3.0", + "source": { + "type": "git", + "url": "https://github.com/atoum/atoum.git", + "reference": "c5279d0ecd4e2d53af6b38815db2cafee8fc46b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/atoum/atoum/zipball/c5279d0ecd4e2d53af6b38815db2cafee8fc46b6", + "reference": "c5279d0ecd4e2d53af6b38815db2cafee8fc46b6", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^5.6.0 || ^7.0.0 <7.4.0" + }, + "replace": { + "mageekguy/atoum": "*" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2" + }, + "suggest": { + "atoum/stubs": "Provides IDE support (like autocompletion) for atoum", + "ext-mbstring": "Provides support for UTF-8 strings", + "ext-xdebug": "Provides code coverage report (>= 2.3)" + }, + "bin": [ + "bin/atoum" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "classmap": [ + "classes/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frédéric Hardy", + "email": "frederic.hardy@atoum.org", + "homepage": "http://blog.mageekbox.net" + }, + { + "name": "François Dussert", + "email": "francois.dussert@atoum.org" + }, + { + "name": "Gérald Croes", + "email": "gerald.croes@atoum.org" + }, + { + "name": "Julien Bianchi", + "email": "julien.bianchi@atoum.org" + }, + { + "name": "Ludovic Fleury", + "email": "ludovic.fleury@atoum.org" + } + ], + "description": "Simple modern and intuitive unit testing framework for PHP 5.3+", + "homepage": "http://www.atoum.org", + "keywords": [ + "TDD", + "atoum", + "test", + "unit testing" + ], + "time": "2018-03-15T22:46:39+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/scripts/cliinstall.php b/scripts/cliinstall.php new file mode 100644 index 0000000000..998d2db37e --- /dev/null +++ b/scripts/cliinstall.php @@ -0,0 +1,123 @@ +. + * --------------------------------------------------------------------- + */ + +//define('GLPI_ROOT', dirname(__DIR__)); + +define('GLPI_ROOT', __DIR__ . "/../../../"); + +chdir(GLPI_ROOT); +if (in_array('--tests', $_SERVER['argv'])) { // Uggly, but must be before any other GLPI include, so not from Getopt +define("GLPI_CONFIG_DIR", GLPI_ROOT . "/tests"); +@mkdir(GLPI_CONFIG_DIR . '/files/_log', 0775, true); +} +include_once (GLPI_ROOT . "/inc/based_config.php"); +include_once (GLPI_ROOT . "/inc/db.function.php"); +$GLPI = new GLPI(); +$GLPI->initLogger(); +Config::detectRootDoc(); +try { +$opts = new \Zend\Console\Getopt([ +'help' => 'Display usage', +'host|h=s' => 'Machine hosting the database', +'db|d=s' => 'Database name (required)', +'user|u=s' => 'Database user (required)', +'pass|p-s' => 'Database password (default: no password) without value will be prompt', +'lang|l=s' => 'Locale (default: en_GB)', +'tests' => 'Test configuration', +'force|f' => 'Override existing configuration', +]); +$opts->parse(); +} catch (Zend\Console\Exception\RuntimeException $e) { +echo $e->getUsageMessage(); +exit; +} +$args = $opts->getArguments(); +if (!isset($args['host'])) { +$args['host'] = 'localhost'; +} +if (!isset($args['pass'])) { +$args['pass'] = ''; +} +if (isset($args['help']) || !(isset($args['db']) && isset($args['user']))) { +echo $opts->getUsageMessage(); +exit; +} +if (isset($args['lang']) && !isset($CFG_GLPI['languages'][$args['lang']])) { +$kl = implode(', ', array_keys($CFG_GLPI['languages'])); +echo "Unkown locale (use one of: $kl)\n"; +die(1); +} +if (file_exists(GLPI_CONFIG_DIR . '/config_db.php') && !isset($args['force'])) { +echo "Already installed (see --force option)\n"; +die(1); +} +$_SESSION = ['glpilanguage' => (isset($args['lang']) ? $args['lang'] : 'en_GB')]; +Toolbox::setDebugMode(Session::DEBUG_MODE, 0, 0, 1); +if ($args['pass'] === true) { +$args['pass'] = \Zend\Console\Prompt\Password::prompt('Password:'); +} +echo "Connect to the DB...\n"; +//Check if the port is in url +$hostport = explode(':', $args['host']); +if (count($hostport) < 2) { +$link = new mysqli($hostport[0], $args['user'], $args['pass']); +} else { +$link = new mysqli($hostport[0], $args['user'], $args['pass'], '', $hostport[1]); +} +if (!$link || mysqli_connect_error()) { +echo "DB connection failed\n"; +die(1); +} +$args['db'] = $link->real_escape_string($args['db']); +$DB_ver = $link->query("SELECT version()"); +$row = $DB_ver->fetch_array(); +$checkdb = Config::displayCheckDbEngine(true, $row[0]); +if ($checkdb > 0) { +return; +} +echo "Create the DB...\n"; +if (!$link->query("CREATE DATABASE IF NOT EXISTS `" . $args['db'] ."`")) { +echo "Can't create the DB\n"; +die(1); +} +if (!$link->select_db($args['db'])) { +echo "Can't select the DB\n"; +die(1); +} +echo "Save configuration file...\n"; +if (!DBConnection::createMainConfig($args['host'], $args['user'], $args['pass'], $args['db'])) { +echo "Can't write configuration file\n"; +die(1); +} +echo "Load default schema...\n"; +Toolbox::createSchema($_SESSION['glpilanguage']); +echo "Done\n"; diff --git a/tests/DbTestCase.php b/tests/DbTestCase.php new file mode 100644 index 0000000000..21c13473e9 --- /dev/null +++ b/tests/DbTestCase.php @@ -0,0 +1,97 @@ +. + * --------------------------------------------------------------------- + */ + +// Generic test classe, to be extended for CommonDBTM Object + +class DbTestCase extends \GLPITestCase { + + public function beforeTestMethod($method) { + global $DB; + $DB->beginTransaction(); + parent::beforeTestMethod($method); + } + + public function afterTestMethod($method) { + global $DB; + $DB->rollback(); + parent::afterTestMethod($method); + } + + + /** + * Connect (using the test user per default) + * + * @param string $user_name User name (defaults to TU_USER) + * @param string $user_pass user password (defaults to TU_PASS) + * + * @return voidd + */ + protected function login($user_name = TU_USER, $user_pass = TU_PASS) { + + $auth = new Auth(); + $this->boolean($auth->login($user_name, $user_pass, true))->isTrue(); + } + + /** + * change current entity + * + * @param string $entityname Name of the entity + * @param boolean $subtree Recursive load + * + * @return void + */ + protected function setEntity($entityname, $subtree) { + $res = Session::changeActiveEntities(getItemByTypeName('Entity', $entityname, true), $subtree); + $this->boolean($res)->isTrue(); + } + + /** + * Generic method to test if an added object is corretly inserted + * + * @param Object $object The object to test + * @param int $id The id of added object + * @param array $input the input used for add object (optionnal) + * + * @return nothing (do tests) + */ + protected function checkInput(CommonDBTM $object, $id = 0, $input = []) { + $this->integer((int)$id)->isGreaterThan(0); + $this->boolean($object->getFromDB($id))->isTrue(); + $this->variable($object->getField('id'))->isEqualTo($id); + + if (count($input)) { + foreach ($input as $k => $v) { + $this->variable($object->getField($k))->isEqualTo($v); + } + } + } +} \ No newline at end of file diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000000..1537b03615 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,64 @@ +## moreticket test suite + +To run the moreticket test suite you need + +* [atoum](http://atoum.org/) + +Installing composer development dependencies +---------------------- + +Run the **composer install** command without --no-dev option in the top of moreticket tree: + +```bash +$ composer install -o + +Loading composer repositories with package information +Installing dependencies (including require-dev) from lock file +[...] +Generating optimized autoload files +``` + +Creating a dedicated database +----------------------------- + +Use the **CliInstall** script to create a new database, +only used for the test suite, using the `--tests` option: + +```bash +$ php scripts/cliinstall.php --db=glpitests --user=root --pass=xxxx --tests +Connect to the DB... +Create the DB... +Save configuration file... +Load default schema... +Done +``` + +The configuration file is saved as `tests/config_db.php`. + +The database is created using the default schema for current version. + +If you need to recreate the database (e.g. for a new schema), you need to run +**CliInstall** again with the `--force` option. + + +Changing database configuration +------------------------------- + +Using the same database than the web application is not recommended. Use the `tests/config_db.php` file to adjust connection settings. + +Running the test suite +---------------------- + +There are two directories for tests: +- `tests/units` for main core tests; +- `tests/api` for API tests. + +You can choose to run tests on a whole directory, on any file, or on any \. You have to specify a bootstrap file each time: + +```bash +$ atoum -bf tests/bootstrap.php -mcn 1 -d tests/units/ +[...] +$ atoum -bf tests/bootstrap.php -f tests/units/Html.php +[...] +$ atoum -bf tests/bootstrap.php -f tests/units/Html.php -m tests\units\Html::testConvDateTime +``` diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 0000000000..31a9732a1d --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,581 @@ +. + * --------------------------------------------------------------------- + */ + +define('GLPI_ROOT', __DIR__ . "/../../../"); +define("GLPI_CONFIG_DIR", GLPI_ROOT . "/tests"); + +error_reporting(E_ALL); +//define('GLPI_CONFIG_DIR', __DIR__); +define('GLPI_LOG_DIR', __DIR__ . '/files/_log'); +define('GLPI_URI', (getenv('GLPI_URI') ?: 'http://localhost:8088')); +define('TU_USER', '_test_user'); +define('TU_PASS', 'PhpUnit_4'); + +if (!file_exists(GLPI_CONFIG_DIR . '/config_db.php')) { + die("\nConfiguration file for tests not found\n\nrun: php scripts/cliinstall.php --tests ...\n\n"); +} + +global $CFG_GLPI; +include_once GLPI_ROOT . '/inc/includes.php'; +include_once GLPI_ROOT . '/tests/GLPITestCase.php'; +include_once GLPI_ROOT . '/tests/DbTestCase.php'; +include_once GLPI_ROOT . '/tests/APIBaseClass.php'; + +echo "\n" . __DIR__ . "\n"; + +// check folder exists instead of class_exists('\GuzzleHttp\Client'), to prevent global includes +if (file_exists(__DIR__ . '../vendor/autoload.php')/* && !file_exists(__DIR__ . '/../vendor/guzzlehttp/guzzle')*/) { + die("\nDevelopment dependencies not found\n\nrun: composer install -o\n\n"); +} +class GlpitestPHPerror extends Exception +{ +} +class GlpitestPHPwarning extends Exception +{ +} +class GlpitestPHPnotice extends Exception +{ +} +class GlpitestSQLError extends Exception +{ +} +function loadDataset() { + global $CFG_GLPI; + // Unit test data definition + $data = [ + // bump this version to force reload of the full dataset, when content change + '_version' => '4.3', + // Type => array of entries + 'Entity' => [ + [ + 'name' => '_test_root_entity', + 'entities_id' => 0, + ], [ + 'name' => '_test_child_1', + 'entities_id' => '_test_root_entity', + ], [ + 'name' => '_test_child_2', + 'entities_id' => '_test_root_entity', + ] + ], 'Computer' => [ + [ + 'name' => '_test_pc01', + 'entities_id' => '_test_root_entity', + 'comment' => 'Comment for computer _test_pc01', + ], [ + 'name' => '_test_pc02', + 'entities_id' => '_test_root_entity', + 'comment' => 'Comment for computer _test_pc02', + ], [ + 'name' => '_test_pc03', + 'entities_id' => '_test_root_entity', + 'comment' => 'Comment for computer _test_pc03', + 'contact' => 'johndoe', + ], [ + 'name' => '_test_pc11', + 'entities_id' => '_test_child_1', + ], [ + 'name' => '_test_pc12', + 'entities_id' => '_test_child_1', + ], [ + 'name' => '_test_pc13', + 'entities_id' => '_test_child_1', + 'comment' => 'Comment for computer _test_pc13', + 'contact' => 'johndoe', + ], [ + 'name' => '_test_pc21', + 'entities_id' => '_test_child_2', + ], [ + 'name' => '_test_pc22', + 'entities_id' => '_test_child_2', + ] + ], 'Software' => [ + [ + 'name' => '_test_soft', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + ], [ + 'name' => '_test_soft2', + 'entities_id' => '_test_child_2', + 'is_recursive' => 0, + ], [ + 'name' => '_test_soft_3', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + ] + ], 'SoftwareVersion' => [ + [ + 'name' => '_test_softver_1', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + 'softwares_id' => '_test_soft', + ], [ + 'name' => '_test_softver_2', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + 'softwares_id' => '_test_soft', + ] + ], 'Printer' => [ + [ + 'name' => '_test_printer_all', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + ], [ + 'name' => '_test_printer_ent0', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 0, + ], [ + 'name' => '_test_printer_ent1', + 'entities_id' => '_test_child_1', + 'is_recursive' => 0, + ], [ + 'name' => '_test_printer_ent2', + 'entities_id' => '_test_child_2', + 'is_recursive' => 0, + ] + ], 'User' => [ + [ + 'name' => TU_USER, + 'password' => TU_PASS, + 'password2' => TU_PASS, + 'entities_id' => '_test_root_entity', + 'profiles_id' => 4, // TODO manage test profiles + '_entities_id' => '_test_root_entity', + '_profiles_id' => 4, + '_is_recursive' => 1, + ] + ], 'TaskCategory' => [ + [ + 'is_recursive' => 1, + 'name' => '_cat_1', + 'completename' => '_cat_1', + 'comment' => 'Comment for category _cat_1', + 'level' => 1, + ], + [ + 'is_recursive' => 1, + 'taskcategories_id' => '_cat_1', + 'name' => '_subcat_1', + 'completename' => '_cat_1 > _subcat_1', + 'comment' => 'Comment for sub-category _subcat_1', + 'level' => 2, + ] + ], 'DropdownTranslation' => [ + [ + 'items_id' => '_cat_1', + 'itemtype' => 'TaskCategory', + 'language' => 'fr_FR', + 'field' => 'name', + 'value' => 'FR - _cat_1' + ], + [ + 'items_id' => '_cat_1', + 'itemtype' => 'TaskCategory', + 'language' => 'fr_FR', + 'field' => 'comment', + 'value' => 'FR - Commentaire pour catégorie _cat_1' + ], + [ + 'items_id' => '_subcat_1', + 'itemtype' => 'TaskCategory', + 'language' => 'fr_FR', + 'field' => 'name', + 'value' => 'FR - _subcat_1' + ], + [ + 'items_id' => '_subcat_1', + 'itemtype' => 'TaskCategory', + 'language' => 'fr_FR', + 'field' => 'comment', + 'value' => 'FR - Commentaire pour sous-catégorie _subcat_1' + ] + ], 'Contact' => [ + [ + 'name' => '_contact01_name', + 'firstname' => '_contact01_firstname', + 'phone' => '0123456789', + 'phone2' => '0123456788', + 'mobile' => '0623456789', + 'fax' => '0123456787', + 'email' => '_contact01_firstname._contact01_name@glpi.com', + 'comment' => 'Comment for contact _contact01_name', + 'entities_id' => '_test_root_entity' + ] + ], 'Supplier' => [ + [ + 'name' => '_suplier01_name', + 'phonenumber' => '0123456789', + 'fax' => '0123456787', + 'email' => 'info@_supplier01_name.com', + 'comment' => 'Comment for supplier _suplier01_name', + 'entities_id' => '_test_root_entity' + ] + ], 'Location' => [ + [ + 'name' => '_location01', + 'comment' => 'Comment for location _location01' + ], + [ + 'name' => '_location01 > _sublocation01', + 'comment' => 'Comment for location _sublocation01' + ], + [ + 'name' => '_location02', + 'comment' => 'Comment for location _sublocation02' + ] + ], 'Netpoint' => [ + [ + 'name' => '_netpoint01', + 'locations_id' => '_location01', + 'comment' => 'Comment for netpoint _netpoint01' + ] + ], 'BudgetType' => [ + [ + 'name' => '_budgettype01', + 'comment' => 'Comment for budgettype _budgettype01' + ] + ], 'Budget' => [ + [ + 'name' => '_budget01', + 'comment' => 'Comment for budget _budget01', + 'locations_id' => '_location01', + 'budgettypes_id' => '_budgettype01', + 'begin_date' => '2016-10-18', + 'end_date' => '2016-12-31', + 'entities_id' => '_test_root_entity' + ] + ], 'Ticket' => [ + [ + 'name' => '_ticket01', + 'content' => 'Content for ticket _ticket01', + 'users_id_recipient' => TU_USER, + 'entities_id' => '_test_root_entity' + ], + [ + 'name' => '_ticket02', + 'content' => 'Content for ticket _ticket02', + 'users_id_recipient' => TU_USER, + 'entities_id' => '_test_root_entity' + ], + [ + 'name' => '_ticket03', + 'content' => 'Content for ticket _ticket03', + 'users_id_recipient' => TU_USER, + 'entities_id' => '_test_child_1' + ] + ], 'TicketTask' => [ + [ + 'tickets_id' => '_ticket01', + 'taskcategories_id' => '_subcat_1', + 'users_id' => TU_USER, + 'content' => 'Task to be done', + 'is_private' => 0, + 'users_id_tech' => TU_USER, + 'date' => '2016-10-19 11:50:50' + ] + ], 'UserEmail' => [ + [ + 'users_id' => TU_USER, + 'is_default' => '1', + 'is_dynamic' => '0', + 'email' => TU_USER.'@glpi.com' + ] + ], 'KnowbaseItem' => [ + [ + 'name' => '_knowbaseitem01', + 'answer' => 'Answer for Knowledge base entry _knowbaseitem01', + 'is_faq' => 0, + 'users_id' => TU_USER, + 'date' => '2016-11-17 12:27:48', + 'date_mod' => '2016-11-17 12:28:06' + ], + [ + 'name' => '_knowbaseitem02', + 'answer' => 'Answer for Knowledge base entry _knowbaseitem02', + 'is_faq' => 0, + 'users_id' => TU_USER, + 'date' => '2016-11-17 12:27:48', + 'date_mod' => '2016-11-17 12:28:06' + ] + ], 'KnowbaseItem_Item' => [ + [ + 'knowbaseitems_id' => '_knowbaseitem01', + 'itemtype' => 'Ticket', + 'items_id' => '_ticket01', + 'date_creation' => '2016-11-17 14:27:28', + 'date_mod' => '2016-11-17 14:27:52' + ], + [ + 'knowbaseitems_id' => '_knowbaseitem01', + 'itemtype' => 'Ticket', + 'items_id' => '_ticket02', + 'date_creation' => '2016-11-17 14:28:28', + 'date_mod' => '2016-11-17 14:28:52' + ], + [ + 'knowbaseitems_id' => '_knowbaseitem01', + 'itemtype' => 'Ticket', + 'items_id' => '_ticket03', + 'date_creation' => '2016-11-17 14:29:28', + 'date_mod' => '2016-11-17 14:29:52' + ], + [ + 'knowbaseitems_id' => '_knowbaseitem02', + 'itemtype' => 'Ticket', + 'items_id' => '_ticket03', + 'date_creation' => '2016-11-17 14:30:28', + 'date_mod' => '2016-11-17 14:30:52' + ], + [ + 'knowbaseitems_id' => '_knowbaseitem02', + 'itemtype' => 'Computer', + 'items_id' => '_test_pc21', + 'date_creation' => '2016-11-17 14:31:28', + 'date_mod' => '2016-11-17 14:31:52' + ] + ], 'Entity_KnowbaseItem' => [ + [ + 'knowbaseitems_id' => '_knowbaseitem01', + 'entities_id' => '_test_root_entity' + ], + [ + 'knowbaseitems_id' => '_knowbaseitem02', + 'entities_id' => '_test_child_1' + ] + ], 'DocumentType' => [ + [ + 'name' => 'markdown', + 'is_uploadable' => '1', + 'ext' => 'md' + ] + ], 'Manufacturer' => [ + [ + 'name' => 'My Manufacturer', + ] + ], 'SoftwareLicense' => [ + [ + 'name' => '_test_softlic_1', + 'completename' => '_test_softlic_1', + 'level' => 0, + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + 'number' => 2, + 'softwares_id' => '_test_soft', + ], + [ + 'name' => '_test_softlic_2', + 'completename' => '_test_softlic_2', + 'level' => 0, + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + 'number' => 3, + 'softwares_id' => '_test_soft', + ], + [ + 'name' => '_test_softlic_3', + 'completename' => '_test_softlic_3', + 'level' => 0, + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + 'number' => 5, + 'softwares_id' => '_test_soft', + ], + [ + 'name' => '_test_softlic_4', + 'completename' => '_test_softlic_4', + 'level' => 0, + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + 'number' => 2, + 'softwares_id' => '_test_soft', + ], + [ + 'name' => '_test_softlic_child', + 'completename' => '_test_softlic_child', + 'level' => 0, + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + 'number' => 1, + 'softwares_id' => '_test_soft', + 'softwarelicenses_id' => '_test_softlic_1', + ], + ], 'Computer_SoftwareLicense' => [ + [ + 'softwarelicenses_id' => '_test_softlic_1', + 'computers_id' => '_test_pc21', + ], [ + 'softwarelicenses_id' => '_test_softlic_1', + 'computers_id' => '_test_pc01', + ], [ + 'softwarelicenses_id' => '_test_softlic_1', + 'computers_id' => '_test_pc02', + ], [ + 'softwarelicenses_id' => '_test_softlic_2', + 'computers_id' => '_test_pc02', + ], [ + 'softwarelicenses_id' => '_test_softlic_3', + 'computers_id' => '_test_pc02', + ], [ + 'softwarelicenses_id' => '_test_softlic_3', + 'computers_id' => '_test_pc21', + ], [ + 'softwarelicenses_id' => '_test_softlic_2', + 'computers_id' => '_test_pc21', + ] + ], 'devicesimcard' => [ + [ + 'designation' => '_test_simcard_1', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1, + ] + ], 'DeviceSensor' => [ + [ + 'designation' => '_test_sensor_1', + 'entities_id' => '_test_root_entity', + 'is_recursive' => 1 + ] + ], 'AuthLdap' => [ + [ + 'name' => '_local_ldap', + 'host' => '127.0.0.1', + 'basedn' => 'dc=glpi,dc=org', + 'rootdn' => 'cn=Manager,dc=glpi,dc=org', + 'port' => '3890', + 'condition' => '(objectclass=inetOrgPerson)', + 'login_field' => 'uid', + 'rootdn_passwd' => 'insecure', + 'is_default' => 1, + 'is_active' => 0, + 'use_tls' => 0, + 'email1_field' => 'mail', + 'realname_field' => 'cn', + 'firstname_field' => 'sn', + 'phone_field' => 'telephonenumber', + 'comment_field' => 'description', + 'title_field' => 'title', + 'category_field' => 'businesscategory', + 'language_field' => 'preferredlanguage', + 'group_search_type' => \AuthLdap::GROUP_SEARCH_GROUP, + 'group_condition' => '(objectclass=groupOfNames)', + 'group_member_field' => 'member' + ] + ] + ]; + // To bypass various right checks + $_SESSION['glpishowallentities'] = 1; + $_SESSION['glpicronuserrunning'] = "cron_phpunit"; + $_SESSION['glpi_use_mode'] = Session::NORMAL_MODE; + $_SESSION['glpiactiveentities'] = [0]; + $_SESSION['glpiactiveentities_string'] = "'0'"; + $CFG_GLPI['root_doc'] = '/glpi'; + // need to set theses in DB, because tests for API use http call and this bootstrap file is not called + Config::setConfigurationValues('core', ['url_base' => GLPI_URI, + 'url_base_api' => GLPI_URI . '/apirest.php']); + $CFG_GLPI['url_base'] = GLPI_URI; + $CFG_GLPI['url_base_api'] = GLPI_URI . '/apirest.php'; + is_dir(GLPI_LOG_DIR) or mkdir(GLPI_LOG_DIR, 0755, true); + $conf = Config::getConfigurationValues('phpunit'); + if (isset($conf['dataset']) && $conf['dataset']==$data['_version']) { + printf("\nGLPI dataset version %s already loaded\n\n", $data['_version']); + } else { + printf("\nLoading GLPI dataset version %s\n", $data['_version']); + $ids = []; + foreach ($data as $type => $inputs) { + if ($type[0] == '_') { + continue; + } + foreach ($inputs as $input) { + // Resolve FK + foreach ($input as $k => $v) { + // $foreigntype = $type; // by default same type than current type (is the case of the dropdowns) + $foreigntype = false; + $match = []; + if (isForeignKeyField($k) && (preg_match("/(.*s)_id$/", $k, $match) || preg_match("/(.*s)_id_/", $k, $match))) { + $foreigntypetxt = array_pop($match); + if (substr($foreigntypetxt, 0, 1) !== '_') { + $foreigntype = getItemTypeForTable("glpi_$foreigntypetxt"); + } + } + if ($foreigntype && isset($ids[$foreigntype][$v]) && !is_numeric($v)) { + $input[$k] = $ids[$foreigntype][$v]; + } else if ($k == 'items_id' && isset( $input['itemtype'] ) && isset($ids[$input['itemtype']][$v]) && !is_numeric($v)) { + $input[$k] = $ids[$input['itemtype']][$v]; + } else if ($foreigntype && $foreigntype != 'UNKNOWN' && !is_numeric($v)) { + // not found in ids array, then must get it from DB + if ($obj = getItemByTypeName($foreigntype, $v)) { + $input[$k] = $obj->getID(); + } + } + } + if (isset($input['name']) && $item = getItemByTypeName($type, $input['name'])) { + $input['id'] = $ids[$type][$input['name']] = $item->getField('id'); + $item->update($input); + echo "."; + } else { + // Not found, create it + $item = getItemForItemtype($type); + $id = $item->add($input); + echo "+"; + if (isset($input['name'])) { + $ids[$type][$input['name']] = $id; + } + } + } + } + Search::$search = []; + echo "\nDone\n\n"; + Config::setConfigurationValues('phpunit', ['dataset' => $data['_version']]); + } +} +/** + * Test helper, search an item from its type and name + * + * @param string $type + * @param string $name + * @param boolean $onlyid + * @return the item, or its id + */ +function getItemByTypeName($type, $name, $onlyid = false) { + $item = getItemForItemtype($type); + $nameField = $type::getNameField(); + if ($item->getFromDBByCrit([$nameField => $name])) { + return ($onlyid ? $item->getField('id') : $item); + } + return false; +} +// Cleanup log directory +foreach (glob(GLPI_LOG_DIR . '/*.log') as $file) { + if (file_exists($file)) { + unlink($file); + } +} +loadDataset(); \ No newline at end of file diff --git a/tests/units/PluginMoreTicketProfile.php b/tests/units/PluginMoreTicketProfile.php new file mode 100644 index 0000000000..f7ce541cf7 --- /dev/null +++ b/tests/units/PluginMoreTicketProfile.php @@ -0,0 +1,20 @@ +newTestedInstance(); + $this->array($this->testedInstance->getAllRights(true)) + ->hasSize(2); + $this->array($this->testedInstance->getAllRights(false)) + ->hasSize(1); + } +} \ No newline at end of file