Commit | Line | Data |
141459fa |
1 | #!perl |
2 | |
3 | use strict; |
4 | use warnings; |
5 | |
6 | use FindBin; |
42da66a9 |
7 | use lib "$FindBin::Bin/../lib"; |
141459fa |
8 | |
9 | our $iters; |
10 | |
6b25e555 |
11 | BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; } |
141459fa |
12 | |
36c67dc1 |
13 | use Test::More; |
141459fa |
14 | use Catalyst::Test 'TestApp'; |
15 | |
16 | if ( $ENV{CAT_BENCHMARK} ) { |
17 | require Benchmark; |
18 | Benchmark::timethis( $iters, \&run_tests ); |
19 | } |
20 | else { |
21 | for ( 1 .. $iters ) { |
8a6a6581 |
22 | run_tests($_); |
141459fa |
23 | } |
24 | } |
922c58d6 |
25 | |
141459fa |
26 | sub run_tests { |
8a6a6581 |
27 | my ($run_number) = @_; |
d416846e |
28 | |
29 | # |
30 | # This is a simple test where the parent and child actions are |
31 | # within the same controller. |
32 | # |
141459fa |
33 | { |
34 | my @expected = qw[ |
5882c86e |
35 | TestApp::Controller::Action::Chained->begin |
36 | TestApp::Controller::Action::Chained->foo |
37 | TestApp::Controller::Action::Chained->endpoint |
38 | TestApp::Controller::Action::Chained->end |
141459fa |
39 | ]; |
922c58d6 |
40 | |
141459fa |
41 | my $expected = join( ", ", @expected ); |
922c58d6 |
42 | |
5882c86e |
43 | ok( my $response = request('http://localhost/chained/foo/1/end/2'), 'chained + local endpoint' ); |
141459fa |
44 | is( $response->header('X-Catalyst-Executed'), |
45 | $expected, 'Executed actions' ); |
46 | is( $response->content, '1; 2', 'Content OK' ); |
47 | } |
d416846e |
48 | |
49 | # |
50 | # This makes sure the above isn't found if the argument for the |
51 | # end action isn't supplied. |
52 | # |
53 | { |
54 | my $expected = undef; |
55 | |
5882c86e |
56 | ok( my $response = request('http://localhost/chained/foo/1/end'), |
57 | 'chained + local endpoint; missing last argument' ); |
d416846e |
58 | is( $response->header('X-Catalyst-Executed'), |
59 | $expected, 'Executed actions' ); |
10ae2631 |
60 | is( $response->code, 500, 'Status OK' ); |
d416846e |
61 | } |
62 | |
63 | # |
64 | # Tests the case when the child action is placed in a subcontroller. |
65 | # |
141459fa |
66 | { |
67 | my @expected = qw[ |
5882c86e |
68 | TestApp::Controller::Action::Chained->begin |
69 | TestApp::Controller::Action::Chained->foo |
70 | TestApp::Controller::Action::Chained::Foo->spoon |
71 | TestApp::Controller::Action::Chained->end |
141459fa |
72 | ]; |
922c58d6 |
73 | |
141459fa |
74 | my $expected = join( ", ", @expected ); |
922c58d6 |
75 | |
5882c86e |
76 | ok( my $response = request('http://localhost/chained/foo/1/spoon'), 'chained + subcontroller endpoint' ); |
141459fa |
77 | is( $response->header('X-Catalyst-Executed'), |
78 | $expected, 'Executed actions' ); |
79 | is( $response->content, '1; ', 'Content OK' ); |
80 | } |
d416846e |
81 | |
82 | # |
5882c86e |
83 | # Tests if the relative specification (e.g.: Chained('bar') ) works |
d416846e |
84 | # as expected. |
85 | # |
141459fa |
86 | { |
87 | my @expected = qw[ |
5882c86e |
88 | TestApp::Controller::Action::Chained->begin |
89 | TestApp::Controller::Action::Chained->bar |
90 | TestApp::Controller::Action::Chained->finale |
91 | TestApp::Controller::Action::Chained->end |
141459fa |
92 | ]; |
922c58d6 |
93 | |
141459fa |
94 | my $expected = join( ", ", @expected ); |
922c58d6 |
95 | |
5882c86e |
96 | ok( my $response = request('http://localhost/chained/bar/1/spoon'), 'chained + relative endpoint' ); |
141459fa |
97 | is( $response->header('X-Catalyst-Executed'), |
98 | $expected, 'Executed actions' ); |
99 | is( $response->content, '; 1, spoon', 'Content OK' ); |
100 | } |
d416846e |
101 | |
102 | # |
103 | # Just a test for multiple arguments. |
104 | # |
922c58d6 |
105 | { |
106 | my @expected = qw[ |
5882c86e |
107 | TestApp::Controller::Action::Chained->begin |
108 | TestApp::Controller::Action::Chained->foo2 |
109 | TestApp::Controller::Action::Chained->endpoint2 |
110 | TestApp::Controller::Action::Chained->end |
922c58d6 |
111 | ]; |
112 | |
113 | my $expected = join( ", ", @expected ); |
114 | |
5882c86e |
115 | ok( my $response = request('http://localhost/chained/foo2/10/20/end2/15/25'), |
116 | 'chained + local (2 args each)' ); |
922c58d6 |
117 | is( $response->header('X-Catalyst-Executed'), |
118 | $expected, 'Executed actions' ); |
119 | is( $response->content, '10, 20; 15, 25', 'Content OK' ); |
120 | } |
d416846e |
121 | |
122 | # |
123 | # The first three-chain test tries to call the action with :Args(1) |
1c34f703 |
124 | # specification. There's also a one action with a :CaptureArgs(1) |
d416846e |
125 | # attribute, that should not be dispatched to. |
126 | # |
922c58d6 |
127 | { |
128 | my @expected = qw[ |
5882c86e |
129 | TestApp::Controller::Action::Chained->begin |
130 | TestApp::Controller::Action::Chained->one_end |
131 | TestApp::Controller::Action::Chained->end |
922c58d6 |
132 | ]; |
133 | |
134 | my $expected = join( ", ", @expected ); |
135 | |
5882c86e |
136 | ok( my $response = request('http://localhost/chained/one/23'), |
922c58d6 |
137 | 'three-chain (only first)' ); |
138 | is( $response->header('X-Catalyst-Executed'), |
139 | $expected, 'Executed actions' ); |
140 | is( $response->content, '; 23', 'Content OK' ); |
141 | } |
d416846e |
142 | |
143 | # |
144 | # This is the second three-chain test, it goes for the action that |
145 | # handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action |
1c34f703 |
146 | # having :Args(2), not the one having :CaptureArgs(2). |
d416846e |
147 | # |
922c58d6 |
148 | { |
149 | my @expected = qw[ |
5882c86e |
150 | TestApp::Controller::Action::Chained->begin |
151 | TestApp::Controller::Action::Chained->one |
152 | TestApp::Controller::Action::Chained->two_end |
153 | TestApp::Controller::Action::Chained->end |
922c58d6 |
154 | ]; |
155 | |
156 | my $expected = join( ", ", @expected ); |
157 | |
5882c86e |
158 | ok( my $response = request('http://localhost/chained/one/23/two/23/46'), |
922c58d6 |
159 | 'three-chain (up to second)' ); |
160 | is( $response->header('X-Catalyst-Executed'), |
161 | $expected, 'Executed actions' ); |
162 | is( $response->content, '23; 23, 46', 'Content OK' ); |
163 | } |
d416846e |
164 | |
165 | # |
1c34f703 |
166 | # Last of the three-chain tests. Has no concurrent action with :CaptureArgs |
d416846e |
167 | # and is more thought to simply test the chain as a whole and the 'two' |
1c34f703 |
168 | # action specifying :CaptureArgs. |
d416846e |
169 | # |
922c58d6 |
170 | { |
171 | my @expected = qw[ |
5882c86e |
172 | TestApp::Controller::Action::Chained->begin |
173 | TestApp::Controller::Action::Chained->one |
174 | TestApp::Controller::Action::Chained->two |
175 | TestApp::Controller::Action::Chained->three_end |
176 | TestApp::Controller::Action::Chained->end |
922c58d6 |
177 | ]; |
178 | |
179 | my $expected = join( ", ", @expected ); |
180 | |
5882c86e |
181 | ok( my $response = request('http://localhost/chained/one/23/two/23/46/three/1/2/3'), |
922c58d6 |
182 | 'three-chain (all three)' ); |
183 | is( $response->header('X-Catalyst-Executed'), |
184 | $expected, 'Executed actions' ); |
185 | is( $response->content, '23, 23, 46; 1, 2, 3', 'Content OK' ); |
186 | } |
d416846e |
187 | |
188 | # |
189 | # Tests dispatching on number of arguments for :Args. This should be |
190 | # dispatched to the action expecting one argument. |
191 | # |
922c58d6 |
192 | { |
193 | my @expected = qw[ |
5882c86e |
194 | TestApp::Controller::Action::Chained->begin |
195 | TestApp::Controller::Action::Chained->multi1 |
196 | TestApp::Controller::Action::Chained->end |
922c58d6 |
197 | ]; |
198 | |
199 | my $expected = join( ", ", @expected ); |
200 | |
5882c86e |
201 | ok( my $response = request('http://localhost/chained/multi/23'), |
922c58d6 |
202 | 'multi-action (one arg)' ); |
203 | is( $response->header('X-Catalyst-Executed'), |
204 | $expected, 'Executed actions' ); |
205 | is( $response->content, '; 23', 'Content OK' ); |
206 | } |
d416846e |
207 | |
208 | # |
209 | # Belongs to the former test and goes for the action expecting two arguments. |
210 | # |
922c58d6 |
211 | { |
212 | my @expected = qw[ |
5882c86e |
213 | TestApp::Controller::Action::Chained->begin |
214 | TestApp::Controller::Action::Chained->multi2 |
215 | TestApp::Controller::Action::Chained->end |
922c58d6 |
216 | ]; |
217 | |
218 | my $expected = join( ", ", @expected ); |
219 | |
5882c86e |
220 | ok( my $response = request('http://localhost/chained/multi/23/46'), |
922c58d6 |
221 | 'multi-action (two args)' ); |
222 | is( $response->header('X-Catalyst-Executed'), |
223 | $expected, 'Executed actions' ); |
224 | is( $response->content, '; 23, 46', 'Content OK' ); |
225 | } |
d416846e |
226 | |
227 | # |
228 | # Dispatching on argument count again, this time we provide too many |
229 | # arguments, so dispatching should fail. |
230 | # |
231 | { |
232 | my $expected = undef; |
233 | |
5882c86e |
234 | ok( my $response = request('http://localhost/chained/multi/23/46/67'), |
d416846e |
235 | 'multi-action (three args, should lead to error)' ); |
236 | is( $response->header('X-Catalyst-Executed'), |
237 | $expected, 'Executed actions' ); |
10ae2631 |
238 | is( $response->code, 500, 'Status OK' ); |
d416846e |
239 | } |
240 | |
241 | # |
242 | # This tests the case when an action says it's the child of an action in |
243 | # a subcontroller. |
244 | # |
245 | { |
246 | my @expected = qw[ |
5882c86e |
247 | TestApp::Controller::Action::Chained->begin |
248 | TestApp::Controller::Action::Chained::Foo->higher_root |
249 | TestApp::Controller::Action::Chained->higher_root |
250 | TestApp::Controller::Action::Chained->end |
d416846e |
251 | ]; |
252 | |
253 | my $expected = join( ", ", @expected ); |
254 | |
5882c86e |
255 | ok( my $response = request('http://localhost/chained/higher_root/23/bar/11'), |
d416846e |
256 | 'root higher than child' ); |
257 | is( $response->header('X-Catalyst-Executed'), |
258 | $expected, 'Executed actions' ); |
259 | is( $response->content, '23; 11', 'Content OK' ); |
260 | } |
261 | |
262 | # |
263 | # Just a more complex version of the former test. It tests if a controller -> |
264 | # subcontroller -> controller dispatch works. |
265 | # |
266 | { |
267 | my @expected = qw[ |
5882c86e |
268 | TestApp::Controller::Action::Chained->begin |
269 | TestApp::Controller::Action::Chained->pcp1 |
270 | TestApp::Controller::Action::Chained::Foo->pcp2 |
271 | TestApp::Controller::Action::Chained->pcp3 |
272 | TestApp::Controller::Action::Chained->end |
d416846e |
273 | ]; |
274 | |
275 | my $expected = join( ", ", @expected ); |
276 | |
5882c86e |
277 | ok( my $response = request('http://localhost/chained/pcp1/1/pcp2/2/pcp3/3'), |
d416846e |
278 | 'parent -> child -> parent' ); |
279 | is( $response->header('X-Catalyst-Executed'), |
280 | $expected, 'Executed actions' ); |
281 | is( $response->content, '1, 2; 3', 'Content OK' ); |
282 | } |
283 | |
284 | # |
285 | # Tests dispatch on capture number. This test is for a one capture action. |
286 | # |
287 | { |
288 | my @expected = qw[ |
5882c86e |
289 | TestApp::Controller::Action::Chained->begin |
290 | TestApp::Controller::Action::Chained->multi_cap1 |
291 | TestApp::Controller::Action::Chained->multi_cap_end1 |
292 | TestApp::Controller::Action::Chained->end |
d416846e |
293 | ]; |
294 | |
295 | my $expected = join( ", ", @expected ); |
296 | |
5882c86e |
297 | ok( my $response = request('http://localhost/chained/multi_cap/1/baz'), |
d416846e |
298 | 'dispatch on capture num 1' ); |
299 | is( $response->header('X-Catalyst-Executed'), |
300 | $expected, 'Executed actions' ); |
301 | is( $response->content, '1; ', 'Content OK' ); |
302 | } |
303 | |
304 | # |
305 | # Belongs to the former test. This one goes for the action expecting two |
306 | # captures. |
307 | # |
308 | { |
309 | my @expected = qw[ |
5882c86e |
310 | TestApp::Controller::Action::Chained->begin |
311 | TestApp::Controller::Action::Chained->multi_cap2 |
312 | TestApp::Controller::Action::Chained->multi_cap_end2 |
313 | TestApp::Controller::Action::Chained->end |
d416846e |
314 | ]; |
315 | |
316 | my $expected = join( ", ", @expected ); |
317 | |
5882c86e |
318 | ok( my $response = request('http://localhost/chained/multi_cap/1/2/baz'), |
d416846e |
319 | 'dispatch on capture num 2' ); |
320 | is( $response->header('X-Catalyst-Executed'), |
321 | $expected, 'Executed actions' ); |
322 | is( $response->content, '1, 2; ', 'Content OK' ); |
323 | } |
324 | |
325 | # |
326 | # Tests the priority of a slurpy arguments action (with :Args) against |
327 | # two actions chained together. The two actions should win. |
328 | # |
329 | { |
330 | my @expected = qw[ |
5882c86e |
331 | TestApp::Controller::Action::Chained->begin |
332 | TestApp::Controller::Action::Chained->priority_a2 |
333 | TestApp::Controller::Action::Chained->priority_a2_end |
334 | TestApp::Controller::Action::Chained->end |
d416846e |
335 | ]; |
336 | |
337 | my $expected = join( ", ", @expected ); |
338 | |
5882c86e |
339 | ok( my $response = request('http://localhost/chained/priority_a/1/end/2'), |
d416846e |
340 | 'priority - slurpy args vs. parent/child' ); |
341 | is( $response->header('X-Catalyst-Executed'), |
342 | $expected, 'Executed actions' ); |
343 | is( $response->content, '1; 2', 'Content OK' ); |
344 | } |
345 | |
346 | # |
347 | # This belongs to the former test but tests if two chained actions have |
348 | # priority over an action with the exact arguments. |
349 | # |
350 | { |
351 | my @expected = qw[ |
5882c86e |
352 | TestApp::Controller::Action::Chained->begin |
353 | TestApp::Controller::Action::Chained->priority_b2 |
354 | TestApp::Controller::Action::Chained->priority_b2_end |
355 | TestApp::Controller::Action::Chained->end |
d416846e |
356 | ]; |
357 | |
358 | my $expected = join( ", ", @expected ); |
359 | |
5882c86e |
360 | ok( my $response = request('http://localhost/chained/priority_b/1/end/2'), |
d416846e |
361 | 'priority - fixed args vs. parent/child' ); |
362 | is( $response->header('X-Catalyst-Executed'), |
363 | $expected, 'Executed actions' ); |
364 | is( $response->content, '1; 2', 'Content OK' ); |
365 | } |
366 | |
367 | # |
b7ce908f |
368 | # This belongs to the former test but tests if two chained actions have |
369 | # priority over an action with one child action not having the Args() attr set. |
370 | # |
371 | { |
372 | my @expected = qw[ |
373 | TestApp::Controller::Action::Chained->begin |
374 | TestApp::Controller::Action::Chained->priority_c1 |
375 | TestApp::Controller::Action::Chained->priority_c2_xyz |
376 | TestApp::Controller::Action::Chained->end |
377 | ]; |
378 | |
379 | my $expected = join( ", ", @expected ); |
380 | |
381 | ok( my $response = request('http://localhost/chained/priority_c/1/xyz/'), |
382 | 'priority - no Args() order mismatch' ); |
383 | is( $response->header('X-Catalyst-Executed'), |
384 | $expected, 'Executed actions' ); |
385 | is( $response->content, '1; ', 'Content OK' ); |
386 | } |
387 | |
388 | # |
d416846e |
389 | # Test dispatching between two controllers that are on the same level and |
390 | # therefor have no parent/child relationship. |
391 | # |
392 | { |
393 | my @expected = qw[ |
5882c86e |
394 | TestApp::Controller::Action::Chained->begin |
395 | TestApp::Controller::Action::Chained::Bar->cross1 |
396 | TestApp::Controller::Action::Chained::Foo->cross2 |
397 | TestApp::Controller::Action::Chained->end |
d416846e |
398 | ]; |
399 | |
400 | my $expected = join( ", ", @expected ); |
401 | |
5882c86e |
402 | ok( my $response = request('http://localhost/chained/cross/1/end/2'), |
d416846e |
403 | 'cross controller w/o par/child relation' ); |
404 | is( $response->header('X-Catalyst-Executed'), |
405 | $expected, 'Executed actions' ); |
406 | is( $response->content, '1; 2', 'Content OK' ); |
407 | } |
b25353e5 |
408 | |
409 | # |
410 | # This is for testing if the arguments got passed to the actions |
411 | # correctly. |
412 | # |
413 | { |
414 | my @expected = qw[ |
5882c86e |
415 | TestApp::Controller::Action::Chained->begin |
416 | TestApp::Controller::Action::Chained::PassedArgs->first |
417 | TestApp::Controller::Action::Chained::PassedArgs->second |
418 | TestApp::Controller::Action::Chained::PassedArgs->third |
419 | TestApp::Controller::Action::Chained::PassedArgs->end |
b25353e5 |
420 | ]; |
421 | |
422 | my $expected = join( ", ", @expected ); |
423 | |
5882c86e |
424 | ok( my $response = request('http://localhost/chained/passedargs/a/1/b/2/c/3'), |
b25353e5 |
425 | 'Correct arguments passed to actions' ); |
426 | is( $response->header('X-Catalyst-Executed'), |
427 | $expected, 'Executed actions' ); |
428 | is( $response->content, '1; 2; 3', 'Content OK' ); |
429 | } |
47f9968d |
430 | |
431 | # |
432 | # The :Args attribute is optional, we check the action not specifying |
433 | # it with these tests. |
434 | # |
435 | { |
436 | my @expected = qw[ |
5882c86e |
437 | TestApp::Controller::Action::Chained->begin |
438 | TestApp::Controller::Action::Chained->opt_args |
439 | TestApp::Controller::Action::Chained->end |
47f9968d |
440 | ]; |
441 | |
442 | my $expected = join( ", ", @expected ); |
443 | |
5882c86e |
444 | ok( my $response = request('http://localhost/chained/opt_args/1/2/3'), |
47f9968d |
445 | 'Optional :Args attribute working' ); |
446 | is( $response->header('X-Catalyst-Executed'), |
447 | $expected, 'Executed actions' ); |
448 | is( $response->content, '; 1, 2, 3', 'Content OK' ); |
449 | } |
9cc84996 |
450 | |
451 | # |
452 | # Tests for optional PathPart attribute. |
453 | # |
454 | { |
455 | my @expected = qw[ |
5882c86e |
456 | TestApp::Controller::Action::Chained->begin |
457 | TestApp::Controller::Action::Chained->opt_pp_start |
458 | TestApp::Controller::Action::Chained->opt_pathpart |
459 | TestApp::Controller::Action::Chained->end |
9cc84996 |
460 | ]; |
461 | |
462 | my $expected = join( ", ", @expected ); |
463 | |
5882c86e |
464 | ok( my $response = request('http://localhost/chained/optpp/1/opt_pathpart/2'), |
9cc84996 |
465 | 'Optional :PathName attribute working' ); |
466 | is( $response->header('X-Catalyst-Executed'), |
467 | $expected, 'Executed actions' ); |
468 | is( $response->content, '1; 2', 'Content OK' ); |
469 | } |
470 | |
471 | # |
472 | # Tests for optional PathPart *and* Args attributes. |
473 | # |
474 | { |
475 | my @expected = qw[ |
5882c86e |
476 | TestApp::Controller::Action::Chained->begin |
477 | TestApp::Controller::Action::Chained->opt_all_start |
478 | TestApp::Controller::Action::Chained->oa |
479 | TestApp::Controller::Action::Chained->end |
9cc84996 |
480 | ]; |
481 | |
482 | my $expected = join( ", ", @expected ); |
483 | |
5882c86e |
484 | ok( my $response = request('http://localhost/chained/optall/1/oa/2/3'), |
9cc84996 |
485 | 'Optional :PathName *and* :Args attributes working' ); |
486 | is( $response->header('X-Catalyst-Executed'), |
487 | $expected, 'Executed actions' ); |
488 | is( $response->content, '1; 2, 3', 'Content OK' ); |
489 | } |
0e853a7f |
490 | |
491 | # |
492 | # Test if :Chained is the same as :Chained('/') |
493 | # |
494 | { |
495 | my @expected = qw[ |
496 | TestApp::Controller::Action::Chained->begin |
497 | TestApp::Controller::Action::Chained->rootdef |
498 | TestApp::Controller::Action::Chained->end |
499 | ]; |
500 | |
501 | my $expected = join( ", ", @expected ); |
502 | |
503 | ok( my $response = request('http://localhost/chained/rootdef/23'), |
504 | ":Chained is the same as :Chained('/')" ); |
505 | is( $response->header('X-Catalyst-Executed'), |
506 | $expected, 'Executed actions' ); |
507 | is( $response->content, '; 23', 'Content OK' ); |
508 | } |
509 | |
510 | # |
f88e7f69 |
511 | # Test if :Chained('.') is working |
0e853a7f |
512 | # |
513 | { |
514 | my @expected = qw[ |
515 | TestApp::Controller::Action::Chained->begin |
516 | TestApp::Controller::Action::Chained->parentchain |
517 | TestApp::Controller::Action::Chained::ParentChain->child |
518 | TestApp::Controller::Action::Chained->end |
519 | ]; |
520 | |
521 | my $expected = join( ", ", @expected ); |
522 | |
523 | ok( my $response = request('http://localhost/chained/parentchain/1/child/2'), |
524 | ":Chained('.') chains to parent controller action" ); |
525 | is( $response->header('X-Catalyst-Executed'), |
526 | $expected, 'Executed actions' ); |
527 | is( $response->content, '1; 2', 'Content OK' ); |
528 | } |
2349aeea |
529 | |
530 | # |
2f381252 |
531 | # Test if :Chained('../act') is working |
532 | # |
533 | { |
534 | my @expected = qw[ |
535 | TestApp::Controller::Action::Chained->begin |
536 | TestApp::Controller::Action::Chained->one |
537 | TestApp::Controller::Action::Chained::ParentChain->chained_rel |
538 | TestApp::Controller::Action::Chained->end |
539 | ]; |
540 | |
541 | my $expected = join( ", ", @expected ); |
542 | |
543 | ok( my $response = request('http://localhost/chained/one/1/chained_rel/3/2'), |
544 | ":Chained('../action') chains to correct action" ); |
545 | is( $response->header('X-Catalyst-Executed'), |
546 | $expected, 'Executed actions' ); |
547 | is( $response->content, '1; 3, 2', 'Content OK' ); |
548 | } |
549 | |
550 | # |
551 | # Test if ../ works to go up more than one level |
552 | # |
553 | { |
554 | my @expected = qw[ |
555 | TestApp::Controller::Action::Chained->begin |
556 | TestApp::Controller::Action::Chained->one |
557 | TestApp::Controller::Action::Chained::ParentChain::Relative->chained_rel_two |
558 | TestApp::Controller::Action::Chained->end |
559 | ]; |
560 | |
561 | my $expected = join( ", ", @expected ); |
562 | |
563 | ok( my $response = request('http://localhost/chained/one/1/chained_rel_two/42/23'), |
564 | "../ works to go up more than one level" ); |
565 | is( $response->header('X-Catalyst-Executed'), |
566 | $expected, 'Executed actions' ); |
567 | is( $response->content, '1; 42, 23', 'Content OK' ); |
568 | } |
569 | |
570 | # |
571 | # Test if :ChainedParent is working |
572 | # |
573 | { |
574 | my @expected = qw[ |
575 | TestApp::Controller::Action::Chained->begin |
576 | TestApp::Controller::Action::Chained->loose |
577 | TestApp::Controller::Action::Chained::ParentChain->loose |
578 | TestApp::Controller::Action::Chained->end |
579 | ]; |
580 | |
581 | my $expected = join( ", ", @expected ); |
582 | |
583 | ok( my $response = request('http://localhost/chained/loose/4/loose/a/b'), |
584 | ":Chained('../action') chains to correct action" ); |
585 | is( $response->header('X-Catalyst-Executed'), |
586 | $expected, 'Executed actions' ); |
587 | is( $response->content, '4; a, b', 'Content OK' ); |
588 | } |
589 | |
590 | # |
591 | # Test if :Chained('../name/act') is working |
592 | # |
593 | { |
594 | my @expected = qw[ |
595 | TestApp::Controller::Action::Chained->begin |
596 | TestApp::Controller::Action::Chained::Bar->cross1 |
597 | TestApp::Controller::Action::Chained::ParentChain->up_down |
598 | TestApp::Controller::Action::Chained->end |
599 | ]; |
600 | |
601 | my $expected = join( ", ", @expected ); |
602 | |
603 | ok( my $response = request('http://localhost/chained/cross/4/up_down/5'), |
604 | ":Chained('../action') chains to correct action" ); |
605 | is( $response->header('X-Catalyst-Executed'), |
606 | $expected, 'Executed actions' ); |
607 | is( $response->content, '4; 5', 'Content OK' ); |
608 | } |
609 | |
610 | # |
2349aeea |
611 | # Test behaviour of auto actions returning '1' for the chain. |
612 | # |
613 | { |
614 | my @expected = qw[ |
615 | TestApp::Controller::Action::Chained->begin |
616 | TestApp::Controller::Action::Chained::Auto->auto |
617 | TestApp::Controller::Action::Chained::Auto::Foo->auto |
618 | TestApp::Controller::Action::Chained::Auto->foo |
619 | TestApp::Controller::Action::Chained::Auto::Foo->fooend |
620 | TestApp::Controller::Action::Chained->end |
621 | ]; |
622 | |
623 | my $expected = join( ", ", @expected ); |
624 | |
625 | ok( my $response = request('http://localhost/chained/autochain1/1/fooend/2'), |
626 | "Behaviour when auto returns 1 correct" ); |
627 | is( $response->header('X-Catalyst-Executed'), |
628 | $expected, 'Executed actions' ); |
629 | is( $response->content, '1; 2', 'Content OK' ); |
630 | } |
631 | |
632 | # |
633 | # Test behaviour of auto actions returning '0' for the chain. |
634 | # |
635 | { |
636 | my @expected = qw[ |
637 | TestApp::Controller::Action::Chained->begin |
638 | TestApp::Controller::Action::Chained::Auto->auto |
639 | TestApp::Controller::Action::Chained::Auto::Bar->auto |
640 | TestApp::Controller::Action::Chained->end |
641 | ]; |
642 | |
643 | my $expected = join( ", ", @expected ); |
644 | |
645 | ok( my $response = request('http://localhost/chained/autochain2/1/barend/2'), |
646 | "Behaviour when auto returns 0 correct" ); |
647 | is( $response->header('X-Catalyst-Executed'), |
648 | $expected, 'Executed actions' ); |
649 | is( $response->content, '1; 2', 'Content OK' ); |
650 | } |
651 | |
652 | # |
653 | # Test what auto actions are run when namespaces are changed |
654 | # horizontally. |
655 | # |
656 | { |
657 | my @expected = qw[ |
658 | TestApp::Controller::Action::Chained->begin |
659 | TestApp::Controller::Action::Chained::Auto->auto |
660 | TestApp::Controller::Action::Chained::Auto::Foo->auto |
661 | TestApp::Controller::Action::Chained::Auto::Bar->crossloose |
662 | TestApp::Controller::Action::Chained::Auto::Foo->crossend |
663 | TestApp::Controller::Action::Chained->end |
664 | ]; |
665 | |
666 | my $expected = join( ", ", @expected ); |
667 | |
668 | ok( my $response = request('http://localhost/chained/auto_cross/1/crossend/2'), |
669 | "Correct auto actions are run on cross controller dispatch" ); |
670 | is( $response->header('X-Catalyst-Executed'), |
671 | $expected, 'Executed actions' ); |
672 | is( $response->content, '1; 2', 'Content OK' ); |
673 | } |
674 | |
675 | # |
676 | # Test forwarding from auto action in chain dispatch. |
677 | # |
678 | { |
679 | my @expected = qw[ |
680 | TestApp::Controller::Action::Chained->begin |
681 | TestApp::Controller::Action::Chained::Auto->auto |
682 | TestApp::Controller::Action::Chained::Auto::Forward->auto |
683 | TestApp::Controller::Action::Chained::Auto->fw3 |
684 | TestApp::Controller::Action::Chained::Auto->fw1 |
685 | TestApp::Controller::Action::Chained::Auto::Forward->forwardend |
686 | TestApp::Controller::Action::Chained->end |
687 | ]; |
688 | |
689 | my $expected = join( ", ", @expected ); |
690 | |
691 | ok( my $response = request('http://localhost/chained/auto_forward/1/forwardend/2'), |
692 | "Forwarding out of auto in chain" ); |
693 | is( $response->header('X-Catalyst-Executed'), |
694 | $expected, 'Executed actions' ); |
695 | is( $response->content, '1; 2', 'Content OK' ); |
696 | } |
697 | |
698 | # |
699 | # Detaching out of the auto action of a chain. |
700 | # |
701 | { |
702 | my @expected = qw[ |
703 | TestApp::Controller::Action::Chained->begin |
704 | TestApp::Controller::Action::Chained::Auto->auto |
705 | TestApp::Controller::Action::Chained::Auto::Detach->auto |
706 | TestApp::Controller::Action::Chained::Auto->fw3 |
707 | TestApp::Controller::Action::Chained->end |
708 | ]; |
709 | |
710 | my $expected = join( ", ", @expected ); |
711 | |
712 | ok( my $response = request('http://localhost/chained/auto_detach/1/detachend/2'), |
713 | "Detaching out of auto in chain" ); |
714 | is( $response->header('X-Catalyst-Executed'), |
715 | $expected, 'Executed actions' ); |
716 | is( $response->content, '1; 2', 'Content OK' ); |
717 | } |
718 | |
719 | # |
720 | # Test forwarding from auto action in chain dispatch. |
721 | # |
722 | { |
723 | my $expected = undef; |
724 | |
725 | ok( my $response = request('http://localhost/chained/loose/23'), |
726 | "Loose end is not callable" ); |
727 | is( $response->header('X-Catalyst-Executed'), |
728 | $expected, 'Executed actions' ); |
10ae2631 |
729 | is( $response->code, 500, 'Status OK' ); |
2349aeea |
730 | } |
731 | |
732 | # |
733 | # Test forwarding out of a chain. |
734 | # |
735 | { |
736 | my @expected = qw[ |
737 | TestApp::Controller::Action::Chained->begin |
738 | TestApp::Controller::Action::Chained->chain_fw_a |
739 | TestApp::Controller::Action::Chained->fw_dt_target |
740 | TestApp::Controller::Action::Chained->chain_fw_b |
741 | TestApp::Controller::Action::Chained->end |
742 | ]; |
743 | |
744 | my $expected = join( ", ", @expected ); |
745 | |
746 | ok( my $response = request('http://localhost/chained/chain_fw/1/end/2'), |
747 | "Forwarding out a chain" ); |
748 | is( $response->header('X-Catalyst-Executed'), |
749 | $expected, 'Executed actions' ); |
750 | is( $response->content, '1; 2', 'Content OK' ); |
751 | } |
752 | |
753 | # |
754 | # Test detaching out of a chain. |
755 | # |
756 | { |
757 | my @expected = qw[ |
758 | TestApp::Controller::Action::Chained->begin |
759 | TestApp::Controller::Action::Chained->chain_dt_a |
760 | TestApp::Controller::Action::Chained->fw_dt_target |
761 | TestApp::Controller::Action::Chained->end |
762 | ]; |
763 | |
764 | my $expected = join( ", ", @expected ); |
765 | |
766 | ok( my $response = request('http://localhost/chained/chain_dt/1/end/2'), |
767 | "Forwarding out a chain" ); |
768 | is( $response->header('X-Catalyst-Executed'), |
769 | $expected, 'Executed actions' ); |
770 | is( $response->content, '1; 2', 'Content OK' ); |
771 | } |
8a6a6581 |
772 | |
773 | # |
81e75875 |
774 | # Tests that an uri_for to a chained root index action |
775 | # returns the right value. |
776 | # |
777 | { |
778 | ok( my $response = request( |
779 | 'http://localhost/action/chained/to_root' ), |
780 | 'uri_for with chained root action as arg' ); |
10ae2631 |
781 | like( $response->content, |
de19de2e |
782 | qr(URI:https?://[^/]+/), |
81e75875 |
783 | 'Correct URI generated' ); |
784 | } |
785 | |
786 | # |
8a6a6581 |
787 | # Test interception of recursive chains. This test was added because at |
788 | # one point during the :Chained development, Catalyst used to hang on |
789 | # recursive chains. |
790 | # |
791 | { |
792 | eval { require 'TestAppChainedRecursive.pm' }; |
05a90578 |
793 | if ($run_number == 1) { |
794 | ok( ! $@, "Interception of recursive chains" ); |
795 | } |
796 | else { pass( "Interception of recursive chains already tested" ) } |
8a6a6581 |
797 | } |
798 | |
799 | # |
800 | # Test failure of absolute path part arguments. |
801 | # |
802 | { |
803 | eval { require 'TestAppChainedAbsolutePathPart.pm' }; |
804 | if ($run_number == 1) { |
805 | like( $@, qr(foo/foo), |
806 | "Usage of absolute path part argument emits error" ); |
807 | } |
808 | else { pass( "Error on absolute path part arguments already tested" ) } |
809 | } |
f505df49 |
810 | |
811 | # |
caaf37ad |
812 | # Test chained actions in the root controller |
813 | # |
814 | { |
815 | my @expected = qw[ |
caaf37ad |
816 | TestApp::Controller::Action::Chained::Root->rootsub |
817 | TestApp::Controller::Action::Chained::Root->endpointsub |
a0a66cb8 |
818 | TestApp::Controller::Root->end |
caaf37ad |
819 | ]; |
820 | |
821 | my $expected = join( ", ", @expected ); |
822 | |
823 | ok( my $response = request('http://localhost/rootsub/1/endpointsub/2'), 'chained in root namespace' ); |
824 | is( $response->header('X-Catalyst-Executed'), |
825 | $expected, 'Executed actions' ); |
f720422c |
826 | is( $response->content, '', 'Content OK' ); |
caaf37ad |
827 | } |
828 | |
829 | # |
f505df49 |
830 | # Complex path with multiple empty pathparts |
831 | # |
832 | { |
833 | my @expected = qw[ |
834 | TestApp::Controller::Action::Chained->begin |
835 | TestApp::Controller::Action::Chained->mult_nopp_base |
836 | TestApp::Controller::Action::Chained->mult_nopp_all |
837 | TestApp::Controller::Action::Chained->end |
838 | ]; |
839 | |
840 | my $expected = join( ", ", @expected ); |
841 | |
842 | ok( my $response = request('http://localhost/chained/mult_nopp'), |
843 | "Complex path with multiple empty pathparts" ); |
844 | is( $response->header('X-Catalyst-Executed'), |
845 | $expected, 'Executed actions' ); |
846 | is( $response->content, '; ', 'Content OK' ); |
847 | } |
848 | |
953c176d |
849 | # |
850 | # Higher Args() hiding more specific CaptureArgs chains sections |
851 | # |
852 | { |
853 | my @expected = qw[ |
854 | TestApp::Controller::Action::Chained->begin |
855 | TestApp::Controller::Action::Chained->cc_base |
856 | TestApp::Controller::Action::Chained->cc_link |
857 | TestApp::Controller::Action::Chained->cc_anchor |
858 | TestApp::Controller::Action::Chained->end |
859 | ]; |
860 | |
861 | my $expected = join ', ', @expected; |
862 | |
863 | ok( my $response = request('http://localhost/chained/choose_capture/anchor.html'), |
864 | 'Choose between an early Args() and a later more ideal chain' ); |
865 | is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions'); |
866 | is( $response->content => '; ', 'Content OK' ); |
867 | } |
868 | |
869 | # |
870 | # Less specific chain not being seen correctly due to earlier looser capture |
871 | # |
872 | { |
873 | my @expected = qw[ |
874 | TestApp::Controller::Action::Chained->begin |
875 | TestApp::Controller::Action::Chained->cc_base |
876 | TestApp::Controller::Action::Chained->cc_b |
877 | TestApp::Controller::Action::Chained->cc_b_link |
878 | TestApp::Controller::Action::Chained->cc_b_anchor |
879 | TestApp::Controller::Action::Chained->end |
880 | ]; |
881 | |
882 | my $expected = join ', ', @expected; |
883 | |
884 | ok( my $response = request('http://localhost/chained/choose_capture/b/a/anchor.html'), |
885 | 'Choose between a more specific chain and an earlier looser one' ); |
886 | is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions'); |
887 | is( $response->content => 'a; ', 'Content OK' ); |
888 | } |
889 | |
890 | # |
891 | # Check we get the looser one when it's the correct match |
892 | # |
893 | { |
894 | my @expected = qw[ |
895 | TestApp::Controller::Action::Chained->begin |
896 | TestApp::Controller::Action::Chained->cc_base |
897 | TestApp::Controller::Action::Chained->cc_a |
898 | TestApp::Controller::Action::Chained->cc_a_link |
899 | TestApp::Controller::Action::Chained->cc_a_anchor |
900 | TestApp::Controller::Action::Chained->end |
901 | ]; |
902 | |
903 | my $expected = join ', ', @expected; |
904 | |
905 | ok( my $response = request('http://localhost/chained/choose_capture/a/a/anchor.html'), |
906 | 'Choose between a more specific chain and an earlier looser one' ); |
907 | is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions'); |
908 | is( $response->content => 'a; anchor.html', 'Content OK' ); |
909 | } |
910 | |
fd91d0c6 |
911 | # CaptureArgs(1) PathPart('...') should win over CaptureArgs(2) PathPart('') |
912 | { |
913 | my @expected = qw[ |
914 | TestApp::Controller::Action::Chained->begin |
915 | TestApp::Controller::Action::Chained::CaptureArgs->base |
916 | TestApp::Controller::Action::Chained::CaptureArgs->one_arg |
917 | TestApp::Controller::Action::Chained::CaptureArgs->edit_one_arg |
918 | TestApp::Controller::Action::Chained::CaptureArgs->end |
919 | ]; |
920 | |
921 | my $expected = join( ", ", @expected ); |
922 | |
923 | # should dispatch to /base/one_args/edit_one_arg |
924 | ok( my $response = request('http://localhost/captureargs/one/edit'), |
925 | 'Correct arg order ran' ); |
ad9c323c |
926 | TODO: { |
927 | local $TODO = 'Known bug'; |
fd91d0c6 |
928 | is( $response->header('X-Catalyst-Executed'), |
929 | $expected, 'Executed actions' ); |
930 | is( $response->content, 'base; one_arg; edit_one_arg', 'Content OK' ); |
ad9c323c |
931 | } |
fd91d0c6 |
932 | } |
933 | |
1c24a6c4 |
934 | # PathPart('...') Args(1) should win over CaptureArgs(2) PathPart('') |
935 | { |
936 | my @expected = qw[ |
937 | TestApp::Controller::Action::Chained->begin |
938 | TestApp::Controller::Action::Chained::CaptureArgs->base |
939 | TestApp::Controller::Action::Chained::CaptureArgs->test_one_arg |
940 | TestApp::Controller::Action::Chained::CaptureArgs->end |
941 | ]; |
942 | |
943 | my $expected = join( ", ", @expected ); |
944 | |
945 | # should dispatch to /base/test_one_arg |
946 | ok( my $response = request('http://localhost/captureargs/test/one'), |
947 | 'Correct pathpart/arg ran' ); |
948 | TODO: { |
949 | local $TODO = 'Known bug'; |
950 | is( $response->header('X-Catalyst-Executed'), |
951 | $expected, 'Executed actions' ); |
952 | is( $response->content, 'base; test_plus_arg; one;', 'Content OK' ); |
953 | } |
954 | } |
955 | |
953c176d |
956 | # |
957 | # Args(0) should win over Args() if we actually have no arguments. |
958 | { |
959 | my @expected = qw[ |
960 | TestApp::Controller::Action::Chained->begin |
961 | TestApp::Controller::Action::Chained::ArgsOrder->base |
962 | TestApp::Controller::Action::Chained::ArgsOrder->index |
963 | TestApp::Controller::Action::Chained::ArgsOrder->end |
964 | ]; |
965 | |
966 | my $expected = join( ", ", @expected ); |
967 | |
968 | # With no args, we should run "index" |
969 | ok( my $response = request('http://localhost/argsorder/'), |
970 | 'Correct arg order ran' ); |
971 | is( $response->header('X-Catalyst-Executed'), |
972 | $expected, 'Executed actions' ); |
973 | is( $response->content, 'base; ; index; ', 'Content OK' ); |
974 | |
975 | # With args given, run "all" |
976 | ok( $response = request('http://localhost/argsorder/X'), |
977 | 'Correct arg order ran' ); |
978 | is( $response->header('X-Catalyst-Executed'), |
979 | join(", ", |
980 | qw[ |
981 | TestApp::Controller::Action::Chained->begin |
982 | TestApp::Controller::Action::Chained::ArgsOrder->base |
983 | TestApp::Controller::Action::Chained::ArgsOrder->all |
984 | TestApp::Controller::Action::Chained::ArgsOrder->end |
985 | ]) |
986 | ); |
987 | is( $response->content, 'base; ; all; X', 'Content OK' ); |
988 | |
989 | } |
6365b527 |
990 | |
2f381252 |
991 | # |
992 | # PathPrefix |
993 | # |
994 | { |
995 | my @expected = qw[ |
996 | TestApp::Controller::Action::Chained->begin |
997 | TestApp::Controller::Action::Chained::PathPrefix->instance |
998 | TestApp::Controller::Action::Chained->end |
999 | ]; |
1000 | |
1001 | my $expected = join( ", ", @expected ); |
1002 | |
1003 | ok( my $response = request('http://localhost/action/chained/pathprefix/1'), |
1004 | "PathPrefix (as an endpoint)" ); |
1005 | is( $response->header('X-Catalyst-Executed'), |
1006 | $expected, 'Executed actions' ); |
1007 | is( $response->content, '; 1', 'Content OK' ); |
1008 | } |
1009 | |
1010 | # |
1011 | # static paths vs. captures |
1012 | # |
1013 | { |
1014 | my @expected = qw[ |
1015 | TestApp::Controller::Action::Chained->begin |
1016 | TestApp::Controller::Action::Chained->apan |
1017 | TestApp::Controller::Action::Chained->korv |
1018 | TestApp::Controller::Action::Chained->static_end |
1019 | TestApp::Controller::Action::Chained->end |
1020 | ]; |
1021 | |
1022 | my $expected = join( ", ", @expected ); |
1023 | |
1024 | ok( my $response = request('http://localhost/action/chained/static_end'), |
1025 | "static paths are prefered over captures" ); |
1026 | is( $response->header('X-Catalyst-Executed'), |
1027 | $expected, 'Executed actions' ); |
1028 | } |
ef5e5ed1 |
1029 | |
1030 | # |
1031 | # */search |
1032 | # doc/* |
1033 | # |
1034 | # request for doc/search should end up in doc/* |
1035 | { |
1036 | my @expected = qw[ |
1037 | TestApp::Controller::Action::Chained->begin |
1038 | TestApp::Controller::Action::Chained->doc_star |
1039 | TestApp::Controller::Action::Chained->end |
1040 | ]; |
1041 | |
1042 | my $expected = join( ", ", @expected ); |
1043 | |
1044 | ok( my $response = request('http://localhost/chained/doc/search'), |
1045 | "we prefer static path parts earlier in the chain" ); |
fc38b056 |
1046 | TODO: { |
1047 | local $TODO = 'gbjk never got off his ass and fixed this'; |
1048 | is( $response->header('X-Catalyst-Executed'), |
1049 | $expected, 'Executed actions' ); |
1050 | } |
ef5e5ed1 |
1051 | } |
2c527b91 |
1052 | |
1053 | { |
1054 | ok( my $content = |
06f97d3f |
1055 | get('http://localhost/chained/capture%2Farg%3B/return_arg/foo%2Fbar%3B'), |
2c527b91 |
1056 | 'request with URI-encoded arg' ); |
634780e0 |
1057 | like( $content, qr{foo/bar;\z}, 'args decoded' ); |
06f97d3f |
1058 | like( $content, qr{capture/arg;}, 'captureargs decoded' ); |
2c527b91 |
1059 | } |
372b0c1b |
1060 | { |
1061 | ok( my $content = |
1062 | get('http://localhost/chained/return_arg_decoded/foo%2Fbar%3B'), |
1063 | 'request with URI-encoded arg' ); |
1064 | like( $content, qr{foo/bar;\z}, 'args decoded' ); |
1065 | } |
60dadd31 |
1066 | |
36c67dc1 |
1067 | # Test round tripping, specifically the / character %2F in uri_for: |
a76d2786 |
1068 | # not being able to feed it back action + captureargs and args into uri for |
1069 | # and result in the original request uri is a major piece of suck ;) |
36c67dc1 |
1070 | foreach my $thing ( |
1071 | ['foo', 'bar'], |
1072 | ['foo%2Fbar', 'baz'], |
1073 | ['foo', 'bar%2Fbaz'], |
1074 | ['foo%2Fbar', 'baz%2Fquux'], |
1075 | ['foo%2Fbar', 'baz%2Fquux', { foo => 'bar', 'baz' => 'quux%2Ffrood'}], |
1076 | ['foo%2Fbar', 'baz%2Fquux', { foo => 'bar', 'baz%2Ffnoo' => 'quux%2Ffrood'}], |
7b346bc3 |
1077 | ['h%C3%BCtte', 'h%C3%BCtte', { test => 'h%C3%BCtte' } ], |
36c67dc1 |
1078 | ) { |
9b7d26c7 |
1079 | my $path = '/chained/roundtrip_urifor/' . |
a76d2786 |
1080 | $thing->[0] . '/' . $thing->[1]; |
9b7d26c7 |
1081 | $path .= '?' . join('&', |
a76d2786 |
1082 | map { $_ .'='. $thing->[2]->{$_}} |
1083 | sort keys %{$thing->[2]}) if $thing->[2]; |
36c67dc1 |
1084 | ok( my $content = |
9b7d26c7 |
1085 | get('http://localhost/' . $path), |
1086 | 'request ' . $path . ' ok'); |
1087 | # Just check that the path matches, as who the hell knows or cares |
1088 | # where the app is based (live tests etc) |
7b346bc3 |
1089 | ok( index($content, $path) > 1, 'uri can round trip through uri_for' ) |
2689f8a4 |
1090 | or diag("Expected $path, got $content"); |
36c67dc1 |
1091 | } |
141459fa |
1092 | } |
372b0c1b |
1093 | |
36c67dc1 |
1094 | done_testing; |
a76d2786 |
1095 | |