Skip to content

Commit

Permalink
Add option to configure custom job decorator classes (#225)
Browse files Browse the repository at this point in the history
  • Loading branch information
ksassnowski authored Feb 22, 2023
1 parent 5b03bbd commit 66c181b
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 20 deletions.
25 changes: 25 additions & 0 deletions src/ActionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@
namespace Lorisleiva\Actions;

use Illuminate\Console\Application as Artisan;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Routing\Router;
use Lorisleiva\Actions\Concerns\AsCommand;
use Lorisleiva\Actions\Concerns\AsController;
use Lorisleiva\Actions\Concerns\AsFake;
use Lorisleiva\Actions\Decorators\JobDecorator;
use Lorisleiva\Actions\Decorators\UniqueJobDecorator;
use Lorisleiva\Actions\DesignPatterns\DesignPattern;
use Lorisleiva\Lody\Lody;

class ActionManager
{
/** @var class-string<JobDecorator> */
public static string $jobDecorator = JobDecorator::class;

/** @var class-string<JobDecorator&ShouldBeUnique> */
public static string $uniqueJobDecorator = UniqueJobDecorator::class;

/** @var DesignPattern[] */
protected array $designPatterns = [];

Expand All @@ -23,6 +32,22 @@ public function __construct(array $designPatterns = [])
$this->setDesignPatterns($designPatterns);
}

/**
* @param class-string<JobDecorator> $jobDecoratorClass
*/
public static function useJobDecorator(string $jobDecoratorClass): void
{
static::$jobDecorator = $jobDecoratorClass;
}

/**
* @param class-string<JobDecorator&ShouldBeUnique> $uniqueJobDecoratorClass
*/
public static function useUniqueJobDecorator(string $uniqueJobDecoratorClass): void
{
static::$uniqueJobDecorator = $uniqueJobDecoratorClass;
}

public function setDesignPatterns(array $designPatterns): ActionManager
{
$this->designPatterns = $designPatterns;
Expand Down
9 changes: 5 additions & 4 deletions src/Concerns/AsJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Foundation\Bus\PendingDispatch;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Fluent;
use Lorisleiva\Actions\ActionManager;
use Lorisleiva\Actions\ActionPendingChain;
use Lorisleiva\Actions\Decorators\JobDecorator;
use Lorisleiva\Actions\Decorators\UniqueJobDecorator;
Expand All @@ -25,7 +26,7 @@ public static function makeJob(...$arguments): JobDecorator
return static::makeUniqueJob(...$arguments);
}

return new JobDecorator(static::class, ...$arguments);
return new ActionManager::$jobDecorator(static::class, ...$arguments);
}

/**
Expand All @@ -34,7 +35,7 @@ public static function makeJob(...$arguments): JobDecorator
*/
public static function makeUniqueJob(...$arguments): UniqueJobDecorator
{
return new UniqueJobDecorator(static::class, ...$arguments);
return new ActionManager::$uniqueJobDecorator(static::class, ...$arguments);
}

