translators-8.x-1.x-dev/modules/translators_content/tests/src/Functional/TranslatorsContentPermissionTestBase.php

modules/translators_content/tests/src/Functional/TranslatorsContentPermissionTestBase.php
<?php

namespace Drupal\Tests\translators_content\Functional;

use Drupal\Tests\BrowserTestBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Language\Language;
use Drupal\user\UserInterface;

/**
 * Class TranslatorsContentPermissionTestBase.
 *
 * @package Drupal\Tests\translators_content\Functional
 *
 * @group translators_content
 */
abstract class TranslatorsContentPermissionTestBase extends BrowserTestBase {
  use TranslatorsContentTestsTrait;

  /**
   * {@inheritdoc}
   */
  protected $profile = 'standard';

  /**
   * The default theme.
   *
   * @var string
   */
  protected $defaultTheme = 'claro';

  /**
   * The administration theme.
   *
   * @var string
   */
  protected $adminTheme = 'claro';

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['translators_content'];
  /**
   * The entity type id.
   *
   * @var string
   */
  protected $entityTypeId;
  /**
   * The entity type bundle id.
   *
   * @var string
   */
  protected $bundle;
  /**
   * If entity permission is supported or not.
   *
   * @var bool
   */
  protected $entityPermissionSupport;
  /**
   * An associative array with expected status as value.
   *
   * @var array
   */
  protected $expectedStatus;

  /**
   * {@inheritdoc}
   */
  public function setUp(): void {
    parent::setUp();
    $this->drupalLogin($this->rootUser);
    $theme_installer = $this->container->get('theme_installer');
    $theme_installer->install([$this->defaultTheme, $this->adminTheme]);
    $this->config('system.theme')
      ->set('default', $this->defaultTheme)
      ->set('admin', $this->adminTheme)
      ->save();
  
    $this->enableFilterTranslationOverviewToSkills(FALSE);
    $this->createLanguages(['fr', 'de', 'sq', 'nb']);
    $this->enableTranslation($this->entityTypeId, $this->bundle);
    $this->drupalLogout();
  }

  /**
   * Create test entity.
   *
   * @param null|string $langcode
   *   Optional. Default language ID.
   * @param null|int $uid
   *   Optional. Author ID.
   *
   * @return \Drupal\Core\Entity\EntityInterface
   *   Created enitity object.
   */
  abstract public function createTestEntity($langcode = NULL, int $uid = NULL);

  /**
   * Get create entity translation form url.
   *
   * @param null|string $langcode
   *   Optional. Language ID.
   *
   * @return string
   *   URL string.
   */
  abstract public function getCreateEntityUrl($langcode = NULL);

  /**
   * Add a translation to an entity.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be translated.
   * @param null|string $target
   *   Optional. Target language ID.
   * @param null|string $source
   *   Optional. Source language ID.
   */
  abstract public function addEntityTranslation(EntityInterface $entity, $target, $source = NULL);

  /**
   * Test that content_translation translation permissions are visable.
   */
  public function testTranslatonPermissionsVisability() {
    $this->drupalLogin($this->rootUser);
    $this->drupalGet('admin/people/permissions');
    $this->assertSession()->statusCodeEquals(200);
    $permissions_prefix = '(in translation skills)';

    // Check for Content Translators permissions section.
    $this->assertSession()->responseContains('Content Translators');

    // Check for "static" permissions existence.
    $this->assertSession()->responseContains("Create translations $permissions_prefix");
    $this->assertSession()->responseContains("Edit translations $permissions_prefix");
    $this->assertSession()->responseContains("Delete translations $permissions_prefix");

  }

