Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test Magento POST controller action - using (or not) EcomDev PHPUnit module

Is there way to test Magento POST controllers actions? E.g. customer login:

Mage_Customer_AccountController::loginPostAction()

I'm using EcomDev_PHPUnit module for test. It works great with basic actions, but I can't invoke POST actions.

$this->getRequest()->setMethod('POST');
// ivokes loginAction instead loginPostAction
$this->dispatch('customer/account/login');
// fails also
$this->dispatch('customer/account/loginPost');
// but this assert pass
$this->assertEquals('POST', $_SERVER['REQUEST_METHOD']);

I would like to make tests more or less like

// ... some setup
$this->getRequest()->setMethod('POST');
$this->dispatch('customer/account/login');
// since login uses singleton, then...
$session = Mage::getSingleton('customer/session');
$this->assertTrue($session->isLoggedIn());
like image 797
Marcin Rogacki Avatar asked Dec 11 '22 23:12

Marcin Rogacki


1 Answers

In customer account controller login and loginPost is two different actions. As for logging in, you need to do something like this:

// Setting data for request
$this->getRequest()->setMethod('POST')
        ->setPost('login', array(
            'username' => '[email protected]',
            'password' => 'customer_password'
        ));

$this->dispatch('customer/account/loginpost'); // This will login customer via controller

But this kind of test body is only required if you need to test login process, but if just want to simulate that customer is logged in, you can create a stub that particular customer is logged in. I used it in few projects. Just add this method to your test case and then use when you need it. It will login customer within single test run and will tear down all the session changes afterwards.

/**
 * Creates information in the session,
 * that customer is logged in
 *
 * @param string $customerEmail
 * @param string $customerPassword
 * @return Mage_Customer_Model_Session|PHPUnit_Framework_MockObject_MockObject
 */
protected function createCustomerSession($customerId, $storeId = null)
{
    // Create customer session mock, for making our session singleton isolated
    $customerSessionMock = $this->getModelMock('customer/session', array('renewSession'));
    $this->replaceByMock('singleton', 'customer/session', $customerSessionMock);

    if ($storeId === null) {
        $storeId = $this->app()->getAnyStoreView()->getCode();
    }

    $this->setCurrentStore($storeId);
    $customerSessionMock->loginById($customerId);

    return $customerSessionMock;
}

Also renewSession method is mocked in above code, because it is using direct setcookie function, instead of core/cookie model, so in command line it produces an error.

Sincerely, Ivan

like image 143
Ivan Chepurnyi Avatar answered May 12 '23 05:05

Ivan Chepurnyi