Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions tests/DbTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,8 @@ protected function checkInput(CommonDBTM $object, $id = 0, $input = [])
$this->assertEquals(
$v,
$object->fields[$k],
"
Object not created as expected
field '$k' value is '{$object->fields[$k]}' (" . gettype($object->fields[$k]) . ")
" Object not created as expected
field '" . $k . "' value is '" . var_export($object->fields[$k], true) . "' (type : " . gettype($object->fields[$k]) . ")
but was expected to be '$v' (" . gettype($v) . ")"
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@

namespace tests\units\Glpi\Features;

use Domain;
use Glpi\Features\AssignableItem;
use Group_Item;
use PHPUnit\Framework\Attributes\DataProvider;

class AssignableItem extends \DbTestCase
class AssignableItemTest extends \DbTestCase
{
protected function itemtypeProvider(): iterable
public static function itemtypeProvider(): iterable
{
global $CFG_GLPI;

Expand All @@ -50,15 +52,27 @@ protected function itemtypeProvider(): iterable
}
}

/**
* @param class-string<AssignableItem> $class
*/
#[DataProvider('itemtypeProvider')]
public function testClassUsesTrait(string $class): void
{
$this->boolean(in_array(\Glpi\Features\AssignableItem::class, class_uses($class), true))->isTrue();
// class_uses() doesn't match traits in parents -> $parent_has_trait() does it.
$has_trait = static fn($_class) => in_array(AssignableItem::class, class_uses($_class), true);
$parent_has_trait = fn($_class) => array_reduce(
class_parents($_class),
static fn($result, $_class) => $result || $has_trait($_class),
false,
);
$this->assertTrue($has_trait($class) || $parent_has_trait($class));
}

/**
* Test adding an item with the groups_id/groups_id_tech field as an array and null.
* Test updating an item with the groups_id/groups_id_tech field as an array and null.
*
* @param class-string<AssignableItem> $class
*/
#[DataProvider('itemtypeProvider')]
public function testAddAndUpdateMultipleGroups(string $class): void
Expand All @@ -73,43 +87,57 @@ public function testAddAndUpdateMultipleGroups(string $class): void
$class::getNameField() => __FUNCTION__ . ' 1',
'groups_id' => [1, 2],
'groups_id_tech' => [3],
'domains_id' => getItemByTypeName(Domain::class, '_testDomain', true),
],
[
'domains_id',
]
);
$this->array($item_1->fields['groups_id'])->isEqualTo([1, 2]);
$this->array($item_1->fields['groups_id_tech'])->isEqualTo([3]);
$this->assertEqualsCanonicalizing([1, 2], $item_1->fields['groups_id']);
$this->assertEqualsCanonicalizing([3], $item_1->fields['groups_id_tech']);

$item_2 = $this->createItem(
$class,
$input + [
$class::getNameField() => __FUNCTION__ . ' 2',
'groups_id' => null,
'groups_id_tech' => null,
'domains_id' => getItemByTypeName(Domain::class, '_testDomain', true),
],
[
// groups_id, groups_id_tech are set as empty array, not null
'groups_id',
'groups_id_tech',
// not all AssignableItem have domains_id field
'domains_id',
]
);
$this->array($item_2->fields['groups_id'])->isEmpty();
$this->array($item_2->fields['groups_id_tech'])->isEmpty();
$this->assertEmpty($item_2->fields['groups_id']);
$this->assertEmpty($item_2->fields['groups_id_tech']);

// Update both items. Asset 1 will have the groups set to null and item 2 will have the groups set to an array.
$updated = $item_1->update(['id' => $item_1->getID(), 'groups_id' => null, 'groups_id_tech' => null]);
$this->boolean($updated)->isTrue();
$this->array($item_1->fields['groups_id'])->isEmpty();
$this->array($item_1->fields['groups_id_tech'])->isEmpty();
$this->assertTrue($updated);
$this->assertEmpty($item_1->fields['groups_id']);
$this->assertEmpty($item_1->fields['groups_id_tech']);

$updated = $item_2->update(['id' => $item_2->getID(), 'groups_id' => [5, 6], 'groups_id_tech' => [7]]);
$this->boolean($updated)->isTrue();
$this->array($item_2->fields['groups_id'])->isEqualTo([5, 6]);
$this->array($item_2->fields['groups_id_tech'])->isEqualTo([7]);
$this->assertTrue($updated);
$this->assertEqualsCanonicalizing([5, 6], $item_2->fields['groups_id']);
$this->assertEqualsCanonicalizing([7], $item_2->fields['groups_id_tech']);

// Test updating array to array
$updated = $item_2->update(['id' => $item_2->getID(), 'groups_id' => [1, 2], 'groups_id_tech' => [4, 5]]);
$this->boolean($updated)->isTrue();
$this->array($item_2->fields['groups_id'])->isEqualTo([1, 2]);
$this->array($item_2->fields['groups_id_tech'])->isEqualTo([4, 5]);
$this->assertTrue($updated);
$this->assertEqualsCanonicalizing([1, 2], $item_2->fields['groups_id']);
$this->assertEqualsCanonicalizing([4, 5], $item_2->fields['groups_id_tech']);
}