  /**
   * Test that content_translation entity permissions are visable.
   */
  public function runTestEntityPermissionsVisability() {
    $this->drupalLogin($this->rootUser);
    $this->drupalGet('admin/people/permissions');
    $this->assertSession()->statusCodeEquals(200);
    $permissions_prefix = '(in translation skills)';

    // Check for "content" permissions existence.
    $entity = $this->createTestEntity();
    $entity_label = strtolower($entity->getEntityType()->getLabel());
    $entityTypeId = $entity->getEntityTypeId();
    $bundle_info = $this->container->get('entity_type.bundle.info');
    $entity_bundle_info = $bundle_info->getBundleInfo($entityTypeId);
    $bundle_label = '';
    foreach ($entity_bundle_info as $bundle => $bundle_info) {
      $bundle_label = !empty($bundle_info['label']) ? $bundle_info['label'] : $bundle;
    }
    $this->assertSession()->responseContains("<em class=\"placeholder\">$bundle_label</em>: Create new $entity_label $permissions_prefix");
    $this->assertSession()->responseContains("<em class=\"placeholder\">$bundle_label</em>: Edit $entity_label $permissions_prefix");
    $this->assertSession()->responseContains("<em class=\"placeholder\">$bundle_label</em>: Delete $entity_label $permissions_prefix");

  }

  /**
   * User has no permissions for translation except 'translate any entity'.
   */
  public function testNonePermissions() {
    $bundle = $this->bundle;
    $user = $this->createUser(['translate any entity']);
    $this->expectedStatus = $this->getDefaultExpectedStatus(403);
    $this->runTests($user);
  }

  /**
   * Test create translation in any language permissions.
   */
  public function testCreateTranslationAnyLanguage() {
    $bundle = $this->bundle;
    $user = $this->createUser([
      'create content translations',
      'translate any entity',
    ]);
    $default_status = $this->getDefaultExpectedStatus(403);
    $expectedStatus = [
      'create translation in any language' => 200,
      'create translation in translation skills' => 200,
      'access translation overview' => 200,
    ];
    $this->expectedStatus = array_merge($default_status, $expectedStatus);
    $this->runTests($user);
  }

  /**
   * Test create translation in translation skills permissions.
   */
  public function testCreateTranslationInTranslationSkills() {
    $bundle = $this->bundle;
    $user = $this->createUser([
      'translators_content create content translations',
      'translate any entity',
    ]);
    $default_status = $this->getDefaultExpectedStatus(403);
    $expectedStatus = [
      'create translation in translation skills' => 200,
      'access translation overview' => 200,
    ];
    $this->expectedStatus = array_merge($default_status, $expectedStatus);
    $this->runTests($user);
  }

  /**
   * Test edit translation in any language permissions.
   */
  public function testEditTranslationAnyLanguage() {
    $bundle = $this->bundle;
    $user = $this->createUser([
      'update content translations',
      'translate any entity',
    ]);
    $default_status = $this->getDefaultExpectedStatus(403);
    $expectedStatus = [
      'edit translation in any language' => 200,
      'edit translation in translation skills' => 200,
      'access translation overview' => 200,
    ];
    $this->expectedStatus = array_merge($default_status, $expectedStatus);
    $this->runTests($user);
  }

  /**
   * Test edit translation in translation skills permissions.
   */
  public function testEditTranslationInTranslationSkills() {
    $bundle = $this->bundle;
    $user = $this->createUser([
      'translators_content update content translations',
      'translate any entity',
    ]);
    $default_status = $this->getDefaultExpectedStatus(403);
    $expectedStatus = [
      'edit translation in translation skills' => 200,
      'access translation overview' => 200,
    ];
    $this->expectedStatus = array_merge($default_status, $expectedStatus);
    $this->runTests($user);
  }

  /**
   * Test delete translation in any language permissions.
   */
  public function testDeleteAnyTranslationAnyLanguage() {
    $bundle = $this->bundle;
    $user = $this->createUser([
      'delete content translations',
      'translate any entity',
    ]);
    $default_status = $this->getDefaultExpectedStatus(403);
    $expectedStatus = [
      'delete translation in any language' => 200,
      'delete translation in translation skills' => 200,
      'access translation overview' => 200,
    ];
    $this->expectedStatus = array_merge($default_status, $expectedStatus);
    $this->runTests($user);
  }

