rules-8.x-3.x-dev/tests/src/Unit/RuleExpressionTest.php

tests/src/Unit/RuleExpressionTest.php
<?php

declare(strict_types=1);

namespace Drupal\Tests\rules\Unit;

use Drupal\rules\Context\ExecutionStateInterface;
use Drupal\rules\Engine\ConditionExpressionInterface;
use Drupal\rules\Engine\ExpressionManagerInterface;
use Drupal\rules\Plugin\RulesExpression\ActionSetExpression;
use Drupal\rules\Plugin\RulesExpression\RuleExpression;
use Drupal\rules\Plugin\RulesExpression\ActionExpression;
use Drupal\rules\Plugin\RulesExpression\AndExpression;
use Drupal\rules\Plugin\RulesExpression\OrExpression;
use Prophecy\Argument;

/**
 * @coversDefaultClass \Drupal\rules\Plugin\RulesExpression\RuleExpression
 * @group Rules
 */
class RuleExpressionTest extends RulesUnitTestBase {

  /**
   * The rules expression plugin manager.
   *
   * @var \Drupal\rules\Engine\ExpressionManagerInterface|\Prophecy\Prophecy\ProphecyInterface
   */
  protected $expressionManager;

  /**
   * The rule being tested.
   *
   * @var \Drupal\rules\Engine\RuleExpressionInterface
   */
  protected $rule;

  /**
   * The primary condition container of the rule.
   *
   * @var \Drupal\rules\Engine\ConditionExpressionContainerInterface
   */
  protected $conditions;

  /**
   * The primary action container of the rule.
   *
   * @var \Drupal\rules\Engine\ActionExpressionContainerInterface
   */
  protected $actions;

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    $this->expressionManager = $this->prophesize(ExpressionManagerInterface::class);

    $this->conditions = new AndExpression([], 'rules_and', ['label' => 'Condition set (AND)'], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal());
    $this->expressionManager->createInstance('rules_and', [])->willReturn($this->conditions);

    $this->actions = new ActionSetExpression([], 'rules_action_set', [], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal());
    $this->expressionManager->createInstance('rules_action_set', [])->willReturn($this->actions);

