Security update for Core, with self-updated composer
[yaffs-website] / web / core / tests / Drupal / Tests / UnitTestCase.php
1 <?php
2
3 namespace Drupal\Tests;
4
5 use Drupal\Component\FileCache\FileCacheFactory;
6 use Drupal\Component\Utility\Random;
7 use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
8 use Drupal\Core\DependencyInjection\ContainerBuilder;
9 use Drupal\Core\StringTranslation\TranslatableMarkup;
10 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
11 use PHPUnit\Framework\TestCase;
12
13 /**
14  * Provides a base class and helpers for Drupal unit tests.
15  *
16  * @ingroup testing
17  */
18 abstract class UnitTestCase extends TestCase {
19
20   use PhpunitCompatibilityTrait;
21
22   /**
23    * The random generator.
24    *
25    * @var \Drupal\Component\Utility\Random
26    */
27   protected $randomGenerator;
28
29   /**
30    * The app root.
31    *
32    * @var string
33    */
34   protected $root;
35
36   /**
37    * {@inheritdoc}
38    */
39   protected function setUp() {
40     parent::setUp();
41     // Ensure that an instantiated container in the global state of \Drupal from
42     // a previous test does not leak into this test.
43     \Drupal::unsetContainer();
44
45     // Ensure that the NullFileCache implementation is used for the FileCache as
46     // unit tests should not be relying on caches implicitly.
47     FileCacheFactory::setConfiguration([FileCacheFactory::DISABLE_CACHE => TRUE]);
48     // Ensure that FileCacheFactory has a prefix.
49     FileCacheFactory::setPrefix('prefix');
50
51     $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
52   }
53
54   /**
55    * Generates a unique random string containing letters and numbers.
56    *
57    * @param int $length
58    *   Length of random string to generate.
59    *
60    * @return string
61    *   Randomly generated unique string.
62    *
63    * @see \Drupal\Component\Utility\Random::name()
64    */
65   public function randomMachineName($length = 8) {
66     return $this->getRandomGenerator()->name($length, TRUE);
67   }
68
69   /**
70    * Gets the random generator for the utility methods.
71    *
72    * @return \Drupal\Component\Utility\Random
73    *   The random generator
74    */
75   protected function getRandomGenerator() {
76     if (!is_object($this->randomGenerator)) {
77       $this->randomGenerator = new Random();
78     }
79     return $this->randomGenerator;
80   }
81
82   /**
83    * Asserts if two arrays are equal by sorting them first.
84    *
85    * @param array $expected
86    * @param array $actual
87    * @param string $message
88    */
89   protected function assertArrayEquals(array $expected, array $actual, $message = NULL) {
90     ksort($expected);
91     ksort($actual);
92     $this->assertEquals($expected, $actual, $message);
93   }
94
95   /**
96    * Returns a stub config factory that behaves according to the passed in array.
97    *
98    * Use this to generate a config factory that will return the desired values
99    * for the given config names.
100    *
101    * @param array $configs
102    *   An associative array of configuration settings whose keys are configuration
103    *   object names and whose values are key => value arrays for the configuration
104    *   object in question. Defaults to an empty array.
105    *
106    * @return \PHPUnit_Framework_MockObject_MockBuilder
107    *   A MockBuilder object for the ConfigFactory with the desired return values.
108    */
109   public function getConfigFactoryStub(array $configs = []) {
110     $config_get_map = [];
111     $config_editable_map = [];
112     // Construct the desired configuration object stubs, each with its own
113     // desired return map.
114     foreach ($configs as $config_name => $config_values) {
115       $map = [];
116       foreach ($config_values as $key => $value) {
117         $map[] = [$key, $value];
118       }
119       // Also allow to pass in no argument.
120       $map[] = ['', $config_values];
121
122       $immutable_config_object = $this->getMockBuilder('Drupal\Core\Config\ImmutableConfig')
123         ->disableOriginalConstructor()
124         ->getMock();
125       $immutable_config_object->expects($this->any())
126         ->method('get')
127         ->will($this->returnValueMap($map));
128       $config_get_map[] = [$config_name, $immutable_config_object];
129
130       $mutable_config_object = $this->getMockBuilder('Drupal\Core\Config\Config')
131         ->disableOriginalConstructor()
132         ->getMock();
133       $mutable_config_object->expects($this->any())
134         ->method('get')
135         ->will($this->returnValueMap($map));
136       $config_editable_map[] = [$config_name, $mutable_config_object];
137     }
138     // Construct a config factory with the array of configuration object stubs
139     // as its return map.
140     $config_factory = $this->createMock('Drupal\Core\Config\ConfigFactoryInterface');
141     $config_factory->expects($this->any())
142       ->method('get')
143       ->will($this->returnValueMap($config_get_map));
144     $config_factory->expects($this->any())
145       ->method('getEditable')
146       ->will($this->returnValueMap($config_editable_map));
147     return $config_factory;
148   }
149
150   /**
151    * Returns a stub config storage that returns the supplied configuration.
152    *
153    * @param array $configs
154    *   An associative array of configuration settings whose keys are
155    *   configuration object names and whose values are key => value arrays
156    *   for the configuration object in question.
157    *
158    * @return \Drupal\Core\Config\StorageInterface
159    *   A mocked config storage.
160    */
161   public function getConfigStorageStub(array $configs) {
162     $config_storage = $this->createMock('Drupal\Core\Config\NullStorage');
163     $config_storage->expects($this->any())
164       ->method('listAll')
165       ->will($this->returnValue(array_keys($configs)));
166
167     foreach ($configs as $name => $config) {
168       $config_storage->expects($this->any())
169         ->method('read')
170         ->with($this->equalTo($name))
171         ->will($this->returnValue($config));
172     }
173     return $config_storage;
174   }
175
176   /**
177    * Mocks a block with a block plugin.
178    *
179    * @param string $machine_name
180    *   The machine name of the block plugin.
181    *
182    * @return \Drupal\block\BlockInterface|\PHPUnit_Framework_MockObject_MockObject
183    *   The mocked block.
184    */
185   protected function getBlockMockWithMachineName($machine_name) {
186     $plugin = $this->getMockBuilder('Drupal\Core\Block\BlockBase')
187       ->disableOriginalConstructor()
188       ->getMock();
189     $plugin->expects($this->any())
190       ->method('getMachineNameSuggestion')
191       ->will($this->returnValue($machine_name));
192
193     $block = $this->getMockBuilder('Drupal\block\Entity\Block')
194       ->disableOriginalConstructor()
195       ->getMock();
196     $block->expects($this->any())
197       ->method('getPlugin')
198       ->will($this->returnValue($plugin));
199     return $block;
200   }
201
202   /**
203    * Returns a stub translation manager that just returns the passed string.
204    *
205    * @return \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\StringTranslation\TranslationInterface
206    *   A mock translation object.
207    */
208   public function getStringTranslationStub() {
209     $translation = $this->createMock('Drupal\Core\StringTranslation\TranslationInterface');
210     $translation->expects($this->any())
211       ->method('translate')
212       ->willReturnCallback(function ($string, array $args = [], array $options = []) use ($translation) {
213         return new TranslatableMarkup($string, $args, $options, $translation);
214       });
215     $translation->expects($this->any())
216       ->method('translateString')
217       ->willReturnCallback(function (TranslatableMarkup $wrapper) {
218         return $wrapper->getUntranslatedString();
219       });
220     $translation->expects($this->any())
221       ->method('formatPlural')
222       ->willReturnCallback(function ($count, $singular, $plural, array $args = [], array $options = []) use ($translation) {
223         $wrapper = new PluralTranslatableMarkup($count, $singular, $plural, $args, $options, $translation);
224         return $wrapper;
225       });
226     return $translation;
227   }
228
229   /**
230    * Sets up a container with a cache tags invalidator.
231    *
232    * @param \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cache_tags_validator
233    *   The cache tags invalidator.
234    *
235    * @return \Symfony\Component\DependencyInjection\ContainerInterface|\PHPUnit_Framework_MockObject_MockObject
236    *   The container with the cache tags invalidator service.
237    */
238   protected function getContainerWithCacheTagsInvalidator(CacheTagsInvalidatorInterface $cache_tags_validator) {
239     $container = $this->createMock('Symfony\Component\DependencyInjection\ContainerInterface');
240     $container->expects($this->any())
241       ->method('get')
242       ->with('cache_tags.invalidator')
243       ->will($this->returnValue($cache_tags_validator));
244
245     \Drupal::setContainer($container);
246     return $container;
247   }
248
249   /**
250    * Returns a stub class resolver.
251    *
252    * @return \Drupal\Core\DependencyInjection\ClassResolverInterface|\PHPUnit_Framework_MockObject_MockObject
253    *   The class resolver stub.
254    */
255   protected function getClassResolverStub() {
256     $class_resolver = $this->createMock('Drupal\Core\DependencyInjection\ClassResolverInterface');
257     $class_resolver->expects($this->any())
258       ->method('getInstanceFromDefinition')
259       ->will($this->returnCallback(function ($class) {
260         if (is_subclass_of($class, 'Drupal\Core\DependencyInjection\ContainerInjectionInterface')) {
261           return $class::create(new ContainerBuilder());
262         }
263         else {
264           return new $class();
265         }
266       }));
267     return $class_resolver;
268   }
269
270 }