1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the Liip/FunctionalTestBundle |
5
|
|
|
* |
6
|
|
|
* (c) Lukas Kahwe Smith <[email protected]> |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the MIT license that is bundled |
9
|
|
|
* with this source code in the file LICENSE. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Liip\FunctionalTestBundle\Test; |
13
|
|
|
|
14
|
|
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; |
15
|
|
|
use Symfony\Bundle\FrameworkBundle\Console\Application; |
16
|
|
|
use Symfony\Bundle\FrameworkBundle\Client; |
17
|
|
|
use Symfony\Component\Console\Input\ArrayInput; |
18
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
19
|
|
|
use Symfony\Component\Console\Output\StreamOutput; |
20
|
|
|
use Symfony\Component\DomCrawler\Crawler; |
21
|
|
|
use Symfony\Component\BrowserKit\Cookie; |
22
|
|
|
use Symfony\Component\HttpKernel\Kernel; |
23
|
|
|
use Symfony\Component\HttpFoundation\Response; |
24
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; |
25
|
|
|
use Symfony\Component\Security\Core\User\UserInterface; |
26
|
|
|
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; |
27
|
|
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
28
|
|
|
use Symfony\Component\HttpFoundation\Session\Session; |
29
|
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
30
|
|
|
use Symfony\Bundle\DoctrineFixturesBundle\Common\DataFixtures\Loader; |
31
|
|
|
use Doctrine\Common\Persistence\ObjectManager; |
32
|
|
|
use Doctrine\Common\DataFixtures\Executor\AbstractExecutor; |
33
|
|
|
use Doctrine\Common\DataFixtures\ProxyReferenceRepository; |
34
|
|
|
use Liip\FunctionalTestBundle\Utils\FixturesLoader; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @author Lea Haensenberger |
38
|
|
|
* @author Lukas Kahwe Smith <[email protected]> |
39
|
|
|
* @author Benjamin Eberlei <[email protected]> |
40
|
|
|
*/ |
41
|
|
|
abstract class WebTestCase extends BaseWebTestCase |
|
|
|
|
42
|
|
|
{ |
43
|
|
|
protected $environment = 'test'; |
44
|
|
|
protected $containers; |
45
|
|
|
protected $kernelDir; |
46
|
|
|
// 5 * 1024 * 1024 KB |
47
|
|
|
protected $maxMemory = 5242880; |
48
|
|
|
|
49
|
|
|
// RUN COMMAND |
50
|
|
|
protected $verbosityLevel; |
51
|
|
|
protected $decorated; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var array |
55
|
|
|
*/ |
56
|
|
|
private $firewallLogins = array(); |
57
|
|
|
|
58
|
1 |
|
protected static function getKernelClass() |
59
|
|
|
{ |
60
|
1 |
|
$dir = isset($_SERVER['KERNEL_DIR']) ? $_SERVER['KERNEL_DIR'] : self::getPhpUnitXmlDir(); |
61
|
|
|
|
62
|
1 |
|
list($appname) = explode('\\', get_called_class()); |
63
|
|
|
|
64
|
1 |
|
$class = $appname.'Kernel'; |
65
|
1 |
|
$file = $dir.'/'.strtolower($appname).'/'.$class.'.php'; |
66
|
1 |
|
if (!file_exists($file)) { |
67
|
1 |
|
return parent::getKernelClass(); |
68
|
|
|
} |
69
|
|
|
require_once $file; |
70
|
|
|
|
71
|
|
|
return $class; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Creates a mock object of a service identified by its id. |
76
|
|
|
* |
77
|
|
|
* @param string $id |
78
|
|
|
* |
79
|
|
|
* @return \PHPUnit_Framework_MockObject_MockBuilder |
80
|
|
|
*/ |
81
|
|
|
protected function getServiceMockBuilder($id) |
82
|
|
|
{ |
83
|
|
|
$service = $this->getContainer()->get($id); |
84
|
|
|
$class = get_class($service); |
85
|
|
|
|
86
|
|
|
return $this->getMockBuilder($class)->disableOriginalConstructor(); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Builds up the environment to run the given command. |
91
|
|
|
* |
92
|
|
|
* @param string $name |
93
|
|
|
* @param array $params |
94
|
|
|
* @param bool $reuseKernel |
95
|
|
|
* |
96
|
|
|
* @return string |
97
|
|
|
*/ |
98
|
12 |
|
protected function runCommand($name, array $params = array(), $reuseKernel = false) |
99
|
|
|
{ |
100
|
12 |
|
array_unshift($params, $name); |
101
|
|
|
|
102
|
12 |
|
if (!$reuseKernel) { |
103
|
12 |
|
if (null !== static::$kernel) { |
104
|
9 |
|
static::$kernel->shutdown(); |
105
|
9 |
|
} |
106
|
|
|
|
107
|
12 |
|
$kernel = static::$kernel = $this->createKernel(array('environment' => $this->environment)); |
108
|
12 |
|
$kernel->boot(); |
109
|
12 |
|
} else { |
110
|
2 |
|
$kernel = $this->getContainer()->get('kernel'); |
111
|
|
|
} |
112
|
|
|
|
113
|
12 |
|
$application = new Application($kernel); |
114
|
12 |
|
$application->setAutoExit(false); |
115
|
|
|
|
116
|
|
|
// @codeCoverageIgnoreStart |
117
|
|
|
if ('20301' === Kernel::VERSION_ID) { |
118
|
|
|
$params = $this->configureVerbosityForSymfony20301($params); |
119
|
|
|
} |
120
|
|
|
// @codeCoverageIgnoreEnd |
121
|
|
|
|
122
|
12 |
|
$input = new ArrayInput($params); |
123
|
12 |
|
$input->setInteractive(false); |
124
|
|
|
|
125
|
12 |
|
$fp = fopen('php://temp/maxmemory:'.$this->maxMemory, 'r+'); |
126
|
12 |
|
$output = new StreamOutput($fp, $this->getVerbosityLevel(), $this->getDecorated()); |
127
|
|
|
|
128
|
11 |
|
$application->run($input, $output); |
129
|
|
|
|
130
|
11 |
|
rewind($fp); |
131
|
|
|
|
132
|
11 |
|
return stream_get_contents($fp); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Retrieves the output verbosity level. |
137
|
|
|
* |
138
|
|
|
* @see Symfony\Component\Console\Output\OutputInterface for available levels |
139
|
|
|
* |
140
|
|
|
* @return int |
141
|
|
|
* |
142
|
|
|
* @throws \OutOfBoundsException If the set value isn't accepted |
143
|
|
|
*/ |
144
|
12 |
|
protected function getVerbosityLevel() |
145
|
|
|
{ |
146
|
|
|
// If `null`, is not yet set |
147
|
12 |
|
if (null === $this->verbosityLevel) { |
148
|
|
|
// Set the global verbosity level that is set as NORMAL by the TreeBuilder in Configuration |
149
|
6 |
|
$level = strtoupper($this->getContainer()->getParameter('liip_functional_test.command_verbosity')); |
150
|
6 |
|
$verbosity = '\Symfony\Component\Console\Output\StreamOutput::VERBOSITY_'.$level; |
151
|
|
|
|
152
|
6 |
|
$this->verbosityLevel = constant($verbosity); |
153
|
6 |
|
} |
154
|
|
|
|
155
|
|
|
// If string, it is set by the developer, so check that the value is an accepted one |
156
|
12 |
|
if (is_string($this->verbosityLevel)) { |
157
|
6 |
|
$level = strtoupper($this->verbosityLevel); |
158
|
6 |
|
$verbosity = '\Symfony\Component\Console\Output\StreamOutput::VERBOSITY_'.$level; |
159
|
|
|
|
160
|
6 |
|
if (!defined($verbosity)) { |
161
|
1 |
|
throw new \OutOfBoundsException( |
162
|
1 |
|
sprintf('The set value "%s" for verbosityLevel is not valid. Accepted are: "quiet", "normal", "verbose", "very_verbose" and "debug".', $level) |
163
|
1 |
|
); |
164
|
|
|
} |
165
|
|
|
|
166
|
5 |
|
$this->verbosityLevel = constant($verbosity); |
167
|
5 |
|
} |
168
|
|
|
|
169
|
11 |
|
return $this->verbosityLevel; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* In Symfony 2.3.1 the verbosity level has to be set through {Symfony\Component\Console\Input\ArrayInput} and not |
174
|
|
|
* in {Symfony\Component\Console\Output\OutputInterface}. |
175
|
|
|
* |
176
|
|
|
* This method builds $params to be passed to {Symfony\Component\Console\Input\ArrayInput}. |
177
|
|
|
* |
178
|
|
|
* @codeCoverageIgnore |
179
|
|
|
* |
180
|
|
|
* @param array $params |
181
|
|
|
* |
182
|
|
|
* @return array |
183
|
|
|
*/ |
184
|
|
|
private function configureVerbosityForSymfony20301(array $params) |
185
|
|
|
{ |
186
|
|
|
switch ($this->getVerbosityLevel()) { |
187
|
|
|
case OutputInterface::VERBOSITY_QUIET: |
188
|
|
|
$params['-q'] = '-q'; |
189
|
|
|
break; |
190
|
|
|
|
191
|
|
|
case OutputInterface::VERBOSITY_VERBOSE: |
192
|
|
|
$params['-v'] = ''; |
193
|
|
|
break; |
194
|
|
|
|
195
|
|
|
case OutputInterface::VERBOSITY_VERY_VERBOSE: |
196
|
|
|
$params['-vv'] = ''; |
197
|
|
|
break; |
198
|
|
|
|
199
|
|
|
case OutputInterface::VERBOSITY_DEBUG: |
200
|
|
|
$params['-vvv'] = ''; |
201
|
|
|
break; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
return $params; |
205
|
|
|
} |
206
|
|
|
|
207
|
6 |
|
public function setVerbosityLevel($level) |
208
|
|
|
{ |
209
|
6 |
|
$this->verbosityLevel = $level; |
210
|
6 |
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Retrieves the flag indicating if the output should be decorated or not. |
214
|
|
|
* |
215
|
|
|
* @return bool |
216
|
|
|
*/ |
217
|
11 |
|
protected function getDecorated() |
218
|
|
|
{ |
219
|
11 |
|
if (null === $this->decorated) { |
220
|
|
|
// Set the global decoration flag that is set to `true` by the TreeBuilder in Configuration |
221
|
5 |
|
$this->decorated = $this->getContainer()->getParameter('liip_functional_test.command_decoration'); |
222
|
5 |
|
} |
223
|
|
|
|
224
|
|
|
// Check the local decorated flag |
225
|
11 |
|
if (false === is_bool($this->decorated)) { |
226
|
|
|
throw new \OutOfBoundsException( |
227
|
|
|
sprintf('`WebTestCase::decorated` has to be `bool`. "%s" given.', gettype($this->decorated)) |
228
|
|
|
); |
229
|
|
|
} |
230
|
|
|
|
231
|
11 |
|
return $this->decorated; |
232
|
|
|
} |
233
|
|
|
|
234
|
6 |
|
public function isDecorated($decorated) |
235
|
|
|
{ |
236
|
6 |
|
$this->decorated = $decorated; |
237
|
6 |
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Get an instance of the dependency injection container. |
241
|
|
|
* (this creates a kernel *without* parameters). |
242
|
|
|
* |
243
|
|
|
* @return ContainerInterface |
244
|
|
|
*/ |
245
|
37 |
|
protected function getContainer() |
246
|
|
|
{ |
247
|
37 |
|
if (!empty($this->kernelDir)) { |
248
|
|
|
$tmpKernelDir = isset($_SERVER['KERNEL_DIR']) ? $_SERVER['KERNEL_DIR'] : null; |
249
|
|
|
$_SERVER['KERNEL_DIR'] = getcwd().$this->kernelDir; |
250
|
|
|
} |
251
|
|
|
|
252
|
37 |
|
$cacheKey = $this->kernelDir.'|'.$this->environment; |
253
|
37 |
|
if (empty($this->containers[$cacheKey])) { |
254
|
|
|
$options = array( |
255
|
37 |
|
'environment' => $this->environment, |
256
|
37 |
|
); |
257
|
37 |
|
$kernel = $this->createKernel($options); |
258
|
37 |
|
$kernel->boot(); |
259
|
|
|
|
260
|
37 |
|
$this->containers[$cacheKey] = $kernel->getContainer(); |
261
|
37 |
|
} |
262
|
|
|
|
263
|
37 |
|
if (isset($tmpKernelDir)) { |
264
|
1 |
|
$_SERVER['KERNEL_DIR'] = $tmpKernelDir; |
265
|
|
|
} |
266
|
|
|
|
267
|
37 |
|
return $this->containers[$cacheKey]; |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* Set the database to the provided fixtures. |
272
|
|
|
* |
273
|
|
|
* Drops the current database and then loads fixtures using the specified |
274
|
|
|
* classes. The parameter is a list of fully qualified class names of |
275
|
|
|
* classes that implement Doctrine\Common\DataFixtures\FixtureInterface |
276
|
|
|
* so that they can be loaded by the DataFixtures Loader::addFixture |
277
|
|
|
* |
278
|
|
|
* When using SQLite this method will automatically make a copy of the |
279
|
|
|
* loaded schema and fixtures which will be restored automatically in |
280
|
|
|
* case the same fixture classes are to be loaded again. Caveat: changes |
281
|
|
|
* to references and/or identities may go undetected. |
282
|
|
|
* |
283
|
|
|
* Depends on the doctrine data-fixtures library being available in the |
284
|
|
|
* class path. |
285
|
|
|
* |
286
|
|
|
* @param array $classNames List of fully qualified class names of fixtures to load |
287
|
|
|
* @param string $omName The name of object manager to use |
288
|
|
|
* @param string $registryName The service id of manager registry to use |
289
|
|
|
* @param int $purgeMode Sets the ORM purge mode |
290
|
|
|
* |
291
|
|
|
* @return null|AbstractExecutor |
292
|
|
|
*/ |
293
|
24 |
|
protected function loadFixtures(array $classNames, $omName = null, $registryName = 'doctrine', $purgeMode = null) |
294
|
|
|
{ |
295
|
24 |
|
$loader = new FixturesLoader($this->getContainer()); |
296
|
|
|
|
297
|
24 |
|
return $loader->loadFixtures($classNames, $omName, $registryName, $purgeMode); |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* @param array $paths Either symfony resource locators (@ BundleName/etc) or actual file paths |
302
|
|
|
* @param bool $append |
303
|
|
|
* @param null $omName |
304
|
|
|
* @param string $registryName |
305
|
|
|
* |
306
|
|
|
* @return array |
307
|
|
|
* |
308
|
|
|
* @throws \BadMethodCallException |
309
|
|
|
*/ |
310
|
3 |
|
public function loadFixtureFiles(array $paths = array(), $append = false, $omName = null, $registryName = 'doctrine') |
311
|
|
|
{ |
312
|
3 |
|
$loader = new FixturesLoader($this->getContainer()); |
313
|
|
|
|
314
|
3 |
|
<<<<<<< HEAD |
|
|
|
|
315
|
|
|
return $loader->loadFixtureFiles($paths, $append, $omName, $registryName); |
316
|
|
|
======= |
317
|
|
|
/** @var ContainerInterface $container */ |
318
|
|
|
$container = $this->getContainer(); |
319
|
|
|
|
320
|
|
|
/** @var ManagerRegistry $registry */ |
321
|
|
|
$registry = $container->get($registryName); |
322
|
|
|
|
323
|
|
|
/** @var EntityManager $om */ |
324
|
|
|
$om = $registry->getManager($omName); |
325
|
|
|
|
326
|
|
|
if ($append === false) { |
327
|
|
|
$this->cleanDatabase($registry, $om); |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
$files = $this->locateResources($paths); |
331
|
|
|
|
332
|
|
|
// Check if the Hautelook AliceBundle is registered and if yes, use it instead of Nelmio Alice |
333
|
|
|
$hautelookLoaderServiceName = 'hautelook_alice.fixtures.loader'; |
334
|
|
|
if ($container->has($hautelookLoaderServiceName)) { |
335
|
|
|
$loaderService = $container->get($hautelookLoaderServiceName); |
336
|
|
|
$persisterClass = class_exists('Nelmio\Alice\ORM\Doctrine') ? |
337
|
|
|
'Nelmio\Alice\ORM\Doctrine' : |
338
|
|
|
'Nelmio\Alice\Persister\Doctrine'; |
339
|
|
|
|
340
|
|
|
return $loaderService->load(new $persisterClass($om), $files); |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
return Fixtures::load($files, $om); |
344
|
|
|
>>>>>>> 2c95f380e7b3cc356e76373c0e4cdbbc4d1a323f |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* Callback function to be executed after Schema creation. |
349
|
|
|
* Use this to execute acl:init or other things necessary. |
350
|
|
|
*/ |
351
|
|
|
protected function postFixtureSetup() |
352
|
|
|
{ |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Callback function to be executed after Schema restore. |
357
|
|
|
* |
358
|
|
|
* @return WebTestCase |
359
|
|
|
*/ |
360
|
|
|
protected function postFixtureRestore() |
361
|
|
|
{ |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
/** |
365
|
|
|
* Callback function to be executed before Schema restore. |
366
|
|
|
* |
367
|
|
|
* @param ObjectManager $manager The object manager |
368
|
|
|
* @param ProxyReferenceRepository $referenceRepository The reference repository |
369
|
|
|
* |
370
|
|
|
* @return WebTestCase |
371
|
|
|
*/ |
372
|
|
|
protected function preFixtureRestore(ObjectManager $manager, ProxyReferenceRepository $referenceRepository) |
373
|
|
|
{ |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* Callback function to be executed after save of references. |
378
|
|
|
* |
379
|
|
|
* @param ObjectManager $manager The object manager |
380
|
|
|
* @param AbstractExecutor $executor Executor of the data fixtures |
381
|
|
|
* @param string $backupFilePath Path of file used to backup the references of the data fixtures |
382
|
|
|
* |
383
|
|
|
* @return WebTestCase |
384
|
|
|
*/ |
385
|
|
|
protected function postReferenceSave(ObjectManager $manager, AbstractExecutor $executor, $backupFilePath) |
386
|
|
|
{ |
387
|
46 |
|
} |
388
|
|
|
|
389
|
46 |
|
/** |
390
|
2 |
|
* Callback function to be executed before save of references. |
391
|
|
|
* |
392
|
1 |
|
* @param ObjectManager $manager The object manager |
393
|
1 |
|
* @param AbstractExecutor $executor Executor of the data fixtures |
394
|
1 |
|
* @param string $backupFilePath Path of file used to backup the references of the data fixtures |
395
|
1 |
|
* |
396
|
1 |
|
* @return WebTestCase |
397
|
1 |
|
*/ |
398
|
|
|
protected function preReferenceSave(ObjectManager $manager, AbstractExecutor $executor, $backupFilePath) |
399
|
2 |
|
{ |
400
|
2 |
|
} |
401
|
2 |
|
|
402
|
2 |
|
/** |
403
|
2 |
|
* Creates an instance of a lightweight Http client. |
404
|
|
|
* |
405
|
46 |
|
* If $authentication is set to 'true' it will use the content of |
406
|
|
|
* 'liip_functional_test.authentication' to log in. |
407
|
46 |
|
* |
408
|
|
|
* $params can be used to pass headers to the client, note that they have |
409
|
2 |
|
* to follow the naming format used in $_SERVER. |
410
|
|
|
* Example: 'HTTP_X_REQUESTED_WITH' instead of 'X-Requested-With' |
411
|
2 |
|
* |
412
|
|
|
* @param bool|array $authentication |
413
|
|
|
* @param array $params |
414
|
|
|
* |
415
|
2 |
|
* @return Client |
416
|
|
|
*/ |
417
|
2 |
|
protected function makeClient($authentication = false, array $params = array()) |
418
|
2 |
|
{ |
419
|
2 |
|
if ($authentication) { |
420
|
|
|
if ($authentication === true) { |
421
|
2 |
|
$authentication = array( |
422
|
|
|
'username' => $this->getContainer() |
423
|
|
|
->getParameter('liip_functional_test.authentication.username'), |
424
|
2 |
|
'password' => $this->getContainer() |
425
|
2 |
|
->getParameter('liip_functional_test.authentication.password'), |
426
|
|
|
); |
427
|
|
|
} |
428
|
|
|
|
429
|
2 |
|
$params = array_merge($params, array( |
430
|
2 |
|
'PHP_AUTH_USER' => $authentication['username'], |
431
|
2 |
|
'PHP_AUTH_PW' => $authentication['password'], |
432
|
|
|
)); |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
$client = static::createClient(array('environment' => $this->environment), $params); |
436
|
|
|
|
437
|
|
|
if ($this->firewallLogins) { |
438
|
2 |
|
// has to be set otherwise "hasPreviousSession" in Request returns false. |
439
|
2 |
|
$options = $client->getContainer()->getParameter('session.storage.options'); |
440
|
2 |
|
|
441
|
|
|
if (!$options || !isset($options['name'])) { |
442
|
2 |
|
throw new \InvalidArgumentException('Missing session.storage.options#name'); |
443
|
2 |
|
} |
444
|
|
|
|
445
|
46 |
|
$session = $client->getContainer()->get('session'); |
446
|
|
|
// Since the namespace of the session changed in symfony 2.1, instanceof can be used to check the version. |
447
|
|
|
if ($session instanceof Session) { |
448
|
|
|
$session->setId(uniqid()); |
449
|
|
|
} |
450
|
|
|
|
451
|
|
|
$client->getCookieJar()->set(new Cookie($options['name'], $session->getId())); |
452
|
|
|
|
453
|
|
|
/** @var $user UserInterface */ |
454
|
|
|
foreach ($this->firewallLogins as $firewallName => $user) { |
455
|
|
|
$token = $this->createUserToken($user, $firewallName); |
456
|
|
|
|
457
|
|
|
// BC: security.token_storage is available on Symfony 2.6+ |
458
|
|
|
// see http://symfony.com/blog/new-in-symfony-2-6-security-component-improvements |
459
|
|
|
if ($client->getContainer()->has('security.token_storage')) { |
460
|
|
|
$tokenStorage = $client->getContainer()->get('security.token_storage'); |
461
|
2 |
|
} else { |
462
|
|
|
// This block will never be reached with Symfony 2.6+ |
463
|
2 |
|
// @codeCoverageIgnoreStart |
464
|
2 |
|
$tokenStorage = $client->getContainer()->get('security.context'); |
465
|
2 |
|
// @codeCoverageIgnoreEnd |
466
|
2 |
|
} |
467
|
2 |
|
|
468
|
2 |
|
$tokenStorage->setToken($token); |
469
|
|
|
$session->set('_security_'.$firewallName, serialize($token)); |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
$session->save(); |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
return $client; |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* Create User Token. |
480
|
1 |
|
* |
481
|
|
|
* Factory method for creating a User Token object for the firewall based on |
482
|
1 |
|
* the user object provided. By default it will be a Username/Password |
483
|
|
|
* Token based on the user's credentials, but may be overridden for custom |
484
|
|
|
* tokens in your applications. |
485
|
|
|
* |
486
|
|
|
* @param UserInterface $user The user object to base the token off of |
487
|
|
|
* @param string $firewallName name of the firewall provider to use |
488
|
|
|
* |
489
|
|
|
* @return TokenInterface The token to be used in the security context |
490
|
|
|
*/ |
491
|
|
|
protected function createUserToken(UserInterface $user, $firewallName) |
492
|
5 |
|
{ |
493
|
|
|
return new UsernamePasswordToken( |
494
|
5 |
|
$user, |
495
|
5 |
|
null, |
496
|
5 |
|
$firewallName, |
497
|
|
|
$user->getRoles() |
498
|
|
|
); |
499
|
|
|
} |
500
|
|
|
|
501
|
|
|
/** |
502
|
|
|
* Extracts the location from the given route. |
503
|
|
|
* |
504
|
|
|
* @param string $route The name of the route |
505
|
|
|
* @param array $params Set of parameters |
506
|
|
|
* @param int $absolute |
507
|
|
|
* |
508
|
|
|
* @return string |
509
|
|
|
*/ |
510
|
1 |
|
protected function getUrl($route, $params = array(), $absolute = UrlGeneratorInterface::ABSOLUTE_PATH) |
511
|
|
|
{ |
512
|
1 |
|
return $this->getContainer()->get('router')->generate($route, $params, $absolute); |
513
|
1 |
|
} |
514
|
|
|
|
515
|
1 |
|
/** |
516
|
1 |
|
* Checks the success state of a response. |
517
|
1 |
|
* |
518
|
1 |
|
* @param Response $response Response object |
519
|
|
|
* @param bool $success to define whether the response is expected to be successful |
520
|
1 |
|
* @param string $type |
521
|
|
|
*/ |
522
|
|
|
public function isSuccessful(Response $response, $success = true, $type = 'text/html') |
523
|
|
|
{ |
524
|
|
|
$this->getContainer()->get('liip_functional_test.http_assertions') |
525
|
|
|
->isSuccessful($response, $success, $type); |
526
|
|
|
} |
527
|
|
|
|
528
|
|
|
/** |
529
|
|
|
* Executes a request on the given url and returns the response contents. |
530
|
|
|
* |
531
|
|
|
* This method also asserts the request was successful. |
532
|
|
|
* |
533
|
|
|
* @param string $path path of the requested page |
534
|
|
|
* @param string $method The HTTP method to use, defaults to GET |
535
|
1 |
|
* @param bool $authentication Whether to use authentication, defaults to false |
536
|
|
|
* @param bool $success to define whether the response is expected to be successful |
537
|
1 |
|
* |
538
|
1 |
|
* @return string |
539
|
|
|
*/ |
540
|
1 |
|
public function fetchContent($path, $method = 'GET', $authentication = false, $success = true) |
541
|
|
|
{ |
542
|
1 |
|
$client = $this->makeClient($authentication); |
543
|
|
|
$client->request($method, $path); |
544
|
|
|
|
545
|
|
|
$content = $client->getResponse()->getContent(); |
546
|
|
|
if (is_bool($success)) { |
547
|
|
|
$this->isSuccessful($client->getResponse(), $success); |
548
|
|
|
} |
549
|
|
|
|
550
|
|
|
return $content; |
551
|
2 |
|
} |
552
|
|
|
|
553
|
2 |
|
/** |
554
|
|
|
* Executes a request on the given url and returns a Crawler object. |
555
|
2 |
|
* |
556
|
|
|
* This method also asserts the request was successful. |
557
|
|
|
* |
558
|
|
|
* @param string $path path of the requested page |
559
|
|
|
* @param string $method The HTTP method to use, defaults to GET |
560
|
|
|
* @param bool $authentication Whether to use authentication, defaults to false |
561
|
|
|
* @param bool $success Whether the response is expected to be successful |
562
|
|
|
* |
563
|
|
|
* @return Crawler |
564
|
|
|
*/ |
565
|
|
|
public function fetchCrawler($path, $method = 'GET', $authentication = false, $success = true) |
566
|
9 |
|
{ |
567
|
|
|
$client = $this->makeClient($authentication); |
568
|
9 |
|
$crawler = $client->request($method, $path); |
569
|
9 |
|
|
570
|
9 |
|
$this->isSuccessful($client->getResponse(), $success); |
571
|
|
|
|
572
|
|
|
return $crawler; |
573
|
|
|
} |
574
|
|
|
|
575
|
|
|
/** |
576
|
|
|
* @param UserInterface $user |
577
|
|
|
* @param string $firewallName |
578
|
|
|
* |
579
|
2 |
|
* @return WebTestCase |
580
|
|
|
*/ |
581
|
2 |
|
public function loginAs(UserInterface $user, $firewallName) |
582
|
2 |
|
{ |
583
|
1 |
|
$this->firewallLogins[$firewallName] = $user; |
584
|
|
|
|
585
|
|
|
return $this; |
586
|
|
|
} |
587
|
|
|
|
588
|
|
|
/** |
589
|
|
|
* Asserts that the HTTP response code of the last request performed by |
590
|
|
|
* $client matches the expected code. If not, raises an error with more |
591
|
|
|
* information. |
592
|
|
|
* |
593
|
|
|
* @param $expectedStatusCode |
594
|
|
|
* @param Client $client |
595
|
|
|
*/ |
596
|
|
|
public function assertStatusCode($expectedStatusCode, Client $client) |
597
|
|
|
{ |
598
|
|
|
$this->getContainer()->get('liip_functional_test.http_assertions') |
599
|
|
|
->assertStatusCode($expectedStatusCode, $client); |
600
|
|
|
} |
601
|
|
|
|
602
|
|
|
/** |
603
|
|
|
* Assert that the last validation errors within $container match the |
604
|
|
|
* expected keys. |
605
|
|
|
* |
606
|
|
|
* @param array $expected A flat array of field names |
607
|
|
|
* @param ContainerInterface $container |
608
|
|
|
*/ |
609
|
|
|
public function assertValidationErrors(array $expected, ContainerInterface $container) |
610
|
|
|
{ |
611
|
|
|
$this->getContainer()->get('liip_functional_test.http_assertions') |
612
|
|
|
->assertValidationErrors($expected, $container); |
613
|
|
|
} |
614
|
|
|
} |
615
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.