Send file to Restful service in codeception - rest

I would like to test restful API test for file uploading.
I try to run:
$I->sendPOST($this->endpoint, $postData, ['file' => 'example.jpg']);
and I would like it to behave the same as user sent example.jpg file in file input with name file but it doesn't seem to work this way. I'm getting:
[PHPUnit_Framework_ExceptionWrapper] An uploaded file must be an array or an instance of UploadedFile.
Is it possible to upload file using REST plugin in codeception? Documentation is very limited and it's hard to say how to do it.
I'm also testing API using Postman plugin to Google Chrome and I can upload file without a problem using this plugin.

I was struggling with the same problem recently and found out that there is another way to solve the issue without using Symfony's UploadedFile class. You only need to pass the array with file data in the same format as if it were the $_FILES array. For example, this code works perfectly well for me:
$I->sendPOST(
'/my-awesome-api',
[
'sample-field' => 'sample-value',
],
[
'myFile' => [
'name' => 'myFile.jpg',
'type' => 'image/jpeg',
'error' => UPLOAD_ERR_OK,
'size' => filesize(codecept_data_dir('myFile.jpg')),
'tmp_name' => codecept_data_dir('myFile.jpg'),
]
]
);
Hope this helps someone and prevents from inspecting the framework's source code (which I was forced to do, as the docs skip such an important detail)

After testing it seems to make it work we need to use UploadedFile object as file.
For example:
$path = codecept_data_dir();
$filename = 'example-image.jpg';
// copy original test file to have at the same place after test
copy($path . 'example.jpg', $path . $filename);
$mime = 'image/jpeg';
$uploadedFile = new \Symfony\Component\HttpFoundation\File\UploadedFile($path . $filename, $filename, $mime,
filesize($path . $filename));
$I->sendPOST($this->endpoint, $postData, ['file' => $uploadedFile]);

['file' => 'example.jpg'] format works too, but the value must be a correct path to existing file.
$path = codecept_data_dir();
$filename = 'example-image.jpg';
// copy original test file to have at the same place after test
copy($path . 'example.jpg', $path . $filename);
$I->sendPOST($this->endpoint, $postData, ['file' => $path . $filename]);

The below worked for myself,
On server:
$uploadedResume= $_FILES['resume_uploader'];
$outPut = [];
if (isset($uploadedResume) && empty($uploadedResume['error'])) {
$uploadDirectory = 'uploads/users/' . $userId . '/documents/';
if (!is_dir($uploadDirectory)) {
#mkdir($uploadDirectory, 0777, true);
}
$ext = explode('.', basename($uploadedResume['name']));
$targetPath = $uploadDirectory . md5(uniqid()) . '.' . end($ext);
if (move_uploaded_file($uploadedResume['tmp_name'], $targetPath)) {
$outPut[] = ['success' => 'success', 'uploaded_path' => $targetPath];
}
}
return json_encode($output);
Sorry for the long description code :P
On Testing side:
//resume.pdf is copied in to tests/_data directory
$I->sendPOST('/student/resume', [], ['resume_uploader' => codecept_data_dir('resume.pdf') ]);

#Yaronius's answer worked for me after I removed the following header from my test:
$I->haveHttpHeader('Content-Type', 'multipart/form-data');

Related

Image request failing. Possible HTTPS issue

I'm working with some Perl code that I don't understand:
my $tmpdir = "XXX";
my $src = "tmp" . time . int rand 10 . ".jpg";
while ( -s "$tmpdir/$src" ) {
$src = "tmp" . time . int rand 10 . ".jpg";
}
my $ua = LWP::UserAgent->new( keep_alive => 0, timeout => 10 );
my $req = HTTP::Request->new(
"GET",
"https://www.com/act/couponimage/1877",
);
my $res = $ua->request( $req, "$tmpdir/$src" );
if ( ! $res || ! -s "$tmpdir/$src" ) {
header( 301, 0, 0, "https://www.com/" );
exit 0;
}
For some reason it hits the point where it redirects to the main page (the header code).
There is clearly something wrong here because it never executes past the last if clause which redirects. Maybe it has to do with using HTTPS?
It is not a filesystem issue. The following coupon image path works fine
Xxx.com/img/coupon-2600.jpg
The request should be working fine,
but as pointed out, you really should check what version of the packages you are using.
For me ( perl 5.22 - LWP::UserAgent 6.26 ) the call $ua->req( $req ) needs to be $ua->request( $req->uri ). And the file to store the response in must be given with $ua->request( $req->uri, :content_file => $fn ) .
I think the original author assumed the content file would be created by giving the filename to $ua->request. With :content_file, that is what's happening for me. He put the while ( -s $src ) in place to ensure he got a filename that was not yet taken.
Thus, I believe the solution to your problem is to change
my $res = $ua->request($req, "$tmpdir/$src") to
$ua->request($req->uri, ':content_file' => "$tmpdir/$src" );
The docs mention that using :content_file means the actual response content is no longer stored in the object, so you may have to adapt your code.
If all you need is the file, I would adapt the final if to check for the file that should now exist ( which should, I believe, only happen upon successful response ).
If what you need is the $res object to use later, I would probably opt to check the response worked, then print the content to the file you want it in, so just do
my $res = $ua->request( $req->uri );
adapt the if accordingly and print content to file.
I would personally prefer the latter, as I can check the response for success, then print: this seems much clearer.

