diff --git a/src/ActivityStub.php b/src/ActivityStub.php index 4d6b5f4..63990f2 100644 --- a/src/ActivityStub.php +++ b/src/ActivityStub.php @@ -32,18 +32,22 @@ public static function make($activity, ...$arguments): PromiseInterface ->whereIndex($context->index) ->first(); - $mocks = WorkflowStub::mocks(); + if (WorkflowStub::faked()) { + $mocks = WorkflowStub::mocks(); - if (! $log && array_key_exists($activity, $mocks)) { - $result = $mocks[$activity]; + if (! $log && array_key_exists($activity, $mocks)) { + $result = $mocks[$activity]; - $log = $context->storedWorkflow->logs() - ->create([ - 'index' => $context->index, - 'now' => $context->now, - 'class' => $activity, - 'result' => Y::serialize(is_callable($result) ? $result($context, ...$arguments) : $result), - ]); + $log = $context->storedWorkflow->logs() + ->create([ + 'index' => $context->index, + 'now' => $context->now, + 'class' => $activity, + 'result' => Y::serialize(is_callable($result) ? $result($context, ...$arguments) : $result), + ]); + + WorkflowStub::recordDispatched($activity, $arguments); + } } if ($log) { diff --git a/src/ChildWorkflowStub.php b/src/ChildWorkflowStub.php index 226bff4..5d20fb6 100644 --- a/src/ChildWorkflowStub.php +++ b/src/ChildWorkflowStub.php @@ -25,18 +25,22 @@ public static function make($workflow, ...$arguments): PromiseInterface ->whereIndex($context->index) ->first(); - $mocks = WorkflowStub::mocks(); + if (WorkflowStub::faked()) { + $mocks = WorkflowStub::mocks(); - if (! $log && array_key_exists($workflow, $mocks)) { - $result = $mocks[$workflow]; + if (! $log && array_key_exists($workflow, $mocks)) { + $result = $mocks[$workflow]; - $log = $context->storedWorkflow->logs() - ->create([ - 'index' => $context->index, - 'now' => $context->now, - 'class' => $workflow, - 'result' => Y::serialize(is_callable($result) ? $result($context, ...$arguments) : $result), - ]); + $log = $context->storedWorkflow->logs() + ->create([ + 'index' => $context->index, + 'now' => $context->now, + 'class' => $workflow, + 'result' => Y::serialize(is_callable($result) ? $result($context, ...$arguments) : $result), + ]); + + WorkflowStub::recordDispatched($workflow, $arguments); + } } if ($log) { diff --git a/src/Traits/Fakes.php b/src/Traits/Fakes.php new file mode 100644 index 0000000..0f0f5bd --- /dev/null +++ b/src/Traits/Fakes.php @@ -0,0 +1,108 @@ +count() > 0, + "The expected [{$workflowOrActivity}] workflow/activity was not dispatched." + ); + }); + + static::macro('assertDispatchedTimes', static function (string $workflowOrActivity, int $times = 1) { + $count = self::dispatched($workflowOrActivity)->count(); + + \PHPUnit\Framework\Assert::assertSame( + $times, + $count, + "The expected [{$workflowOrActivity}] workflow/activity was dispatched {$count} times instead of {$times} times." + ); + }); + + static::macro('assertNotDispatched', static function (string $workflowOrActivity, $callback = null) { + \PHPUnit\Framework\Assert::assertTrue( + self::dispatched($workflowOrActivity, $callback)->count() === 0, + "The unexpected [{$workflowOrActivity}] workflow/activity was dispatched." + ); + }); + + static::macro('assertNothingDispatched', static function () { + $dispatched = App::make(self::$DISPATCHED_LIST); + \PHPUnit\Framework\Assert::assertTrue( + count($dispatched) === 0, + 'An unexpected workflow/activity was dispatched.' + ); + }); + + static::macro('dispatched', static function (string $workflowOrActivity, $callback = null): Collection { + $dispatched = App::make(self::$DISPATCHED_LIST); + if (! isset($dispatched[$workflowOrActivity])) { + return collect(); + } + + $callback = $callback ?: static fn () => true; + + return collect($dispatched[$workflowOrActivity])->filter( + static fn ($arguments) => $callback(...$arguments) + ); + }); + } +} diff --git a/src/WorkflowStub.php b/src/WorkflowStub.php index e42f4f4..2d76967 100644 --- a/src/WorkflowStub.php +++ b/src/WorkflowStub.php @@ -7,7 +7,7 @@ use Illuminate\Database\QueryException; use Illuminate\Support\Arr; use Illuminate\Support\Carbon; -use Illuminate\Support\Facades\App; +use Illuminate\Support\Traits\Macroable; use LimitIterator; use ReflectionClass; use SplFileObject; @@ -21,6 +21,7 @@ use Workflow\States\WorkflowPendingStatus; use Workflow\Traits\Awaits; use Workflow\Traits\AwaitWithTimeouts; +use Workflow\Traits\Fakes; use Workflow\Traits\SideEffects; use Workflow\Traits\Timers; @@ -28,11 +29,11 @@ final class WorkflowStub { use Awaits; use AwaitWithTimeouts; + use Fakes; + use Macroable; use SideEffects; use Timers; - public const MOCKS_LIST = 'workflow.mocks'; - private static ?\stdClass $context = null; private function __construct( @@ -84,40 +85,6 @@ public function __call($method, $arguments) } } - public static function fake(): void - { - App::bind(static::MOCKS_LIST, static function ($app) { - return []; - }); - } - - public static function faked(): bool - { - return App::bound(static::MOCKS_LIST); - } - - public static function mock($class, $result) - { - if (! static::faked()) { - return; - } - - $mocks = static::mocks(); - - App::bind(static::MOCKS_LIST, static function ($app) use ($mocks, $class, $result) { - $mocks[$class] = $result; - return $mocks; - }); - } - - public static function mocks() - { - if (! static::faked()) { - return []; - } - return App::make(static::MOCKS_LIST); - } - public static function connection() { return Arr::get( diff --git a/tests/Unit/WorkflowFakerTest.php b/tests/Unit/WorkflowFakerTest.php index bfb8b0b..bad1e79 100644 --- a/tests/Unit/WorkflowFakerTest.php +++ b/tests/Unit/WorkflowFakerTest.php @@ -26,9 +26,14 @@ public function testTimeTravelWorkflow(): void return 'other_activity'; }); + WorkflowStub::assertNothingDispatched(); + $workflow = WorkflowStub::make(TestTimeTravelWorkflow::class); $workflow->start(); + WorkflowStub::assertDispatched(TestOtherActivity::class, 1); + WorkflowStub::assertNotDispatched(TestActivity::class); + $this->assertFalse($workflow->isCanceled()); $this->assertNull($workflow->output()); @@ -41,6 +46,12 @@ public function testTimeTravelWorkflow(): void $this->assertTrue($workflow->isCanceled()); $this->assertSame($workflow->output(), 'workflow_activity_other_activity'); + + WorkflowStub::assertDispatched(TestOtherActivity::class, static function ($string) { + return $string === 'other'; + }); + + WorkflowStub::assertDispatched(TestActivity::class); } public function testParentWorkflow(): void @@ -54,6 +65,9 @@ public function testParentWorkflow(): void $workflow = WorkflowStub::make(TestParentWorkflow::class); $workflow->start(); + WorkflowStub::assertDispatchedTimes(TestActivity::class, 1); + WorkflowStub::assertDispatchedTimes(TestChildWorkflow::class, 1); + $this->assertSame($workflow->output(), 'workflow_activity_other_activity'); } @@ -71,6 +85,9 @@ public function testConcurrentWorkflow(): void $workflow = WorkflowStub::make(TestConcurrentWorkflow::class); $workflow->start(); + WorkflowStub::assertDispatched(TestActivity::class); + WorkflowStub::assertDispatched(TestOtherActivity::class); + $this->assertSame($workflow->output(), 'workflow_activity_other_activity'); } }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: