Skip to content

Commit

Permalink
[11.x] Supports laravel/serializable-closure 2 (#53552)
Browse files Browse the repository at this point in the history
* [11.x] Supports `laravel/serializable-closure` 2

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* Apply fixes from StyleCI

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* Apply fixes from StyleCI

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* Apply fixes from StyleCI

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* Apply fixes from StyleCI

* Update SerializableClosureV1QueueTest.php

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

* Apply suggestions from code review

* wip

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>

---------

Signed-off-by: Mior Muhammad Zaki <crynobone@gmail.com>
Co-authored-by: StyleCI Bot <bot@styleci.io>
  • Loading branch information
crynobone and StyleCIBot authored Nov 19, 2024
1 parent d7345b6 commit c272db4
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 3 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"guzzlehttp/guzzle": "^7.8",
"guzzlehttp/uri-template": "^1.0",
"laravel/prompts": "^0.1.18|^0.2.0|^0.3.0",
"laravel/serializable-closure": "^1.3",
"laravel/serializable-closure": "^1.3|^2.0",
"league/commonmark": "^2.2.1",
"league/flysystem": "^3.8.0",
"monolog/monolog": "^3.0",
Expand Down Expand Up @@ -107,7 +107,7 @@
"league/flysystem-sftp-v3": "^3.0",
"mockery/mockery": "^1.6.10",
"nyholm/psr7": "^1.2",
"orchestra/testbench-core": "^9.5",
"orchestra/testbench-core": "^9.6",
"pda/pheanstalk": "^5.0",
"phpstan/phpstan": "^1.11.5",
"phpunit/phpunit": "^10.5|^11.0",
Expand Down
2 changes: 1 addition & 1 deletion src/Illuminate/Queue/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"illuminate/filesystem": "^11.0",
"illuminate/pipeline": "^11.0",
"illuminate/support": "^11.0",
"laravel/serializable-closure": "^1.2.2",
"laravel/serializable-closure": "^1.3|^2.0",
"ramsey/uuid": "^4.7",
"symfony/process": "^7.0"
},
Expand Down
29 changes: 29 additions & 0 deletions tests/Integration/Queue/Fixtures/Jobs/DeleteUser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Illuminate\Tests\Integration\Queue\Fixtures\Jobs;

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Auth\User;
use Illuminate\Foundation\Queue\Queueable;

class DeleteUser implements ShouldQueue
{
use Queueable;

/**
* Create a new job instance.
*/
public function __construct(
public User $user
) {
log($user);
}

/**
* Execute the job.
*/
public function handle(): void
{
$this->user->delete();
}
}
67 changes: 67 additions & 0 deletions tests/Integration/Queue/SerializableClosureV1QueueTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Illuminate\Tests\Integration\Queue;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\DB;
use Orchestra\Testbench\Attributes\WithMigration;
use Orchestra\Testbench\Factories\UserFactory;
use Orchestra\Testbench\TestCase;

