3 namespace Drupal\Tests\Core\Update;
5 use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
6 use Drupal\Core\Site\Settings;
7 use Drupal\Core\Update\UpdateRegistry;
8 use Drupal\Tests\UnitTestCase;
9 use org\bovigo\vfs\vfsStream;
12 * @coversDefaultClass \Drupal\Core\Update\UpdateRegistry
15 * Note we load code, so isolate the tests.
17 * @runTestsInSeparateProcesses
18 * @preserveGlobalState disabled
20 class UpdateRegistryTest extends UnitTestCase {
25 protected function setUp() {
29 $settings['extension_discovery_scan_tests'] = TRUE;
30 new Settings($settings);
34 * Sets up some modules with some update functions.
36 protected function setupBasicModules() {
55 function module_a_post_update_b() {
61 function module_a_post_update_a() {
71 function module_b_post_update_a() {
75 vfsStream::setup('drupal');
81 'module_a.post_update.php' => $module_a,
82 'module_a.info.yml' => $info_a
85 'module_b.post_update.php' => $module_b,
86 'module_b.info.yml' => $info_b
95 * @covers ::getPendingUpdateFunctions
97 public function testGetPendingUpdateFunctionsNoExistingUpdates() {
98 $this->setupBasicModules();
100 $key_value = $this->prophesize(KeyValueStoreInterface::class);
101 $key_value->get('existing_updates', [])->willReturn([]);
102 $key_value = $key_value->reveal();
104 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
107 ], $key_value, FALSE);
109 $this->assertEquals([
110 'module_a_post_update_a',
111 'module_a_post_update_b',
112 'module_b_post_update_a'
113 ], $update_registry->getPendingUpdateFunctions());
117 * @covers ::getPendingUpdateFunctions
119 public function testGetPendingUpdateFunctionsWithLoadedModulesButNotEnabled() {
120 $this->setupBasicModules();
122 $key_value = $this->prophesize(KeyValueStoreInterface::class);
123 $key_value->get('existing_updates', [])->willReturn([]);
124 $key_value = $key_value->reveal();
126 // Preload modules to ensure that ::getAvailableUpdateFunctions filters out
127 // not enabled modules.
128 include_once 'vfs://drupal/sites/default/modules/module_a/module_a.post_update.php';
129 include_once 'vfs://drupal/sites/default/modules/module_b/module_b.post_update.php';
131 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
133 ], $key_value, FALSE);
135 $this->assertEquals([
136 'module_a_post_update_a',
137 'module_a_post_update_b',
138 ], $update_registry->getPendingUpdateFunctions());
142 * @covers ::getPendingUpdateFunctions
144 public function testGetPendingUpdateFunctionsExistingUpdates() {
145 $this->setupBasicModules();
147 $key_value = $this->prophesize(KeyValueStoreInterface::class);
148 $key_value->get('existing_updates', [])->willReturn(['module_a_post_update_a']);
149 $key_value = $key_value->reveal();
151 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
154 ], $key_value, FALSE);
156 $this->assertEquals(array_values([
157 'module_a_post_update_b',
158 'module_b_post_update_a'
159 ]), array_values($update_registry->getPendingUpdateFunctions()));
164 * @covers ::getPendingUpdateInformation
166 public function testGetPendingUpdateInformation() {
167 $this->setupBasicModules();
169 $key_value = $this->prophesize(KeyValueStoreInterface::class);
170 $key_value->get('existing_updates', [])->willReturn([]);
171 $key_value = $key_value->reveal();
173 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
176 ], $key_value, FALSE);
179 $expected['module_a']['pending']['a'] = 'Module A update A.';
180 $expected['module_a']['pending']['b'] = 'Module A update B.';
181 $expected['module_a']['start'] = 'a';
182 $expected['module_b']['pending']['a'] = 'Module B update A.';
183 $expected['module_b']['start'] = 'a';
185 $this->assertEquals($expected, $update_registry->getPendingUpdateInformation());
189 * @covers ::getPendingUpdateInformation
191 public function testGetPendingUpdateInformationWithExistingUpdates() {
192 $this->setupBasicModules();
194 $key_value = $this->prophesize(KeyValueStoreInterface::class);
195 $key_value->get('existing_updates', [])->willReturn(['module_a_post_update_a']);
196 $key_value = $key_value->reveal();
198 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
201 ], $key_value, FALSE);
204 $expected['module_a']['pending']['b'] = 'Module A update B.';
205 $expected['module_a']['start'] = 'b';
206 $expected['module_b']['pending']['a'] = 'Module B update A.';
207 $expected['module_b']['start'] = 'a';
209 $this->assertEquals($expected, $update_registry->getPendingUpdateInformation());
213 * @covers ::getModuleUpdateFunctions
215 public function testGetModuleUpdateFunctions() {
216 $this->setupBasicModules();
217 $key_value = $this->prophesize(KeyValueStoreInterface::class)->reveal();
219 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
222 ], $key_value, FALSE);
224 $this->assertEquals(['module_a_post_update_a', 'module_a_post_update_b'], array_values($update_registry->getModuleUpdateFunctions('module_a')));
225 $this->assertEquals(['module_b_post_update_a'], array_values($update_registry->getModuleUpdateFunctions('module_b')));
229 * @covers ::registerInvokedUpdates
231 public function testRegisterInvokedUpdatesWithoutExistingUpdates() {
232 $this->setupBasicModules();
233 $key_value = $this->prophesize(KeyValueStoreInterface::class);
234 $key_value->get('existing_updates', [])
236 ->shouldBeCalledTimes(1);
237 $key_value->set('existing_updates', ['module_a_post_update_a'])
239 ->shouldBeCalledTimes(1);
240 $key_value = $key_value->reveal();
242 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
245 ], $key_value, FALSE);
246 $update_registry->registerInvokedUpdates(['module_a_post_update_a']);
250 * @covers ::registerInvokedUpdates
252 public function testRegisterInvokedUpdatesWithMultiple() {
253 $this->setupBasicModules();
254 $key_value = $this->prophesize(KeyValueStoreInterface::class);
255 $key_value->get('existing_updates', [])
257 ->shouldBeCalledTimes(1);
258 $key_value->set('existing_updates', ['module_a_post_update_a', 'module_a_post_update_b'])
260 ->shouldBeCalledTimes(1);
261 $key_value = $key_value->reveal();
263 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
266 ], $key_value, FALSE);
267 $update_registry->registerInvokedUpdates(['module_a_post_update_a', 'module_a_post_update_b']);
271 * @covers ::registerInvokedUpdates
273 public function testRegisterInvokedUpdatesWithExistingUpdates() {
274 $this->setupBasicModules();
275 $key_value = $this->prophesize(KeyValueStoreInterface::class);
276 $key_value->get('existing_updates', [])
277 ->willReturn(['module_a_post_update_b'])
278 ->shouldBeCalledTimes(1);
279 $key_value->set('existing_updates', ['module_a_post_update_b', 'module_a_post_update_a'])
281 ->shouldBeCalledTimes(1);
282 $key_value = $key_value->reveal();
284 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
287 ], $key_value, FALSE);
288 $update_registry->registerInvokedUpdates(['module_a_post_update_a']);
292 * @covers ::filterOutInvokedUpdatesByModule
294 public function testFilterOutInvokedUpdatesByModule() {
295 $this->setupBasicModules();
296 $key_value = $this->prophesize(KeyValueStoreInterface::class);
297 $key_value->get('existing_updates', [])
298 ->willReturn(['module_a_post_update_b', 'module_a_post_update_a', 'module_b_post_update_a'])
299 ->shouldBeCalledTimes(1);
300 $key_value->set('existing_updates', ['module_b_post_update_a'])
302 ->shouldBeCalledTimes(1);
303 $key_value = $key_value->reveal();
305 $update_registry = new UpdateRegistry('vfs://drupal', 'sites/default', [
308 ], $key_value, FALSE);
310 $update_registry->filterOutInvokedUpdatesByModule('module_a');