/**
* Test the loading item which still have integer values for groups_id/groups_id_tech (0 for no group).
* The value should be automatically normalized to an array. If the group was '0', the array should be empty.
*
* @param class-string<AssignableItem> $class
*/
#[DataProvider('itemtypeProvider')]
public function testLoadGroupsFromDb(string $class): void
Expand All @@ -122,10 +150,14 @@ public function testLoadGroupsFromDb(string $class): void
$class,
$input + [
$class::getNameField() => __FUNCTION__,
'domains_id' => getItemByTypeName(Domain::class, '_testDomain', true),
],
[
'domains_id',
]
);
$this->array($item->fields['groups_id'])->isEmpty();
$this->array($item->fields['groups_id_tech'])->isEmpty();
$this->assertEmpty($item->fields['groups_id']);
$this->assertEmpty($item->fields['groups_id_tech']);

$DB->insert(
'glpi_groups_items',
Expand All @@ -146,9 +178,9 @@ public function testLoadGroupsFromDb(string $class): void
],
);

$this->boolean($item->getFromDB($item->getID()))->isTrue();
$this->array($item->fields['groups_id'])->isEqualTo([1]);
$this->array($item->fields['groups_id_tech'])->isEqualTo([2]);
$this->assertTrue($item->getFromDB($item->getID()));
$this->assertEqualsCanonicalizing([1], $item->fields['groups_id']);
$this->assertEqualsCanonicalizing([2], $item->fields['groups_id_tech']);

$DB->insert(
'glpi_groups_items',
Expand All @@ -168,25 +200,29 @@ public function testLoadGroupsFromDb(string $class): void
'type' => Group_Item::GROUP_TYPE_TECH,
],
);
$this->boolean($item->getFromDB($item->getID()))->isTrue();
$this->array($item->fields['groups_id'])->isEqualTo([1, 3]);
$this->array($item->fields['groups_id_tech'])->isEqualTo([2, 4]);
$this->assertTrue($item->getFromDB($item->getID()));
$this->assertEqualsCanonicalizing([1, 3], $item->fields['groups_id']);
$this->assertEqualsCanonicalizing([2, 4], $item->fields['groups_id_tech']);
}

/**
* An empty item should have the groups_id/groups_id_tech fields initialized as an empty array.
*
* @param class-string<AssignableItem> $class
*/
#[DataProvider('itemtypeProvider')]
public function testGetEmpty(string $class): void
{
$item = new $class();
$this->boolean($item->getEmpty())->isTrue();
$this->array($item->fields['groups_id'])->isEmpty();
$this->array($item->fields['groups_id_tech'])->isEmpty();
$this->assertTrue($item->getEmpty());
$this->assertEmpty($item->fields['groups_id']);
$this->assertEmpty($item->fields['groups_id_tech']);
}

/**
* Check that adding and updating an item with groups_id/groups_id_tech as an integer still works (minor BC, mainly for API scripts).
*
* @param class-string<AssignableItem> $class
*/
#[DataProvider('itemtypeProvider')]
public function testAddUpdateWithIntGroups(string $class): void
Expand All @@ -201,16 +237,24 @@ public function testAddUpdateWithIntGroups(string $class): void
$class::getNameField() => __FUNCTION__,
'groups_id' => 1,
'groups_id_tech' => 2,
'domains_id' => getItemByTypeName(Domain::class, '_testDomain', true),
],
['groups_id', 'groups_id_tech'] // ignore the fields as it will be transformed to an array
[
// groups_id & groups_id_tech are returned as array
'groups_id',
'groups_id_tech',
// set only for some Itemtypes (eg. Appliance)
'domains_id',
]
);
$this->array($item->fields['groups_id'])->isEqualTo([1]);
$this->array($item->fields['groups_id_tech'])->isEqualTo([2]);

$this->assertEqualsCanonicalizing([1], $item->fields['groups_id']);
$this->assertEqualsCanonicalizing([2], $item->fields['groups_id_tech']);

$updated = $item->update(['id' => $item->getID(), 'groups_id' => 3, 'groups_id_tech' => 4]);
$this->boolean($updated)->isTrue();
$this->array($item->fields['groups_id'])->isEqualTo([3]);
$this->array($item->fields['groups_id_tech'])->isEqualTo([4]);
$this->assertTrue($updated);
$this->assertEqualsCanonicalizing([3], $item->fields['groups_id']);
$this->assertEqualsCanonicalizing([4], $item->fields['groups_id_tech']);
}

public function testGenericAsset(): void
Expand Down
11 changes: 9 additions & 2 deletions tests/src/autoload/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function loadDataset()
// Unit test data definition
$data = [
// bump this version to force reload of the full dataset, when content change
'_version' => '4.13',
'_version' => '4.14',

// Type => array of entries
'Entity' => [
Expand Down Expand Up @@ -838,6 +838,11 @@ function loadDataset()
'solutiontemplates_id' => 'noupdate_solutiontemplate',
],
],
Domain::class => [
[
'name' => '_testDomain',
],
],
];

// To bypass various right checks
Expand Down Expand Up @@ -935,7 +940,9 @@ function getItemByTypeName(string $type, string $name, bool $onlyid = false): Co
$item = getItemForItemtype($type);
$nameField = $type::getNameField();
if (!$item->getFromDBByCrit([$nameField => $name])) {
throw new RuntimeException(sprintf('Unable to load a single `%s` item with the name `%s` (none or many exist may exist).', $type, $name));
$found = $item->find();
$found_names = array_column($found, $nameField);
throw new RuntimeException(sprintf('Unable to load a single `%s` item with the name `%s` (available items names are : ' . implode(', ', $found_names) . ').', $type, $name));
}
return ($onlyid ? $item->getID() : $item);
}
Expand Down