#[WithMigration]
class SerializableClosureV1QueueTest extends TestCase
{
use RefreshDatabase;

/** {@inheritDoc} */
#[\Override]
protected function defineEnvironment($app)
{
$this->markTestSkippedWhen($this->usingInMemoryDatabase(), 'Test does not support using :memory: database connection');

tap($app->make('config'), function ($config) {
$config->set([
'app.key' => 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF',
'queue.default' => 'database',
]);
});
}

/** {@inheritDoc} */
protected function afterRefreshingDatabase()
{
UserFactory::new()->create([
'id' => 100,
'name' => 'Taylor Otwell',
'email' => 'taylor@laravel.com',
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
]);

DB::table('jobs')->insert([
'queue' => 'default',
'payload' => "{\"uuid\":\"d7c0856d-733a-4e73-89c8-eca4dea621ff\",\"displayName\":\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\Fixtures\\\\Jobs\\\\DeleteUser\",\"job\":\"Illuminate\\\\Queue\\\\CallQueuedHandler@call\",\"maxTries\":null,\"maxExceptions\":null,\"failOnTimeout\":false,\"backoff\":null,\"timeout\":null,\"retryUntil\":null,\"data\":{\"commandName\":\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\Fixtures\\\\Jobs\\\\DeleteUser\",\"command\":\"O:59:\\\"Illuminate\\\\Tests\\\\Integration\\\\Queue\\\\Fixtures\\\\Jobs\\\\DeleteUser\\\":3:{s:4:\\\"user\\\";O:45:\\\"Illuminate\\\\Contracts\\\\Database\\\\ModelIdentifier\\\":5:{s:5:\\\"class\\\";s:31:\\\"Illuminate\\\\Foundation\\\\Auth\\\\User\\\";s:2:\\\"id\\\";i:100;s:9:\\\"relations\\\";a:0:{}s:10:\\\"connection\\\";s:6:\\\"sqlite\\\";s:15:\\\"collectionClass\\\";N;}s:7:\\\"chained\\\";a:1:{i:0;s:571:\\\"O:34:\\\"Illuminate\\\\Queue\\\\CallQueuedClosure\\\":1:{s:7:\\\"closure\\\";O:47:\\\"Laravel\\\\SerializableClosure\\\\SerializableClosure\\\":1:{s:12:\\\"serializable\\\";O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Signed\\\":2:{s:12:\\\"serializable\\\";s:282:\\\"O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Native\\\":5:{s:3:\\\"use\\\";a:0:{}s:8:\\\"function\\\";s:57:\\\"function () {\\n \\\\info('Hello world');\\n }\\\";s:5:\\\"scope\\\";s:44:\\\"Illuminate\\\\Foundation\\\\Console\\\\ClosureCommand\\\";s:4:\\\"this\\\";N;s:4:\\\"self\\\";s:32:\\\"000000000000021e0000000000000000\\\";}\\\";s:4:\\\"hash\\\";s:44:\\\"VGMlRmFr2\\/U1E8lksExnzODwffyWR8oD01WOcQ2SUjE=\\\";}}}\\\";}s:19:\\\"chainCatchCallbacks\\\";a:1:{i:0;O:47:\\\"Laravel\\\\SerializableClosure\\\\SerializableClosure\\\":1:{s:12:\\\"serializable\\\";O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Signed\\\":2:{s:12:\\\"serializable\\\";s:309:\\\"O:46:\\\"Laravel\\\\SerializableClosure\\\\Serializers\\\\Native\\\":5:{s:3:\\\"use\\\";a:0:{}s:8:\\\"function\\\";s:84:\\\"function (\\\\Throwable \$e) {\\n \\\\Illuminate\\\\Support\\\\Facades\\\\Log::error(\$e);\\n }\\\";s:5:\\\"scope\\\";s:44:\\\"Illuminate\\\\Foundation\\\\Console\\\\ClosureCommand\\\";s:4:\\\"this\\\";N;s:4:\\\"self\\\";s:32:\\\"00000000000002380000000000000000\\\";}\\\";s:4:\\\"hash\\\";s:44:\\\"RBSD4RFLgmKL9WJEGY66aeZtWDkX\\/aY1J+MJ8LQSYi4=\\\";}}}}\"}}",
'attempts' => 0,
'available_at' => 1731919764,
'created_at' => 1731919764,
]);
}

public function testItCanProcessQueueFromSerializableClosureV1()
{
$this->assertDatabaseHas('users', [
'name' => 'Taylor Otwell',
'email' => 'taylor@laravel.com',
]);

$this->artisan('queue:work', [
'connection' => 'database',
'--stop-when-empty' => true,
'--memory' => 1024,
])->assertExitCode(0);

$this->assertDatabaseMissing('users', [
'name' => 'Taylor Otwell',
'email' => 'taylor@laravel.com',
]);
}
}
59 changes: 59 additions & 0 deletions tests/Integration/Routing/SerializableClosureV1CacheRouteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace Illuminate\Tests\Integration\Route;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Orchestra\Testbench\Attributes\WithConfig;
use Orchestra\Testbench\Attributes\WithMigration;
use Orchestra\Testbench\Factories\UserFactory;
use Orchestra\Testbench\TestCase;
use PHPUnit\Framework\Attributes\RequiresOperatingSystemFamily;

use function Illuminate\Filesystem\join_paths;

