12
12
use Illuminate \Support \Arr ;
13
13
use Illuminate \Support \Collection ;
14
14
use Illuminate \Support \Testing \Fakes \Fake ;
15
- use Illuminate \Support \Traits \ReflectsClosures ;
16
- use PHPUnit \Framework \Assert as PHPUnit ;
17
15
18
16
class FakeDispatcher extends ActualDispatcher implements Fake
19
17
{
20
- use ReflectsClosures ;
18
+ use ActionRecording ;
21
19
22
20
/**
23
21
* List of actions to fake
@@ -34,11 +32,11 @@ class FakeDispatcher extends ActualDispatcher implements Fake
34
32
protected array $ actionsToDispatch = [];
35
33
36
34
/**
37
- * List of actions that have run this session
35
+ * List of actions to allow execution even if faked
38
36
*
39
- * @var array<class-string<Actionable>,array<Actionable> >
37
+ * @var array<class-string<Actionable>, bool >
40
38
*/
41
- protected array $ actions = [];
39
+ protected array $ actionsAllowed = [];
42
40
43
41
/**
44
42
* Flag to determine if the actions should still execute
@@ -56,6 +54,7 @@ public function __construct(
56
54
) {
57
55
parent ::__construct ($ container , $ events , $ db );
58
56
$ this ->actionsToFake = Arr::wrap ($ actionsToFake );
57
+ $ this ->enableRecording ();
59
58
}
60
59
61
60
/**
@@ -124,18 +123,36 @@ public function disallowExecution(): static
124
123
return $ this ;
125
124
}
126
125
126
+ public function allow (array |string $ actions ): static
127
+ {
128
+ foreach (Arr::wrap ($ actions ) as $ action ) {
129
+ $ this ->actionsAllowed [$ action ] = true ;
130
+ }
131
+
132
+ return $ this ;
133
+ }
134
+
135
+ public function disallow (array |string $ actions ): static
136
+ {
137
+ foreach (Arr::wrap ($ actions ) as $ action ) {
138
+ $ this ->actionsAllowed [$ action ] = false ;
139
+ }
140
+
141
+ return $ this ;
142
+ }
143
+
127
144
/**
128
145
* Dispatch the given action
129
146
*/
130
147
public function dispatch (Actionable $ action ): mixed
131
148
{
132
- $ this ->actions [ get_class ($ action )][] = $ action ;
149
+ $ this ->recordAction ($ action );
133
150
134
151
if (! $ this ->shouldFakeJob ($ action )) {
135
152
return parent ::dispatch ($ action );
136
153
}
137
154
138
- if ($ this ->executeActions ) {
155
+ if ($ this ->shouldHandleReal ( $ action ) ) {
139
156
return parent ::dispatch ($ action );
140
157
}
141
158
@@ -168,6 +185,27 @@ protected function shouldFakeJob(Actionable $action): bool
168
185
->isNotEmpty ();
169
186
}
170
187
188
+ protected function shouldHandleReal (Actionable $ action ): bool
189
+ {
190
+ /**
191
+ * If this action is allowed to run
192
+ */
193
+ $ explicit = $ this ->actionsAllowed [$ action ::class] ?? null ;
194
+
195
+ if ($ explicit !== null ) {
196
+ return $ explicit ;
197
+ }
198
+
199
+ /**
200
+ * If all execution is allowed
201
+ */
202
+ if ($ this ->executeActions ) {
203
+ return true ;
204
+ }
205
+
206
+ return false ;
207
+ }
208
+
171
209
/**
172
210
* Determine if a command should be dispatched or not.
173
211
*/
@@ -181,105 +219,4 @@ protected function shouldDispatchCommand(Actionable $action): bool
181
219
})
182
220
->isNotEmpty ();
183
221
}
184
-
185
- /**
186
- * Assert if a job was dispatched based on a truth-test callback.
187
- */
188
- public function assertDispatched (Closure |string $ command , Closure |int |null $ callback = null ): static
189
- {
190
- if ($ command instanceof Closure) {
191
- [$ command , $ callback ] = [$ this ->firstClosureParameterType ($ command ), $ command ];
192
- /** @var class-string<Actionable> $command */
193
- /** @var Closure $callback */
194
- }
195
-
196
- if (is_int ($ callback )) {
197
- return $ this ->assertDispatchedTimes ($ command , $ callback );
198
- }
199
-
200
- PHPUnit::assertTrue (
201
- $ this ->dispatched ($ command , $ callback )->count () > 0 ,
202
- "The expected [ {$ command }] job was not dispatched. " ,
203
- );
204
-
205
- return $ this ;
206
- }
207
-
208
- /**
209
- * Assert if a job was pushed a number of times.
210
- */
211
- public function assertDispatchedTimes (Closure |string $ command , int $ times = 1 ): static
212
- {
213
- $ callback = null ;
214
-
215
- if ($ command instanceof Closure) {
216
- [$ command , $ callback ] = [$ this ->firstClosureParameterType ($ command ), $ command ];
217
- /** @var class-string<Actionable> $command */
218
- /** @var Closure $callback */
219
- }
220
-
221
- $ count = $ this ->dispatched ($ command , $ callback )->count ();
222
-
223
- PHPUnit::assertSame (
224
- $ times ,
225
- $ count ,
226
- "The expected [ {$ command }] action was dispatched {$ count } times instead of {$ times } times. " ,
227
- );
228
-
229
- return $ this ;
230
- }
231
-
232
- /**
233
- * Determine if a job was dispatched based on a truth-test callback.
234
- */
235
- public function assertNotDispatched (Closure |string $ command , ?Closure $ callback = null ): static
236
- {
237
- if ($ command instanceof Closure) {
238
- [$ command , $ callback ] = [$ this ->firstClosureParameterType ($ command ), $ command ];
239
- /** @var class-string<Actionable> $command */
240
- /** @var Closure $callback */
241
- }
242
-
243
- PHPUnit::assertTrue (
244
- $ this ->dispatched ($ command , $ callback )->count () === 0 ,
245
- "The unexpected [ {$ command }] action was dispatched. " ,
246
- );
247
-
248
- return $ this ;
249
- }
250
-
251
- /**
252
- * Assert that no jobs were dispatched.
253
- */
254
- public function assertNothingDispatched (): static
255
- {
256
- PHPUnit::assertEmpty ($ this ->actions , 'Actions were dispatched unexpectedly. ' );
257
-
258
- return $ this ;
259
- }
260
-
261
- /**
262
- * Get all of the jobs matching a truth-test callback.
263
- *
264
- * @return Collection<int, Actionable>
265
- */
266
- public function dispatched (string $ command , ?Closure $ callback = null ): Collection
267
- {
268
- if (! $ this ->hasDispatched ($ command )) {
269
- return Collection::make ();
270
- }
271
-
272
- $ callback = $ callback ?: fn () => true ;
273
-
274
- return Collection::make ($ this ->actions [$ command ])
275
- ->filter (fn (Actionable $ action ) => $ callback ($ action ));
276
- }
277
-
278
- /**
279
- * Determine if there are any stored commands for a given class.
280
- */
281
- public function hasDispatched (string $ action ): bool
282
- {
283
- return isset ($ this ->actions [$ action ]) && ! empty ($ this ->actions [$ action ]);
284
- }
285
222
}
0 commit comments