Search code examples
cakephpcakephp-3.0cakephp-3.x

Cakephp integration test how I will post request after login?


I am trying to make a post request in cakephp IntegrationTest, Where post request, I have to send after login into admin prefix directory.

My database table name is admin_users

I have created an AdminUsersFixture, and Fixture has 3 records

Where 1st record is :

$this->records = [
  [
      'id' => 1,
      'name' => 'jone_due',
      'email' => '[email protected]',
      'password' => 'password',
      'status' => 1,
      'modified' => date('Y-m-d H:i:s'),
      'created' => date('Y-m-d H:i:s'),
  ],
]

I have written AdminUsersTestController.php

<?php 

class AdminUsersTest extends TestCase{
    use IntegrationTestTrait;

    public $fixtures = [
        'app.AdminUsers'
    ];

    public function testAddAuthenticated(): void
    {
          $query = $this->AdminUsers->find()->all();
          $this->assertEquals(3, $query->count());
    }
}

After run test script I have got response ok

OK (1 test, 1 assertion)

Then tried to login by post request and below changes I have written in action testAddAuthenticated()

public function testAddAuthenticated(): void
{
        $query = $this->AdminUsers->find()->all();
        $this->assertEquals(3, $query->count());

        $user = [
            'email' => '[email protected]',
            'password' => 'password'
        ];
        $this->post('/admin?type=admin',$user);
        debug($this->_response);
       
        $this->get('/admin/adminUsers/add');
        $this->assertResponseOk();

}

In debug I always getting email and password is wrong message. Below this my login from html

<form method="post" accept-charset="utf-8" action="/admin?type=admin">
    <input type="hidden" name="_method" value="POST">   
    <input type="email" name="email">
    <input type="password" name="password">

    <button name="redirect" type="submit">ログイン</button>
</form>

This is the output that I am getting in PHP unit result

There was 1 failure:

1) App\Test\TestCase\Controller\Admin\AdminUsersTest::testAddAuthenticated
Failed asserting that 302 is between 200 and 204.

In fixers has there any hash password issue ? Am I in right way ? How can I access link after login post request ?


Solution

  • Your fixture must contain the hashed password, as the data will be inserted into the database as-is, it will not go the way trough the ORM where your entity and its password hashing mechanism would be triggered.

    Also note that you cannot just make two consecutive requests like that, as there is no actual state handling in integration tests. The second request would have an empty session, meaning you would not be authenticated.

    Usually it's enough to simply check that your login request returns the expected response, that is for example a valid session cookie (assertCookie()), the expected session data (assertSession()), and a location header (assertRedirect()).

    It doesn't make too much sense to test the login flow further in the very same method, as it will rely on you populating the session data for the next request manually anyways, meaning if the response session data is valid, then a request with that session data should work fine.

    You would have tests for your other non-login endpoints accordingly anyways, where you'd manually populate the session with the expected data required for a valid authenticated state.

    See also