#[RequiresOperatingSystemFamily('Linux|Darwin')]
#[WithConfig('app.key', 'AckfSECXIvnK5r28GVIWUAxmbBSjTsmF')]
#[WithMigration]
class SerializableClosureV1CacheRouteTest extends TestCase
{
use RefreshDatabase;

/** {@inheritDoc} */
#[\Override]
protected function getPackageProviders($app)
{
return [
\Illuminate\Foundation\Support\Providers\RouteServiceProvider::class,
];
}

/** {@inheritDoc} */
#[\Override]
protected function setUp(): void
{
$_ENV['APP_ROUTES_CACHE'] = realpath(join_paths(__DIR__, 'stubs', 'serializable-closure-v1', 'routes-v7.php'));

parent::setUp();
}

/** {@inheritDoc} */
#[\Override]
protected function tearDown(): void
{
unset($_ENV['APP_ROUTES_CACHE']);

parent::tearDown();
}

public function testItCanUseCachedRouteFromSerializableClosureV1()
{
$user = UserFactory::new()->create();

$this->assertTrue($this->app->routesAreCached());

$this->get('/')->assertSee('Laravel');

$this->get("/users/{$user->getKey()}")
->assertJson($user->toArray());
}
}
120 changes: 120 additions & 0 deletions tests/Integration/Routing/stubs/serializable-closure-v1/routes-v7.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

app('router')->setCompiledRoutes(
[
'compiled' => [
0 => false,
1 => [
'/' => [
0 => [
0 => [
'_route' => 'generated::7CFionvE02fEbBNP',
],
1 => null,
2 => [
'GET' => 0,
'HEAD' => 1,
],
3 => null,
4 => false,
5 => false,
6 => null,
],
],
],
2 => [
0 => '{^(?|/users/([^/]++)(*:22))/?$}sDu',
],
3 => [
22 => [
0 => [
0 => [
'_route' => 'generated::YmZUvOCRFrqhC2sO',
],
1 => [
0 => 'user',
],
2 => [
'GET' => 0,
'HEAD' => 1,
],
3 => null,
4 => false,
5 => true,
6 => null,
],
1 => [
0 => null,
1 => null,
2 => null,
3 => null,
4 => false,
5 => false,
6 => 0,
],
],
],
4 => null,
],
'attributes' => [
'generated::7CFionvE02fEbBNP' => [
'methods' => [
0 => 'GET',
1 => 'HEAD',
],
'uri' => '/',
'action' => [
'middleware' => [
0 => 'web',
],
'uses' => 'O:55:"Laravel\\SerializableClosure\\UnsignedSerializableClosure":1:{s:12:"serializable";O:46:"Laravel\\SerializableClosure\\Serializers\\Native":5:{s:3:"use";a:0:{}s:8:"function";s:44:"function () {
return \\view(\'welcome\');
}";s:5:"scope";s:37:"Illuminate\\Routing\\RouteFileRegistrar";s:4:"this";N;s:4:"self";s:32:"00000000000002f00000000000000000";}}',
'namespace' => null,
'prefix' => '',
'where' => [
],
'as' => 'generated::7CFionvE02fEbBNP',
],
'fallback' => false,
'defaults' => [
],
'wheres' => [
],
'bindingFields' => [
],
'lockSeconds' => null,
'waitSeconds' => null,
'withTrashed' => false,
],
'generated::YmZUvOCRFrqhC2sO' => [
'methods' => [
0 => 'GET',
1 => 'HEAD',
],
'uri' => 'users/{user}',
'action' => [
'middleware' => [
0 => 'web',
],
'uses' => 'O:55:"Laravel\\SerializableClosure\\UnsignedSerializableClosure":1:{s:12:"serializable";O:46:"Laravel\\SerializableClosure\\Serializers\\Native":5:{s:3:"use";a:0:{}s:8:"function";s:52:"fn (\\Illuminate\\Foundation\\Auth\\User $user) => $user";s:5:"scope";s:37:"Illuminate\\Routing\\RouteFileRegistrar";s:4:"this";N;s:4:"self";s:32:"00000000000002f20000000000000000";}}',
'namespace' => null,
'prefix' => '',
'where' => [
],
'as' => 'generated::YmZUvOCRFrqhC2sO',
],
'fallback' => false,
'defaults' => [
],
'wheres' => [
],
'bindingFields' => [
],
'lockSeconds' => null,
'waitSeconds' => null,
'withTrashed' => false,
],
],
]
);

0 comments on commit c272db4

Please sign in to comment.