<?php
/*
** Zabbix
** Copyright (C) 2001-2022 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';
require_once dirname(__FILE__).'/behaviors/CMessageBehavior.php';
require_once dirname(__FILE__).'/../include/helpers/CDataHelper.php';

/**
 * @backup hosts
 * @onBefore prepareUpdateData
 */
class testFormHost extends CWebTest {

	/**
	 * SQL query to get host and host interfaces tables to compare hash values.
	 */
	private $hosts_sql = 'SELECT * FROM hosts h INNER JOIN interface i ON h.hostid=i.hostid ORDER BY h.hostid, i.interfaceid';

	/**
	 * SQL query to get snmp interface table to compare hash values.
	 */
	private $interface_snmp_sql = 'SELECT * FROM interface_snmp ORDER BY interfaceid, community';

	/**
	 * Ids of the hosts that are created within this test specifically for the update scenario.
	 *
	 * @var array
	 */
	protected static $hostids;

	/**
	 * Ids of the items that are created within this test.
	 *
	 * @var array
	 */
	protected static $itemids;

	/**
	 * Default values of interfaces.
	 *
	 * @var array
	 */
	private $default_values = [
		'Agent' => [
			'ip' => '127.0.0.1',
			'dns' => '',
			'Connect to' => 'IP',
			'port' => '10050'
		],
		'SNMP' => [
			'ip' => '127.0.0.1',
			'dns' => '',
			'Connect to' => 'IP',
			'port' => '161',
			'SNMP version' => 'SNMPv2',
			'SNMP community' => '{$SNMP_COMMUNITY}',
			'Use bulk requests' => true
		],
		'JMX' => [
			'ip' => '127.0.0.1',
			'dns' => '',
			'Connect to' => 'IP',
			'port' => '12345'
		],
		'IPMI' => [
			'ip' => '127.0.0.1',
			'dns' => '',
			'Connect to' => 'IP',
			'port' => '623'
		]
	];

	/**
	 * Attach Behaviors to the test.
	 *
	 * @return array
	 */
	public function getBehaviors() {
		return ['class' => CMessageBehavior::class];
	}

	public static function prepareUpdateData() {
		$interfaces = [
			[
				'type' => 1,
				'main' => 1,
				'useip' => 1,
				'ip' => '127.1.1.1',
				'dns' => '',
				'port' => '10011'
			],
			[
				'type' => 2,
				'main' => 1,
				'useip' => 1,
				'ip' => '127.2.2.2',
				'dns' => '',
				'port' => '122',
				'details' => [
					'version' => '1',
					'bulk' => '0',
					'community' => 'zabbix'
				]
			],
			[
				'type' => 3,
				'main' => 1,
				'useip' => 0,
				'ip' => '',
				'dns' => 'selenium.test',
				'port' => '30053'
			],
			[
				'type' => 4,
				'main' => 1,
				'useip' => 1,
				'ip' => '127.4.4.4',
				'dns' => '',
				'port' => '426'
			]
		];

		$groups = [
			[
				'groupid' => 4
			]
		];

		$result = CDataHelper::createHosts([
			[
				'host' => 'testFormHost_Update',
				'name' => 'testFormHost_Update Visible name',
				'description' => 'Created host via API to test update functionality in host form and interfaces',
				'interfaces' => $interfaces,
				'groups' => $groups,
				'proxy_hostid' => 20001,
				'status' => HOST_STATUS_MONITORED
			],
			[
				'host' => 'testFormHost with items',
				'description' => 'Created host via API to test clone functionality in host form and interfaces',
				'interfaces' => $interfaces,
				'groups' => $groups,
				'proxy_hostid' => 20001,
				'status' => HOST_STATUS_NOT_MONITORED,
				'items' => [
					[
						'name' => 'Agent active item',
						'key_' => 'agent.ping',
						'type' => ITEM_TYPE_ZABBIX_ACTIVE,
						'value_type' => ITEM_VALUE_TYPE_UINT64,
						'delay' => '1m'
					],
					[
						'name' => 'Agent item',
						'key_' => 'agent.hostname',
						'type' => ITEM_TYPE_ZABBIX,
						'value_type' => ITEM_VALUE_TYPE_UINT64,
						'delay' => '1h'
					],
					[
						'name' => 'JMX item',
						'key_' => 'jmx[object_name,attribute_name]',
						'type' => ITEM_TYPE_JMX,
						'value_type' => ITEM_VALUE_TYPE_TEXT,
						'delay' => '1s',
						'username' => '',
						'password' => ''
					]
				]
			]
		]);

		self::$hostids = $result['hostids'];
		self::$itemids = $result['itemids'];
	}

