mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-09-26 11:19:16 +02:00
Fix form field suggestions (#2840)
Other available fields should be suggested when no check command has been chosen for service template. fixes #2826, #2815
This commit is contained in:
commit
0493f93a74
1
.github/workflows/php.yml
vendored
1
.github/workflows/php.yml
vendored
@ -150,6 +150,7 @@ jobs:
|
||||
|
||||
- name: Setup Libraries
|
||||
run: |
|
||||
composer require --working-dir=_icingaweb2 -n --no-progress mockery/mockery
|
||||
mkdir _libraries
|
||||
git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-library.git _libraries/ipl
|
||||
git clone --depth 1 -b snapshot/nightly https://github.com/Icinga/icinga-php-thirdparty.git _libraries/vendor
|
||||
|
@ -53,13 +53,8 @@ class IcingaObjectFieldForm extends DirectorObjectForm
|
||||
$command = null;
|
||||
}
|
||||
|
||||
if ($command) {
|
||||
$suggestions = $this->fieldSuggestion = new FormFieldSuggestion($command, $this->db->enumDatafields());
|
||||
$fields = $suggestions->getCommandFields();
|
||||
} else {
|
||||
$suggestions = null;
|
||||
$fields = [];
|
||||
}
|
||||
$suggestions = $this->fieldSuggestion = new FormFieldSuggestion($command, $this->db->enumDatafields());
|
||||
$fields = $suggestions->getCommandFields();
|
||||
|
||||
$this->addElement('select', 'datafield_id', [
|
||||
'label' => 'Field',
|
||||
@ -97,7 +92,7 @@ class IcingaObjectFieldForm extends DirectorObjectForm
|
||||
. ' user puts the focus on this field'
|
||||
),
|
||||
'ignore' => true,
|
||||
'value' => $suggestions ? $suggestions->getDescription($id) : null,
|
||||
'value' => $command ? $suggestions->getDescription($id) : null,
|
||||
'rows' => '3',
|
||||
]);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class FormFieldSuggestion
|
||||
protected $descriptions = [];
|
||||
protected $booleans = [];
|
||||
|
||||
/** @var IcingaCommand */
|
||||
/** @var ?IcingaCommand */
|
||||
protected $command;
|
||||
|
||||
/** @var array */
|
||||
@ -29,7 +29,7 @@ class FormFieldSuggestion
|
||||
protected $fields = null;
|
||||
|
||||
public function __construct(
|
||||
IcingaCommand $command,
|
||||
?IcingaCommand $command,
|
||||
array $existingFields
|
||||
) {
|
||||
$this->command = $command;
|
||||
@ -54,19 +54,23 @@ class FormFieldSuggestion
|
||||
$this->blacklistedVars['$' . $m[1] . '$'] = $id;
|
||||
}
|
||||
}
|
||||
foreach ($this->command->arguments() as $arg) {
|
||||
if ($arg->argument_format === 'string') {
|
||||
foreach (self::extractMacroNamesFromString($arg->argument_value) as $val) {
|
||||
$this->addSuggestion($val, $arg->description, $this->argumentVars);
|
||||
|
||||
if ($this->command) {
|
||||
foreach ($this->command->arguments() as $arg) {
|
||||
if ($arg->argument_format === 'string') {
|
||||
foreach (self::extractMacroNamesFromString($arg->argument_value) as $val) {
|
||||
$this->addSuggestion($val, $arg->description, $this->argumentVars);
|
||||
}
|
||||
}
|
||||
|
||||
if (($arg->set_if_format === 'string' || $arg->set_if_format === null)
|
||||
&& $val = self::getMacroIfStringIsSingleMacro($arg->set_if)
|
||||
) {
|
||||
$this->addSuggestion($val, $arg->description, $this->booleans);
|
||||
}
|
||||
}
|
||||
|
||||
if (($arg->set_if_format === 'string' || $arg->set_if_format === null)
|
||||
&& $val = self::getMacroIfStringIsSingleMacro($arg->set_if)
|
||||
) {
|
||||
$this->addSuggestion($val, $arg->description, $this->booleans);
|
||||
}
|
||||
}
|
||||
|
||||
asort($this->suggestedFields, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
ksort($this->argumentVars);
|
||||
ksort($this->booleans);
|
||||
|
@ -10,20 +10,15 @@ use Icinga\Module\Director\Db;
|
||||
use Icinga\Module\Director\Db\Migrations;
|
||||
use Icinga\Module\Director\Objects\IcingaObject;
|
||||
use Icinga\Module\Director\Objects\IcingaZone;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Icinga\Test\BaseTestCase as IcingaBaseTestCase;
|
||||
|
||||
abstract class BaseTestCase extends TestCase
|
||||
abstract class BaseTestCase extends IcingaBaseTestCase
|
||||
{
|
||||
private static $app;
|
||||
|
||||
/** @var Db */
|
||||
private static $db;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->app();
|
||||
}
|
||||
|
||||
protected function skipForMissingDb()
|
||||
{
|
||||
if ($this->hasDb()) {
|
||||
@ -81,11 +76,14 @@ abstract class BaseTestCase extends TestCase
|
||||
self::$db = new Db($dbConfig);
|
||||
$migrations = new Migrations(self::$db);
|
||||
$migrations->applyPendingMigrations();
|
||||
IcingaZone::create([
|
||||
$zone = IcingaZone::create([
|
||||
'object_name' => 'director-global',
|
||||
'object_type' => 'external_object',
|
||||
'is_global' => 'y'
|
||||
])->store(self::$db);
|
||||
]);
|
||||
if (! IcingaZone::exists($zone->getId(), self::$db)) {
|
||||
$zone->store(self::$db);
|
||||
}
|
||||
}
|
||||
|
||||
return self::$db;
|
||||
|
@ -88,5 +88,7 @@ abstract class IcingaObjectTestCase extends BaseTestCase
|
||||
$this->subject->delete();
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ abstract class SyncTest extends BaseTestCase
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->source = ImportSource::create(array(
|
||||
'source_name' => 'testimport',
|
||||
'provider_class' => 'Icinga\\Module\\Director\\Test\\ImportSourceDummy',
|
||||
@ -75,6 +76,7 @@ abstract class SyncTest extends BaseTestCase
|
||||
// make sure cache is clean for other tests
|
||||
PrefetchCache::forget();
|
||||
DbObject::clearAllPrefetchCaches();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -510,11 +510,6 @@ parameters:
|
||||
count: 3
|
||||
path: library/Director/ProvidedHook/IcingaDbCubeLinks.php
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined method Icinga\\\\Module\\\\Director\\\\Test\\\\TestSuiteUnit\\:\\:newTempfile\\(\\)\\.$#"
|
||||
count: 1
|
||||
path: library/Director/Test/TestSuiteUnit.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property Zend_Controller_Action_HelperBroker\\:\\:\\$viewRenderer\\.$#"
|
||||
count: 1
|
||||
|
@ -25,6 +25,8 @@ parameters:
|
||||
|
||||
excludePaths:
|
||||
- library/Director/CoreBeta
|
||||
- test
|
||||
- library/Director/Test
|
||||
|
||||
universalObjectCratesClasses:
|
||||
- Icinga\Module\Director\Data\Db\DbObject
|
||||
|
151
test/php/library/Director/Form/IcingaObjectFieldFormTest.php
Normal file
151
test/php/library/Director/Form/IcingaObjectFieldFormTest.php
Normal file
@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Icinga\Module\Director\Field;
|
||||
|
||||
use Icinga\Module\Director\Forms\IcingaObjectFieldForm;
|
||||
use Icinga\Module\Director\Objects\DirectorDatafield;
|
||||
use Icinga\Module\Director\Objects\IcingaHost;
|
||||
use Icinga\Module\Director\Test\BaseTestCase;
|
||||
use Icinga\Module\Director\Objects\IcingaCommand;
|
||||
|
||||
class IcingaObjectFieldFormTest extends BaseTestCase
|
||||
{
|
||||
/** @var string */
|
||||
protected const COMMAND_NAME = 'icingaTestCommand';
|
||||
|
||||
/** @var string */
|
||||
protected const DATAFIELD_NAME = 'dataFieldTest';
|
||||
|
||||
/** @var string */
|
||||
protected const HOST_NAME = 'testHost';
|
||||
|
||||
/** @var ?DirectorDatafield */
|
||||
protected $testDatafield = null;
|
||||
|
||||
/** @var ?IcingaCommand */
|
||||
protected $testIcingaCommand = null;
|
||||
|
||||
/** @var IcingaHost */
|
||||
private $testHost;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
if ($this->hasDb()) {
|
||||
$db = $this->getDb();
|
||||
$this->testDatafield = DirectorDatafield::create([
|
||||
'varname' => self::DATAFIELD_NAME,
|
||||
'caption' => 'Blah',
|
||||
'description' => '',
|
||||
'datatype' => 'Icinga\Module\Director\DataType\DataTypeArray',
|
||||
'format' => 'json'
|
||||
]);
|
||||
$this->testDatafield->store($db);
|
||||
|
||||
$this->testIcingaCommand = IcingaCommand::create(
|
||||
[
|
||||
'object_name' => self::COMMAND_NAME,
|
||||
'object_type' => 'object'
|
||||
],
|
||||
$db
|
||||
);
|
||||
$this->testIcingaCommand->store($db);
|
||||
|
||||
$this->testHost = IcingaHost::create([
|
||||
'object_name' => self::HOST_NAME,
|
||||
'object_type' => 'object',
|
||||
'display_name' => 'Whatever'
|
||||
], $this->getDb());
|
||||
}
|
||||
}
|
||||
|
||||
public function testFieldSuggestionsWithoutCheckCommand()
|
||||
{
|
||||
if ($this->skipForMissingDb()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$db = $this->getDb();
|
||||
|
||||
$icingaHostFieldForm = (new IcingaObjectFieldForm())
|
||||
->setDb($db)
|
||||
->setIcingaObject($this->testHost);
|
||||
|
||||
$icingaHostFieldForm->setup();
|
||||
/** @var array<string> $suggestions */
|
||||
$suggestions = $icingaHostFieldForm->getElement('datafield_id')
|
||||
->getAttrib('options');
|
||||
|
||||
array_shift($suggestions);
|
||||
|
||||
$this->assertEquals(
|
||||
[
|
||||
'Other available fields' => [
|
||||
$this->testDatafield->get('id') => "Blah (dataFieldTest)"
|
||||
]
|
||||
],
|
||||
$suggestions
|
||||
);
|
||||
}
|
||||
|
||||
public function testFieldSuggestionsWithCheckCommand()
|
||||
{
|
||||
if ($this->skipForMissingDb()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$db = $this->getDb();
|
||||
|
||||
$this->testHost->check_command = self::COMMAND_NAME;
|
||||
$icingaHostFieldForm = (new IcingaObjectFieldForm())
|
||||
->setDb($db)
|
||||
->setIcingaObject($this->testHost);
|
||||
|
||||
$icingaHostFieldForm->setup();
|
||||
|
||||
/** @var array<string> $suggestions */
|
||||
$suggestions = $icingaHostFieldForm->getElement('datafield_id')
|
||||
->getAttrib('options');
|
||||
|
||||
array_shift($suggestions);
|
||||
$this->assertEquals(
|
||||
[
|
||||
'Other available fields' => [
|
||||
$this->testDatafield->get('id') => "Blah (dataFieldTest)"
|
||||
]
|
||||
],
|
||||
$suggestions
|
||||
);
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
if ($this->hasDb()) {
|
||||
$db = $this->getDb();
|
||||
$this->deleteDatafields();
|
||||
|
||||
if (IcingaHost::exists(self::HOST_NAME, $db)) {
|
||||
IcingaHost::load(self::HOST_NAME, $db)->delete();
|
||||
}
|
||||
|
||||
if (IcingaCommand::exists(self::COMMAND_NAME, $db)) {
|
||||
IcingaCommand::load(self::COMMAND_NAME, $db)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected function deleteDatafields()
|
||||
{
|
||||
$db = $this->getDb();
|
||||
$dbAdapter = $db->getDbAdapter();
|
||||
|
||||
$query = $dbAdapter->select()
|
||||
->from('director_datafield')
|
||||
->where('varname = ?', self::DATAFIELD_NAME);
|
||||
foreach (DirectorDatafield::loadAll($db, $query, 'id') as $datafield) {
|
||||
$datafield->delete();
|
||||
}
|
||||
}
|
||||
}
|
@ -167,5 +167,7 @@ class StateFilterSetTest extends BaseTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ class HostGroupMembershipResolverTest extends BaseTestCase
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
IcingaTemplateRepository::clear();
|
||||
}
|
||||
|
||||
|
@ -212,5 +212,7 @@ class IcingaCommandTest extends BaseTestCase
|
||||
if (IcingaCommand::exists($this->testCommandName, $db)) {
|
||||
IcingaCommand::load($this->testCommandName, $db)->delete();
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -747,7 +747,7 @@ class IcingaHostTest extends BaseTestCase
|
||||
}
|
||||
}
|
||||
|
||||
$kill = array('___TEST___zone');
|
||||
$kill = ['___TEST___zone', '___TEST___zone2'];
|
||||
foreach ($kill as $name) {
|
||||
if (IcingaZone::exists($name, $db)) {
|
||||
IcingaZone::load($name, $db)->delete();
|
||||
@ -756,6 +756,8 @@ class IcingaHostTest extends BaseTestCase
|
||||
|
||||
$this->deleteDatafields();
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected function deleteDatafields()
|
||||
|
@ -244,5 +244,7 @@ class IcingaNotificationTest extends BaseTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ class IcingaServiceSetTest extends IcingaObjectTestCase
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->assertNull($this->subject, 'subject must have been taken down before!');
|
||||
|
||||
if ($this->hasDb()) {
|
||||
|
@ -44,6 +44,7 @@ class IcingaServiceTest extends BaseTestCase
|
||||
|
||||
public function testAcceptsAssignRules()
|
||||
{
|
||||
$this->expectNotToPerformAssertions();
|
||||
$service = $this->service();
|
||||
$service->object_type = 'apply';
|
||||
$service->assign_filter = 'host.address="127.*"';
|
||||
@ -287,5 +288,7 @@ class IcingaServiceTest extends BaseTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -154,5 +154,7 @@ class IcingaTemplateResolverTest extends BaseTestCase
|
||||
IcingaHost::load($name, $db)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -180,5 +180,7 @@ class IcingaTimePeriodTest extends BaseTestCase
|
||||
IcingaTimePeriod::load($name, $db)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
@ -255,5 +255,7 @@ class TemplateTreeTest extends BaseTestCase
|
||||
$this->removeHosts($db);
|
||||
$this->removeServices($db);
|
||||
}
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user