improvements-2.x-dev/tests/src/Traits/ImprovementsTestTrait.php
tests/src/Traits/ImprovementsTestTrait.php
<?php namespace Drupal\Tests\improvements\Traits; use Drupal\block\BlockInterface; use Drupal\block_content\BlockContentInterface; use Drupal\block_content\BlockContentTypeInterface; use Drupal\block_content\Entity\BlockContent; use Drupal\block_content\Entity\BlockContentType; use Drupal\comment\CommentInterface; use Drupal\comment\Entity\Comment; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Url; use Drupal\field\Entity\FieldConfig; use Drupal\field\Entity\FieldStorageConfig; use Drupal\file\Entity\File; use Drupal\file\FileInterface; use Drupal\filter\Entity\FilterFormat; use Drupal\filter\FilterFormatInterface; use Drupal\menu_link_content\Entity\MenuLinkContent; use Drupal\menu_link_content\MenuLinkContentInterface; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; use Drupal\node\NodeStorageInterface; use Drupal\system\Entity\Menu; use Drupal\system\MenuInterface; use Drupal\Tests\block\Traits\BlockCreationTrait; use Drupal\Tests\RandomGeneratorTrait; use Drupal\Tests\UiHelperTrait; use Drupal\views\Entity\View; use Drupal\views\ViewEntityInterface; use Drupal\views\ViewExecutable; use Drupal\views\Views; trait ImprovementsTestTrait { use BlockCreationTrait; use RandomGeneratorTrait; use UiHelperTrait; /** * Install module. */ public function installModule(...$modules): void { $this->container->get('module_installer')->install($modules); } /** * Run all private tests. */ public function runAllPrivateTests(): void { foreach (get_class_methods(self::class) as $class_method) { if (str_starts_with($class_method, '_test')) { $result = $this->{$class_method}(); if ($result === FALSE) { break; } } } } /** * Create content block. */ public function createBlockContent(array $values = []): BlockContentInterface { $block_content = BlockContent::create($values + [ 'info' => $this->randomString(), 'type' => 'basic', 'body' => [ 'value' => $this->randomString(), 'format' => 'plain_text', ], ]); $block_content->save(); return $block_content; } /** * Place content block. */ public function placeBlockContent(BlockContentInterface $block_content, array $settings = []): BlockInterface { return $this->placeBlock('block_content:' . $block_content->uuid(), $settings); } /** * Create field. */ public function createField( string $entity_type, string $entity_bundle, string $field_name, string $field_type, string $field_label, array $storage_settings = [], array $instance_settings = [], string $widget_type = NULL, array $widget_options = [], string $formatter_type = NULL, array $formatter_options = [], ): void { $entity_display_repository = $this->container->get('entity_display.repository'); /** @var EntityDisplayRepositoryInterface $entity_display_repository */ // Create field storage $field_storage = FieldStorageConfig::create([ 'field_name' => $field_name, 'entity_type' => $entity_type, 'type' => $field_type, ] + $storage_settings); $field_storage->save(); // Create field instance $field_instance = FieldConfig::create([ 'field_storage' => $field_storage, 'bundle' => $entity_bundle, 'label' => $field_label, ] + $instance_settings); $field_instance->save(); // Set widget if ($widget_type || $widget_options) { if ($widget_type) { $widget_options['type'] = $widget_type; } $entity_form_display = $entity_display_repository->getFormDisplay($entity_type, $entity_bundle); $entity_form_display->setComponent($field_storage->getName(), $widget_options)->save(); } // Set formatter if ($formatter_type || $formatter_options) { if ($formatter_type) { $formatter_options['type'] = $formatter_type; } $entity_view_display = $entity_display_repository->getViewDisplay($entity_type, $entity_bundle); $entity_view_display->setComponent($field_storage->getName(), $formatter_options)->save(); } } /** * Delete field. */ public function deleteField(string $field_name, string $entity_type = 'node'): void { FieldStorageConfig::loadByName($entity_type, $field_name)->delete(); } /** * Creates a custom block type (bundle). */ public function createBlockContentType(string $id = 'basic', string $label = 'Basic', $create_body = TRUE): BlockContentTypeInterface { $block_content_type = BlockContentType::create([ 'id' => $id, 'label' => $label, 'revision' => FALSE, ]); $block_content_type->save(); if ($create_body) { block_content_add_body_field($block_content_type->id()); } return $block_content_type; } /** * Create filter format. */ public function createFilterFormat(array $values = []): FilterFormatInterface { $filter_format_random_name = $this->randomMachineName(); $filter_format = FilterFormat::create($values + [ 'format' => $filter_format_random_name, 'name' => $filter_format_random_name, 'weight' => 0, 'filters' => [], ]); $filter_format->save(); return $filter_format; } /** * Create comment. */ public function createComment(EntityInterface $commented_entity, string $field_name = 'comment', array $values = []): CommentInterface { $values += [ 'entity_type' => $commented_entity->getEntityTypeId(), 'entity_id' => $commented_entity->id(), 'field_name' => $field_name, 'uid' => $this->rootUser->id(), 'status' => CommentInterface::PUBLISHED, 'body' => 'Test comment body', ]; $comment = Comment::create($values); $comment->save(); return $comment; } /** * Create File entity. */ public function createFileEntity(array $values): FileInterface { $file = File::create($values); $file->save(); return $file; } /** * Create View entity. */ public function createView(array $values): ViewEntityInterface { $view = View::create($values + [ 'id' => 'test_view', 'label' => 'Test view', 'base_table' => 'node_field_data', ]); $view->save(); return $view; } /** * Create menu. */ public function createMenu($id, $label): MenuInterface { $menu = Menu::create([ 'id' => $id, 'label' => $label, ]); $menu->save(); return $menu; } /** * Create menu link for node. */ public function createMenuLinkForEntity(EntityInterface $entity, string $menu_name, $values = []): MenuLinkContentInterface { $menu_link = MenuLinkContent::create([ 'title' => $entity->label(), 'menu_name' => $menu_name, 'link' => 'internal:' . $entity->toUrl()->toString(), ] + $values); $menu_link->save(); return $menu_link; } /** * Login as root */ public function drupalLoginAsRoot(): void { if (!$this->drupalUserIsLoggedIn($this->rootUser)) { $this->drupalLogin($this->rootUser); } } /** * Set field widget settings. */ public function setFieldWidgetSettings(string $entity_type, string $entity_bundle, string $field_name, array $settings, bool $merge_settings = TRUE): void { $entity_display_repository = $this->container->get('entity_display.repository'); /** @var EntityDisplayRepositoryInterface $entity_display_repository */ $form_display = $entity_display_repository->getFormDisplay($entity_type, $entity_bundle); if ($merge_settings) { $current_widget_settings = $form_display->getComponent($field_name) ?: []; $settings = NestedArray::mergeDeep($current_widget_settings, $settings); } $form_display->setComponent($field_name, $settings)->save(); } /** * Set field formatter settings. */ public function setFieldFormatterSettings(string $entity_type, string $entity_bundle, string $field_name, array $settings, bool $merge_settings = TRUE): void { $entity_display_repository = $this->container->get('entity_display.repository'); /** @var EntityDisplayRepositoryInterface $entity_display_repository */ $view_display = $entity_display_repository->getViewDisplay($entity_type, $entity_bundle); if ($merge_settings) { $current_formatter_settings = $view_display->getComponent($field_name) ?: []; $settings = NestedArray::mergeDeep($current_formatter_settings, $settings); } $view_display->setComponent($field_name, $settings)->save(); } /** * Get entity page. */ public function drupalGetEntityPage(EntityInterface $entity, string $rel = 'canonical', array $options = [], array $headers = []): string { return $this->drupalGet($entity->toUrl($rel), $options, $headers); } /** * Get front page. */ public function drupalGetFrontPage(): string { return $this->drupalGet(Url::fromRoute('<front>')); } /** * Execute View and return query. */ public function getViewQuery(string $view_name, string $display_name = 'default', array $arguments = []): SelectInterface { $view_executable = $this->getExecutedView($view_name, $display_name, $arguments); return $view_executable->build_info['query']; } /** * Return executed View. */ public function getExecutedView(string $view_name, string $display_name = 'default', array $arguments = [], $pre_execute_callback = NULL): ViewExecutable { $view_executable = Views::getView($view_name); $view_executable->setDisplay($display_name); $view_executable->setArguments($arguments); if ($pre_execute_callback) { $pre_execute_callback($view_executable); } $view_executable->preExecute(); $view_executable->execute(); return $view_executable; } /** * Check page for errors. */ public function dontSeeErrorMessage($check_status_code = TRUE, $check_drupal_markup = TRUE, $check_error_message = TRUE): void { if ($check_status_code) { $this->assertSession()->statusCodeEquals(200); } if ($check_drupal_markup && !$this->cssSelect('div[data-drupal-messages-fallback]')) { throw new \Exception('Page not contain Drupal markup: "' . $this->getPageContent() . '"'); } if ($check_error_message && $error_message = $this->cssSelect('.messages--error')) { throw new \Exception('I see error message — ' . $error_message[0]->getText()); } } /** * Delete entities. */ public function deleteEntities(...$entities): void { foreach ($entities as $entity) { $entity->delete(); } } /** * Delete nodes by type. */ public function deleteNodesByType(string $node_type): void { $node_storage = $this->container->get('entity_type.manager')->getStorage('node'); /** @var NodeStorageInterface $node_storage */ $nodes = $node_storage->loadByProperties(['type' => $node_type]); $node_storage->delete($nodes); } /** * Return last added node id. */ public function getLastAddedNodeId(string $node_type = NULL): int { $query = \Drupal::database()->select('node'); $query->addExpression('MAX(nid)', 'nid'); if ($node_type) { $query->condition('type', $node_type); } return (int)$query->execute()->fetchField(); } /** * Return last added node. */ public function getLastAddedNode(string $node_type = NULL): ?NodeInterface { if ($last_added_node_id = $this->getLastAddedNodeId($node_type)) { /** @noinspection All */ return Node::load($last_added_node_id); } return NULL; } /** * Count render cache. */ public function countRenderCache($cid): int { return (int)\Drupal::database() ->select('cache_render') ->condition('cid', $cid . '%', 'LIKE') ->countQuery() ->execute() ->fetchField(); } /** * Clear render cache. */ public function clearRenderCache(): void { \Drupal::database()->truncate('cache_render')->execute(); } /** * Reset storage caches. */ public function resetStorageCaches(): void { $entity_type_manager = \Drupal::entityTypeManager(); foreach (array_keys($entity_type_manager->getDefinitions()) as $entity_type_id) { $entity_type_manager->getStorage($entity_type_id)->resetCache(); } } /** * Save content. */ public function saveData($data, string $filename = 'saved-data.txt'): void { if (is_array($data)) { $data = print_r($data, TRUE); } file_put_contents('sites/simpletest/' . $filename, (string)$data); } /** * Return page content. */ public function getPageContent(): string { return $this->getSession()->getPage()->getContent(); } /** * Save page content. */ public function savePageContent($path = NULL): void { if ($path) { $this->drupalGet($path); } $this->saveData($this->getPageContent(), 'browser-output.html'); } /** * Open field widget/formatter settings. */ public function openEntityDisplayComponentSettings(string $field_name): void { $this->submitForm([], $field_name . '_settings_edit'); $this->dontSeeErrorMessage(); } }