fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-02-28 10:45 am

[dw-free] Need a way to cleanly call controllers from tests

[commit: http://hg.dwscoalition.org/dw-free/rev/37f7a2c8953c]

http://bugs.dwscoalition.org/show_bug.cgi?id=3547

Limit the methods that are supported by controllers to GET/POST/HEAD.
Controllers can override to allow other methods.

Patch by [personal profile] exor674.

Files modified:
  • cgi-bin/DW/Controller/Interface/S2.pm
  • cgi-bin/DW/Request/Standard.pm
  • cgi-bin/DW/Routing.pm
  • cgi-bin/DW/Routing/CallInfo.pm
  • t/routing.t
--------------------------------------------------------------------------------
diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Controller/Interface/S2.pm
--- a/cgi-bin/DW/Controller/Interface/S2.pm	Mon Feb 28 16:33:50 2011 +0800
+++ b/cgi-bin/DW/Controller/Interface/S2.pm	Mon Feb 28 18:44:54 2011 +0800
@@ -21,7 +21,7 @@ use DW::Routing;
 use DW::Routing;
 
 # handle, even with no id, so that we can present an informative error message
-DW::Routing->register_regex( '^/interface/s2(?:/(\d+)?)?$', \&interface_handler, app => 1, format => 'plain' );
+DW::Routing->register_regex( '^/interface/s2(?:/(\d+)?)?$', \&interface_handler, app => 1, format => 'plain', methods => { GET => 1, PUT => 1 } );
 
 # handles menu nav pages
 sub interface_handler {
@@ -101,10 +101,6 @@ sub interface_handler {
 
             return $r->OK;
         }
-    } else {
-        # Return 'method not allowed' so that we can add methods in future
-        # and clients will get a sensible error from old servers.
-        return error( $r, $r->HTTP_METHOD_NOT_ALLOWED, 'Method Not Allowed', 'Only GET and PUT are supported for this resource' );
     }
 }
 
diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Request/Standard.pm
--- a/cgi-bin/DW/Request/Standard.pm	Mon Feb 28 16:33:50 2011 +0800
+++ b/cgi-bin/DW/Request/Standard.pm	Mon Feb 28 18:44:54 2011 +0800
@@ -291,10 +291,14 @@ sub OK        { return 200; }
 sub OK        { return 200; }
 sub HTTP_CREATED { return 201; }
 sub REDIRECT  { return 302; }
+sub NOT_FOUND { return 404; }
+sub SERVER_ERROR { return 500; }
+sub HTTP_UNAUTHORIZED { return 401; }
 sub HTTP_BAD_REQUEST { return 400; }
-sub HTTP_UNAUTHORIZED { return 403; }
-sub NOT_FOUND { return 404; }
+sub HTTP_UNSUPPORTED_MEDIA_TYPE { return 415; }
 sub HTTP_SERVER_ERROR { return 500; }
