You are here

ScheduledUpdatesTestBase.php in Scheduled Updates 8

Contains \Drupal\Tests\scheduled_updates\ScheduledUpdatesTestBase.

File

tests/src/FunctionalJavascript/ScheduledUpdatesTestBase.php
View source
<?php

/**
 * @file
 * Contains \Drupal\Tests\scheduled_updates\ScheduledUpdatesTestBase.
 */
namespace Drupal\Tests\scheduled_updates\FunctionalJavascript;

use Drupal\Component\Render\FormattableMarkup;
use Drupal\scheduled_updates\Plugin\UpdateRunnerInterface;
use Drupal\user\Entity\Role;

/**
 * Define base class for Scheduled Updates Tests
 */
abstract class ScheduledUpdatesTestBase extends WebTestExtended {
  const NODE_SAVE_BUTTON_TEXT = 'Save';

  /**
   * Profile to use.
   */
  protected $profile = 'testing';

  /**
   * Admin user
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $adminUser;

  /**
   * Permissions to grant admin user.
   *
   * @var array
   */
  protected $permissions = [
    'access administration pages',
    'administer content types',
    'administer nodes',
    'administer scheduled update types',
    'administer scheduled_update fields',
    'administer scheduled_update form display',
    'access site reports',
  ];

  /**
   * Modules to enable.
   *
   * @var array
   */
  public static $modules = [
    'scheduled_updates',
    'node',
    'user',
    'field_ui',
    'block',
    'inline_entity_form',
  ];

  /**
   * Sets the test up.
   */
  protected function setUp() {
    parent::setUp();
    $this->adminUser = $this
      ->drupalCreateUser($this->permissions);
    $this
      ->drupalPlaceBlock('local_tasks_block', [
      'id' => 'tabs_block',
    ]);
    $this
      ->drupalPlaceBlock('page_title_block');
    $this
      ->drupalPlaceBlock('local_actions_block', [
      'id' => 'actions_block',
    ]);
    $this
      ->setupContentTypes();
  }

  /**
   * Clone multiple fields on the Clone Field Page.
   *
   * @param $type_id
   * @param array $fields
   *
   * @throws \Exception
   */
  protected function cloneFields($type_id, array $fields) {
    $this
      ->gotoURLIfNot("admin/config/workflow/scheduled-update-type/{$type_id}/clone-fields");
    $edit = [];
    foreach ($fields as $input_name => $field_info) {

      // Check the field label exists.
      $this
        ->assertSession()
        ->pageTextContains($field_info['label']);

      // Add to post data.
      $edit[$input_name] = $field_info['input_value'];
    }
    $this
      ->drupalPostForm(NULL, $edit, t('Clone Fields'));
    if ($this->adminUser
      ->hasPermission('administer scheduled_update form display')) {

      // Should be redirected to form display after cloning fields
      $this
        ->assertUrl("admin/config/workflow/scheduled-update-type/{$type_id}/form-display");
      $this
        ->checkFieldLabels($fields);
    }
    else {

      // @todo Does it make any sense for admin to be able to add update types without Field UI permissions
      //  Enforce Field UI permissions to add scheduled update type?
      $this
        ->assertSession()
        ->pageTextContains('You do not have permission to administer fields on Scheduled Updates.');
    }
  }

  /**
   * @param array $fields
   */
  protected function checkFieldLabels(array $fields) {
    foreach ($fields as $input_name => $field_info) {

      // We only know what base field labels should look like.
      if (stripos($input_name, 'base_fields[') === 0) {

        // Check the field label exists.
        $this
          ->assertSession()
          ->pageTextContains($field_info['label']);
      }
      else {

        // @test that Configurable fields were cloned.
      }
    }
  }

  /**
   * Get Node Property machine names.
   *
   * @return array
   *   The node property machine names.
   */
  protected function getNodePropertyMachineNames() {
    $property_labels = [
      'langcode',
      'title',
      'status',
      'uid',
      'revision_timestamp',
      'revision_uid',
      'revision_log',
      'created',
      'changed',
      'promote',
      'sticky',
    ];
    return $property_labels;
  }

