You are here

class EntitySubjectTest in Changed Fields API 8.3

@coversDefaultClass \Drupal\changed_fields\EntitySubject

@group changed_fields

Hierarchy

Expanded class hierarchy of EntitySubjectTest

File

tests/src/Unit/EntitySubjectTest.php, line 12

Namespace

Drupal\Tests\changed_fields\Unit
View source
class EntitySubjectTest extends UnitTestCase {

  /**
   * Content entity's subject.
   *
   * @var Drupal\changed_fields\EntitySubject
   */
  private $entitySubject;

  /**
   * Sets a protected property on a given object via reflection.
   *
   * @param mixed $object
   *   Instance in which protected value is being modified.
   * @param string $property
   *   Property on instance being modified.
   * @param mixed $value
   *   New value of the property being modified.
   */
  public function setProtectedProperty($object, $property, $value) {
    $reflection = new \ReflectionClass($object);
    $reflection_property = $reflection
      ->getProperty($property);
    $reflection_property
      ->setAccessible(TRUE);
    $reflection_property
      ->setValue($object, $value);
  }

  /**
   * {@inheritdoc}
   */
  public function setUp() {
    $this->entitySubject = $this
      ->getMockBuilder('\\Drupal\\changed_fields\\EntitySubject')
      ->setMethods(NULL)
      ->disableOriginalConstructor()
      ->getMock();
  }

  /**
   * Entity subject can attach observers.
   */
  public function testAttachMethod() {
    $observer_mock = $this
      ->createMock('SplObserver');
    $this
      ->expectException(\InvalidArgumentException::class);
    $this
      ->expectExceptionMessage('Observer must implement ObserverInterface interface.');
    $this->entitySubject
      ->attach($observer_mock);
  }

  /**
   * Entity subject can detach observers.
   */
  public function testDetachMethod() {
    $observer_mock = $this
      ->createMock('SplObserver');
    $this
      ->expectException(\InvalidArgumentException::class);
    $this
      ->expectExceptionMessage('Observer must implement ObserverInterface interface.');
    $this->entitySubject
      ->detach($observer_mock);
  }

  /**
   * Observers 1 and 2 are notified. Observer 3 is not notified.
   *
   * Entity: node:article.
   * Observer 1: listens to node:article.
   * Observer 2: listens to node:article and node:page.
   * Observer 3: listens to media:image.
   */
  public function testNotifyObservers() {
    $observer_1 = $this
      ->getMockBuilder('Drupal\\changed_fields\\ObserverInterface')
      ->setMethods([
      'getInfo',
      'update',
    ])
      ->getMock();
    $observer_1
      ->expects($this
      ->once())
      ->method('getInfo')
      ->willReturn([
      'node' => [
        'article' => [
          'title',
          'body',
        ],
      ],
    ]);
    $observer_1
      ->expects($this
      ->once())
      ->method('update');
    $observer_2 = $this
      ->getMockBuilder('Drupal\\changed_fields\\ObserverInterface')
      ->setMethods([
      'getInfo',
      'update',
    ])
      ->getMock();
    $observer_2
      ->expects($this
      ->once())
      ->method('getInfo')
      ->willReturn([
      'node' => [
        'article' => [
          'title',
          'body',
        ],
        'page' => [
          'title',
          'body',
        ],
      ],
      'user' => [
        'user' => [
          'name',
        ],
      ],
    ]);
    $observer_2
      ->expects($this
      ->once())
      ->method('update');
    $observer_3 = $this
      ->getMockBuilder('Drupal\\changed_fields\\ObserverInterface')
      ->setMethods([
      'getInfo',
      'update',
    ])
      ->getMock();
    $observer_3
      ->expects($this
      ->once())
      ->method('getInfo')
      ->willReturn([
      'media' => [
        'image' => [
          'name',
          'field_media_image',
        ],
      ],
      'comment' => [
        'comment' => [
          'subject',
          'comment_body',
        ],
      ],
    ]);
    $observer_3
      ->expects($this
      ->never())
      ->method('update');
    $field_definition_mock = $this
      ->getMockBuilder('Drupal\\field\\Entity\\FieldConfig')
      ->disableOriginalConstructor()
      ->setMethods([
      'getType',
    ])
      ->getMock();
    $field_definition_mock
      ->expects($this
      ->any())
      ->method('getType')
      ->willReturn('string');
    $field_item_list_mock = $this
      ->getMockBuilder('Drupal\\Core\\Field\\FieldItemList')
      ->disableOriginalConstructor()
      ->setMethods([
      'getValue',
      'getFieldDefinition',
    ])
      ->getMock();
    $field_item_list_mock
      ->expects($this
      ->any())
      ->method('getValue')
      ->willReturn([]);
    $field_item_list_mock
      ->expects($this
      ->any())
      ->method('getFieldDefinition')
      ->willReturn($field_definition_mock);
    $entity_mock = $this
      ->getMockBuilder('Drupal\\node\\Entity\\Node')
      ->disableOriginalConstructor()
      ->setMethods([
      'isNew',
      'getEntityTypeId',
      'bundle',
      'get',
    ])
      ->getMock();
    $entity_mock
      ->expects($this
      ->once())
      ->method('isNew')
      ->willReturn(FALSE);

    // Invoke 5 times: each entity type in each observer.
    $entity_mock
      ->expects($this
      ->exactly(5))
      ->method('getEntityTypeId')
      ->willReturn('node');

    // Invoke 3 times: each node bundle in each observer.
    $entity_mock
      ->expects($this
      ->exactly(3))
      ->method('bundle')
      ->willReturn('article');
    $entity_mock
      ->expects($this
      ->any())
      ->method('get')
      ->willReturn($field_item_list_mock);
    $original_entity_mock = $this
      ->getMockBuilder('Drupal\\node\\Entity\\Node')
      ->disableOriginalConstructor()
      ->setMethods([
      'get',
    ])
      ->getMock();
    $original_entity_mock
      ->expects($this
      ->any())
      ->method('get')
      ->willReturn($field_item_list_mock);
    $field_comparator_plugin_mock = $this
      ->getMockBuilder('Drupal\\changed_fields\\Plugin\\FieldComparator\\DefaultFieldComparator')
      ->disableOriginalConstructor()
      ->setMethods([
      'compareFieldValues',
    ])
      ->getMock();
    $field_comparator_plugin_mock
      ->expects($this
      ->any())
      ->method('compareFieldValues')
      ->willReturn([]);
    $this
      ->setProtectedProperty($entity_mock, 'fieldDefinitions', []);
    $this
      ->setProtectedProperty($this->entitySubject, 'entity', $entity_mock);
    $this
      ->setProtectedProperty($this->entitySubject, 'fieldComparatorPlugin', $field_comparator_plugin_mock);
    $entity_mock->original = $original_entity_mock;
    $this->entitySubject
      ->attach($observer_1);
    $this->entitySubject
      ->attach($observer_2);
    $this->entitySubject
      ->attach($observer_3);
    $this->entitySubject
      ->notify();
    $this
      ->assertTrue($entity_mock === $this->entitySubject
      ->getEntity());
    $this
      ->assertEquals([
      'title' => [],
      'body' => [],
    ], $this->entitySubject
      ->getChangedFields());
  }

  /**
   * Observer is not notified because node:article is new.
   *
   * Entity: node:article.
   */
  public function testNotifyNewEntity() {
    $observer = $this
      ->getMockBuilder('Drupal\\changed_fields\\ObserverInterface')
      ->setMethods([
      'getInfo',
      'update',
    ])
      ->getMock();
    $observer
      ->expects($this
      ->never())
      ->method('getInfo');
    $observer
      ->expects($this
      ->never())
      ->method('update');
    $entity_mock = $this
      ->getMockBuilder('Drupal\\node\\Entity\\Node')
      ->disableOriginalConstructor()
      ->setMethods([
      'isNew',
      'getEntityTypeId',
      'bundle',
    ])
      ->getMock();
    $entity_mock
      ->expects($this
      ->once())
      ->method('isNew')
      ->willReturn(TRUE);
    $entity_mock
      ->expects($this
      ->never())
      ->method('getEntityTypeId')
      ->willReturn('node');
    $entity_mock
      ->expects($this
      ->never())
      ->method('bundle')
      ->willReturn('article');
    $this
      ->setProtectedProperty($this->entitySubject, 'entity', $entity_mock);
    $this->entitySubject
      ->attach($observer);
    $this->entitySubject
      ->notify();
    $this
      ->assertTrue($entity_mock === $this->entitySubject
      ->getEntity());
    $this
      ->assertEquals(NULL, $this->entitySubject
      ->getChangedFields());
  }

}

Members

Namesort descending Modifiers Type Description Overrides
EntitySubjectTest::$entitySubject private property Content entity's subject.
EntitySubjectTest::setProtectedProperty public function Sets a protected property on a given object via reflection.
EntitySubjectTest::setUp public function Overrides UnitTestCase::setUp
EntitySubjectTest::testAttachMethod public function Entity subject can attach observers.
EntitySubjectTest::testDetachMethod public function Entity subject can detach observers.
EntitySubjectTest::testNotifyNewEntity public function Observer is not notified because node:article is new.
EntitySubjectTest::testNotifyObservers public function Observers 1 and 2 are notified. Observer 3 is not notified.
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.
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.