Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 089ec9d

Browse files
minor #49286 Split and clean up tests (localheinz)
This PR was merged into the 5.4 branch. Discussion ---------- Split and clean up tests | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | n/a | License | MIT | Doc PR | n/a This pull request - [x] splits a test and removes a data provider to avoid creating test doubles in data providers Follows #49244. 💁‍♂️ This follows a brief discussion on Twitter (see https://twitter.com/VotrubaT/status/1622995017756291074). I do not expect this to be merged, but in my opinion, creating - test doubles - the system under test (not the case here, but I have observed it elsewhere) in data providers are anti-patterns. ~~Other than that, I have no idea what we are testing here.~~ Commits ------- 66e9fe1 Fix: Split and clean up tests
2 parents 59f2eba + 66e9fe1 commit 089ec9d

File tree

1 file changed

+124
-82
lines changed

1 file changed

+124
-82
lines changed

src/Symfony/Bundle/SecurityBundle/Tests/DataCollector/SecurityDataCollectorTest.php

Lines changed: 124 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Security\Core\User\InMemoryUser;
3434
use Symfony\Component\Security\Http\FirewallMapInterface;
3535
use Symfony\Component\Security\Http\Logout\LogoutUrlGenerator;
36+
use Symfony\Component\VarDumper\Caster\ClassStub;
3637
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
3738

3839
class SecurityDataCollectorTest extends TestCase
@@ -223,46 +224,111 @@ public function testGetListeners()
223224
$this->assertSame(1, $listenerCalled);
224225
}
225226

