yii2 icon indicating copy to clipboard operation
yii2 copied to clipboard

UploadedFile - Codeception

Open BerkantC opened this issue 8 years ago • 16 comments

What steps will reproduce the problem?

When i have a codeception test, i send the next POST request

$files = [ 'file_name' => codecept_data_dir('image.jpg') ];

but it gets conflicted with the function UploadedFile::saveAs ()

[...] elseif (is_uploaded_file($this->tempName)) [...]

Because the file is not upladed but 'emulated' via codeception

What is the expected result?

File Uploaded

What do you get instead?

File is not uploaded

Additional info

Q A
Yii version 2.0.12
PHP version 7.0.18
Operating system Linux Ubuntu 16.04

BerkantC avatar Jun 06 '17 18:06 BerkantC

Please fix this issue, we can not write any test cases around uploading a file at the moment.

Illuminerdy avatar Feb 02 '18 00:02 Illuminerdy

The same problem here. Can't test because any use of attachFile() will not really save the file in Yii2 at all because UploadedFile::saveAs() with $deleteTempFile = false will check is_uploaded_file() and, if it has not POSTed, it will not be saved. (not sure move_uploaded_file() would work too for the sake of the 'cli' mode.)

sdlins avatar Jun 29 '18 16:06 sdlins

Any idea on how to fix it?

samdark avatar Jun 29 '18 23:06 samdark

Yeah, @samdark. I tryed this and it works fine in my tests (files are being 'copied' or moved as expected):

public function saveAs($file, $deleteTempFile = true)
    {
        if ($this->error == UPLOAD_ERR_OK) {
            // added this if block
            if (YII_ENV_TEST) {
                if ($deleteTempFile) {
                    return rename($this->tempName, $file);
                } else {
                    return copy($this->tempName, $file);
                }
            }
            if ($deleteTempFile) {
                return move_uploaded_file($this->tempName, $file);
            } elseif (is_uploaded_file($this->tempName)) {
                return copy($this->tempName, $file);
            }
        }

        return false;
    }

sdlins avatar Jun 30 '18 05:06 sdlins

Can't we mock UploadedFile somehow instead of mixing production code and tests?

samdark avatar Jun 30 '18 22:06 samdark

About the mock, maybe somebody has some idea but now I just cant see how since UploadedFile is being directly instantiated inside the SUT code without use SL/DI.

sdlins avatar Jul 01 '18 02:07 sdlins

@SamMousa do you have any ideas about that?

samdark avatar Jul 02 '18 08:07 samdark

We could mock the function; since UploadedFile is in a namespace, doing this will make it work:

namespace \yii\web {
    function is_uploaded_file() {
        return true;
    }

This code could then be part of the yii2 module, this is a working example:


<?php

namespace test\abc;

class Test {


    public function override() {

        eval(<<<PHP
        namespace test\abc {
            function is_uploaded_file() {
                echo "OVERRIDE IN EFFECT\n";
                return true;
            }
        }
PHP
        );
    }
}

$test = new Test();
$file = tempnam(sys_get_temp_dir(), 'x');
file_put_contents($file, 'abc');
var_dump(is_uploaded_file($file));
$test->override();
var_dump(is_uploaded_file($file));

SamMousa avatar Jul 02 '18 08:07 SamMousa

Sounds much better than conditions in UploadedFile itself. Should we move it to Codeception repo issues?

samdark avatar Jul 02 '18 08:07 samdark

Yes, first there should be a failing test case created: https://github.com/codeception/yii2-tests @BerkantC are you up for that? Basically you create a new app config with a test that fails.

In your case you could even just add a test here: https://github.com/Codeception/yii2-tests/tree/master/cases/simple/functional

SamMousa avatar Jul 02 '18 09:07 SamMousa

Everytime I enter in github I learn more! It seems a very good solution @SamMousa.

sdlins avatar Jul 02 '18 22:07 sdlins

Was it finally fixed? I'm having the same error :(

marcis14 avatar Jan 12 '22 15:01 marcis14

@marcis14 no, it was not. Do you have time to contribute a fix?

samdark avatar Jan 12 '22 16:01 samdark

Yes. If you explain me how to do it, please.

marcis14 avatar Jan 12 '22 16:01 marcis14

I think https://github.com/yiisoft/yii2/issues/14260#issuecomment-401725014 is still valid but tests were moved to https://github.com/Codeception/module-yii2

samdark avatar Jan 12 '22 16:01 samdark

Sorry, didn't get it.

In case it helps, this was my solution:

// Copy if TESTING, move if not $this->file->saveAs($fullPath, !YII_ENV_TEST);

marcis14 avatar Jan 13 '22 07:01 marcis14