From: Dave Rolsky Date: Sat, 22 Jan 2011 15:50:14 +0000 (-0600) Subject: Action::REST::ForBrowsers works, with tests X-Git-Tag: 1.08~93 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Action-Serialize-Data-Serializer.git;a=commitdiff_plain;h=83273f945c722f1a05e584fb44c8664c1ab4c4b4 Action::REST::ForBrowsers works, with tests --- diff --git a/lib/Catalyst/Action/REST/ForBrowsers.pm b/lib/Catalyst/Action/REST/ForBrowsers.pm new file mode 100644 index 0000000..1f647dd --- /dev/null +++ b/lib/Catalyst/Action/REST/ForBrowsers.pm @@ -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; diff --git a/lib/Catalyst/Request/REST.pm b/lib/Catalyst/Request/REST.pm index 1432392..0dacfc6 100644 --- a/lib/Catalyst/Request/REST.pm +++ b/lib/Catalyst/Request/REST.pm @@ -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 index 0000000..c309ae7 --- /dev/null +++ b/t/catalyst-action-rest-action-dispatch-for-browsers.t @@ -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 index 0000000..d9eb184 --- /dev/null +++ b/t/lib/Test/Catalyst/Action/REST/Controller/ActionsForBrowsers.pm @@ -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; +