Elwhis
Elwhis

Reputation: 1261

cakephp controller testing - how to test actions which require authorization?

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); 
}

Upvotes: 4

Views: 3521

Answers (2)

John Hogan
John Hogan

Reputation: 1036

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>');
}

Upvotes: 2

Jeff Parker
Jeff Parker

Reputation: 7507

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();
}

Upvotes: 6

Related Questions