You are here

class StateTransitionValidationTest in Workbench Moderation 8.2

Same name and namespace in other branches
  1. 8 tests/src/Unit/StateTransitionValidationTest.php \Drupal\Tests\workbench_moderation\Unit\StateTransitionValidationTest

@coversDefaultClass \Drupal\workbench_moderation\StateTransitionValidation @group workbench_moderation

Hierarchy

  • class \Drupal\Tests\workbench_moderation\Unit\StateTransitionValidationTest extends \Drupal\Tests\workbench_moderation\Unit\PHPUnit_Framework_TestCase

Expanded class hierarchy of StateTransitionValidationTest

File

tests/src/Unit/StateTransitionValidationTest.php, line 18

Namespace

Drupal\Tests\workbench_moderation\Unit
View source
class StateTransitionValidationTest extends \PHPUnit_Framework_TestCase {

  /**
   * Builds a mock storage object for Transitions.
   *
   * @return EntityStorageInterface
   */
  protected function setupTransitionStorage() {
    $entity_storage = $this
      ->prophesize(EntityStorageInterface::class);
    $list = $this
      ->setupTransitionEntityList();
    $entity_storage
      ->loadMultiple()
      ->willReturn($list);
    $entity_storage
      ->loadMultiple(Argument::type('array'))
      ->will(function ($args) use ($list) {
      $keys = $args[0];
      if (empty($keys)) {
        return $list;
      }
      $return = array_map(function ($key) use ($list) {
        return $list[$key];
      }, $keys);
      return $return;
    });
    return $entity_storage
      ->reveal();
  }

  /**
   * Builds an array of mocked Transition objects.
   *
   * @return ModerationStateTransitionInterface[]
   */
  protected function setupTransitionEntityList() {
    $transition = $this
      ->prophesize(ModerationStateTransitionInterface::class);
    $transition
      ->id()
      ->willReturn('draft__needs_review');
    $transition
      ->getFromState()
      ->willReturn('draft');
    $transition
      ->getToState()
      ->willReturn('needs_review');
    $list[$transition
      ->reveal()
      ->id()] = $transition
      ->reveal();
    $transition = $this
      ->prophesize(ModerationStateTransitionInterface::class);
    $transition
      ->id()
      ->willReturn('needs_review__staging');
    $transition
      ->getFromState()
      ->willReturn('needs_review');
    $transition
      ->getToState()
      ->willReturn('staging');
    $list[$transition
      ->reveal()
      ->id()] = $transition
      ->reveal();
    $transition = $this
      ->prophesize(ModerationStateTransitionInterface::class);
    $transition
      ->id()
      ->willReturn('staging__published');
    $transition
      ->getFromState()
      ->willReturn('staging');
    $transition
      ->getToState()
      ->willReturn('published');
    $list[$transition
      ->reveal()
      ->id()] = $transition
      ->reveal();
    $transition = $this
      ->prophesize(ModerationStateTransitionInterface::class);
    $transition
      ->id()
      ->willReturn('needs_review__draft');
    $transition
      ->getFromState()
      ->willReturn('needs_review');
    $transition
      ->getToState()
      ->willReturn('draft');
    $list[$transition
      ->reveal()
      ->id()] = $transition
      ->reveal();
    $transition = $this
      ->prophesize(ModerationStateTransitionInterface::class);
    $transition
      ->id()
      ->willReturn('draft__draft');
    $transition
      ->getFromState()
      ->willReturn('draft');
    $transition
      ->getToState()
      ->willReturn('draft');
    $list[$transition
      ->reveal()
      ->id()] = $transition
      ->reveal();
    $transition = $this
      ->prophesize(ModerationStateTransitionInterface::class);
    $transition
      ->id()
      ->willReturn('needs_review__needs_review');
    $transition
      ->getFromState()
      ->willReturn('needs_review');
    $transition
      ->getToState()
      ->willReturn('needs_review');
    $list[$transition
      ->reveal()
      ->id()] = $transition
      ->reveal();
    $transition = $this
      ->prophesize(ModerationStateTransitionInterface::class);
    $transition
      ->id()
      ->willReturn('published__published');
    $transition
      ->getFromState()
      ->willReturn('published');
    $transition
      ->getToState()
      ->willReturn('published');
    $list[$transition
      ->reveal()
      ->id()] = $transition
      ->reveal();
    return $list;
  }

