2
0

PQueueConsumerFactoryTest.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. namespace Test\Michel\PQueue;
  3. use Michel\PQueue\PQueueHandlerFinder;
  4. use Michel\UniTester\TestCase;
  5. use Michel\PQueue\HandlerResolver\ContainerHandlerResolver;
  6. use Michel\PQueue\HandlerResolver\HandlerResolverInterface;
  7. use Michel\PQueue\PQueueConsumer;
  8. use Michel\PQueue\PQueueConsumerFactory;
  9. use Psr\Container\ContainerInterface;
  10. use Psr\Container\NotFoundExceptionInterface;
  11. use LogicException;
  12. use Test\Michel\PQueue\Extra\TestMessage;
  13. use Test\Michel\PQueue\Extra\TestMessageHandler;
  14. class PQueueConsumerFactoryTest extends TestCase
  15. {
  16. private array $tempDirs = [];
  17. protected function setUp(): void
  18. {
  19. // All mocks and temporary directories will be created within each test method for clarity and isolation.
  20. }
  21. protected function tearDown(): void
  22. {
  23. // Clean up all temporary directories created during tests.
  24. foreach ($this->tempDirs as $dir) {
  25. if (is_dir($dir)) {
  26. $this->deleteDirectory($dir);
  27. }
  28. }
  29. $this->tempDirs = [];
  30. }
  31. // --- Helper Mocks (defined once, used in tests) ---
  32. /**
  33. * Creates a mock PSR-11 ContainerInterface.
  34. * @param bool $withHandler If true, the container will have 'App\MyTestHandler' registered.
  35. */
  36. private function createMockContainer(bool $withHandler = true): ContainerInterface
  37. {
  38. $container = new class implements ContainerInterface {
  39. private array $services = [];
  40. public function get(string $id) {
  41. if (!array_key_exists($id, $this->services)) { // Use array_key_exists for robustness
  42. throw new \Exception("Service $id not found.");
  43. }
  44. return $this->services[$id];
  45. }
  46. public function has(string $id): bool { return array_key_exists($id, $this->services); } // Use array_key_exists for robustness
  47. public function set(string $id, object $service): void { $this->services[$id] = $service; }
  48. };
  49. if ($withHandler) {
  50. // Use a real handler class from your Extra directory for more realistic testing
  51. $container->set(TestMessageHandler::class, new TestMessageHandler());
  52. }
  53. return $container;
  54. }
  55. /**
  56. * Creates a mock HandlerResolverInterface.
  57. * @param ContainerInterface $container The container to back the resolver.
  58. */
  59. private function createMockHandlerResolver(ContainerInterface $container): HandlerResolverInterface
  60. {
  61. return new ContainerHandlerResolver($container);
  62. }
  63. // --- Test Execution ---
  64. public function execute(): void
  65. {
  66. $this->testFactoryCreatesConsumerSuccessfully();
  67. $this->testFactoryFailsWithoutHandlerSource();
  68. $this->testFactoryFailsIfHandlerIsNotInContainer();
  69. }
  70. // --- Individual Tests ---
  71. private function testFactoryCreatesConsumerSuccessfully()
  72. {
  73. // Arrange
  74. $container = $this->createMockContainer(); // Container has the handler
  75. $resolver = $this->createMockHandlerResolver($container);
  76. $sourceDir = $this->createTempDir();
  77. // Copy a real handler and message to the temp source dir
  78. copy(__DIR__ . '/Extra/TestMessage.php', $sourceDir . '/TestMessage.php');
  79. copy(__DIR__ . '/Extra/TestMessageHandler.php', $sourceDir . '/TestMessageHandler.php');
  80. $finder = new PQueueHandlerFinder([$sourceDir]);
  81. $factory = new PQueueConsumerFactory($resolver, $finder->find());
  82. // Act
  83. $consumer = $factory->createConsumer();
  84. // Assert
  85. $this->assertInstanceOf(PQueueConsumer::class, $consumer);
  86. }
  87. private function testFactoryFailsWithoutHandlerSource()
  88. {
  89. // Arrange
  90. $container = $this->createMockContainer(false); // No handler needed if source is missing
  91. $resolver = $this->createMockHandlerResolver($container);
  92. // Assert
  93. $this->expectException(LogicException::class, function () use ($resolver) {
  94. // Act
  95. $factory = new PQueueConsumerFactory($resolver, []); // This MUST throw LogicException
  96. $factory->createConsumer();
  97. });
  98. }
  99. private function testFactoryFailsIfHandlerIsNotInContainer()
  100. {
  101. // Arrange
  102. $container = $this->createMockContainer(false); // Container WITHOUT the handler
  103. $resolver = $this->createMockHandlerResolver($container);
  104. $sourceDir = $this->createTempDir();
  105. // Copy a handler that the container *doesn't* know about
  106. copy(__DIR__ . '/Extra/TestMessage.php', $sourceDir . '/TestMessage.php');
  107. copy(__DIR__ . '/Extra/TestMessageHandler.php', $sourceDir . '/TestMessageHandler.php');
  108. // Assert
  109. $this->expectException(LogicException::class, function () use ($resolver, $sourceDir) {
  110. // Act
  111. $finder = new PQueueHandlerFinder([$sourceDir]);
  112. $factory = new PQueueConsumerFactory($resolver, $finder->find()); // This MUST throw LogicException because the handler is not in the container
  113. $factory->createConsumer();
  114. });
  115. }
  116. // --- Utility Helpers ---
  117. private function createTempDir(): string
  118. {
  119. $dir = sys_get_temp_dir() . '/' . uniqid('pqueue_consumer_factory_test_');
  120. mkdir($dir, 0777, true);
  121. $this->tempDirs[] = $dir;
  122. return $dir;
  123. }
  124. private function deleteDirectory(string $dir): void
  125. {
  126. if (!is_dir($dir)) return;
  127. $files = new \RecursiveIteratorIterator(
  128. new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS),
  129. \RecursiveIteratorIterator::CHILD_FIRST
  130. );
  131. foreach ($files as $fileinfo) {
  132. $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
  133. $todo($fileinfo->getRealPath());
  134. }
  135. rmdir($dir);
  136. }
  137. }