-
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
522 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Queue\Tests\Integration\Support; | ||
|
||
use Yiisoft\Queue\Message\Message; | ||
use Yiisoft\Queue\Middleware\MessageHandlerInterface; | ||
use Yiisoft\Queue\Middleware\MiddlewareInterface; | ||
use Yiisoft\Queue\Middleware\Request; | ||
|
||
final class ConsumeMiddleware implements MiddlewareInterface | ||
{ | ||
public function __construct(private string $stage) | ||
{ | ||
} | ||
|
||
public function process(Request $request, MessageHandlerInterface $handler): Request | ||
{ | ||
$message = $request->getMessage(); | ||
$stack = $message->getData(); | ||
$stack[] = $this->stage; | ||
$messageNew = new Message($message->getHandlerName(), $stack); | ||
|
||
return $handler->handle($request->withMessage($messageNew)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Queue\Tests\Unit\Middleware\Consume; | ||
|
||
use Yiisoft\Queue\Adapter\AdapterInterface; | ||
use Yiisoft\Queue\Message\Message; | ||
use Yiisoft\Queue\Middleware\Request; | ||
use Yiisoft\Queue\QueueInterface; | ||
use Yiisoft\Queue\Tests\TestCase; | ||
|
||
final class ConsumeRequestTest extends TestCase | ||
{ | ||
public function testImmutable(): void | ||
{ | ||
$message = new Message('test', 'test'); | ||
$adapter = $this->createMock(AdapterInterface::class); | ||
$consumeRequest = new Request($message, $adapter); | ||
|
||
$this->assertNotSame($consumeRequest, $consumeRequest->withMessage($message)); | ||
$this->assertNotSame($consumeRequest, $consumeRequest->withAdapter($adapter)); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
tests/Unit/Middleware/Consume/InvalidMiddlewareDefinitionExceptionTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Queue\Tests\Unit\Middleware\Consume; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use stdClass; | ||
use Yiisoft\Queue\Middleware\InvalidMiddlewareDefinitionException; | ||
use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware; | ||
|
||
final class InvalidMiddlewareDefinitionExceptionTest extends TestCase | ||
{ | ||
public function dataBase(): array | ||
{ | ||
return [ | ||
[ | ||
'test', | ||
'"test"', | ||
], | ||
[ | ||
new TestCallableMiddleware(), | ||
sprintf( | ||
'an instance of "%s"', | ||
TestCallableMiddleware::class, | ||
), | ||
], | ||
[ | ||
[TestCallableMiddleware::class, 'notExistsAction'], | ||
sprintf( | ||
'["%s", "notExistsAction"]', | ||
TestCallableMiddleware::class, | ||
), | ||
], | ||
[ | ||
['class' => TestCallableMiddleware::class, 'index'], | ||
sprintf( | ||
'["class" => "%s", "index"]', | ||
TestCallableMiddleware::class, | ||
), | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider dataBase | ||
*/ | ||
public function testBase(mixed $definition, string $expected): void | ||
{ | ||
$exception = new InvalidMiddlewareDefinitionException($definition); | ||
self::assertStringEndsWith('. Got ' . $expected . '.', $exception->getMessage()); | ||
} | ||
|
||
public function dataUnknownDefinition(): array | ||
{ | ||
return [ | ||
[42], | ||
[[new stdClass()]], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider dataUnknownDefinition | ||
*/ | ||
public function testUnknownDefinition(mixed $definition): void | ||
{ | ||
$exception = new InvalidMiddlewareDefinitionException($definition); | ||
self::assertSame( | ||
'Parameter should be either middleware class name or a callable.', | ||
$exception->getMessage() | ||
); | ||
} | ||
} |
186 changes: 186 additions & 0 deletions
186
tests/Unit/Middleware/Consume/MiddlewareDispatcherTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Yiisoft\Queue\Tests\Unit\Middleware\Consume; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Psr\Container\ContainerInterface; | ||
use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestCallableMiddleware; | ||
use Yiisoft\Queue\Tests\Unit\Middleware\Support\TestMiddleware; | ||
use Yiisoft\Test\Support\Container\SimpleContainer; | ||
use Yiisoft\Queue\Adapter\AdapterInterface; | ||
use Yiisoft\Queue\Message\Message; | ||
use Yiisoft\Queue\Middleware\CallableFactory; | ||
use Yiisoft\Queue\Middleware\MiddlewareDispatcher; | ||
use Yiisoft\Queue\Middleware\Request; | ||
use Yiisoft\Queue\Middleware\MessageHandlerInterface; | ||
use Yiisoft\Queue\Middleware\MiddlewareFactory; | ||
use Yiisoft\Queue\QueueInterface; | ||
use Yiisoft\Queue\Tests\App\FakeAdapter; | ||
|
||
final class MiddlewareDispatcherTest extends TestCase | ||
{ | ||
public function testCallableMiddlewareCalled(): void | ||
{ | ||
$request = $this->getRequest(); | ||
$queue = $this->createMock(QueueInterface::class); | ||
$adapter = $this->createMock(AdapterInterface::class); | ||
|
||
$dispatcher = $this->createDispatcher()->withMiddlewares( | ||
[ | ||
static function (Request $request) use ($adapter): Request { | ||
return $request->withMessage(new Message('test', 'New closure test data'))->withAdapter($adapter); | ||
}, | ||
] | ||
); | ||
|
||
$request = $dispatcher->dispatch($request, $this->getRequestHandler()); | ||
$this->assertSame('New closure test data', $request->getMessage()->getData()); | ||
} | ||
|
||
public function testArrayMiddlewareCallableDefinition(): void | ||
{ | ||
$request = $this->getRequest(); | ||
$container = $this->createContainer( | ||
[ | ||
TestCallableMiddleware::class => new TestCallableMiddleware(), | ||
] | ||
); | ||
$dispatcher = $this->createDispatcher($container)->withMiddlewares([[TestCallableMiddleware::class, 'index']]); | ||
$request = $dispatcher->dispatch($request, $this->getRequestHandler()); | ||
$this->assertSame('New test data', $request->getMessage()->getData()); | ||
} | ||
|
||
public function testFactoryArrayDefinition(): void | ||
{ | ||
$request = $this->getRequest(); | ||
$container = $this->createContainer(); | ||
$definition = [ | ||
'class' => TestMiddleware::class, | ||
'__construct()' => ['message' => 'New test data from the definition'], | ||
]; | ||
$dispatcher = $this->createDispatcher($container)->withMiddlewares([$definition]); | ||
$request = $dispatcher->dispatch($request, $this->getRequestHandler()); | ||
$this->assertSame('New test data from the definition', $request->getMessage()->getData()); | ||
} | ||
|
||
public function testMiddlewareFullStackCalled(): void | ||
{ | ||
$request = $this->getRequest(); | ||
|
||
$middleware1 = static function (Request $request, MessageHandlerInterface $handler): Request { | ||
$request = $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'new test data')); | ||
|
||
return $handler->handle($request); | ||
}; | ||
$middleware2 = static function (Request $request, MessageHandlerInterface $handler): Request { | ||
$request = $request->withMessage(new Message('new handler', $request->getMessage()->getData())); | ||
|
||
return $handler->handle($request); | ||
}; | ||
|
||
$dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); | ||
|
||
$request = $dispatcher->dispatch($request, $this->getRequestHandler()); | ||
$this->assertSame('new test data', $request->getMessage()->getData()); | ||
$this->assertSame('new handler', $request->getMessage()->getHandlerName()); | ||
} | ||
|
||
public function testMiddlewareStackInterrupted(): void | ||
{ | ||
$request = $this->getRequest(); | ||
|
||
$middleware1 = static function (Request $request, MessageHandlerInterface $handler): Request { | ||
return $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'first')); | ||
}; | ||
$middleware2 = static function (Request $request, MessageHandlerInterface $handler): Request { | ||
return $request->withMessage(new Message($request->getMessage()->getHandlerName(), 'second')); | ||
}; | ||
|
||
$dispatcher = $this->createDispatcher()->withMiddlewares([$middleware1, $middleware2]); | ||
|
||
$request = $dispatcher->dispatch($request, $this->getRequestHandler()); | ||
$this->assertSame('first', $request->getMessage()->getData()); | ||
} | ||
|
||
public function dataHasMiddlewares(): array | ||
{ | ||
return [ | ||
[[], false], | ||
[[[TestCallableMiddleware::class, 'index']], true], | ||
]; | ||
} | ||
|
||
/** | ||
* @dataProvider dataHasMiddlewares | ||
*/ | ||
public function testHasMiddlewares(array $definitions, bool $expected): void | ||
{ | ||
self::assertSame( | ||
$expected, | ||
$this->createDispatcher()->withMiddlewares($definitions)->hasMiddlewares() | ||
); | ||
} | ||
|
||
public function testImmutability(): void | ||
{ | ||
$dispatcher = $this->createDispatcher(); | ||
self::assertNotSame($dispatcher, $dispatcher->withMiddlewares([])); | ||
} | ||
|
||
public function testResetStackOnWithMiddlewares(): void | ||
{ | ||
$request = $this->getRequest(); | ||
$container = $this->createContainer( | ||
[ | ||
TestCallableMiddleware::class => new TestCallableMiddleware(), | ||
TestMiddleware::class => new TestMiddleware(), | ||
] | ||
); | ||
|
||
$dispatcher = $this | ||
->createDispatcher($container) | ||
->withMiddlewares([[TestCallableMiddleware::class, 'index']]); | ||
$dispatcher->dispatch($request, $this->getRequestHandler()); | ||
|
||
$dispatcher = $dispatcher->withMiddlewares([TestMiddleware::class]); | ||
$request = $dispatcher->dispatch($request, $this->getRequestHandler()); | ||
|
||
self::assertSame('New middleware test data', $request->getMessage()->getData()); | ||
} | ||
|
||
private function getRequestHandler(): MessageHandlerInterface | ||
{ | ||
return new class () implements MessageHandlerInterface { | ||
public function handle(Request $request): Request | ||
{ | ||
return $request; | ||
} | ||
}; | ||
} | ||
|
||
private function createDispatcher( | ||
ContainerInterface $container = null, | ||
): MiddlewareDispatcher { | ||
$container ??= $this->createContainer([AdapterInterface::class => new FakeAdapter()]); | ||
$callableFactory = new CallableFactory($container); | ||
|
||
return new MiddlewareDispatcher( | ||
new MiddlewareFactory($container, $callableFactory), | ||
); | ||
} | ||
|
||
private function createContainer(array $instances = []): ContainerInterface | ||
{ | ||
return new SimpleContainer($instances); | ||
} | ||
|
||
private function getRequest(): Request | ||
{ | ||
return new Request( | ||
new Message('handler', 'data'), | ||
$this->createMock(AdapterInterface::class) | ||
); | ||
} | ||
} |
Oops, something went wrong.