	public function testFormHost_Layout() {
		$this->page->login()->open('hosts.php?form=update&hostid='.self::$hostids['testFormHost with items']);
		$form = $this->query('id:hostsForm')->asForm()->one()->waitUntilVisible();
		// Host form fields maxlength attribute.
		foreach (['Host name' => 128, 'Visible name' => 128, 'Description' => 65535] as $field => $maxlength) {
			$this->assertEquals($maxlength, $form->getField($field)->getAttribute('maxlength'));
		}

		$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement();
		$this->assertEquals(['', 'Type', 'IP address', 'DNS name', 'Connect to', 'Port', 'Default'], $interfaces_form->getHeadersText());

		foreach ($interfaces_form->getRows() as $i => $row) {
			$enabled = ($i !== 0 && $i !== 2);
			// "Remove" button is disabled (in the 7th column) for Agent (in 0th row) and JMX (in 2th row) interfaces.
			$this->assertTrue($row->getColumn(7)->query('tag:button')->one()->isEnabled($enabled));
		}
		// Interface fields maxlength attribute.
		foreach (['IP address' => 64, 'DNS name' => 255, 'Port' => 64] as $field => $maxlength) {
			$this->assertEquals($maxlength, $interfaces_form->getRow(0)->getColumn($field)
					->query('tag:input')->one()->getAttribute('maxlength'));
		}

		// Click the "expand" icon (in the 0th column) for the SNMP interface (1th row).
		$interfaces_form->getRow(1)->getColumn(0)->query('tag:button')->one()->click();
		$snmp_form = $interfaces_form->getRow(1)->query('xpath://ul[@class="table-forms"]')->asForm(['normalized' => true])->one();
		$data = [
			'SNMPv1' => ['SNMP version', 'SNMP community', 'Use bulk requests'],
			'SNMPv2' => ['SNMP version', 'SNMP community', 'Use bulk requests'],
			'SNMPv3' => ['SNMP version', 'Context name', 'Security name', 'Security level', 'Use bulk requests'],
			'authNoPriv' => ['SNMP version', 'Context name', 'Security name', 'Security level',
				'Authentication protocol', 'Authentication passphrase', 'Use bulk requests'
			]
		];
		// The SNMP interface has specific fields depending on the SNMP version and protocol.
		foreach ($data as $field => $labels) {
			$select = ($field === 'authNoPriv') ? 'Security level' : 'SNMP version';
			$form->fill([$select => $field]);
			$this->assertEquals($labels, array_values($snmp_form->getLabels()
					->filter(new CElementFilter(CElementFilter::VISIBLE))->asText()));
		}
	}

