devel_wizard-2.x-dev/src/Plugin/DevelWizard/Spell/BlockContentTypeBehatSpell.php

src/Plugin/DevelWizard/Spell/BlockContentTypeBehatSpell.php
<?php

declare(strict_types=1);

namespace Drupal\devel_wizard\Plugin\DevelWizard\Spell;

use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\devel_wizard\Attribute\DevelWizardSpell;
use Symfony\Component\Filesystem\Path;

#[DevelWizardSpell(
  id: 'devel_wizard_block_content_type_behat',
  category: new TranslatableMarkup('Block type'),
  label: new TranslatableMarkup('Block type - Behat tests'),
  description: new TranslatableMarkup('Generates Behat tests for an existing Block type.'),
  tags: [
    'bundle' => new TranslatableMarkup('Bundle'),
    'config_entity' => new TranslatableMarkup('Config entity'),
    'block_content_type' => new TranslatableMarkup('Block type'),
    'quality_assurance' => new TranslatableMarkup('QA'),
    'behat' => new TranslatableMarkup('Behat'),
  ],
)]
class BlockContentTypeBehatSpell extends ConfigEntityBehatSpellBase {

  protected string $id = 'devel_wizard_block_content_type_behat';

  protected string $provider = 'block_content';

  protected string $contentEntityTypeId = 'block_content';

  protected string $configEntityTypeId = 'block_content_type';

  protected EntityTypeBundleInfoInterface $bundleInfo;

  /**
   * @throws \Drupal\Core\Entity\EntityMalformedException
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Twig\Error\LoaderError
   * @throws \Twig\Error\RuntimeError
   * @throws \Twig\Error\SyntaxError
   */
  protected function doItGenerateTests(): static {
    $configuration = $this->getConfiguration();
    $machineName = $configuration['machine_name'];

    $configStorage = $this->getConfigStorage();
    /** @var \Drupal\Core\Config\Entity\ConfigEntityInterface $bundle */
    $bundle = $configStorage->load($machineName);
    if (!$bundle) {
      throw new \InvalidArgumentException("{$this->configEntityTypeId}:$machineName not exists");
    }

    $args = [
      '@spell' => $this->getPluginDefinition()->id(),
      '@machine_name' => $machineName,
      '@bundle.url.canonical' => $bundle->toUrl()->toString(),
      '@bundle.label' => $bundle->label(),
    ];
    /* @noinspection HtmlUnknownTarget */
    $this->batchContext['sandbox']['messages'][] = [
      'type' => MessengerInterface::TYPE_STATUS,
      'message' => $this->t(
        '@spell - Create behat test for <a href="@bundle.url.canonical">@bundle.label</a>',
        $args,
      ),
    ];

    $tests = [
      'access' => [
        'create',
        'edit',
        'delete',
      ],
      'form' => [
        'create',
        'edit',
      ],
    ];

    foreach ($tests as $testType => $operations) {
      foreach ($operations as $operation) {
        $this->doItGenerateTest(
          $testType,
          $operation,
          $bundle->getEntityTypeId(),
          $machineName,
          $bundle->label(),
        );
      }
    }

    return $this;
  }

  /**
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Twig\Error\RuntimeError
   * @throws \Twig\Error\LoaderError
   * @throws \Twig\Error\SyntaxError
   */
  protected function doItGenerateTest(
    string $testType,
    string $operation,
    string $entityTypeId,
    string $bundleMachineName,
    string $bundleLabel,
  ): static {
    $conf = $this->getConfiguration();
    $filePath = Path::join(
      $conf['features_dir'],
      $bundleMachineName,
      "{$bundleMachineName}.{$this->contentEntityTypeId}.{$testType}.{$operation}.feature",
    );

    $templatePath = "@devel_wizard/behat/{$entityTypeId}/devel_wizard.behat_{$testType}_{$operation}.feature.twig";

    $values = [
      'machine_name' => $bundleMachineName,
      'label' => $bundleLabel,
      'roles' => $this->getRolesWithStatusCode($bundleMachineName),
    ];

    $rendered = $this->twig->render($templatePath, $values);

    $this->fs->mkdir(Path::getDirectory($filePath));
    $this->fs->dumpFile($filePath, $rendered);
    $this->messageFilesystemEntryCreate($filePath);

    return $this;
  }

  /**
   * Loads all roles in the system with status codes.
   *
   * Helper method to load all roles in the system with status codes
   * determining if the role has access to various operations, also provides
   * the number of spaces needed between TableNode keys.
   *
   * @param string $bundleMachineName
   *   The bundle machine-name we are creating the Behat tests for.
   *
   * @return array
   *   Returns an array with the roles and status codes.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function getRolesWithStatusCode(string $bundleMachineName): array {
    $roles = [];
    $userRoleStorage = $this
      ->entityTypeManager
      ->getStorage('user_role');
    $adminRoles = $userRoleStorage
      ->getQuery()
      ->condition('is_admin', TRUE)
      ->execute();
    $adminRoles[] = "{$this->configEntityTypeId}_{$bundleMachineName}_admin";

    $allRoles = $userRoleStorage->loadMultiple();
    $roleNames = array_keys($allRoles);
    $longestRoleLength = (int) max(array_map('strlen', $roleNames));
    foreach ($roleNames as $role) {
      // Determine how many spaces we need in each row of TableNode.
      $roles[$role]['spaces'] = $longestRoleLength - strlen($role) + 1;
      if (!in_array($role, $adminRoles)) {
        $roles[$role]['code'] = 403;
        continue;
      }
      $roles[$role]['code'] = 200;
    }
    // Sort the array by code.
    array_multisort(array_column($roles, 'code'), SORT_ASC, $roles);
    // Determine how many spaces we need in TableNode header after 'role'.
    $roles['headerSpaces'] = $longestRoleLength - 4 + 1;

    return $roles;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc