X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=web%2Fcore%2Fmodules%2Fsystem%2Ftests%2Fsrc%2FFunctional%2FEntity%2FUpdate%2FUpdateApiEntityDefinitionUpdateTest.php;fp=web%2Fcore%2Fmodules%2Fsystem%2Ftests%2Fsrc%2FFunctional%2FEntity%2FUpdate%2FUpdateApiEntityDefinitionUpdateTest.php;h=89c1d7072d78b94a820e40531fbbdfce46405fc1;hp=0000000000000000000000000000000000000000;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hpb=aea91e65e895364e460983b890e295aa5d5540a5 diff --git a/web/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php b/web/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php new file mode 100644 index 000000000..89c1d7072 --- /dev/null +++ b/web/core/modules/system/tests/src/Functional/Entity/Update/UpdateApiEntityDefinitionUpdateTest.php @@ -0,0 +1,209 @@ +entityManager = $this->container->get('entity.manager'); + $this->updatesManager = $this->container->get('entity.definition_update_manager'); + + $admin = $this->drupalCreateUser([], FALSE, TRUE); + $this->drupalLogin($admin); + } + + /** + * Tests that individual updates applied sequentially work as expected. + */ + public function testSingleUpdates() { + // Create a test entity. + $user_ids = [mt_rand(), mt_rand()]; + $entity = EntityTest::create(['name' => $this->randomString(), 'user_id' => $user_ids]); + $entity->save(); + + // Check that only a single value is stored for 'user_id'. + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 1); + $this->assertEqual($entity->user_id->target_id, $user_ids[0]); + + // Make 'user_id' multiple by applying updates. + $this->enableUpdates('entity_test', 'entity_definition_updates', 8001); + $this->applyUpdates(); + + // Ensure the 'entity_test__user_id' table got created. + $this->assertTrue(\Drupal::database()->schema()->tableExists('entity_test__user_id')); + + // Check that data was correctly migrated. + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 1); + $this->assertEqual($entity->user_id->target_id, $user_ids[0]); + + // Store multiple data and check it is correctly stored. + $entity->user_id = $user_ids; + $entity->save(); + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 2); + $this->assertEqual($entity->user_id[0]->target_id, $user_ids[0]); + $this->assertEqual($entity->user_id[1]->target_id, $user_ids[1]); + + // Make 'user_id' single again by applying updates. + $this->enableUpdates('entity_test', 'entity_definition_updates', 8002); + $this->applyUpdates(); + + // Check that data was correctly migrated/dropped. + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 1); + $this->assertEqual($entity->user_id->target_id, $user_ids[0]); + + // Check that only a single value is stored for 'user_id' again. + $entity->user_id = $user_ids; + $entity->save(); + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 1); + $this->assertEqual($entity->user_id[0]->target_id, $user_ids[0]); + } + + /** + * Tests that multiple updates applied in bulk work as expected. + */ + public function testMultipleUpdates() { + // Create a test entity. + $user_ids = [mt_rand(), mt_rand()]; + $entity = EntityTest::create(['name' => $this->randomString(), 'user_id' => $user_ids]); + $entity->save(); + + // Check that only a single value is stored for 'user_id'. + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 1); + $this->assertEqual($entity->user_id->target_id, $user_ids[0]); + + // Make 'user_id' multiple and then single again by applying updates. + $this->enableUpdates('entity_test', 'entity_definition_updates', 8002); + $this->applyUpdates(); + + // Check that data was correctly migrated back and forth. + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 1); + $this->assertEqual($entity->user_id->target_id, $user_ids[0]); + + // Check that only a single value is stored for 'user_id' again. + $entity->user_id = $user_ids; + $entity->save(); + $entity = $this->reloadEntity($entity); + $this->assertEqual(count($entity->user_id), 1); + $this->assertEqual($entity->user_id[0]->target_id, $user_ids[0]); + } + + /** + * Tests that entity updates are correctly reported in the status report page. + */ + public function testStatusReport() { + // Create a test entity. + $entity = EntityTest::create(['name' => $this->randomString(), 'user_id' => mt_rand()]); + $entity->save(); + + // Check that the status report initially displays no error. + $this->drupalGet('admin/reports/status'); + $this->assertNoRaw('Out of date'); + $this->assertNoRaw('Mismatched entity and/or field definitions'); + + // Enable an entity update and check that we have a dedicated status report + // item. + $this->container->get('state')->set('entity_test.remove_name_field', TRUE); + $this->drupalGet('admin/reports/status'); + $this->assertNoRaw('Out of date'); + $this->assertRaw('Mismatched entity and/or field definitions'); + + // Enable a db update and check that now the entity update status report + // item is no longer displayed. We assume an update function will fix the + // mismatch. + $this->enableUpdates('entity_test', 'status_report', 8001); + $this->drupalGet('admin/reports/status'); + $this->assertRaw('Out of date'); + $this->assertRaw('Mismatched entity and/or field definitions'); + + // Apply db updates and check that entity updates were not applied. + $this->applyUpdates(); + $this->drupalGet('admin/reports/status'); + $this->assertNoRaw('Out of date'); + $this->assertRaw('Mismatched entity and/or field definitions'); + + // Check that en exception would be triggered when trying to apply them with + // existing data. + $message = 'Entity updates cannot run if entity data exists.'; + try { + $this->updatesManager->applyUpdates(); + $this->fail($message); + } + catch (FieldStorageDefinitionUpdateForbiddenException $e) { + $this->pass($message); + } + + // Check the status report is the same after trying to apply updates. + $this->drupalGet('admin/reports/status'); + $this->assertNoRaw('Out of date'); + $this->assertRaw('Mismatched entity and/or field definitions'); + + // Delete entity data, enable a new update, run updates again and check that + // entity updates were not applied even when no data exists. + $entity->delete(); + $this->enableUpdates('entity_test', 'status_report', 8002); + $this->applyUpdates(); + $this->drupalGet('admin/reports/status'); + $this->assertNoRaw('Out of date'); + $this->assertRaw('Mismatched entity and/or field definitions'); + } + + /** + * Reloads the specified entity. + * + * @param \Drupal\entity_test\Entity\EntityTest $entity + * An entity object. + * + * @return \Drupal\entity_test\Entity\EntityTest + * The reloaded entity object. + */ + protected function reloadEntity(EntityTest $entity) { + $this->entityManager->useCaches(FALSE); + $this->entityManager->getStorage('entity_test')->resetCache([$entity->id()]); + return EntityTest::load($entity->id()); + } + +}