]> Dogcows Code - chaz/p5-CGI-Ex/blob - t/4_app_00_base.t
add PSGI handler
[chaz/p5-CGI-Ex] / t / 4_app_00_base.t
1 # -*- Mode: Perl; -*-
2
3 =head1 NAME
4
5 4_app_00_base.t - Check for the basic functionality of CGI::Ex::App.
6
7 =head1 NOTE
8
9 These tests are extremely stripped down to test the basic path flow. Normally
10 unit tests are useful for garnering information about a module. For CGI::Ex::App
11 it is suggested to stick to live use cases or the CGI::Ex::App perldoc - though
12 we do try to put it through most paces.
13
14 =cut
15
16 use Test::More tests => 234;
17 use strict;
18 use warnings;
19 use CGI::Ex::Dump qw(debug caller_trace);
20
21 {
22 package CGIXFail;
23 use vars qw($AUTOLOAD);
24 sub new { bless {}, __PACKAGE__ }
25 sub DESTROY {}
26 sub AUTOLOAD {
27 my $self = shift;
28 my $meth = ($AUTOLOAD =~ /::(\w+$)/) ? $1 : die "Invalid method $AUTOLOAD";
29 die "Not calling CGI::Ex method $meth while testing App";
30 }
31 }
32 {
33 package Foo;
34
35 use base qw(CGI::Ex::App);
36 use vars qw($test_stdout);
37 use CGI::Ex::Dump qw(debug caller_trace);
38
39 sub cgix { shift->{'cgix'} ||= CGIXFail->new } # for our tests try not to access external
40
41 sub form { shift->{'form'} ||= {} }
42
43 sub cookies { shift->{'cookies'} ||= {} }
44
45 sub init { $test_stdout = '' }
46
47 sub print_out {
48 my $self = shift;
49 my $step = shift;
50 my $str = shift;
51 $test_stdout = ref($str) ? $$str : $str;
52 }
53
54 sub swap_template {
55 my ($self, $step, $file, $swap) = @_;
56 die "No filenames allowed during test mode" if ! ref($file);
57 return $self->SUPER::swap_template($step, $file, $swap);
58 }
59
60 sub auth_args { {login_template => \q{Login Form}, key_user => 'user', key_pass => 'pass', key_cookie => 'user', set_cookie => sub {}} }
61
62 sub get_pass_by_user { '123qwe' }
63
64 ###----------------------------------------------------------------###
65
66 sub main_info_complete { 0 }
67
68 sub main_file_print { return \ "Main Content [%~ extra %]" }
69
70 sub main_path_info_map { shift->{'main_path_info_map'} }
71
72 sub step2_hash_validation { return {wow => {required => 1, required_error => 'wow is required'}} }
73
74 sub step2_path_info_map { [[qr{^/step2/(\w+)$}x, 'wow']] }
75
76 sub step2_file_print { return \ "Some step2 content ([% foo %], [% one %]) <input type=text name=wow>[% wow_error %]" }
77
78 sub step2_hash_swap { return {foo => 'bar', one => 'two'} }
79
80 sub step2_hash_fill { return {wow => 'wee'} }
81
82 sub step2_finalize { shift->append_path('step3') }
83
84 sub step3_info_complete { 0 }
85
86 sub step3_file_print { return \ "All good [%~ extra %]" }
87
88 sub step4_file_val { return {wow => {required => 1, required_error => 'wow is required'}} }
89
90 sub step4_path_info_map { [[qr{^/step4/(\w+)$}x, 'wow']] }
91
92 sub step4_file_print { return \ "Some step4 content ([% foo %], [% one %]) <form><input type=text name=wow>[% wow_error %]</form>[% js_validation %]" }
93
94 sub step4_hash_swap { return {foo => 'bar', one => 'two'} }
95
96 sub step4_hash_fill { return {wow => 'wee'} }
97
98 sub step4_finalize { shift->append_path('step3') }
99
100 sub step5__part_a_file_print { return \ "Step 5 Nested ([% step %])" }
101
102 sub step5__part_a_info_complete { 0 }
103
104 }
105
106 ###----------------------------------------------------------------###
107 ###----------------------------------------------------------------###
108 print "#-----------------------------------------\n";
109 print "### Test some basic returns ###\n";
110
111 ok(! eval { CGI::Ex::App::new() }, "Invalid new");
112 ok(! eval { CGI::Ex::App::new(0) }, "Invalid new");
113
114 my $app = CGI::Ex::App->new({script_name => '/cgi-bin/foo_bar'});
115 ok($app->script_name eq '/cgi-bin/foo_bar', "Can pass in script_name");
116 ok($app->name_module eq 'foo_bar', "Can pass in script_name");
117
118 $app = CGI::Ex::App->new({script_name => '/cgi-bin/foo_bar.pl'});
119 ok($app->script_name eq '/cgi-bin/foo_bar.pl', "Can pass in script_name");
120 ok($app->name_module eq 'foo_bar', "Can pass in script_name");
121
122 ok(Foo->new(name_module => 'foo')->name_module eq 'foo', "Got the name_module");
123 ok(! eval { Foo->new(script_name => '%####$')->name_module } && $@, "Bad script_name");
124 ok(! eval { Foo->new(script_name => '%####$')->name_module('foo') } && $@, "Bad script_name");
125
126 ok(! eval { $app->morph_package } && $@, "Can't get a good morph_package");
127 ok($app->morph_package('foo') eq 'CGI::Ex::App::Foo', "Got a good morph_package");
128 ok($app->morph_package('foo_bar') eq 'CGI::Ex::App::FooBar', "Got a good morph_package");
129
130 ok(ref($app->path), "Got a good path");
131 ok(@{ $app->path } == 0, "Got a good path");
132 is($app->default_step, 'main', "Got a good default_step");
133 is($app->login_step, '__login', "Got a good login_step");
134 is($app->error_step, '__error', "Got a good error_step");
135 is($app->forbidden_step, '__forbidden', "Got a good forbidden_step");
136 is($app->js_step, 'js', "Got a good js_step");
137
138 # check for different step types
139 is($app->run_hook('file_print', '__leading_underbars'), 'foo_bar/__leading_underbars.html', 'file_print - __ is preserved at beginning of step');
140 is($app->run_hook('file_print', 'central__underbars'), 'foo_bar/central/underbars.html', 'file_print - __ is used in middle of step');
141 my $ref = ref($app);
142 is($app->run_hook('morph_package', '__leading_underbars'), "${ref}::LeadingUnderbars", 'morph_package - __ is works at beginning of step');
143 is($app->run_hook('morph_package', 'central__underbars'), "${ref}::Central::Underbars", 'morph_package - __ is used in middle of step');
144
145 ###----------------------------------------------------------------###
146 ###----------------------------------------------------------------###
147 print "#-----------------------------------------\n";
148 print "### Test basic step selection/form input/validation/filling/template swapping methods ###\n";
149
150 #$ENV{'REQUEST_METHOD'} = 'GET';
151 #$ENV{'QUERY_STRING'} = '';
152
153 Foo->new({
154 form => {},
155 })->navigate;
156 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo");
157
158 {
159 package Foo2;
160 our @ISA = qw(Foo);
161 sub form { {} }
162 }
163 Foo2->navigate;
164 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo2");
165
166 ###----------------------------------------------------------------###
167
168 {
169 package Foo2_1;
170 our @ISA = qw(Foo);
171 sub pre_navigate { 1 }
172 }
173 Foo2_1->navigate;
174 ok($Foo::test_stdout eq "", "Got the right output for Foo2_1");
175
176 Foo2_1->new({_no_pre_navigate => 1})->navigate;
177 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo2_1");
178
179 {
180 package Foo2_2;
181 our @ISA = qw(Foo);
182 sub pre_loop { 1 }
183 }
184 Foo2_2->navigate;
185 ok($Foo::test_stdout eq "", "Got the right output for Foo2_2");
186
187 {
188 package Foo2_3;
189 our @ISA = qw(Foo);
190 sub post_loop { 1 }
191 }
192 Foo2_3->navigate;
193 ok($Foo::test_stdout eq "", "Got the right output for Foo2_3");
194
195 {
196 package Foo2_4;
197 our @ISA = qw(Foo);
198 sub post_navigate { $Foo::test_stdout .= " post"; 1 }
199 }
200 Foo2_4->navigate;
201 ok($Foo::test_stdout eq "Main Content post", "Got the right output for Foo2_4");
202
203 Foo2_4->new({_no_post_navigate => 1})->navigate;
204 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo2_4");
205
206 my $f;
207
208 ###----------------------------------------------------------------###
209
210 local $ENV{'REQUEST_METHOD'} = 'POST';
211 #$ENV{'QUERY_STRING'} = 'step=step2';
212
213 Foo->new({
214 form => {step => 'step2'},
215 })->navigate;
216 ok($Foo::test_stdout eq "Some step2 content (bar, two) <input type=text name=wow value=\"wee\">wow is required", "Got the right output for Foo");
217
218 Foo->new({
219 form => {step => 'step4'},
220 })->navigate;
221 ok($Foo::test_stdout =~ /Some step4 content.*wow is required.*<script>/s, "Got the right output for Foo (step4)");
222
223 $f = Foo->new({
224 form => {step => 'step5/part_a'},
225 })->navigate;
226 is($Foo::test_stdout, 'Step 5 Nested (step5__part_a)', "Got the right output for Foo (step5__part_a)");
227
228 $f = Foo->new({
229 form => {step => 'step5__part_a'},
230 })->navigate;
231 is($Foo::test_stdout, 'Step 5 Nested (step5__part_a)', "Got the right output for Foo (step5__part_a)");
232
233 {
234 package Foo3;
235 our @ISA = qw(Foo);
236 sub main_info_complete { 1 }
237 }
238 eval { Foo3->navigate };
239 ok($Foo::test_stdout =~ /recurse_limit \(15\)/, "Got the right output for Foo3");
240
241 eval { Foo3->new({recurse_limit => 10})->navigate };
242 ok($Foo::test_stdout =~ /recurse_limit \(10\)/, "Got the right output for Foo3");
243
244 ###----------------------------------------------------------------###
245
246 #$ENV{'REQUEST_METHOD'} = 'GET';
247 #$ENV{'QUERY_STRING'} = 'step=step2&wow=something';
248
249 Foo->new({
250 form=> {step => 'step2', wow => 'something'},
251 })->navigate;
252 ok($Foo::test_stdout eq "All good", "Got the right output for Foo");
253
254 ###----------------------------------------------------------------###
255
256 #$ENV{'REQUEST_METHOD'} = 'GET';
257 #$ENV{'QUERY_STRING'} = 'step=step2&wow=something';
258
259 Foo->new({
260 form=> {step => '_bling'},
261 })->navigate;
262 ok($Foo::test_stdout =~ /Denied/i, "Got the right output for Foo");
263
264 {
265 package Foo4;
266 our @ISA = qw(Foo);
267 sub path { shift->{'path'} ||= ['3foo'] }
268 }
269 Foo4->new({form => {}})->navigate;
270 ok($Foo::test_stdout =~ /Denied/i, "Got the right output for Foo4");
271
272 ###----------------------------------------------------------------###
273
274 #$ENV{'REQUEST_METHOD'} = 'GET';
275 #$ENV{'QUERY_STRING'} = '';
276 local $ENV{'PATH_INFO'} = '/step2';
277
278 Foo->new({
279 form=> {},
280 })->navigate;
281 ok($Foo::test_stdout eq "Some step2 content (bar, two) <input type=text name=wow value=\"wee\">wow is required", "Got the right output");
282
283 Foo->new({
284 path_info_map_base => [],
285 })->navigate;
286 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo ($Foo::test_stdout)");
287
288 Foo->new({
289 path_info_map_base => [[qr{(?!)}, 'foo']],
290 })->navigate;
291 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo ($Foo::test_stdout)");
292
293 eval { Foo->new({
294 path_info_map_base => {},
295 })->navigate };
296 ok($Foo::test_stdout eq "", "Got the right output for Foo");
297
298 eval { Foo->new({
299 path_info_map_base => [{}],
300 })->navigate };
301 ok($Foo::test_stdout eq "", "Got the right output for Foo");
302
303 {
304 package Foo5;
305 our @ISA = qw(Foo);
306 sub path_info_map_base {}
307 }
308 Foo5->navigate;
309 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo5");
310
311 local $ENV{'PATH_INFO'} = '/blah';
312
313 eval { Foo->new({
314 path_info_map_base => [],
315 main_path_info_map => {},
316 })->navigate };
317 ok($Foo::test_stdout =~ /fatal error.+path_info_map/, "Got the right output for Foo");
318
319 eval { Foo->new({
320 path_info_map_base => [],
321 main_path_info_map => [{}],
322 })->navigate };
323 ok($Foo::test_stdout =~ /fatal error.+path_info_map/, "Got the right output for Foo");
324
325 ###----------------------------------------------------------------###
326
327 local $ENV{'PATH_INFO'} = '/whatever';
328 $f = Foo->new({
329 path_info_map_base => [[qr{(.+)}, sub { my ($form, $m1) = @_; $form->{'step'} = 'step3'; $form->{'extra'} = $m1 }]],
330 })->navigate;
331 is($Foo::test_stdout, 'All good/whatever', "Got the right output path_info_map_base with a code ref");
332
333 ###----------------------------------------------------------------###
334
335 #$ENV{'REQUEST_METHOD'} = 'GET';
336 #$ENV{'QUERY_STRING'} = 'wow=something';
337 local $ENV{'PATH_INFO'} = '/step2';
338
339 $f = Foo->new({
340 form=> {wow => 'something'},
341 })->navigate;
342 ok($Foo::test_stdout eq "All good", "Got the right output");
343 ok($f->form->{'step'} eq 'step2', "Got the right variable set in form");
344
345 ###----------------------------------------------------------------###
346
347 #$ENV{'REQUEST_METHOD'} = 'GET';
348 #$ENV{'QUERY_STRING'} = '';
349 local $ENV{'PATH_INFO'} = '/step2/something';
350
351 $f = Foo->new({
352 form => {},
353 })->navigate;
354 ok($Foo::test_stdout eq "All good", "Got the right output");
355 ok($f->form->{'step'} eq 'step2', "Got the right variable set in form");
356 ok($f->form->{'wow'} eq 'something', "Got the right variable set in form");
357
358 ###----------------------------------------------------------------###
359
360 local $ENV{'PATH_INFO'} = '/step5/part_a';
361 $f = Foo->new({
362 path_info_map_base => [[qr{(.+)}, 'step']],
363 })->navigate;
364 is($Foo::test_stdout, 'Step 5 Nested (step5__part_a)', "Got the right output for Foo (step5/part_a)");
365
366 ###----------------------------------------------------------------###
367
368 local $ENV{'PATH_INFO'} = '';
369
370 {
371 package Foo6;
372 our @ISA = qw(Foo);
373 sub valid_steps { {step2 => 1} }
374 sub js_run_step { $Foo::test_stdout = 'JS' }
375 }
376 Foo6->navigate;
377 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo6");
378
379 Foo6->new({form => {step => 'main'}})->navigate;
380 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo6");
381
382 Foo6->new({form => {step => 'step3'}})->navigate;
383 ok($Foo::test_stdout =~ /denied/i, "Got the right output for Foo6");
384
385 Foo6->new({form => {step => 'step2'}})->navigate;
386 ok($Foo::test_stdout =~ /step2/i, "Got the right output for Foo6");
387
388 Foo6->new({form => {step => Foo6->new->js_step}})->navigate;
389 ok($Foo::test_stdout eq 'JS', "Got the right output for Foo6");
390
391
392
393 ###----------------------------------------------------------------###
394 ###----------------------------------------------------------------###
395 ###----------------------------------------------------------------###
396 ###----------------------------------------------------------------###
397 print "#-----------------------------------------\n";
398 print "### Test Authorization Methods ###\n";
399
400 local $ENV{'PATH_INFO'} = '';
401 local $ENV{'SCRIPT_NAME'} = '/foo';
402
403 Foo->new({
404 form => {},
405 require_auth => 1,
406 })->navigate;
407 is($Foo::test_stdout, "Login Form", "Got the right output");
408
409 Foo->new({
410 form => {},
411 cookies => {user => 'foo/123qwe'},
412 require_auth => 1,
413 })->navigate;
414 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo ($Foo::test_stdout)");
415
416 ok(Foo->new({
417 form => {},
418 cookies => {user => 'foo/123qwe'},
419 })->check_valid_auth, "Ran check_valid_auth");
420
421 my $cva = Foo->new({form => {}, cookies => {user => 'foo/123qwe'}});
422 ok($cva->check_valid_auth && $cva->check_valid_auth, "Can run twice");
423
424
425
426 ok(! Foo->new({
427 form => {},
428 })->check_valid_auth, "Ran check_valid_auth");
429
430 Foo->new({
431 form => {},
432 auth_data => {user => 'foo'},
433 require_auth => 1,
434 })->navigate;
435 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo ($Foo::test_stdout)");
436
437 ###----------------------------------------------------------------###
438
439 Foo->new({
440 form => {},
441 })->navigate_authenticated;
442 ok($Foo::test_stdout eq "Login Form", "Got the right output");
443
444 ###----------------------------------------------------------------###
445
446 {
447 package Bar;
448 our @ISA = qw(Foo);
449 sub require_auth { 1 }
450 }
451
452 Bar->new({
453 form => {},
454 })->navigate;
455 ok($Foo::test_stdout eq "Login Form", "Got the right output for Bar");
456
457 ###----------------------------------------------------------------###
458
459 {
460 package Bar1;
461 our @ISA = qw(Foo);
462 sub require_auth { 1 }
463 }
464
465 my $ok = eval { Bar1->new({
466 form => {},
467 })->navigate_authenticated; 1 }; # can't call navigate_authenticated with overwritten require_auth
468 ok(! $ok, "Got the right output for Bar1");
469
470 ###----------------------------------------------------------------###
471
472 {
473 package Bar2;
474 our @ISA = qw(Foo);
475 sub main_require_auth { 1 }
476 }
477
478 Bar2->new({
479 form => {},
480 })->navigate;
481 ok($Foo::test_stdout eq "Login Form", "Got the right output for Bar2");
482
483 ###----------------------------------------------------------------###
484
485 {
486 package Bar3;
487 our @ISA = qw(Foo);
488 sub require_auth { 1 }
489 sub main_require_auth { 0 }
490 }
491
492 Bar3->new({
493 form => {},
494 })->navigate;
495 ok($Foo::test_stdout eq "Main Content", "Got the right output for Bar3");
496
497 ###----------------------------------------------------------------###
498
499 Foo->new({
500 form => {},
501 require_auth => {main => 0},
502 })->navigate;
503 ok($Foo::test_stdout eq "Main Content", "Got the right output");
504
505 ###----------------------------------------------------------------###
506
507 Foo->new({
508 form => {},
509 require_auth => {main => 1},
510 })->navigate;
511 ok($Foo::test_stdout eq "Login Form", "Got the right output");
512
513 ###----------------------------------------------------------------###
514
515 {
516 package Bar4;
517 our @ISA = qw(Foo);
518 sub pre_navigate { shift->require_auth(0); 0 }
519 }
520
521 Bar4->new({
522 form => {},
523 })->navigate_authenticated;
524 ok($Foo::test_stdout eq "Main Content", "Got the right output for Bar4");
525
526 ###----------------------------------------------------------------###
527
528 {
529 package Bar5;
530 our @ISA = qw(Foo);
531 sub pre_navigate { shift->require_auth(1); 0 }
532 }
533
534 Bar5->new({
535 form => {},
536 })->navigate;
537 ok($Foo::test_stdout eq "Login Form", "Got the right output for Bar5 ($@)");
538
539 ###----------------------------------------------------------------###
540
541 {
542 package Bar6;
543 our @ISA = qw(Foo);
544 sub pre_navigate { shift->require_auth({main => 1}); 0 }
545 }
546
547 Bar6->new({
548 form => {},
549 })->navigate;
550 ok($Foo::test_stdout eq "Login Form", "Got the right output for Bar6 ($@)");
551
552 ###----------------------------------------------------------------###
553 ###----------------------------------------------------------------###
554 ###----------------------------------------------------------------###
555 ###----------------------------------------------------------------###
556 print "#-----------------------------------------\n";
557 print "### Test Configuration methods ###\n";
558
559 {
560 package Conf1;
561 our @ISA = qw(Foo);
562 sub name_module { my $self = shift; defined($self->{'name_module'}) ? $self->{'name_module'} : 'conf_1' }
563 }
564
565 my $file = Conf1->new->conf_file;
566 ok($file && $file eq 'conf_1.pl', "Got a conf_file ($file)");
567
568 ok(! eval { Conf1->new(name_module => '')->conf_file } && $@, "Couldn't get conf_file");
569
570 $file = Conf1->new({ext_conf => 'ini'})->conf_file;
571 ok($file && $file eq 'conf_1.ini', "Got a conf_file ($file)");
572
573 eval { Conf1->new({
574 load_conf => 1,
575 })->navigate };
576 my $err = $@;
577 ok($err, "Got an error");
578 chomp $err;
579 ok($Foo::test_stdout eq "", "Got the right output for Conf1");
580
581 Conf1->new({
582 load_conf => 1,
583 conf => {
584 form => {step => 'step3'},
585 },
586 })->navigate;
587 ok($Foo::test_stdout eq "All good", "Got the right output for Conf1");
588
589 Conf1->new({
590 load_conf => 1,
591 conf_file => {form => {step => 'step3'}},
592 })->navigate;
593 ok($Foo::test_stdout eq "All good", "Got the right output for Conf1");
594
595 Conf1->new({
596 load_conf => 1,
597 conf_file => {form => {step => 'step3'}},
598 conf_validation => {form => {required => 1}},
599 })->navigate;
600 ok($Foo::test_stdout eq "All good", "Got the right output for Conf1");
601
602 eval { Conf1->new({
603 load_conf => 1,
604 conf_file => {},
605 conf_validation => {form => {required => 1}},
606 })->navigate };
607 ok($Foo::test_stdout eq "" && $@, "Got a conf_validation error");
608
609 ###----------------------------------------------------------------###
610 ###----------------------------------------------------------------###
611 ###----------------------------------------------------------------###
612 ###----------------------------------------------------------------###
613 print "#-----------------------------------------\n";
614 print "### Various other coverage tests\n";
615
616 ok(Conf1->new->conf_obj, "Got a conf_obj");
617 ok(Conf1->new(conf_args => {paths => './', directive => 'merge'})->conf_obj, "Got a conf_obj");
618 ok(Conf1->new->val_obj, "Got a val_obj");
619 ok(Conf1->new(val_args => {cgix => Conf1->new->cgix})->val_obj, "Got a val_obj");
620 ok(Conf1->new->load_conf(1), "Ran load_conf");
621
622 ok(Foo2->navigate->clear_app, "clear_app works");
623
624 my $dh = Foo2->navigate;
625 push @{ $dh->history }, "A string", ['A non ref'], {key => 'No elapsed key'};
626 push @{ $dh->history }, {step => 'foo', meth => 'bar', found => 'bar', elapsed => 2, response => {}};
627 push @{ $dh->history }, {step => 'foo', meth => 'bar', found => 'bar', elapsed => 2, response => {hi => 'there'}};
628 push @{ $dh->history }, {step => 'foo', meth => 'bar', found => 'bar', elapsed => 1, response => []};
629 push @{ $dh->history }, {step => 'foo', meth => 'bar', found => 'bar', elapsed => 1, response => ['hi']};
630 push @{ $dh->history }, {step => 'foo', meth => 'bar', found => 'bar', elapsed => 1, response => 'a'};
631 push @{ $dh->history }, {step => 'foo', meth => 'bar', found => 'bar', elapsed => 1, response => 'a'x100};
632 ok($dh->dump_history, "Can call dump_history");
633 ok($dh->dump_history('all'), "Can call dump_history");
634 $dh->{'history_max'} = 10;
635 ok($dh->dump_history('all'), "Can call dump_history");
636
637 {
638 package Foo7;
639 our @ISA = qw(Foo);
640 sub hash_base {}
641 sub hash_common {}
642 sub hash_form {}
643 sub hash_fill {}
644 sub hash_swap {}
645 sub hash_errors {}
646 sub find_hook { my ($self, $hook, $step) = @_; return $self->SUPER::find_hook($hook, $step) if $step eq 'main'; return ["non_code",1] }
647 }
648 Foo7->new({no_history => 1})->navigate;
649 ok($Foo::test_stdout eq "Main Content", "Got the right output for Foo7 ($Foo::test_stdout)");
650
651 ok( eval { Foo->new->run_hook('hash_base', 'main') }, "Can run_hook main hash_base on Foo");
652 ok(! eval { Foo->new->run_hook('bogus', 'main') }, "Can't run_hook main bogus on Foo");
653 ok(! eval { Foo7->new->run_hook('hash_base', 'bogus') }, "Can't run_hook bogus hash_base on Foo7 for other reasons");
654
655 foreach my $meth (qw(auth_args conf_args template_args val_args)) {
656 ok(! CGI::Ex::App->new->$meth, "Got a good $meth");
657 ok(CGI::Ex::App->new($meth => {a=>'A'})->$meth->{'a'} eq 'A', "Got a good $meth");
658 }
659
660 ### test read only
661 foreach my $meth (qw(charset
662 conf_die_on_fail
663 conf_obj
664 conf_path
665 conf_validation
666 default_step
667 error_step
668 forbidden_step
669 js_step
670 login_step
671 mimetype
672 path_info
673 path_info_map_base
674 script_name
675 step_key
676 template_obj
677 template_path
678 val_obj
679 val_path
680 )) {
681 ok(CGI::Ex::App->new($meth => 'blah')->$meth eq 'blah', "I can set $meth");
682 }
683
684 ### test read/write
685 foreach my $meth (qw(base_dir_abs
686 base_dir_rel
687 cgix
688 conf
689 conf_file
690 cookies
691 ext_conf
692 ext_print
693 ext_val
694 form
695 )) {
696 ok(CGI::Ex::App->new($meth => 'blah')->$meth eq 'blah', "I can set $meth");
697 my $c = CGI::Ex::App->new;
698 $c->$meth('blah');
699 ok($c->$meth eq 'blah', "I can set $meth");
700 }
701
702 foreach my $type (qw(base
703 common
704 errors
705 fill
706 form
707 swap
708 )) {
709 my $meth = "hash_$type";
710 ok(CGI::Ex::App->new("hash_$type" => {bing => 'bang'})->$meth->{'bing'} eq 'bang', "Can initialize $meth")
711 if $type ne 'form';
712
713 my $meth2 = "add_to_$type";
714 my $c = CGI::Ex::App->new({cgix => CGI::Ex->new({form=>{}})});
715 $c->$meth2({bing => 'bang'});
716 $c->$meth2(bong => 'beng');
717
718 if ($type eq 'errors') {
719 $c->$meth2({bing => "wow"});
720 ok($c->$meth->{"bing_error"} eq "bang<br>wow", "$meth2 works");
721 ok($c->$meth->{"bong_error"} eq 'beng', "$meth2 works");
722
723 ok($c->has_errors, "has_errors works") if $type eq 'errors';
724 } else {
725 ok($c->$meth->{'bing'} eq 'bang', "$meth2 works");
726 ok($c->$meth->{'bong'} eq 'beng', "$meth2 works");
727 }
728 }
729
730 ok(! eval { CGI::Ex::App->new->get_pass_by_user } && $@, "Got a good error for get_pass_by_user");
731 ok(! eval { CGI::Ex::App->new->find_hook } && $@, "Got a good error for find_hook");
732
733 ###----------------------------------------------------------------###
734 print "#-----------------------------------------\n";
735 print "### Some morph tests ###\n";
736
737 {
738 package Foo8;
739 our @ISA = qw(Foo);
740
741 sub blah1_pre_step { $Foo::test_stdout = 'blah1_pre'; 1 }
742 sub blah2_skip { 1 }
743 sub blah3_info_complete { 1 }
744 sub blah3_post_step { $Foo::test_stdout = 'blah3_post'; 1 }
745
746 sub blah4_prepare { 0 }
747 sub blah4_file_print { \ 'blah4_file_print' }
748
749 sub blah5_finalize { 0 }
750 sub blah5_info_complete { 1 }
751 sub blah5_file_print { \ 'blah5_file_print' }
752
753 sub blah8_morph_package { 'Foo8' }
754 sub blah8_info_complete { 0 }
755 sub blah8_file_print { \ 'blah8_file_print' }
756
757 sub blah6_allow_morph { 1 }
758 package Foo8::Blah6;
759 our @ISA = qw(Foo8);
760 sub info_complete { 0 }
761 sub file_print { \ 'blah6_file_print' }
762 sub early_exit_run_step { $Foo::test_stdout = 'early'; shift->exit_nav_loop }
763
764 sub blah7_allow_morph { 1 }
765 package Foo8::Blah6::Blah7;
766 our @ISA = qw(Foo8::Blah6);
767 sub info_complete { 0 }
768 sub file_print { \ 'blah7_file_print' }
769
770 package Foo8::Blah9;
771 our @ISA = qw(Foo8);
772 sub info_complete { 0 }
773 sub file_print { \ 'blah9_file_print' }
774
775 package Foo8;
776 sub __error_allow_morph { 0 }
777 sub __error_file_print { \ '[% error_step %] - [% error %]' }
778 $INC{'Foo8/Blah10.pm'} = 'internal'; # fake require - not a real App package
779
780 package Foo8;
781 sub blah11_morph_package { 'Not::Exists::Blah11' }
782 }
783
784 Foo8->new({form => {step => 'blah1'}})->navigate;
785 is($Foo::test_stdout, 'blah1_pre', "Got the right output for Foo8");
786
787 Foo8->new({form => {step => 'blah1'}, allow_morph => 1})->navigate;
788 is($Foo::test_stdout, 'blah1_pre', "Got the right output for Foo8");
789
790 Foo8->new({form => {step => 'blah2'}})->navigate;
791 is($Foo::test_stdout, 'Main Content', "Got the right output for Foo8");
792
793 Foo8->new({form => {step => 'blah3'}})->navigate;
794 is($Foo::test_stdout, 'blah3_post', "Got the right output for Foo8");
795
796 Foo8->new({form => {step => 'blah4'}})->navigate;
797 is($Foo::test_stdout, 'blah4_file_print', "Got the right output for Foo8");
798
799 Foo8->new({form => {step => 'blah5'}})->navigate;
800 is($Foo::test_stdout, 'blah5_file_print', "Got the right output for Foo8");
801
802 Foo8->new({form => {step => 'blah5'}, allow_morph => 1})->navigate;
803 is($Foo::test_stdout, 'blah5_file_print', "Got the right output for Foo8");
804
805 Foo8->new({form => {step => 'blah5'}, allow_morph => 0})->navigate;
806 is($Foo::test_stdout, 'blah5_file_print', "Got the right output for Foo8");
807
808 Foo8->new({form => {step => 'blah5'}, allow_morph => {}})->navigate;
809 is($Foo::test_stdout, 'blah5_file_print', "Got the right output for Foo8");
810
811 Foo8->new({form => {step => 'blah5'}, allow_morph => {blah5 => 1}})->navigate;
812 is($Foo::test_stdout, 'blah5_file_print', "Got the right output for Foo8");
813
814 Foo8->new({form => {step => 'blah6'}})->navigate;
815 is($Foo::test_stdout, 'blah6_file_print', "Got the right output for Foo8");
816
817 Foo8->new({form => {step => 'blah8'}, allow_morph => 1})->navigate;
818 is($Foo::test_stdout, 'blah8_file_print', "Got the right output for Foo8 ($Foo::test_stdout)");
819
820 my $foo8 = Foo8->new({form => {step => 'blah7'}});
821 $foo8->morph('blah6');
822 $foo8->navigate;
823 is($Foo::test_stdout, 'blah7_file_print', "Got the right output for Foo8");
824
825 $foo8 = Foo8->new({form => {step => 'early_exit'}, no_history => 1});
826 $foo8->morph('blah6');
827 $foo8->navigate;
828 ok($Foo::test_stdout eq 'early', "Got the right output for Foo8");
829 is(ref($foo8), 'Foo8::Blah6', 'Still is unmorphed right');
830
831 $foo8 = Foo8->new;
832 $foo8->morph;
833 ok(ref($foo8) eq 'Foo8', 'Got the right class');
834 $foo8->morph('blah6');
835 eval { $foo8->exit_nav_loop }; # coverage
836 ok($@, "Got the die from exit_nav_loop");
837
838 Foo8->new({form => {step => 'blah9'}, allow_morph => 2})->navigate;
839 is($Foo::test_stdout, 'blah9_file_print', "Got the right output for Foo8::Blah9 ($Foo::test_stdout)");
840
841 $foo8 = Foo8->new({form => {step => 'blah10'}, allow_morph => 2});
842 eval { $foo8->navigate };
843 #use CGI::Ex::Dump qw(debug);
844 #debug $foo8->dump_history;
845 ok($Foo::test_stdout =~ /^blah10 -/, "Got the right output for Foo8::Blah10");
846 ok($Foo::test_stdout =~ m|Found package Foo8::Blah10|, "Got the right output for Foo8::Blah10") || diag $Foo::test_stdout;
847
848 $foo8 = Foo8->new({form => {step => 'blah11'}, allow_morph => 2});
849 eval { $foo8->navigate };
850 #use CGI::Ex::Dump qw(debug);
851 #debug $foo8->dump_history;
852 ok($Foo::test_stdout =~ /^blah11 -/, "Got the right output for Foo8::Blah11");
853 ok($Foo::test_stdout =~ m|Not/Exists/Blah11.pm.*\@INC|, "Got the right output for Foo8::Blah11") || diag $Foo::test_stdout;
854
855
856 $foo8 = Foo8->new;
857 $foo8->run_hook('morph', 'blah6', 1);
858 is(ref($foo8), 'Foo8::Blah6', "Right package");
859
860 $foo8->run_hook_as('run_step', 'blah7', 'Foo8::Blah6::Blah7');
861 is($Foo::test_stdout, 'blah7_file_print', "Got the right output for Foo8::Blah6::Blah7");
862 is(ref($foo8), 'Foo8::Blah6', "Right package");
863
864 $foo8->run_hook_as('run_step', 'main', 'Foo8');
865 is($Foo::test_stdout, 'Main Content', "Got the right output for Foo8");
866 is(ref($foo8), 'Foo8::Blah6', "Right package");
867
868 $foo8->run_hook_as('run_step', 'blah6', 'Foo8::Blah6');
869 is($Foo::test_stdout, 'blah6_file_print', "Got the right output for Foo8::Blah6");
870 $foo8->run_hook('unmorph', 'blah6');
871 #use CGI::Ex::Dump qw(debug);
872 #debug $foo8->dump_history;
873
874
875
876 {
877 package Baz;
878 our @ISA = qw(Foo);
879 sub default_step { 'bazmain' }
880 sub info_complete { 0 }
881 sub file_print { my ($self, $step) = @_; return \qq{\u$step Content} }
882 sub allow_morph { 1 }
883
884 package Baz::Bstep1;
885 our @ISA = qw(Baz);
886
887 package Baz::Bstep2;
888 our @ISA = qw(Baz);
889 sub hash_swap { shift->goto_step('bstep3') } # hijack it here
890
891 package Baz::Bstep3;
892 our @ISA = qw(Baz);
893 }
894
895 Baz->navigate;
896 is($Foo::test_stdout, 'Bazmain Content', "Got the right output for Foo8::Blah6");
897 Baz->navigate({form => {step => 'bstep1'}});
898 is($Foo::test_stdout, 'Bstep1 Content', "Got the right output for Foo8::Blah6");
899
900 my $baz = Baz->new({form => {step => 'bstep2'}});
901 eval { $baz->navigate };
902 is($Foo::test_stdout, 'Bstep3 Content', "Got the right output for Foo8::Blah6");
903 is(ref($baz), 'Baz', "And back to the correct object type");
904 #debug $baz->dump_history;
905
906 ###----------------------------------------------------------------###
907 print "#-----------------------------------------\n";
908 print "### Some path tests ###\n";
909
910 {
911 package Foo9;
912 our @ISA = qw(Foo);
913 sub file_print {
914 my $self = shift;
915 my $str = "First(".$self->first_step.") Previous(".$self->previous_step.") Current(".$self->current_step.") Next(".$self->next_step.") Last(".$self->last_step.")";
916 return \$str;
917 }
918 sub one_skip { 1 }
919 sub two_skip { 1 }
920 sub info_complete { 0 }
921 sub invalid_run_step { shift->goto_step('::') }
922 }
923 ok(Foo9->new->previous_step eq '', 'No previous step if not navigating');
924
925 my $c = Foo9->new(form => {step => 'one'});
926 $c->add_to_path('three', 'four', 'five');
927 $c->insert_path('one', 'two');
928 $c->navigate;
929 is($Foo::test_stdout, 'First(one) Previous(two) Current(three) Next(four) Last(five)', "Got the right content for Foo9");
930 ok(! eval { $c->set_path("more") }, "Can't call set_path after nav started");
931
932 $c = Foo9->new(form => {step => 'five'});
933 $c->set_path('one', 'two', 'three', 'four', 'five');
934 $c->navigate;
935 is($Foo::test_stdout, 'First(one) Previous(two) Current(three) Next(four) Last(five)', "Got the right content for Foo9");
936
937 $c = Foo9->new;
938 $c->append_path('one');
939 eval { $c->goto_step('FIRST') };
940 is($Foo::test_stdout, 'Main Content', "Can jump without nav_loop started");
941
942 $c = Foo9->new;
943 $c->set_path('one');
944 eval { $c->goto_step('main') };
945 is($Foo::test_stdout, 'Main Content', "Can jump to step not on the path");
946
947 ###----------------------------------------------------------------###
948
949 {
950 package Foo10;
951 our @ISA = qw(Foo);
952
953 sub join_path {
954 my $self = shift;
955 my $s = join "", @{ $self->path };
956 substr($s, $self->{'path_i'}, 0, '(');
957 substr($s, $self->{'path_i'} + 2, 0, ')');
958 return $s;
959 }
960
961 #sub run_hook {
962 # my ($self, $hook, $step) = @_;
963 # print "Into $step: ".$self->join_path."\n" if $hook eq 'run_step';
964 # return $self->SUPER::run_hook($hook, $step);
965 #}
966
967 sub a_run_step {
968 my $self = shift;
969 if ($self->join_path eq '(a)') {
970 $self->append_path('b', 'c', 'd', 'e');
971 $self->jump('CURRENT');
972 } elsif ($self->join_path eq 'a(a)bcde') {
973 $self->jump('NEXT');
974 } elsif ($self->join_path eq 'aab(a)bcde') {
975 $self->jump(1);
976 } elsif ($self->join_path eq 'aabab(a)ababcde') {
977 $self->jump('c');
978 } elsif ($self->join_path eq 'aababacd(a)ababacde') {
979 $self->jump('LAST');
980 } else {
981 die "Shouldn't get here";
982 }
983 }
984
985 sub b_run_step {
986 my $self = shift;
987 if ($self->join_path eq 'aa(b)cde') {
988 $self->jump('PREVIOUS');
989 } elsif ($self->join_path eq 'aaba(b)cde') {
990 $self->jump(-10);
991 } else {
992 die "Shouldn't get here";
993 }
994 }
995
996 sub c_run_step { 0 }
997
998 sub d_run_step { shift->jump('FIRST') }
999
1000 sub e_run_step {
1001 my $self = shift;
1002 $self->replace_path(); # truncate
1003 $self->jump(1);
1004 }
1005
1006 sub default_step { 'z' }
1007
1008 sub z_run_step { 1 }
1009
1010 sub __error_run_step { 1 }
1011 }
1012
1013 my $Foo10 = Foo10->new(form => {step => 'a'});
1014 $Foo10->navigate;
1015 is($Foo10->join_path, 'aababacdae(z)', 'Followed good path');
1016
1017 ###----------------------------------------------------------------###
1018 print "#-----------------------------------------\n";
1019 print "### Integrated validation tests ###\n";
1020
1021 {
1022 package Foo11;
1023 our @ISA = qw(Foo);
1024 sub step1_skip { 1 }
1025 sub step1_next_step { 'step6' }
1026 sub step6_file_print { \ 'step6_file_print' }
1027 sub step2_name_step { '' }
1028 sub step3_name_step { 'foo.htm' }
1029
1030 package Foo12;
1031 our @ISA = qw(Foo11);
1032 sub val_path { '' }
1033 }
1034
1035 local $ENV{'SCRIPT_NAME'} = '/cgi/ralph.pl';
1036 ok(Foo11->new->file_print("george") eq 'ralph/george.html', 'file_print: '. Foo11->new->file_print("george"));
1037 ok(Foo11->new->file_val("george") =~ m|\Q/ralph/george.val\E|, 'file_val: '. Foo11->new->file_val("george"));
1038 ok(ref(Foo12->new->file_val("george")) eq 'HASH', 'file_val: no such path');
1039 ok(Foo11->new(val_path => '../' )->file_val("george") eq '../ralph/george.val', 'file_val');
1040 ok(Foo11->new(val_path => sub {'../'} )->file_val("george") eq '../ralph/george.val', 'file_val');
1041 ok(Foo11->new(val_path => ['../'] )->file_val("george") eq '../ralph/george.val', 'file_val');
1042 ok(Foo11->new(val_path => ['../', './'])->file_val("george") eq '../ralph/george.val', 'file_val');
1043
1044 ok(! eval { Foo11->new->file_print("step2") } && $@, 'Bad name_step');
1045 ok(! eval { Foo11->new->file_val("step2") } && $@, 'Bad name_step');
1046
1047 ok(Foo11->new->file_print("step3") eq 'ralph/foo.htm', 'file_print: '. Foo11->new->file_print("step3"));
1048 ok(Foo11->new->file_val("step3") =~ m|\Q/ralph/foo.val\E|, 'file_val: '. Foo11->new->file_val("step3"));
1049
1050
1051 local $ENV{'REQUEST_METHOD'} = 'POST';
1052
1053 Foo11->new(form => {step => 'step1'})->navigate;
1054 ok($Foo::test_stdout eq 'step6_file_print', "Refine Path and set_ready_validate work ($Foo::test_stdout)");
1055
1056 $f = Foo11->new;
1057 $f->set_ready_validate(1);
1058 ok($f->ready_validate, "Is ready to validate");
1059 $f->set_ready_validate(0);
1060 ok(! $f->ready_validate, "Not ready to validate");
1061 $f->set_ready_validate(1);
1062 ok($f->ready_validate, "Is ready to validate");
1063 $f->set_ready_validate('somestep', 0);
1064 ok(! $f->ready_validate, "Not ready to validate");
1065
1066 ###----------------------------------------------------------------###
1067
1068 {
1069 package Foo13;
1070 our @ISA = qw(Foo);
1071 sub step0_ready_validate { 1 }
1072 sub step0_hash_validation { {foo => {required => 1}} }
1073
1074 sub step1_ready_validate { 1 }
1075 sub step1_form_name { shift->{'step1_form_name'} }
1076 sub step1_hash_validation { shift->{'step1_hash_validation'} }
1077 sub step1_file_print { \ 'step1_file_print [% has_errors %]' }
1078 }
1079
1080 ok(Foo13->new(ext_val => 'html')->navigate, 'Ran Foo13');
1081 ok($Foo::test_stdout eq 'Main Content', "Got the right content on Foo13 ($Foo::test_stdout)");
1082
1083 Foo13->new(form => {step => 'step1'})->navigate->js_validation('step1');
1084 ok($Foo::test_stdout eq 'Main Content', "Got the right content on Foo13");
1085
1086 ok(Foo13->new->js_validation('step1') eq '', "No validation found");
1087 ok(Foo13->new->js_validation('step1', 'foo') eq '', "No validation found");
1088 ok(Foo13->new->js_validation('step1', 'foo', {}) eq '', "No validation found");
1089 ok(Foo13->new->js_validation('step1', 'foo', {foo => {required => 1}}), "Validation found");
1090
1091 ###----------------------------------------------------------------###
1092 print "#-----------------------------------------\n";
1093 print "### Header tests ###\n";
1094
1095 {
1096 package CGIX;
1097 sub new { bless {}, __PACKAGE__ }
1098 sub get_form { {} }
1099 sub print_js {
1100 my ($self, $file) = @_;
1101 $Foo::test_stdout = "Print JS: $file";
1102 }
1103 sub print_content_type {
1104 my $self = shift;
1105 my $mime = shift || 'text/html';
1106 my $char = shift || '';
1107 $mime .= "; charset=$char" if $char && $char =~ m|^[\w\-\.\:\+]+$|;
1108 $Foo::test_stdout = "Print: $mime";
1109 }
1110 }
1111
1112 CGI::Ex::App->new(cgix => CGIX->new)->js_run_step;
1113 ok($Foo::test_stdout eq 'Print JS: ', "Ran js_run_step: $Foo::test_stdout");
1114
1115 CGI::Ex::App->new(cgix => CGIX->new, form => {js => 'CGI/Ex/validate.js'})->js_run_step;
1116 ok($Foo::test_stdout eq 'Print JS: CGI/Ex/validate.js', "Ran js_run_step: $Foo::test_stdout");
1117
1118 CGI::Ex::App->new(cgix => CGIX->new, path_info => '/js/CGI/Ex/validate.js')->js_run_step;
1119 ok($Foo::test_stdout eq 'Print JS: CGI/Ex/validate.js', "Ran js_run_step: $Foo::test_stdout");
1120
1121 CGI::Ex::App->new(cgix => CGIX->new)->print_out('foo', "# the output\n");
1122 ok($Foo::test_stdout eq 'Print: text/html', "Got right header: $Foo::test_stdout");
1123 CGI::Ex::App->new(cgix => CGIX->new, mimetype => 'img/gif')->print_out('foo', "# the output\n");
1124 ok($Foo::test_stdout eq 'Print: img/gif', "Got right header: $Foo::test_stdout");
1125 CGI::Ex::App->new(cgix => CGIX->new, charset => 'ISO-foo')->print_out('foo', "# the output\n");
1126 ok($Foo::test_stdout eq 'Print: text/html; charset=ISO-foo', "Got right header: $Foo::test_stdout");
1127
1128 CGI::Ex::App->new(cgix => CGIX->new)->print_out('foo', \ "# the output\n");
1129 ok($Foo::test_stdout eq 'Print: text/html', "Got right header: $Foo::test_stdout");
1130
1131 ###----------------------------------------------------------------###\
1132 print "#-----------------------------------------\n";
This page took 0.088971 seconds and 4 git commands to generate.