Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added tests that exhibit issue #980 + fix; also fix #979 #993

Open
wants to merge 10 commits into
base: devel
Choose a base branch
from
7 changes: 5 additions & 2 deletions lib/Dancer/Handler.pm
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ sub handle_request {
Dancer::SharedData->request($request);

# deserialize the request body if possible
$request = Dancer::Serializer->process_request($request)
if Dancer::App->current->setting('serializer');
if (Dancer::App->current->setting('serializer')) {
$request = Dancer::Serializer->process_request($request);
return $self->render_response unless $request;
}


# read cookies from client

Expand Down
3 changes: 2 additions & 1 deletion lib/Dancer/Request.pm
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,8 @@ sub _build_params {
%$previous, %{$self->{_query_params}},
%{$self->{_route_params}}, %{$self->{_body_params}},
};

# there may be new parameters in need of _decode()ing
$self->{_params_are_decoded} = 0;
}

# Written from PSGI specs:
Expand Down
9 changes: 7 additions & 2 deletions lib/Dancer/Serializer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,21 @@ sub process_request {

my $old_params = $request->params('body');

# try to deserialize
# deserialize
my $new_params;
eval {
$new_params = engine->deserialize($request->body)
};
if ($@) {
Dancer::Error->new(
code => 400,
title => "Bad request",
message => "Deserialization failed",
)->render;
Dancer::Logger::core "Unable to deserialize request body with "
. engine()
. " : \n$@";
return $request;
return;
}

if(!ref $new_params or ref $new_params ne 'HASH'){
Expand Down
50 changes: 50 additions & 0 deletions t/02_request/19_decode_added_params.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use Dancer ':tests';
use Dancer::Test;
use Test::More;
use Dancer::ModuleLoader;
use LWP::UserAgent;

plan skip_all => "skip test with Test::TCP in win32" if $^O eq 'MSWin32';
plan skip_all => 'Test::TCP is needed to run this test'
unless Dancer::ModuleLoader->load('Test::TCP' => "1.30");

plan skip_all => 'JSON is needed to run this test'
unless Dancer::ModuleLoader->load('JSON');

plan tests => 2;

my $unicode = "\x{30dc}\x{a9}";

Test::TCP::test_tcp(
client => sub {
my $port = shift;
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(
POST => "http://127.0.0.1:$port/foo/$unicode",
[
Host => 'localhost',
Content_Type => 'application/json',
],
to_json({ foo => 'bar' }),
);
my $res = $ua->request($request);
ok $res->is_success, 'Successful response from server';
is $res->content, 1, 'Correct content';
},
server => sub {
my $port = shift;
use Dancer ':tests';
set(
apphandler => 'Standalone',
port => $port,
show_errors => 0,
startup_info => 0,
charset => 'utf-8',
serializer => 'JSON',
);
post '/foo/*' => sub {
params->{splat}[0] eq $unicode;
};
Dancer->dance;
},
);
8 changes: 4 additions & 4 deletions t/14_serializer/02_request_json.t
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ BEGIN {
set 'serializer' => 'JSON', 'show_errors' => 1;

get '/' => sub { { foo => 'bar' } };
post '/' => sub { params };
post '/' => sub { scalar params };
put '/' => sub { param("id") };
get '/error' => sub { send_error( { foo => 42 }, 401 ) };
get '/error_bis' => sub { send_error( 42, 402 ) };
get '/json' => sub {
content_type('application/json');
to_json( { foo => 'bar' } )
+{ foo => 'bar' };
};

response_content_is [ PUT => '/',
Expand All @@ -41,8 +41,8 @@ my $res = dancer_response
(
POST => '/',
{
params => { foo => 1 },
headers => [ 'Content-Type' => 'application/json' ]
headers => [ 'Content-Type' => 'application/json' ],
body => to_json({ foo => 1 }),
}
);

Expand Down
4 changes: 2 additions & 2 deletions t/14_serializer/04_request_xml.t
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ SKIP: {
my $res = dancer_response(
POST => '/',
{
params => { foo => 1 },
headers => [ 'Content-Type' => 'text/xml' ]
headers => [ 'Content-Type' => 'text/xml' ],
body => to_xml({ foo => 1 }),
}
);
is_deeply(
Expand Down
81 changes: 81 additions & 0 deletions t/14_serializer/19_deserialization_failure.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use Dancer ':tests';
use Dancer::Test;
use Test::More;
use Dancer::ModuleLoader;
use LWP::UserAgent;

plan skip_all => "skip test with Test::TCP in win32" if $^O eq 'MSWin32';
plan skip_all => 'Test::TCP is needed to run this test'
unless Dancer::ModuleLoader->load('Test::TCP' => "1.30");

plan skip_all => 'JSON is needed to run this test'
unless Dancer::ModuleLoader->load('JSON');

plan tests => 3;

set serializer => 'JSON';

my $data = { foo => 'bar' };

Test::TCP::test_tcp(
client => sub {
my $port = shift;
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(
PUT => "http://127.0.0.1:$port/deserialization",
[
Host => 'localhost',
Content_Type => 'application/json'
],
to_json($data),
);
my $res = $ua->request($request);
ok $res->is_success, 'Successful response from server';
is_deeply from_json($res->content), $data, 'Correct content';
},
server => sub {
my $port = shift;
use Dancer ':tests';
set(
apphandler => 'Standalone',
port => $port,
show_errors => 0,
startup_info => 0,
);
put '/deserialization' => sub { $data };
Dancer->dance;
},
);

Test::TCP::test_tcp(
client => sub {
my $port = shift;
my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new(
PUT => "http://127.0.0.1:$port/deserialization",
[
Host => 'localhost',
Content_Type => 'application/json'
],
# broken JSON
'{ "foo": "bar", }',
);
my $res = $ua->request($request);
is $res->code, 400, '400 bad request';
},
server => sub {
my $port = shift;
use Dancer ':tests';
set(
apphandler => 'Standalone',
port => $port,
show_errors => 1,
startup_info => 0,
);
put '/deserialization' => sub { $data };
Dancer->dance;
},
);