  /**
   * Test delete translation in translation skills permissions.
   */
  public function testDeleteTranslationInTranslationSkills() {
    $bundle = $this->bundle;
    $user = $this->createUser([
      'translators_content delete content translations',
      'translate any entity',
    ]);
    $default_status = $this->getDefaultExpectedStatus(403);
    $expectedStatus = [
      'delete translation in translation skills' => 200,
      'access translation overview' => 200,
    ];
    $this->expectedStatus = array_merge($default_status, $expectedStatus);
    $this->runTests($user);
  }

  /**
   * Test case for admin.
   */
  public function testAdminPermissions() {
    $user = $this->createUser([]);
    $user->addRole('administrator');
    $user->save();
    $this->expectedStatus = $this->getDefaultExpectedStatus(200);
    $this->runTests($user);
  }

  /**
   * Checks that workflows have the expected behaviors for the given user.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user to test the workflow behavior against.
   */
  protected function runTests(UserInterface $user) {
    // @todo: Make tests run with several translation skills
    // @todo: Test more entity types: Users, Media, Files, Comments, Blocks.
    // @todo: Test translate bundle vs any permissions
    $this->drupalLogin($user);
    $this->addSkill(['fr', 'de']);

    // Create, edit and delete entities.
    if ($this->entityPermissionSupport) {
      $this->runTestCreateEntity();
      $this->runTestEntityOperations('edit');
      $this->runTestEntityOperations('delete');
    }

    // Create translations.
    $this->runTestCreateTranslation();
    // With strict translation skill pairing:
    $this->drupalLogout();
    $this->drupalLogin($this->rootUser);
    $this->enableStrictTranslationSkillsPairing(TRUE);
    $this->drupalLogout();
    $this->drupalLogin($user);
    $this->runTestCreateTranslation();

    // Edit and delete translations.
    $this->drupalLogout();
    $this->drupalLogin($this->rootUser);
    $entity = $this->createTestEntity();
    $this->assertTrue($entity instanceof EntityInterface);
    $this->addAllEntityTranslations($entity);
    $entity = $entity->load($entity->id());
    $this->drupalLogout();
    $this->drupalLogin($user);
    $this->runTestTranslationOperations($entity, 'edit');
    $this->runTestTranslationOperations($entity, 'delete');

    // Translation overview.
    // No filtering + always display original language:
    $this->runTestAccessTranslationOverview($entity);
    // With filtering:
    $this->drupalLogout();
    $this->drupalLogin($this->rootUser);
    $this->enableFilterTranslationOverviewToSkills(TRUE);
    $this->drupalLogout();
    $this->drupalLogin($user);
    $this->runTestAccessTranslationOverview($entity);
    // Don't always display original language:
    $this->drupalLogout();
    $this->drupalLogin($this->rootUser);
    $this->enableAlwaysDisplayOriginalLanguageInTranslationOverview(FALSE);
    $this->drupalLogout();
    $this->drupalLogin($user);
    $this->runTestAccessTranslationOverview($entity);

    // Check access to edit user' own profile.
    $this->runTestUserEditForm($user);
  }

