Issues (3627)

bundles/CoreBundle/Test/AbstractMauticTestCase.php (5 issues)

1
<?php
2
3
namespace Mautic\CoreBundle\Test;
4
5
use Doctrine\Common\DataFixtures\Executor\AbstractExecutor;
6
use Doctrine\DBAL\Connection;
7
use Doctrine\ORM\EntityManager;
8
use Liip\TestFixturesBundle\Test\FixturesTrait;
9
use Mautic\CoreBundle\ErrorHandler\ErrorHandler;
10
use Mautic\CoreBundle\Helper\CookieHelper;
11
use Mautic\CoreBundle\Test\Session\FixedMockFileSessionStorage;
12
use RuntimeException;
13
use Symfony\Bundle\FrameworkBundle\Client;
14
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
15
use Symfony\Bundle\FrameworkBundle\Console\Application;
16
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
17
use Symfony\Component\Console\Command\Command;
18
use Symfony\Component\Console\Input\ArgvInput;
19
use Symfony\Component\Console\Input\ArrayInput;
20
use Symfony\Component\Console\Output\BufferedOutput;
21
use Symfony\Component\DependencyInjection\ContainerInterface;
22
use Symfony\Component\Finder\Finder;
23
use Symfony\Component\HttpFoundation\Session\Session;
24
use Symfony\Component\Routing\RouterInterface;
25
26
abstract class AbstractMauticTestCase extends WebTestCase
27
{
28
    use FixturesTrait {
29
        loadFixtures as private traitLoadFixtures;
30
        loadFixtureFiles as private traitLoadFixtureFiles;
31
    }
32
33
    /**
34
     * @var EntityManager
35
     */
36
    protected $em;
37
38
    /**
39
     * @var Connection
40
     */
41
    protected $connection;
42
43
    /**
44
     * @var ContainerInterface
45
     */
46
    protected $container;
47
48
    /**
49
     * @var Client
50
     */
51
    protected $client;
52
53
    /**
54
     * @var array
55
     */
56
    protected $clientOptions = [];
57
58
    /**
59
     * @var array
60
     */
61
    protected $clientServer = [
62
        'PHP_AUTH_USER' => 'admin',
63
        'PHP_AUTH_PW'   => 'mautic',
64
    ];
65
66
    protected function setUp(): void
67
    {
68
        $this->setUpSymfony(
69
            [
70
                'api_enabled'                       => true,
71
                'api_enable_basic_auth'             => true,
72
                'create_custom_field_in_background' => false,
73
            ]
74
        );
75
    }
76
77
    protected function setUpSymfony(array $defaultConfigOptions = []): void
78
    {
79
        putenv('MAUTIC_CONFIG_PARAMETERS='.json_encode($defaultConfigOptions));
80
81
        ErrorHandler::register('prod');
82
83
        $this->client = static::createClient($this->clientOptions, $this->clientServer);
84
        $this->client->disableReboot();
85
        $this->client->followRedirects(true);
86
87
        $this->container  = $this->client->getContainer();
88
        $this->em         = $this->container->get('doctrine')->getManager();
0 ignored issues
show
The method get() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

88
        $this->em         = $this->container->/** @scrutinizer ignore-call */ get('doctrine')->getManager();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
89
        $this->connection = $this->em->getConnection();
90
91
        /** @var RouterInterface $router */
92
        $router = $this->container->get('router');
93
        $scheme = $router->getContext()->getScheme();
94
        $secure = 0 === strcasecmp($scheme, 'https');
95
96
        $this->client->setServerParameter('HTTPS', $secure);
97
98
        $this->mockServices();
99
    }
100
101
    protected function tearDown(): void
102
    {
103
        static::$class = null;
104
105
        $this->em->close();
106
107
        parent::tearDown();
108
    }
109
110
    /**
111
     * Overrides \Liip\TestFixturesBundle\Test\FixturesTrait::getContainer() method to prevent from having multiple instances of container.
112
     */
113
    protected function getContainer(): ContainerInterface
114
    {
115
        return $this->container;
116
    }
117
118
    /**
119
     * Make `$append = true` default so we can avoid unnecessary purges.
120
     */
121
    protected function loadFixtures(array $classNames = [], bool $append = true, ?string $omName = null, string $registryName = 'doctrine', ?int $purgeMode = null): ?AbstractExecutor
122
    {
123
        return $this->traitLoadFixtures($classNames, $append, $omName, $registryName, $purgeMode);
124
    }
125
126
    /**
127
     * Make `$append = true` default so we can avoid unnecessary purges.
128
     */
129
    protected function loadFixtureFiles(array $paths = [], bool $append = true, ?string $omName = null, string $registryName = 'doctrine', ?int $purgeMode = null): array
130
    {
131
        return $this->traitLoadFixtureFiles($paths, $append, $omName, $registryName, $purgeMode);
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     */
137
    protected static function getKernelClass()
138
    {
139
        if (isset($_SERVER['KERNEL_DIR'])) {
140
            $dir = $_SERVER['KERNEL_DIR'];
141
142
            if (!is_dir($dir)) {
143
                $phpUnitDir = static::getPhpUnitXmlDir();
0 ignored issues
show
Deprecated Code introduced by
The function Symfony\Bundle\Framework...ase::getPhpUnitXmlDir() has been deprecated: since 3.4 and will be removed in 4.0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

143
                $phpUnitDir = /** @scrutinizer ignore-deprecated */ static::getPhpUnitXmlDir();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
144
                if (is_dir("$phpUnitDir/$dir")) {
145
                    $dir = "$phpUnitDir/$dir";
146
                }
147
            }
148
        } else {
149
            $dir = static::getPhpUnitXmlDir();
0 ignored issues
show
Deprecated Code introduced by
The function Symfony\Bundle\Framework...ase::getPhpUnitXmlDir() has been deprecated: since 3.4 and will be removed in 4.0. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

149
            $dir = /** @scrutinizer ignore-deprecated */ static::getPhpUnitXmlDir();

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
150
        }
151
152
        $finder = new Finder();
153
        $finder->name('*TestKernel.php')->depth(0)->in($dir);
154
        $results = iterator_to_array($finder);
155
        if (!count($results)) {
156
            throw new RuntimeException('Either set KERNEL_DIR in your phpunit.xml according to https://symfony.com/doc/current/book/testing.html#your-first-functional-test or override the WebTestCase::createKernel() method.');
157
        }
158
159
        $file  = current($results);
160
        $class = $file->getBasename('.php');
161
162
        require_once $file;
163
164
        return $class;
165
    }
166
167
    private function mockServices()
168
    {
169
        $cookieHelper = $this->getMockBuilder(CookieHelper::class)
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\MockOb...ckBuilder::setMethods() has been deprecated: https://github.com/sebastianbergmann/phpunit/pull/3687 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

169
        $cookieHelper = /** @scrutinizer ignore-deprecated */ $this->getMockBuilder(CookieHelper::class)

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
170
            ->disableOriginalConstructor()
171
            ->setMethods(['setCookie', 'setCharset'])
172
            ->getMock();
173
174
        $cookieHelper->expects($this->any())
175
            ->method('setCookie');
176
177
        $this->container->set('mautic.helper.cookie', $cookieHelper);
178
179
        $this->container->set('session', new Session(new FixedMockFileSessionStorage()));
180
    }
181
182
    protected function applyMigrations()
183
    {
184
        $input  = new ArgvInput(['console', 'doctrine:migrations:version', '--add', '--all', '--no-interaction']);
185
        $output = new BufferedOutput();
186
187
        $application = new Application($this->container->get('kernel'));
0 ignored issues
show
It seems like $this->container->get('kernel') can also be of type null; however, parameter $kernel of Symfony\Bundle\Framework...lication::__construct() does only seem to accept Symfony\Component\HttpKernel\KernelInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

187
        $application = new Application(/** @scrutinizer ignore-type */ $this->container->get('kernel'));
Loading history...
188
        $application->setAutoExit(false);
189
        $application->run($input, $output);
190
    }
191
192
    protected function installDatabaseFixtures(array $classNames = [])
193
    {
194
        $this->loadFixtures($classNames);
195
    }
196
197
    /**
198
     * Use when POSTing directly to forms.
199
     *
200
     * @param string $intention
201
     *
202
     * @return string
203
     */
204
    protected function getCsrfToken($intention)
205
    {
206
        return $this->client->getContainer()->get('security.csrf.token_manager')->refreshToken($intention)->getValue();
207
    }
208
209
    /**
210
     * @return string[]
211
     */
212
    protected function createAjaxHeaders(): array
213
    {
214
        return [
215
            'HTTP_Content-Type'     => 'application/x-www-form-urlencoded; charset=UTF-8',
216
            'HTTP_X-Requested-With' => 'XMLHttpRequest',
217
            'HTTP_X-CSRF-Token'     => $this->getCsrfToken('mautic_ajax_post'),
218
        ];
219
    }
220
221
    /**
222
     * @param $name
223
     *
224
     * @return string
225
     *
226
     * @throws \Exception
227
     */
228
    protected function runCommand($name, array $params = [], Command $command = null)
229
    {
230
        $params      = array_merge(['command' => $name], $params);
231
        $kernel      = $this->container->get('kernel');
232
        $application = new Application($kernel);
233
        $application->setAutoExit(false);
234
235
        if ($command) {
236
            if ($command instanceof ContainerAwareCommand) {
237
                $command->setContainer($this->container);
238
            }
239
240
            // Register the command
241
            $application->add($command);
242
        }
243
244
        $input  = new ArrayInput($params);
245
        $output = new BufferedOutput();
246
        $application->run($input, $output);
247
248
        return $output->fetch();
249
    }
250
}
251