workflow_participants-8.x-2.x-dev/tests/src/Functional/AdminUiTest.php

tests/src/Functional/AdminUiTest.php
<?php

namespace Drupal\Tests\workflow_participants\Functional;

use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\user\RoleInterface;
use Drupal\workflow_participants\Entity\WorkflowParticipantsInterface;
use Drupal\workflows\Entity\Workflow;
use PHPUnit\Framework\Attributes\Group;

/**
 * Tests for the admin UI of workflow participants.
 */
#[Group('workflow_participants')]
class AdminUiTest extends TestBase {

  use StringTranslationTrait;

  /**
   * Tests admin configuration UI.
   */
  public function testAdminConfiguration() {
    // Verify 3rd-party settings work for transitions on edit form.
    $expected = [
      'archive' => 'archive',
      'create_new_draft' => 'create_new_draft',
    ];
    foreach ($expected as $transition) {
      $this->drupalGet('admin/config/workflow/workflows/manage/editorial/transition/' . $transition);
      $edit = [
        'editor_transitions' => TRUE,
        'reviewer_transitions' => $transition === 'archive',
      ];
      $this->submitForm($edit, 'Save');
    }

    // Test that the edit form for the transitions display the saved
    // editor_transitions and reviewer_transitions settings properly.
    foreach ($expected as $transition) {
      $this->drupalGet('admin/config/workflow/workflows/manage/editorial/transition/' . $transition);
      $this->assertSession()->checkboxChecked('editor_transitions');
      if ($transition === 'archive') {
        $this->assertSession()->checkboxChecked('reviewer_transitions');
      }
      else {
        $this->assertSession()->checkboxNotChecked('reviewer_transitions');
      }
    }

    // Load the workflow and verify 3rd-party setting.
    /** @var \Drupal\workflows\WorkflowInterface $workflow */
    $workflow = Workflow::load('editorial');
    $this->assertEquals($expected, $workflow->getThirdPartySetting('workflow_participants', 'editor_transitions', []));
    $this->assertEquals(['archive' => 'archive'], $workflow->getThirdPartySetting('workflow_participants', 'reviewer_transitions', []));

    // Test on transition add form.
    $workflow->getTypePlugin()->addState('foo', 'Foo');
    $workflow->save();
    $this->drupalGet('admin/config/workflow/workflows/manage/editorial/add_transition');
    $edit = [
      'label' => 'Foo',
      'id' => 'draft_foo',
      'from[draft]' => TRUE,
      'to' => 'foo',
      'editor_transitions' => TRUE,
    ];
    $this->submitForm($edit, 'Save');
    $expected['draft_foo'] = 'draft_foo';
    $workflow = Workflow::load('editorial');
    $this->assertEquals($expected, $workflow->getThirdPartySetting('workflow_participants', 'editor_transitions', []));
  }

