Search code examples
cakephpuploadintegration-testingcakephp-3.x

CakePHP IntegrationTestTrait, Testing File Upload


I have been stuck on this for days! I am trying to test an a Controller function that reads a file uploaded in $_FILES and sets a variable containing error/success messages.

I know that CakePHP IntegrationTestTrait does not actually dispatch an HTTP request, however, I found a thread of someone claiming they could bypass it:

I have tried implementing the following solution I have found here: https://discourse.cakephp.org/t/unit-testing-of-file-uploads-solved/5241

But the problem still persist.

Controller/StudentsController.php

public function import() {
        if ($this->request->is('post')) {
                .
                .
                . 

                $import = $this->Students->import($this->request->getData('CsvFile.tmp_name'));

                if (! empty($import['errors'])) {
                   $this->Flash->error($error);
                } else {
                    $this->set('import', $import);
                }
       }
}

Here is my Test case using IntegrationTestTrait.

public function testImport() {

        // Append a bad file (wrong type) by spoofing PHP's files array
        $_FILES = [
            'CsvFile' => [
                'name'     => 'student-import-test-1.csv',
                'type'     => 'text/csv',
                'tmp_name' => 'tests/Fixture/csv/',
                'error'    => 0,
                'size'     => 258
            ]
        ];

        $data = [
            'CsvFile.name'     => 'student-import-test-1.csv',
            'CsvFile.type'     => 'text/csv',
            'CsvFile.tmp_name' => 'tests/Fixture/csv/',
            'CsvFile.error'    => 0,
            'CsvFile.size'     => 258
        ];

        $this->post('/students/import', $data);

        $this->assertResponseOk();
        $this->assertFlashElement('Flash/error');

        $_FILES = [];
    }

The $this->assertResponseOk() fails because, Failed asserting that 302 is between 200 and 204. However, the $this->assertFlashElement('Flash/error') is a success.

I am new to Testing on CakePHP. I am stuck on debugging this issue. There are a couple things I believe may be making this

The tmp_name / file may not be accessible. I have tried changing the tmp_name to an incorrect path and I receive a "PSD cannot read stream" error. However, when I change the name to an incorrect filename, there seems to be not difference in output.

Does anyone know how I can debug this further?


Solution

  • I figured out what was wrong. It turns out I wasn't AUTHENTICATING myself.

    I added and Authentication token and loaded fixtures:

    public funciton setUp() {
    
            // Configure Authentication
            $this->session([
                'Auth' => [
                    'User' => [
                        'id' => 21896, /* Insert Test User Info */
                        'is_admin' => false /* Insert Test User Info */
                    ]
                ]
            ]);
    
          // Load Fixtures necessary for User authentication 
          $this->loadFixtures('Users', 'Permissions');