From: David Baird Date: Tue, 11 Oct 2005 21:30:59 +0000 (+0000) Subject: Implemented daveh's fixes for is_applicable() - X-Git-Tag: 2.11~122 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=maypole.git;a=commitdiff_plain;h=699c932710930328fa6942c375e097fbced03e5a Implemented daveh's fixes for is_applicable() - renaming it to is_model_applicable() and returning a boolean. Refactored tj's default_table_view() code within is_model_applicable(), but commented it out until we have implementations of _default_table_view() and _have_default_table_view() git-svn-id: http://svn.maypole.perl.org/Maypole/trunk@396 48953598-375a-da11-a14b-00016c27c3ee --- diff --git a/lib/Maypole.pm b/lib/Maypole.pm index e8de04e..36f0858 100644 --- a/lib/Maypole.pm +++ b/lib/Maypole.pm @@ -115,7 +115,7 @@ sub handler_guts $self->__load_model; - my $applicable = __to_boolean( $self->is_applicable ); + my $applicable = $self->is_model_applicable; $self->__setup_plain_template unless $applicable; @@ -225,51 +225,63 @@ sub __load_model # instead of changing is_applicable() to return 0 or 1, the return value is # passed through __to_boolean. I think it helps handler_guts() if we don't # have multiple sets of return codes being checked for different things -drb. -sub is_applicable +sub is_model_applicable { my ($self) = @_; + # cater for applications that are using obsolete version + if ($self->can('is_applicable')) + { + warn "DEPRECATION WARNING: rewrite is_applicable to the interface ". + "of Maypole::is_model_applicable\n"; + return $self->is_applicable == OK; + } + + # Establish which tables should be processed by the model my $config = $self->config; $config->ok_tables || $config->ok_tables( $config->display_tables ); $config->ok_tables( { map { $_ => 1 } @{ $config->ok_tables } } ) if ref $config->ok_tables eq "ARRAY"; + + my $ok_tables = $config->ok_tables; + # Does this request concern a table to be processed by the model? my $table = $self->table; - warn "We don't have that table ($table).\n" - . "Available tables are: " - . join( ",", @{ $config->ok_tables } ) - if $self->debug - and not $config->ok_tables->{$table} - and $self->action; # this is probably always true - - return DECLINED unless exists $config->ok_tables->{$table}; - - my $path_is_ok = 0; - if (exists $config->ok_tables->{ $self->{table} }) { - $path_is_ok = 1; - } else { - if ( $self->_have_default_table_view ) { - my $path_is_ok = $self->default_table_view($self->{path},$self->{args}); - } - unless ($path_is_ok) { - warn "We don't have that table ($self->{table}).\n" - . "Available tables are: " - . join( ",", @{ $config->{display_tables} } ) - if $self->debug - and not $config->ok_tables->{ $self->{table} } - and $self->{action}; - } + my $ok = 0; + + if (exists $ok_tables->{$table}) + { + $ok = 1; + } +# implements tj's default_table_view(), but there's no _default_table_view() +# or _have_default_table_view() yet +# else +# { +# $ok = $self->default_table_view($self->path, $self->args) +# if $self->_have_default_table_view; +# } + + if (not $ok) + { + warn "We don't have that table ($table).\n" + . "Available tables are: " + . join( ",", keys %$ok_tables ) + if $self->debug and not $ok_tables->{$table}; + + return 0; } - - return DECLINED() unless $path_is_ok; - - # Is it public? - return DECLINED unless $self->model_class->is_public($self->action); - return OK; + # Is the action public? + my $action = $self->action; + return 1 if $self->model_class->is_public($action); + + warn "The action '$action' is not applicable to the table $table" + if $self->debug; + + return 0; } # *only* intended for translating the return code from is_applicable() @@ -542,9 +554,17 @@ or CGI request object, it defaults to blank. Returns a Maypole::Constant to indicate whether the request is valid. -The default implementation checks that C<$self-Etable> is publicly -accessible -and that the model class is configured to handle the C<$self-Eaction> +B as of version 2.11. If you have overridden it, +please override C instead, and change the return type +from Maypole:Constants to true/false. + +=head3 is_model_applicable + +Returns true or false to indicate whether the request is valid. + +The default implementation checks that C<< $r->table >> is publicly +accessible and that the model class is configured to handle the +C<< $r->action >>. =head3 authenticate diff --git a/t/maypole.t b/t/maypole.t index f376697..8686254 100755 --- a/t/maypole.t +++ b/t/maypole.t @@ -1,7 +1,7 @@ #!/usr/bin/perl use strict; use warnings; -use Test::More tests => 73; +use Test::More tests => 74; use Test::MockModule; # module compilation @@ -26,7 +26,7 @@ my $ERROR = Maypole::Constants::ERROR(); my @API = qw/ config init_done view_object params query objects model_class template_args output path args action template error document_encoding content_type table headers_in headers_out - is_applicable setup init handler handler_guts + is_model_applicable setup init handler handler_guts call_authenticate call_exception additional_data authenticate exception parse_path get_template_root get_request parse_location send_output @@ -34,6 +34,8 @@ my @API = qw/ config init_done view_object params query objects model_class can_ok(Maypole => @API); +ok( ! UNIVERSAL::can(Maypole => 'is_applicable'), 'no is_applicable() method' ); + ok(Maypole->config->isa('Maypole::Config'), 'config is a Maypole::Config object'); ok(! Maypole->init_done, '... which is false by default'); is(Maypole->view_object, undef, '... which is undefined'); @@ -183,7 +185,9 @@ my ($r, $req); # request objects my $mock_table = new Test::MockModule($table_class, no_auto => 1); $mock_driver->mock( - is_applicable => sub {push @{$called{applicable}},\@_; $applicable}, + #is_applicable => sub {push @{$called{applicable}},\@_; $applicable}, + is_model_applicable => + sub {push @{$called{applicable}},\@_; $applicable}, get_request => sub {($r, $req) = @_}, additional_data => sub {$called{additional_data}++}, ); @@ -202,7 +206,7 @@ my ($r, $req); # request objects ); # allow request - $applicable = $OK; + $applicable = 1; $r->{path} = '/table/action'; $r->parse_path; @@ -218,7 +222,7 @@ my ($r, $req); # request objects # decline request %called = (); - $applicable = $DECLINED; + $applicable = 0; $r->{path} = '/table/action'; $r->parse_path; @@ -255,7 +259,7 @@ my ($r, $req); # request objects # ... TODO view processing error handling } -# is_applicable() +# is_model_applicable() { $r->config->display_tables([qw(one two)]); $r->config->ok_tables(undef); @@ -264,19 +268,19 @@ my ($r, $req); # request objects $r->action('unittest'); my $is_public; $mock_model->mock('is_public', sub {0}); - my $status = $r->is_applicable; - is($status, $DECLINED, - '... return DECLINED unless model_class->is_public(action)'); + my $true_false = $r->is_model_applicable; + is($true_false, 0, + '... returns 0 unless model_class->is_public(action)'); $mock_model->mock('is_public', sub {$is_public = \@_; 1}); - $status = $r->is_applicable; - is($status, $OK, '... returns OK if table is in ok_tables'); + $true_false = $r->is_model_applicable; + is($true_false, 1, '... returns 1 if table is in ok_tables'); is_deeply($is_public, [$r->model_class, 'unittest'], '... calls model_class->is_public with request action'); is_deeply($r->config->ok_tables, {one => 1, two => 1}, '... config->ok_tables defaults to config->display_tables'); delete $r->config->ok_tables->{one}; - $status = $r->is_applicable; - is($status, $DECLINED, '... return DECLINED unless $r->table is in ok_tables'); + $true_false = $r->is_model_applicable; + is($true_false, 0, '... returns 0 unless $r->table is in ok_tables'); } my $mock_driver = new Test::MockModule($driver_class, no_auto => 1);