entity_change_notifier-8.x-1.0/tests/src/Kernel/EntityPublisherTest.php

tests/src/Kernel/EntityPublisherTest.php
<?php

namespace Drupal\Tests\entity_change_notifier\Kernel;

use Drupal\entity_change_notifier\Plugin\MessageDestination\MessageDestinationInterface;
use Drupal\entity_change_notifier\Plugin\MessageDestination\MessageGenerator;
use Drupal\entity_change_notifier\Plugin\MessageDestination\NotifyException;
use Drupal\file\Entity\File;
use Drupal\KernelTests\KernelTestBase;
use Drupal\node\Entity\Node;
use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\BufferingLogger;

/**
 * Tests publishing entities to destinations.
 *
 * The EntityPublisher class is currently very simple, and just wraps calling
 * individual publishers in a loop. Since unit testing entities is very painful
 * (they don't support injection), we mark multiple classes as being covered
 * here. If EntityPublisher becomes more complex, we should split out it's tests
 * from those that cover Publisher itself.
 *
 * @group entity_change_notifier
 *
 * @coversDefaultClass Drupal\entity_change_notifier\EntityPublisher
 */
class EntityPublisherTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'system',
    'field',
    'node',
    'file',
    'text',
    'user',
    'serialization',
    'jsonapi',
    'entity_change_notifier',
    'entity_change_notifier_test',
  ];

  /**
   * {@inheritdoc}
   */
  public function setUp() {
    parent::setUp();
    $this->installSchema('node', 'node_access');
    $this->installEntitySchema('user');
    $this->installEntitySchema('node');
    $this->installEntitySchema('file');
    $this->installConfig(['node', 'file']);
    $this->installConfig(['entity_change_notifier_test']);
  }

  /**
   * Test firing of inserts on hook_entity_insert.
   *
   * @covers ::notifyMultiple
   * @covers \Drupal\entity_change_notifier\Entity\Publisher::notify
   */
  public function testNotifyInsert() {
    $logger = new BufferingLogger();
    $this->container->get('logger.factory')->addLogger($logger);

    $node = Node::create([
      'type' => 'ecn_test',
      'title' => $this->randomString(),
    ]);
    $node->save();

    $logs = $logger->cleanLogs();
    $this->assertCount(2, $logs);
    $this->assertEquals(MessageDestinationInterface::ENTITY_INSERT, $logs[0][2]['%action']);
  }

  /**
   * Test firing of updates on hook_entity_update.
   *
   * @covers ::notifyMultiple
   * @covers \Drupal\entity_change_notifier\Entity\Publisher::notify
   */
  public function testNotifyUpdate() {
    $node = Node::create([
      'type' => 'ecn_test',
      'title' => $this->randomString(),
    ]);
    $node->save();

    $logger = new BufferingLogger();
    $this->container->get('logger.factory')->addLogger($logger);
    $node->save();

    $logs = $logger->cleanLogs();
    $this->assertCount(2, $logs);
    $this->assertEquals(MessageDestinationInterface::ENTITY_UPDATE, $logs[0][2]['%action']);
  }

  /**
   * Test notifying for URI-less entities.
   *
   * @covers \Drupal\entity_change_notifier\Entity\Publisher::notify
   */
  public function testNotifyNoUri() {
    // Turn on notifications for files.
    /** @var \Drupal\entity_change_notifier\Entity\PublisherInterface $publisher */
    $publisher = $this->container->get('entity_type.manager')->getStorage('ecn_publisher')->load('test_publisher');
    $publisher->setPublishTypes(['file' => ['file']]);
    $publisher->save();

    $file = File::create([
      'type' => 'file',
      'title' => $this->randomString(),
      'uri' => 'core/misc/druplicon.png',
    ]);
    $file->save();

    $logger = new BufferingLogger();
    $this->container->get('logger.factory')->addLogger($logger);
    $file->save();

    $logs = $logger->cleanLogs();
    $this->assertCount(2, $logs);
    $this->assertEquals(MessageDestinationInterface::ENTITY_UPDATE, $logs[0][2]['%action']);
    $this->assertEmpty($logs[1][2]['link']);
  }

  /**
   * Test firing of updates on hook_entity_delete.
   *
   * @covers ::notifyMultiple
   * @covers \Drupal\entity_change_notifier\Entity\Publisher::notify
   */
  public function testNotifyDelete() {
    $node = Node::create([
      'type' => 'ecn_test',
      'title' => $this->randomString(),
    ]);
    $node->save();

    $logger = new BufferingLogger();
    $this->container->get('logger.factory')->addLogger($logger);
    $node->delete();

    $logs = $logger->cleanLogs();
    $this->assertCount(2, $logs);
    $this->assertEquals(MessageDestinationInterface::ENTITY_DELETE, $logs[0][2]['%action']);
  }

  /**
   * Test queuing retry on failure.
   *
   * @covers ::notifyMultiple
   * @covers ::logRetry
   * @covers ::watchdogException
   * @covers \Drupal\entity_change_notifier\Entity\Publisher::notify
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::__construct
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::fromNotifyException
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::fromNotifyException
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::getExpires
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::getData
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::getMessageDestinationEntityId
   */
  public function testQueueRetry() {
    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */
    $logger = $this->getMockBuilder(LoggerInterface::class)
      ->disableOriginalConstructor()
      ->getMock();

    $logger->expects($this->any())->method('error')->willReturn(NULL);
    $logger->expects($this->any())->method('warning')->willReturn(NULL);
    $logger->expects($this->at(0))->method('log')->willThrowException(new \Exception('logging error'));
    $logger->expects($this->at(1))->method('log')->willReturn(TRUE);
    $this->container->get('logger.factory')->addLogger($logger);

    $node = Node::create([
      'type' => 'ecn_test',
      'title' => $this->randomString(),
    ]);
    $node->save();
    $queue = \Drupal::queue('entity_change_notifier_retry');
    $size = (int) $queue->numberOfItems();
    $this->assertSame(1, $size);

    $item = $queue->claimItem();
    /** @var \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem $failedItem */
    $failedItem = $item->data;
    $this->assertEquals($this->container->get('datetime.time')->getRequestTime() + 86400, $failedItem->getExpires());
    $this->assertEquals('test_destination', $failedItem->getMessageDestinationEntityId());
    $expected = [
      '%action' => 'insert',
      '%uri' => 'http://localhost/jsonapi/node/ecn_test/' . $node->uuid(),
      '%entity_id' => $node->id(),
      '%entity_uuid' => $node->uuid(),
      '%entity_type' => 'node',
      '%bundle' => 'ecn_test',
      'link' => '<a href="http://localhost/jsonapi/node/ecn_test/' . $node->uuid() . '">View</a>',
      'action' => 'insert',
      'uri' => 'http://localhost/jsonapi/node/ecn_test/' . $node->uuid(),
      'entity_id' => $node->id(),
      'entity_uuid' => $node->uuid(),
      'entity_type' => 'node',
      'bundle' => 'ecn_test',
    ];
    $data = $failedItem->getData();
    $data['link'] = (string) $data['link'];
    $this->assertEquals($expected, $data);
  }

  /**
   * Test queuing retry for URL-less entities.
   *
   * @covers ::logRetry
   */
  public function testQueueRetryNoCanonical() {
    $logger = new BufferingLogger();
    $this->container->get('logger.factory')->addLogger($logger);

    $file = File::create([
      'type' => 'file',
      'title' => $this->randomString(),
      'uri' => 'core/misc/druplicon.png',
    ]);
    $file->save();

    $publisher = $this->container->get('entity_change_notifier.entity_publisher');
    /** @var \Drupal\entity_change_notifier\Entity\DestinationInterface $destination */
    $generator = new MessageGenerator($this->container->get('jsonapi.link_manager'));
    $message = $generator->createMessage(MessageDestinationInterface::ENTITY_INSERT, $file);
    $exception = new NotifyException($message, new \Exception('Such failure'), 'test_destination');
    $destination = $this->container->get('entity_type.manager')->getStorage('ecn_destination')->load('test_destination');
    $publisher->logRetry($destination, $exception, $file);

    $logs = $logger->cleanLogs();
    $this->assertEmpty($logs[0][2]['link']);
  }

  /**
   * Test setting a custom retry expiry time.
   *
   * @covers ::notifyMultiple
   * @covers ::logRetry
   * @covers \Drupal\entity_change_notifier\Entity\Publisher::notify
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::__construct
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::fromNotifyException
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::fromNotifyException
   * @covers \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem::getExpires
   */
  public function testSetQueueRetry() {
    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */
    $logger = $this->getMockBuilder(LoggerInterface::class)
      ->disableOriginalConstructor()
      ->getMock();

    $logger->expects($this->any())->method('error')->willReturn(NULL);
    $logger->expects($this->any())->method('warning')->willReturn(NULL);
    $logger->expects($this->at(0))->method('log')->willThrowException(new \Exception('logging error'));
    $logger->expects($this->at(1))->method('log')->willReturn(TRUE);

    $this->container->get('logger.factory')->addLogger($logger);

    /** @var \Drupal\entity_change_notifier\Entity\DestinationInterface $destination */
    $destination = $this->container->get('entity_type.manager')->getStorage('ecn_destination')->load('test_destination');

    // Override the expiry to one second.
    $destination->setMessageExpiry(1);
    $destination->save();

    $node = Node::create([
      'type' => 'ecn_test',
      'title' => $this->randomString(),
    ]);
    $node->save();
    $queue = \Drupal::queue('entity_change_notifier_retry');
    $size = (int) $queue->numberOfItems();
    $this->assertSame(1, $size);

    $item = $queue->claimItem();
    /** @var \Drupal\entity_change_notifier\Plugin\QueueWorker\FailedItem $failedItem */
    $failedItem = $item->data;
    $this->assertEquals($this->container->get('datetime.time')->getRequestTime() + 1, $failedItem->getExpires());
  }

  /**
   * Test that we can retry a failed notification.
   *
   * @covers ::retryNotification
   */
  public function testRetryNotification() {
    $node = Node::create([
      'type' => 'ecn_test',
      'title' => $this->randomString(),
    ]);
    $node->save();

    $message = [
      'action' => MessageDestinationInterface::ENTITY_INSERT,
      'uri' => $node->toUrl()->toString(),
      'entity_id' => $node->id(),
      'entity_uuid' => $node->uuid(),
      'entity_type' => 'node',
      'bundle' => 'ecn_test',
    ];

    /** @var \Drupal\entity_change_notifier\Entity\DestinationInterface $destination */
    $destination = $this->container->get('entity_type.manager')->getStorage('ecn_destination')->load('test_destination');

    $logger = new BufferingLogger();
    $this->container->get('logger.factory')->addLogger($logger);

    $publisher = $this->container->get('entity_change_notifier.entity_publisher');
    $publisher->retryNotification($destination, $message);

    $logs = $logger->cleanLogs();
    $this->assertCount(1, $logs);
  }

  /**
   * Test that we can retry a failed notification.
   *
   * @covers ::retryNotification
   */
  public function testRetryNotificationFails() {
    $node = Node::create([
      'type' => 'ecn_test',
      'title' => $this->randomString(),
    ]);
    $node->save();

    $message = [
      'action' => MessageDestinationInterface::ENTITY_INSERT,
      'uri' => $node->toUrl()->toString(),
      'entity_id' => $node->id(),
      'entity_uuid' => $node->uuid(),
      'entity_type' => 'node',
      'bundle' => 'ecn_test',
    ];

    /** @var \Drupal\entity_change_notifier\Entity\DestinationInterface $destination */
    $destination = $this->container->get('entity_type.manager')->getStorage('ecn_destination')->load('test_destination');

    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */
    $logger = $this->getMockBuilder(LoggerInterface::class)
      ->disableOriginalConstructor()
      ->getMock();

    $logger->expects($this->at(0))->method('log')->willThrowException(new \Exception('logging error'));

    $this->container->get('logger.factory')->addLogger($logger);

    $publisher = $this->container->get('entity_change_notifier.entity_publisher');

    $this->setExpectedException(NotifyException::class, 'Unable to log the notification.');
    $publisher->retryNotification($destination, $message);
  }

}

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

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