Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
UiPatternsFunctionalTestBase.php 3.40 KiB
<?php

declare(strict_types=1);

namespace Drupal\Tests\ui_patterns\Functional;

use Drupal\Component\Serialization\Yaml;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\ui_patterns\Traits\TestContentCreationTrait;
use Drupal\Tests\ui_patterns\Traits\TestDataTrait;

/**
 * Base function testing.
 *
 * @group ui_patterns
 */
abstract class UiPatternsFunctionalTestBase extends BrowserTestBase {

  use TestContentCreationTrait;
  use TestDataTrait;

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'ui_patterns_test_theme';

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'node',
    'ui_patterns',
    'ui_patterns_layouts',
    'field_ui',
  ];

  /**
   * Config is initialized.
   */
  private bool $configInitialize = FALSE;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $user = $this->drupalCreateUser([
      'configure any layout',
      'administer node display',
    ], NULL, TRUE);
    if ($user) {
      $this->drupalLogin($user);
    }
  }

  /**
   * Initialize config.
   */
  private function initializeConfig() {
    if ($this->configInitialize === FALSE) {
      $this->copyConfig(\Drupal::service('config.storage'), \Drupal::service('config.storage.sync'));
    }
    $this->configInitialize = TRUE;
  }

  /**
   * Load a configure fixture.
   *
   * @param string $path
   *   The path to the fixture.
   *
   * @return array
   *   The fixture.
   */
  public function loadConfigFixture(string $path):array {
    $yaml = file_get_contents($path);
    if ($yaml === FALSE) {
      throw new \InvalidArgumentException($path . ' not found.');
    }
    return Yaml::decode($yaml);
  }

  /**
   * Import config fixture.
   *
   * @param string $config_id
   *   The config id.
   * @param array $config
   *   The config fixture.
   */
  public function importConfigFixture(string $config_id, array $config) {
    $this->initializeConfig();
    \Drupal::service('config.storage.sync')->write($config_id, $config);
    $config_importer = $this->configImporter();
    $config_importer->import();
  }

  /**
   * Build UI Patterns compatible configuration for given test_set.
   *
   * @param array $test_set
   *   The test_set to build the configuration from.
   *
   * @return array
   *   The builded configuration.
   */
  protected function buildUiPatternsConfig(array $test_set):array {
    if (!isset($test_set['component']['slots'])) {
      $test_set['component']['slots'] = [];
    }
    return $test_set['component'];
  }

  /**
   * Validates rendered component.
   *
   * @param array $test_set
   *   The test set to validate against.
   *
   * @throws \Behat\Mink\Exception\ElementNotFoundException
   */
  protected function validateRenderedComponent($test_set) {
    $output = $test_set['output'] ?? [];
    foreach ($output as $prop_or_slot => $prop_or_slot_item) {
      foreach ($prop_or_slot_item as $prop_name => $output) {
        $type = $prop_or_slot;
        $assert_session = $this->assertSession();
        $selector = '#ui-patterns-' . $type . '-' . $prop_name;
        $element = $assert_session->elementExists('css', $selector);
        $prop_value = $element->getText();
        $message = sprintf("Test '%s' failed for prop/slot '%s' of component %s. Selector %s", $test_set["name"] ?? "", $prop_or_slot, $test_set['component']['component_id'], $selector);
        $this->assertExpectedOutput($output, $prop_value, $message);
      }
    }

  }

}