Zend_Config_Xml

So i will list my problems here, please help
First of all, i use Zend_Http_Client to call to an url:
$client = new Zend_Http_Client('http://mydomain.com/Statistics.aspx?activity=top');
$response = $client->request('POST');
$response = $response->getRawBody();
Then i get an Xml document structure for $response when i print it out:
[?xml version='1.0' encoding='UTF-8'?]
[root]
[member]
[username>gh_MXH[/username]
[money]129300[/money]
[/member]
[member]
[username]sonhothiet_MXH[/username]
[money]107400[/money]
[/member]
[/root]
After that, i use Zend_Config_Xml:
$xmlReader = new Zend_Config_Xml($response);
$xml = $xmlReader->toArray();
But all i get is just only the first element of the array when i print out $xml:
Array
(
[member] => Array
(
[username] => gh_MXH
[money] => 129300
)
)
Please show me how to get all the elements so that i can do the looping like:
foreach($xml as $key => $value){
echo $value['username'] . 'has' . $value['money'];
}
And one more question, when i wrote:
$xml = new Zend_Config_Xml($response, 'root');
It appears an error saying: Section 'root' cannot be found in. Really need your help. Thank you and sorry for bad English.
Don't use Zend_Config_Xml to parse standard XML docments, it is for config files. PHP can easily do this natively:
$xml = simplexml_load_string($response);
foreach($xml->member as $member){
echo $member->username . 'has' . $member->money;
}

Zend_File_Transfer: Rename file after upload

I'm trying to rename the uploaded file with the rename-addFilter. The actual upload already works, but the files are just uploaded and not renamed, so how can I do this?
Here's my Controller-Code, that uploads the file:
//Getting the new filename, works perfectly:
$name = explode('.', $form['pic']);
$ext = $name[1];
$mapper = new Application_Model_CmsMap();
$row = $mapper->fetchRow('childId = "' . $id . '" AND type= "pic"');
$new_filename = $row->name.'.'.$ext;
//All images will and are be stored in /public/images/
//Maybe the picture should be replaced, so it should be overwrited, in case it already exists
$upload->addFilter('Rename', array(
'target' => '/images/'.$new_filename,
'overwrite' => true,
)
);
$upload->receive();
Screw Zend.
Good ol' PHP is easy and works perfectly:
rename('images/'.$form['pic'], 'images/'.$new_filename);
Should work :-)
$transferAdapter = new Zend_File_Transfer_Adapter_Http();
$transferAdapter->receive();
$newFilename = 'MY_NEW_FILE';
$filterFileRename = new Zend_Filter_File_Rename(array(
'target' => 'PATH' + $newFilename,
));
$file = $transferAdapter->getFileName();
// new location and name..
$movedFile = $filterFileRename->filter($file);

How Upload file using Mojolicious?

I have been trying out Mojolicious web framework based on perl. And I have try to develop a full application instead of the Lite. The problem I am facing is that I am trying to upload files to server, but the below code is not working.
Please guide me what is wrong with it. Also, if the file gets uploaded then is it in public folder of the application or some place else.
Thanks in advance.
sub posted {
my $self = shift;
my $logger = $self->app->log;
my $filetype = $self->req->param('filetype');
my $fileuploaded = $self->req->upload('upload');
$logger->debug("filetype: $filetype");
$logger->debug("upload: $fileuploaded");
return $self->render(message => 'File is not available.')
unless ($fileuploaded);
return $self->render(message => 'File is too big.', status => 200)
if $self->req->is_limit_exceeded;
# Render template "example/posted.html.ep" with message
$self->render(message => 'Stuff Uploaded in this website.');
}
(First, you need some HTML form with method="post" and enctype="multipart/form-data", and a input type="file" with name="upload". Just to be sure.)
If there were no errors, $fileuploaded would be a Mojo::Upload. Then you could check its size, its headers, you could slurp it or move it, with $fileuploaded->move_to('path/file.ext').
Taken from a strange example.
To process uploading files you should use $c->req->uploads
post '/' => sub {
my $c = shift;
my #files;
for my $file (#{$c->req->uploads('files')}) {
my $size = $file->size;
my $name = $file->filename;
push #files, "$name ($size)";
$file->move_to("C:\\Program Files\\Apache Software Foundation\\Apache24\\htdocs\\ProcessingFolder\\".$name);
}
$c->render(text => "#files");
} => 'save';
See full code here: https://stackoverflow.com/a/28605563/4632019
You can use Mojolicious::Plugin::RenderFile
Mojolicious::Plugin::RenderFile

addFilter Rename ZendFramework

i need to Rename a file with Zend_File_Transfer() only if new file match with old one in the server using some convention like newfile-1.ext where the -1 is the string that is added but Rename filter is strange, i really dont understand so good.
For example, is necesary some like this:
if(file_exists($file)){
$upload->addFilter('Rename', $file);
}
or Rename does it?
thanks
Here is an example from one of my apps. File is recvieved by an Zend_Form
$upload->receive();
$name = $upload->getFileName();
$newFile = 'mynewfile.xyz'
$filterFileRename = new Zend_Filter_File_Rename(array(
'target' => $this->path . $newFile, // path to file
'overwrite' => true
));
$file = $filterFileRename->filter($name);