/**
Expand Down Expand Up @@ -122,8 +123,8 @@ public static function assertPushed($times = null, Closure $callback = null): vo
}

$decoratorClass = static::jobShouldBeUnique()
? UniqueJobDecorator::class
: JobDecorator::class;
? ActionManager::$uniqueJobDecorator
: ActionManager::$jobDecorator;

$count = Queue::pushed($decoratorClass, function (JobDecorator $job, $queue) use ($callback) {
if (! $job->decorates(static::class)) {
Expand Down
17 changes: 17 additions & 0 deletions tests/ActionManagerTest.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
<?php

use Lorisleiva\Actions\ActionManager;
use Lorisleiva\Actions\Decorators\JobDecorator;
use Lorisleiva\Actions\Decorators\UniqueJobDecorator;
use Lorisleiva\Actions\Facades\Actions;
use Lorisleiva\Actions\Tests\Stubs\CustomJobDecorator;
use Lorisleiva\Actions\Tests\Stubs\CustomUniqueJobDecorator;

it('resolves from the container', function () {
$manager = app(ActionManager::class);
Expand All @@ -21,3 +25,16 @@

expect($managerA)->toBe($managerB);
});

it('stores the configured job decorator classes', function () {
expect(ActionManager::$jobDecorator)->toBe(JobDecorator::class);
expect(ActionManager::$uniqueJobDecorator)->toBe(UniqueJobDecorator::class);
});

it('can register custom job decorator classes', function () {
ActionManager::useJobDecorator(CustomJobDecorator::class);
ActionManager::useUniqueJobDecorator(CustomUniqueJobDecorator::class);

expect(ActionManager::$jobDecorator)->toBe(CustomJobDecorator::class);
expect(ActionManager::$uniqueJobDecorator)->toBe(CustomUniqueJobDecorator::class);
});
15 changes: 9 additions & 6 deletions tests/AsJobTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Queue;
use Lorisleiva\Actions\ActionManager;
use Lorisleiva\Actions\Concerns\AsJob;
use Lorisleiva\Actions\Decorators\JobDecorator;
use Lorisleiva\Actions\Decorators\UniqueJobDecorator;
use Lorisleiva\Actions\Tests\Stubs\CustomJobDecorator;
use Lorisleiva\Actions\Tests\Stubs\CustomUniqueJobDecorator;

class AsJobTest
{
Expand Down Expand Up @@ -79,7 +82,7 @@ public function handle()
assertJobPushedWith(AsJobTest::class, $parameters);
});

it('can make a job statically', function () {
it('can make a job statically', function (string $expectedJobClass) {
// Given the following job parameters.
$parameters = [1, 'two', new Filesystem()];

Expand All @@ -90,7 +93,7 @@ public function handle()
dispatch($job);

// Then the created job is a JobDecorator that kept track of the action and its paremeters.
expect($job)->toBeInstanceOf(JobDecorator::class);
expect($job)->toBeInstanceOf($expectedJobClass);
expect($job->getAction())->toBeInstanceOf(AsJobTest::class);
expect($job->getParameters())->toBe($parameters);

Expand All @@ -99,16 +102,16 @@ public function handle()

// And the job was dispatched to the queue.
assertJobPushed(AsJobTest::class);
});
})->with('custom job decorators');

it('can make a unique job statically', function () {
it('can make a unique job statically', function (string $expectedJobClass) {
// When we make a unique job from the action.
$job = AsJobTest::makeUniqueJob();

// Then it returns a UniqueJobDecorator.
expect($job)->toBeInstanceOf(UniqueJobDecorator::class);
expect($job)->toBeInstanceOf($expectedJobClass);
expect($job)->toBeInstanceOf(ShouldBeUnique::class);
});
})->with('custom unique job decorators');

it('can be dispatched with overridden configurations', function () {
// When we dispatch a job with the following configurations.
Expand Down
16 changes: 8 additions & 8 deletions tests/AsJobWithAssertionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public function handle()

// Then we can assert it has been dispatched.
AsJobWithAssertionsTest::assertPushed();
});
})->with('custom job decorators');

it('asserts an action has been pushed - failure', function () {
// Given we don't dispatch the action.
Expand All @@ -55,15 +55,15 @@ public function handle()

// When we assert that it was pushed.
AsJobWithAssertionsTest::assertPushed();
});
})->with('custom job decorators');

it('asserts an action has not been pushed - success', function () {
// When we don't dispatch the action.
// ...

// Then we can assert it has not been dispatched.
AsJobWithAssertionsTest::assertNotPushed();
});
})->with('custom job decorators');

it('asserts an action has not been pushed - failure', function () {
// Given we dispatched the action.
Expand All @@ -75,7 +75,7 @@ public function handle()

// When we assert that it was not pushed.
AsJobWithAssertionsTest::assertNotPushed();
});
})->with('custom job decorators');

it('asserts an action has been pushed a given amount of times - success', function () {
// When we dispatch the action twice.
Expand All @@ -84,7 +84,7 @@ public function handle()

// Then we can assert it has been dispatched.
AsJobWithAssertionsTest::assertPushed(2);
});
})->with('custom job decorators');

it('asserts an action has been pushed a given amount of times - failure', function () {
// Given we dispatched the action twice.
Expand All @@ -97,7 +97,7 @@ public function handle()

// When we assert that it was pushed 3 times.
AsJobWithAssertionsTest::assertPushed(3);
});
})->with('custom job decorators');

it('asserts an action has been pushed on a given queue - success', function () {
// When we dispatch the action on "some-queue".
Expand All @@ -106,7 +106,7 @@ public function handle()

// Then we can assert it has been dispatched on that queue.
AsJobWithAssertionsTest::assertPushedOn('some-queue');
});
})->with('custom job decorators');

it('asserts an action has been pushed on a given queue - failure', function () {
// Given we dispatched the action on "some-queue".
Expand All @@ -119,4 +119,4 @@ public function handle()

// When we pushed it on some other queue.
AsJobWithAssertionsTest::assertPushedOn('some-other-queue');
});
})->with('custom job decorators');
3 changes: 2 additions & 1 deletion tests/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Str;
use Lorisleiva\Actions\ActionManager;
use Lorisleiva\Actions\Decorators\JobDecorator;
use Lorisleiva\Actions\Tests\Stubs\User;

Expand Down Expand Up @@ -46,7 +47,7 @@ function registerCommands(array $commands): void

function assertJobPushed(string $class, ?Closure $callback = null): void
{
Queue::assertPushed(JobDecorator::class, function (JobDecorator $job) use ($class, $callback) {
Queue::assertPushed(ActionManager::$jobDecorator, function (JobDecorator $job) use ($class, $callback) {
if (! $job->decorates($class)) {
return false;
}
Expand Down
29 changes: 28 additions & 1 deletion tests/Pest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
<?php

use Lorisleiva\Actions\ActionManager;
use Lorisleiva\Actions\Decorators\JobDecorator;
use Lorisleiva\Actions\Decorators\UniqueJobDecorator;
use Lorisleiva\Actions\Tests\Stubs\CustomJobDecorator;
use Lorisleiva\Actions\Tests\Stubs\CustomUniqueJobDecorator;
use Lorisleiva\Actions\Tests\TestCase;

uses(TestCase::class)->in(__DIR__);
uses(TestCase::class)
->afterEach(function () {
// Reset any custom job classes so they don't pollute other tests.
ActionManager::useJobDecorator(JobDecorator::class);
ActionManager::useUniqueJobDecorator(UniqueJobDecorator::class);
})
->in(__DIR__);

dataset('custom job decorators', [
'default job decorator class' => [JobDecorator::class],
'custom job decorator class' => function () {
ActionManager::useJobDecorator(CustomJobDecorator::class);
return CustomJobDecorator::class;
},
]);

dataset('custom unique job decorators', [
'default job decorator class' => [UniqueJobDecorator::class],
'custom job decorator class' => function () {
ActionManager::useUniqueJobDecorator(CustomUniqueJobDecorator::class);
return CustomUniqueJobDecorator::class;
},
]);
9 changes: 9 additions & 0 deletions tests/Stubs/CustomJobDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Lorisleiva\Actions\Tests\Stubs;

use Lorisleiva\Actions\Decorators\JobDecorator;

class CustomJobDecorator extends JobDecorator
{
}
9 changes: 9 additions & 0 deletions tests/Stubs/CustomUniqueJobDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Lorisleiva\Actions\Tests\Stubs;

use Lorisleiva\Actions\Decorators\UniqueJobDecorator;

class CustomUniqueJobDecorator extends UniqueJobDecorator
{
}

0 comments on commit 66c181b

Please sign in to comment.