View source
<?php
namespace Drupal\Tests\double_field\Functional;
use Behat\Mink\Element\NodeElement;
use Drupal\Component\Utility\NestedArray;
use Drupal\Tests\BrowserTestBase;
use Drupal\double_field\Plugin\Field\FieldFormatter\Base as BaseFormatter;
use Drupal\double_field\Plugin\Field\FieldWidget\DoubleField;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\node\Entity\Node;
abstract class TestBase extends BrowserTestBase {
protected $defaultTheme = 'stark';
protected $fieldName;
protected $contentTypeId;
protected $fieldAdminPath;
protected $fieldStorageAdminPath;
protected $fieldStorage;
protected $field;
protected static $modules = [
'double_field',
'node',
'field_ui',
];
protected function setUp() : void {
parent::setUp();
$this->fieldName = strtolower($this
->randomMachineName());
$this->contentTypeId = $this
->drupalCreateContentType([
'type' => $this
->randomMachineName(),
])
->id();
$this->fieldAdminPath = "admin/structure/types/manage/{$this->contentTypeId}/fields/node.{$this->contentTypeId}.{$this->fieldName}";
$this->fieldStorageAdminPath = $this->fieldAdminPath . '/storage';
$permissions = [
'administer content types',
'administer node fields',
'administer nodes',
'administer node form display',
'administer node display',
"edit any {$this->contentTypeId} content",
"delete any {$this->contentTypeId} content",
];
$admin_user = $this
->drupalCreateUser($permissions, NULL, NULL, [
'timezone' => 'Europe/Moscow',
]);
$this
->drupalLogin($admin_user);
$storage_settings['storage'] = [
'first' => [
'type' => 'string',
'maxlength' => 50,
'precision' => 10,
'scale' => 2,
'datetime_type' => 'datetime',
],
'second' => [
'type' => 'string',
'maxlength' => 50,
'precision' => 10,
'scale' => 2,
'datetime_type' => 'datetime',
],
];
$this->fieldStorage = FieldStorageConfig::create([
'field_name' => $this->fieldName,
'entity_type' => 'node',
'type' => 'double_field',
'settings' => $storage_settings,
]);
$this->fieldStorage
->save();
$this->field = FieldConfig::create([
'field_storage' => $this->fieldStorage,
'bundle' => $this->contentTypeId,
'required' => TRUE,
]);
$this->field
->save();
$this
->saveWidgetSettings([]);
$this
->saveFormatterSettings('unformatted_list');
}
protected function saveFieldSettings(array $settings) : void {
$persisted_settings = $this->field
->getSettings();
foreach ([
'first',
'second',
] as $subfield) {
if (isset($persisted_settings[$subfield]['allowed_values'], $settings[$subfield]['allowed_values'])) {
unset($persisted_settings[$subfield]['allowed_values']);
}
}
$this->field
->setSettings(NestedArray::mergeDeep($persisted_settings, $settings));
$this->field
->save();
}
protected function saveFieldStorageSettings(array $settings) : void {
$this->fieldStorage
->setSettings(NestedArray::mergeDeep($this->fieldStorage
->getSettings(), $settings));
$this->fieldStorage
->save();
}
protected function saveWidgetSettings(array $settings) : void {
$form_display = \Drupal::entityTypeManager()
->getStorage('entity_form_display')
->load('node.' . $this->contentTypeId . '.default');
$options = [
'type' => 'double_field',
'weight' => 100,
'settings' => NestedArray::mergeDeep(DoubleField::defaultSettings(), $settings),
'third_party_settings' => [],
];
$form_display
->setComponent($this->fieldName, $options);
$form_display
->save();
}
protected function saveFormatterSettings(string $formatter, array $settings = []) : void {
$view_display = \Drupal::entityTypeManager()
->getStorage('entity_view_display')
->load("node.{$this->contentTypeId}.default");
$options = [
'label' => 'hidden',
'type' => 'double_field_' . $formatter,
'weight' => 100,
'settings' => NestedArray::mergeDeep(BaseFormatter::defaultSettings(), $settings),
'third_party_settings' => [],
];
$view_display
->setComponent($this->fieldName, $options);
$view_display
->save();
}
protected function assertXpath($xpath) : void {
if (is_array($xpath)) {
$xpath = implode($xpath);
}
$this
->assertSession()
->elementExists('xpath', $xpath);
}
protected function assertNoXpath($xpath) : void {
if (is_array($xpath)) {
$xpath = implode($xpath);
}
$this
->assertSession()
->elementNotExists('xpath', $xpath);
}
protected function getMessages(string $type) : array {
$messages = [];
$get_message = function (NodeElement $element) : string {
$message = preg_replace('#<h2[^>]*>.*</h2>#', '', $element
->getHtml());
$message = strip_tags($message, '<em>');
return trim(preg_replace('#\\s+#', ' ', $message));
};
$xpath = sprintf('//div[@aria-label = "%s message"]', ucfirst($type));
if ($type == 'error') {
$xpath .= '/div[@role = "alert"]';
}
$wrapper = $this
->xpath($xpath);
if (!empty($wrapper[0])) {
unset($wrapper[0]->h2);
$items = $wrapper[0]
->findAll('xpath', '/ul/li');
if ($items) {
foreach ($items as $item) {
$messages[] = $get_message($item);
}
}
else {
$messages[] = $get_message($wrapper[0]);
}
}
return $messages;
}
protected function assertStatusMessage(string $message) : void {
$messages = $this
->getMessages('status');
self::assertTrue(in_array($message, $messages), 'Status message was found.');
}
protected function assertWarningMessage(string $message) : void {
$messages = $this
->getMessages('warning');
self::assertTrue(in_array($message, $messages), 'Warning message was found.');
}
protected function assertErrorMessage(string $message) : void {
$messages = $this
->getMessages('error');
self::assertTrue(in_array($message, $messages), 'Error message was found.');
}
protected function assertViolations(array $values, array $expected_messages) : void {
$node = Node::create([
'type' => $this->contentTypeId,
]);
$node->{$this->fieldName} = [
'first' => $values[0],
'second' => $values[1],
];
$violations = $node->{$this->fieldName}
->validate();
foreach ($violations as $index => $violation) {
$message = strip_tags($violations[$index]
->getMessage());
$key = array_search($message, $expected_messages);
self::assertNotFalse($key, sprintf('Found violation: "%s".', $message));
}
self::assertEquals(count($violations), count($expected_messages));
}
protected function assertNoViolations(array $values) : void {
$this
->assertViolations($values, []);
}
}