rah. rename everything.
[catagits/Catalyst-Runtime.git] / t / live_component_controller_action_childof.t
1 #!perl
2
3 use strict;
4 use warnings;
5
6 use FindBin;
7 use lib "$FindBin::Bin/lib";
8
9 our $iters;
10
11 BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 2; }
12
13 use Test::More tests => 66*$iters;
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 ) {
22         run_tests();
23     }
24 }
25
26 sub run_tests {
27
28     #
29     #   This is a simple test where the parent and child actions are
30     #   within the same controller.
31     #
32     {
33         my @expected = qw[
34           TestApp::Controller::Action::Chained->begin
35           TestApp::Controller::Action::Chained->foo
36           TestApp::Controller::Action::Chained->endpoint
37           TestApp::Controller::Action::Chained->end
38         ];
39
40         my $expected = join( ", ", @expected );
41
42         ok( my $response = request('http://localhost/chained/foo/1/end/2'), 'chained + local endpoint' );
43         is( $response->header('X-Catalyst-Executed'),
44             $expected, 'Executed actions' );
45         is( $response->content, '1; 2', 'Content OK' );
46     }
47
48     #
49     #   This makes sure the above isn't found if the argument for the
50     #   end action isn't supplied.
51     #
52     {
53         my $expected = undef;
54
55         ok( my $response = request('http://localhost/chained/foo/1/end'), 
56             'chained + local endpoint; missing last argument' );
57         is( $response->header('X-Catalyst-Executed'),
58             $expected, 'Executed actions' );
59         is( $response->header('Status'), 500, 'Status OK' );
60     }
61
62     #
63     #   Tests the case when the child action is placed in a subcontroller.
64     #
65     {
66         my @expected = qw[
67           TestApp::Controller::Action::Chained->begin
68           TestApp::Controller::Action::Chained->foo
69           TestApp::Controller::Action::Chained::Foo->spoon
70           TestApp::Controller::Action::Chained->end
71         ];
72
73         my $expected = join( ", ", @expected );
74
75         ok( my $response = request('http://localhost/chained/foo/1/spoon'), 'chained + subcontroller endpoint' );
76         is( $response->header('X-Catalyst-Executed'),
77             $expected, 'Executed actions' );
78         is( $response->content, '1; ', 'Content OK' );
79     }
80
81     #
82     #   Tests if the relative specification (e.g.: Chained('bar') ) works
83     #   as expected.
84     #
85     {
86         my @expected = qw[
87           TestApp::Controller::Action::Chained->begin
88           TestApp::Controller::Action::Chained->bar
89           TestApp::Controller::Action::Chained->finale
90           TestApp::Controller::Action::Chained->end
91         ];
92
93         my $expected = join( ", ", @expected );
94
95         ok( my $response = request('http://localhost/chained/bar/1/spoon'), 'chained + relative endpoint' );
96         is( $response->header('X-Catalyst-Executed'),
97             $expected, 'Executed actions' );
98         is( $response->content, '; 1, spoon', 'Content OK' );
99     }
100
101     #
102     #   Just a test for multiple arguments.
103     #
104     {
105         my @expected = qw[
106           TestApp::Controller::Action::Chained->begin
107           TestApp::Controller::Action::Chained->foo2
108           TestApp::Controller::Action::Chained->endpoint2
109           TestApp::Controller::Action::Chained->end
110         ];
111
112         my $expected = join( ", ", @expected );
113
114         ok( my $response = request('http://localhost/chained/foo2/10/20/end2/15/25'), 
115             'chained + local (2 args each)' );
116         is( $response->header('X-Catalyst-Executed'),
117             $expected, 'Executed actions' );
118         is( $response->content, '10, 20; 15, 25', 'Content OK' );
119     }
120
121     #
122     #   The first three-chain test tries to call the action with :Args(1)
123     #   specification. There's also a one action with a :Captures(1)
124     #   attribute, that should not be dispatched to.
125     #
126     {
127         my @expected = qw[
128           TestApp::Controller::Action::Chained->begin
129           TestApp::Controller::Action::Chained->one_end
130           TestApp::Controller::Action::Chained->end
131         ];
132
133         my $expected = join( ", ", @expected );
134
135         ok( my $response = request('http://localhost/chained/one/23'),
136             'three-chain (only first)' );
137         is( $response->header('X-Catalyst-Executed'),
138             $expected, 'Executed actions' );
139         is( $response->content, '; 23', 'Content OK' );
140     }
141
142     #
143     #   This is the second three-chain test, it goes for the action that
144     #   handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action
145     #   having :Args(2), not the one having :Captures(2).
146     #
147     {
148         my @expected = qw[
149           TestApp::Controller::Action::Chained->begin
150           TestApp::Controller::Action::Chained->one
151           TestApp::Controller::Action::Chained->two_end
152           TestApp::Controller::Action::Chained->end
153         ];
154
155         my $expected = join( ", ", @expected );
156
157         ok( my $response = request('http://localhost/chained/one/23/two/23/46'),
158             'three-chain (up to second)' );
159         is( $response->header('X-Catalyst-Executed'),
160             $expected, 'Executed actions' );
161         is( $response->content, '23; 23, 46', 'Content OK' );
162     }
163
164     #
165     #   Last of the three-chain tests. Has no concurrent action with :Captures
166     #   and is more thought to simply test the chain as a whole and the 'two'
167     #   action specifying :Captures.
168     #
169     {
170         my @expected = qw[
171           TestApp::Controller::Action::Chained->begin
172           TestApp::Controller::Action::Chained->one
173           TestApp::Controller::Action::Chained->two
174           TestApp::Controller::Action::Chained->three_end
175           TestApp::Controller::Action::Chained->end
176         ];
177
178         my $expected = join( ", ", @expected );
179
180         ok( my $response = request('http://localhost/chained/one/23/two/23/46/three/1/2/3'),
181             'three-chain (all three)' );
182         is( $response->header('X-Catalyst-Executed'),
183             $expected, 'Executed actions' );
184         is( $response->content, '23, 23, 46; 1, 2, 3', 'Content OK' );
185     }
186
187     #
188     #   Tests dispatching on number of arguments for :Args. This should be
189     #   dispatched to the action expecting one argument.
190     #
191     {
192         my @expected = qw[
193           TestApp::Controller::Action::Chained->begin
194           TestApp::Controller::Action::Chained->multi1
195           TestApp::Controller::Action::Chained->end
196         ];
197
198         my $expected = join( ", ", @expected );
199
200         ok( my $response = request('http://localhost/chained/multi/23'),
201             'multi-action (one arg)' );
202         is( $response->header('X-Catalyst-Executed'),
203             $expected, 'Executed actions' );
204         is( $response->content, '; 23', 'Content OK' );
205     }
206
207     #
208     #   Belongs to the former test and goes for the action expecting two arguments.
209     #
210     {
211         my @expected = qw[
212           TestApp::Controller::Action::Chained->begin
213           TestApp::Controller::Action::Chained->multi2
214           TestApp::Controller::Action::Chained->end
215         ];
216
217         my $expected = join( ", ", @expected );
218
219         ok( my $response = request('http://localhost/chained/multi/23/46'),
220             'multi-action (two args)' );
221         is( $response->header('X-Catalyst-Executed'),
222             $expected, 'Executed actions' );
223         is( $response->content, '; 23, 46', 'Content OK' );
224     }
225
226     #
227     #   Dispatching on argument count again, this time we provide too many
228     #   arguments, so dispatching should fail.
229     #
230     {
231         my $expected = undef;
232
233         ok( my $response = request('http://localhost/chained/multi/23/46/67'),
234             'multi-action (three args, should lead to error)' );
235         is( $response->header('X-Catalyst-Executed'),
236             $expected, 'Executed actions' );
237         is( $response->header('Status'), 500, 'Status OK' );
238     }
239
240     #
241     #   This tests the case when an action says it's the child of an action in
242     #   a subcontroller.
243     #
244     {
245         my @expected = qw[
246           TestApp::Controller::Action::Chained->begin
247           TestApp::Controller::Action::Chained::Foo->higher_root
248           TestApp::Controller::Action::Chained->higher_root
249           TestApp::Controller::Action::Chained->end
250         ];
251
252         my $expected = join( ", ", @expected );
253
254         ok( my $response = request('http://localhost/chained/higher_root/23/bar/11'),
255             'root higher than child' );
256         is( $response->header('X-Catalyst-Executed'),
257             $expected, 'Executed actions' );
258         is( $response->content, '23; 11', 'Content OK' );
259     }
260
261     #
262     #   Just a more complex version of the former test. It tests if a controller ->
263     #   subcontroller -> controller dispatch works.
264     #
265     {
266         my @expected = qw[
267           TestApp::Controller::Action::Chained->begin
268           TestApp::Controller::Action::Chained->pcp1
269           TestApp::Controller::Action::Chained::Foo->pcp2
270           TestApp::Controller::Action::Chained->pcp3
271           TestApp::Controller::Action::Chained->end
272         ];
273
274         my $expected = join( ", ", @expected );
275
276         ok( my $response = request('http://localhost/chained/pcp1/1/pcp2/2/pcp3/3'),
277             'parent -> child -> parent' );
278         is( $response->header('X-Catalyst-Executed'),
279             $expected, 'Executed actions' );
280         is( $response->content, '1, 2; 3', 'Content OK' );
281     }
282
283     #
284     #   Tests dispatch on capture number. This test is for a one capture action.
285     #
286     {
287         my @expected = qw[
288           TestApp::Controller::Action::Chained->begin
289           TestApp::Controller::Action::Chained->multi_cap1
290           TestApp::Controller::Action::Chained->multi_cap_end1
291           TestApp::Controller::Action::Chained->end
292         ];
293
294         my $expected = join( ", ", @expected );
295
296         ok( my $response = request('http://localhost/chained/multi_cap/1/baz'),
297             'dispatch on capture num 1' );
298         is( $response->header('X-Catalyst-Executed'),
299             $expected, 'Executed actions' );
300         is( $response->content, '1; ', 'Content OK' );
301     }
302
303     #
304     #   Belongs to the former test. This one goes for the action expecting two
305     #   captures.
306     #
307     {
308         my @expected = qw[
309           TestApp::Controller::Action::Chained->begin
310           TestApp::Controller::Action::Chained->multi_cap2
311           TestApp::Controller::Action::Chained->multi_cap_end2
312           TestApp::Controller::Action::Chained->end
313         ];
314
315         my $expected = join( ", ", @expected );
316
317         ok( my $response = request('http://localhost/chained/multi_cap/1/2/baz'),
318             'dispatch on capture num 2' );
319         is( $response->header('X-Catalyst-Executed'),
320             $expected, 'Executed actions' );
321         is( $response->content, '1, 2; ', 'Content OK' );
322     }
323
324     #
325     #   Tests the priority of a slurpy arguments action (with :Args) against
326     #   two actions chained together. The two actions should win.
327     #
328     {
329         my @expected = qw[
330           TestApp::Controller::Action::Chained->begin
331           TestApp::Controller::Action::Chained->priority_a2
332           TestApp::Controller::Action::Chained->priority_a2_end
333           TestApp::Controller::Action::Chained->end
334         ];
335
336         my $expected = join( ", ", @expected );
337
338         ok( my $response = request('http://localhost/chained/priority_a/1/end/2'),
339             'priority - slurpy args vs. parent/child' );
340         is( $response->header('X-Catalyst-Executed'),
341             $expected, 'Executed actions' );
342         is( $response->content, '1; 2', 'Content OK' );
343     }
344
345     #
346     #   This belongs to the former test but tests if two chained actions have
347     #   priority over an action with the exact arguments.
348     #
349     {
350         my @expected = qw[
351           TestApp::Controller::Action::Chained->begin
352           TestApp::Controller::Action::Chained->priority_b2
353           TestApp::Controller::Action::Chained->priority_b2_end
354           TestApp::Controller::Action::Chained->end
355         ];
356
357         my $expected = join( ", ", @expected );
358
359         ok( my $response = request('http://localhost/chained/priority_b/1/end/2'),
360             'priority - fixed args vs. parent/child' );
361         is( $response->header('X-Catalyst-Executed'),
362             $expected, 'Executed actions' );
363         is( $response->content, '1; 2', 'Content OK' );
364     }
365
366     #
367     #   Test dispatching between two controllers that are on the same level and
368     #   therefor have no parent/child relationship.
369     #
370     {
371         my @expected = qw[
372           TestApp::Controller::Action::Chained->begin
373           TestApp::Controller::Action::Chained::Bar->cross1
374           TestApp::Controller::Action::Chained::Foo->cross2
375           TestApp::Controller::Action::Chained->end
376         ];
377
378         my $expected = join( ", ", @expected );
379
380         ok( my $response = request('http://localhost/chained/cross/1/end/2'),
381             'cross controller w/o par/child relation' );
382         is( $response->header('X-Catalyst-Executed'),
383             $expected, 'Executed actions' );
384         is( $response->content, '1; 2', 'Content OK' );
385     }
386
387     #
388     #   This is for testing if the arguments got passed to the actions 
389     #   correctly.
390     #
391     {
392         my @expected = qw[
393           TestApp::Controller::Action::Chained->begin
394           TestApp::Controller::Action::Chained::PassedArgs->first
395           TestApp::Controller::Action::Chained::PassedArgs->second
396           TestApp::Controller::Action::Chained::PassedArgs->third
397           TestApp::Controller::Action::Chained::PassedArgs->end
398         ];
399
400         my $expected = join( ", ", @expected );
401
402         ok( my $response = request('http://localhost/chained/passedargs/a/1/b/2/c/3'),
403             'Correct arguments passed to actions' );
404         is( $response->header('X-Catalyst-Executed'),
405             $expected, 'Executed actions' );
406         is( $response->content, '1; 2; 3', 'Content OK' );
407     }
408
409     #
410     #   The :Args attribute is optional, we check the action not specifying
411     #   it with these tests.
412     #
413     {
414         my @expected = qw[
415           TestApp::Controller::Action::Chained->begin
416           TestApp::Controller::Action::Chained->opt_args
417           TestApp::Controller::Action::Chained->end
418         ];
419
420         my $expected = join( ", ", @expected );
421
422         ok( my $response = request('http://localhost/chained/opt_args/1/2/3'),
423             'Optional :Args attribute working' );
424         is( $response->header('X-Catalyst-Executed'),
425             $expected, 'Executed actions' );
426         is( $response->content, '; 1, 2, 3', 'Content OK' );
427     }
428
429     #
430     #   Tests for optional PathPart attribute.
431     #
432     {
433         my @expected = qw[
434           TestApp::Controller::Action::Chained->begin
435           TestApp::Controller::Action::Chained->opt_pp_start
436           TestApp::Controller::Action::Chained->opt_pathpart
437           TestApp::Controller::Action::Chained->end
438         ];
439
440         my $expected = join( ", ", @expected );
441
442         ok( my $response = request('http://localhost/chained/optpp/1/opt_pathpart/2'),
443             'Optional :PathName attribute working' );
444         is( $response->header('X-Catalyst-Executed'),
445             $expected, 'Executed actions' );
446         is( $response->content, '1; 2', 'Content OK' );
447     }
448
449     #
450     #   Tests for optional PathPart *and* Args attributes.
451     #
452     {
453         my @expected = qw[
454           TestApp::Controller::Action::Chained->begin
455           TestApp::Controller::Action::Chained->opt_all_start
456           TestApp::Controller::Action::Chained->oa
457           TestApp::Controller::Action::Chained->end
458         ];
459
460         my $expected = join( ", ", @expected );
461
462         ok( my $response = request('http://localhost/chained/optall/1/oa/2/3'),
463             'Optional :PathName *and* :Args attributes working' );
464         is( $response->header('X-Catalyst-Executed'),
465             $expected, 'Executed actions' );
466         is( $response->content, '1; 2, 3', 'Content OK' );
467     }
468 }