  /**
   * @param $label
   * @param $id
   * @param array $clone_fields
   *
   * @param array $type_options
   *
   * @throws \Exception
   */
  protected function createType($label, $id, array $clone_fields, $type_options = []) {
    $this
      ->drupalGet('admin/config/workflow/scheduled-update-type/add');

    // Revision options should not be displayed until entity type that supports it is selected.
    $this
      ->assertSession()
      ->pageTextNotContains('The owner of the last revision.');
    $this
      ->assertSession()
      ->pageTextNotContains('Create New Revisions');
    $edit = $type_options + [
      'label' => $label,
      'id' => $id,
      'update_entity_type' => 'node',
      'update_runner[id]' => 'default_independent',
      'update_runner[after_run]' => UpdateRunnerInterface::AFTER_DELETE,
      'update_runner[invalid_update_behavior]' => UpdateRunnerInterface::INVALID_DELETE,
      'update_runner[update_user]' => UpdateRunnerInterface::USER_UPDATE_RUNNER,
    ];
    $this
      ->checkRunnersAvailable();
    $this
      ->drupalPostAjaxForm(NULL, $edit, 'update_entity_type');
    $this
      ->assertSession()
      ->pageTextContains('The owner of the last revision.');
    $this
      ->assertSession()
      ->pageTextContains('Create New Revisions');
    $edit = $type_options + [
      'label' => $label,
      'id' => $id,
      'clone_field' => 'multiple-field',
      'update_entity_type' => 'node',
      'update_runner[id]' => 'default_independent',
      'update_runner[after_run]' => UpdateRunnerInterface::AFTER_DELETE,
      'update_runner[invalid_update_behavior]' => UpdateRunnerInterface::INVALID_DELETE,
      'update_runner[update_user]' => UpdateRunnerInterface::USER_UPDATE_RUNNER,
      'update_runner[create_revisions]' => UpdateRunnerInterface::REVISIONS_YES,
      'update_runner[bundles][article]' => 'article',
    ];
    $this
      ->drupalPostForm(NULL, $edit, t('Save'));
    $this
      ->assertUrl("admin/config/workflow/scheduled-update-type/{$id}/clone-fields");
    $this
      ->assertSession()
      ->pageTextContains("Created the {$label} Scheduled Update Type.");
    $this
      ->assertSession()
      ->pageTextContains("Select fields to add to these updates");
    $this
      ->checkExpectedCheckboxes('base_fields', $this
      ->getNodePropertyMachineNames());

    // @todo test that node.body displays and is select field.
    $this
      ->cloneFields($id, $clone_fields);
  }
  protected function setupContentTypes() {
    if ($this->profile != 'standard') {
      $this
        ->drupalCreateContentType([
        'type' => 'article',
        'name' => 'Article',
      ]);
      $this
        ->drupalCreateContentType([
        'type' => 'page',
        'name' => 'Basic Page',
      ]);
    }
  }

  /**
   * Check that a set of runner plugins are on form and no extras.
   *
   * @param array $expected_runners
   */
  protected function checkRunnersAvailable(array $expected_runners = []) {
    $all_runners = [
      'default_embedded',
      'default_independent',
      'latest_revision',
    ];
    if (!$expected_runners) {
      $expected_runners = $all_runners;
    }
    $unexpected_runners = array_diff($all_runners, $expected_runners);
    $this
      ->checkExpectedRadioOptions('update_runner[id]', $expected_runners, $unexpected_runners);
  }

  /**
   * Runs Updates via the UI.
   */
  protected function runUpdatesUI() {
    $this
      ->drupalGet('admin/config/workflow/schedule-updates/run');
    $this
      ->drupalPostForm(NULL, [], 'Run Updates');
  }

  /**
   * Checks that an scheduled update type can be edit via the form.
   *
   * @param string $type_id
   *   The type id.
   */
  protected function checkEditType($type_id) {
    $this
      ->drupalGet("admin/config/workflow/scheduled-update-type/{$type_id}");

    // For now just test the saving without changes works.
    // See https://www.drupal.org/node/2674874
    $this
      ->drupalPostForm(NULL, [], t('Save'));
  }

  /**
   * Grant permissions to a user.
   *
   * The permissions are actually added to the users role.
   * Relies on test users only having 1 non-locked role.
   *
   * @param array $permissions
   */
  protected function grantPermissionsToUser($permissions) {
    $roles = $this->adminUser
      ->getRoles(TRUE);
    $this
      ->assert('debug', "roles =" . implode(',', $roles));
    $role_id = array_pop($roles);

    /** @var \Drupal\user\RoleInterface $role */
    $role = Role::load($role_id);
    $this
      ->grantPermissions($role, $permissions);
  }

  /**
   * Grant permissions to a user.
   *
   * The permissions are actually added to the users role.
   * Relies on test users only having 1 non-locked role.
   *
   * @param array $permissions
   */
  protected function revokePermissionsFromUser($permissions) {
    $roles = $this->adminUser
      ->getRoles(TRUE);
    $role_id = array_pop($roles);
    foreach ($permissions as $permission) {
      Role::load($role_id)
        ->revokePermission($permission);
    }
  }

}

Classes

Namesort descending Description
ScheduledUpdatesTestBase Define base class for Scheduled Updates Tests