Skip to content

Commit c043428

Browse files
committed
test(hidden-question): cover the string condition operators
The condition handlers added to HiddenQuestion were not covered by any test. Add a test case based on the core AbstractConditionHandlerTest, which evaluates every operator supported by StringConditionHandler on a hidden question and checks that the question type exposes them. Extract the configurable items helpers of AdvancedFormsTestCase into a trait, as a test case extending a core abstract test case can't extend AdvancedFormsTestCase but still needs to enable the tested question type. Also add the missing changelog entry for the fix itself.
1 parent b352cf4 commit c043428

5 files changed

Lines changed: 475 additions & 72 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1818
- Fixed the `Hidden`, `IP address`, and `Hostname` questions to always use the correct value regardless of what was submitted, and restored the missing access check on the tree cascade dropdown children endpoint
1919
- Fixed the `LDAP select` question's autocomplete search to properly handle special characters in the search text
2020
- Fix visibility conditions on tree cascade dropdown questions
21+
- Fix string condition operators (equals, contains, length) not being available on hidden questions
2122
- Fixed the `Tree cascade Dropdown` field so that the subtree depth limit is enforced when loading children via AJAX
2223
- Fixed the `Tree cascade Dropdown` question to only show items from the configured custom dropdown instead of all custom dropdowns
2324
- Fixed `Tree cascade Dropdown` question showing items from all custom dropdowns instead of only items from the configured one

tests/AdvancedFormsTestCase.php

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
namespace GlpiPlugin\Advancedforms\Tests;
3535

3636
use AuthLDAP;
37-
use Config;
3837
use Glpi\Form\Form;
3938
use Glpi\Form\Migration\TypesConversionMapper;
4039
use Glpi\Form\QuestionType\QuestionTypeInterface;
@@ -46,13 +45,11 @@
4645
use GlpiPlugin\Advancedforms\Model\QuestionType\LdapQuestion;
4746
use GlpiPlugin\Advancedforms\Model\QuestionType\LdapQuestionConfig;
4847
use GlpiPlugin\Advancedforms\Service\ConfigManager;
49-
use GlpiPlugin\Advancedforms\Service\InitManager;
50-
use InvalidArgumentException;
51-
use ReflectionClass;
5248

5349
abstract class AdvancedFormsTestCase extends DbTestCase
5450
{
5551
use FormTesterTrait;
52+
use ConfigurableItemsTrait;
5653

5754
/** @return array<array{ConfigurableItemInterface&QuestionTypeInterface}> */
5855
final public static function provideQuestionTypes(): array
@@ -72,42 +69,6 @@ public function setUp(): void
7269
]);
7370
}
7471

75-
protected function enableConfigurableItem(
76-
ConfigurableItemInterface|string $item,
77-
): void {
78-
$this->setConfigurableItemConfig($item, true);
79-
InitManager::getInstance()->init();
80-
}
81-
82-
/** @var array<ConfigurableItemInterface|string> $items */
83-
protected function enableConfigurableItems(
84-
array $items,
85-
): void {
86-
foreach ($items as $item) {
87-
$this->setConfigurableItemConfig($item, true);
88-
}
89-
90-
InitManager::getInstance()->init();
91-
}
92-
93-
protected function disableConfigurableItem(
94-
ConfigurableItemInterface|string $item,
95-
): void {
96-
$this->setConfigurableItemConfig($item, false);
97-
InitManager::getInstance()->init();
98-
}
99-
100-
/** @var array<ConfigurableItemInterface|string> $items */
101-
protected function disableConfigurableItems(
102-
array $items,
103-
): void {
104-
foreach ($items as $item) {
105-
$this->setConfigurableItemConfig($item, false);
106-
}
107-
108-
InitManager::getInstance()->init();
109-
}
110-
11172
protected function setupAuthLdap(): AuthLDAP
11273
{
11374
return $this->createItem(AuthLDAP::class, [
@@ -141,36 +102,4 @@ protected function createFormWithLdapQuestion(AuthLdap $ldap): Form
141102
);
142103
return $this->createForm($builder);
143104
}
144-
145-
private function setConfigurableItemConfig(
146-
ConfigurableItemInterface|string $item,
147-
bool $enabled,
148-
): void {
149-
if (
150-
is_string($item)
151-
&& !is_a($item, ConfigurableItemInterface::class, true)
152-
) {
153-
throw new InvalidArgumentException();
154-
}
155-
156-
Config::setConfigurationValues('advancedforms', [
157-
$item::getConfigKey() => (int) $enabled,
158-
]);
159-
}
160-
161-
private function deleteSingletonInstance(array $classes)
162-
{
163-
foreach ($classes as $class) {
164-
$reflection_class = new ReflectionClass($class);
165-
if ($reflection_class->hasProperty('instance')) {
166-
$reflection_property = $reflection_class->getProperty('instance');
167-
$reflection_property->setValue(null, null);
168-
}
169-
170-
if ($reflection_class->hasProperty('_instances')) {
171-
$reflection_property = $reflection_class->getProperty('_instances');
172-
$reflection_property->setValue(null, []);
173-
}
174-
}
175-
}
176105
}

