Skip to content

Commit 2de3dd3

Browse files
committed
minor #7507 Merged and improved the articles about testing + authentication (javiereguiluz, HeahDude)
This PR was merged into the 2.7 branch. Discussion ---------- Merged and improved the articles about testing + authentication This fixes #6741. Commits ------- fc8e8c6 Fixed status code test be5fe37 Improved a test 211da90 Merged and improved the articles about testing + authentication
2 parents 801b5d6 + fc8e8c6 commit 2de3dd3

File tree

3 files changed

+84
-78
lines changed

3 files changed

+84
-78
lines changed

_build/redirection_map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,4 @@
325325
/deployment/tools /deployment
326326
/install/bundles /setup/bundles
327327
/form /forms
328+
/testing/simulating_authentication /testing/http_authentication

testing/http_authentication.rst

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,24 @@
44
How to Simulate HTTP Authentication in a Functional Test
55
========================================================
66

7-
If your application needs HTTP authentication, pass the username and password
8-
as server variables to ``createClient()``::
7+
Authenticating requests in functional tests can slow down the entire test suite.
8+
This could become an issue especially when the tests reproduce the same steps
9+
that users follow to authenticate, such as submitting a login form or using
10+
OAuth authentication services.
911

10-
$client = static::createClient(array(), array(
11-
'PHP_AUTH_USER' => 'username',
12-
'PHP_AUTH_PW' => 'pa$$word',
13-
));
12+
This article explains the two most popular techniques to avoid these issues and
13+
create fast tests when using authentication.
1414

15-
You can also override it on a per request basis::
15+
Using a Faster Authentication Mechanism Only for Tests
16+
------------------------------------------------------
1617

17-
$client->request('DELETE', '/post/12', array(), array(), array(
18-
'PHP_AUTH_USER' => 'username',
19-
'PHP_AUTH_PW' => 'pa$$word',
20-
));
18+
When your application is using a ``form_login`` authentication, you can make
19+
your tests faster by allowing them to use HTTP authentication. This way your
20+
tests authenticate with the simple and fast HTTP Basic method whilst your real
21+
users still log in via the normal login form.
2122

22-
When your application is using a ``form_login``, you can simplify your tests
23-
by allowing your test configuration to make use of HTTP authentication. This
24-
way you can use the above to authenticate in tests, but still have your users
25-
log in via the normal ``form_login``. The trick is to include the ``http_basic``
26-
key in your firewall, along with the ``form_login`` key:
23+
The trick is to use the ``http_basic`` authentication in your application
24+
firewall, but only in the configuration file used by tests:
2725

2826
.. configuration-block::
2927

@@ -54,3 +52,72 @@ key in your firewall, along with the ``form_login`` key:
5452
),
5553
),
5654
));
55+
56+
Tests can now authenticate via HTTP passing the username and password as server
57+
variables using the second argument of ``createClient()``::
58+
59+
$client = static::createClient(array(), array(
60+
'PHP_AUTH_USER' => 'username',
61+
'PHP_AUTH_PW' => 'pa$$word',
62+
));
63+
64+
The username and password can also be passed on a per request basis::
65+
66+
$client->request('DELETE', '/post/12', array(), array(), array(
67+
'PHP_AUTH_USER' => 'username',
68+
'PHP_AUTH_PW' => 'pa$$word',
69+
));
70+
71+
Creating the Authentication Token
72+
---------------------------------
73+
74+
If your application uses a more advanced authentication mechanism, you can't
75+
use the previous trick, but it's still possible to make tests faster. The trick
76+
now is to bypass the authentication process, create the *authentication token*
77+
yourself and store it in the session.
78+
79+
This technique requires some knowledge of the security component internals,
80+
but the following example shows a complete example that you can adapt to your
81+
needs::
82+
83+
// src/AppBundle/Tests/Controller/DefaultControllerTest.php
84+
namespace Appbundle\Tests\Controller;
85+
86+
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
87+
use Symfony\Component\BrowserKit\Cookie;
88+
use Symfony\Component\HttpFoundation\Response;
89+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
90+
91+
class DefaultControllerTest extends WebTestCase
92+
{
93+
private $client = null;
94+
95+
public function setUp()
96+
{
97+
$this->client = static::createClient();
98+
}
99+
100+
public function testSecuredHello()
101+
{
102+
$this->logIn();
103+
$crawler = $this->client->request('GET', '/admin');
104+
105+
$this->assertSame(Response::HTTP_OK, $this->client->getResponse()->getStatusCode());
106+
$this->assertSame('Admin Dashboard', $crawler->filter('h1')->text());
107+
}
108+
109+
private function logIn()
110+
{
111+
$session = $this->client->getContainer()->get('session');
112+
113+
// the firewall context defaults to the firewall name
114+
$firewallContext = 'secured_area';
115+
116+
$token = new UsernamePasswordToken('admin', null, $firewallContext, array('ROLE_ADMIN'));
117+
$session->set('_security_'.$firewallContext, serialize($token));
118+
$session->save();
119+
120+
$cookie = new Cookie($session->getName(), $session->getId());
121+
$this->client->getCookieJar()->set($cookie);
122+
}
123+
}

testing/simulating_authentication.rst

Lines changed: 0 additions & 62 deletions
This file was deleted.

0 commit comments

Comments
 (0)