226-
public static function providerCollectDecisionLog(): \Generator
227+
public function testCollectCollectsDecisionLogWhenStrategyIsAffirmative()
227228
{
228229
$voter1 = new DummyVoter();
229230
$voter2 = new DummyVoter();
230231

231-
$eventDispatcher = new class() implements EventDispatcherInterface {
232+
$decoratedVoter1 = new TraceableVoter($voter1, new class() implements EventDispatcherInterface {
232233
public function dispatch(object $event, string $eventName = null): object
233234
{
234235
return new \stdClass();
235236
}
236-
};
237-
$decoratedVoter1 = new TraceableVoter($voter1, $eventDispatcher);
237+
});
238+
239+
$strategy = MainConfiguration::STRATEGY_AFFIRMATIVE;
240+
241+
$accessDecisionManager = $this->createMock(TraceableAccessDecisionManager::class);
242+
243+
$accessDecisionManager
244+
->method('getStrategy')
245+
->willReturn($strategy);
238246

239-
yield [
240-
MainConfiguration::STRATEGY_AFFIRMATIVE,
241-
[[
247+
$accessDecisionManager
248+
->method('getVoters')
249+
->willReturn([
250+
$decoratedVoter1,
251+
$decoratedVoter1,
252+
]);
253+
254+
$accessDecisionManager
255+
->method('getDecisionLog')
256+
->willReturn([[
242257
'attributes' => ['view'],
243258
'object' => new \stdClass(),
244259
'result' => true,
245260
'voterDetails' => [
246261
['voter' => $voter1, 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
247262
['voter' => $voter2, 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
248263
],
249-
]],
250-
[$decoratedVoter1, $decoratedVoter1],
251-
[\get_class($voter1), \get_class($voter2)],
252-
[[
253-
'attributes' => ['view'],
254-
'object' => new \stdClass(),
255-
'result' => true,
256-
'voter_details' => [
257-
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
258-
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
259-
],
260-
]],
264+
]]);
265+
266+
$dataCollector = new SecurityDataCollector(null, null, null, $accessDecisionManager, null, null, true);
267+
268+
$dataCollector->collect(new Request(), new Response());
269+
270+
$actualDecisionLog = $dataCollector->getAccessDecisionLog();
271+
272+
$expectedDecisionLog = [[
273+
'attributes' => ['view'],
274+
'object' => new \stdClass(),
275+
'result' => true,
276+
'voter_details' => [
277+
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
278+
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_ABSTAIN],
279+
],
280+
]];
281+
282+
$this->assertEquals($actualDecisionLog, $expectedDecisionLog, 'Wrong value returned by getAccessDecisionLog');
283+
284+
$actualVoterClasses = array_map(static function (ClassStub $classStub): string {
285+
return (string) $classStub;
286+
}, $dataCollector->getVoters());
287+
288+
$expectedVoterClasses = [
289+
\get_class($voter1),
290+
\get_class($voter2),
261291
];
262292

263-
yield [
264-
MainConfiguration::STRATEGY_UNANIMOUS,
265-
[
293+
$this->assertSame(
294+
$actualVoterClasses,
295+
$expectedVoterClasses,
296+
'Wrong value returned by getVoters'
297+
);
298+
299+
$this->assertSame($dataCollector->getVoterStrategy(), $strategy, 'Wrong value returned by getVoterStrategy');
300+
}
301+
302+
public function testCollectCollectsDecisionLogWhenStrategyIsUnanimous()
303+
{
304+
$voter1 = new DummyVoter();
305+
$voter2 = new DummyVoter();
306+
307+
$decoratedVoter1 = new TraceableVoter($voter1, new class() implements EventDispatcherInterface {
308+
public function dispatch(object $event, string $eventName = null): object
309+
{
310+
return new \stdClass();
311+
}
312+
});
313+
314+
$strategy = MainConfiguration::STRATEGY_UNANIMOUS;
315+
316+
$accessDecisionManager = $this->createMock(TraceableAccessDecisionManager::class);
317+
318+
$accessDecisionManager
319+
->method('getStrategy')
320+
->willReturn($strategy);
321+
322+
$accessDecisionManager
323+
->method('getVoters')
324+
->willReturn([
325+
$decoratedVoter1,
326+
$decoratedVoter1,
327+
]);
328+
329+
$accessDecisionManager
330+
->method('getDecisionLog')
331+
->willReturn([
266332
[
267333
'attributes' => ['view', 'edit'],
268334
'object' => new \stdClass(),
@@ -283,78 +349,54 @@ public function dispatch(object $event, string $eventName = null): object
283349
['voter' => $voter2, 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
284350
],
285351
],
286-
],
287-
[$decoratedVoter1, $decoratedVoter1],
288-
[\get_class($voter1), \get_class($voter2)],
352+
]);
353+
354+
$dataCollector = new SecurityDataCollector(null, null, null, $accessDecisionManager, null, null, true);
355+
356+
$dataCollector->collect(new Request(), new Response());
357+
358+
$actualDecisionLog = $dataCollector->getAccessDecisionLog();
359+
360+
$expectedDecisionLog = [
289361
[
290-
[
291-
'attributes' => ['view', 'edit'],
292-
'object' => new \stdClass(),
293-
'result' => false,
294-
'voter_details' => [
295-
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_DENIED],
296-
['class' => \get_class($voter1), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_DENIED],
297-
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_GRANTED],
298-
['class' => \get_class($voter2), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_GRANTED],
299-
],
362+
'attributes' => ['view', 'edit'],
363+
'object' => new \stdClass(),
364+
'result' => false,
365+
'voter_details' => [
366+
['class' => \get_class($voter1), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_DENIED],
367+
['class' => \get_class($voter1), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_DENIED],
368+
['class' => \get_class($voter2), 'attributes' => ['view'], 'vote' => VoterInterface::ACCESS_GRANTED],
369+
['class' => \get_class($voter2), 'attributes' => ['edit'], 'vote' => VoterInterface::ACCESS_GRANTED],
300370
],
301-
[
302-
'attributes' => ['update'],
303-
'object' => new \stdClass(),
304-
'result' => true,
305-
'voter_details' => [
306-
['class' => \get_class($voter1), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
307-
['class' => \get_class($voter2), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
308-
],
371+
],
372+
[
373+
'attributes' => ['update'],
374+
'object' => new \stdClass(),
375+
'result' => true,
376+
'voter_details' => [
377+
['class' => \get_class($voter1), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
378+
['class' => \get_class($voter2), 'attributes' => ['update'], 'vote' => VoterInterface::ACCESS_GRANTED],
309379
],
310380
],
311381
];
312-
}
313382

314-
/**
315-
* Test the returned data when AccessDecisionManager is a TraceableAccessDecisionManager.
316-
*
317-
* @param string $strategy strategy returned by the AccessDecisionManager
318-
* @param array $voters voters returned by AccessDecisionManager
319-
* @param array $decisionLog log of the votes and final decisions from AccessDecisionManager
320-
* @param array $expectedVoterClasses expected voter classes returned by the collector
321-
* @param array $expectedDecisionLog expected decision log returned by the collector
322-
*
323-
* @dataProvider providerCollectDecisionLog
324-
*/
325-
public function testCollectDecisionLog(string $strategy, array $decisionLog, array $voters, array $expectedVoterClasses, array $expectedDecisionLog)
326-
{
327-
$accessDecisionManager = $this
328-
->getMockBuilder(TraceableAccessDecisionManager::class)
329-
->disableOriginalConstructor()
330-
->setMethods(['getStrategy', 'getVoters', 'getDecisionLog'])
331-
->getMock();
383+
$this->assertEquals($actualDecisionLog, $expectedDecisionLog, 'Wrong value returned by getAccessDecisionLog');
332384

333-
$accessDecisionManager
334-
->expects($this->any())
335-
->method('getStrategy')
336-
->willReturn($strategy);
385+
$actualVoterClasses = array_map(static function (ClassStub $classStub): string {
386+
return (string) $classStub;
387+
}, $dataCollector->getVoters());
337388

338-
$accessDecisionManager
339-
->expects($this->any())
340-
->method('getVoters')
341-
->willReturn($voters);
342-
343-
$accessDecisionManager
344-
->expects($this->any())
345-
->method('getDecisionLog')
346-
->willReturn($decisionLog);
347-
348-
$dataCollector = new SecurityDataCollector(null, null, null, $accessDecisionManager, null, null, true);
349-
$dataCollector->collect(new Request(), new Response());
350-
351-
$this->assertEquals($dataCollector->getAccessDecisionLog(), $expectedDecisionLog, 'Wrong value returned by getAccessDecisionLog');
389+
$expectedVoterClasses = [
390+
\get_class($voter1),
391+
\get_class($voter2),
392+
];
352393

353394
$this->assertSame(
354-
array_map(function ($classStub) { return (string) $classStub; }, $dataCollector->getVoters()),
395+
$actualVoterClasses,
355396
$expectedVoterClasses,
356397
'Wrong value returned by getVoters'
357398
);
399+
358400
$this->assertSame($dataCollector->getVoterStrategy(), $strategy, 'Wrong value returned by getVoterStrategy');
359401
}
360402

@@ -390,7 +432,7 @@ private function getRoleHierarchy()
390432
}
391433
}
392434

393-
class DummyVoter implements VoterInterface
435+
final class DummyVoter implements VoterInterface
394436
{
395437
public function vote(TokenInterface $token, $subject, array $attributes)
396438
{

0 commit comments

Comments
 (0)