  /**
   * Test create entity in any language.
   */
  public function runTestCreateEntity() {
    $bundle = $this->bundle;
    $locked_langcodes = [
      Language::LANGCODE_NOT_SPECIFIED,
      Language::LANGCODE_NOT_APPLICABLE,
    ];
    $translatorSkills = $this->container->get('translators.skills');
    if ($this->expectedStatus['create entity in any language'] == 200) {
      foreach ($this->getAllSiteLangcodes() as $langcode) {
        $this->drupalGet($this->getCreateEntityUrl($langcode));
        $this->assertSession()->statusCodeEquals(200);
        foreach ($this->getAllSiteLangcodes() as $all_langcode) {
          $this->assertOptionAvailable('langcode[0][value]', $all_langcode);
        }
        foreach ($locked_langcodes as $locked_langcode) {
          $this->assertOptionAvailable('langcode[0][value]', $locked_langcode);
        }
      }
    }
    elseif ($this->expectedStatus['create entity in translation skills'] == 200) {
      foreach ($translatorSkills->getAllLangcodes() as $langcode) {
        $this->drupalGet($this->getCreateEntityUrl($langcode));
        $this->assertSession()->statusCodeEquals(200);
        // Check language option field.
        foreach ($translatorSkills->getAllLangcodes() as $user_langcode) {
          $this->assertOptionAvailable('langcode[0][value]', $user_langcode);
        }
        foreach ($locked_langcodes as $locked_langcode) {
          $this->assertOptionAvailable('langcode[0][value]', $locked_langcode);
        }
        foreach ($this->getUnregisteredLangcodes() as $un_langcode) {
          $this->assertOptionNotAvailable('langcode[0][value]', $un_langcode);
        }
      }
      foreach ($this->getUnregisteredLangcodes() as $langcode) {
        $this->drupalGet($this->getCreateEntityUrl($langcode));
        $this->assertSession()->statusCodeEquals(403);
      }
    }
    else {
      foreach ($this->getAllSiteLangcodes() as $langcode) {
        $this->drupalGet($this->getCreateEntityUrl($langcode));
        $this->assertSession()->statusCodeEquals(403);
      }
    }
  }

  /**
   * Test entity operation all languages.
   */
  public function runTestEntityOperations(string $operation) {
    $other_user_id = 1;
    $translatorSkills = $this->container->get('translators.skills');
    if ($this->expectedStatus["$operation any entity in any language"] == 200) {
      foreach ($this->getAllSiteLangcodes() as $langcode) {
        $entity = $this->createTestEntity($langcode);
        $this->runTestEntityOperation($entity, $operation, TRUE);
        $entity = $this->createTestEntity($langcode, $other_user_id);
        $this->runTestEntityOperation($entity, $operation, TRUE);
      }
    }
    elseif ($this->expectedStatus["$operation any entity in translation skills"] == 200) {
      foreach ($translatorSkills->getAllLangcodes() as $langcode) {
        $entity = $this->createTestEntity($langcode);
        $this->runTestEntityOperation($entity, $operation, TRUE);
        $entity = $this->createTestEntity($langcode, $other_user_id);
        $this->runTestEntityOperation($entity, $operation, TRUE);

      }
      foreach ($this->getUnregisteredLangcodes() as $langcode) {
        $entity = $this->createTestEntity($langcode);
        $this->runTestEntityOperation($entity, $operation, FALSE);
        $entity = $this->createTestEntity($langcode, $other_user_id);
        $this->runTestEntityOperation($entity, $operation, FALSE);
      }
    }
    elseif ($this->expectedStatus["$operation own entity"] == 200) {
      foreach ($this->getAllSiteLangcodes() as $langcode) {
        $entity = $this->createTestEntity($langcode);
        $this->runTestEntityOperation($entity, $operation, TRUE);
        $entity = $this->createTestEntity($langcode, $other_user_id);
        $this->runTestEntityOperation($entity, $operation, FALSE);
      }
    }
    else {
      foreach ($this->getAllSiteLangcodes() as $langcode) {
        $entity = $this->createTestEntity($langcode);
        $this->runTestEntityOperation($entity, $operation, FALSE);
        $entity = $this->createTestEntity($langcode, $other_user_id);
        $this->runTestEntityOperation($entity, $operation, FALSE);
      }
    }
  }

