Completed
Push — master ( 3a65e8...9f4bbe )
by Grégoire
16s
created

GenerateAdminCommandTest::testExecuteInteractive()   C

Complexity

Conditions 10
Paths 1

Size

Total Lines 90
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 90
rs 5.1578
c 0
b 0
f 0
cc 10
eloc 62
nc 1
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\AdminBundle\Tests\Command;
13
14
use PHPUnit\Framework\TestCase;
15
use Sonata\AdminBundle\Command\GenerateAdminCommand;
16
use Sonata\AdminBundle\Tests\Fixtures\Bundle\DemoAdminBundle;
17
use Symfony\Bundle\FrameworkBundle\Console\Application;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Console\Question\Question;
21
use Symfony\Component\Console\Tester\CommandTester;
22
use Symfony\Component\DependencyInjection\Container;
23
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
24
25
/**
26
 * @author Andrej Hudec <[email protected]>
27
 */
28
class GenerateAdminCommandTest extends TestCase
29
{
30
    /**
31
     * @var Application
32
     */
33
    private $application;
34
35
    /**
36
     * @var string
37
     */
38
    private $tempDirectory;
39
40
    /**
41
     * @var Container
42
     */
43
    private $container;
44
45
    /**
46
     * @var GenerateAdminCommand
47
     */
48
    private $command;
49
50
    protected function setUp()
51
    {
52
        // create temp dir
53
        $tempfile = tempnam(sys_get_temp_dir(), 'sonata_admin');
54
        if (file_exists($tempfile)) {
55
            unlink($tempfile);
56
        }
57
        mkdir($tempfile);
58
        $this->tempDirectory = $tempfile;
59
60
        $bundle = new DemoAdminBundle();
61
        $bundle->setPath($this->tempDirectory);
62
63
        $kernel = $this->createMock('Symfony\Component\HttpKernel\KernelInterface');
64
        $kernel->expects($this->any())
65
            ->method('getBundles')
66
            ->will($this->returnValue([$bundle]));
67
68
        $parameterBag = new ParameterBag();
69
        $this->container = new Container($parameterBag);
70
71
        $kernel->expects($this->any())
72
            ->method('getBundle')
73
            ->with($this->equalTo('AcmeDemoBundle'))
74
            ->will($this->returnValue($bundle));
75
76
        $kernel->expects($this->any())
77
            ->method('getContainer')
78
            ->will($this->returnValue($this->container));
79
80
        $this->application = new Application($kernel);
81
        $this->command = new GenerateAdminCommand();
82
83
        $this->application->add($this->command);
84
    }
85
86
    public function tearDown()
87
    {
88
        if ($this->tempDirectory) {
89
            if (file_exists($this->tempDirectory.'/Controller/FooAdminController.php')) {
90
                unlink($this->tempDirectory.'/Controller/FooAdminController.php');
91
            }
92
93
            if (file_exists($this->tempDirectory.'/Admin/FooAdmin.php')) {
94
                unlink($this->tempDirectory.'/Admin/FooAdmin.php');
95
            }
96
97
            if (file_exists($this->tempDirectory.'/Resources/config/admin.yml')) {
98
                unlink($this->tempDirectory.'/Resources/config/admin.yml');
99
            }
100
101
            if (is_dir($this->tempDirectory.'/Controller')) {
102
                rmdir($this->tempDirectory.'/Controller');
103
            }
104
105
            if (is_dir($this->tempDirectory.'/Admin')) {
106
                rmdir($this->tempDirectory.'/Admin');
107
            }
108
109
            if (is_dir($this->tempDirectory.'/Resources/config')) {
110
                rmdir($this->tempDirectory.'/Resources/config');
111
            }
112
113
            if (is_dir($this->tempDirectory.'/Resources')) {
114
                rmdir($this->tempDirectory.'/Resources');
115
            }
116
117
            if (file_exists($this->tempDirectory) && is_dir($this->tempDirectory)) {
118
                rmdir($this->tempDirectory);
119
            }
120
        }
121
    }
122
123
    public function testExecute()
124
    {
125
        $this->command->setContainer($this->container);
126
        $this->container->set('sonata.admin.manager.foo', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
127
128
        $command = $this->application->find('sonata:admin:generate');
129
        $commandTester = new CommandTester($command);
130
        $commandTester->execute([
131
            'command' => $command->getName(),
132
            'model' => 'Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Foo',
133
            '--bundle' => 'AcmeDemoBundle',
134
            '--admin' => 'FooAdmin',
135
            '--controller' => 'FooAdminController',
136
            '--services' => 'admin.yml',
137
            '--id' => 'acme_demo_admin.admin.foo',
138
        ], ['interactive' => false]);
139
140
        $expectedOutput = '';
141
        $expectedOutput .= sprintf('%3$sThe admin class "Sonata\AdminBundle\Tests\Fixtures\Bundle\Admin\FooAdmin" has been generated under the file "%1$s%2$sAdmin%2$sFooAdmin.php".%3$s', $this->tempDirectory, DIRECTORY_SEPARATOR, PHP_EOL);
142
        $expectedOutput .= sprintf('%3$sThe controller class "Sonata\AdminBundle\Tests\Fixtures\Bundle\Controller\FooAdminController" has been generated under the file "%1$s%2$sController%2$sFooAdminController.php".%3$s', $this->tempDirectory, DIRECTORY_SEPARATOR, PHP_EOL);
143
        $expectedOutput .= sprintf('%3$sThe service "acme_demo_admin.admin.foo" has been appended to the file "%1$s%2$sResources%2$sconfig%2$sadmin.yml".%3$s', $this->tempDirectory, DIRECTORY_SEPARATOR, PHP_EOL);
144
145
        $this->assertSame($expectedOutput, $commandTester->getDisplay());
146
147
        $this->assertFileExists($this->tempDirectory.'/Admin/FooAdmin.php');
148
        $this->assertFileExists($this->tempDirectory.'/Controller/FooAdminController.php');
149
        $this->assertFileExists($this->tempDirectory.'/Resources/config/admin.yml');
150
151
        $adminContent = file_get_contents($this->tempDirectory.'/Admin/FooAdmin.php');
152
        $this->assertContains('class FooAdmin extends AbstractAdmin', $adminContent);
153
        $this->assertContains('use Sonata\AdminBundle\Admin\AbstractAdmin;', $adminContent);
154
        $this->assertContains('use Sonata\AdminBundle\Datagrid\DatagridMapper;', $adminContent);
155
        $this->assertContains('use Sonata\AdminBundle\Datagrid\ListMapper;', $adminContent);
156
        $this->assertContains('use Sonata\AdminBundle\Form\FormMapper;', $adminContent);
157
        $this->assertContains('use Sonata\AdminBundle\Show\ShowMapper;', $adminContent);
158
        $this->assertContains('protected function configureDatagridFilters(DatagridMapper $datagridMapper)', $adminContent);
159
        $this->assertContains('protected function configureListFields(ListMapper $listMapper)', $adminContent);
160
        $this->assertContains('protected function configureFormFields(FormMapper $formMapper)', $adminContent);
161
        $this->assertContains('protected function configureShowFields(ShowMapper $showMapper)', $adminContent);
162
163
        $controllerContent = file_get_contents($this->tempDirectory.'/Controller/FooAdminController.php');
164
        $this->assertContains('class FooAdminController extends CRUDController', $controllerContent);
165
        $this->assertContains('use Sonata\AdminBundle\Controller\CRUDController;', $controllerContent);
166
167
        $configServiceContent = file_get_contents($this->tempDirectory.'/Resources/config/admin.yml');
168
        $this->assertContains('services:'."\n".'    acme_demo_admin.admin.foo', $configServiceContent);
169
        $this->assertContains('            - { name: sonata.admin, manager_type: foo, group: admin, label: Foo }', $configServiceContent);
170
    }
171
172
    public function testExecuteWithExceptionNoModelManagers()
173
    {
174
        $this->expectException('RuntimeException', 'There are no model managers registered.');
175
176
        $this->command->setContainer($this->container);
177
178
        $command = $this->application->find('sonata:admin:generate');
179
        $commandTester = new CommandTester($command);
180
        $commandTester->execute([
181
            'command' => $command->getName(),
182
            'model' => 'Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Foo',
183
            '--bundle' => 'AcmeDemoBundle',
184
            '--admin' => 'FooAdmin',
185
            '--controller' => 'FooAdminController',
186
            '--services' => 'admin.yml',
187
            '--id' => 'acme_demo_admin.admin.foo',
188
        ], ['interactive' => false]);
189
    }
190
191
    /**
192
     * @dataProvider getExecuteInteractiveTests
193
     */
194
    public function testExecuteInteractive($modelEntity)
195
    {
196
        $this->command->setContainer($this->container);
197
        $this->container->set('sonata.admin.manager.foo', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
198
        $this->container->set('sonata.admin.manager.bar', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
199
200
        $command = $this->application->find('sonata:admin:generate');
201
202
        $questionHelper = $this->getMockBuilder('Sensio\Bundle\GeneratorBundle\Command\Helper\QuestionHelper')
203
            ->setMethods(['ask'])
204
            ->getMock();
205
206
        $questionHelper->expects($this->any())
207
            ->method('ask')
208
            ->will($this->returnCallback(function (InputInterface $input, OutputInterface $output, Question $question) use ($modelEntity) {
209
                $questionClean = substr($question->getQuestion(), 6, strpos($question->getQuestion(), '</info>') - 6);
210
211
                switch ($questionClean) {
212
                    // confirmations
213
                    case 'Do you want to generate a controller':
214
                        return 'yes';
215
216
                    case 'Do you want to update the services YAML configuration file':
217
                        return 'yes';
218
219
                    // inputs
220
                    case 'The fully qualified model class':
221
                        return $modelEntity;
222
223
                    case 'The bundle name':
224
                        return 'AcmeDemoBundle';
225
226
                    case 'The admin class basename':
227
                        return 'FooAdmin';
228
229
                    case 'The controller class basename':
230
                        return 'FooAdminController';
231
232
                    case 'The services YAML configuration file':
233
                        return 'admin.yml';
234
235
                    case 'The admin service ID':
236
                        return 'acme_demo_admin.admin.foo';
237
238
                    case 'The manager type':
239
                        return 'foo';
240
                }
241
242
                return false;
243
            }));
244
245
        $command->getHelperSet()->set($questionHelper, 'question');
246
247
        $commandTester = new CommandTester($command);
248
        $commandTester->execute([
249
            'command' => $command->getName(),
250
            'model' => $modelEntity,
251
            ]);
252
253
        $expectedOutput = PHP_EOL.str_pad('', 41, ' ').PHP_EOL.'  Welcome to the Sonata admin generator  '.PHP_EOL.str_pad('', 41, ' ').PHP_EOL.PHP_EOL;
254
        $expectedOutput .= sprintf('%3$sThe admin class "Sonata\AdminBundle\Tests\Fixtures\Bundle\Admin\FooAdmin" has been generated under the file "%1$s%2$sAdmin%2$sFooAdmin.php".%3$s', $this->tempDirectory, DIRECTORY_SEPARATOR, PHP_EOL);
255
        $expectedOutput .= sprintf('%3$sThe controller class "Sonata\AdminBundle\Tests\Fixtures\Bundle\Controller\FooAdminController" has been generated under the file "%1$s%2$sController%2$sFooAdminController.php".%3$s', $this->tempDirectory, DIRECTORY_SEPARATOR, PHP_EOL);
256
        $expectedOutput .= sprintf('%3$sThe service "acme_demo_admin.admin.foo" has been appended to the file "%1$s%2$sResources%2$sconfig%2$sadmin.yml".%3$s', $this->tempDirectory, DIRECTORY_SEPARATOR, PHP_EOL);
257
258
        $this->assertSame($expectedOutput, str_replace("\n", PHP_EOL, str_replace(PHP_EOL, "\n", $commandTester->getDisplay())));
259
260
        $this->assertFileExists($this->tempDirectory.'/Admin/FooAdmin.php');
261
        $this->assertFileExists($this->tempDirectory.'/Controller/FooAdminController.php');
262
        $this->assertFileExists($this->tempDirectory.'/Resources/config/admin.yml');
263
264
        $adminContent = file_get_contents($this->tempDirectory.'/Admin/FooAdmin.php');
265
        $this->assertContains('class FooAdmin extends AbstractAdmin', $adminContent);
266
        $this->assertContains('use Sonata\AdminBundle\Admin\AbstractAdmin;', $adminContent);
267
        $this->assertContains('use Sonata\AdminBundle\Datagrid\DatagridMapper;', $adminContent);
268
        $this->assertContains('use Sonata\AdminBundle\Datagrid\ListMapper;', $adminContent);
269
        $this->assertContains('use Sonata\AdminBundle\Form\FormMapper;', $adminContent);
270
        $this->assertContains('use Sonata\AdminBundle\Show\ShowMapper;', $adminContent);
271
        $this->assertContains('protected function configureDatagridFilters(DatagridMapper $datagridMapper)', $adminContent);
272
        $this->assertContains('protected function configureListFields(ListMapper $listMapper)', $adminContent);
273
        $this->assertContains('protected function configureFormFields(FormMapper $formMapper)', $adminContent);
274
        $this->assertContains('protected function configureShowFields(ShowMapper $showMapper)', $adminContent);
275
276
        $controllerContent = file_get_contents($this->tempDirectory.'/Controller/FooAdminController.php');
277
        $this->assertContains('class FooAdminController extends CRUDController', $controllerContent);
278
        $this->assertContains('use Sonata\AdminBundle\Controller\CRUDController;', $controllerContent);
279
280
        $configServiceContent = file_get_contents($this->tempDirectory.'/Resources/config/admin.yml');
281
        $this->assertContains('services:'."\n".'    acme_demo_admin.admin.foo', $configServiceContent);
282
        $this->assertContains('            - { name: sonata.admin, manager_type: foo, group: admin, label: Foo }', $configServiceContent);
283
    }
284
285
    public function getExecuteInteractiveTests()
286
    {
287
        return [
288
            ['Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Foo'],
289
            ['Sonata\AdminBundle\Tests\Fixtures\Entity\Foo'],
290
        ];
291
    }
292
293
    /**
294
     * @dataProvider getValidateManagerTypeTests
295
     */
296
    public function testValidateManagerType($expected, $managerType)
297
    {
298
        $this->command->setContainer($this->container);
299
        $this->container->set('sonata.admin.manager.foo', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
300
        $this->container->set('sonata.admin.manager.bar', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
301
302
        $this->assertSame($expected, $this->command->validateManagerType($managerType));
303
    }
304
305
    public function getValidateManagerTypeTests()
306
    {
307
        return [
308
            ['foo', 'foo'],
309
            ['bar', 'bar'],
310
        ];
311
    }
312
313
    public function testValidateManagerTypeWithException1()
314
    {
315
        $this->command->setContainer($this->container);
316
        $this->setExpectedException('InvalidArgumentException', 'Invalid manager type "foo". Available manager types are "".');
317
        $this->command->validateManagerType('foo');
318
    }
319
320
    public function testValidateManagerTypeWithException2()
321
    {
322
        $this->command->setContainer($this->container);
323
        $this->container->set('sonata.admin.manager.foo', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
324
        $this->container->set('sonata.admin.manager.bar', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
325
326
        $this->expectException('InvalidArgumentException', 'Invalid manager type "baz". Available manager types are "foo", "bar".');
327
        $this->command->validateManagerType('baz');
328
    }
329
330
    public function testValidateManagerTypeWithException3()
331
    {
332
        $this->expectException('InvalidArgumentException', 'Invalid manager type "baz". Available manager types are "".');
333
        $this->command->validateManagerType('baz');
334
    }
335
336
    public function testAnswerUpdateServicesWithNo()
337
    {
338
        $this->container->set('sonata.admin.manager.foo', $this->createMock('Sonata\AdminBundle\Model\ModelManagerInterface'));
339
340
        $modelEntity = 'Sonata\AdminBundle\Tests\Fixtures\Bundle\Entity\Foo';
341
342
        $command = $this->application->find('sonata:admin:generate');
343
344
        $questionHelper = $this->getMockBuilder('Sensio\Bundle\GeneratorBundle\Command\Helper\QuestionHelper')
345
            ->setMethods(['ask'])
346
            ->getMock();
347
348
        $questionHelper->expects($this->any())
349
            ->method('ask')
350
            ->will($this->returnCallback(function (InputInterface $input, OutputInterface $output, Question $question) use ($modelEntity) {
351
                $questionClean = substr($question->getQuestion(), 6, strpos($question->getQuestion(), '</info>') - 6);
352
353
                switch ($questionClean) {
354
                    // confirmations
355
                    case 'Do you want to generate a controller':
356
                        return false;
357
358
                    case 'Do you want to update the services YAML configuration file':
359
                        return false;
360
361
                    // inputs
362
                    case 'The fully qualified model class':
363
                        return $modelEntity;
364
365
                    case 'The bundle name':
366
                        return 'AcmeDemoBundle';
367
368
                    case 'The admin class basename':
369
                        return 'FooAdmin';
370
                }
371
372
                return false;
373
            }));
374
375
        $command->getHelperSet()->set($questionHelper, 'question');
376
377
        $commandTester = new CommandTester($command);
378
        $commandTester->execute([
379
            'command' => $command->getName(),
380
            'model' => $modelEntity,
381
        ]);
382
383
        $this->assertFalse(file_exists($this->tempDirectory.'/Resources/config/services.yml'));
384
    }
385
}
386