Question

The title pretty much says it all. I would like to test e.g. UsersController::admin_index() action, but it's required for the user to be authorized to access this location, therefore when I run the test it sends me to the login page and even when I log in manully, no tests are done.

So how can I force cake to skip authorization without editing the actual authorization code?

btw, in case it helps, my testAdminIndex() code looks like this:

function testAdminIndex() {     
    $result = $this->testAction('/admin/users/index');      
    debug($result); 
}
Was it helpful?

Solution

There's an article that covers the subject here ...

http://mark-story.com/posts/view/testing-cakephp-controllers-the-hard-way

The recommendation is to bypass "testAction" completely and manually perform the request, after adding session values for the authenticated user. The example is as follows ...

function testAdminEdit() {
    $this->Posts->Session->write('Auth.User', array(
        'id' => 1,
        'username' => 'markstory',
    ));
    $this->Posts->data = array(
        'Post' => array(
            'id' => 2,
            'title' => 'Best article Evar!',
            'body' => 'some text',
        ),
        'Tag' => array(
            'Tag' => array(1,2,3),
        )
    );
    $this->Posts->params = Router::parse('/admin/posts/edit/2');
    $this->Posts->beforeFilter();
    $this->Posts->Component->startup($this->Posts);
    $this->Posts->admin_edit();
}

OTHER TIPS

This is on the cakephp testing documentation.

http://book.cakephp.org/3.0/en/development/testing.html#testing-actions-that-require-authentication

Testing Actions That Require Authentication If you are using AuthComponent you will need to stub out the session data that AuthComponent uses to validate a user’s identity. You can use helper methods in IntegrationTestCase to do this. Assuming you had an ArticlesController that contained an add method, and that add method required authentication, you could write the following tests:

public function testAddUnauthenticatedFails()
{
    // No session data set.
    $this->get('/articles/add');

    $this->assertRedirect(['controller' => 'Users', 'action' => 'login']);
}

public function testAddAuthenticated()
{
    // Set session data
    $this->session([
        'Auth' => [
            'User' => [
                'id' => 1,
                'username' => 'testing',
                // other keys.
            ]
        ]
    ]);
    $this->get('/articles/add');

    $this->assertResponseOk();
    // Other assertions.
}

I used this

// Set session data
$this->session(['Auth.User.id' => 1]);

I actually have roles so my solution looks like this:

public function testDisplay()
{
 $this->session(['Auth.User.id' => 1, 'Auth.User.role' => 'admin']);

    $this->get('/pages/home');
    $this->assertResponseOk();
    $this->assertResponseContains('CakePHP');
    $this->assertResponseContains('<html>');
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top