make uri_for unicode safe
Brian Cassidy [Fri, 21 Apr 2006 18:29:33 +0000 (18:29 +0000)]
added utf8 tests for uri_for and uri_with

lib/Catalyst.pm
t/lib/TestApp/Controller/Engine/Request/URI.pm
t/live_engine_request_uri.t
t/unit_core_uri_for.t

index d756514..1026625 100644 (file)
@@ -22,6 +22,7 @@ use Scalar::Util qw/weaken blessed/;
 use Tree::Simple qw/use_weak_refs/;
 use Tree::Simple::Visitor::FindByUID;
 use attributes;
+use utf8;
 use Carp qw/croak/;
 
 __PACKAGE__->mk_accessors(
@@ -854,6 +855,14 @@ sub uri_for {
     my $params =
       ( scalar @args && ref $args[$#args] eq 'HASH' ? pop @args : {} );
 
+    for my $value ( values %$params ) {\r
+        my $isa_ref = ref $value;\r
+        if( $isa_ref and $isa_ref ne 'ARRAY' ) {\r
+            croak( "Non-array reference ($isa_ref) passed to uri_for()" );\r
+        }\r
+        utf8::encode( $_ ) for $isa_ref ? @$value : $value;\r
+    };
+    
     # join args with '/', or a blank string
     my $args = ( scalar @args ? '/' . join( '/', @args ) : '' );
     $args =~ s/^\/// unless $path;
index cf0c408..97b2579 100644 (file)
@@ -41,4 +41,15 @@ sub uri_with : Local {
     $c->forward('TestApp::View::Dump::Request');\r
 }\r
 \r
+sub uri_with_utf8 : Local {\r
+    my ( $self, $c ) = @_;\r
+\r
+    # change the current uri\r
+    my $uri = $c->req->uri_with( { unicode => "\x{2620}" } );\r
+    \r
+    $c->res->header( 'X-Catalyst-uri-with' => "$uri" );\r
+    \r
+    $c->forward('TestApp::View::Dump::Request');\r
+}\r
+\r
 1;\r
index 3bfaec4..dba622f 100644 (file)
@@ -1,4 +1,4 @@
-#!perl\r
+\feff#!perl\r
 \r
 use strict;\r
 use warnings;\r
@@ -6,7 +6,7 @@ use warnings;
 use FindBin;\r
 use lib "$FindBin::Bin/lib";\r
 \r
-use Test::More tests => 35;\r
+use Test::More tests => 38;\r
 use Catalyst::Test 'TestApp';\r
 use Catalyst::Request;\r
 \r
@@ -83,3 +83,10 @@ my $creq;
     is( $response->header( 'X-Catalyst-Param-a' ), '1', 'param "a" ok' );\r
     is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );\r
 }\r
+\r
+# test that uri_with is utf8 safe\r
+{\r
+    ok( my $response = request("http://localhost/engine/request/uri/uri_with_utf8"), 'Request' );\r
+    ok( $response->is_success, 'Response Successful 2xx' );\r
+    like( $response->header( 'X-Catalyst-uri-with' ), qr/%E2%98%A0$/, 'uri_with ok' );\r
+}\r
index f46e2fd..bd0690b 100644 (file)
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 8;
+use Test::More tests => 9;
 use Test::MockObject;
 use URI;
 
@@ -42,6 +42,13 @@ is(
     'URI for undef action with query params'
 );
 
+# test with utf-8
+is(
+    Catalyst::uri_for( $context, 'quux', { param1 => "\x{2620}" } )->as_string,
+    'http://127.0.0.1/foo/yada/quux?param1=%E2%98%A0',
+    'URI for undef action with query params in unicode'
+);
+
 $request->mock( 'base',  sub { URI->new('http://localhost:3000/') } );
 $request->mock( 'match', sub { 'orderentry/contract' } );
 is(
@@ -60,3 +67,4 @@ is(
     is( Catalyst::uri_for( $context, '/bar/baz' )->as_string,
         'http://127.0.0.1/bar/baz', 'URI with no base or match' );
 }
+