Symfony:测试自定义用户登录


Symfony: testing custom user login

就在最近,我开始测试一个symfony应用程序。。。首先,我想我会尝试测试一个登录表单,该表单应该允许访问私人区域。

这个私有区域的用户被正确地持久化到数据库中,并且已经在开发环境中进行了尝试。config_test.yml文件如下所示:

imports:
    - { resource: config_dev.yml }
framework:
    test: ~
    session:
        storage_id: session.storage.mock_file
    profiler:
        collect: false
web_profiler:
    toolbar: false
    intercept_redirects: false
swiftmailer:
    disable_delivery: true 

因此,它应该使用config_dev.yml.中公开的数据库配置

我的用户提供商没有什么特别之处:

providers:
    users:
        entity: 
            class: MyBundle:User
            property: login

根据评论部分的要求,以下是安全信息。请注意,所有名称空间、类名和相关数据都已更改,因为我无法发布真实的内容。如果你发现任何错误,那一定是我更改了相关代码。

security:
    encoders:
        MyBundle'Entity'User:
           algorithm: bcrypt
           cost: 12
    role_hierarchy:
        ROLE_CUSER:       ROLE_USER
        ROLE_CUSER_A: ROLE_CUSER
        ROLE_CUSER_B: ROLE_CUSER
        ROLE_CUSER_C: ROLE_CUSER
        ROLE_CUSER_D: ROLE_CUSER
        ROLE_CUSER_E: ROLE_CUSER
    providers:
        users:
            entity: 
                class: MyBundle:User
                property: login
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        user_tools_login_firewall:
             pattern:   ^/user_tools/login$
             anonymous: ~
        user_tools:
             pattern: ^/user_tools
             http_basic: ~
             provider: users
             form_login:
                 login_path: /user_tools/login
                 check_path: /user_tools/login_check
             logout:
                 path: /user_tools/logout
                 target: /user_tools/home
                 invalidate_session: false
    access_control:
        - {path: /user_tools/login, roles: IS_AUTHENTICATED_ANONYMOUSLY}
        - {path: ^/user_tools/users/, roles: ROLE_CUSER_A}
        - {path: ^/user_tools/news/, roles: ROLE_CUSER_B}

让我们来看看测试单元。。。

class SecurityControllerTest extends WebTestCase
{
    const LOGIN_ERROR='this_is_a_non_existing_user';
    const PASS_ERROR='with_a_non_existing_pass';
    const LOGIN='this_is_a_valid_user';
    const PASS='with_a_valid_pass';
    const PASS_CRYPT='##and_this_is_the_encripted_pass_as_pasted_from_the_database##';
    const ID_SUBMIT='btn_submit';
    private $client;
    private $crawler;
    public function testIndex()
    {
        $this->client=static::createClient();
        $this->crawler=$this->client->request('GET', '/route_to_login');
        //Let's check that there are users in the database...
            $em=$this->client->getContainer()->get('doctrine')->getManager();
        $users=$em->getRepository("MyBundle:User")->findAll();
        $this->assertGreaterThan(0, count($users));
        //Now let's check that there's a valid user...
        $valid_user=$em->getRepository("MyBundle:User")->findBy(
            array('login' => self::LOGIN,
                'pass' => self::PASS_CRYPT));
        $this->assertGreaterThan(0, count($valid_user));
        //Let's check that there is no invalid user ;).
        $invalid_user=$em->getRepository("MyBundle:User")->findBy(
            array('login' => self::LOGIN_ERROR,
                'pass' => self::PASS_ERROR));
        $this->assertEquals(0, count($invalid_user));
        //The view should be the one I expect...
        $this->assertEquals('MyBundle'Controller'User'SecurityController::loginAction', $this->client->getRequest()->attributes->get('_controller'));
        //Let's try an invalid access...
        $this->form_login(self::LOGIN_ERROR, self::PASS_ERROR);
        $this->assertEquals('MyBundle'Controller'User'SecurityController::loginAction', $this->client->getRequest()->attributes->get('_controller'));
        //And now, let's try the good one!.
        self::form_login(self::LOGIN, self::PASS);
        $this->assertEquals('MyBundle'Controller'User'HomeController::homeAction', $this->client->getRequest()->attributes->get('_controller'));
    }
    private function form_login($login, $pass)
    {
        $form=$this->crawler->selectButton(self::ID_SUBMIT)->form();
        $form['_username']=$login;
        $form['_password']=$pass;
        $this->client->submit($form);
        $this->crawler=$this->client->followRedirect();
    }
}

问题是,除了最后一个测试(即良好登录)外,所有测试都通过了。它不会转到预期的控制器,而是返回到登录名。

以下是phpunit错误:

There was 1 failure:
1) MyBundle'Tests'Controller'User'SecurityControllerTest::testIndex
Failed asserting that null matches expected 'MyBundle'Controller'User'HomeController::homeAction'.

这里有我遗漏的东西吗?。在开发环境中,一切都按预期进行。用户确实存在(并且是断言的,正如您所看到的)。我准备根据要求提供更多信息。

谢谢!。

您忘记在form_login配置中定义default_target_path,请尝试添加以下路径:

         form_login:
             login_path: /user_tools/login
             check_path: /user_tools/login_check
             default_target_path: your_target_path