  /**
   * Builds a mock storage object for States.
   *
   * @return EntityStorageInterface
   */
  protected function setupStateStorage() {
    $entity_storage = $this
      ->prophesize(EntityStorageInterface::class);
    $state = $this
      ->prophesize(ModerationStateInterface::class);
    $state
      ->id()
      ->willReturn('draft');
    $state
      ->label()
      ->willReturn('Draft');
    $state
      ->isPublishedState()
      ->willReturn(FALSE);
    $state
      ->isDefaultRevisionState()
      ->willReturn(FALSE);
    $states['draft'] = $state
      ->reveal();
    $state = $this
      ->prophesize(ModerationStateInterface::class);
    $state
      ->id()
      ->willReturn('needs_review');
    $state
      ->label()
      ->willReturn('Needs Review');
    $state
      ->isPublishedState()
      ->willReturn(FALSE);
    $state
      ->isDefaultRevisionState()
      ->willReturn(FALSE);
    $states['needs_review'] = $state
      ->reveal();
    $state = $this
      ->prophesize(ModerationStateInterface::class);
    $state
      ->id()
      ->willReturn('published');
    $state
      ->label()
      ->willReturn('Published');
    $state
      ->isPublishedState()
      ->willReturn(TRUE);
    $state
      ->isDefaultRevisionState()
      ->willReturn(TRUE);
    $states['published'] = $state
      ->reveal();
    $entity_storage
      ->loadMultiple()
      ->willReturn($states);
    return $entity_storage
      ->reveal();
  }

  /**
   * Builds a mocked Entity Type Manager.
   *
   * @return EntityTypeManagerInterface
   */
  protected function setupEntityTypeManager() {
    $entityTypeManager = $this
      ->prophesize(EntityTypeManagerInterface::class);
    $entityTypeManager
      ->getStorage('moderation_state')
      ->willReturn($this
      ->setupStateStorage());
    $entityTypeManager
      ->getStorage('moderation_state_transition')
      ->willReturn($this
      ->setupTransitionStorage());
    return $entityTypeManager
      ->reveal();
  }

  /**
   * Builds a mocked query factory that does nothing.
   *
   * @return QueryFactory
   */
  protected function setupQueryFactory() {
    $factory = $this
      ->prophesize(QueryFactory::class);
    return $factory
      ->reveal();
  }

  /**
   * @covers ::isTransitionAllowed
   * @covers ::calculatePossibleTransitions
   */
  public function testIsTransitionAllowedWithValidTransition() {
    $state_transition_validation = new StateTransitionValidation($this
      ->setupEntityTypeManager(), $this
      ->setupQueryFactory());
    $this
      ->assertTrue($state_transition_validation
      ->isTransitionAllowed('draft', 'draft'));
    $this
      ->assertTrue($state_transition_validation
      ->isTransitionAllowed('draft', 'needs_review'));
    $this
      ->assertTrue($state_transition_validation
      ->isTransitionAllowed('needs_review', 'needs_review'));
    $this
      ->assertTrue($state_transition_validation
      ->isTransitionAllowed('needs_review', 'staging'));
    $this
      ->assertTrue($state_transition_validation
      ->isTransitionAllowed('staging', 'published'));
    $this
      ->assertTrue($state_transition_validation
      ->isTransitionAllowed('needs_review', 'draft'));
  }

