Symfony: тестирование пользовательского логина

0

Совсем недавно я попал в тестовые фрагменты приложения 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 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 check that there 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 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 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 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'.

Здесь что-то не хватает? Все работает должным образом в окружающей среде Dev. Пользователи существуют (и утверждаются, как вы можете видеть). Я готов предоставить дополнительную информацию по запросу.

Благодарю!.

  • 0
    Ну, атрибут _controller запроса в вашем последнем тесте равен нулю. Можете ли вы показать нам свой security.yml?
  • 0
    Да, конечно, только что отредактировал вопрос. Благодарю.
Показать ещё 3 комментария
Теги:
unit-testing
phpunit

1 ответ

2
Лучший ответ

Вы забыли form_login путь default_target_path в своей конфигурации form_login, попробуйте добавить свой путь следующим образом:

         form_login:
             login_path: /user_tools/login
             check_path: /user_tools/login_check
             default_target_path: your_target_path
  • 0
    Как сказано выше: большое спасибо. Я полностью упустил это из виду. Плюс, это исправило раздражающую ситуацию, но также и в среде разработчиков.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню