Completed
Push — master ( 3f58ef...2b3071 )
by Yann
02:01
created

DependencyInjectionTest   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 177
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 9
dl 0
loc 177
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Yokai\SecurityTokenBundle\Tests\DependencyInjection;
4
5
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
6
use Doctrine\ORM\Configuration;
7
use Doctrine\ORM\EntityManager;
8
use Prophecy\Prophecy\ProphecySubjectInterface;
9
use Psr\Log\LoggerInterface;
10
use Symfony\Component\Config\FileLocator;
11
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
12
use Symfony\Component\DependencyInjection\ContainerBuilder;
13
use Symfony\Component\DependencyInjection\Definition;
14
use Symfony\Component\DependencyInjection\Loader;
15
use Symfony\Component\HttpFoundation\RequestStack;
16
use Yokai\SecurityTokenBundle\Archive\ArchivistInterface;
17
use Yokai\SecurityTokenBundle\Configuration\TokenConfiguration;
18
use Yokai\SecurityTokenBundle\Factory\TokenFactoryInterface;
19
use Yokai\SecurityTokenBundle\Generator\OpenSslTokenGenerator;
20
use Yokai\SecurityTokenBundle\Generator\TokenGeneratorInterface;
21
use Yokai\SecurityTokenBundle\InformationGuesser\InformationGuesserInterface;
22
use Yokai\SecurityTokenBundle\Manager\TokenManagerInterface;
23
use Yokai\SecurityTokenBundle\Manager\UserManagerInterface;
24
use Yokai\SecurityTokenBundle\Repository\TokenRepositoryInterface;
25
use Yokai\SecurityTokenBundle\YokaiSecurityTokenBundle;
26
27
/**
28
 * @author Yann Eugoné <[email protected]>
29
 */
30
class DependencyInjectionTest extends \PHPUnit_Framework_TestCase
31
{
32
    /**
33
     * @var ContainerBuilder
34
     */
35
    private $container;
36
37
    protected function setUp()
38
    {
39
        $bundle = new YokaiSecurityTokenBundle();
40
        $this->container = new ContainerBuilder();
41
42
        $bundles = [
43
            'FrameworkBundle' => 'Symfony\Bundle\FrameworkBundle\FrameworkBundle',
44
            'DoctrineBundle' => 'Doctrine\Bundle\DoctrineBundle\DoctrineBundle',
45
            'YokaiSecurityTokenBundle' => 'Yokai\SecurityTokenBundle\YokaiSecurityTokenBundle',
46
            'AppBundle' => 'AppBundle\AppBundle',
47
        ];
48
49
        $this->container->setParameter('kernel.debug', true);
50
        $this->container->setParameter('kernel.bundles', $bundles);
51
        $this->container->set('logger', $this->prophesize(LoggerInterface::class)->reveal());
52
        $this->container->setDefinition('doctrine.orm.default_entity_manager', new Definition(EntityManager::class));
53
        $this->container->setDefinition('doctrine.orm.default_metadata_driver', new Definition(MappingDriverChain::class));
54
        $this->container->setDefinition('doctrine.orm.default_configuration', new Definition(Configuration::class));
55
        $this->container->setDefinition('request_stack', new Definition(RequestStack::class));
56
        $this->container->setParameter('doctrine.default_entity_manager', 'default');
57
58
        $mocks = [
59
            'generator_mock' => TokenGeneratorInterface::class,
60
            'information_guesser_mock' => InformationGuesserInterface::class,
61
            'token_factory_mock' => TokenFactoryInterface::class,
62
            'token_repository_mock' => TokenRepositoryInterface::class,
63
            'token_manager_mock' => TokenManagerInterface::class,
64
            'user_manager_mock' => UserManagerInterface::class,
65
            'archivist_mock' => ArchivistInterface::class,
66
        ];
67
        foreach ($mocks as $id => $class) {
68
            $service = $this->prophesize($class)->reveal();
69
            $this->container->setDefinition($id, new Definition(get_class($service)));
70
        }
71
72
        $this->container->registerExtension($bundle->getContainerExtension());
73
        $bundle->build($this->container);
74
    }
75
76
    /**
77
     * @test
78
     * @dataProvider configurationProvider
79
     */
80
    public function it_parse_configuration_as_expected($resource, array $tokens, array $aliases)
81
    {
82
        // for test purpose, all services are switched to public
83
        $this->container->addCompilerPass(new class implements CompilerPassInterface {
84
            public function process(ContainerBuilder $container)
85
            {
86
                $container->findDefinition('yokai_security_token.configuration_registry')->setPublic(true);
87
                $container->findDefinition('yokai_security_token.default_information_guesser')->setPublic(true);
88
                $container->findDefinition('yokai_security_token.default_token_factory')->setPublic(true);
89
                $container->findDefinition('yokai_security_token.default_token_repository')->setPublic(true);
90
                $container->findDefinition('yokai_security_token.default_token_manager')->setPublic(true);
91
                $container->findDefinition('yokai_security_token.default_user_manager')->setPublic(true);
92
                $container->findDefinition('yokai_security_token.delete_archivist')->setPublic(true);
93
            }
94
        });
95
96
        $this->loadConfiguration($resource);
97
        $this->container->compile();
98
99
        foreach ($tokens as $tokenId => $tokenConfig) {
100
            $token = $this->container->get('yokai_security_token.configuration_registry')->get($tokenId);
101
102
            self::assertInstanceOf(TokenConfiguration::class, $token);
103
            self::assertInstanceOf($tokenConfig['generator'], $token->getGenerator());
104
            self::assertSame($tokenId, $token->getPurpose());
105
            self::assertSame($tokenConfig['duration'], $token->getDuration());
106
        }
107
108
        foreach ($aliases as $alias => $expectedId) {
109
            self::assertTrue(
110
                $this->container->hasAlias($alias),
111
                "An alias named \"$alias\" exists."
112
            );
113
            self::assertSame(
114
                $expectedId, (string) $this->container->getAlias($alias),
115
                "The alias named \"$alias\" refer to \"$expectedId\"."
116
            );
117
        }
118
    }
119
120
    /**
121
     * @param string $resource
122
     */
123
    protected function loadConfiguration($resource)
124
    {
125
        $locator = new FileLocator(__DIR__.'/configuration/');
126
        $path = $locator->locate($resource);
127
128
        switch (pathinfo($path, PATHINFO_EXTENSION)) {
129
            case 'yml':
130
                $loader = new Loader\YamlFileLoader($this->container, $locator);
131
                break;
132
133
            //todo nice to have : support more configuration format
134
135
            default:
136
                throw new \InvalidArgumentException('File ' . $path . ' is not supported.');
137
                break;
138
        }
139
140
        $loader->load($resource);
141
    }
142
143
    public function configurationProvider()
144
    {
145
        $defaultAliases = [
146
            'yokai_security_token.information_guesser' => 'yokai_security_token.default_information_guesser',
147
            'yokai_security_token.token_factory' => 'yokai_security_token.default_token_factory',
148
            'yokai_security_token.token_repository' => 'yokai_security_token.default_token_repository',
149
            'yokai_security_token.token_manager' => 'yokai_security_token.default_token_manager',
150
            'yokai_security_token.user_manager' => 'yokai_security_token.default_user_manager',
151
            'yokai_security_token.archivist' => 'yokai_security_token.delete_archivist',
152
        ];
153
154
        foreach ($this->formatProvider() as $format) {
155
            $format = $format[0];
156
157
            yield $format . ' - none' => [
158
                'none.' . $format,
159
                [],
160
                $defaultAliases,
161
            ];
162
163
            yield $format . ' - names only' => [
164
                'names.' . $format,
165
                [
166
                    'security_password_init' => [
167
                        'generator' => OpenSslTokenGenerator::class,
168
                        'duration' => '+2 days',
169
                    ],
170
                    'security_password_reset' => [
171
                        'generator' => OpenSslTokenGenerator::class,
172
                        'duration' => '+2 days',
173
                    ],
174
                ],
175
                $defaultAliases,
176
            ];
177
178
            yield $format . ' - fully configured' => [
179
                'full.' . $format,
180
                [
181
                    'security_password_init' => [
182
                        'generator' => ProphecySubjectInterface::class,
183
                        'duration' => '+1 month',
184
                    ],
185
                    'security_password_reset' => [
186
                        'generator' => ProphecySubjectInterface::class,
187
                        'duration' => '+2 monthes',
188
                    ],
189
                ],
190
                [
191
                    'yokai_security_token.information_guesser' => 'information_guesser_mock',
192
                    'yokai_security_token.token_factory' => 'token_factory_mock',
193
                    'yokai_security_token.token_repository' => 'token_repository_mock',
194
                    'yokai_security_token.token_manager' => 'token_manager_mock',
195
                    'yokai_security_token.user_manager' => 'user_manager_mock',
196
                    'yokai_security_token.archivist' => 'archivist_mock',
197
                ],
198
            ];
199
        }
200
    }
201
202
    public function formatProvider()
203
    {
204
        yield ['yml'];
205
    }
206
}
207