1

I'm developing a PHP application where I have a form in which the user should upload a text file and an other page works with this data. I'm also creating controller tests with CakePHP and PHPUnit. My question is, how can I make the test automatically upload a file for the tests of this action? Thanks in advance.

update 1: The question in more details: Basically I have a 'submit' action which has the form in its view which submits the parameters (and the uploaded file) to the 'curl' action. Here this curl action processes the uploaded text file and this is actually what I'd like to test. But to test this, I should have an uploaded file with its content, so a more specific question: how could I mock this uploaded file to 'submit' it to my curl controller?

Code snippet for the View:

...
echo '<fieldset><table>';
echo $this->Form->create('Job', array('type' => 'post','action' => 'curl', 'enctype' => 'multipart/form-data'));

echo $this->Form->input('user.name', array('type' => 'hidden', 'value' => $this->User->getCode1(),'name' => 'user.name'));
echo $this->Form->input('class', array('type' => 'hidden', 'value' => $this->Hadoop->getClass(), 'name' => 'class'));
...

update 2: The test I've already written:

public function testCurl() {

    $data = array(
        'user_name' => ...,
        'release' => ...,
        'analysis_period_start' => ...,
        'uploaded_file' => ???
    );

    $Jobs = $this->generate('Jobs', array('components' => array('Session')));
    $Jobs->Session->expects($this->any())->method('setFlash');
    $this->testAction('/jobs/curl', array('data' => $data, 'method' => 'post'));

}

So basically I'm trying to test my curl action with a POST method with the data provided in the $data variable. But I don't know how to mock/imitate an uploaded file into that array.

update 3: The relevant cod snippet from my controller's given action:

public function curl() {
    /* This action accepts only POST request */
    if (!$this->isPOSTRequest())
        return $this->redirect(array('controller' => 'jobs', 'action' => 'submit'));

    /* Create a new entry in the database and get its ID */
    $id = $this->createNewEntryInTheDatabase();

    /* Inserts the new patterns into the DB and looks up the already existing
    ** patterns in the DB. Returns an array with the IDs of the submitted patterns */
    $patternIds = $this->lookupPatternIDsAndInsertNewPatterns($_FILES['patterns']);

    $curl = $this->initCURL();
    ...
    $this->closeCURL($curl);

    return $this->redirect(array('controller' => 'jobs', 'action' => 'submit'));
}

...

private function lookupPatternIDsAndInsertNewPatterns($patternsFile) {
    $patternIDs = null;

    /* One element for each row */
    $patternsArray = $this->convertUploadedCSVFileIntoArray(
        $patternsFile, $this->CSV->getDelimiter(),
        $this->CSV->getEnclosure(), $this->CSV->getEscape());

    ...

    return $patternIDs;
}

/* Returns the patterns from the CSV file in an array */
private function convertUploadedCSVFileIntoArray(
    $patternsFile, $delimiter, $enclosure, $escape) {
    $patternsArray = file($patternsFile['tmp_name']);
    $patterns = null;
    foreach ($patternsArray as $pattern)
        $patterns[] = str_getcsv(
            $pattern,
            $delimiter,
            $enclosure,
            $escape);

    return $patterns;
}
zdtorok
  • 594
  • 1
  • 7
  • 21
  • Thanks for your feedback, I've updated my question with a small code snippet, but I think the other controller parts are not relevant for now. As I've updated the question, I basically would like to test with the content of the uploaded file. – zdtorok May 14 '14 at 10:28
  • You're right, I've added information about my test I've written so far for this part, but my controller is not relevant for my question now. – zdtorok May 14 '14 at 13:01
  • Last attempt. If you want help testing x - you need to show x. No controller code means there can be no answer. -1 – AD7six May 14 '14 at 13:10
  • 2
    I've already said what I want to test. HOW to mock/imitate an uploaded file with POST method to a given action which does some work with the passed input file. I still don't see why would it be relevant for anybody, that what does exactly my controller's given action do with my uploaded file. – zdtorok May 14 '14 at 13:42
  • It's relevant because you have [an x/y problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). You can't do what you're asking because [move_uploaded_file won't work with fake data](http://stackoverflow.com/questions/3402765/how-can-i-write-tests-for-file-upload-in-php) - which means the very first thing to do to help you is determine _if_ your controller action is testable at all. It either is testable because you already thought about this; isn't testable because it's all in one method or worse is testable because it's fundamentally insecure and should be rewritten. – AD7six May 14 '14 at 14:40
  • I've added the controller's code snippet to the question, thanks in advance if you can take a look at it. – zdtorok May 15 '14 at 09:17
  • Well it's not very pretty but you can test that. However, as I alluded earlier it's insecure because there are no checks that the file is infact an upload just. This: `$patternsArray = file($patternsFile['tmp_name']);` Will work with a file upload OR a fabricated post request pointing at anything in the file system (which is what your test case will do); All of that logic should be in a model. – AD7six May 15 '14 at 13:40

0 Answers0