    $this->rule = new RuleExpression([], 'rules_rule', ['label' => 'Rule'], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal());
  }

  /**
   * Tests that a rule is constructed with condition and action containers.
   *
   * @covers ::__construct
   */
  public function testContainersOnConstruct(): void {
    $this->assertSame($this->conditions, $this->rule->getConditions());
    $this->assertSame($this->actions, $this->rule->getActions());
  }

  /**
   * Tests the condition container setter and getter.
   *
   * @covers ::setConditions
   * @covers ::getConditions
   */
  public function testSetConditionsGetConditions(): void {
    $or = new OrExpression([], 'rules_or', ['label' => 'Condition set (OR)'], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal());
    $this->rule->setConditions($or);
    $this->assertSame($or, $this->rule->getConditions());

    $and = new AndExpression([], 'rules_and', ['label' => 'Condition set (AND)'], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal());
    $this->rule->setConditions($and);
    $this->assertSame($and, $this->rule->getConditions());
  }

  /**
   * Tests the condition container setter and getter.
   *
   * @covers ::setActions
   * @covers ::getActions
   */
  public function testSetActionsGetActions(): void {
    $action_set = new ActionSetExpression([], '', [], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal());
    $this->rule->setActions($action_set);
    $this->assertSame($action_set, $this->rule->getActions());
  }

  /**
   * Tests that an action fires if a condition passes.
   *
   * @covers ::execute
   */
  public function testActionExecution(): void {
    // The method on the test action must be called once.
    $this->testActionExpression->executeWithState(
      Argument::type(ExecutionStateInterface::class))->shouldBeCalledTimes(1);

    $this->rule
      ->addExpressionObject($this->trueConditionExpression->reveal())
      ->addExpressionObject($this->testActionExpression->reveal())
      ->execute();
  }

  /**
   * Tests that an action does not fire if a condition fails.
   *
   * @covers ::execute
   */
  public function testConditionFails(): void {
    // The execute method on the action must never be called.
    $this->testActionExpression->executeWithState(
      Argument::type(ExecutionStateInterface::class))->shouldNotBeCalled();

    $this->rule
      ->addExpressionObject($this->falseConditionExpression->reveal())
      ->addExpressionObject($this->testActionExpression->reveal())
      ->execute();
  }

  /**
   * Tests that an action fires if a condition passes.
   *
   * @covers ::execute
   */
  public function testTwoConditionsTrue(): void {
    // The method on the test action must be called once.
    $this->testActionExpression->executeWithState(
      Argument::type(ExecutionStateInterface::class))->shouldBeCalledTimes(1);

    $this->trueConditionExpression->getWeight()->willReturn(0);

    $second_condition = $this->prophesize(ConditionExpressionInterface::class);
    $second_condition->getUuid()->willReturn('true_uuid2');
    $second_condition->getWeight()->willReturn(0);

    $second_condition->executeWithState(Argument::type(ExecutionStateInterface::class))
      ->willReturn(TRUE);

    $this->rule
      ->addExpressionObject($this->trueConditionExpression->reveal())
      ->addExpressionObject($second_condition->reveal())
      ->addExpressionObject($this->testActionExpression->reveal())
      ->execute();
  }

  /**
   * Tests that an action does not fire if a condition fails.
   *
   * @covers ::execute
   */
  public function testTwoConditionsFalse(): void {
    // The execute method on the action must never be called.
    $this->testActionExpression->executeWithState(
      Argument::type(ExecutionStateInterface::class))->shouldNotBeCalled();
    $this->testActionExpression->getWeight()->willReturn(0);

    $this->trueConditionExpression->getWeight()->willReturn(0);
    $this->falseConditionExpression->getWeight()->willReturn(0);

    $this->rule
      ->addExpressionObject($this->trueConditionExpression->reveal())
      ->addExpressionObject($this->falseConditionExpression->reveal())
      ->addExpressionObject($this->testActionExpression->reveal())
      ->execute();
  }

  /**
   * Tests that nested rules are properly executed.
   *
   * @covers ::execute
   */
  public function testNestedRules(): void {
    $this->testActionExpression->executeWithState(
      Argument::type(ExecutionStateInterface::class))->shouldBeCalledTimes(1);

    $nested = new RuleExpression([], 'rules_rule', ['label' => 'Rule'], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal());
    // We need to replace the action and condition container to not have the
    // same instances as in the outer rule.
    $nested->setConditions(new AndExpression([], 'rules_and', ['label' => 'Condition set (AND)'], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal()));
    $nested->setActions(new ActionSetExpression([], 'rules_action_set', [], $this->expressionManager->reveal(), $this->rulesDebugLogger->reveal()));

    $nested->addExpressionObject($this->trueConditionExpression->reveal())
      ->addExpressionObject($this->testActionExpression->reveal());

    $this->rule
      ->addExpressionObject($this->trueConditionExpression->reveal())
      ->addExpressionObject($nested)
      ->execute();
  }

  /**
   * Tests that a nested expression can be retrieved by UUID.
   */
  public function testLookupExpression(): void {
    // Test Conditions.
    $this->rule->addExpressionObject($this->trueConditionExpression->reveal());
    $uuid = $this->trueConditionExpression->reveal()->getUuid();
    $this->assertSame($this->trueConditionExpression->reveal(), $this->rule->getExpression($uuid));

    // Test actions.
    $this->rule->addExpressionObject($this->testActionExpression->reveal());
    $uuid = $this->testActionExpression->reveal()->getUuid();
    $this->assertSame($this->testActionExpression->reveal(), $this->rule->getExpression($uuid));

    $this->assertFalse($this->rule->getExpression('invalid UUID'));
  }

  /**
   * Tests that removing expressions by indices works.
   */
  public function testDeletingExpressions(): void {
    // Create a rule with 2 conditions and 2 actions.
    $this->rule->addExpressionObject($this->trueConditionExpression->reveal());
    $this->rule->addExpressionObject($this->falseConditionExpression->reveal());
    $this->rule->addExpressionObject($this->testActionExpression->reveal());
    $second_action = $this->prophesize(ActionExpression::class);
    $second_action->getUuid()->willReturn('action_uuid2');
    $this->rule->addExpressionObject($second_action->reveal());

    $this->trueConditionExpression->getWeight()->willReturn(0);
    $this->falseConditionExpression->getWeight()->willReturn(0);
    $this->testActionExpression->getWeight()->willReturn(0);
    $second_action->getWeight()->willReturn(0);

    // Delete the first action.
    $uuid = $this->testActionExpression->reveal()->getUuid();
    $this->rule->deleteExpression($uuid);
    $this->assertCount(2, $this->rule->getConditions()->getIterator());
    $this->assertCount(1, $this->rule->getActions()->getIterator());

    // Delete the second condition.
    $uuid = $this->falseConditionExpression->reveal()->getUuid();
    $this->rule->deleteExpression($uuid);
    $this->assertCount(1, $this->rule->getConditions()->getIterator());
    $this->assertCount(1, $this->rule->getActions()->getIterator());

    // Delete the remaining action.
    $uuid = $second_action->reveal()->getUuid();
    $this->rule->deleteExpression($uuid);
    $this->assertCount(1, $this->rule->getConditions()->getIterator());
    $this->assertCount(0, $this->rule->getActions()->getIterator());

    // Delete the remaining condition, rule should be empty now.
    $uuid = $this->trueConditionExpression->reveal()->getUuid();
    $this->rule->deleteExpression($uuid);
    $this->assertCount(0, $this->rule->getConditions()->getIterator());
    $this->assertCount(0, $this->rule->getActions()->getIterator());
  }

}

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

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