  /**
   * Test entity operation in one language.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be tested on.
   * @param string $operation
   *   Operation.
   * @param bool $has_permission
   *   Indicate if user has permission.
   */
  public function runTestEntityOperation(EntityInterface $entity, string $operation, bool $has_permission) {
    $langcode = $entity->getUntranslated()->language()->getId();
    $url = $entity->toUrl("$operation-form");
    $this->drupalGet($url);
    $path = $this->getCurrentPath($langcode);
    if ($has_permission) {
      // Check direct link permission.
      $this->assertSession()->statusCodeEquals(200);
      // Check local task tabs existence.
      $label = ucfirst($operation);
      $this->runTestLocalTaskTabsExistence($entity, $label, $url);
      // Check operation existence on translation overview page.
      if ($this->expectedStatus['access translation overview'] == 200) {
        $this->drupalGet($entity->toUrl('drupal:content-translation-overview'));
        $this->assertSession()->statusCodeEquals(200);
        $this->assertSession()
          ->elementExists('css', ".$operation a[hreflang=\"" . $langcode . "\"]");
        $this->click(".$operation a[hreflang=\"" . $langcode . "\"]");
        $this->assertSession()->addressEquals($path);
      }
    }
    else {
      // Check NO direct link permission.
      $this->assertSession()->statusCodeEquals(403);
      // Check NO local task tabs existence.
      $label = ucfirst($operation);
      $this->runTestNoLocalTaskTabsExistence($entity, $label);
      // Check NO operation existence on translation overview page.
      $this->drupalGet($entity->toUrl('drupal:content-translation-overview'));
      $this->assertSession()
        ->elementNotExists('css', ".$operation a[hreflang=\"" . $langcode . "\"]");
    }
  }

  /**
   * Test access translation overview.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be tested on.
   */
  public function runTestAccessTranslationOverview(EntityInterface $entity) {
    // Test direct link.
    $url = $entity->toUrl('drupal:content-translation-overview');
    $this->drupalGet($url);
    $url_string = $url->toString();
    $this->assertSession()->statusCodeEquals($this->expectedStatus['access translation overview']);
    if ($this->expectedStatus['access translation overview'] == 200) {
      // Check the language row filtering.
      $config = \Drupal::configFactory()->get('translators.settings');
      $translatorSkills = $this->container->get('translators.skills');
      if ($config->get('enable_filter_translation_overview_to_skills')) {
        if (count($this->getAllSiteLangcodes()) > count($translatorSkills->getAllLangcodes())) {
          $button_css = 'main #show-more-translations-link';
          $button_label = t('Show all languages')->render();
          $this->assertSession()->elementContains('css', $button_css, $button_label);
        }
        else {
          $this->assertSession()->elementNotExists('css', $button_css);
        }
        // Check translation language visability.
        $default_langcode = $entity->getUntranslated()->language()->getId();
        $language_manager = $this->container->get('language_manager');
        $always_display_default = $config
          ->get('always_display_original_language_translation_overview');
        $language_column_css = 'main table td:first-child';
        foreach ($this->getAllSiteLangcodes() as $langcode) {
          $language_name = t($language_manager->getLanguageName($langcode))->render();
          if ($translatorSkills->hasLangcode($langcode)) {
            $this->assertAnyElementContains('css', $language_column_css, $language_name);
          }
          else {
            if (($always_display_default == TRUE) && ($langcode == $default_langcode)) {
              $this->assertAnyElementContains('css', $language_column_css, $language_name);
            }
            else {
              $this->assertNoneElementContains('css', $language_column_css, $language_name);
            }
          }
        }
        // Check original language visability.
        $original_language_label = t('(Original language)')->render();
        if ($always_display_default == TRUE) {
          $this->assertAnyElementContains('css', $language_column_css, $original_language_label);
        }
        else {
          if ($translatorSkills->hasLangcode($default_langcode)) {
            $this->assertAnyElementContains('css', $language_column_css, $original_language_label);
          }
          else {
            $this->assertNoneElementContains('css', $language_column_css, $original_language_label);
          }
        }
      }
      else {
        $this->assertSession()->elementNotExists('css', 'main #show-more-translations-link');
      }
      // Check local task tabs existence.
      $this->runTestLocalTaskTabsExistence($entity, 'Translate', $url);
    }
  }