	public static function getCreateData() {
		return [
			// Host form without mandatory values.
			[
				[
					'expected' => TEST_BAD,
					'interfaces' => [
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						]
					],
					'error' => ['Field "groups" is mandatory.', 'Incorrect value for field "Host name": cannot be empty.',
						'Field "interfaces" is mandatory.'
					]
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'error' => ['Field "groups" is mandatory.', 'Incorrect value for field "Host name": cannot be empty.']
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Groups' => 'Zabbix servers'
					],
					'error' => 'Incorrect value for field "Host name": cannot be empty.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty host group'
					],
					'error' => 'Field "groups" is mandatory.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Host without interface',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						]
					],
					'error' => 'Field "interfaces" is mandatory.'
				]
			],
			// Existing host name and visible name.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Available host',
						'Groups' => 'Zabbix servers'
					],
					'error_title' => 'Cannot add host',
					'error' => 'Host with the same name "Available host" already exists.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty template',
						'Groups' => 'Zabbix servers'
					],
					'error_title' => 'Cannot add host',
					'error' => 'Template with the same name "Empty template" already exists.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Existen visible name',
						'Groups' => 'Zabbix servers',
						'Visible name' => 'ЗАББИКС Сервер'
					],
					'error_title' => 'Cannot add host',
					'error' => 'Host with the same visible name "ЗАББИКС Сервер" already exists.'
				]
			],
			// Host name field validation.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => '@#$%^&*()_+',
						'Groups' => 'Zabbix servers'
					],
					'error_title' => 'Cannot add host',
					'error' => 'Incorrect characters used for host name "@#$%^&*()_+".'
				]
			],
			// Interface fields validation.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty ip address',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => ''
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'IP and DNS cannot be empty for host interface.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty dns',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '',
							'Connect to' => 'DNS'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'IP and DNS cannot be empty for host interface.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty IP and filled in DNS',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '',
							'dns' => 'test'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Interface with DNS "test" cannot have empty IP address.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty dns and filled in IP',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'Connect to' => 'DNS'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Interface with IP "127.0.0.1" cannot have empty DNS name while having'.
						' "Use DNS" property on "Empty dns and filled in IP".'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty port',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => ''
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Port cannot be empty for host interface.'
				]
			],
			// IP validation.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid ip',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => 'test'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Invalid IP address "test".'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid ip',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '127.0.0.'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Invalid IP address "127.0.0.".'
				]
			],
			// Port validation.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid port',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => '100500'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Incorrect interface port "100500" provided.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid port',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => 'test'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Incorrect interface port "test" provided.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid port',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => '10.5'
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Incorrect interface port "10.5" provided.'
				]
			],
			// Empty SNMP community.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid snmp community',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'SNMP',
							'SNMP community' => ''
						]
					],
					'error_title' => 'Cannot add host',
					'error' => 'Incorrect arguments passed to function.'
				]
			],
			// Default values of Agent interface.
			[
				[
					'expected' => TEST_GOOD,
					'host_fields' => [
						'Host name' => 'Host with default agent interface',
						'Groups' => 'Zabbix servers'
					]
				]
			],
			// Default values of all interfaces.
			[
				[
					'expected' => TEST_GOOD,
					'host_fields' => [
						'Host name' => 'Host with default values of all interfaces',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'SNMP'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'JMX'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'IPMI'
						]
					]
				]
			],
			// Change default host interface.
			[
				[
					'expected' => TEST_GOOD,
					'default_values' => true,
					'host_fields' => [
						'Host name' => 'Host with default second agent interface',
						'Groups' => 'Zabbix servers'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'Agent',
							'ip' => '127.1.1.1',
							'port' => '111',
							'Default' => true
						]
					]
				]
			],
			// All interfaces and all fields in form.
			[
				[
					'expected' => TEST_GOOD,
					'host_fields' => [
						'Host name' => 'Host with all interfaces',
						'Visible name' => 'Host with all interfaces visible name',
						'Groups' => 'Zabbix servers',
						'Description' => 'Added description for host with all interfaces',
						'Monitored by proxy' => 'Active proxy 1',
						'Enabled' => false
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '::1',
							'dns' => '1211',
							'Connect to' => 'DNS',
							'port' => '100'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'SNMP',
							'ip' => '',
							'dns' => 'localhost',
							'Connect to' => 'DNS',
							'port' => '200',
							'SNMP version' => 'SNMPv3',
							'Context name' => 'aaa',
							'Security name' => 'bbb',
							'Security level' => 'authPriv',
							'Authentication protocol' => 'SHA',
							'Authentication passphrase' => 'ccc',
							'Privacy protocol' => 'AES',
							'Privacy passphrase' => 'ddd',
							'Use bulk requests' => false
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'SNMP',
							'ip' => '0:0:0:0:0:ffff:7c01:101',
							'dns' => 'test',
							'port' => '500',
							'SNMP version' => 'SNMPv1',
							'SNMP community' => 'test',
							'Use bulk requests' => true
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'JMX',
							'dns' => '1333',
							'Connect to' => 'DNS',
							'port' => '300'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'IPMI',
							'ip' => '127.2.2.2',
							'dns' => '1444',
							'port' => '400'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'IPMI',
							'ip' => '127.3.3.3',
							'dns' => '1444',
							'Connect to' => 'DNS',
							'port' => '500',
							'Default' => true
						]
					]
				]
			]
		];
	}

	/**
	 * @dataProvider getCreateData
	 */
	public function testFormHost_Create($data) {
		if ($data['expected'] === TEST_BAD) {
			$old_hash = CDBHelper::getHash($this->hosts_sql);
			$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);
		}

		$this->page->login()->open('hosts.php?form=create');
		$form = $this->query('id:hostsForm')->asForm()->one()->waitUntilVisible();
		$form->fill(CTestArrayHelper::get($data, 'host_fields', []));

		// Set name for field "Default".
		$names = ['1' => 'default'];
		$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names]);
		$interfaces = CTestArrayHelper::get($data, 'interfaces', []);
		$interfaces_form->fill($interfaces);
		$form->submit();

		switch ($data['expected']) {
			case TEST_GOOD:
				$this->assertMessage(TEST_GOOD, 'Host added');

				// Check host fields.
				$host = CTestArrayHelper::get($data, 'host_fields.Visible name', $data['host_fields']['Host name']);
				$this->query('link', $host)->waitUntilClickable()->one()->click();
				$this->page->waitUntilReady();
				$form->invalidate();
				$form->checkValue($data['host_fields']);

				// Preparing reference data for interfaces.
				$agent = true;
				// Mark whether the first default agent interface will be changed or removed.
				foreach ($interfaces as $interface) {
					if (in_array($interface['action'], [USER_ACTION_UPDATE, USER_ACTION_REMOVE])
							&& CTestArrayHelper::get($interface, 'index') === 0) {
						$agent = false;
						break;
					}
				}

				foreach ($interfaces as &$interface) {
					$interface['action'] = CTestArrayHelper::get($interface, 'action', USER_ACTION_ADD);

					// Add default values for interface, if it added without any values except action and type.
					if (count($interface) === 2 && $interface['action'] === USER_ACTION_ADD) {
						$interface = $this->default_values[$interface['type']];
					}

					unset($interface['index'], $interface['action'], $interface['type']);
				}
				unset($interface);

				$data['interfaces'] = $interfaces;

				// Add the default values for agent interface.
				if ($agent || empty($interfaces)) {
					array_unshift($data['interfaces'], $this->default_values['Agent']);
				}

				// Check host fields in DB.
				$this->assertDatabaseFields($data);

				// Check interfaces field values.
				$form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names])->checkValue($data['interfaces']);
				break;

			case TEST_BAD:
				$this->assertEquals($old_hash, CDBHelper::getHash($this->hosts_sql));
				$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));

				$error_title = CTestArrayHelper::get($data, 'error_title', 'Page received incorrect data');
				$this->assertMessage(TEST_BAD, $error_title, $data['error']);
				break;
		}
	}

	public static function getUpdateData() {
		return [
			// Host form validation
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => '',
						'Groups' => ''
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						]
					],
					'error' => ['Field "groups" is mandatory.', 'Incorrect value for field "Host name": cannot be empty.',
						'Field "interfaces" is mandatory.'
					]
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => '',
						'Groups' => ''
					],
					'error' => ['Field "groups" is mandatory.', 'Incorrect value for field "Host name": cannot be empty.']
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => ''
					],
					'error' => 'Incorrect value for field "Host name": cannot be empty.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty host group',
						'Groups' => ''
					],
					'error' => 'Field "groups" is mandatory.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'interfaces' => [
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						]
					],
					'error' => 'Field "interfaces" is mandatory.'
				]
			],
			// Existing host name and visible name.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Available host'
					],
					'error_title' => 'Cannot update host',
					'error' => 'Host with the same name "Available host" already exists.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty template'
					],
					'error_title' => 'Cannot update host',
					'error' => 'Template with the same name "Empty template" already exists.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Visible name' => 'ЗАББИКС Сервер'
					],
					'error_title' => 'Cannot update host',
					'error' => 'Host with the same visible name "ЗАББИКС Сервер" already exists.'
				]
			],
			// Host name field validation.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => '@#$%^&*()_+'
					],
					'error_title' => 'Cannot update host',
					'error' => 'Incorrect characters used for host name "@#$%^&*()_+".'
				]
			],
			// Interface fields validation.
			[
				[
					'expected' => TEST_BAD,
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => ''
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'IP and DNS cannot be empty for host interface.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty dns'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '',
							'Connect to' => 'DNS'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'IP and DNS cannot be empty for host interface.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty IP and filled in DNS'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '',
							'dns' => 'test'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Interface with DNS "test" cannot have empty IP address.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty dns and filled in IP'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'Connect to' => 'DNS'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Interface with IP "127.1.1.1" cannot have empty DNS name while having'.
						' "Use DNS" property on "Empty dns and filled in IP".'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Empty port'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => ''
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Port cannot be empty for host interface.'
				]
			],
			// IP validation.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid ip'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => 'test'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Invalid IP address "test".'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid ip'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '127.0.0.'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Invalid IP address "127.0.0.".'
				]
			],
			// Port validation.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid port'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => '100500'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Incorrect interface port "100500" provided.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid port'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => 'test'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Incorrect interface port "test" provided.'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid port'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'port' => '10.5'
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Incorrect interface port "10.5" provided.'
				]
			],
			// Empty SNMP community.
			[
				[
					'expected' => TEST_BAD,
					'host_fields' => [
						'Host name' => 'Invalid snmp community'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 1,
							'SNMP community' => ''
						]
					],
					'error_title' => 'Cannot update host',
					'error' => 'Incorrect arguments passed to function.'
				]
			],
			// Successful host form update.
			// Add defualt interface values.
			[
				[
					'expected' => TEST_GOOD,
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'Agent'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'SNMP'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'JMX'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'IPMI'
						]
					]
				]
			],
			// Set "Default" option to another interface.
			[
				[
					'expected' => TEST_GOOD,
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'Agent',
							'ip' => '',
							'dns' => 'agent',
							'Connect to' => 'DNS',
							'port' => '10054',
							'Default' => true
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'SNMP',
							'ip' => '',
							'dns' => 'snmp',
							'Connect to' => 'DNS',
							'port' => '166',
							'SNMP version' => 'SNMPv3',
							'Context name' => 'zabbix',
							'Security name' => 'selenium',
							'Security level' => 'authPriv',
							'Authentication protocol' => 'SHA',
							'Authentication passphrase' => 'test123',
							'Privacy protocol' => 'AES',
							'Privacy passphrase' => '456test',
							'Default' => true
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'IPMI',
							'ip' => '',
							'dns' => 'ipmi',
							'Connect to' => 'DNS',
							'port' => '500',
							'Default' => true
						]
					]
				]
			],
			// Remove all interfaces except JMX.
			[
				[
					'expected' => TEST_GOOD,
					'interfaces' => [
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 0
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 1
						]
					]
				]
			],
			// Update all fields.
			[
				[
					'expected' => TEST_GOOD,
					'host_fields' => [
						'Host name' => 'Update host with all interfaces',
						'Visible name' => 'Update host with all interfaces visible name',
						'Groups' => 'Linux servers',
						'Description' => 'Update description',
						'Monitored by proxy' => 'Active proxy 3',
						'Enabled' => false
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 0,
							'ip' => '',
							'dns' => 'zabbix.com',
							'Connect to' => 'DNS'
						],
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 1,
							'ip' => '',
							'dns' => 'zabbix.com',
							'port' => '122',
							'Connect to' => 'DNS',
							'SNMP version' => 'SNMPv3',
							'Context name' => 'new-zabbix',
							'Security name' => 'new-selenium',
							'Security level' => 'authNoPriv',
							'Authentication protocol' => 'SHA',
							'Authentication passphrase' => 'new-test123',
							'Use bulk requests' => true
						],
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 2,
							'ip' => '',
							'dns' => 'zabbix.com',
							'Connect to' => 'DNS'
						],
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 3,
							'ip' => '',
							'dns' => 'zabbix.com',
							'Connect to' => 'DNS'
						]
					]
				]
			],
			// Add two agent interfaces and remove it.
			[
				[
					'expected' => TEST_GOOD,
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'Agent'
						],
						[
							'action' => USER_ACTION_ADD,
							'type' => 'Agent'
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 1
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 1
						]
					]
				]
			],
			// Mixed actions Add, Remove, Update interfaces.
			[
				[
					'expected' => TEST_GOOD,
					'host_fields' => [
						'Host name' => 'Mixed interface actions',
						'Visible name' => '',
						'Groups' => 'Discovered hosts',
						'Description' => '',
						'Monitored by proxy' => '(no proxy)'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'Agent'
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 3
						],
						[
							'action' => USER_ACTION_UPDATE,
							'index' => 2,
							'port' => '501',
							'SNMP version' => 'SNMPv3',
							'Context name' => 'new-zabbix',
							'Security name' => 'new-selenium',
							'Security level' => 'noAuthNoPriv',
							'Use bulk requests' => true
						],
						[
							'action' => USER_ACTION_REMOVE,
							'index' => 3
						]
					]
				]
			]
		];
	}

	/**
	 * @backup hosts
	 *
	 * @dataProvider getUpdateData
	 */
	public function testFormHost_Update($data) {
		if ($data['expected'] === TEST_BAD) {
			$host_old_hash = CDBHelper::getHash($this->hosts_sql);
			$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);
		}

		$source = [
			'host_fields' => [
				'Host name' => 'testFormHost_Update',
				'Visible name' => 'testFormHost_Update Visible name',
				'Groups' => 'Zabbix servers',
				'Description' => 'Created host via API to test update functionality in host form and interfaces',
				'Monitored by proxy' => 'Active proxy 2',
				'Enabled' => true
			],
			'interfaces' => [
				'Agent' => [
					[
						'type' => 'Agent',
						'ip' => '127.1.1.1',
						'dns' => '',
						'Connect to' => 'IP',
						'port' => '10011'
					]
				],
				'SNMP' => [
					[
						'ip' => '127.2.2.2',
						'dns' => '',
						'Connect to' => 'IP',
						'port' => '122',
						'SNMP version' => 'SNMPv1',
						'SNMP community' => 'zabbix',
						'Use bulk requests' => false
					]
				],
				'JMX' => [
					[
						'type' => 'JMX',
						'ip' => '127.4.4.4',
						'dns' => '',
						'Connect to' => 'IP',
						'port' => '426'
					]
				],
				'IPMI' => [
					[
						'type' => 'JMX',
						'ip' => '',
						'dns' => 'selenium.test',
						'Connect to' => 'DNS',
						'port' => '30053'
					]
				]
			]
		];

		$this->page->login()->open('hosts.php?form=update&hostid='.self::$hostids['testFormHost_Update']);
		$form = $this->query('id:hostsForm')->asForm()->one()->waitUntilVisible();
		$form->fill(CTestArrayHelper::get($data, 'host_fields', []));

		// Set name for field "Default".
		$names = ['1' => 'default'];
		$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names]);
		$interfaces_form->fill(CTestArrayHelper::get($data, 'interfaces', []));
		$form->submit();

		switch ($data['expected']) {
			case TEST_GOOD:
				$this->assertMessage(TEST_GOOD, 'Host updated');

				if (CTestArrayHelper::get($data, 'host_fields.Visible name') === "") {
					$host = CTestArrayHelper::get($data, 'host_fields.Host name', 'testFormHost_Update');
				}
				else {
					$host = CTestArrayHelper::get($data, 'host_fields.Visible name', 'testFormHost_Update Visible name');
				}
				$this->query('link', $host)->waitUntilClickable()->one()->forceClick();
				$this->page->waitUntilReady();
				$form->invalidate();

				// Update or add new source data from host data.
				foreach (CTestArrayHelper::get($data, 'host_fields', []) as $key => $value) {
					$source['host_fields'][$key] = $value;
				}
				// Check host fields.
				$form->checkValue($source['host_fields']);

				// Preparing reference data for interfaces.
				foreach ($data['interfaces'] as $i => $interface) {
					$interface['action'] = CTestArrayHelper::get($interface, 'action', USER_ACTION_ADD);

					switch ($interface['action']) {
						case USER_ACTION_ADD:
							$type = CTestArrayHelper::get($interface, 'type', 'Agent');
							// Add default values for interface, if it added without any values, except action and type.
							if (count($interface) === 2) {
								$interface = $this->default_values[$interface['type']];
								$interface['type'] = $type;
							}

							$source['interfaces'][$type][] = $interface;
							break;

						case USER_ACTION_REMOVE:
							foreach (array_keys($source['interfaces']) as $type) {
								$count = count($source['interfaces'][$type]);
								if ($interface['index'] >= $count) {
									$interface['index'] -= $count;
								}
								else {
									unset($source['interfaces'][$type][$interface['index']]);
									// Reindex the keys to start from 0.
									$source['interfaces'][$type] = array_values($source['interfaces'][$type]);
									break;
								}
							}
							break;

						case USER_ACTION_UPDATE:
							foreach (array_keys($source['interfaces']) as $type) {
								$count = count($source['interfaces'][$type]);
								if ($interface['index'] >= $count) {
									$interface['index'] -= $count;
								}
								else {
									// Update or add new source interface fields from host data.
									foreach ($interface as $key => $value) {
										$source['interfaces'][$type][$interface['index']][$key] = $value;
									}

									if (CTestArrayHelper::get($interface, 'SNMP version', false) === 'SNMPv3') {
										// 'SNMP community' used only by SNMPv1 and SNMPv2 interfaces.
										unset($source['interfaces']['SNMP'][0]['SNMP community']);
									}
									break;
								}
							}
							break;
					}
				}

				// Remove interface type as array key in source data.
				$source['interfaces'] = array_merge($source['interfaces']['Agent'], $source['interfaces']['SNMP'],
						$source['interfaces']['JMX'], $source['interfaces']['IPMI']);

				// Remove unnecessary keys from source array to check the values on frontend.
				foreach ($source['interfaces'] as &$interface) {
					unset($interface['index'], $interface['action'], $interface['type']);
				}
				unset($interface);

				// Check host fields in DB.
				$this->assertDatabaseFields($source);

				// Check interfaces field values.
				$form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $names])->checkValue($source['interfaces']);
				break;

			case TEST_BAD:
				$this->assertEquals($host_old_hash, CDBHelper::getHash($this->hosts_sql));
				$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));

				$error_title = CTestArrayHelper::get($data, 'error_title', 'Page received incorrect data');
				$this->assertMessage(TEST_BAD, $error_title, $data['error']);
				break;
		}
	}

	/**
	 * Check host fields data with data in DB.
	 *
	 * @param array $data	data provider with fields values
	 */
	private function assertDatabaseFields($data) {
		$db_default = [
			'name' => $data['host_fields']['Host name'],
			'description' => '',
			'status' => 0
		];
		$db_host = CDBHelper::getRow('SELECT hostid, host, name, description, status FROM hosts WHERE host='.
				zbx_dbstr($data['host_fields']['Host name']));

		if (CTestArrayHelper::get($data, 'host_fields.Visible name') === "") {
			$data['host_fields']['Visible name'] = $data['host_fields']['Host name'];
		}
		$fields = ['Host name' => 'host', 'Visible name' => 'name', 'Description' => 'description', 'Enabled' => 'status'];
		foreach ($fields as $ui_field => $db_field) {
			if (array_key_exists($ui_field, $data['host_fields'])) {
				if ($ui_field === 'Enabled') {
					$data['host_fields'][$ui_field] = ($data['host_fields'][$ui_field] === false)
							? HOST_STATUS_NOT_MONITORED
							: HOST_STATUS_MONITORED;
				}
				$this->assertEquals($data['host_fields'][$ui_field], $db_host[$db_field]);
			}
			else {
				$this->assertEquals($db_default[$db_field], $db_host[$db_field]);
			}
		}

		// Check interfaces amount in DB.
		$db_interfaces = CDBHelper::getCount('SELECT NULL FROM interface WHERE hostid='.$db_host['hostid']);
		$this->assertEquals(count($data['interfaces']), $db_interfaces);
	}

	/**
	 * Update the host without any changes and check host and interfaces hashes.
	 */
	public function testFormHost_SimpleUpdate() {
		$host_old_hash = CDBHelper::getHash($this->hosts_sql);
		$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);

		$this->page->login()->open('hosts.php?form=update&hostid='.self::$hostids['testFormHost_Update']);
		$this->page->waitUntilReady();
		$this->query('button:Update')->waitUntilClickable()->one()->click();
		$this->assertMessage(TEST_GOOD, 'Host updated');

		$this->assertEquals($host_old_hash, CDBHelper::getHash($this->hosts_sql));
		$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));
	}

	public static function getCloneData() {
		return [
			[
				[
					'host_fields' => [
						'Host name' => microtime().' clone without interface changes'
					]
				]
			],
			[
				[
					'host_fields' => [
						'Host name' => microtime().' clone with interface changes'
					],
					'interfaces' => [
						[
							'action' => USER_ACTION_ADD,
							'type' => 'SNMP',
							'ip' => '127.1.1.1',
							'dns' => '',
							'Connect to' => 'IP',
							'port' => '122',
							'SNMP version' => 'SNMPv1',
							'SNMP community' => 'zabbix',
							'Use bulk requests' => false
						]
					]
				]
			]
		];
	}

	/**
	 * @dataProvider getCloneData
	 */
	public function testFormHost_Clone($data) {
		$this->cloneHost($data);

		// Check that items isn't cloned from original host.
		$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($data['host_fields']['Host name']));
		$this->assertEquals(0, CDBHelper::getCount('SELECT null FROM items WHERE hostid='.$hostid));
	}

	/**
	 * @dataProvider getCloneData
	 */
	public function testFormHost_FullClone($data) {
		$this->cloneHost($data, true);

		// Check that items cloned from original host.
		$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($data['host_fields']['Host name']));
		$this->assertEquals(3, CDBHelper::getCount('SELECT null FROM items WHERE hostid='.$hostid));
	}

	/**
	 * Clone or Full clone a host and compare the data with the original host.
	 *
	 * @param type $data		data provider with fields values
	 * @param type $full_clone	type of cloning
	 */
	private function cloneHost($data, $full_clone = false) {
		$name = 'testFormHost with items';
		$type = $full_clone ? 'Full clone' : 'Clone';
		$this->page->login()->open('hosts.php?form=update&hostid='.self::$hostids[$name]);

		$form = $this->query('id:hostsForm')->asForm()->one()->waitUntilVisible();
		$form->setFilter(new CElementFilter(CElementFilter::VISIBLE));
		// Get values from form.
		$form->fill(CTestArrayHelper::get($data, 'host_fields', []));
		$original = $form->getFields()->asValues();
		// Get values from interface fields.
		$container_names = ['1' => 'default'];
		$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $container_names]);
		$interfaces_form->fill(CTestArrayHelper::get($data, 'interfaces', []));
		$original_interfaces = $interfaces_form->getValue();

		// Clone host.
		$this->query('button', $type)->waitUntilClickable()->one()->click();
		$form->submit();
		$this->assertMessage(TEST_GOOD, 'Host added');

		// Check the values of the original host with the cloned host.
		$this->query('link', $data['host_fields']['Host name'])->waitUntilClickable()->one()->forceClick();
		$cloned_form = $form;
		$form->invalidate();
		$cloned_form->checkValue($original);
		$cloned_form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => $container_names])->checkValue($original_interfaces);
	}

	public static function getСancelData() {
		return [
			[
				[
					'action' => 'Add'
				]
			],
			[
				[
					'action' => 'Update'
				]
			],
			[
				[
					'action' => 'Clone'
				]
			],
			[
				[
					'action' => 'Full clone'
				]
			],
			[
				[
					'action' => 'Delete'
				]
			]
		];
	}

	/**
	 * @dataProvider getСancelData
	 */
	public function testFormHost_Cancel($data) {
		$host_old_hash = CDBHelper::getHash($this->hosts_sql);
		$interface_old_hash = CDBHelper::getHash($this->interface_snmp_sql);
		$name = 'testFormHost with items';
		$new_name = microtime(true).' Cancel '.$name;
		$interface = [
			[
				'action' => USER_ACTION_ADD,
				'type' => 'SNMP',
				'ip' => '0:0:0:0:0:ffff:7c01:101',
				'dns' => 'test',
				'port' => '500',
				'SNMP version' => 'SNMPv1',
				'SNMP community' => 'test',
				'Use bulk requests' => false
			]
		];

		if ($data['action'] === 'Add') {
			$this->page->login()->open('hosts.php?form=create');
		}
		else {
			$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($name));
			$this->page->login()->open('hosts.php?form=update&hostid='.$hostid);
		}

		// Change the host data to make sure that the changes are not saved to the database after cancellation.
		$form = $this->query('id:hostsForm')->asForm()->one()->waitUntilVisible();
		$form->fill(['Host name' => $new_name]);
		$interfaces_form = $form->getFieldContainer('Interfaces')->asHostInterfaceElement(['names' => ['1' => 'default']]);
		$interfaces_form->fill($interface);

		if (in_array($data['action'], ['Clone', 'Full clone', 'Delete'])) {
			$this->query('button', $data['action'])->one()->click();
		}
		if ($data['action'] === 'Delete') {
			$this->page->dismissAlert();
		}

		// Check that the host creation page is open after cloning or full cloning.
		if ($data['action'] === 'Clone' || $data['action'] === 'Full clone') {
			$this->assertEquals(PHPUNIT_URL.'hosts.php', $this->page->getCurrentUrl());
			$this->assertFalse($this->query('xpath:.//ul['.CXPathHelper::fromClass('filter-breadcrumb').']')->one(false)->isValid());
			$this->assertFalse($this->query('button', ['Update', 'Clone', 'Full clone', 'Delete'])->one(false)->isValid());
			$this->assertTrue($this->query('id', ['add', 'cancel'])->one(false)->isValid());
		}

		$this->page->waitUntilReady();
		$this->query('button:Cancel')->waitUntilClickable()->one()->click();

		// Check invariability of host data in the database.
		$this->assertEquals($host_old_hash, CDBHelper::getHash($this->hosts_sql));
		$this->assertEquals($interface_old_hash, CDBHelper::getHash($this->interface_snmp_sql));
		$this->assertEquals(0, CDBHelper::getCount('SELECT null FROM hosts WHERE host='.zbx_dbstr($new_name)));
	}

	public static function getDeleteData() {
		return [
			[
				[
					'expected' => TEST_GOOD,
					'name' => 'testFormHost with items'
				]
			],
			[
				[
					'expected' => TEST_BAD,
					'name' => 'Host for suppression',
					'error' => 'Cannot delete host because maintenance "Maintenance for suppression test" must contain at least one host or host group.'
				]
			]
		];
	}

	/**
	 * @dataProvider getDeleteData
	 */
	public function testFormHost_Delete($data) {
		$hostid = CDBHelper::getValue('SELECT hostid FROM hosts WHERE host='.zbx_dbstr($data['name']));
		if ($data['expected'] === TEST_BAD) {
			$old_hash = CDBHelper::getHash($this->hosts_sql);
		}
		else {
			// Get snmp interface ids.
			$interfaceids = CDBHelper::getAll('SELECT interfaceid FROM interface WHERE hostid='.$hostid.' AND type=2');
			$ids = array_column($interfaceids, 'interfaceid');
		}

		$this->page->login()->open('hosts.php?form=update&hostid='.$hostid);
		$this->query('button:Delete')->waitUntilClickable()->one()->click();
		$this->page->acceptAlert();

		switch ($data['expected']) {
			case TEST_GOOD:
				$this->assertMessage(TEST_GOOD, 'Host deleted');
				// Check if all host records have been deleted.
				$tables=['hosts', 'interface', 'items', 'applications', 'hostmacro', 'hosts_groups', 'hosts_templates',
					'maintenances_hosts', 'host_inventory'];
				foreach ($tables as $table) {
					$this->assertEquals(0, CDBHelper::getCount('SELECT null FROM '.$table.' WHERE hostid='.$hostid));
				}
				$this->assertEquals(0, CDBHelper::getCount('SELECT null FROM interface_snmp'.
						' WHERE interfaceid IN ('.CDBHelper::escape($ids).')'));
				break;

			case TEST_BAD:
				$this->assertEquals($old_hash, CDBHelper::getHash($this->hosts_sql));
				$this->assertMessage(TEST_BAD, 'Cannot delete host', $data['error']);
		}
	}
}