Test::Mojo post_ok not reading in POST data correctly

187 views Asked by At

I am creating a simple Mojolicious app that is to be a REST API for some objects in my database. I am trying to test creating a new object, but POSTing data to the object collection. Here is the basic structure of my Test::Mojo script:

use Mojo::Base -strict;
use Test::More;
use Test::Mojo;

use strict;
use warnings;

my $ip_node = {ipname => 'ip_alias.subdomain.company.com', ipservice => 'reserved', ipaddress => '192.168.0.1'};

my $t = Test::Mojo->new('Tools');
$t->post_ok('/tools/ipadmin/nodes' => {Accept => 'application/json'} => form => $ip_node)->status_is(201);

done_testing();

But for whatever reason, the Mojo Controller cannot read in the POST data when sent in the above fashion. To debug this, in my Controller I have the following lines to respond to the request:

my $c = shift;

print "All params: " . $c->req->params . "\n";
print "IP Name: " . $c->req->param("ipname") . "\n";
print "IP Service: " . $c->req->param("ipservice") . "\n";
print "IP Address: " . $c->req->param("ipaddress") . "\n";

When I run the test script via prove:

$ prove -v -I /path/to/workspace/Tools/lib t/basic.t

The output varies between one of these three outputs. Most of the time the all 4 print statements are empty, but occasionally a CRLF + the POST data (with the final two characters stripped off, probably from the CRLF eating up the content_length) and even more rarely the content_length of the HTTP Headers gets output.

All params: %0D%0Aipaddress=192.168.0.1&ipname=ip_alias.subdomain.company.com&ipservice=reserv
IP Name: ip_alias.subdomain.company.com
IP Service: reserv
IP Address: 

All params: User-Agent%3A+Mojolicious+%28Perl%29%0D%0AHost%3A+127.0.0.1%3A35611%0D%0AAccept-Encoding%3A+gzip%0D%0A=
IP Name: 
IP Service: 
IP Address: 

All params: 
IP Name: 
IP Service: 
IP Address:

Has anyone seen this type of behaviour before? Is something with my post_ok syntax wrong? I've read the Mojo docs for Test::Mojo and it looks (to me) like this should work, but it just doesn't. Any ideas?

Thanks!

1

There are 1 answers

0
Sean Rumsby On BEST ANSWER

It turns out that this behavior is the result of a stray newline character on my cookie that is passed in to the Controller. I was creating and attaching a Cookie Jar for authn/authz onto the mojo object with:

my $jar = Mojo::UserAgent::CookieJar->new;

$jar->add(
    Mojo::Cookie::Response->new(
        name   => "$mojo_cookie_name",
        value  => "$cookie_data",
        domain => "127.0.0.1",
        path   => "$mojo_cookie_path"
    )
);

$t->{ua}->{cookie_jar} =  $jar;

But $cookie_data had an extra newline character on it. By performing a chomp() on the $cookie_data before adding it on to the Cookie Jar, everything works as expected. I don't know why the Mojo request failed so spectacularly when there is an extra new line character on the cookie - and I assume it would fail if any manual header has an extra new line character on it as well. If anything further comes of this, I'll updated/comment on this answer accordingly.