Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added methods to QueueFake to work with listeners #54056

Closed
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
147 changes: 144 additions & 3 deletions src/Illuminate/Support/Testing/Fakes/QueueFake.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use BadMethodCallException;
use Closure;
use Illuminate\Contracts\Queue\Queue;
use Illuminate\Events\CallQueuedListener;
use Illuminate\Queue\CallQueuedClosure;
use Illuminate\Queue\QueueManager;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -43,6 +44,13 @@ class QueueFake extends QueueManager implements Fake, Queue
*/
protected $jobs = [];

/**
* All of the listeners that have been pushed.
*
* @var array
*/
protected $listeners = [];

/**
* Indicates if items should be serialized and restored when pushed to the queue.
*
Expand Down Expand Up @@ -103,6 +111,29 @@ public function assertPushed($job, $callback = null)
);
}

/**
* Assert if a listener was pushed based on a truth-test callback.
*
* @param string|\Closure $listener
* @param callable|int|null $callback
* @return void
*/
public function assertListenerPushed($listener, $callback = null)
{
if ($listener instanceof Closure) {
[$listener, $callback] = [$this->firstClosureParameterType($listener), $listener];
}

if (is_numeric($callback)) {
return $this->assertListenerPushedTimes($listener, $callback);
}

PHPUnit::assertTrue(
$this->listenersPushed($listener, $callback)->count() > 0,
"The expected [{$listener}] listener was not pushed."
);
}

/**
* Assert if a job was pushed a number of times.
*
Expand All @@ -120,6 +151,23 @@ protected function assertPushedTimes($job, $times = 1)
);
}

/**
* Assert if a listener was pushed a number of times.
*
* @param string $listener
* @param int $times
* @return void
*/
protected function assertListenerPushedTimes($listener, $times = 1)
{
$count = $this->listenersPushed($listener)->count();

PHPUnit::assertSame(
$times, $count,
"The expected [{$listener}] listener was pushed {$count} times instead of {$times} times."
);
}

/**
* Assert if a job was pushed based on a truth-test callback.
*
Expand All @@ -143,6 +191,29 @@ public function assertPushedOn($queue, $job, $callback = null)
});
}

/**
* Assert if a listener was pushed based on a truth-test callback.
*
* @param string $queue
* @param string|\Closure $listener
* @param callable|null $callback
* @return void
*/
public function assertListenerPushedOn($queue, $listener, $callback = null)
{
if ($listener instanceof Closure) {
[$listener, $callback] = [$this->firstClosureParameterType($listener), $listener];
}

$this->assertListenerPushed($listener, function ($listener, $pushedQueue) use ($callback, $queue) {
if ($pushedQueue !== $queue) {
return false;
}

return $callback ? $callback(...func_get_args()) : true;
});
}

/**
* Assert if a job was pushed with chained jobs based on a truth-test callback.
*
Expand Down Expand Up @@ -278,6 +349,25 @@ public function assertNotPushed($job, $callback = null)
);
}

/**
* Determine if a listener was pushed based on a truth-test callback.
*
* @param string|\Closure $listener
* @param callable|null $callback
* @return void
*/
public function assertListenerNotPushed($listener, $callback = null)
{
if ($listener instanceof Closure) {
[$listener, $callback] = [$this->firstClosureParameterType($listener), $listener];
}

PHPUnit::assertCount(
0, $this->listenersPushed($listener, $callback),
"The unexpected [{$listener}] listener was pushed."
);
}

/**
* Assert the total count of jobs that were pushed.
*
Expand Down Expand Up @@ -326,6 +416,34 @@ public function pushed($job, $callback = null)
)->pluck('job');
}

/**
* Get all of the listeners matching a truth-test callback.
*
* @param string $listener
* @param callable|null $callback
* @return \Illuminate\Support\Collection
*/
public function listenersPushed($listener, $callback = null)
{
if (! $this->hasListenerPushed($listener)) {
return new Collection;
}

$callback = $callback ?: fn () => true;

return (new Collection($this->listeners[$listener]))
->filter(
function ($data) use ($callback) {
return $callback(
new $data['job']->class,
$data['queue'],
$data['data'],
);
}
)
->pluck('job');
}

