View source
<?php
namespace Drupal\Tests\acquia_contenthub\Unit\EventSubscriber\HandleWebhook;
use Acquia\ContentHubClient\ContentHubClient;
use Acquia\ContentHubClient\Settings;
use Acquia\Hmac\Key;
use Drupal\acquia_contenthub\Client\ClientFactory;
use Drupal\acquia_contenthub\Event\HandleWebhookEvent;
use Drupal\acquia_contenthub_subscriber\EventSubscriber\HandleWebhook\DeleteAssets;
use Drupal\acquia_contenthub_subscriber\SubscriberTracker;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityBase;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use Symfony\Component\HttpFoundation\Request;
class DeleteAssetsTest extends UnitTestCase {
private const STATUS_SUCCESSFUL = 'successful';
private const OPERATION_DELETE = 'delete';
private const CLIENT_UUID = 'some-client-uuid';
private const INITIATOR_UUID = 'some-initiator-uuid';
private const EXISTING_ENTITY_UUID = 'some-existing-entity-uuid';
private const NON_EXISTING_ENTITY_UUID = 'some-non-existing-entity-uuid';
private const EXISTING_DISCONNECTED_ENTITY_UUID = 'some-existing-disconnected-entity-uuid';
private const ASSET_TYPE_D8_CONTENT_ENTITY = 'drupal8_content_entity';
private const WEBHOOK_UUID = 'webhook-uuid';
private $entity;
private $contentHubSettings;
private $contentHubClient;
private $clientFactory;
protected $configFactory;
private $key;
private $request;
private $tracker;
public function setUp() {
$this->entity = $this
->prophesize(EntityBase::class);
$entity = $this->entity;
$this->contentHubSettings = $this
->prophesize(Settings::class);
$this->contentHubSettings
->getUuid()
->willReturn(self::CLIENT_UUID);
$this->contentHubSettings
->getWebhook("uuid")
->willReturn(self::WEBHOOK_UUID);
$this->contentHubClient = $this
->prophesize(ContentHubClient::class);
$this->contentHubClient
->getSettings()
->willReturn($this->contentHubSettings);
$this->clientFactory = $this
->prophesize(ClientFactory::class);
$this->clientFactory
->getClient()
->willReturn($this->contentHubClient);
$this->configFactory = $this
->prophesize(ConfigFactoryInterface::class);
$config = $this
->prophesize(Config::class);
$config
->get(Argument::any())
->willReturn(TRUE);
$this->configFactory
->getEditable(Argument::any())
->willReturn($config
->reveal());
$this->key = new Key('id', 'secret');
$this->request = $this
->prophesize(Request::class)
->reveal();
$this->tracker = $this
->prophesize(SubscriberTracker::class);
$this->tracker
->delete(Argument::type('string'));
$this->tracker
->getEntityByRemoteIdAndHash(Argument::type('string'))
->will(function ($uuid) use ($entity) {
switch (current($uuid)) {
case self::NON_EXISTING_ENTITY_UUID:
return NULL;
case self::EXISTING_ENTITY_UUID:
return $entity;
case self::EXISTING_DISCONNECTED_ENTITY_UUID:
return $entity;
}
});
$this->tracker
->getStatusByUuid(Argument::type('string'))
->will(function ($uuid) {
switch (current($uuid)) {
case self::EXISTING_DISCONNECTED_ENTITY_UUID:
return SubscriberTracker::AUTO_UPDATE_DISABLED;
default:
return SubscriberTracker::IMPORTED;
}
});
}
public function testNonSuccessfulStatus() : void {
$payload = [
'status' => 'some-status',
'crud' => self::OPERATION_DELETE,
'initiator' => self::INITIATOR_UUID,
'assets' => [
[
'type' => self::ASSET_TYPE_D8_CONTENT_ENTITY,
'uuid' => self::EXISTING_ENTITY_UUID,
],
],
];
$this
->triggerEvent($this
->createEvent($payload));
$this
->assertNoOperationShouldBeDone();
}
public function testNonDeleteCrud() : void {
$payload = [
'status' => self::STATUS_SUCCESSFUL,
'crud' => 'some-funny-operation',
'initiator' => self::INITIATOR_UUID,
'assets' => [
[
'type' => self::ASSET_TYPE_D8_CONTENT_ENTITY,
'uuid' => self::EXISTING_ENTITY_UUID,
],
],
];
$this
->triggerEvent($this
->createEvent($payload));
$this
->assertNoOperationShouldBeDone();
}
public function testInitiatorSameAsClient() : void {
$payload = [
'status' => self::STATUS_SUCCESSFUL,
'crud' => self::OPERATION_DELETE,
'initiator' => self::CLIENT_UUID,
'assets' => [
[
'type' => self::ASSET_TYPE_D8_CONTENT_ENTITY,
'uuid' => self::EXISTING_ENTITY_UUID,
],
],
];
$this
->triggerEvent($this
->createEvent($payload));
$this
->assertNoOperationShouldBeDone();
}
public function testAnEmptyAssetList() : void {
$payload = [
'status' => self::STATUS_SUCCESSFUL,
'crud' => self::OPERATION_DELETE,
'initiator' => self::INITIATOR_UUID,
'assets' => [],
];
$this
->triggerEvent($this
->createEvent($payload));
$this
->assertNoOperationShouldBeDone();
}
public function testUnsupportedAssetType() : void {
$payload = [
'status' => self::STATUS_SUCCESSFUL,
'crud' => self::OPERATION_DELETE,
'initiator' => self::INITIATOR_UUID,
'assets' => [
[
'type' => 'some_unsupported_type',
'uuid' => self::EXISTING_ENTITY_UUID,
],
],
];
$this
->triggerEvent($this
->createEvent($payload));
$this
->assertNoOperationShouldBeDone();
}
public function testNonExistingEntity() : void {
$payload = [
'status' => self::STATUS_SUCCESSFUL,
'crud' => self::OPERATION_DELETE,
'initiator' => self::INITIATOR_UUID,
'assets' => [
[
'type' => self::ASSET_TYPE_D8_CONTENT_ENTITY,
'uuid' => self::NON_EXISTING_ENTITY_UUID,
],
],
];
$this->tracker
->delete(self::NON_EXISTING_ENTITY_UUID)
->shouldBeCalledTimes(1);
$this->contentHubClient
->deleteInterest(self::NON_EXISTING_ENTITY_UUID, self::WEBHOOK_UUID)
->shouldBeCalledTimes(1);
$this->entity
->delete()
->shouldNotBeCalled();
$this
->triggerEvent($this
->createEvent($payload));
}
public function testDeletionOfAnExistingEntity() : void {
$payload = [
'status' => self::STATUS_SUCCESSFUL,
'crud' => self::OPERATION_DELETE,
'initiator' => self::INITIATOR_UUID,
'assets' => [
[
'type' => self::ASSET_TYPE_D8_CONTENT_ENTITY,
'uuid' => self::EXISTING_ENTITY_UUID,
],
],
];
$this
->triggerEvent($this
->createEvent($payload));
$this->tracker
->getEntityByRemoteIdAndHash(self::EXISTING_ENTITY_UUID)
->shouldBeCalledTimes(1);
$this->tracker
->getStatusByUuid(self::EXISTING_ENTITY_UUID)
->shouldBeCalledTimes(1);
$this->entity
->delete()
->shouldBeCalledTimes(1);
}
public function testDeletionOfAnExistingDisconnectedEntity() : void {
$payload = [
'status' => self::STATUS_SUCCESSFUL,
'crud' => self::OPERATION_DELETE,
'initiator' => self::INITIATOR_UUID,
'assets' => [
[
'type' => self::ASSET_TYPE_D8_CONTENT_ENTITY,
'uuid' => self::EXISTING_DISCONNECTED_ENTITY_UUID,
],
],
];
$this->tracker
->delete(self::EXISTING_DISCONNECTED_ENTITY_UUID)
->shouldBeCalledTimes(1);
$this
->triggerEvent($this
->createEvent($payload));
$this->tracker
->getEntityByRemoteIdAndHash(self::EXISTING_DISCONNECTED_ENTITY_UUID)
->shouldBeCalledTimes(1);
$this->tracker
->getStatusByUuid(self::EXISTING_DISCONNECTED_ENTITY_UUID)
->shouldBeCalledTimes(1);
$this->entity
->delete()
->shouldNotBeCalled();
}
private function createEvent(array $payload) : HandleWebhookEvent {
return new HandleWebhookEvent($this->request, $payload, $this->key, $this->contentHubClient
->reveal());
}
private function triggerEvent(HandleWebhookEvent $event) : void {
(new DeleteAssets($this->tracker
->reveal(), $this->configFactory
->reveal()))
->onHandleWebhook($event);
}
private function assertNoOperationShouldBeDone() : void {
$this->tracker
->getEntityByRemoteIdAndHash()
->shouldNotBeCalled();
$this->tracker
->delete()
->shouldNotBeCalled();
$this->entity
->delete()
->shouldNotBeCalled();
}
}