tests/ConfigurableItemsTrait.php

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
3+
/**
4+
* -------------------------------------------------------------------------
5+
* advancedforms plugin for GLPI
6+
* -------------------------------------------------------------------------
7+
*
8+
* MIT License
9+
*
10+
* Permission is hereby granted, free of charge, to any person obtaining a copy
11+
* of this software and associated documentation files (the "Software"), to deal
12+
* in the Software without restriction, including without limitation the rights
13+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14+
* copies of the Software, and to permit persons to whom the Software is
15+
* furnished to do so, subject to the following conditions:
16+
*
17+
* The above copyright notice and this permission notice shall be included in all
18+
* copies or substantial portions of the Software.
19+
*
20+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26+
* SOFTWARE.
27+
* -------------------------------------------------------------------------
28+
* @copyright Copyright (C) 2025 by the advancedforms plugin team.
29+
* @license MIT https://opensource.org/licenses/mit-license.php
30+
* @link https://github.com/pluginsGLPI/advancedforms
31+
* -------------------------------------------------------------------------
32+
*/
33+
34+
namespace GlpiPlugin\Advancedforms\Tests;
35+
36+
use Config;
37+
use GlpiPlugin\Advancedforms\Model\Config\ConfigurableItemInterface;
38+
use GlpiPlugin\Advancedforms\Service\InitManager;
39+
use InvalidArgumentException;
40+
use ReflectionClass;
41+
42+
/**
43+
* Enable or disable the plugin's configurable items (question types, ...) from a
44+
* test case.
45+
*
46+
* Available as a trait (and not only through AdvancedFormsTestCase) because some
47+
* test cases must extend a core abstract test case instead.
48+
*/
49+
trait ConfigurableItemsTrait
50+
{
51+
protected function enableConfigurableItem(
52+
ConfigurableItemInterface|string $item,
53+
): void {
54+
$this->setConfigurableItemConfig($item, true);
55+
InitManager::getInstance()->init();
56+
}
57+
58+
/** @var array<ConfigurableItemInterface|string> $items */
59+
protected function enableConfigurableItems(
60+
array $items,
61+
): void {
62+
foreach ($items as $item) {
63+
$this->setConfigurableItemConfig($item, true);
64+
}
65+
66+
InitManager::getInstance()->init();
67+
}
68+
69+
protected function disableConfigurableItem(
70+
ConfigurableItemInterface|string $item,
71+
): void {
72+
$this->setConfigurableItemConfig($item, false);
73+
InitManager::getInstance()->init();
74+
}
75+
76+
/** @var array<ConfigurableItemInterface|string> $items */
77+
protected function disableConfigurableItems(
78+
array $items,
79+
): void {
80+
foreach ($items as $item) {
81+
$this->setConfigurableItemConfig($item, false);
82+
}
83+
84+
InitManager::getInstance()->init();
85+
}
86+
87+
private function setConfigurableItemConfig(
88+
ConfigurableItemInterface|string $item,
89+
bool $enabled,
90+
): void {
91+
if (
92+
is_string($item)
93+
&& !is_a($item, ConfigurableItemInterface::class, true)
94+
) {
95+
throw new InvalidArgumentException();
96+
}
97+
98+
Config::setConfigurationValues('advancedforms', [
99+
$item::getConfigKey() => (int) $enabled,
100+
]);
101+
}
102+
103+
/** @var array<class-string> $classes */
104+
private function deleteSingletonInstance(array $classes)
105+
{
106+
foreach ($classes as $class) {
107+
$reflection_class = new ReflectionClass($class);
108+
if ($reflection_class->hasProperty('instance')) {
109+
$reflection_property = $reflection_class->getProperty('instance');
110+
$reflection_property->setValue(null, null);
111+
}
112+
113+
if ($reflection_class->hasProperty('_instances')) {
114+
$reflection_property = $reflection_class->getProperty('_instances');
115+
$reflection_property->setValue(null, []);
116+
}
117+
}
118+
}
119+
}

0 commit comments

Comments
 (0)