  /**
   * @covers ::isTransitionAllowed
   * @covers ::calculatePossibleTransitions
   */
  public function testIsTransitionAllowedWithInValidTransition() {
    $state_transition_validation = new StateTransitionValidation($this
      ->setupEntityTypeManager(), $this
      ->setupQueryFactory());
    $this
      ->assertFalse($state_transition_validation
      ->isTransitionAllowed('published', 'needs_review'));
    $this
      ->assertFalse($state_transition_validation
      ->isTransitionAllowed('published', 'staging'));
    $this
      ->assertFalse($state_transition_validation
      ->isTransitionAllowed('staging', 'needs_review'));
    $this
      ->assertFalse($state_transition_validation
      ->isTransitionAllowed('staging', 'staging'));
    $this
      ->assertFalse($state_transition_validation
      ->isTransitionAllowed('needs_review', 'published'));
    $this
      ->assertFalse($state_transition_validation
      ->isTransitionAllowed('published', 'archived'));
    $this
      ->assertFalse($state_transition_validation
      ->isTransitionAllowed('archived', 'published'));
  }

  /**
   * Verifies user-aware transition validation.
   *
   * @param string $from
   *   The state to transition from.
   * @param string $to
   *   The state to transition to.
   * @param string $permission
   *   The permission to give the user, or not.
   * @param bool $allowed
   *   Whether or not to grant a user this permission.
   * @param bool $result
   *   Whether userMayTransition() is expected to return TRUE or FALSE.
   *
   * @dataProvider userTransitionsProvider
   */
  public function testUserSensitiveValidTransitions($from, $to, $permission, $allowed, $result) {
    $user = $this
      ->prophesize(AccountInterface::class);

    // The one listed permission will be returned as instructed; Any others are
    // always denied.
    $user
      ->hasPermission($permission)
      ->willReturn($allowed);
    $user
      ->hasPermission(Argument::type('string'))
      ->willReturn(FALSE);
    $validator = new Validator($this
      ->setupEntityTypeManager(), $this
      ->setupQueryFactory());
    $this
      ->assertEquals($result, $validator
      ->userMayTransition($from, $to, $user
      ->reveal()));
  }

  /**
   * Data provider for the user transition test.
   *
   * @return array
   */
  public function userTransitionsProvider() {

    // The user has the right permission, so let it through.
    $ret[] = [
      'draft',
      'draft',
      'use draft__draft transition',
      TRUE,
      TRUE,
    ];

    // The user doesn't have the right permission, block it.
    $ret[] = [
      'draft',
      'draft',
      'use draft__draft transition',
      FALSE,
      FALSE,
    ];

    // The user has some other permission that doesn't matter.
    $ret[] = [
      'draft',
      'draft',
      'use draft__needs_review transition',
      TRUE,
      FALSE,
    ];

    // The user has permission, but the transition isn't allowed anyway.
    $ret[] = [
      'published',
      'needs_review',
      'use published__needs_review transition',
      TRUE,
      FALSE,
    ];
    return $ret;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
StateTransitionValidationTest::setupEntityTypeManager protected function Builds a mocked Entity Type Manager.
StateTransitionValidationTest::setupQueryFactory protected function Builds a mocked query factory that does nothing.
StateTransitionValidationTest::setupStateStorage protected function Builds a mock storage object for States.
StateTransitionValidationTest::setupTransitionEntityList protected function Builds an array of mocked Transition objects.
StateTransitionValidationTest::setupTransitionStorage protected function Builds a mock storage object for Transitions.
StateTransitionValidationTest::testIsTransitionAllowedWithInValidTransition public function @covers ::isTransitionAllowed @covers ::calculatePossibleTransitions
StateTransitionValidationTest::testIsTransitionAllowedWithValidTransition public function @covers ::isTransitionAllowed @covers ::calculatePossibleTransitions
StateTransitionValidationTest::testUserSensitiveValidTransitions public function Verifies user-aware transition validation.
StateTransitionValidationTest::userTransitionsProvider public function Data provider for the user transition test.