From 823a4c6f8bb3bc46e439fe1af0038942d1a27bf8 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 19 Jun 2026 00:51:20 +0300 Subject: [PATCH 01/17] Harden GitHub workflows --- .github/workflows/build.yml | 8 ++++++-- .github/workflows/composer-require-checker.yml | 4 +++- .github/workflows/mutation.yml | 4 +++- .github/workflows/rector.yml | 4 +++- .github/workflows/static.yml | 4 +++- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fd797cf..f53b13f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,12 +22,16 @@ on: name: build +permissions: + contents: read jobs: phpunit: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 + with: + persist-credentials: false - name: Build working-directory: ./tests run: docker compose build @@ -35,7 +39,7 @@ jobs: working-directory: ./tests run: docker compose run --rm php-cli vendor/bin/phpunit --coverage-clover ./tests/runtime/coverage.xml - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 with: verbose: true files: ./tests/runtime/coverage.xml diff --git a/.github/workflows/composer-require-checker.yml b/.github/workflows/composer-require-checker.yml index a857bce..3bd9db4 100644 --- a/.github/workflows/composer-require-checker.yml +++ b/.github/workflows/composer-require-checker.yml @@ -24,9 +24,11 @@ on: name: Composer require checker +permissions: + contents: read jobs: composer-require-checker: - uses: yiisoft/actions/.github/workflows/composer-require-checker.yml@master + uses: yiisoft/actions/.github/workflows/composer-require-checker.yml@ab62d6b3b0e0cff6c9724ec5a395bedb41c639a2 with: os: >- ['ubuntu-latest'] diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml index 4c64b99..37445d0 100644 --- a/.github/workflows/mutation.yml +++ b/.github/workflows/mutation.yml @@ -28,6 +28,8 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + persist-credentials: false - name: Mutation tests run: make mutation diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml index 7bb92d8..64bdca8 100644 --- a/.github/workflows/rector.yml +++ b/.github/workflows/rector.yml @@ -19,6 +19,8 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + with: + persist-credentials: false - name: Rector run: make rector diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index e33eca8..d49009d 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -22,9 +22,11 @@ on: name: static analysis +permissions: + contents: read jobs: psalm: - uses: yiisoft/actions/.github/workflows/psalm.yml@master + uses: yiisoft/actions/.github/workflows/psalm.yml@ab62d6b3b0e0cff6c9724ec5a395bedb41c639a2 with: os: >- ['ubuntu-latest'] From 9862cc786f8fff5fbc0e2da841300e7fb8eb36f3 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 19 Jun 2026 02:21:48 +0300 Subject: [PATCH 02/17] Add zizmorify configuration --- .github/dependabot.yml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index db86156..6cc0071 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,16 +1,8 @@ version: 2 updates: - # Maintain dependencies for GitHub Actions. - package-ecosystem: "github-actions" directory: "/" schedule: - interval: "daily" - # Too noisy. See https://github.community/t/increase-if-necessary-for-github-actions-in-dependabot/179581 - open-pull-requests-limit: 0 - - # Maintain dependencies for Composer - - package-ecosystem: "composer" - directory: "/" - schedule: - interval: "daily" - versioning-strategy: increase-if-necessary + interval: "weekly" + cooldown: + default-days: 7 From fdd6823be5b8f8e655adcbd380440d6f82388b1b Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 19 Jun 2026 02:41:12 +0300 Subject: [PATCH 03/17] Add zizmorify workflow --- .github/workflows/zizmor.yml | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 0000000..e9b7e06 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,37 @@ +name: GitHub Actions Security Analysis with zizmor 🌈 + +on: + push: + branches: + - main + paths: + - '.github/**.yml' + - '.github/**.yaml' + pull_request: + paths: + - '.github/**.yml' + - '.github/**.yaml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + zizmor: + name: Run zizmor 🌈 + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Run zizmor 🌈 + uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 + with: + advanced-security: false + annotations: true + persona: 'pedantic' From 583e0d2284b8ee40986581b359c44cf2b10a0ae7 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 19 Jun 2026 12:07:07 +0300 Subject: [PATCH 04/17] Restore Dependabot non-GitHub-Actions updates --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6cc0071..b185d42 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,5 +1,11 @@ version: 2 updates: + # Maintain dependencies for GitHub Actions. + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "daily" + versioning-strategy: increase-if-necessary - package-ecosystem: "github-actions" directory: "/" schedule: From 462f32b900514f89c35f8dff290699742068a3e6 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 19 Jun 2026 12:14:38 +0300 Subject: [PATCH 05/17] Restore Dependabot non-GitHub-Actions updates --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b185d42..988aa61 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,8 @@ version: 2 updates: # Maintain dependencies for GitHub Actions. + + # Maintain dependencies for Composer - package-ecosystem: "composer" directory: "/" schedule: From db96b49e8cc41c089b5c604945591b6f4b0413df Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 19 Jun 2026 12:21:35 +0300 Subject: [PATCH 06/17] Restore Dependabot non-GitHub-Actions updates --- .github/dependabot.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 988aa61..41b2db6 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,5 @@ version: 2 updates: - # Maintain dependencies for GitHub Actions. # Maintain dependencies for Composer - package-ecosystem: "composer" From 430a3cbba558992028ed6a6b91849492160fb82f Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Fri, 19 Jun 2026 12:31:56 +0300 Subject: [PATCH 07/17] Restore Dependabot non-GitHub-Actions updates --- .github/dependabot.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 41b2db6..0088948 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,6 +1,5 @@ version: 2 updates: - # Maintain dependencies for Composer - package-ecosystem: "composer" directory: "/" From c0fa1bf225f259fab328d22207aaac0098ce0e38 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 20 Jun 2026 11:55:31 +0300 Subject: [PATCH 08/17] Use master for yiisoft actions --- .github/workflows/composer-require-checker.yml | 2 +- .github/workflows/static.yml | 2 +- .github/zizmor.yml | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .github/zizmor.yml diff --git a/.github/workflows/composer-require-checker.yml b/.github/workflows/composer-require-checker.yml index 3bd9db4..560a8c0 100644 --- a/.github/workflows/composer-require-checker.yml +++ b/.github/workflows/composer-require-checker.yml @@ -28,7 +28,7 @@ permissions: contents: read jobs: composer-require-checker: - uses: yiisoft/actions/.github/workflows/composer-require-checker.yml@ab62d6b3b0e0cff6c9724ec5a395bedb41c639a2 + uses: yiisoft/actions/.github/workflows/composer-require-checker.yml@master with: os: >- ['ubuntu-latest'] diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index d49009d..2047aec 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -26,7 +26,7 @@ permissions: contents: read jobs: psalm: - uses: yiisoft/actions/.github/workflows/psalm.yml@ab62d6b3b0e0cff6c9724ec5a395bedb41c639a2 + uses: yiisoft/actions/.github/workflows/psalm.yml@master with: os: >- ['ubuntu-latest'] diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..85ca798 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,5 @@ +rules: + unpinned-uses: + config: + policies: + "yiisoft/*": any From 5544e2e6a0b9855b217c713dadad7975147a6285 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 20 Jun 2026 11:55:36 +0300 Subject: [PATCH 09/17] Use master for yiisoft actions --- .github/zizmor.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .github/zizmor.yml diff --git a/.github/zizmor.yml b/.github/zizmor.yml new file mode 100644 index 0000000..85ca798 --- /dev/null +++ b/.github/zizmor.yml @@ -0,0 +1,5 @@ +rules: + unpinned-uses: + config: + policies: + "yiisoft/*": any From 4ef42b1922e02af552927f89be2795026ae887ce Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 20 Jun 2026 12:24:52 +0300 Subject: [PATCH 10/17] Use master for yiisoft actions --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index db86156..7da1f95 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,6 +9,8 @@ updates: open-pull-requests-limit: 0 # Maintain dependencies for Composer + ignore: + - dependency-name: "yiisoft/*" - package-ecosystem: "composer" directory: "/" schedule: From 4346fb8ca4ffcf6553335b393575f60d41bdeb6f Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sat, 20 Jun 2026 12:24:56 +0300 Subject: [PATCH 11/17] Use master for yiisoft actions --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0088948..0510f85 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,3 +12,5 @@ updates: interval: "weekly" cooldown: default-days: 7 + ignore: + - dependency-name: "yiisoft/*" From e25b3b49ef6ba7b8bee1ad8b047e74cb8e2e990e Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Sun, 21 Jun 2026 15:22:18 +0300 Subject: [PATCH 12/17] Remove redundant zizmor config --- .github/zizmor.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .github/zizmor.yml diff --git a/.github/zizmor.yml b/.github/zizmor.yml deleted file mode 100644 index 85ca798..0000000 --- a/.github/zizmor.yml +++ /dev/null @@ -1,5 +0,0 @@ -rules: - unpinned-uses: - config: - policies: - "yiisoft/*": any From 2cbd6717d75e0cfddf4f5d79c25a630fc54dfa6a Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Wed, 24 Jun 2026 16:15:14 +0300 Subject: [PATCH 13/17] Remove redundant dependabot change --- .github/dependabot.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7da1f95..db86156 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,8 +9,6 @@ updates: open-pull-requests-limit: 0 # Maintain dependencies for Composer - ignore: - - dependency-name: "yiisoft/*" - package-ecosystem: "composer" directory: "/" schedule: From 340f7e79396ae33e9b1e5d740de55b6f68580459 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Wed, 24 Jun 2026 16:37:03 +0300 Subject: [PATCH 14/17] Revert "Remove redundant dependabot change" This reverts commit 2cbd6717d75e0cfddf4f5d79c25a630fc54dfa6a. --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index db86156..7da1f95 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,6 +9,8 @@ updates: open-pull-requests-limit: 0 # Maintain dependencies for Composer + ignore: + - dependency-name: "yiisoft/*" - package-ecosystem: "composer" directory: "/" schedule: From 2e31498b33f37cf6fced01ef87406e066ed31949 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Thu, 25 Jun 2026 00:48:17 +0300 Subject: [PATCH 15/17] Fix zizmor workflow findings --- .github/dependabot.yml | 2 ++ .github/workflows/zizmor.yml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a47ec9b..10f7e30 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,4 +15,6 @@ updates: directory: "/" schedule: interval: "daily" + cooldown: + default-days: 7 versioning-strategy: increase-if-necessary diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index 9465846..430255d 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -14,8 +14,8 @@ on: - '.github/**.yaml' permissions: - actions: read - contents: read + actions: read # Required by zizmor when reading workflow metadata through the API. + contents: read # Required to read workflow files. jobs: zizmor: From 23775da24af2a4302806beafc1523d3c4b808474 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 30 Jun 2026 16:04:19 +0300 Subject: [PATCH 16/17] Fix queue API compatibility and workflow audit --- .github/workflows/build.yml | 9 ++- .github/workflows/mutation.yml | 7 +- .github/workflows/rector.yml | 7 +- src/Adapter.php | 4 +- src/Message/Message.php | 72 +++++++++++++++++-- src/QueueProvider.php | 2 + src/QueueProviderInterface.php | 3 + tests/Integration/QueueProviderTest.php | 2 +- tests/Integration/QueueTest.php | 11 +-- .../Support/ExtendedSimpleMessageHandler.php | 2 +- tests/Support/IntegrationTestCase.php | 7 +- tests/Unit/Message/MessageTest.php | 45 +++++++++++- tests/Unit/QueueTest.php | 7 +- 13 files changed, 153 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f53b13f..a375a6c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,14 +22,19 @@ on: name: build +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read jobs: phpunit: + name: phpunit runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 + uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0 with: persist-credentials: false - name: Build @@ -39,7 +44,7 @@ jobs: working-directory: ./tests run: docker compose run --rm php-cli vendor/bin/phpunit --coverage-clover ./tests/runtime/coverage.xml - name: Upload coverage to Codecov - uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 + uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 with: verbose: true files: ./tests/runtime/coverage.xml diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml index 37445d0..98b3351 100644 --- a/.github/workflows/mutation.yml +++ b/.github/workflows/mutation.yml @@ -20,15 +20,20 @@ on: name: mutation test +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read jobs: mutation: + name: mutation runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: Mutation tests diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml index 64bdca8..fd176e6 100644 --- a/.github/workflows/rector.yml +++ b/.github/workflows/rector.yml @@ -11,15 +11,20 @@ on: name: rector +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + permissions: contents: read jobs: rector: + name: rector runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: Rector diff --git a/src/Adapter.php b/src/Adapter.php index 0ce544c..707b5a0 100644 --- a/src/Adapter.php +++ b/src/Adapter.php @@ -9,7 +9,7 @@ use Yiisoft\Queue\Cli\LoopInterface; use Yiisoft\Queue\Message\IdEnvelope; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Message\MessageSerializerInterface; +use Yiisoft\Queue\Message\Serializer\MessageSerializerInterface; use Yiisoft\Queue\MessageStatus; final class Adapter implements AdapterInterface @@ -63,7 +63,7 @@ public function status(int|string $id): MessageStatus public function push(MessageInterface $message): MessageInterface { $payload = $this->serializer->serialize($message); - $id = $this->provider->pushMessage($payload, $message->getMetadata()); + $id = $this->provider->pushMessage($payload, $message->getMeta()); return new IdEnvelope($message, $id); } diff --git a/src/Message/Message.php b/src/Message/Message.php index 93c9491..f111420 100644 --- a/src/Message/Message.php +++ b/src/Message/Message.php @@ -6,14 +6,19 @@ use Yiisoft\Queue\Message\MessageInterface; +/** + * @psalm-import-type MessageMeta from MessageInterface + * @psalm-import-type MessagePayload from MessageInterface + */ final class Message implements MessageInterface { /** - * @param array $metadata + * @psalm-param MessagePayload $data + * @psalm-param MessageMeta $metadata */ public function __construct( private string $handlerName, - private mixed $data, + private bool|int|float|string|array|null $data, private array $metadata, private int $delay = 0 //delay in seconds ) { @@ -44,8 +49,13 @@ public function getData(): mixed return $this->data; } + public function getPayload(): bool|int|float|string|array|null + { + return $this->data; + } + /** - * @return array + * @psalm-return MessageMeta */ public function getMetadata(): array { @@ -53,7 +63,15 @@ public function getMetadata(): array } /** - * @param array $metadata + * @psalm-return MessageMeta + */ + public function getMeta(): array + { + return $this->metadata; + } + + /** + * @psalm-param MessageMeta $metadata */ public function withMetadata(array $metadata): static { @@ -62,8 +80,54 @@ public function withMetadata(array $metadata): static return $message; } + /** + * @psalm-param MessageMeta $meta + */ + public function withMeta(array $meta): static + { + return $this->withMetadata($meta); + } + public static function fromData(string $type, mixed $data): self { + self::assertPayload($data); return new self($type, $data, []); } + + public static function fromPayload(string $type, bool|int|float|string|array|null $payload): self + { + return new self($type, $payload, []); + } + + /** + * @psalm-assert MessagePayload $payload + */ + private static function assertPayload(mixed $payload): void + { + if (!self::isPayload($payload)) { + throw new \InvalidArgumentException('Payload must contain only null, scalar values, and arrays of them.'); + } + } + + /** + * @psalm-assert-if-true MessagePayload $payload + */ + private static function isPayload(mixed $payload): bool + { + if ($payload === null || is_scalar($payload)) { + return true; + } + + if (!is_array($payload)) { + return false; + } + + foreach ($payload as $value) { + if (!self::isPayload($value)) { + return false; + } + } + + return true; + } } diff --git a/src/QueueProvider.php b/src/QueueProvider.php index da397a8..dd31ae6 100644 --- a/src/QueueProvider.php +++ b/src/QueueProvider.php @@ -26,6 +26,8 @@ public function __construct( } /** + * @param array $metadata + * * @throws RedisException */ public function pushMessage(string $message, array $metadata = []): int diff --git a/src/QueueProviderInterface.php b/src/QueueProviderInterface.php index 4efefd9..71b61b9 100644 --- a/src/QueueProviderInterface.php +++ b/src/QueueProviderInterface.php @@ -6,6 +6,9 @@ interface QueueProviderInterface { + /** + * @param array $metadata + */ public function pushMessage(string $message, array $metadata = []): int; /** diff --git a/tests/Integration/QueueProviderTest.php b/tests/Integration/QueueProviderTest.php index 09d2281..1b529b5 100644 --- a/tests/Integration/QueueProviderTest.php +++ b/tests/Integration/QueueProviderTest.php @@ -36,7 +36,7 @@ public function test__construct(): QueueProvider public function testDelay(QueueProvider $provider): void { $message = new Message('test', ['key' => 'value'], [], 2); - $id = $provider->pushMessage(json_encode($message->getData(), JSON_THROW_ON_ERROR), $message->getMetadata()); + $id = $provider->pushMessage(json_encode($message->getPayload(), JSON_THROW_ON_ERROR), $message->getMeta()); $this->assertGreaterThan(0, $id); $reserv = $provider->reserve($id); $this->assertNull($reserv); diff --git a/tests/Integration/QueueTest.php b/tests/Integration/QueueTest.php index 5683720..f3f6fb0 100644 --- a/tests/Integration/QueueTest.php +++ b/tests/Integration/QueueTest.php @@ -6,10 +6,11 @@ use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Cli\LoopInterface; -use Yiisoft\Queue\Message\JsonMessageSerializer; use Yiisoft\Queue\Message\GenericMessage as Message; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Message\MessageSerializerInterface; +use Yiisoft\Queue\Message\Serializer\JsonMessageEncoder; +use Yiisoft\Queue\Message\Serializer\MessageSerializer; +use Yiisoft\Queue\Message\Serializer\MessageSerializerInterface; use Yiisoft\Queue\MessageStatus; use Yiisoft\Queue\Queue; use Yiisoft\Queue\Redis\Adapter; @@ -65,7 +66,7 @@ public function testStatus(): void $mockReserved = $this->createMock(QueueProviderInterface::class); $mockReserved->method('existInReserved')->willReturn(true); - $adapter = new Adapter($mockReserved, new JsonMessageSerializer(), $this->getLoop()); + $adapter = new Adapter($mockReserved, new MessageSerializer(new JsonMessageEncoder()), $this->getLoop()); $status = $adapter->status('1'); $this->assertEquals(MessageStatus::RESERVED, $status); @@ -83,7 +84,7 @@ public function testListen(): void $adapter = new Adapter( $queueProvider ->withChannelName('yii-queue'), - new JsonMessageSerializer(), + new MessageSerializer(new JsonMessageEncoder()), $mockLoop, ); $queue = $this->getDefaultQueue($adapter); @@ -131,7 +132,7 @@ public function testAdapterNullMessage() $adapter = new Adapter( $provider, - new JsonMessageSerializer(), + new MessageSerializer(new JsonMessageEncoder()), $mockLoop, ); $notUseHandler = true; diff --git a/tests/Support/ExtendedSimpleMessageHandler.php b/tests/Support/ExtendedSimpleMessageHandler.php index ef74fc9..1cc87ab 100644 --- a/tests/Support/ExtendedSimpleMessageHandler.php +++ b/tests/Support/ExtendedSimpleMessageHandler.php @@ -17,7 +17,7 @@ public function __construct(private FileHelper $fileHelper) public function handle(MessageInterface $message): void { - $data = $message->getData(); + $data = $message->getPayload(); if (null !== $data) { $this->fileHelper->put($data['file_name'], $data['payload']['time']); } diff --git a/tests/Support/IntegrationTestCase.php b/tests/Support/IntegrationTestCase.php index 7eb8b4f..062fcd6 100644 --- a/tests/Support/IntegrationTestCase.php +++ b/tests/Support/IntegrationTestCase.php @@ -11,8 +11,9 @@ use Yiisoft\Queue\Adapter\AdapterInterface; use Yiisoft\Queue\Cli\LoopInterface; use Yiisoft\Queue\Cli\SignalLoop; -use Yiisoft\Queue\Message\JsonMessageSerializer; use Yiisoft\Queue\Message\MessageInterface; +use Yiisoft\Queue\Message\Serializer\JsonMessageEncoder; +use Yiisoft\Queue\Message\Serializer\MessageSerializer; use Yiisoft\Queue\Middleware\CallableFactory; use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareDispatcher; use Yiisoft\Queue\Middleware\Consume\ConsumeMiddlewareFactory; @@ -91,7 +92,7 @@ protected function getMessageHandlers(): array return [ 'ext-simple' => [new ExtendedSimpleMessageHandler(new FileHelper()), 'handle'], 'exception-listen' => static function (MessageInterface $message) { - $data = $message->getData(); + $data = $message->getPayload(); if (null !== $data) { throw new \RuntimeException((string) $data['payload']['time']); } @@ -134,7 +135,7 @@ protected function getAdapter(): AdapterInterface { return $this->adapter ??= new Adapter( $this->getQueueProvider(), - new JsonMessageSerializer(), + new MessageSerializer(new JsonMessageEncoder()), $this->getLoop(), ); } diff --git a/tests/Unit/Message/MessageTest.php b/tests/Unit/Message/MessageTest.php index c1c3681..60c5e4e 100644 --- a/tests/Unit/Message/MessageTest.php +++ b/tests/Unit/Message/MessageTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace Unit\Message; +namespace Yiisoft\Queue\Redis\Tests\Unit\Message; use PHPUnit\Framework\TestCase; use Yiisoft\Queue\Redis\Message\Message; -class MessageTest extends TestCase +final class MessageTest extends TestCase { public function testGetHandlerName(): void { @@ -20,6 +20,7 @@ public function testGetData(): void { $message = new Message('handler', 'data', []); $this->assertEquals('data', $message->getData()); + $this->assertEquals('data', $message->getPayload()); } public function testGetMetadata(): void @@ -27,10 +28,12 @@ public function testGetMetadata(): void $metadata = ['key' => 'value']; $message = new Message('handler', 'data', $metadata); $this->assertEquals($metadata, $message->getMetadata()); + $this->assertEquals($metadata, $message->getMeta()); $message = new Message('handler', 'data', $metadata, 2); $metadata['delay'] = 2; $this->assertEquals($metadata, $message->getMetadata()); + $this->assertEquals($metadata, $message->getMeta()); } public function testWithMetadata(): void @@ -43,6 +46,16 @@ public function testWithMetadata(): void $this->assertSame(['key' => 'value'], $messageWithMetadata->getMetadata()); } + public function testWithMeta(): void + { + $message = new Message('handler', 'data', []); + $messageWithMeta = $message->withMeta(['key' => 'value']); + + $this->assertNotSame($message, $messageWithMeta); + $this->assertSame([], $message->getMeta()); + $this->assertSame(['key' => 'value'], $messageWithMeta->getMeta()); + } + public function testWithDelay(): void { $message = new Message('handler', 'data', []); @@ -64,4 +77,32 @@ public function testFromData(): void $this->assertEquals($data, $message->getData()); $this->assertEquals([], $message->getMetadata()); } + + public function testFromPayload(): void + { + $handlerName = 'test-handler'; + $payload = ['key' => 'value']; + + $message = Message::fromPayload($handlerName, $payload); + + $this->assertSame($handlerName, $message->getType()); + $this->assertSame($payload, $message->getPayload()); + $this->assertSame([], $message->getMeta()); + } + + public function testFromDataFailsWithInvalidPayload(): void + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Payload must contain only null, scalar values, and arrays of them.'); + + Message::fromData('handler', new \stdClass()); + } + + public function testFromDataFailsWithNestedInvalidPayload(): void + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Payload must contain only null, scalar values, and arrays of them.'); + + Message::fromData('handler', ['nested' => new \stdClass()]); + } } diff --git a/tests/Unit/QueueTest.php b/tests/Unit/QueueTest.php index abbee71..642460e 100644 --- a/tests/Unit/QueueTest.php +++ b/tests/Unit/QueueTest.php @@ -6,10 +6,11 @@ use PHPUnit\Framework\TestCase; use Yiisoft\Queue\Cli\LoopInterface; -use Yiisoft\Queue\Message\JsonMessageSerializer; use Yiisoft\Queue\Message\Message; use Yiisoft\Queue\Message\MessageInterface; -use Yiisoft\Queue\Message\MessageSerializerInterface; +use Yiisoft\Queue\Message\Serializer\JsonMessageEncoder; +use Yiisoft\Queue\Message\Serializer\MessageSerializer; +use Yiisoft\Queue\Message\Serializer\MessageSerializerInterface; use Yiisoft\Queue\Redis\Adapter; use Yiisoft\Queue\Redis\QueueProviderInterface; @@ -37,7 +38,7 @@ public function testAdapterNullMessage() $adapter = new Adapter( $provider, - new JsonMessageSerializer(), + new MessageSerializer(new JsonMessageEncoder()), $mockLoop, ); $notUseHandler = true; From aa472b3cc5f1394db62548f76612c221399e33e4 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Wed, 1 Jul 2026 10:41:42 +0000 Subject: [PATCH 17/17] Apply fixes from StyleCI --- src/QueueProvider.php | 2 +- src/QueueProviderInterface.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/QueueProvider.php b/src/QueueProvider.php index dd31ae6..e073a6e 100644 --- a/src/QueueProvider.php +++ b/src/QueueProvider.php @@ -26,7 +26,7 @@ public function __construct( } /** - * @param array $metadata + * @param array $metadata * * @throws RedisException */ diff --git a/src/QueueProviderInterface.php b/src/QueueProviderInterface.php index 71b61b9..a57b94d 100644 --- a/src/QueueProviderInterface.php +++ b/src/QueueProviderInterface.php @@ -7,7 +7,7 @@ interface QueueProviderInterface { /** - * @param array $metadata + * @param array $metadata */ public function pushMessage(string $message, array $metadata = []): int;