Action::REST::ForBrowsers works, with tests
Dave Rolsky [Sat, 22 Jan 2011 15:50:14 +0000 (09:50 -0600)]
lib/Catalyst/Action/REST/ForBrowsers.pm [new file with mode: 0644]
lib/Catalyst/Request/REST.pm
t/catalyst-action-rest-action-dispatch-for-browsers.t [new file with mode: 0644]
t/lib/Test/Catalyst/Action/REST/Controller/ActionsForBrowsers.pm [new file with mode: 0644]

diff --git a/lib/Catalyst/Action/REST/ForBrowsers.pm b/lib/Catalyst/Action/REST/ForBrowsers.pm
new file mode 100644 (file)
index 0000000..1f647dd
--- /dev/null
@@ -0,0 +1,44 @@
+package Catalyst::Action::REST::ForBrowsers;
+
+use Moose;
+use namespace::autoclean;
+
+our $VERSION = '0.88';
+$VERSION = eval $VERSION;
+
+extends 'Catalyst::Action::REST';
+use Catalyst::Request::REST::ForBrowsers;
+
+sub BUILDARGS {
+    my $class  = shift;
+    my $config = shift;
+    Catalyst::Request::REST::ForBrowsers->_insert_self_into( $config->{class} );
+    return $class->SUPER::BUILDARGS( $config, @_ );
+}
+
+override dispatch => sub {
+    my $self = shift;
+    my $c    = shift;
+
+    my $req = $c->request();
+
+    return super()
+        unless $req->can('looks_like_browser')
+            && $req->looks_like_browser()
+            && uc $c->request()->method() eq 'GET';
+
+    my $controller  = $c->component( $self->class );
+    my $rest_method = $self->name() . '_GET_html';
+
+    if (   $controller->action_for($rest_method)
+        || $controller->can($rest_method) ) {
+
+        return $self->_dispatch_rest_method( $c, $rest_method );
+    }
+
+    return super();
+};
+
+__PACKAGE__->meta->make_immutable;
+
+1;
index 1432392..0dacfc6 100644 (file)
@@ -23,14 +23,15 @@ sub _insert_self_into {
   my $req_class = $app->request_class;
   return if $req_class->isa($class);
   my $req_class_meta = Moose->init_meta( for_class => $req_class );
-  return if $req_class_meta->does_role('Catalyst::TraitFor::Request::REST');
+  my $role = $self->_related_role;
+  return if $req_class_meta->does_role($role);
   if ($req_class eq 'Catalyst::Request') {
     $app->request_class($class);
   }
   else {
       my $meta = Moose::Meta::Class->create_anon_class(
           superclasses => [$req_class],
-          roles => ['Catalyst::TraitFor::Request::REST'],
+          roles => [$role],
           cache => 1
       );
       $meta->_add_meta_method('meta');
@@ -38,6 +39,8 @@ sub _insert_self_into {
   }
 }
 
+sub _related_role { 'Catalyst::TraitFor::Request::REST' }
+
 __PACKAGE__->meta->make_immutable;
 
 1;
diff --git a/t/catalyst-action-rest-action-dispatch-for-browsers.t b/t/catalyst-action-rest-action-dispatch-for-browsers.t
new file mode 100644 (file)
index 0000000..c309ae7
--- /dev/null
@@ -0,0 +1,52 @@
+use strict;
+use warnings;
+use Test::More;
+use FindBin;
+
+use lib ( "$FindBin::Bin/lib", "$FindBin::Bin/../lib" );
+use Test::Rest;
+
+my $t = Test::Rest->new( 'content_type' => 'text/plain' );
+
+use_ok 'Catalyst::Test', 'Test::Catalyst::Action::REST';
+
+my $url = '/actionsforbrowsers/for_browsers';
+
+foreach my $method (qw(GET POST)) {
+    my $run_method = lc($method);
+    my $result     = "something $method";
+    my $res;
+    if ( $method eq 'GET' ) {
+        $res = request( $t->$run_method( url => $url ) );
+    } else {
+        $res = request(
+            $t->$run_method(
+                url  => $url,
+                data => '',
+            )
+        );
+    }
+    ok( $res->is_success, "$method request succeeded" );
+    is(
+        $res->content,
+        "$method",
+        "$method request had proper response"
+    );
+}
+
+my $res = request(
+    $t->get(
+        url     => $url,
+        headers => { Accept => 'text/html' },
+    )
+);
+
+ok( $res->is_success, "GET request succeeded (client looks like browser)" );
+is(
+    $res->content,
+    "GET_html",
+    "GET request had proper response (client looks like browser)"
+);
+
+done_testing;
+
diff --git a/t/lib/Test/Catalyst/Action/REST/Controller/ActionsForBrowsers.pm b/t/lib/Test/Catalyst/Action/REST/Controller/ActionsForBrowsers.pm
new file mode 100644 (file)
index 0000000..d9eb184
--- /dev/null
@@ -0,0 +1,32 @@
+package Test::Catalyst::Action::REST::Controller::ActionsForBrowsers;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends qw/Catalyst::Controller::REST/ }
+
+sub begin {}  # Don't need serialization..
+
+sub for_browsers : Local : ActionClass('REST::ForBrowsers') {
+    my ( $self, $c ) = @_;
+    $c->res->header('X-Was-In-TopLevel', 1);
+}
+
+sub for_browsers_GET : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('GET');
+}
+
+sub for_browsers_GET_html : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('GET_html');
+}
+
+sub for_browsers_POST : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('POST');
+}
+
+sub end : Private {} # Don't need serialization..
+
+1;
+