  /**
   * Test basic workflow participants.
   */
  public function testUi() {
    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->linkExists('Workflow participants');
    $this->drupalGet('node/' . $this->node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(200);

    // Add some participants.
    $edit = [
      'editors[0][target_id]' => $this->participants[1]->getAccountName(),
      'reviewers[0][target_id]' => $this->participants[2]->getAccountName(),
    ];
    $this->submitForm($edit, 'Save');
    $workflow_participants = \Drupal::entityTypeManager()
      ->getStorage('workflow_participants')
      ->loadForModeratedEntity($this->node);
    $this->assertInstanceOf(WorkflowParticipantsInterface::class, $workflow_participants);
    $this->assertEquals($this->node->id(), $workflow_participants->getModeratedEntity()->id());
    $this->assertEquals([$this->participants[1]->id()], array_keys($workflow_participants->getEditors()));
    $this->assertEquals([$this->participants[2]->id()], array_keys($workflow_participants->getReviewers()));

    // Add another reviewer.
    $edit = [
      'editors[0][target_id]' => $this->participants[1]->getAccountName(),
      'editors[1][target_id]' => $this->participants[3]->getAccountName(),
      'reviewers[0][target_id]' => $this->participants[2]->getAccountName(),
      'reviewers[1][target_id]' => $this->participants[4]->getAccountName(),
    ];
    $this->submitForm($edit, 'Save');

    $workflow_participants = $this->participantStorage->loadUnchanged($workflow_participants->id());
    $this->assertEquals([
      $this->participants[1]->id(),
      $this->participants[3]->id(),
    ],
      array_keys($workflow_participants->getEditors()));
    $this->assertEquals([
      $this->participants[2]->id(),
      $this->participants[4]->id(),
    ], array_keys($workflow_participants->getReviewers()));

    // Attempt to add a user that is not in the participant role.
    $edit = [
      'editors[0][target_id]' => $this->participants[5]->getAccountName(),
    ];
    $this->submitForm($edit, 'Save');
    $this->assertSession()->pageTextContains('There are no users matching "' . $this->participants[5]->getAccountName() . '".');

    // Add a node type without moderation enabled, and verify the tab doesn't
    // appear for content of that type.
    $node_type = $this->createContentType();
    $node = $this->createNode([
      'type' => $node_type->id(),
    ]);
    $this->drupalGet($node->toUrl());
    $this->assertSession()->linkNotExists('Workflow participants');
    $this->drupalGet('node/' . $node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(403);

    // Ensure this link is not in the entity operations either.
    $this->drupalLogin($this->adminUser);
    $this->drupalGet('admin/content');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->linkByHrefNotExists('/node/' . $node->id() . '/workflow-participants?destination=/admin/content');
  }

  /**
   * Tests author access to manage participants.
   */
  public function testAuthorUi() {
    $author = $this->createUser([
      'create article content',
      'edit own article content',
      'manage own workflow participants',
    ]);
    $this->drupalLogin($author);

    // Verify they cannot access another user's workflow participants.
    $this->drupalGet('node/' . $this->node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(403);

    // Verify they can access their own participants.
    $node = $this->createNode(['type' => 'article', 'uid' => $author->id()]);
    $this->drupalGet('node/' . $node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(200);
  }

  /**
   * Test participants ability to view/edit participants.
   */
  public function testEditorUi() {
    $editor = $this->participants[2];

    // User should not have view access prior to being a participant.
    $this->assertFalse($this->node->access('view', $editor));
    $participants = $this->participantStorage->loadForModeratedEntity($this->node);
    $participants->editors[0] = $editor;
    $participants->save();

    // Editor should have full UI access.
    $this->drupalLogin($editor);
    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->linkExists('Workflow participants');
    $this->drupalGet('node/' . $this->node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(200);
    $edit = [
      'reviewers[0][target_id]' => $this->participants[3]->getAccountName(),
    ];
    $this->submitForm($edit, 'Save');
    $participants = $this->participantStorage->loadUnchanged($participants->id());
    $expected = [
      $this->participants[3]->id() => $this->participants[3]->id(),
    ];
    $this->assertEquals($expected, $participants->getReviewerIds());

    // Remove self and verify proper redirect.
    $edit = [
      'editors[0][target_id]' => '',
    ];
    $this->submitForm($edit, 'Save');
    $participants = $this->participantStorage->loadUnchanged($participants->id());
    $this->assertEmpty($participants->getEditorIds());
    // For some reason, the front page redirects to the user page.
    $this->assertSession()->addressEquals($editor->toUrl()->setAbsolute()->toString());

    // Verify redirect to node page if user still has access to view.
    /** @var \Drupal\node\NodeInterface $node */
    $node = \Drupal::entityTypeManager()->getStorage('node')->loadUnchanged($this->node->id());
    $node->setPublished();
    $node->moderation_state = 'published';
    $node->save();
    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->statusCodeEquals(200);
    $participants->editors->target_id = $editor->id();
    $participants->save();
    // Remove self and verify proper redirect.
    $edit = [
      'editors[0][target_id]' => '',
    ];
    $this->drupalGet('node/' . $node->id() . '/workflow-participants');
    $this->submitForm($edit, 'Save');
    $participants = $this->participantStorage->loadUnchanged($participants->id());
    $this->assertEmpty($participants->getEditorIds());
    $this->assertSession()->addressEquals($this->node->toUrl()->setAbsolute()->toString());
    $this->assertSession()->linkNotExists('Workflow participants');
  }

  /**
   * Test reviewer UI.
   */
  public function testReviewerUi() {
    $reviewer = $this->participants[1];
    $participants = $this->participantStorage->loadForModeratedEntity($this->node);
    $participants->editors[0] = $this->participants[3];
    $participants->reviewers[0] = $reviewer;
    $participants->reviewers[1] = $this->participants[2];
    $participants->save();

    // Login reviewer and verify limited access.
    $this->drupalLogin($reviewer);
    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->linkExists('Workflow participants');
    $this->drupalGet('node/' . $this->node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->buttonExists('Remove me as reviewer');
    $this->assertSession()->buttonExists('Cancel');
    $this->assertSession()->fieldNotExists('Editors');
    $this->assertSession()->fieldNotExists('Reviewers');
    $this->assertSession()->linkByHrefExists($this->participants[1]->toUrl()->toString());
    $this->assertSession()->linkByHrefExists($this->participants[3]->toUrl()->toString());

    // Try cancel button.
    $this->submitForm([], 'Cancel');
    $this->assertSession()->addressEquals('node/' . $this->node->id());

    // Remove self.
    $this->drupalGet('node/' . $this->node->id() . '/workflow-participants');
    $this->submitForm([], 'Remove me as reviewer');
    $participants = $this->participantStorage->loadUnchanged($participants->id());
    $expected = [
      $this->participants[2]->id() => $this->participants[2]->id(),
    ];
    $this->assertSession()->pageTextContains('You have been removed as a reviewer.');
    $this->assertEquals($expected, $participants->getReviewerIds());
    $this->drupalGet('node/' . $this->node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(403);
  }

  /**
   * Tests that normal authenticated users can be added as participants.
   */
  public function testAuthenticatedUsers() {
    $editor = $this->drupalCreateUser();

    // Add the appropriate permissions to the authenticated role.
    /** @var \Drupal\user\RoleInterface $role */
    $role = \Drupal::entityTypeManager()->getStorage('user_role')->load(RoleInterface::AUTHENTICATED_ID);
    $role->grantPermission('can be workflow participant');
    $role->save();

    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->linkExists('Workflow participants');
    $this->drupalGet('node/' . $this->node->id() . '/workflow-participants');
    $this->assertSession()->statusCodeEquals(200);

    // Add some participants.
    $edit = [
      'editors[0][target_id]' => $editor->getAccountName(),
    ];
    $this->submitForm($edit, 'Save');
    $workflow_participants = \Drupal::entityTypeManager()
      ->getStorage('workflow_participants')
      ->loadForModeratedEntity($this->node);
    $this->assertInstanceOf(WorkflowParticipantsInterface::class, $workflow_participants);
    $this->assertEquals($this->node->id(), $workflow_participants->getModeratedEntity()->id());
    $this->assertEquals([$editor->id()], array_keys($workflow_participants->getEditors()));
    $this->assertEmpty($workflow_participants->getReviewers());
  }

  /**
   * Tests basic cache tag invalidation.
   */
  public function testCacheTags() {
    $author = $this->drupalCreateUser(['manage own workflow participants']);
    $this->node->setOwner($author);
    $this->node->moderation_state = 'published';
    $this->node->save();

    $editor = $this->participants[1];
    $this->drupalLogin($editor);
    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->linkNotExists('Workflow participants');

    // Login as author, add the editor.
    $this->drupalLogin($author);
    $this->drupalGet('/node/' . $this->node->id() . '/workflow-participants');
    $edit = [
      'editors[0][target_id]' => $editor->getAccountName(),
    ];
    $this->submitForm($edit, $this->t('Save'));

    $this->drupalLogin($editor);
    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->linkExists('Workflow participants');
    $this->clickLink('Workflow participants');
    $this->assertSession()->statusCodeEquals(200);

    // Login as author, remove the editor.
    $this->drupalLogin($author);
    $this->drupalGet('/node/' . $this->node->id() . '/workflow-participants');
    $edit = [
      'editors[0][target_id]' => '',
    ];
    $this->submitForm($edit, 'Save');

    $this->drupalLogin($editor);
    $this->drupalGet($this->node->toUrl());
    $this->assertSession()->statusCodeEquals(200);
    $this->assertSession()->linkNotExists('Workflow participants');
  }

}

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

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