+sub HTTP_METHOD_NOT_ALLOWED { return 405; }
+sub FORBIDDEN { return 403; }
 
 # spawn a process for an external program
 sub spawn {
diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Routing.pm
--- a/cgi-bin/DW/Routing.pm	Mon Feb 28 16:33:50 2011 +0800
+++ b/cgi-bin/DW/Routing.pm	Mon Feb 28 18:44:54 2011 +0800
@@ -157,6 +157,10 @@ sub _call_hash {
     my $opts = $r->pnote('routing_opts');
 
     $opts->prepare_for_call;
+
+    # check method
+    my $method = uc( $r->method );
+    return $r->HTTP_METHOD_NOT_ALLOWED unless $opts->method_valid( $method );
 
     my $format = $opts->format;
     # check for format validity
@@ -370,7 +374,7 @@ sub _apply_defaults {
 sub _apply_defaults {
     my ( $opts, $hash ) = @_;
 
-    $hash ||= 0;
+    $hash ||= {};
     $opts->{app} = 1 if ! defined $opts->{app} && !$opts->{user};
     $hash->{args} = $opts->{args};
     $hash->{ssl} = $opts->{ssl} || 0;
@@ -382,6 +386,7 @@ sub _apply_defaults {
     $formats = { map { ( $_, 1 ) } @$formats } if ( ref($formats) eq 'ARRAY' );
 
     $hash->{formats} = $formats;
+    $hash->{methods} = $opts->{methods} || { GET => 1, POST => 1, HEAD => 1 };
 
     return $hash;
 }
diff -r b7d1369e7005 -r 37f7a2c8953c cgi-bin/DW/Routing/CallInfo.pm
--- a/cgi-bin/DW/Routing/CallInfo.pm	Mon Feb 28 16:33:50 2011 +0800
+++ b/cgi-bin/DW/Routing/CallInfo.pm	Mon Feb 28 18:44:54 2011 +0800
@@ -114,6 +114,18 @@ sub format_valid {
     return $formats->{$_[0]->format} || 0;
 }
 
+=head2 C<< $self->method_valid( $method ) >>
+
+Returns if the method is valid for the callinfo
+
+=cut
+
+sub method_valid {
+    my $methods = $_[0]->{__hash}->{methods};
+    return 1 if $methods == 1;
+    return $methods->{$_[1]} || 0;
+}
+
 =head2 C<< $self->role >>
 
 Current mode: 'app' or 'user' or 'ssl'
diff -r b7d1369e7005 -r 37f7a2c8953c t/routing.t
--- a/t/routing.t	Mon Feb 28 16:33:50 2011 +0800
+++ b/t/routing.t	Mon Feb 28 18:44:54 2011 +0800
@@ -14,7 +14,7 @@
 # 'perldoc perlartistic' or 'perldoc perlgpl'.
 #
 use strict;
-use Test::More tests => 203;
+use Test::More tests => 238;
 use lib "$ENV{LJHOME}/cgi-bin";
 
 # don't let DW::Routing load DW::Controller subclasses
@@ -251,7 +251,6 @@ handle_redirect( '/xx3', '/xx3/' );
 handle_redirect( '/xx3', '/xx3/' );
 # 194
 
-
 # test dying
 DW::Routing->register_string( "/test/die/all_format", \&died_handler, app => 1, formats => 1 );
 
@@ -259,6 +258,32 @@ handle_server_error( "/test die .json fo
 handle_server_error( "/test die .json format (app)", "/test/die/all_format.json", "json" ); # 2 tests
 handle_server_error( "/test die .html format (app)", "/test/die/all_format.html", "html" ); # 2 tests
 handle_server_error( "/test die .blah format (app)", "/test/die/all_format.blah", "blah" ); # 2 tests
+# 203 ( I know this doesn't add up. )
+
+DW::Routing->register_string( "/test/method/normal", \&handler, app => 1 );
+
+handle_request( "Method GET  - okay", "/test/method/normal", 1, undef, method => 'GET' );  # 3 tests
+handle_request( "Method POST - okay", "/test/method/normal", 1, undef, method => 'POST' );
+handle_request( "Method HEAD - okay", "/test/method/normal", 1, undef, method => 'HEAD' );
+handle_request( "Method PUT  - !ok",  "/test/method/normal", 1, undef, method => 'PUT', expected_error => 405 ); # 1 test
+# 213
+
+DW::Routing->register_string( "/test/method/all", \&handler, app => 1, methods => 1 );
+
+handle_request( "Method GET  - okay", "/test/method/all", 1, undef, method => 'GET' );  # 3 tests
+handle_request( "Method POST - okay", "/test/method/all", 1, undef, method => 'POST' );
+handle_request( "Method HEAD - okay", "/test/method/all", 1, undef, method => 'HEAD' );
+handle_request( "Method PUT  - okay", "/test/method/all", 1, undef, method => 'PUT' );
+handle_request( "Method FOO  - okay", "/test/method/all", 1, undef, method => 'FOO' );
+# 228
+
+DW::Routing->register_string( "/test/method/no_post", \&handler, app => 1, methods => { GET => 1, HEAD => 1, PUT => 1 } );
+
+handle_request( "Method GET  - okay", "/test/method/no_post", 1, undef, method => 'GET' );  # 3 tests
+handle_request( "Method POST - !ok",  "/test/method/no_post", 1, undef, method => 'POST', expected_error => 405 ); # 1 test
+handle_request( "Method HEAD - okay", "/test/method/no_post", 1, undef, method => 'HEAD' ); # 3 tests
+handle_request( "Method PUT  - okay", "/test/method/no_post", 1, undef, method => 'PUT' ); # 3 test
+# 238
 
 
 sub handle_redirect {
@@ -286,7 +311,9 @@ sub handle_request {
     $DW::Request::determined = 0;
     $DW::Request::cur_req = undef;
 
-    my $req = HTTP::Request->new(GET=>"$uri");
+    my $method = $opts{method} || 'GET';
+
+    my $req = HTTP::Request->new($method=>"$uri");
     my $r = DW::Request::Standard->new($req);
 
     $result = undef;
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
No Subject Icon Selected
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org