How to construct a mojo request with file uploads to test a controller?

119 views
Skip to first unread message

Gordon Dollarnanda

unread,
Jul 24, 2020, 5:43:34 AM7/24/20
to Mojolicious
Hi guys,

 Good day. 

 I have my controller working perfectly for file uploads.
 I get my file uploads by doing 

    my @file_uploads = @{ $self->req->uploads() };


  I tried writing the test before development but due to time constraints, I had to cheat and use something else like a webform which i kept posting to my controller.

 Done with the development now and Im picking up where I left off with the test.


What I want to achieve:

  Create a Test::Mojo object which will upload 2 files into my Mojo application .

My test code:


 27 my $t      = Test::Mojo->new('EMU');

 28 my $header = Mojo::Headers->new->from_hash( $t->app->conf->get('test_default_headers') );

 29 my $base_url = q{/emu/api/func/v6/fwm};

 30 my $user_info = $t->app->conf->get('test_userinfo');

 31 

 32 {

 33     my $file_1 = Mojo::Asset::File->new();

 34      $file_1->add_chunk(' this is a test ');

 35 

 36     my $file_2 = Mojo::Asset::File->new();

 37        $file_2->add_chunk(' this is another test ');

 38 

 39     my $userinfo = 'ad...@mytestdomain.com.au:testPasswordHere';

 40 

 41     my $specifc_device_scenario =

 42     {

 43         'url'      => join(q{/}, $base_url, q{files}),

 44         'header'   => $header,

 45         'contents' => [

 46             'format' => q{json},

 47             'file'   => [

 48                 'deviceTypeFile' => $file_1,

 49                 'deviceTypeFile' => $file_2,

 50             ],

 51         ],

 52         'method' => [ 'post', ],

 53         'content-type' => q{application/octet-stream},

 54     };

 55 

 56    $header->append( 'deviceTypeFile' => $file_1);

 57    $header->append( 'deviceTypeFile' => $file_2);

 58     

 59     my $request_url = Mojo::URL->new( $specifc_device_scenario->{'url'})->userinfo(

 60         $userinfo

 61     );  

 62     

 63     $request_url->query( $specifc_device_scenario->{'contents'} );

 64     $t->post_ok( $request_url, $specifc_device_scenario->{'header'})->status_is(200, q{Success in upload} );

 65 }   

 66 

 67 done_testing();

 68  



What I have tried to do:

In my controller , i dumped out the contents of the uploads:

    my @file_uploads = @{ $self->req->uploads() };

    $self->log->debug(" the file uploads: " . Dumper([ \@file_uploads ] ) );


However, whether I used append (in line 56 and 57 ), or replaced append with 'add', or set the static file asset contents in the request object  (in line 59 ), the file uploads persist to be blank.

 Very strangely, when I looked in my logs, this is what I see:


[2020-07-24 19:26:23.55465] [30776] [debug] [_is_nOV1] Input data:

{

  "file" => [

    "deviceTypeFile",

    "Mojo::Asset::File=HASH(0x7fc606825b28)",

    "deviceTypeFile",

    "Mojo::Asset::File=HASH(0x7fc5e2102b90)"

  ],

  "format" => "json"

}


Manual testing with a form:

When I use a webform and submit the contents via the form,it's perfect. The form's element name is 'deviceTypeFile'.

I have also even used the following in the controller to no avail.

    my @file_uploads = @{ $self->req->uploads('deviceTypeFile') };


My question:


  With the attempts above, can anyone please show me how to use Test::Mojo to test POSTing two file objects (Mojo::File::Asset) to a Mojo application?



Thank you, everyone.

Veesh Goldman

unread,
Jul 24, 2020, 7:24:33 AM7/24/20
to mojol...@googlegroups.com
In the test, you're sending your files as JSON. Don't you mean to send them as a multipart file upload, using the multipart generator.

--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mojolicious/4c7be939-a40e-494e-8360-b848ed98c8f9n%40googlegroups.com.

Gordon Dollarnanda

unread,
Jul 24, 2020, 7:43:38 AM7/24/20
to Mojolicious
Yep.

$t = $t->post_ok('http://example.com/foo');
$t = $t->post_ok('/foo');
$t = $t->post_ok('/foo' => {Accept => '*/*'} => 'Content!');
$t = $t->post_ok('/foo' => {Accept => '*/*'} => form => {a => 'b'});
$t = $t->post_ok('/foo' => {Accept => '*/*'} => json => {a => 'b'});


In my case, I have more than 1 file to upload.

 How would I fit the 2 files (Mojo::Asset::File) into the post_ok() body?

Thank you


Gordon Dollarnanda

unread,
Jul 24, 2020, 8:17:15 AM7/24/20
to Mojolicious
I had also looked at https://mojolicious.narkive.com/5XGiHXfh/test-mojo-with-uploading-files.


I had implemented the changes as below to no avail.
The code I used is "    $t->post_ok( $request_url, $upload )->status_is(200, q{Success in upload} );"

The uploaded files still do not get shown in my logs...

 The code in its entirety is as below:

my $t      = Test::Mojo->new('EMU');
my $header = Mojo::Headers->new->from_hash( $t->app->conf->get('test_default_headers') );
my $base_url = q{/api/wow/v6/muz};

my $user_info = $t->app->conf->get('test_userinfo');

{

my $file_1 = Mojo::Asset::File->new();
 $file_1->add_chunk(' this is a test ');

my $file_2 = Mojo::Asset::File->new();
   $file_2->add_chunk(' this is another test ');

my $userinfo = 'adm...@mytestdomain.com.au:dropThePasswordHere';

    my $specifc_device_scenario =
    {
        'url'      => join(q{/}, $base_url, q{deviceTypes}, q{Polycom_VVX101},q{files}),
        'header'   => $header,
        'contents' => [

            'format' => q{json},
            'file'   => [
                'deviceTypeFile' => $file_1,
                'deviceTypeFile' => $file_2,
            ],
        ],

        'method' => [ 'post', ],
        'content-type' => q{application/octet-stream},
    };

 
   $header->content_type($specifc_device_scenario->{'content-type'});


    my $request_url = Mojo::URL->new( $specifc_device_scenario->{'url'})->userinfo(
        $userinfo
    );


    $request_url->query( $specifc_device_scenario->{'contents'} );

    my $upload = {
         'file' =>
         {
             'deviceTypeFile' => $file_1,
             'deviceTypeFile' => $file_2,
         }
    };

    $t->post_ok( $request_url, $upload )->status_is(200, q{Success in upload} );
}





Reply all
Reply to author
Forward
0 new messages