You are here

class RuleExpressionTest in Rules 8.3

@coversDefaultClass \Drupal\rules\Plugin\RulesExpression\RuleExpression @group Rules

Hierarchy

Expanded class hierarchy of RuleExpressionTest

File

tests/src/Unit/RuleExpressionTest.php, line 19

Namespace

Drupal\Tests\rules\Unit
View source
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() {
    $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() {
    $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() {
    $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() {

    // 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() {

    // 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() {

    // 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() {

    // 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() {
    $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() {

    // 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() {

    // 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
      ->assertEquals(2, count($this->rule
      ->getConditions()
      ->getIterator()));
    $this
      ->assertEquals(1, count($this->rule
      ->getActions()
      ->getIterator()));

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

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

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

}

Members

Namesort descending Modifiers Type Description Overrides
PhpunitCompatibilityTrait::getMock Deprecated public function Returns a mock object for the specified class using the available method.
PhpunitCompatibilityTrait::setExpectedException Deprecated public function Compatibility layer for PHPUnit 6 to support PHPUnit 4 code.
RuleExpressionTest::$actions protected property The primary action container of the rule.
RuleExpressionTest::$conditions protected property The primary condition container of the rule.
RuleExpressionTest::$expressionManager protected property The rules expression plugin manager. Overrides RulesUnitTestBase::$expressionManager
RuleExpressionTest::$rule protected property The rule being tested.
RuleExpressionTest::setUp protected function Overrides RulesUnitTestBase::setUp
RuleExpressionTest::testActionExecution public function Tests that an action fires if a condition passes.
RuleExpressionTest::testConditionFails public function Tests that an action does not fire if a condition fails.
RuleExpressionTest::testContainersOnConstruct public function Tests that a rule is constructed with condition and action containers.
RuleExpressionTest::testDeletingExpressions public function Tests that removing expressions by indices works.
RuleExpressionTest::testLookupExpression public function Tests that a nested expression can be retrieved by UUID.
RuleExpressionTest::testNestedRules public function Tests that nested rules are properly executed.
RuleExpressionTest::testSetActionsGetActions public function Tests the condition container setter and getter.
RuleExpressionTest::testSetConditionsGetConditions public function Tests the condition container setter and getter.
RuleExpressionTest::testTwoConditionsFalse public function Tests that an action does not fire if a condition fails.
RuleExpressionTest::testTwoConditionsTrue public function Tests that an action fires if a condition passes.
RulesUnitTestBase::$falseConditionExpression protected property A mocked condition that always evaluates to FALSE.
RulesUnitTestBase::$rulesDebugLogger protected property The mocked expression manager object.
RulesUnitTestBase::$testActionExpression protected property A mocked dummy action object.
RulesUnitTestBase::$testFirstActionExpression protected property A mocked dummy action object.
RulesUnitTestBase::$trueConditionExpression protected property A mocked condition that always evaluates to TRUE.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getBlockMockWithMachineName Deprecated protected function Mocks a block with a block plugin. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.