Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions src/Message/IdEnvelope.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function __construct(

public static function fromMessage(MessageInterface $message): self
{
return new self($message, $message->getMetadata()[self::MESSAGE_ID_KEY] ?? null);
return new self($message, self::getIdFromMessage($message));
}

public function setId(string|int|null $id): void
Expand All @@ -31,11 +31,27 @@ public function setId(string|int|null $id): void

public function getId(): string|int|null
{
return $this->id ?? $this->message->getMetadata()[self::MESSAGE_ID_KEY] ?? null;
return $this->id ?? self::getIdFromMessage($this->message);
}

private function getEnvelopeMetadata(): array
{
return [self::MESSAGE_ID_KEY => $this->getId()];
}

private static function getIdFromMessage(MessageInterface $message): string|int|null
{
$id = $message->getMetadata()[self::MESSAGE_ID_KEY] ?? null;
if ($id instanceof \Stringable) {
$id = (string) $id;
}

// We don't throw an error as this value could come from external sources,
// and we should process the message either way
if (!is_string($id) && !is_int($id)) {
return null;
}

return $id;
}
}
112 changes: 112 additions & 0 deletions tests/Unit/Message/IdEnvelopeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Tests\Unit\Message;

use PHPUnit\Framework\TestCase;
use Yiisoft\Queue\Message\IdEnvelope;
use Yiisoft\Queue\Message\Message;
use Yiisoft\Queue\Message\MessageInterface;

final class IdEnvelopeTest extends TestCase
{
public function testConstructor(): void
{
$message = $this->createMessage();
$id = 'test-id';

$envelope = new IdEnvelope($message, $id);

$this->assertSame($message, $envelope->getMessage());
$this->assertSame($id, $envelope->getId());
}

public function testFromMessageWithStringId(): void
{
$id = 'test-id';
$message = $this->createMessage([IdEnvelope::MESSAGE_ID_KEY => $id]);

$envelope = IdEnvelope::fromMessage($message);

$this->assertSame($id, $envelope->getId());
}

public function testFromMessageWithIntId(): void
{
$id = 123;
$message = $this->createMessage([IdEnvelope::MESSAGE_ID_KEY => $id]);

$envelope = IdEnvelope::fromMessage($message);

$this->assertSame($id, $envelope->getId());
}

public function testFromMessageWithNullId(): void
{
$message = $this->createMessage();

$envelope = IdEnvelope::fromMessage($message);

$this->assertNull($envelope->getId());
}

public function testFromMessageWithObjectHavingToString(): void
{
$stringableObject = new class () {
public function __toString(): string
{
return 'object-id';
}
};
$message = $this->createMessage([IdEnvelope::MESSAGE_ID_KEY => $stringableObject]);
$envelope = IdEnvelope::fromMessage($message);

$this->assertSame('object-id', $envelope->getId());
}

public function testFromMessageWithInvalidIdType(): void
{
$invalidId = ['array-cannot-be-id'];
$message = $this->createMessage([IdEnvelope::MESSAGE_ID_KEY => $invalidId]);
$message = IdEnvelope::fromMessage($message);

$this->assertNull($message->getId());
}

public function testGetEnvelopeMetadata(): void
{
$id = 'test-id';
$message = $this->createMessage();
$envelope = new IdEnvelope($message, $id);

$metadata = $envelope->getMetadata();

$this->assertArrayHasKey(IdEnvelope::MESSAGE_ID_KEY, $metadata);
$this->assertSame($id, $metadata[IdEnvelope::MESSAGE_ID_KEY]);
}

public function testFromData(): void
{
$handlerName = 'test-handler';
$data = ['key' => 'value'];
$metadata = ['meta' => 'data', IdEnvelope::MESSAGE_ID_KEY => 'test-id'];

/**
* @var IdEnvelope $envelope
*/
$envelope = IdEnvelope::fromData($handlerName, $data, $metadata);

$this->assertInstanceOf(IdEnvelope::class, $envelope);
$this->assertSame($handlerName, $envelope->getHandlerName());
$this->assertSame($data, $envelope->getData());
$this->assertArrayHasKey('meta', $envelope->getMetadata());
$this->assertSame('data', $envelope->getMetadata()['meta']);
$this->assertSame('test-id', $envelope->getId());
}

private function createMessage(array $metadata = []): MessageInterface
{
return new Message('test-handler', ['test-data'], $metadata);
}
}
83 changes: 83 additions & 0 deletions tests/Unit/Middleware/FailureHandling/FailureEnvelopeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Queue\Tests\Unit\Middleware\FailureHandling;

use PHPUnit\Framework\TestCase;
use Yiisoft\Queue\Message\Message;
use Yiisoft\Queue\Message\MessageInterface;
use Yiisoft\Queue\Middleware\FailureHandling\FailureEnvelope;

