You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

852 lines
27 KiB

1 year ago
<?php
/*
** Zabbix
** Copyright (C) 2001-2023 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
require_once dirname(__FILE__).'/../../include/CWebTest.php';
/**
* The ignore browser errors annotation is required due to the errors coming from the URL opened in the URL widget.
* @ignoreBrowserErrors
*
* @backup dashboard
* @onBefore prepareData
*/
class testDashboardURLWidget extends CWebTest {
/**
* Attach MessageBehavior to the test.
*
* @return array
*/
public function getBehaviors() {
return [
'class' => CMessageBehavior::class
];
}
private static $dashboardid;
private static $dashboard_create;
private static $default_widget = 'Default URL Widget';
private static $update_widget = 'Update URL Widget';
private static $delete_widget = 'Widget for delete';
private static $frame_widget = 'Widget for iframe and xframe testing';
/**
* SQL query to get widget and widget_field tables to compare hash values, but without widget_fieldid
* because it can change.
*/
private $sql = 'SELECT wf.widgetid, wf.type, wf.name, wf.value_int, wf.value_str, wf.value_groupid, wf.value_hostid,'.
' wf.value_itemid, wf.value_graphid, wf.value_sysmapid, w.widgetid, w.dashboard_pageid, w.type, w.name, w.x, w.y,'.
' w.width, w.height'.
' FROM widget_field wf'.
' INNER JOIN widget w'.
' ON w.widgetid=wf.widgetid ORDER BY wf.widgetid, wf.name, wf.value_int, wf.value_str, wf.value_groupid,'.
' wf.value_itemid, wf.value_graphid';
public static function prepareData() {
$response = CDataHelper::call('dashboard.create', [
[
'name' => 'Dashboard for URL Widget test',
'pages' => [
[
'name' => 'Page with default widgets',
'widgets' => [
[
'type' => 'url',
'name' => self::$default_widget,
'x' => 0,
'y' => 0,
'width' => 12,
'height' => 5,
'fields' => [
[
'type' => ZBX_WIDGET_FIELD_TYPE_STR,
'name' => 'url',
'value' => 'http://zabbix.com'
],
[
'type' => ZBX_WIDGET_FIELD_TYPE_INT32,
'name' => 'dynamic',
'value' => '1'
]
]
],
[
'type' => 'url',
'name' => self::$frame_widget,
'x' => 12,
'y' => 0,
'width' => 12,
'height' => 5,
'fields' => [
[
'type' => ZBX_WIDGET_FIELD_TYPE_STR,
'name' => 'url',
'value' => 'zabbix.php?action=host.edit&hostid=10084'
]
]
],
[
'type' => 'url',
'name' => self::$delete_widget,
'x' => 0,
'y' => 5,
'width' => 12,
'height' => 5,
'fields' => [
[
'type' => ZBX_WIDGET_FIELD_TYPE_STR,
'name' => 'url',
'value' => 'zabbix.php?action=dashboard.view'
]
]
]
]
]
]
],
[
'name' => 'Dashboard for URL Widget create/update test',
'pages' => [
[
'name' => 'Page with created/updated widgets',
'widgets' => [
[
'type' => 'url',
'name' => self::$update_widget,
'x' => 0,
'y' => 0,
'width' => 12,
'height' => 5,
'fields' => [
[
'type' => ZBX_WIDGET_FIELD_TYPE_STR,
'name' => 'url',
'value' => 'https://zabbix.com'
]
]
]
]
]
]
]
]);
self::$dashboardid = $response['dashboardids'][0];
self::$dashboard_create = $response['dashboardids'][1];
// Create host for ResolvedMacro test purposes.
CDataHelper::createHosts([
[
'host' => 'Host for resolved DNS macro',
'interfaces' => [
[
'type' => INTERFACE_TYPE_AGENT,
'main' => INTERFACE_PRIMARY,
'useip' => INTERFACE_USE_DNS,
'ip' => '',
'dns' => 'dnsmacro.com',
'port' => '10051'
]
],
'groups' => [
'groupid' => '4'
],
'items' => [
[
'name' => 'Test DNS',
'key_' => 'dns_macro',
'type' => ITEM_TYPE_ZABBIX,
'value_type' => ITEM_VALUE_TYPE_FLOAT,
'delay' => '30'
]
]
]
]);
}
public function testDashboardURLWidget_Layout() {
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$dashboard = CDashboardElement::find()->one();
$dialog = $dashboard->edit()->addWidget();
$this->assertEquals('Add widget', $dialog->getTitle());
$form = $dialog->asForm();
if ($form->getField('Type')->getText() !== 'URL') {
$form->fill(['Type' => CFormElement::RELOADABLE_FILL('URL')]);
}
// Check default state.
$default_state = [
'Type' => 'URL',
'Name' => '',
'Show header' => true,
'Refresh interval' => 'Default (No refresh)',
'URL' => '',
'Enable host selection' => false
];
$form->checkValue($default_state);
$this->assertTrue($form->isRequired('URL'));
// Check attributes of input elements.
$inputs = [
'Name' => [
'maxlength' => '255',
'placeholder' => 'default'
],
'URL' => [
'maxlength' => '2048'
]
];
foreach ($inputs as $field => $attributes) {
$this->assertTrue($form->getField($field)->isAttributePresent($attributes));
}
$refresh_interval = ['Default (No refresh)', 'No refresh', '10 seconds', '30 seconds', '1 minute',
'2 minutes', '10 minutes', '15 minutes'];
$this->assertEquals($refresh_interval, $form->getField('Refresh interval')->getOptions()->asText());
// Check if buttons present and clickable.
$this->assertEquals(2, $dialog->query('button', ['Add', 'Cancel'])->all()
->filter(new CElementFilter(CElementFilter::CLICKABLE))->count()
);
$dialog->close();
$dashboard->save();
// Check parameter 'Enable host selection' true/false state.
$host_selector = $dashboard->getControls()->query('class:multiselect-control')->asMultiselect()->one();
$this->assertTrue($host_selector->isVisible());
$this->assertEquals('No host selected.', $dashboard->getWidget(self::$default_widget)
->query('class:nothing-to-show')->one()->getText());
$dashboard->getWidget(self::$default_widget)->edit();
$this->assertEquals('Edit widget', $dialog->getTitle());
$form->fill(['Enable host selection' => false])->submit();
$dashboard->save();
$this->assertFalse($host_selector->isVisible());
}
public static function getWidgetData() {
return [
[
[
'expected' => TEST_BAD,
'fields' => [
'URL' => ''
],
'error' => 'Invalid parameter "URL": cannot be empty.'
]
],
[
[
'expected' => TEST_BAD,
'fields' => [
'URL' => '?'
],
'error' => 'Invalid parameter "URL": unacceptable URL.'
]
],
[
[
'expected' => TEST_BAD,
'fields' => [
'URL' => 'dns://zabbix.com'
],
'error' => 'Invalid parameter "URL": unacceptable URL.'
]
],
[
[
'expected' => TEST_BAD,
'fields' => [
'URL' => 'message://zabbix.com'
],
'error' => 'Invalid parameter "URL": unacceptable URL.'
]
],
// Widget name "URL", if no name is given.
[
[
'expected' => TEST_GOOD,
'fields' => [
'Name' => '',
'URL' => 'zabbix.php?action=dashboard.view'
]
]
],
// The 'Refresh interval' value depends on the previous test case value = 'No refresh'.
[
[
'expected' => TEST_GOOD,
'fields' => [
'URL' => 'http://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Refresh interval' => 'Default (No refresh)',
'URL' => 'http://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Show header' => false,
'Refresh interval' => '10 seconds',
'URL' => 'http://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Show header' => false,
'Refresh interval' => '30 seconds',
'URL' => 'https://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Refresh interval' => '1 minute',
'URL' => 'ftp://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Refresh interval' => '2 minutes',
'URL' => 'file://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Refresh interval' => '10 minutes',
'URL' => 'mailto://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Refresh interval' => '15 minutes',
'URL' => 'tel://zabbix.com'
]
]
],
[
[
'expected' => TEST_GOOD,
'fields' => [
'Refresh interval' => 'No refresh',
'URL' => 'ssh://zabbix.com'
]
]
]
];
}
/**
* @dataProvider getWidgetData
*/
public function testDashboardURLWidget_Create($data) {
$this->checkWidgetForm($data);
}
public function testDashboardURLWidget_SimpleUpdate() {
$old_hash = CDBHelper::getHash($this->sql);
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboard_create)->waitUntilReady();
$dashboard = CDashboardElement::find()->one();
$dashboard->getWidget(self::$update_widget)->edit()->submit();
$dashboard->save();
$this->page->waitUntilReady();
$this->assertMessage(TEST_GOOD, 'Dashboard updated');
$this->assertEquals($old_hash, CDBHelper::getHash($this->sql));
}
/**
* @dataProvider getWidgetData
*/
public function testDashboardURLWidget_Update($data) {
$this->checkWidgetForm($data, true);
}
/**
* Perform URL widget creation or update and verify the result.
*
* @param boolean $update updating is performed
*/
public function checkWidgetForm($data, $update = false) {
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
$old_hash = CDBHelper::getHash($this->sql);
}
$data['fields']['Name'] = CTestArrayHelper::get($data, 'fields.Name', 'URL widget test '.microtime());
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboard_create)->waitUntilReady();
$dashboard = CDashboardElement::find()->one();
$old_widget_count = $dashboard->getWidgets()->count();
$form = ($update)
? $dashboard->getWidget(self::$update_widget)->edit()->asForm()
: $dashboard->edit()->addWidget()->asForm();
if ($form->getField('Type')->getText() !== 'URL') {
$form->fill(['Type' => CFormElement::RELOADABLE_FILL('URL')]);
}
$form->fill($data['fields']);
$values = $form->getValues();
$form->submit();
$this->page->waitUntilReady();
if (CTestArrayHelper::get($data, 'expected', TEST_GOOD) === TEST_BAD) {
$this->assertMessage($data['expected'], null, $data['error']);
$this->assertEquals($old_hash, CDBHelper::getHash($this->sql));
COverlayDialogElement::find()->one()->close();
$dashboard->save();
$this->page->waitUntilReady();
$this->assertFalse($dashboard->getWidget($data['fields']['Name'], false)->isValid());
}
else {
// If name is empty string it is replaced by default name "URL".
$header = ($data['fields']['Name'] === '') ? 'URL' : $data['fields']['Name'];
if ($update) {
self::$update_widget = $header;
}
COverlayDialogElement::ensureNotPresent();
$widget = $dashboard->getWidget($header);
// Save Dashboard to ensure that widget is correctly saved.
$dashboard->save();
$this->page->waitUntilReady();
$this->assertMessage(TEST_GOOD, 'Dashboard updated');
// Check widget count.
$this->assertEquals($old_widget_count + ($update ? 0 : 1), $dashboard->getWidgets()->count());
// Check new widget form fields and values in frontend.
$saved_form = $widget->edit();
$this->assertEquals($values, $saved_form->getValues());
if (array_key_exists('Show header', $data['fields'])) {
$saved_form->checkValue(['Show header' => $data['fields']['Show header']]);
}
$saved_form->submit();
COverlayDialogElement::ensureNotPresent();
$dashboard->save();
$this->page->waitUntilReady();
$this->assertMessage(TEST_GOOD, 'Dashboard updated');
// Check new widget update interval.
$refresh = (CTestArrayHelper::get($data['fields'], 'Refresh interval') === 'Default (No refresh)')
? 'No refresh'
: (CTestArrayHelper::get($data['fields'], 'Refresh interval', 'No refresh'));
$this->assertEquals($refresh, $widget->getRefreshInterval());
}
}
public static function getCancelData() {
return [
// Cancel update widget.
[
[
'update' => true,
'save_widget' => true,
'save_dashboard' => false
]
],
[
[
'update' => true,
'save_widget' => false,
'save_dashboard' => true
]
],
// Cancel create widget.
[
[
'save_widget' => true,
'save_dashboard' => false
]
],
[
[
'save_widget' => false,
'save_dashboard' => true
]
]
];
}
/**
* @dataProvider getCancelData
*/
public function testDashboardURLWidget_Cancel($data) {
$old_hash = CDBHelper::getHash($this->sql);
$new_name = 'Widget to be cancelled';
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$dashboard = CDashboardElement::find()->one()->edit();
$old_widget_count = $dashboard->getWidgets()->count();
// Start updating or creating a widget.
if (CTestArrayHelper::get($data, 'update', false)) {
$form = $dashboard->getWidget(self::$default_widget)->edit();
}
else {
$form = $dashboard->addWidget()->asForm();
if ($form->getField('Type')->getText() !== 'URL') {
$form->fill(['Type' => CFormElement::RELOADABLE_FILL('URL')]);
}
}
$form->fill([
'Name' => $new_name,
'Refresh interval' => '15 minutes',
'URL' => 'zabbix.php?action=dashboard.view'
]);
// Save or cancel widget.
if (CTestArrayHelper::get($data, 'save_widget', false)) {
$form->submit();
// Check that changes took place on the unsaved dashboard.
$this->assertTrue($dashboard->getWidget($new_name)->isVisible());
}
else {
$dialog = COverlayDialogElement::find()->one();
$dialog->query('button:Cancel')->one()->click();
$dialog->ensureNotPresent();
if (CTestArrayHelper::get($data, 'update', false)) {
foreach ([self::$default_widget => true, $new_name => false] as $name => $valid) {
$dashboard->getWidget($name, false)->isValid($valid);
}
}
$this->assertEquals($old_widget_count, $dashboard->getWidgets()->count());
}
// Save or cancel dashboard update.
if (CTestArrayHelper::get($data, 'save_dashboard', false)) {
$dashboard->save();
}
else {
$dashboard->cancelEditing();
}
// Confirm that no changes were made to the widget.
$this->assertEquals($old_hash, CDBHelper::getHash($this->sql));
}
public function testDashboardURLWidget_Delete() {
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$dashboard = CDashboardElement::find()->one()->edit();
$widget = $dashboard->getWidget(self::$delete_widget);
$dashboard->deleteWidget(self::$delete_widget);
$widget->waitUntilNotPresent();
$dashboard->save();
$this->assertMessage(TEST_GOOD, 'Dashboard updated');
// Confirm that widget is not present on dashboard.
$this->assertFalse($dashboard->getWidget(self::$delete_widget, false)->isValid());
$widget_sql = 'SELECT NULL FROM widget_field wf LEFT JOIN widget w ON w.widgetid=wf.widgetid'.
' WHERE w.name='.zbx_dbstr(self::$delete_widget);
$this->assertEquals(0, CDBHelper::getCount($widget_sql));
}
public static function getWidgetMacroData() {
return [
[
[
'fields' => [
'Name' => 'ЗАББИКС Сервер',
'Enable host selection' => true,
'URL' => 'zabbix.php?action=host.edit&hostid={HOST.ID}'
],
'result' => [
'element' => 'id:visiblename',
'value' => 'ЗАББИКС Сервер',
'src' => 'zabbix.php?action=host.edit&hostid=10084'
]
]
],
[
[
'fields' => [
'Name' => 'Dynamic widgets H1',
'Enable host selection' => true,
'URL' => 'zabbix.php?name={HOST.NAME}&ip=&dns=&port=&status=-1&evaltype=0&tags[0][tag]=&'.
'tags[0][operator]=0&tags[0][value]=&maintenance_status=1&filter_name=&filter_show_counter=0&'.
'filter_custom_time=0&sort=name&sortorder=ASC&show_suppressed=0&action=host.view'
],
'result' => [
'element' => 'id:name_#{uniqid}',
'value' => 'Dynamic widgets H1',
'src' => 'zabbix.php?name=Dynamic widgets H1&ip=&dns=&port=&status=-1&evaltype=0&tags[0][tag]=&'.
'tags[0][operator]=0&tags[0][value]=&maintenance_status=1&filter_name=&filter_show_counter=0&'.
'filter_custom_time=0&sort=name&sortorder=ASC&show_suppressed=0&action=host.view'
]
]
],
[
[
'fields' => [
'Name' => 'Host-layout-test-001',
'Enable host selection' => true,
'URL' => 'zabbix.php?name=&ip={HOST.IP}&dns=&port=&status=-1&evaltype=0&tags[0][tag]=&'.
'tags[0][operator]=0&tags[0][value]=&maintenance_status=1&filter_name=&filter_show_counter=0&'.
'filter_custom_time=0&sort=name&sortorder=ASC&show_suppressed=0&action=host.view'
],
'result' => [
'element' => 'id:ip_#{uniqid}',
'value' => '127.0.7.1',
'src' => 'zabbix.php?name=&ip=127.0.7.1&dns=&port=&status=-1&evaltype=0&tags[0][tag]=&'.
'tags[0][operator]=0&tags[0][value]=&maintenance_status=1&filter_name=&filter_show_counter=0&'.
'filter_custom_time=0&sort=name&sortorder=ASC&show_suppressed=0&action=host.view'
]
]
],
[
[
'fields' => [
'Name' => 'Host for resolved DNS macro',
'Enable host selection' => true,
'URL' => 'zabbix.php?name=&ip=&dns={HOST.DNS}&port=&status=-1&evaltype=0&tags[0][tag]=&'.
'tags[0][operator]=0&tags[0][value]=&maintenance_status=1&filter_name=&filter_show_counter=0&'.
'filter_custom_time=0&sort=name&sortorder=ASC&show_suppressed=0&action=host.view'
],
'result' => [
'element' => 'id:dns_#{uniqid}',
'value' => 'dnsmacro.com',
'src' => 'zabbix.php?name=&ip=&dns=dnsmacro.com&port=&status=-1&evaltype=0&'.
'tags[0][tag]=&tags[0][operator]=0&tags[0][value]=&maintenance_status=1&filter_name=&'.
'filter_show_counter=0&filter_custom_time=0&sort=name&sortorder=ASC&show_suppressed=0&action=host.view'
]
]
]
];
}
/**
* @dataProvider getWidgetMacroData
*/
public function testDashboardURLWidget_ResolvedMacro($data) {
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$dashboard = CDashboardElement::find()->one();
$form = $dashboard->getWidget(self::$default_widget)->edit();
if ($form->getField('Type')->getText() !== 'URL') {
$form->fill(['Type' => CFormElement::RELOADABLE_FILL('URL')]);
}
$form->fill($data['fields'])->submit();
$dashboard->save();
self::$default_widget = $data['fields']['Name'];
// Select host.
$host = $dashboard->getControls()->query('class:multiselect-control')->asMultiselect()->one()->fill($data['fields']['Name']);
// Check widget content when the host match dynamic option criteria.
$widget = $dashboard->getWidget($data['fields']['Name'])->getContent();
$this->page->switchTo($widget->query('id:iframe')->one());
$this->assertEquals($data['result']['value'], $this->query($data['result']['element'])->one()->getValue());
// Check iframe source link
$this->page->switchTo();
$this->assertEquals($data['result']['src'], $widget->query('xpath://iframe')->one()->getAttribute('src'));
$host->clear();
}
/**
* Modify iframe sandboxing and exception configuration. Parameters determine whether retrieved URL content
* should be put into the sandbox or not.
*/
public function testDashboardURLWidget_IframeSandboxing() {
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$dashboard = CDashboardElement::find()->one();
$widget = $dashboard->getWidget(self::$frame_widget)->getContent();
// Update host in widget.
foreach ([true, false] as $state) {
$this->page->switchTo($widget->query('id:iframe')->one());
$this->query('button:Update')->one()->click();
// Wait for message good when 'Use iframe sandboxing' is unchecked (false).
if (!$state) {
CMessageElement::find()->one()->waitUntilVisible();
}
// Verifies that host in widget can or can't be updated regarding 'Use iframe sandboxing' state.
$this->assertFalse($this->query('class:msg-good')->one(false)->isVisible($state));
// After successful host update, the page is redirected to the list of hosts where Update button isn't visible.
$this->assertTrue($this->query('button:Update')->one(false)->isVisible($state));
$this->page->switchTo();
// Disable 'Use iframe sandboxing' option for false state scenario.
if ($state) {
$this->page->open('zabbix.php?action=miscconfig.edit')->waitUntilReady();
$other_form = $this->query('name:otherForm')->waitUntilVisible()->asForm()->one();
$other_form->fill(['Use iframe sandboxing' => !$state]);
$other_form->submit();
$this->page->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
}
}
// Check that host in widget can be updated via iframe if necessary sandboxing exceptions are set.
$this->page->open('zabbix.php?action=miscconfig.edit')->waitUntilReady();
$other_form->fill([
'Use iframe sandboxing' => true,
'Iframe sandboxing exceptions' => 'allow-scripts allow-same-origin allow-forms'
]);
$other_form->submit();
$this->page->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$this->page->switchTo($widget->query('id:iframe')->one());
$this->query('button:Update')->one()->click();
CMessageElement::find()->one()->waitUntilVisible();
$this->assertTrue($this->query('class:msg-good')->one()->isVisible());
$this->assertFalse($this->query('button:Update')->one(false)->isVisible());
$this->page->switchTo();
}
/**
* Modify the URI scheme validation rules and check the result for the URL type in Widget form.
*/
public function testDashboardURLWidget_ValidateUriSchemes() {
$invalid_schemes = ['dns://zabbix.com', 'message://zabbix.com'];
$default_valid_schemes = ['http://zabbix.com', 'https://zabbix.com', 'ftp://zabbix.com', 'file://zabbix.com',
'mailto://zabbix.com', 'tel://zabbix.com', 'ssh://zabbix.com'
];
$this->page->login()->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$dashboard = CDashboardElement::find()->one();
$form = $dashboard->getWidget(self::$default_widget)->edit();
// Check default URI scheme rules: http, https, ftp, file, mailto, tel, ssh.
$this->assertUriScheme($form, $default_valid_schemes);
$this->assertUriScheme($form, $invalid_schemes, TEST_BAD);
// Change valid URI schemes on "Other configuration parameters" page.
$this->page->open('zabbix.php?action=miscconfig.edit')->waitUntilReady();
$config_form = $this->query('name:otherForm')->asForm()->waitUntilVisible()->one();
$config_form->fill(['Valid URI schemes' => 'dns,message']);
$config_form->submit();
$this->assertMessage(TEST_GOOD, 'Configuration updated');
// Check that already created widget became invalid and returns error regarding invalid parameter.
$this->page->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$widget = $dashboard->getWidget(self::$default_widget)->getContent();
$this->assertEquals('Invalid parameter "URL": unacceptable URL.', $widget->query('class:msg-details')->one()->getText());
$broken_form = $dashboard->getWidget(self::$default_widget)->edit();
// Check that the widget URL field is empty.
$broken_form->checkValue(['URL' => '', 'Name' => self::$default_widget]);
COverlayDialogElement::find()->one()->close();
$this->query('button:Save changes')->one()->click();
// Check that Dashboard can't be saved and returns error regarding invalid parameter.
$message = CMessageElement::find('xpath://div[@class="wrapper"]', true)->one();
$this->assertMessage(TEST_BAD, null, 'Cannot save widget "'.self::$default_widget.'". Invalid parameter "URL": unacceptable URL.');
$message->close();
// Check updated valid URI schemes.
$dashboard->getWidget(self::$default_widget)->edit();
$broken_form->fill(['URL' => 'any'])->submit();
$this->assertUriScheme($form, $default_valid_schemes, TEST_BAD);
$this->assertUriScheme($form, $invalid_schemes);
// Disable URI scheme validation.
$this->page->open('zabbix.php?action=miscconfig.edit')->waitUntilReady();
$config_form->invalidate();
$config_form->fill(['Validate URI schemes' => false]);
$config_form->submit();
$this->assertMessage(TEST_GOOD, 'Configuration updated');
$this->page->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$this->assertUriScheme($form, array_merge($default_valid_schemes, $invalid_schemes));
}
/**
* Fill in the URL field to check the uri scheme validation rules.
*
* @param CFormElement $form form element of widget
* @param array $data url field data
* @param string $expected expected result after widget form submit, TEST_GOOD or TEST_BAD
*/
private function assertUriScheme($form, $data, $expected = TEST_GOOD) {
$dashboard = CDashboardElement::find()->one();
foreach ($data as $scheme) {
$dashboard->getWidget(self::$default_widget)->edit();
COverlayDialogElement::find()->one()->waitUntilReady();
$form->fill(['URL' => $scheme]);
$form->submit();
if ($expected === TEST_GOOD) {
$dashboard->save();
$this->page->waitUntilReady();
$this->assertMessage(TEST_GOOD, 'Dashboard updated');
}
else {
$this->assertMessage(TEST_BAD, null, 'Invalid parameter "URL": unacceptable URL.');
CMessageElement::find()->one()->close();
COverlayDialogElement::find()->one()->close();
}
}
}
/**
* Modify value of 'HTTP X-Frame-options header' and check widget content with changed Xframe options.
* TODO: new test cases should be added after ZBX-21973 fix.
*/
public function testDashboardURLWidget_XframeOptions() {
// Change Xframe options.
$this->page->login()->open('zabbix.php?action=miscconfig.edit')->waitUntilReady();
$other_form = $this->query('name:otherForm')->waitUntilVisible()->asForm()->one();
$other_form->fill(['X-Frame-Options HTTP header' => 'DENY']);
$other_form->submit();
// Check widget content with changed Xframe options.
$this->page->open('zabbix.php?action=dashboard.view&dashboardid='.self::$dashboardid)->waitUntilReady();
$dashboard = CDashboardElement::find()->one();
$widget = $dashboard->getWidget(self::$frame_widget)->getContent();
$this->page->switchTo($widget->query('id:iframe')->one());
$error_details = $this->query('id:sub-frame-error-details')->one()->getText();
$this->assertStringContainsString( 'refused to connect.', $error_details);
$this->page->switchTo();
}
}