DependencyInjectionTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <?php declare(strict_types=1);
  2. namespace mikemadisonweb\rabbitmq\tests;
  3. use mikemadisonweb\rabbitmq\components\{
  4. Consumer, ConsumerInterface, Logger, Producer, Routing
  5. };
  6. use mikemadisonweb\rabbitmq\Configuration;
  7. use mikemadisonweb\rabbitmq\controllers\RabbitMQController;
  8. use mikemadisonweb\rabbitmq\exceptions\InvalidConfigException;
  9. use PhpAmqpLib\Connection\AbstractConnection;
  10. class DependencyInjectionTest extends TestCase
  11. {
  12. public function testBootstrap()
  13. {
  14. $name = 'test';
  15. $callbackName = 'CallbackMock';
  16. $this->getMockBuilder(ConsumerInterface::class)
  17. ->setMockClassName($callbackName)
  18. ->getMock();
  19. $this->loadExtension([
  20. 'components' => [
  21. 'rabbitmq' => [
  22. 'class' => Configuration::class,
  23. 'connections' => [
  24. [
  25. 'name' => $name,
  26. 'url' => 'amqp://user:pass@host:5432/vhost?query',
  27. ],
  28. ],
  29. 'exchanges' => [
  30. [
  31. 'name' => $name,
  32. 'type' => 'direct'
  33. ],
  34. ],
  35. 'queues' => [
  36. [
  37. 'name' => $name,
  38. 'durable' => true,
  39. ],
  40. ],
  41. 'bindings' => [
  42. [
  43. 'queue' => $name,
  44. 'exchange' => $name,
  45. 'routing_keys' => [$name],
  46. ],
  47. ],
  48. 'producers' => [
  49. [
  50. 'name' => $name,
  51. 'connection' => $name,
  52. ],
  53. ],
  54. 'consumers' => [
  55. [
  56. 'name' => $name,
  57. 'connection' => $name,
  58. 'callbacks' => [
  59. $name => $callbackName,
  60. ],
  61. ],
  62. ],
  63. ],
  64. ],
  65. ]);
  66. $container = \Yii::$container;
  67. $connection = $container->get(sprintf(Configuration::CONNECTION_SERVICE_NAME, $name));
  68. $this->assertInstanceOf(AbstractConnection::class, $connection);
  69. $this->assertInstanceOf(Routing::class, $container->get(Configuration::ROUTING_SERVICE_NAME, ['conn' => $connection]));
  70. $this->assertInstanceOf(Producer::class, $container->get(sprintf(Configuration::PRODUCER_SERVICE_NAME, $name)));
  71. $this->assertInstanceOf(Consumer::class, $container->get(sprintf(Configuration::CONSUMER_SERVICE_NAME, $name)));
  72. $this->assertInstanceOf(Logger::class, $container->get(Configuration::LOGGER_SERVICE_NAME));
  73. $this->assertSame(\Yii::$app->controllerMap[Configuration::EXTENSION_CONTROLLER_ALIAS], RabbitMQController::class);
  74. }
  75. public function testBootstrapEmpty()
  76. {
  77. $this->loadExtension([
  78. 'components' => [
  79. 'rabbitmq' => [
  80. 'class' => Configuration::class,
  81. 'connections' => [
  82. [
  83. 'host' => 'somehost',
  84. ],
  85. ],
  86. ],
  87. ],
  88. ]);
  89. $container = \Yii::$container;
  90. $conn = $container->get(sprintf(Configuration::CONNECTION_SERVICE_NAME, Configuration::DEFAULT_CONNECTION_NAME));
  91. $this->assertInstanceOf(AbstractConnection::class, $conn);
  92. $router = $container->get(Configuration::ROUTING_SERVICE_NAME, ['conn' => $conn]);
  93. // Declare nothing as nothing was configured
  94. $this->assertTrue($router->declareAll($conn));
  95. }
  96. public function testBootstrapWrongUrl()
  97. {
  98. $this->loadExtension([
  99. 'components' => [
  100. 'rabbitmq' => [
  101. 'class' => Configuration::class,
  102. 'connections' => [
  103. [
  104. 'url' => 'https://www.rabbitmq.com/uri-spec.html',
  105. ],
  106. ],
  107. ],
  108. ],
  109. ]);
  110. $this->expectException(\InvalidArgumentException::class);
  111. \Yii::$app->rabbitmq->getConnection();
  112. }
  113. public function testBootstrapProducer()
  114. {
  115. $producerName = 'smth';
  116. $contentType = 'non-existing';
  117. $deliveryMode = 432;
  118. $serializer = 'json_encode';
  119. $safe = false;
  120. $this->loadExtension([
  121. 'components' => [
  122. 'rabbitmq' => [
  123. 'class' => Configuration::class,
  124. 'connections' => [
  125. [
  126. 'host' => 'unreal',
  127. ],
  128. ],
  129. 'producers' => [
  130. [
  131. 'name' => $producerName,
  132. 'content_type' => $contentType,
  133. 'delivery_mode' => $deliveryMode,
  134. 'safe' => $safe,
  135. 'serializer' => $serializer,
  136. ]
  137. ],
  138. ],
  139. ],
  140. ]);
  141. // Test producer setter injection
  142. $producer = \Yii::$container->get(sprintf(Configuration::PRODUCER_SERVICE_NAME, $producerName));
  143. $props = $producer->getBasicProperties();
  144. $this->assertSame($producerName, $producer->getName());
  145. $this->assertSame($safe, $producer->getSafe());
  146. $this->assertSame($contentType, $props['content_type']);
  147. $this->assertSame($deliveryMode, $props['delivery_mode']);
  148. $this->assertSame($serializer, $producer->getSerializer());
  149. }
  150. public function testBootstrapConsumer()
  151. {
  152. $consumerName = 'smth';
  153. $queueName = 'non-existing';
  154. $callbackName = 'CallbackMock';
  155. $callback = $this->getMockBuilder(ConsumerInterface::class)
  156. ->setMockClassName($callbackName)
  157. ->setMethods(['execute'])
  158. ->getMock();
  159. $deserializer = 'json_decode';
  160. $qos = [
  161. 'prefetch_size' => 11,
  162. 'prefetch_count' => 11,
  163. 'global' => true,
  164. ];
  165. $idleTimeout = 100;
  166. $idleTimeoutExitCode = 101;
  167. $proceedOnException = true;
  168. $this->loadExtension([
  169. 'components' => [
  170. 'rabbitmq' => [
  171. 'class' => Configuration::class,
  172. 'connections' => [
  173. [
  174. 'host' => 'unreal',
  175. ],
  176. ],
  177. 'queues' => [
  178. [
  179. 'name' => $queueName,
  180. ]
  181. ],
  182. 'consumers' => [
  183. [
  184. 'name' => $consumerName,
  185. 'callbacks' => [
  186. $queueName => $callbackName,
  187. ],
  188. 'qos' => $qos,
  189. 'idle_timeout' => $idleTimeout,
  190. 'idle_timeout_exit_code' => $idleTimeoutExitCode,
  191. 'proceed_on_exception' => $proceedOnException,
  192. 'deserializer' => $deserializer,
  193. ]
  194. ],
  195. ],
  196. ],
  197. ]);
  198. $consumer = \Yii::$container->get(sprintf(Configuration::CONSUMER_SERVICE_NAME, $consumerName));
  199. $this->assertSame($consumerName, $consumer->getName());
  200. $this->assertSame(array_keys([$queueName => $callback,]), array_keys($consumer->getQueues()));
  201. $this->assertSame($qos, $consumer->getQos());
  202. $this->assertSame($idleTimeout, $consumer->getIdleTimeout());
  203. $this->assertSame($idleTimeoutExitCode, $consumer->getIdleTimeoutExitCode());
  204. $this->assertSame($deserializer, $consumer->getDeserializer());
  205. $this->assertSame($proceedOnException, $consumer->getProceedOnException());
  206. }
  207. public function testBootstrapLogger()
  208. {
  209. $options = [
  210. 'log' => true,
  211. 'category' => 'some',
  212. 'print_console' => false,
  213. 'system_memory' => true,
  214. ];
  215. $this->loadExtension([
  216. 'components' => [
  217. 'rabbitmq' => [
  218. 'class' => Configuration::class,
  219. 'connections' => [
  220. [
  221. 'host' => 'unreal',
  222. ],
  223. ],
  224. 'logger' => $options,
  225. ],
  226. ],
  227. ]);
  228. $logger = \Yii::$container->get(Configuration::LOGGER_SERVICE_NAME);
  229. $this->assertSame($options, $logger->options);
  230. }
  231. public function testValidateCallbackInterface()
  232. {
  233. $callbackAlias = 'callback_mock';
  234. $callbackName = 'WrongCallbackMock';
  235. $queueName = 'queue';
  236. $consumerName = 'consumer';
  237. // not implementing interface
  238. $this
  239. ->getMockBuilder(\AnotherInterface::class)
  240. ->setMockClassName($callbackName)
  241. ->disableOriginalConstructor()
  242. ->getMock();
  243. \Yii::$container->setSingleton($callbackAlias, ['class' => $callbackName]);
  244. $this->loadExtension([
  245. 'components' => [
  246. 'rabbitmq' => [
  247. 'class' => Configuration::class,
  248. 'connections' => [
  249. [
  250. 'host' => 'unreal',
  251. ],
  252. ],
  253. 'queues' => [
  254. [
  255. 'name' => $queueName,
  256. ]
  257. ],
  258. 'consumers' => [
  259. [
  260. 'name' => $consumerName,
  261. 'callbacks' => [
  262. $queueName => $callbackAlias,
  263. ],
  264. ]
  265. ],
  266. ],
  267. ],
  268. ]);
  269. $this->expectException(InvalidConfigException::class);
  270. \Yii::$app->rabbitmq->getConsumer($consumerName);
  271. }
  272. }