dpx86402 2015-02-11 10:22
浏览 56
已采纳

Symfony:测试自定义用户登录

Just recently I got into testing pieces of a symfony application... For starters, I thought I would try and test a login form that should grant access to a private area.

The users for this private area are correctly persisted to the database and have been tried on the development enviroment. The config_test.yml file goes like this:

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 

So it should use the database configuration exposed in config_dev.yml.

There's nothing special about my user provider:

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

As requested in the comments section, here's the security info. Please note that all namespaces, class names and relevant data have been changed, as I can't publish the real thing. If you spot any mistake it must have been me changing the relevant code.

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}

Let's take a look at the testing unit...

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

The thing is, all tests are passed except the last one (that is, the good login). It does not go to the expected controller, but back to the login.

Here's the phpunit error:

There was 1 failure:

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

Is there something I am missing here?. Everything is working as expected into the dev enviroment. Users do exists (and are asserted, as you can see). I am prepared to give more info as requested.

Thanks!.

  • 写回答

1条回答 默认 最新

  • duanrebo3559 2015-02-11 10:54
    关注

    You forgot to define the default_target_path in your form_login configuration, try to add your path like this:

             form_login:
                 login_path: /user_tools/login
                 check_path: /user_tools/login_check
                 default_target_path: your_target_path
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)
  • ¥15 用前端向数据库插入数据,通过debug发现数据能走到后端,但是放行之后就会提示错误