final class FailureEnvelopeTest extends TestCase
{
public function testConstructor(): void
{
$message = $this->createMessage();
$metadata = ['attempt' => 1, 'error' => 'Test error'];

$envelope = new FailureEnvelope($message, $metadata);

$this->assertSame($message, $envelope->getMessage());
$this->assertArrayHasKey(FailureEnvelope::FAILURE_META_KEY, $envelope->getMetadata());
$this->assertSame($metadata, $envelope->getMetadata()[FailureEnvelope::FAILURE_META_KEY]);
}

public function testFromMessageWithExistingMetadata(): void
{
$existingMetadata = ['attempt' => 1];
$message = $this->createMessage([FailureEnvelope::FAILURE_META_KEY => $existingMetadata]);

$envelope = FailureEnvelope::fromMessage($message);

$this->assertSame($existingMetadata, $envelope->getMetadata()[FailureEnvelope::FAILURE_META_KEY]);
}

public function testFromMessageWithoutMetadata(): void
{
$message = $this->createMessage();

$envelope = FailureEnvelope::fromMessage($message);

$this->assertArrayHasKey(FailureEnvelope::FAILURE_META_KEY, $envelope->getMetadata());
$this->assertSame([], $envelope->getMetadata()[FailureEnvelope::FAILURE_META_KEY]);
}

public function testMetadataMerging(): void
{
$existingMetadata = ['attempt' => 1, 'firstError' => 'First error'];
$message = $this->createMessage([FailureEnvelope::FAILURE_META_KEY => $existingMetadata]);
$newMetadata = ['attempt' => 2, 'lastError' => 'Last error'];

$envelope = new FailureEnvelope($message, $newMetadata);

$mergedMetadata = $envelope->getMetadata()[FailureEnvelope::FAILURE_META_KEY];
$this->assertSame(2, $mergedMetadata['attempt']);
$this->assertSame('First error', $mergedMetadata['firstError']);
$this->assertSame('Last error', $mergedMetadata['lastError']);
}

public function testFromData(): void
{
$handlerName = 'test-handler';
$data = ['key' => 'value'];
$metadata = [
'meta' => 'data',
FailureEnvelope::FAILURE_META_KEY => ['attempt' => 1],
];

$envelope = FailureEnvelope::fromData($handlerName, $data, $metadata);

$this->assertInstanceOf(FailureEnvelope::class, $envelope);
$this->assertSame($handlerName, $envelope->getHandlerName());
$this->assertSame($data, $envelope->getData());
$this->assertArrayHasKey('meta', $envelope->getMetadata());
$this->assertSame('data', $envelope->getMetadata()['meta']);
$this->assertSame(['attempt' => 1], $envelope->getMetadata()[FailureEnvelope::FAILURE_META_KEY]);
}

private function createMessage(array $metadata = []): MessageInterface
{
return new Message('test-handler', ['test-data'], $metadata);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,6 @@ public function testQueueSendingStrategies(
$this->expectExceptionMessage('testException');
}

$metaInitial = [FailureEnvelope::FAILURE_META_KEY => $metaInitial];
$metaResult = [FailureEnvelope::FAILURE_META_KEY => $metaResult];

$handler = $this->getHandler($metaResult, $suites);
$queue = $this->getPreparedQueue($metaResult, $suites);

Expand All @@ -162,7 +159,7 @@ public function testQueueSendingStrategies(
new Message(
'test',
null,
$metaInitial
[FailureEnvelope::FAILURE_META_KEY => $metaInitial]
),
new Exception('testException'),
$queue
Expand Down Expand Up @@ -194,7 +191,7 @@ private function getHandler(array $metaResult, bool $suites): MessageFailureHand
$pipelineAssertion = static function (FailureHandlingRequest $request) use (
$metaResult
): FailureHandlingRequest {
Assert::assertEquals($metaResult, $request->getMessage()->getMetadata());
Assert::assertEquals($metaResult, $request->getMessage()->getMetadata()[FailureEnvelope::FAILURE_META_KEY] ?? []);

throw $request->getException();
};
Expand All @@ -209,7 +206,7 @@ private function getHandler(array $metaResult, bool $suites): MessageFailureHand
private function getPreparedQueue(array $metaResult, bool $suites): QueueInterface
{
$queueAssertion = static function (MessageInterface $message) use ($metaResult): MessageInterface {
Assert::assertEquals($metaResult, $message->getMetadata());
Assert::assertEquals($metaResult, $message->getMetadata()[FailureEnvelope::FAILURE_META_KEY] ?? []);

return $message;
};
Expand Down
Loading