  /**
   * Test local task tabs existence.
   */
  public function runTestLocalTaskTabsExistence($entity, $label, $url, $langcode = NULL) {
    $this->drupalGetEntity($entity, $langcode);
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->elementExists('xpath', '//a[text()="' . $label . '"]/@href');
    $this->clickLink($label);
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->addressEquals($url->toString());
  }

  /**
   * Test NO local task tabs existence.
   */
  public function runTestNoLocalTaskTabsExistence($entity, $label, $langcode = NULL) {
    $this->drupalGetEntity($entity, $langcode);
    $this->assertSession()->elementNotExists('xpath', '//a[text()="' . $label . '"]/@href');
  }

  /**
   * Test create translation any language.
   */
  public function runTestCreateTranslation() {
    $entity = $this->createTestEntity();
    $entityTypeId = $entity->getEntityTypeId();
    $original = $entity->getUntranslated()->language()->getId();
    $config = \Drupal::configFactory()->get('translators.settings');
    $translatorSkills = $this->container->get('translators.skills');
    if ($this->expectedStatus['create translation in any language'] == 200) {
      foreach ($this->getAllSiteLangcodes() as $target) {
        if ($target == $original) {
          continue;
        }
        $source = $translatorSkills->getTranslationSourceLangcode($entity, $target);
        $this->runTestCreateOperationTranslation($entity, $source, $target, TRUE);
      }
    }
    elseif ($this->expectedStatus['create translation in translation skills'] == 200) {
      $strict_skill_pairing = (bool) $config->get('enable_strict_translation_skill_pairing');
      foreach ($this->getAllSiteLangcodes() as $target) {
        if ($target == $original) {
          continue;
        }
        $source = $translatorSkills->getTranslationSourceLangcode($entity, $target);
        if ($strict_skill_pairing
          && $translatorSkills->hasTranslationSkills($source, $target)) {
          $this->runTestCreateOperationTranslation($entity, $source, $target, TRUE);
        }
        elseif (!$strict_skill_pairing
          && $translatorSkills->hasLangcode($source)
          && $translatorSkills->hasLangcode($target)) {
          $this->runTestCreateOperationTranslation($entity, $source, $target, TRUE);
        }
        else {
          $this->runTestCreateOperationTranslation($entity, $source, $target, FALSE);
        }
      }
    }
    else {
      foreach ($this->getAllSiteLangcodes() as $target) {
        if ($target == $original) {
          continue;
        }
        $source = $translatorSkills->getTranslationSourceLangcode($entity, $target);
        $this->runTestCreateOperationTranslation($entity, $source, $target, FALSE);
      }
    }
  }

  /**
   * Test create translation operation.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be tested on.
   * @param string $source
   *   Language ID of source language.
   * @param string $target
   *   Language ID of target language.
   * @param bool $has_permission
   *   Indicate if user has permission.
   */
  public function runTestCreateOperationTranslation(EntityInterface $entity, string $source, string $target, bool $has_permission) {
    $translatorSkills = $this->container->get('translators.skills');
    $source = $translatorSkills->getTranslationSourceLangcode($entity, $target);
    $translation_add_url = $this->getCreateEntityTranslationUrl($entity, $source, $target);
    $this->drupalGet($translation_add_url);
    $this->assertSession()->addressEquals($translation_add_url->toString());
    $path = $this->getCurrentPath($target);
    if ($has_permission) {
      // Check direct link access.
      $this->assertSession()->statusCodeEquals(200);
      // Check translation operation existence on translation overview page.
      $this->drupalGet($entity->toUrl('drupal:content-translation-overview'));
      $this->assertSession()->statusCodeEquals(200);
      $this->assertSession()
        ->elementExists('css', '.add a[hreflang="' . $target . '"]');
      $this->click('.add a[hreflang="' . $target . '"]');
      $this->assertSession()->addressEquals($path);
      $this->assertSession()->statusCodeEquals(200);
      // Check source language field.
      $this->runTestCreateTranslationSourceLanguages($entity, $target);
    }
    else {
      // Check NO direct link access.
      $this->assertSession()->statusCodeEquals(403);
      // Check NO translation operation existence on translation overview page.
      $this->drupalGet($entity->toUrl('drupal:content-translation-overview'));
      $this->assertSession()
        ->elementNotExists('css', '.add a[hreflang="' . $target . '"]');
    }
  }

