View source
<?php
namespace Drupal\Tests\radioactivity\Unit;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueInterface;
use Drupal\Core\State\StateInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\field\FieldStorageConfigInterface;
use Drupal\radioactivity\IncidentInterface;
use Drupal\radioactivity\IncidentStorageInterface;
use Drupal\radioactivity\RadioactivityProcessor;
use Drupal\radioactivity\RadioactivityProcessorInterface;
use Drupal\radioactivity\StorageFactory;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class RadioactivityProcessorTest extends UnitTestCase {
protected $sut;
protected $entityTypeManager;
protected $fieldStorageConfig;
protected $state;
protected $loggerFactory;
protected $loggerChannel;
protected $storage;
protected $incidentStorage;
protected $queueFactory;
protected $eventDispatcher;
protected $requestTime = 1000;
protected function setUp() : void {
parent::setUp();
$this->entityTypeManager = $this
->prophesize(EntityTypeManager::class);
$this->fieldStorageConfig = $this
->prophesize(EntityStorageInterface::class);
$this->entityTypeManager
->getStorage('field_storage_config')
->willReturn($this->fieldStorageConfig
->reveal());
$this->state = $this
->prophesize(StateInterface::class);
$loggerFactory = $this
->prophesize(LoggerChannelFactoryInterface::class);
$this->loggerChannel = $this
->prophesize(LoggerChannelInterface::class);
$loggerFactory
->get(RadioactivityProcessorInterface::LOGGER_CHANNEL)
->willReturn($this->loggerChannel
->reveal());
$this->storage = $this
->prophesize(StorageFactory::class);
$this->incidentStorage = $this
->prophesize(IncidentStorageInterface::class);
$this->storage
->getConfiguredStorage()
->willReturn($this->incidentStorage
->reveal());
$time = $this
->prophesize(TimeInterface::class);
$time
->getRequestTime()
->willReturn($this->requestTime);
$this->queueFactory = $this
->prophesize(QueueFactory::class);
$this->eventDispatcher = $this
->prophesize(EventDispatcherInterface::class);
$this->sut = new RadioactivityProcessor($this->entityTypeManager
->reveal(), $this->state
->reveal(), $loggerFactory
->reveal(), $this->storage
->reveal(), $time
->reveal(), $this->queueFactory
->reveal(), $this->eventDispatcher
->reveal());
}
public function testProcessDecayNoFields() {
$data = [];
$this->fieldStorageConfig
->loadByProperties([
'type' => 'radioactivity',
])
->willReturn($data);
$this->state
->set(RadioactivityProcessorInterface::LAST_PROCESSED_STATE_KEY, Argument::any())
->shouldNotBeCalled();
$this->loggerChannel
->notice(Argument::any())
->shouldNotBeCalled();
$this->sut
->processDecay();
}
public function testProcessDecayNoData() {
$profile = 'count';
$hasData = FALSE;
$resultCount = 0;
$configData = $this
->prophesize(FieldStorageConfig::class);
$configData
->getSetting('profile')
->willReturn($profile);
$configData
->hasData()
->willReturn($hasData);
$data = [
$configData
->reveal(),
];
$this->fieldStorageConfig
->loadByProperties([
'type' => 'radioactivity',
])
->willReturn($data);
$this->state
->set(RadioactivityProcessorInterface::LAST_PROCESSED_STATE_KEY, Argument::any())
->shouldNotBeCalled();
$this->loggerChannel
->notice('Processed @count radioactivity decays.', [
'@count' => $resultCount,
])
->shouldBeCalled();
$this->sut
->processDecay();
}
public function testProcessDecayCountProfile() {
$profile = 'count';
$hasData = TRUE;
$resultCount = 0;
$configData1 = $this
->prophesize(FieldStorageConfig::class);
$configData1
->getSetting('profile')
->willReturn($profile);
$configData1
->hasData()
->willReturn($hasData);
$data = [
$configData1
->reveal(),
];
$this->fieldStorageConfig
->loadByProperties([
'type' => 'radioactivity',
])
->willReturn($data);
$this->state
->set(RadioactivityProcessorInterface::LAST_PROCESSED_STATE_KEY, Argument::any())
->shouldNotBeCalled();
$this->loggerChannel
->notice('Processed @count radioactivity decays.', [
'@count' => $resultCount,
])
->shouldBeCalled();
$this->sut
->processDecay();
}
public function testQueueProcessDecay($profile, $halfLife, $cutoff, $initialEnergy, $elapsedTime, $isPublished, $resultEnergy) {
$fieldConfig = $this
->prophesize(FieldStorageConfigInterface::class);
$fieldConfig
->getTargetEntityTypeId()
->willReturn('entity_test');
$fieldConfig
->get('field_name')
->willReturn('ra_field');
$fieldConfig
->getSetting('profile')
->willReturn($profile);
$fieldConfig
->getSetting('halflife')
->willReturn($halfLife);
$fieldConfig
->getSetting('cutoff')
->willReturn($cutoff);
$fieldItemList = $this
->prophesize(FieldItemListInterface::class);
$fieldItemList
->getValue()
->willReturn([
[
'energy' => $initialEnergy,
'timestamp' => $this->requestTime - $elapsedTime,
],
]);
$fieldItemList
->setValue([
'energy' => $resultEnergy,
'timestamp' => $this->requestTime,
])
->shouldBeCalledTimes($isPublished ? 1 : 0);
$entityType = $this
->prophesize(EntityTypeInterface::class);
$entityType
->isRevisionable()
->willReturn(FALSE);
$entity = $this
->prophesize(PublishedContentEntityInterface::class);
$entity
->getEntityType()
->willReturn($entityType);
$entity
->isPublished()
->willReturn($isPublished);
$entity
->get('ra_field')
->willReturn($fieldItemList
->reveal());
$entity
->save()
->shouldBeCalledTimes($isPublished ? 1 : 0);
$entityStorage = $this
->prophesize(EntityStorageInterface::class);
$entityStorage
->loadMultiple([
123,
])
->willReturn([
$entity
->reveal(),
]);
$this->entityTypeManager
->getStorage('entity_test')
->willReturn($entityStorage
->reveal());
$this->sut
->queueProcessDecay($fieldConfig
->reveal(), [
123,
]);
}
public function providerQueueProcessDecay() {
return [
[
'count',
10,
10,
100,
10,
TRUE,
100,
],
[
'linear',
10,
10,
100,
0,
TRUE,
100,
],
[
'linear',
10,
10,
100,
10,
TRUE,
90,
],
[
'linear',
10,
10,
100,
90,
TRUE,
0,
],
[
'decay',
10,
10,
100,
0,
TRUE,
100,
],
[
'decay',
10,
10,
100,
10,
TRUE,
50,
],
[
'decay',
10,
10,
100,
20,
TRUE,
25,
],
[
'decay',
10,
30,
100,
20,
TRUE,
0,
],
[
'decay',
5,
10,
100,
10,
TRUE,
25,
],
[
'count',
10,
10,
100,
10,
FALSE,
0,
],
[
'linear',
10,
10,
100,
10,
FALSE,
100,
],
[
'decay',
10,
10,
100,
10,
FALSE,
100,
],
];
}
public function testProcessIncidents() {
$incidentsByType['entity_type_a'] = [
'incidentA1',
'incidentA2',
'incidentA3',
];
$incidentsByType['entity_type_b'] = [
'incidentB1',
'incidentB2',
'incidentB3',
'incidentB4',
'incidentB5',
'incidentB6',
'incidentB7',
'incidentB8',
'incidentB9',
'incidentB10',
'incidentB11',
'incidentB12',
];
$this->incidentStorage
->getIncidentsByType()
->willReturn($incidentsByType);
$this->incidentStorage
->clearIncidents()
->shouldBeCalled();
$queue = $this
->prophesize(QueueInterface::class);
$this->queueFactory
->get(RadioactivityProcessorInterface::QUEUE_WORKER_INCIDENTS)
->willReturn($queue
->reveal());
$queue
->createItem([
'entity_type' => 'entity_type_a',
'incidents' => [
0 => 'incidentA1',
1 => 'incidentA2',
2 => 'incidentA3',
],
])
->shouldBeCalledTimes(1);
$queue
->createItem([
'entity_type' => 'entity_type_b',
'incidents' => [
0 => 'incidentB1',
1 => 'incidentB2',
2 => 'incidentB3',
3 => 'incidentB4',
4 => 'incidentB5',
5 => 'incidentB6',
6 => 'incidentB7',
7 => 'incidentB8',
8 => 'incidentB9',
9 => 'incidentB10',
],
])
->shouldBeCalledTimes(1);
$queue
->createItem([
'entity_type' => 'entity_type_b',
'incidents' => [
10 => 'incidentB11',
11 => 'incidentB12',
],
])
->shouldBeCalledTimes(1);
$this->loggerChannel
->notice('Processed @count radioactivity incidents.', [
'@count' => 15,
])
->shouldBeCalled();
$this->sut
->processIncidents();
}
public function testQueueProcessIncidents($isRevisonable, $initialEnergy, $emittedEnergy, $resultEnergy) {
$energyField = (object) [
'energy' => $initialEnergy,
'timestamp' => $this->requestTime,
];
$entityType = $this
->prophesize(EntityTypeInterface::class);
$entityType
->isRevisionable()
->willReturn($isRevisonable);
$entity = $this
->prophesize(PublishedContentEntityInterface::class);
$entity
->getEntityType()
->willReturn($entityType);
$entity
->id()
->willReturn(123);
$entity
->get('ra_field')
->willReturn($energyField);
$entity
->setNewRevision(FALSE)
->shouldBeCalledTimes($isRevisonable ? 1 : 0);
$entity
->save()
->shouldBeCalled();
$entityStorage = $this
->prophesize(EntityStorageInterface::class);
$entityStorage
->loadMultiple([
123,
])
->willReturn([
$entity
->reveal(),
]);
$this->entityTypeManager
->getStorage('entity_test')
->willReturn($entityStorage
->reveal());
$incident = $this
->prophesize(IncidentInterface::class);
$incident
->getFieldName()
->willReturn('ra_field');
$incident
->getEnergy()
->willReturn($emittedEnergy);
$this->sut
->queueProcessIncidents('entity_test', [
123 => $incident,
]);
}
public function providerQueueProcessIncidents() {
return [
[
TRUE,
0,
10,
10,
],
[
FALSE,
0,
10,
10,
],
];
}
}
interface PublishedContentEntityInterface extends ContentEntityInterface, EntityPublishedInterface {
}