22
33namespace WpOrg \Requests \Tests ;
44
5+ use Closure ;
6+ use stdClass ;
7+ use WpOrg \Requests \Exception \InvalidArgument ;
58use WpOrg \Requests \Hooks ;
9+ use WpOrg \Requests \Tests \Fixtures \ArrayAccessibleObject ;
10+ use WpOrg \Requests \Tests \Fixtures \StringableObject ;
611use WpOrg \Requests \Tests \TestCase ;
712
813/**
@@ -70,8 +75,11 @@ public function testRegister() {
7075 'Registering a second callback on the same hook with the same priority failed '
7176 );
7277
73- // Verify that new subkeys are created when needed.
74- $ this ->hooks ->register ('hookname ' , 'is_int ' , 10 );
78+ /*
79+ * Verify that new subkeys are created when needed.
80+ * Also verifies that the input validation isn't too strict for the priority.
81+ */
82+ $ this ->hooks ->register ('hookname ' , 'is_int ' , '10 ' );
7583 $ this ->assertSame (
7684 array (
7785 'hookname ' => array (
@@ -89,6 +97,29 @@ public function testRegister() {
8997 );
9098 }
9199
100+ /**
101+ * Technical test to verify and safeguard Hooks::register() accepts closure callbacks.
102+ *
103+ * @covers ::register
104+ *
105+ * @return void
106+ */
107+ public function testRegisterClosureCallback () {
108+ $ this ->hooks ->register (
109+ 'hookname ' ,
110+ function ($ param ) {
111+ return true ;
112+ }
113+ );
114+
115+ $ hooks_prop = $ this ->getPropertyValue ($ this ->hooks , 'hooks ' );
116+
117+ $ this ->assertArrayHasKey ('hookname ' , $ hooks_prop , '$hooks property does not have key ["hookname"] ' );
118+ $ this ->assertArrayHasKey (0 , $ hooks_prop ['hookname ' ], '$hooks property does not have key ["hookname"][0] ' );
119+ $ this ->assertArrayHasKey (0 , $ hooks_prop ['hookname ' ][0 ], '$hooks property does not have key ["hookname"][0][0] ' );
120+ $ this ->assertInstanceof (Closure::class, $ hooks_prop ['hookname ' ][0 ][0 ], 'Closure callback is not registered correctly ' );
121+ }
122+
92123
93124 /**
94125 * Verify that the return value of the dispatch method is false when no hooks are registered.
@@ -171,6 +202,152 @@ public function testDispatchWithMultipleRegisteredHooks() {
171202 $ this ->assertTrue ($ this ->hooks ->dispatch ('hook_b ' , array (10 , 'text ' )));
172203 }
173204
205+ /**
206+ * Tests receiving an exception when an invalid input type is passed to `register()` as `$hook`.
207+ *
208+ * @dataProvider dataInvalidHookname
209+ *
210+ * @covers ::register
211+ *
212+ * @param mixed $input Invalid hook name input.
213+ *
214+ * @return void
215+ */
216+ public function testRegisterInvalidHookname ($ input ) {
217+ $ this ->expectException (InvalidArgument::class);
218+ $ this ->expectExceptionMessage ('Argument #1 ($hook) must be of type string ' );
219+
220+ $ this ->hooks ->register ($ input , 'is_string ' );
221+ }
222+
223+ /**
224+ * Tests receiving an exception when an invalid input type is passed to `dispatch()` as `$hook`.
225+ *
226+ * @dataProvider dataInvalidHookname
227+ *
228+ * @covers ::dispatch
229+ *
230+ * @param mixed $input Invalid hook name input.
231+ *
232+ * @return void
233+ */
234+ public function testDispatchInvalidHookname ($ input ) {
235+ $ this ->expectException (InvalidArgument::class);
236+ $ this ->expectExceptionMessage ('Argument #1 ($hook) must be of type string ' );
237+
238+ $ this ->hooks ->dispatch ($ input );
239+ }
240+
241+ /**
242+ * Data Provider.
243+ *
244+ * @return array
245+ */
246+ public function dataInvalidHookname () {
247+ return array (
248+ 'null ' => array (null ),
249+ 'float ' => array (1.1 ),
250+ 'stringable object ' => array (new StringableObject ('value ' )),
251+ );
252+ }
253+
254+ /**
255+ * Tests receiving an exception when an invalid input type is passed to `register()` as `$callback`.
256+ *
257+ * @dataProvider dataRegisterInvalidCallback
258+ *
259+ * @covers ::register
260+ *
261+ * @param mixed $input Invalid callback.
262+ *
263+ * @return void
264+ */
265+ public function testRegisterInvalidCallback ($ input ) {
266+ $ this ->expectException (InvalidArgument::class);
267+ $ this ->expectExceptionMessage ('Argument #2 ($callback) must be of type callable ' );
268+
269+ $ this ->hooks ->register ('hookname ' , $ input );
270+ }
271+
272+ /**
273+ * Data Provider.
274+ *
275+ * @return array
276+ */
277+ public function dataRegisterInvalidCallback () {
278+ return array (
279+ 'null ' => array (null ),
280+ 'non-existent function ' => array ('functionname ' ),
281+ 'non-existent method ' => array (array ($ this , 'dummyCallbackDoesNotExist ' )),
282+ 'empty array ' => array (array ()),
283+ 'plain object ' => array (new stdClass (), 'method ' ),
284+ );
285+ }
286+
287+ /**
288+ * Tests receiving an exception when an invalid input type is passed to `register()` as `$priority`.
289+ *
290+ * @dataProvider dataRegisterInvalidPriority
291+ *
292+ * @covers ::register
293+ *
294+ * @param mixed $input Invalid priority.
295+ *
296+ * @return void
297+ */
298+ public function testRegisterInvalidPriority ($ input ) {
299+ $ this ->expectException (InvalidArgument::class);
300+ $ this ->expectExceptionMessage ('Argument #3 ($priority) must be of type int ' );
301+
302+ $ this ->hooks ->register ('hookname ' , array ($ this , 'dummyCallback1 ' ), $ input );
303+ }
304+
305+ /**
306+ * Data Provider.
307+ *
308+ * @return array
309+ */
310+ public function dataRegisterInvalidPriority () {
311+ return array (
312+ 'null ' => array (null ),
313+ 'float ' => array (1.1 ),
314+ 'string "123 abc" ' => array ('123 abc ' ),
315+ );
316+ }
317+
318+ /**
319+ * Tests receiving an exception when an invalid input type is passed to `dispatch()` as `$parameters`.
320+ *
321+ * @dataProvider dataDispatchInvalidParameters
322+ *
323+ * @covers ::dispatch
324+ *
325+ * @param mixed $input Invalid parameters array.
326+ *
327+ * @return void
328+ */
329+ public function testDispatchInvalidParameters ($ input ) {
330+ $ this ->expectException (InvalidArgument::class);
331+ $ this ->expectExceptionMessage ('Argument #2 ($parameters) must be of type array ' );
332+
333+ $ this ->hooks ->dispatch ('hookname ' , $ input );
334+ }
335+
336+ /**
337+ * Data Provider.
338+ *
339+ * @return array
340+ */
341+ public function dataDispatchInvalidParameters () {
342+ return array (
343+ 'null ' => array (null ),
344+ 'bool false ' => array (false ),
345+ 'float ' => array (1.1 ),
346+ 'string ' => array ('param ' ),
347+ 'object implementing ArrayAccess ' => array (new ArrayAccessibleObject ()),
348+ );
349+ }
350+
174351 /**
175352 * Dummy callback method.
176353 *
0 commit comments