From 8446c20e161c258268fe4284215842ce26f506bf Mon Sep 17 00:00:00 2001 From: Jonathan Hedstrom Date: Thu, 16 Mar 2017 11:17:17 -0700 Subject: [PATCH] Convert message subscribe to DeliveryCandidate. - Converts all message_subscribe implementations to use the DeliveryCandidate object rather than arrays. --- message_subscribe.api.php | 14 +- message_subscribe.module | 4 +- src/Subscribers.php | 16 +- src/Subscribers/DeliveryCandidate.php | 44 +- .../DeliveryCandidateInterface.php | 44 ++ src/SubscribersInterface.php | 15 +- .../message_subscribe_test.module | 13 +- tests/src/Kernel/QueueTest.php | 6 +- tests/src/Kernel/SubscribersTest.php | 72 +-- .../Subscribers/DeliveryCandidateTest.php | 84 ++++ tests/src/Unit/SubscribersTest.php | 409 +++++++++--------- tests/src/Unit/fixture_foo.module.php | 26 ++ 12 files changed, 414 insertions(+), 333 deletions(-) create mode 100644 tests/src/Unit/Subscribers/DeliveryCandidateTest.php create mode 100644 tests/src/Unit/fixture_foo.module.php diff --git a/message_subscribe.api.php b/message_subscribe.api.php index 200f4d6..fcf3010 100644 --- a/message_subscribe.api.php +++ b/message_subscribe.api.php @@ -27,13 +27,8 @@ * value. According to this context this function will retrieve the * related subscribers. * - * @return \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface[]|array - * Array of delivery candidate objects keyed with the user ID, or an array of - * arrays with the value (array usage is deprecated and will be removed in - * 2.0): - * - "flags": Array with the flag names that resulted with including - * the user. - * - "notifiers": Array with the Message notifier name plugins. + * @return \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface[] + * An array, keyed by recipeint user ID, of delivery candidate objects. */ function hook_message_subscribe_get_subscribers(MessageInterface $message, array $subscribe_options = [], array $context = []) { return [ @@ -45,10 +40,9 @@ function hook_message_subscribe_get_subscribers(MessageInterface $message, array /** * Alter the subscribers list. * - * @param \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface[]|array &$uids + * @param \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface[] &$uids * The array of delivery candidates as defined by - * `hook_message_subscribe_get_subscribers()`. This can also be an array of - * arrays, but is deprecated. + * `hook_message_subscribe_get_subscribers()`. * @param array $values * A keyed array of values containing: * - 'context' - The context array. diff --git a/message_subscribe.module b/message_subscribe.module index 0d92d5e..7da2c65 100755 --- a/message_subscribe.module +++ b/message_subscribe.module @@ -60,9 +60,7 @@ function message_subscribe_message_subscribe_get_subscribers(MessageInterface $m $uids[$row->uid] = !empty($uids[$row->uid]) ? $uids[$row->uid] : new DeliveryCandidate([], [], $row->uid); // Register the flag name. - $flags = $uids[$row->uid]->getFlags(); - $flags[] = $row->flag_id; - $uids[$row->uid]->setFlags(array_unique($flags)); + $uids[$row->uid]->addFlag($row->flag_id); if ($range) { --$range; diff --git a/src/Subscribers.php b/src/Subscribers.php index e5e990e..96c24e4 100644 --- a/src/Subscribers.php +++ b/src/Subscribers.php @@ -14,8 +14,6 @@ use Drupal\message\MessageInterface; use Drupal\message_notify\MessageNotifier; use Drupal\message_subscribe\Exception\MessageSubscribeException; -use Drupal\message_subscribe\Subscribers\DeliveryCandidate; -use Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface; use Drupal\og\MembershipManagerInterface; use Drupal\user\EntityOwnerInterface; @@ -182,13 +180,6 @@ public function sendMessage(EntityInterface $entity, MessageInterface $message, } foreach ($uids as $uid => $delivery_candidate) { - // Array usage is deprecated, but supported until 2.0. - if (!$delivery_candidate instanceof DeliveryCandidateInterface) { - trigger_error('Usage of arrays in subscriber information is deprecated and will be removed in Message Subscribe 2.0. Use a DeliveryCandidate object instead.', E_USER_DEPRECATED); - $delivery_candidate += ['notifiers' => []]; - $delivery_candidate = new DeliveryCandidate($delivery_candidate['flags'], $delivery_candidate['notifiers'], $uid); - } - $last_uid = $uid; // Clone the message in case it will need to be saved, it won't // overwrite the existing one. @@ -419,7 +410,7 @@ public function getBasicContext(EntityInterface $entity, $skip_detailed_context /** * Get the default notifiers for a given set of users. * - * @param array &$uids + * @param \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface[] &$uids * An array detailing notification info for users. */ protected function addDefaultNotifiers(array &$uids) { @@ -429,9 +420,10 @@ protected function addDefaultNotifiers(array &$uids) { } // Use notifier names as keys to avoid potential duplication of notifiers // by other modules' hooks. - $notifiers = array_combine($notifiers, $notifiers); foreach (array_keys($uids) as $uid) { - $uids[$uid]['notifiers'] += $notifiers; + foreach ($notifiers as $notifier) { + $uids[$uid]->addNotifier($notifier); + } } } diff --git a/src/Subscribers/DeliveryCandidate.php b/src/Subscribers/DeliveryCandidate.php index 85c22ec..5980802 100644 --- a/src/Subscribers/DeliveryCandidate.php +++ b/src/Subscribers/DeliveryCandidate.php @@ -12,14 +12,14 @@ class DeliveryCandidate implements DeliveryCandidateInterface { * * @var string[] */ - protected $flags; + protected $flags = []; /** * An array of notifier IDs for delivery. * * @var string[] */ - protected $notifiers; + protected $notifiers = []; /** * The delivery candidate account ID. @@ -39,11 +39,43 @@ class DeliveryCandidate implements DeliveryCandidateInterface { * The delivery candidate account ID. */ public function __construct(array $flags, array $notifiers, $uid) { - $this->flags = $flags; - $this->notifiers = $notifiers; + $this->flags = array_combine($flags, $flags); + $this->notifiers = array_combine($notifiers, $notifiers); $this->uid = $uid; } + /** + * {@inheritdoc} + */ + public function addFlag($flag_id) { + $this->flags[$flag_id] = $flag_id; + return $this; + } + + /** + * {@inheritdoc} + */ + public function removeFlag($flag_id) { + unset($this->flags[$flag_id]); + return $this; + } + + /** + * {@inheritdoc} + */ + public function addNotifier($notifier_id) { + $this->notifiers[$notifier_id] = $notifier_id; + return $this; + } + + /** + * {@inheritdoc} + */ + public function removeNotifier($notifier_id) { + unset($this->notifiers[$notifier_id]); + return $this; + } + /** * {@inheritdoc} */ @@ -55,7 +87,7 @@ public function getFlags() { * {@inheritdoc} */ public function setFlags(array $flag_ids) { - $this->flags = $flag_ids; + $this->flags = array_combine($flag_ids, $flag_ids); return $this; } @@ -70,7 +102,7 @@ public function getNotifiers() { * {@inheritdoc} */ public function setNotifiers(array $notifier_ids) { - $this->notifiers = $notifier_ids; + $this->notifiers = array_combine($notifier_ids, $notifier_ids); return $this; } diff --git a/src/Subscribers/DeliveryCandidateInterface.php b/src/Subscribers/DeliveryCandidateInterface.php index 6fa01e4..4e47d3d 100644 --- a/src/Subscribers/DeliveryCandidateInterface.php +++ b/src/Subscribers/DeliveryCandidateInterface.php @@ -26,6 +26,28 @@ public function getFlags(); */ public function setFlags(array $flag_ids); + /** + * Adds a flag. + * + * @param string $flag_id + * The flag ID to add. + * + * @return static + * Return the object. + */ + public function addFlag($flag_id); + + /** + * Remove a flag. + * + * @param string $flag_id + * The flag ID to remove. + * + * @return static + * Return the object. + */ + public function removeFlag($flag_id); + /** * Get the notifier IDs. * @@ -45,6 +67,28 @@ public function getNotifiers(); */ public function setNotifiers(array $notifier_ids); + /** + * Adds a notifier. + * + * @param string $notifier_id + * The notifier ID to add. + * + * @return static + * Return the object. + */ + public function addNotifier($notifier_id); + + /** + * Remove a notifier. + * + * @param string $notifier_id + * The notifier ID to remove. + * + * @return static + * Return the object. + */ + public function removeNotifier($notifier_id); + /** * Gets the account ID of the recipient. * diff --git a/src/SubscribersInterface.php b/src/SubscribersInterface.php index c745799..2971e2b 100644 --- a/src/SubscribersInterface.php +++ b/src/SubscribersInterface.php @@ -89,18 +89,9 @@ public function sendMessage(EntityInterface $entity, MessageInterface $message, * (optional) The context array, passed by reference. This has the same * elements as the `$context` paramater for `self::sendMessage()`. * - * @return array - * Array keyed with the user IDs to send notifications to, and an array with - * the flags used for the subscription, and the notifier names to use. - * - * @code - * array( - * 1 => array( - * 'flags' => array('subscribe_node', 'subscribe_og'), - * 'notifiers' => array('email', 'sms'), - * ), - * ); - * @endcode + * @return \Drupal\message_subscribe\Subscribers\DeliveryCandidateInterface[] + * Array of delivery candidate objects keyed with the user IDs to send + * notifications to. */ public function getSubscribers(EntityInterface $entity, MessageInterface $message, array $options = [], array &$context = []); diff --git a/tests/modules/message_subscribe_test/message_subscribe_test.module b/tests/modules/message_subscribe_test/message_subscribe_test.module index 47d883b..3257770 100644 --- a/tests/modules/message_subscribe_test/message_subscribe_test.module +++ b/tests/modules/message_subscribe_test/message_subscribe_test.module @@ -30,18 +30,7 @@ function message_subscribe_test_message_subscribe_get_subscribers_alter(array &$ \Drupal::state('message_subscribe_test')->set('alter_hook_called', TRUE); if (!\Drupal::state('message_subscribe_test')->get('disable_subscribers_alter', FALSE)) { - // Add non-existent user 10001. - if (\Drupal::state('message_subscribe_test')->get('use_array', FALSE)) { - // Test to ensure array usage still works (it will throw a deprecated - // notice). - $uids[10001] = [ - 'flags' => ['bar_flag'], - 'notifiers' => ['email'], - ]; - } - else { - $uids[10001] = new DeliveryCandidate(['bar_flag'], ['email'], 10001); - } + $uids[10001] = new DeliveryCandidate(['bar_flag'], ['email'], 10001); // Remove user 2. unset($uids[2]); diff --git a/tests/src/Kernel/QueueTest.php b/tests/src/Kernel/QueueTest.php index 7599a0e..13542d4 100644 --- a/tests/src/Kernel/QueueTest.php +++ b/tests/src/Kernel/QueueTest.php @@ -5,6 +5,7 @@ use Drupal\message\Entity\Message; use Drupal\message\Entity\MessageTemplate; use Drupal\message_subscribe\Exception\MessageSubscribeException; +use Drupal\message_subscribe\Subscribers\DeliveryCandidate; /** * Test queue integration. @@ -77,7 +78,10 @@ public function testQueue() { } // Assert message was saved and added to queue. - $uids = array_fill(1, 10, ['flags' => [], 'notifiers' => []]); + $uids = array_fill(1, 10, new DeliveryCandidate([], [], 1)); + foreach ($uids as $uid => $candidate) { + $candidate->setAccountId($uid); + } $subscribe_options = [ 'uids' => $uids, 'skip context' => TRUE, diff --git a/tests/src/Kernel/SubscribersTest.php b/tests/src/Kernel/SubscribersTest.php index 6bc3534..90bab93 100644 --- a/tests/src/Kernel/SubscribersTest.php +++ b/tests/src/Kernel/SubscribersTest.php @@ -135,13 +135,7 @@ public function testGetSubscribers() { // Assert subscribers data. $expected_uids = [ - $user2->id() => [ - 'notifiers' => [], - 'flags' => [ - 'subscribe_node', - 'subscribe_user', - ], - ], + $user2->id() => new DeliveryCandidate(['subscribe_node', 'subscribe_user'], [], $user2->id()), ]; $this->assertEquals($uids, $expected_uids, 'All expected subscribers were fetched.'); @@ -166,19 +160,8 @@ public function testGetSubscribers() { $uids = $this->messageSubscribers->getSubscribers($node, $message, $subscribe_options); $expected_uids = [ - $user2->id() => [ - 'notifiers' => [], - 'flags' => [ - 'subscribe_node', - 'subscribe_user', - ], - ], - $user_blocked->id() => [ - 'notifiers' => [], - 'flags' => [ - 'subscribe_node', - ], - ], + $user2->id() => new DeliveryCandidate(['subscribe_node', 'subscribe_user'], [], $user2->id()), + $user_blocked->id() => new DeliveryCandidate(['subscribe_node'], [], $user_blocked->id()), ]; $this->assertEquals($uids, $expected_uids, 'All expected subscribers were fetched, including blocked users.'); @@ -229,13 +212,7 @@ public function testGetSubscribersExcludeSelf() { // Assert subscribers data. $expected_uids = [ - $this->users[2]->id() => [ - 'notifiers' => [], - 'flags' => [ - 'subscribe_node', - 'subscribe_user', - ], - ], + $this->users[2]->id() => new DeliveryCandidate(['subscribe_node', 'subscribe_user'], [], $this->users[2]->id()), ]; $this->assertEquals($uids, $expected_uids, 'All subscribers except for the triggering user were fetched.'); @@ -246,19 +223,8 @@ public function testGetSubscribersExcludeSelf() { // Assert subscribers data. $expected_uids = [ - $user1->id() => [ - 'notifiers' => [], - 'flags' => [ - 'subscribe_node', - ], - ], - $user2->id() => [ - 'notifiers' => [], - 'flags' => [ - 'subscribe_node', - 'subscribe_user', - ], - ], + $this->users[1]->id() => new DeliveryCandidate(['subscribe_node'], [], $this->users[1]->id()), + $this->users[2]->id() => new DeliveryCandidate(['subscribe_node', 'subscribe_user'], [], $this->users[2]->id()), ]; $this->assertEquals($uids, $expected_uids, 'All subscribers including the triggering user were fetched.'); } @@ -323,12 +289,6 @@ public function testHooks() { // called once for each subscriber, so 2 times). $this->messageSubscribers->sendMessage($node, $message, [], ['entity access' => FALSE]); $this->assertEquals(2, \Drupal::state('message_subscribe_test')->get('message_alter_hook_called', FALSE)); - - // Verify legacy array support. Will trigger a notice. - $this->setExpectedException(\PHPUnit_Framework_Error_Deprecated::class); - \Drupal::state('message_subscribe_test')->set('disable_subscribers_alter', FALSE); - \Drupal::state('message_subscribe_test')->set('use_array', TRUE); - $this->messageSubscribers->sendMessage($node, $message, [], ['entity access' => FALSE]); } /** @@ -420,14 +380,8 @@ public function testNotifyEntityOwner() { $message = Message::create(['template' => $this->template->id()]); $subscribers = $this->messageSubscribers->getSubscribers($this->nodes[0], $message); $expected = [ - $this->users[1]->id() => [ - 'notifiers' => [], - 'flags' => ['subscribe_node'], - ], - $this->users[2]->id() => [ - 'notifiers' => [], - 'flags' => ['subscribe_node'], - ], + $this->users[1]->id() => new DeliveryCandidate(['subscribe_node'], [], $this->users[1]->id()), + $this->users[2]->id() => new DeliveryCandidate(['subscribe_node'], [], $this->users[2]->id()), ]; $this->assertEquals($expected, $subscribers); @@ -436,14 +390,8 @@ public function testNotifyEntityOwner() { $this->nodes[0]->save(); $subscribers = $this->messageSubscribers->getSubscribers($this->nodes[0], $message); $expected = [ - $this->users[1]->id() => [ - 'notifiers' => [], - 'flags' => ['subscribe_node'], - ], - $this->users[3]->id() => [ - 'notifiers' => [], - 'flags' => ['subscribe_node'], - ], + $this->users[1]->id() => new DeliveryCandidate(['subscribe_node'], [], $this->users[1]->id()), + $this->users[3]->id() => new DeliveryCandidate(['subscribe_node'], [], $this->users[3]->id()), ]; $this->assertEquals($expected, $subscribers); } diff --git a/tests/src/Unit/Subscribers/DeliveryCandidateTest.php b/tests/src/Unit/Subscribers/DeliveryCandidateTest.php new file mode 100644 index 0000000..ad23222 --- /dev/null +++ b/tests/src/Unit/Subscribers/DeliveryCandidateTest.php @@ -0,0 +1,84 @@ +assertEquals(['foo' => 'foo'], $candidate->getFlags()); + $this->assertEquals(['bar' => 'bar'], $candidate->getNotifiers()); + $this->assertEquals(123, $candidate->getAccountId()); + } + + /** + * Test adding and removing flags. + * + * @covers ::addFlag + * @covers ::removeFlag + * @covers ::getFlags + * @covers ::setFlags + */ + public function testAddRemoveFlag() { + $candidate = new DeliveryCandidate([], [], 42); + $this->assertEmpty($candidate->getFlags()); + $this->assertInstanceOf(DeliveryCandidateInterface::class, $candidate->addFlag('foo')); + $this->assertEquals(['foo' => 'foo'], $candidate->getFlags()); + $this->assertInstanceOf(DeliveryCandidateInterface::class, $candidate->removeFlag('foo')); + $this->assertEmpty($candidate->getFlags()); + $this->assertInstanceOf(DeliveryCandidateInterface::class, $candidate->setFlags(['foo', 'bar'])); + $this->assertEquals(['foo' => 'foo', 'bar' => 'bar'], $candidate->getFlags()); + } + + /** + * Test adding and removing flags. + * + * @covers ::addNotifier + * @covers ::removeNotifier + * @covers ::getNotifiers + * @covers ::setNotifiers + */ + public function testAddRemoveNotifier() { + $candidate = new DeliveryCandidate([], [], 42); + $this->assertEmpty($candidate->getNotifiers()); + $this->assertInstanceOf(DeliveryCandidateInterface::class, $candidate->addNotifier('foo')); + $this->assertEquals(['foo' => 'foo'], $candidate->getNotifiers()); + $this->assertInstanceOf(DeliveryCandidateInterface::class, $candidate->removeNotifier('foo')); + $this->assertEmpty($candidate->getNotifiers()); + $this->assertInstanceOf(DeliveryCandidateInterface::class, $candidate->setNotifiers(['foo', 'bar'])); + $this->assertEquals(['foo' => 'foo', 'bar' => 'bar'], $candidate->getNotifiers()); + } + + /** + * Test setting account ID. + * + * @covers ::getAccountId + * @covers ::setAccountId + */ + public function testAccountId() { + $candidate = new DeliveryCandidate([], [], 42); + $this->assertEquals(42, $candidate->getAccountId()); + $this->assertInstanceOf(DeliveryCandidateInterface::class, $candidate->setAccountId(123)); + $this->assertEquals(123, $candidate->getAccountId()); + } + +} diff --git a/tests/src/Unit/SubscribersTest.php b/tests/src/Unit/SubscribersTest.php index e9beb70..8c7d3bd 100644 --- a/tests/src/Unit/SubscribersTest.php +++ b/tests/src/Unit/SubscribersTest.php @@ -1,230 +1,209 @@ flagService = $this->prophesize(FlagServiceInterface::class) - ->reveal(); - $this->configFactory = $this->prophesize(ConfigFactoryInterface::class) - ->reveal(); - $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class) - ->reveal(); - $this->messageNotifier = $this->prophesize(MessageNotifier::class) - ->reveal(); - $this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class) - ->reveal(); - $this->queue = $this->prophesize(QueueFactory::class)->reveal(); - } - - /** - * Helper to generate a new subscriber service with mock services. - * - * @return \Drupal\message_subscribe\SubscribersInterface - * The subscribers service object. - */ - protected function getSubscriberService() { - return new Subscribers( - $this->flagService, - $this->configFactory, - $this->entityTypeManager, - $this->messageNotifier, - $this->moduleHandler, - $this->queue - ); - } - - /** - * Test the getFlags method. - * - * @covers ::getFlags - */ - public function testGetFlags() { - // Override config mock to allow access to the prefix variable. - $config = $this->prophesize(ImmutableConfig::class); - $config->get('flag_prefix')->willReturn('blah'); - $config_factory = $this->prophesize(ConfigFactoryInterface::class); - $config_factory->get('message_subscribe.settings')->willReturn($config); - $this->configFactory = $config_factory->reveal(); - - // No flags. - $flag_service = $this->prophesize(FlagServiceInterface::class); - $flag_service->getAllFlags(NULL, NULL, NULL)->willReturn([]); - $this->flagService = $flag_service->reveal(); - $subscribers = $this->getSubscriberService(); - $this->assertEquals([], $subscribers->getFlags()); - - // No flags matching prefix. - $flag = $this->prophesize(FlagInterface::class)->reveal(); - $flag_service = $this->prophesize(FlagServiceInterface::class); - $flag_service->getAllFlags(NULL, NULL, NULL)->willReturn([ - 'foo' => $flag, - 'bar' => $flag, - ]); - $this->flagService = $flag_service->reveal(); - $subscribers = $this->getSubscriberService(); - $this->assertEquals([], $subscribers->getFlags()); - - // Matching prefix. - $flag_service = $this->prophesize(FlagServiceInterface::class); - $flag_service->getAllFlags(NULL, NULL, NULL)->willReturn( - ['foo' => $flag, 'bar' => $flag, 'blah_foo' => $flag] - ); - $this->flagService = $flag_service->reveal(); - $subscribers = $this->getSubscriberService(); - $this->assertEquals(['blah_foo' => $flag], $subscribers->getFlags()); - } - - /** - * Test the sendMessage method. - * - * @covers ::sendMessage - */ - public function testSendMessage() { - // Mock config. - $config = $this->prophesize(ImmutableConfig::class); - $config_factory = $this->prophesize(ConfigFactoryInterface::class); - $config_factory->get('message_subscribe.settings')->willReturn($config); - $this->configFactory = $config_factory->reveal(); - - // Mock module handler. - $module_handler = $this->prophesize(ModuleHandlerInterface::class); - $module_handler->getImplementations(Argument::any())->willReturn(['foo']); - $module_handler->alter('message_subscribe_get_subscribers', Argument::any(), Argument::any()) - ->shouldBeCalled(); - $module_handler->alter('message_subscribe_message', Argument::any(), Argument::any()) - ->shouldBeCalled(); - $this->moduleHandler = $module_handler->reveal(); - - // Mock query. - $query = $this->prophesize(QueryInterface::class); - $query->condition(Argument::any(), Argument::any(), Argument::any())->willReturn($query->reveal()); - // User 4 is blocked. - $query->execute()->willReturn([1 => 1, 2 => 2, 7 => 7]); - - // Mock user storage. - $account = $this->prophesize(UserInterface::class)->reveal(); - $entity_storage = $this->prophesize(EntityStorageInterface::class); - $entity_storage->load(Argument::any())->willReturn($account); - $entity_storage->getQuery()->willReturn($query->reveal()); - - // Mock entity type manager. - $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class); - $entity_type_manager->getStorage('user')->willReturn($entity_storage->reveal()); - $this->entityTypeManager = $entity_type_manager->reveal(); - - $subscribers = $this->getSubscriberService(); - - $entity = $this->prophesize(EntityInterface::class); - $entity->access('view', $account)->willReturn(TRUE); - $entity->id()->willReturn(42); - $entity->getEntityTypeId()->willReturn('foo'); - $message = $this->prophesize(Message::class); - $message->createDuplicate()->willReturn($message->reveal()); - $message->id()->willReturn(22); - $message->getFieldDefinitions()->willReturn([]); - $message->setOwnerId(1)->shouldBeCalled(); - $message->setOwnerId(2)->shouldBeCalled(); - $message->setOwnerId(7)->shouldBeCalled(); - // User 4 is blocked. - $message->setOwnerId(4)->shouldNotBeCalled(); - $subscribers->sendMessage($entity->reveal(), $message->reveal()); - } + protected $configFactory; - } + /** + * Mock entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; -} + /** + * Mock message notifier. + * + * @var \Drupal\message_notify\MessageNotifier + */ + protected $messageNotifier; + + /** + * Mock module handler. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * Mock queue factory. + * + * @var \Drupal\Core\Queue\QueueFactory + */ + protected $queue; -// Add a fake module implementation. -namespace { + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + require __DIR__ . '/fixture_foo.module.php'; + + // Setup default mock services. Individual tests can override as needed. + $this->flagService = $this->prophesize(FlagServiceInterface::class) + ->reveal(); + $this->configFactory = $this->prophesize(ConfigFactoryInterface::class) + ->reveal(); + $this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class) + ->reveal(); + $this->messageNotifier = $this->prophesize(MessageNotifier::class) + ->reveal(); + $this->moduleHandler = $this->prophesize(ModuleHandlerInterface::class) + ->reveal(); + $this->queue = $this->prophesize(QueueFactory::class)->reveal(); + } - if (!function_exists('foo_message_subscribe_get_subscribers')) { + /** + * Helper to generate a new subscriber service with mock services. + * + * @return \Drupal\message_subscribe\SubscribersInterface + * The subscribers service object. + */ + protected function getSubscriberService() { + return new Subscribers( + $this->flagService, + $this->configFactory, + $this->entityTypeManager, + $this->messageNotifier, + $this->moduleHandler, + $this->queue + ); + } - /** - * Implements hook_message_subscribe_get_subscribers(). - */ - function foo_message_subscribe_get_subscribers() { - return [ - // Verify arrays are still supported until 2.0. - 1 => ['flags' => [], 'notifiers' => []], - 2 => ['flags' => [], 'notifiers' => []], - 4 => ['flags' => [], 'notifiers' => []], - 7 => ['flags' => [], 'notifiers' => []], - ]; - } + /** + * Test the getFlags method. + * + * @covers ::getFlags + */ + public function testGetFlags() { + // Override config mock to allow access to the prefix variable. + $config = $this->prophesize(ImmutableConfig::class); + $config->get('flag_prefix')->willReturn('blah'); + $config_factory = $this->prophesize(ConfigFactoryInterface::class); + $config_factory->get('message_subscribe.settings')->willReturn($config); + $this->configFactory = $config_factory->reveal(); + + // No flags. + $flag_service = $this->prophesize(FlagServiceInterface::class); + $flag_service->getAllFlags(NULL, NULL, NULL)->willReturn([]); + $this->flagService = $flag_service->reveal(); + $subscribers = $this->getSubscriberService(); + $this->assertEquals([], $subscribers->getFlags()); + + // No flags matching prefix. + $flag = $this->prophesize(FlagInterface::class)->reveal(); + $flag_service = $this->prophesize(FlagServiceInterface::class); + $flag_service->getAllFlags(NULL, NULL, NULL)->willReturn([ + 'foo' => $flag, + 'bar' => $flag, + ]); + $this->flagService = $flag_service->reveal(); + $subscribers = $this->getSubscriberService(); + $this->assertEquals([], $subscribers->getFlags()); + + // Matching prefix. + $flag_service = $this->prophesize(FlagServiceInterface::class); + $flag_service->getAllFlags(NULL, NULL, NULL)->willReturn( + ['foo' => $flag, 'bar' => $flag, 'blah_foo' => $flag] + ); + $this->flagService = $flag_service->reveal(); + $subscribers = $this->getSubscriberService(); + $this->assertEquals(['blah_foo' => $flag], $subscribers->getFlags()); + } + /** + * Test the sendMessage method. + * + * @covers ::sendMessage + */ + public function testSendMessage() { + // Mock config. + $config = $this->prophesize(ImmutableConfig::class); + $config_factory = $this->prophesize(ConfigFactoryInterface::class); + $config_factory->get('message_subscribe.settings')->willReturn($config); + $this->configFactory = $config_factory->reveal(); + + // Mock module handler. + $module_handler = $this->prophesize(ModuleHandlerInterface::class); + $module_handler->getImplementations(Argument::any())->willReturn(['foo']); + $module_handler->alter('message_subscribe_get_subscribers', Argument::any(), Argument::any()) + ->shouldBeCalled(); + $module_handler->alter('message_subscribe_message', Argument::any(), Argument::any()) + ->shouldBeCalled(); + $this->moduleHandler = $module_handler->reveal(); + + // Mock query. + $query = $this->prophesize(QueryInterface::class); + $query->condition(Argument::any(), Argument::any(), Argument::any())->willReturn($query->reveal()); + // User 4 is blocked. + $query->execute()->willReturn([1 => 1, 2 => 2, 7 => 7]); + + // Mock user storage. + $account = $this->prophesize(UserInterface::class)->reveal(); + $entity_storage = $this->prophesize(EntityStorageInterface::class); + $entity_storage->load(Argument::any())->willReturn($account); + $entity_storage->getQuery()->willReturn($query->reveal()); + + // Mock entity type manager. + $entity_type_manager = $this->prophesize(EntityTypeManagerInterface::class); + $entity_type_manager->getStorage('user')->willReturn($entity_storage->reveal()); + $this->entityTypeManager = $entity_type_manager->reveal(); + + $subscribers = $this->getSubscriberService(); + + $entity = $this->prophesize(EntityInterface::class); + $entity->access('view', $account)->willReturn(TRUE); + $entity->id()->willReturn(42); + $entity->getEntityTypeId()->willReturn('foo'); + $message = $this->prophesize(Message::class); + $message->createDuplicate()->willReturn($message->reveal()); + $message->id()->willReturn(22); + $message->getFieldDefinitions()->willReturn([]); + $message->setOwnerId(1)->shouldBeCalled(); + $message->setOwnerId(2)->shouldBeCalled(); + $message->setOwnerId(7)->shouldBeCalled(); + // User 4 is blocked. + $message->setOwnerId(4)->shouldNotBeCalled(); + $subscribers->sendMessage($entity->reveal(), $message->reveal()); } + } diff --git a/tests/src/Unit/fixture_foo.module.php b/tests/src/Unit/fixture_foo.module.php new file mode 100644 index 0000000..8742406 --- /dev/null +++ b/tests/src/Unit/fixture_foo.module.php @@ -0,0 +1,26 @@ + new DeliveryCandidate([], [], 1), + 2 => new DeliveryCandidate([], [], 2), + 4 => new DeliveryCandidate([], [], 4), + 7 => new DeliveryCandidate([], [], 7), + ]; + } + +}