[Catalyst-commits] r9494 - in Catalyst-Action-REST/0.60/trunk: lib/Catalyst/Action t

timbunce at dev.catalyst.perl.org timbunce at dev.catalyst.perl.org
Wed Mar 11 16:46:02 GMT 2009


Author: timbunce
Date: 2009-03-11 16:46:02 +0000 (Wed, 11 Mar 2009)
New Revision: 9494

Modified:
   Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm
   Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm
   Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t
Log:
Add content_type_stash_key to enable a stash entry to override the serialize content type.
With docs and tests.


Modified: Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm
===================================================================
--- Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm	2009-03-11 16:08:35 UTC (rev 9493)
+++ Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/Serialize.pm	2009-03-11 16:46:02 UTC (rev 9494)
@@ -99,27 +99,30 @@
 
 =head1 CONFIGURATION
 
-=over 4
+=head2 map
 
-=item default
+Takes a hashref, mapping Content-Types to a given serializer plugin.
 
-The Content-Type of the default Serialization format.  This must be a
-Content-Type associated with a plugin in the "map" section below.  
+=head2 default
 
-This is used if a requested content-type is not recognized.
+This is the 'fall-back' Content-Type if none of the requested or acceptable
+types is found in the L</map>. It must be an entry in the L</map>.
 
-=item stash_key 
+=head2 stash_key 
 
-We will serialize the data that lives in this location in the stash.  So
-if the value is "rest", we will serialize the data under:
+Specifies the key of the stash entry holding the data that is to be serialized.
+So if the value is "rest", we will serialize the data under:
 
   $c->stash->{'rest'}
 
-=item map
+=head2 content_type_stash_key
 
-Takes a hashref, mapping Content-Types to a given plugin.
+Specifies the key of the stash entry that optionally holds an overriding
+Content-Type. If set, and if the specified stash entry has a valid value,
+then it takes priority over the requested content types.
 
-=back
+This can be useful if you want to dynamically force a particular content type,
+perhaps for debugging.
 
 =head1 HELPFUL PEOPLE
 

Modified: Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm
===================================================================
--- Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm	2009-03-11 16:08:35 UTC (rev 9493)
+++ Catalyst-Action-REST/0.60/trunk/lib/Catalyst/Action/SerializeBase.pm	2009-03-11 16:46:02 UTC (rev 9494)
@@ -53,19 +53,28 @@
         $config = $controller->config;
     }
     $map = $config->{'map'};
-    # If we don't have a handler for our preferred content type, try
-    # the default
 
-    my ($content_type) = grep { $map->{$_} } @{$c->request->accepted_content_types};
-
-    unless ( defined $content_type ) {
-        if( exists $config->{'default'} ) {
-            $content_type = $config->{'default'} ;
-        } else {
-            return $self->_unsupported_media_type($c, $content_type);
-        }
+    # pick preferred content type
+    my @accepted_types; # priority order, best first
+    # give top priority to content type specified by stash, if any
+    my $content_type_stash_key = $config->{content_type_stash_key};
+    if ($content_type_stash_key
+        and my $stashed = $c->stash->{$content_type_stash_key}
+    ) {
+        # convert to array if not already a ref
+        $stashed = [ $stashed ] if not ref $stashed;
+        push @accepted_types, @$stashed;
     }
+    # then content types requested by caller
+    push @accepted_types, @{ $c->request->accepted_content_types };
+    # then the default
+    push @accepted_types, $config->{'default'} if $config->{'default'};
+    # pick the best match that we have a serializer mapping for
+    my ($content_type) = grep { $map->{$_} } @accepted_types;
 
+    return $self->_unsupported_media_type($c, $content_type)
+        if not $content_type;
+
     # carp about old text/x-json
     if ($content_type eq 'text/x-json') {
         $c->log->info('Using deprecated text/x-json content-type.');

Modified: Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t
===================================================================
--- Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t	2009-03-11 16:08:35 UTC (rev 9493)
+++ Catalyst-Action-REST/0.60/trunk/t/catalyst-action-serialize-accept.t	2009-03-11 16:46:02 UTC (rev 9494)
@@ -16,6 +16,7 @@
     serialize => {
         'default'   => 'text/x-yaml',
         'stash_key' => 'rest',
+        'content_type_stash_key' => 'serialize_content_type',
         'map'       => {
             'text/x-yaml'        => 'YAML',
             'application/json'   => 'JSON',
@@ -36,16 +37,18 @@
 
 sub test_second :Local :ActionClass('Serialize') {
     my ( $self, $c ) = @_;
+    $c->stash->{'serialize_content_type'} = $c->req->params->{'serialize_content_type'};
     $c->stash->{'rest'} = {
         lou => 'is my cat',
     };
 }
 
+
 package main;
 
 use strict;
 use warnings;
-use Test::More tests => 10;
+use Test::More tests => 16;
 use Data::Serializer;
 use FindBin;
 use Data::Dump qw(dump);
@@ -107,4 +110,26 @@
 	is( $res->header('Content-type'), 'text/x-yaml', '... with expected content-type')
 }
 
+# Make that using content_type_stash_key, an invalid value in the stash gets ignored
+{
+	my $req = $t->get(url => '/test_second?serialize_content_type=nonesuch');
+	$req->remove_header('Content-Type');
+	$req->header('Accept', '*/*');
+	my $res = request($req);
+	ok( $res->is_success, 'GET the serialized request succeeded' );
+	is( $res->content, $data, "Request returned proper data");
+	is( $res->header('Content-type'), 'text/x-yaml', '... with expected content-type')
+}
+
+# Make that using content_type_stash_key, a valid value in the stash gets priority
+{
+	my $req = $t->get(url => '/test_second?serialize_content_type=text/x-data-dumper');
+	$req->remove_header('Content-Type');
+	$req->header('Accept', '*/*');
+	my $res = request($req);
+	ok( $res->is_success, 'GET the serialized request succeeded' );
+	is( $res->content, "{'lou' => 'is my cat'}", "Request returned proper data");
+	is( $res->header('Content-type'), 'text/x-data-dumper', '... with expected content-type')
+}
+
 1;




More information about the Catalyst-commits mailing list