I have implemented a Mojolicious Web Service as a module that accepts file uploads via POST. An example cURL command:
curl -X POST http://localhost:3000/process -F inputFile=@file.txt
This works as expected, the file is processed and the result is returned.
I am now trying to test it using Test::Mojo like this:
my $t = Test::Mojo->new( 'TK::Proxy' );
my $data = {
inputFile => { filename => 't/file.txt' },
};
$t->post_ok('/process' => form => $data)
->status_is(200)
The test fails:
$ ./Build test
[...]
# Failed test '200 OK'
# at t/20_app.t line 44.
# got: '400'
# expected: '200'
Debugging the code reveals that the uploaded content is empty.
I have verified that it finds the file by adding a simple print before the test:
open FILE,'<', 't/file.pdf' or die("Could not read file");
while (my $line = <FILE>) {
print STDERR ($line . "\n");
}
This outputs the file as expected.
My conclusion is hence that the error is in the post_ok
call and/or the structure of $data
, but I could not figure out where. As far as I can tell, the call looks exactly like in the example given in the documentation.
This is how the file content is processed on the server-side:
my $self = shift()->openapi()->valid_input() or return;
my $input = $self->validation()->output();
my $content;
eval {
my $document = $input->{inputFile}->slurp;
$content = $self->textractor()
->process(
$input->{source},
$input->{target},
$document,
_parse_runtime_params($input->{runtimeParams}),
);
};
It turns out that the result of $input->{inputFile}->slurp;
is an empty string for the test. In the cURL call, however, it correctly contains the file content.
The solution, as indicated by @Boroding, was indeed to replace fileName
with file
:
my $data = {
inputFile => { file => 't/file.txt' },
};
$t->post_ok('/process' => form => $data)->status_is(200);
Presumably, the reason why this is missing in the documentation example is that test should not depend on external files. So the cleaner way to do this is:
my $data = {
inputFile => { content => "File content", fileName => 'file.txt' },
};
$t->post_ok('/process' => form => $data)->status_is(200);