/**
* Determine if there are any stored jobs for a given class.
*
Expand All @@ -337,6 +455,17 @@ public function hasPushed($job)
return isset($this->jobs[$job]) && ! empty($this->jobs[$job]);
}

/**
* Determine if there are any stored listeners for a given class.
*
* @param string $listener
* @return bool
*/
public function hasListenerPushed($listener)
{
return isset($this->listeners[$listener]) && ! empty($this->listeners[$listener]);
}

/**
* Resolve a queue connection instance.
*
Expand Down Expand Up @@ -376,6 +505,14 @@ public function push($job, $data = '', $queue = null)
$job = CallQueuedClosure::create($job);
}

if ($job instanceof CallQueuedListener) {
$this->listeners[$job->displayName()][] = [
'job' => $this->serializeAndRestore ? $this->serializeAndRestoreJob($job) : $job,
'queue' => $queue,
'data' => $job->data,
];
}

$this->jobs[is_object($job) ? get_class($job) : $job][] = [
'job' => $this->serializeAndRestore ? $this->serializeAndRestoreJob($job) : $job,
'queue' => $queue,
Expand All @@ -391,7 +528,7 @@ public function push($job, $data = '', $queue = null)
/**
* Determine if a job should be faked or actually dispatched.
*
* @param object $job
* @param string|object $job
* @return bool
*/
public function shouldFakeJob($job)
Expand All @@ -405,14 +542,16 @@ public function shouldFakeJob($job)
}

return $this->jobsToFake->contains(
fn ($jobToFake) => $job instanceof ((string) $jobToFake) || $job === (string) $jobToFake
fn ($jobToFake) => $job instanceof ((string) $jobToFake)
|| ($job instanceof CallQueuedListener && $job->displayName() === (string) $jobToFake)
|| $job === (string) $jobToFake
);
}

/**
* Determine if a job should be pushed to the queue instead of faked.
*
* @param object $job
* @param string|object $job
* @return bool
*/
protected function shouldDispatchJob($job)
Expand All @@ -423,6 +562,8 @@ protected function shouldDispatchJob($job)

return $this->jobsToBeQueued->contains(
fn ($jobToQueue) => $job instanceof ((string) $jobToQueue)
|| ($job instanceof CallQueuedListener && $job->displayName() === (string) $jobToQueue)
|| $job === (string) $jobToQueue
);
}

Expand Down
3 changes: 3 additions & 0 deletions tests/Events/QueuedEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public function testCustomizedQueuedEventHandlersAreQueued()
$d->dispatch('some.event', ['foo', 'bar']);

$fakeQueue->assertPushedOn('my_queue', CallQueuedListener::class);
$fakeQueue->assertListenerPushedOn('my_queue', TestDispatcherConnectionQueuedHandler::class);
}

public function testQueueIsSetByGetQueue()
Expand All @@ -66,6 +67,7 @@ public function testQueueIsSetByGetQueue()
$d->dispatch('some.event', ['foo', 'bar']);

$fakeQueue->assertPushedOn('some_other_queue', CallQueuedListener::class);
$fakeQueue->assertListenerPushedOn('some_other_queue', TestDispatcherGetQueue::class);
}

public function testQueueIsSetByGetConnection()
Expand Down Expand Up @@ -116,6 +118,7 @@ public function testQueueIsSetByGetQueueDynamically()
$d->dispatch('some.event', [['useHighPriorityQueue' => true], 'bar']);

$fakeQueue->assertPushedOn('p0', CallQueuedListener::class);
$fakeQueue->assertListenerPushedOn('p0', TestDispatcherGetQueueDynamically::class);
}

public function testQueueIsSetByGetConnectionDynamically()
Expand Down
2 changes: 2 additions & 0 deletions tests/Integration/Queue/QueuedListenersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ public function testListenersCanBeQueuedOptionally()
Queue::assertPushed(CallQueuedListener::class, function ($job) {
return $job->class == QueuedListenersTestListenerShouldQueue::class;
});
Queue::assertListenerPushed(QueuedListenersTestListenerShouldQueue::class);

Queue::assertNotPushed(CallQueuedListener::class, function ($job) {
return $job->class == QueuedListenersTestListenerShouldNotQueue::class;
});
Queue::assertListenerNotPushed(QueuedListenersTestListenerShouldNotQueue::class);
}
}

Expand Down
Loading