  /**
   * Test source language field for create translation operation.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be tested on.
   * @param string $target
   *   Language ID of target language.
   */
  public function runTestCreateTranslationSourceLanguages(EntityInterface $entity, string $target) {
    $translation_langcodes = array_keys($entity->getTranslationLanguages());
    if (count($translation_langcodes) > 1) {
      if ($this->expectedStatus['create entity in any language'] == 200) {
        foreach ($translation_langcodes as $source) {
          $this->assertOptionAvailable('source_langcode[source]', $source);
        }
      }
      else {
        $strict_skill_pairing = \Drupal::configFactory()->get('translators.settings')
          ->get('enable_strict_translation_skill_pairing');
        $translatorSkills = $this->container->get('translators.skills');
        foreach ($translation_langcodes as $source) {
          if ($strict_skill_pairing
            && $translatorSkills->hasTranslationSkills($source, $target)) {
            $this->assertOptionAvailable('source_langcode[source]', $source);
          }
          elseif (!$strict_skill_pairing && $translatorSkills->hasLangcode($source)) {
            $this->assertOptionAvailable('source_langcode[source]', $source);
          }
          else {
            $this->assertOptionNotAvailable('source_langcode[source]', $source);
          }
        }
      }
    }
  }

  /**
   * Test translation operations in all languages.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be tested on.
   * @param string $operation
   *   Operation.
   */
  public function runTestTranslationOperations(EntityInterface $entity, string $operation) {
    $translatorSkills = $this->container->get('translators.skills');
    if ($this->expectedStatus["$operation translation in any language"] == 200) {
      foreach ($this->getAllSiteLangcodes() as $langcode) {
        if ($langcode == $entity->getUntranslated()->language()->getId()) {
          continue;
        }
        $this->runTestTranslationOperation($entity, $operation, $langcode, TRUE);
      }
    }
    elseif ($this->expectedStatus["$operation translation in translation skills"] == 200) {
      foreach ($translatorSkills->getAllLangcodes() as $langcode) {
        if ($langcode == $entity->getUntranslated()->language()->getId()) {
          continue;
        }
        $this->runTestTranslationOperation($entity, $operation, $langcode, TRUE);
      }
      foreach ($this->getUnregisteredLangcodes() as $langcode) {
        if ($langcode == $entity->getUntranslated()->language()->getId()) {
          continue;
        }
        $this->runTestTranslationOperation($entity, $operation, $langcode, FALSE);
      }
    }
    else {
      foreach ($this->getAllSiteLangcodes() as $langcode) {
        if ($langcode == $entity->getUntranslated()->language()->getId()) {
          continue;
        }
        $this->runTestTranslationOperation($entity, $operation, $langcode, FALSE);
      }
    }
  }

  /**
   * Test translation operation in one language.
   *
   * @param \Drupal\Core\Entity\EntityInterface $entity
   *   The entity to be tested on.
   * @param string $operation
   *   Operation.
   * @param string $langcode
   *   Language ID.
   * @param bool $has_permission
   *   Indicate if user has permission.
   */
  public function runTestTranslationOperation(EntityInterface $entity, string $operation, string $langcode, bool $has_permission) {
    $entity = $entity->getTranslation($langcode);
    $url = $this->getEntityTranslationOperationUrl($entity, $langcode, $operation);
    $this->drupalGet($url);
    $this->assertSession()->addressEquals($url->toString());
    if ($has_permission) {
      // Check direct link access.
      $this->assertSession()->statusCodeEquals(200);
      // Check translation operation existence on translation overview page.
      $this->drupalGet($entity->toUrl('drupal:content-translation-overview'));
      $this->assertSession()->statusCodeEquals(200);
      $this->assertSession()
        ->elementExists('css', ".$operation a[hreflang=\"" . $langcode . "\"]");
      $this->click(".$operation a[hreflang=\"" . $langcode . "\"]");
      $this->assertSession()->addressEquals($url->toString());
      $this->assertSession()->statusCodeEquals(200);
      // Check local task tabs existence.
      $label = ucfirst($operation);
      $this->runTestLocalTaskTabsExistence($entity, $label, $url, $langcode);
    }
    else {
      // Check NO direct link access.
      $this->assertSession()->statusCodeEquals(403);
      // Check NO translation operation existence on translation overview page.
      $this->drupalGet($entity->toUrl('drupal:content-translation-overview'));
      $this->assertSession()
        ->elementNotExists('css', ".$operation a[hreflang=\"" . $langcode . "\"]");
      // Check NO local task tabs existence.
      $label = ucfirst($operation);
      $this->runTestNoLocalTaskTabsExistence($entity, $label, $langcode);
    }
  }

  /**
   * Test that ensures we don't restrict access to the user's edit form.
   *
   * @throws \Behat\Mink\Exception\ExpectationException
   */
  public function runTestUserEditForm($user) {
    $another_user = $this->createUser();

    // Check that local task tabs exist for own page.
    $this->drupalGet("user/{$user->id()}");
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->elementExists('xpath', '//a[text()=\'Edit\']/@href');
    // Check that local task tabs doesn't exist for other uers's pages.
    $this->drupalGet("user/{$another_user->id()}");
    if ($user->hasPermission('administer users')) {
      $this->assertSession()->statusCodeEquals(200);
      $this->assertSession()->elementExists('xpath', '//a[text()=\'Edit\']/@href');
    }
    else {
      $this->assertSession()->statusCodeEquals(403);
      $this->assertSession()->elementNotExists('xpath', '//a[text()=\'Edit\']/@href');
    }

    // Check for the edit page access for own page.
    $this->drupalGet("user/{$user->id()}/edit");
    $this->assertSession()->statusCodeEquals(200);
    // Check for the edit page access for other users's page.
    $this->drupalGet("user/{$another_user->id()}/edit");
    if ($user->hasPermission('administer users')) {
      $this->assertSession()->statusCodeEquals(200);
    }
    else {
      $this->assertSession()->statusCodeEquals(403);
    }

    // Additionally check that we don't give access to this form
    // for anonymous users.
    $this->drupalLogout();
    $this->drupalGet("user/{$user->id()}/edit");
    $this->assertSession()->statusCodeEquals(403);
    $this->drupalLogin($user);
  }

  /**
   * Get default expected result code.
   *
   * @param int $default
   *   Default expected result code.
   *
   * @return array
   *   Array with default expected result code.
   */
  public function getDefaultExpectedStatus($default) {
    return [
      'create entity in any language' => $default,
      'create entity in translation skills' => $default,
      'edit any entity in any language' => $default,
      'edit any entity in translation skills' => $default,
      'edit own entity' => $default,
      'delete any entity in any language' => $default,
      'delete any entity in translation skills' => $default,
      'delete own entity' => $default,
      'access translation overview' => $default,
      'create translation in any language' => $default,
      'create translation in translation skills' => $default,
      'edit translation in any language' => $default,
      'edit translation in translation skills' => $default,
      'delete translation in any language' => $default,
      'delete translation in translation skills' => $default,
    ];
  }

}

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

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