Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Support\Testing\Fakes;
4
 
5
use BadMethodCallException;
6
use Closure;
7
use Illuminate\Contracts\Queue\Queue;
8
use Illuminate\Queue\QueueManager;
9
use Illuminate\Support\Collection;
10
use Illuminate\Support\Traits\ReflectsClosures;
11
use PHPUnit\Framework\Assert as PHPUnit;
12
 
13
class QueueFake extends QueueManager implements Queue
14
{
15
    use ReflectsClosures;
16
 
17
    /**
18
     * The original queue manager.
19
     *
20
     * @var \Illuminate\Contracts\Queue\Queue
21
     */
22
    protected $queue;
23
 
24
    /**
25
     * The job types that should be intercepted instead of pushed to the queue.
26
     *
27
     * @var \Illuminate\Support\Collection
28
     */
29
    protected $jobsToFake;
30
 
31
    /**
32
     * The job types that should be pushed to the queue and not intercepted.
33
     *
34
     * @var \Illuminate\Support\Collection
35
     */
36
    protected $jobsToBeQueued;
37
 
38
    /**
39
     * All of the jobs that have been pushed.
40
     *
41
     * @var array
42
     */
43
    protected $jobs = [];
44
 
45
    /**
46
     * Create a new fake queue instance.
47
     *
48
     * @param  \Illuminate\Contracts\Foundation\Application  $app
49
     * @param  array  $jobsToFake
50
     * @param  \Illuminate\Queue\QueueManager|null  $queue
51
     * @return void
52
     */
53
    public function __construct($app, $jobsToFake = [], $queue = null)
54
    {
55
        parent::__construct($app);
56
 
57
        $this->jobsToFake = Collection::wrap($jobsToFake);
58
        $this->jobsToBeQueued = Collection::make();
59
        $this->queue = $queue;
60
    }
61
 
62
    /**
63
     * Specify the jobs that should be queued instead of faked.
64
     *
65
     * @param  array|string  $jobsToBeQueued
66
     * @return $this
67
     */
68
    public function except($jobsToBeQueued)
69
    {
70
        $this->jobsToBeQueued = Collection::wrap($jobsToBeQueued)->merge($this->jobsToBeQueued);
71
 
72
        return $this;
73
    }
74
 
75
    /**
76
     * Assert if a job was pushed based on a truth-test callback.
77
     *
78
     * @param  string|\Closure  $job
79
     * @param  callable|int|null  $callback
80
     * @return void
81
     */
82
    public function assertPushed($job, $callback = null)
83
    {
84
        if ($job instanceof Closure) {
85
            [$job, $callback] = [$this->firstClosureParameterType($job), $job];
86
        }
87
 
88
        if (is_numeric($callback)) {
89
            return $this->assertPushedTimes($job, $callback);
90
        }
91
 
92
        PHPUnit::assertTrue(
93
            $this->pushed($job, $callback)->count() > 0,
94
            "The expected [{$job}] job was not pushed."
95
        );
96
    }
97
 
98
    /**
99
     * Assert if a job was pushed a number of times.
100
     *
101
     * @param  string  $job
102
     * @param  int  $times
103
     * @return void
104
     */
105
    protected function assertPushedTimes($job, $times = 1)
106
    {
107
        $count = $this->pushed($job)->count();
108
 
109
        PHPUnit::assertSame(
110
            $times, $count,
111
            "The expected [{$job}] job was pushed {$count} times instead of {$times} times."
112
        );
113
    }
114
 
115
    /**
116
     * Assert if a job was pushed based on a truth-test callback.
117
     *
118
     * @param  string  $queue
119
     * @param  string|\Closure  $job
120
     * @param  callable|null  $callback
121
     * @return void
122
     */
123
    public function assertPushedOn($queue, $job, $callback = null)
124
    {
125
        if ($job instanceof Closure) {
126
            [$job, $callback] = [$this->firstClosureParameterType($job), $job];
127
        }
128
 
129
        $this->assertPushed($job, function ($job, $pushedQueue) use ($callback, $queue) {
130
            if ($pushedQueue !== $queue) {
131
                return false;
132
            }
133
 
134
            return $callback ? $callback(...func_get_args()) : true;
135
        });
136
    }
137
 
138
    /**
139
     * Assert if a job was pushed with chained jobs based on a truth-test callback.
140
     *
141
     * @param  string  $job
142
     * @param  array  $expectedChain
143
     * @param  callable|null  $callback
144
     * @return void
145
     */
146
    public function assertPushedWithChain($job, $expectedChain = [], $callback = null)
147
    {
148
        PHPUnit::assertTrue(
149
            $this->pushed($job, $callback)->isNotEmpty(),
150
            "The expected [{$job}] job was not pushed."
151
        );
152
 
153
        PHPUnit::assertTrue(
154
            collect($expectedChain)->isNotEmpty(),
155
            'The expected chain can not be empty.'
156
        );
157
 
158
        $this->isChainOfObjects($expectedChain)
159
                ? $this->assertPushedWithChainOfObjects($job, $expectedChain, $callback)
160
                : $this->assertPushedWithChainOfClasses($job, $expectedChain, $callback);
161
    }
162
 
163
    /**
164
     * Assert if a job was pushed with an empty chain based on a truth-test callback.
165
     *
166
     * @param  string  $job
167
     * @param  callable|null  $callback
168
     * @return void
169
     */
170
    public function assertPushedWithoutChain($job, $callback = null)
171
    {
172
        PHPUnit::assertTrue(
173
            $this->pushed($job, $callback)->isNotEmpty(),
174
            "The expected [{$job}] job was not pushed."
175
        );
176
 
177
        $this->assertPushedWithChainOfClasses($job, [], $callback);
178
    }
179
 
180
    /**
181
     * Assert if a job was pushed with chained jobs based on a truth-test callback.
182
     *
183
     * @param  string  $job
184
     * @param  array  $expectedChain
185
     * @param  callable|null  $callback
186
     * @return void
187
     */
188
    protected function assertPushedWithChainOfObjects($job, $expectedChain, $callback)
189
    {
190
        $chain = collect($expectedChain)->map(fn ($job) => serialize($job))->all();
191
 
192
        PHPUnit::assertTrue(
193
            $this->pushed($job, $callback)->filter(fn ($job) => $job->chained == $chain)->isNotEmpty(),
194
            'The expected chain was not pushed.'
195
        );
196
    }
197
 
198
    /**
199
     * Assert if a job was pushed with chained jobs based on a truth-test callback.
200
     *
201
     * @param  string  $job
202
     * @param  array  $expectedChain
203
     * @param  callable|null  $callback
204
     * @return void
205
     */
206
    protected function assertPushedWithChainOfClasses($job, $expectedChain, $callback)
207
    {
208
        $matching = $this->pushed($job, $callback)->map->chained->map(function ($chain) {
209
            return collect($chain)->map(function ($job) {
210
                return get_class(unserialize($job));
211
            });
212
        })->filter(function ($chain) use ($expectedChain) {
213
            return $chain->all() === $expectedChain;
214
        });
215
 
216
        PHPUnit::assertTrue(
217
            $matching->isNotEmpty(), 'The expected chain was not pushed.'
218
        );
219
    }
220
 
221
    /**
222
     * Determine if the given chain is entirely composed of objects.
223
     *
224
     * @param  array  $chain
225
     * @return bool
226
     */
227
    protected function isChainOfObjects($chain)
228
    {
229
        return ! collect($chain)->contains(fn ($job) => ! is_object($job));
230
    }
231
 
232
    /**
233
     * Determine if a job was pushed based on a truth-test callback.
234
     *
235
     * @param  string|\Closure  $job
236
     * @param  callable|null  $callback
237
     * @return void
238
     */
239
    public function assertNotPushed($job, $callback = null)
240
    {
241
        if ($job instanceof Closure) {
242
            [$job, $callback] = [$this->firstClosureParameterType($job), $job];
243
        }
244
 
245
        PHPUnit::assertCount(
246
            0, $this->pushed($job, $callback),
247
            "The unexpected [{$job}] job was pushed."
248
        );
249
    }
250
 
251
    /**
252
     * Assert that no jobs were pushed.
253
     *
254
     * @return void
255
     */
256
    public function assertNothingPushed()
257
    {
258
        PHPUnit::assertEmpty($this->jobs, 'Jobs were pushed unexpectedly.');
259
    }
260
 
261
    /**
262
     * Get all of the jobs matching a truth-test callback.
263
     *
264
     * @param  string  $job
265
     * @param  callable|null  $callback
266
     * @return \Illuminate\Support\Collection
267
     */
268
    public function pushed($job, $callback = null)
269
    {
270
        if (! $this->hasPushed($job)) {
271
            return collect();
272
        }
273
 
274
        $callback = $callback ?: fn () => true;
275
 
276
        return collect($this->jobs[$job])->filter(
277
            fn ($data) => $callback($data['job'], $data['queue'], $data['data'])
278
        )->pluck('job');
279
    }
280
 
281
    /**
282
     * Determine if there are any stored jobs for a given class.
283
     *
284
     * @param  string  $job
285
     * @return bool
286
     */
287
    public function hasPushed($job)
288
    {
289
        return isset($this->jobs[$job]) && ! empty($this->jobs[$job]);
290
    }
291
 
292
    /**
293
     * Resolve a queue connection instance.
294
     *
295
     * @param  mixed  $value
296
     * @return \Illuminate\Contracts\Queue\Queue
297
     */
298
    public function connection($value = null)
299
    {
300
        return $this;
301
    }
302
 
303
    /**
304
     * Get the size of the queue.
305
     *
306
     * @param  string|null  $queue
307
     * @return int
308
     */
309
    public function size($queue = null)
310
    {
311
        return collect($this->jobs)->flatten(1)->filter(
312
            fn ($job) => $job['queue'] === $queue
313
        )->count();
314
    }
315
 
316
    /**
317
     * Push a new job onto the queue.
318
     *
319
     * @param  string|object  $job
320
     * @param  mixed  $data
321
     * @param  string|null  $queue
322
     * @return mixed
323
     */
324
    public function push($job, $data = '', $queue = null)
325
    {
326
        if ($this->shouldFakeJob($job)) {
327
            $this->jobs[is_object($job) ? get_class($job) : $job][] = [
328
                'job' => $job,
329
                'queue' => $queue,
330
                'data' => $data,
331
            ];
332
        } else {
333
            is_object($job) && isset($job->connection)
334
                ? $this->queue->connection($job->connection)->push($job, $data, $queue)
335
                : $this->queue->push($job, $data, $queue);
336
        }
337
    }
338
 
339
    /**
340
     * Determine if a job should be faked or actually dispatched.
341
     *
342
     * @param  object  $job
343
     * @return bool
344
     */
345
    public function shouldFakeJob($job)
346
    {
347
        if ($this->shouldDispatchJob($job)) {
348
            return false;
349
        }
350
 
351
        if ($this->jobsToFake->isEmpty()) {
352
            return true;
353
        }
354
 
355
        return $this->jobsToFake->contains(
356
            fn ($jobToFake) => $job instanceof ((string) $jobToFake)
357
        );
358
    }
359
 
360
    /**
361
     * Determine if a job should be pushed to the queue instead of faked.
362
     *
363
     * @param  object  $job
364
     * @return bool
365
     */
366
    protected function shouldDispatchJob($job)
367
    {
368
        if ($this->jobsToBeQueued->isEmpty()) {
369
            return false;
370
        }
371
 
372
        return $this->jobsToBeQueued->contains(
373
            fn ($jobToQueue) => $job instanceof ((string) $jobToQueue)
374
        );
375
    }
376
 
377
    /**
378
     * Push a raw payload onto the queue.
379
     *
380
     * @param  string  $payload
381
     * @param  string|null  $queue
382
     * @param  array  $options
383
     * @return mixed
384
     */
385
    public function pushRaw($payload, $queue = null, array $options = [])
386
    {
387
        //
388
    }
389
 
390
    /**
391
     * Push a new job onto the queue after (n) seconds.
392
     *
393
     * @param  \DateTimeInterface|\DateInterval|int  $delay
394
     * @param  string|object  $job
395
     * @param  mixed  $data
396
     * @param  string|null  $queue
397
     * @return mixed
398
     */
399
    public function later($delay, $job, $data = '', $queue = null)
400
    {
401
        return $this->push($job, $data, $queue);
402
    }
403
 
404
    /**
405
     * Push a new job onto the queue.
406
     *
407
     * @param  string  $queue
408
     * @param  string|object  $job
409
     * @param  mixed  $data
410
     * @return mixed
411
     */
412
    public function pushOn($queue, $job, $data = '')
413
    {
414
        return $this->push($job, $data, $queue);
415
    }
416
 
417
    /**
418
     * Push a new job onto a specific queue after (n) seconds.
419
     *
420
     * @param  string  $queue
421
     * @param  \DateTimeInterface|\DateInterval|int  $delay
422
     * @param  string|object  $job
423
     * @param  mixed  $data
424
     * @return mixed
425
     */
426
    public function laterOn($queue, $delay, $job, $data = '')
427
    {
428
        return $this->push($job, $data, $queue);
429
    }
430
 
431
    /**
432
     * Pop the next job off of the queue.
433
     *
434
     * @param  string|null  $queue
435
     * @return \Illuminate\Contracts\Queue\Job|null
436
     */
437
    public function pop($queue = null)
438
    {
439
        //
440
    }
441
 
442
    /**
443
     * Push an array of jobs onto the queue.
444
     *
445
     * @param  array  $jobs
446
     * @param  mixed  $data
447
     * @param  string|null  $queue
448
     * @return mixed
449
     */
450
    public function bulk($jobs, $data = '', $queue = null)
451
    {
452
        foreach ($jobs as $job) {
453
            $this->push($job, $data, $queue);
454
        }
455
    }
456
 
457
    /**
458
     * Get the jobs that have been pushed.
459
     *
460
     * @return array
461
     */
462
    public function pushedJobs()
463
    {
464
        return $this->jobs;
465
    }
466
 
467
    /**
468
     * Get the connection name for the queue.
469
     *
470
     * @return string
471
     */
472
    public function getConnectionName()
473
    {
474
        //
475
    }
476
 
477
    /**
478
     * Set the connection name for the queue.
479
     *
480
     * @param  string  $name
481
     * @return $this
482
     */
483
    public function setConnectionName($name)
484
    {
485
        return $this;
486
    }
487
 
488
    /**
489
     * Override the QueueManager to prevent circular dependency.
490
     *
491
     * @param  string  $method
492
     * @param  array  $parameters
493
     * @return mixed
494
     *
495
     * @throws \BadMethodCallException
496
     */
497
    public function __call($method, $parameters)
498
    {
499
        throw new BadMethodCallException(sprintf(
500
            'Call to undefined method %s::%s()', static::class, $method
501
        ));
502
    }
503
}