Search code examples
codeignitercodeigniter-4

Post request for CI4 Unit testing


I have the following code running in CI 4.1.2:

public function testForgotten(){

    fwrite(STDERR,"\n\nProcess Forgotten:\n");

    $_COOKIE[csrf_token()] = csrf_hash();

    $result = $this->post('site/forgotten',array(
        'Username'      => 'my@email.com',
        csrf_token()        => csrf_hash(),
    ));

    print'<pre>';print_r($result->response());print'</pre>';

    $result->assertRedirect();
}

As you can see I simply want to check if the forgotten password form/page is working. However the output of $result->response() includes the unposted to page along with <form action="http://example.com/site/forgotten" id="Config\Forms::reset" enctype="multipart/form-data" method="post" accept-charset="utf-8"> as part of the form (noting I've not put in the example.com - Codeigniter did that! So just wondering what I'm missing in terms of getting this test to run/work?

FYI I'm running under a PHAR file with php punit.phar tests/app/Controllers/SiteTests.php which works fine when running simple get('/path/to/page'); calls.

I have since found the example.com can be changed in phpunit.xml.dist but this has still not fixed the assertRedirect issue.


Solution

  • So the answer appears to be that CI4 does not actually populate the $_GET or $_POST variables rather its own internal mechanism. This becomes apparent when you use:

    $request = \Config\Services::request();
    
    print_r($request->getPost('Username'));
    

    Instead of $_POST.

    The solution is either a) use the getPost() type functions or b) amend the framework (yes shock/horror!) in system/HTTP/RequestTrait.php and setGlobal to include:

    switch ($method){
        case 'post': $_POST = $value; break;
        case 'get': $_GET = $value; break;
    }