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
2 changes: 2 additions & 0 deletions src/events/src/CallQueuedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Hypervel\Events;

use AllowDynamicProperties;
use DateTimeInterface;
use Hypervel\Bus\Queueable;
use Hypervel\Container\Container;
Expand All @@ -13,6 +14,7 @@
use Hypervel\Queue\InteractsWithQueue;
use Throwable;

#[AllowDynamicProperties]
class CallQueuedListener implements ShouldQueue
{
use InteractsWithQueue;
Expand Down
50 changes: 50 additions & 0 deletions tests/Events/CallQueuedListenerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Hypervel\Tests\Events;

use Hypervel\Events\CallQueuedListener as HypervelCallQueuedListener;
use Hypervel\Tests\TestCase;

/**
* @internal
* @coversNothing
*/
class CallQueuedListenerTest extends TestCase
{
public function testHypervelListenerToleratesUnknownPropertiesOnUnserialization()
{
$this->assertListenerToleratesUnknownProperties(
HypervelCallQueuedListener::class
);
}

/**
* Simulates cross-version deserialization: a job payload serialized by a
* newer Laravel/Hypervel version (which adds extra properties to
* CallQueuedListener) is unserialized by an older version that does not
* declare those properties. Without #[AllowDynamicProperties], PHP 8.2+
* raises an error on the dynamic property assignment during unserialize().
*/
private function assertListenerToleratesUnknownProperties(string $class): void
{
$listener = new $class('App\Listeners\OrderShipped', 'handle', []);
$serialized = serialize($listener);

// Inject a synthetic property absent from the current class definition.
$extra = 's:18:"newPropertyFromV11";s:5:"value";';
$serialized = preg_replace_callback(
'/^(O:\d+:"[^"]+":)(\d+):/',
fn ($m) => $m[1] . ((int) $m[2] + 1) . ':',
$serialized
);
$serialized = substr($serialized, 0, -1) . $extra . '}';

$result = unserialize($serialized);

$this->assertInstanceOf($class, $result);
$this->assertSame('App\Listeners\OrderShipped', $result->class);
$this->assertSame('value', $result->newPropertyFromV11);
}
}