Skip to content
Snippets Groups Projects
Commit 61ba9554 authored by DEEPAK MISHRA's avatar DEEPAK MISHRA Committed by Ted Bowman
Browse files

Issue #3471028 by deepakkm, tedbow, akhil babu: Expand test coverage in FieldUninstallValidatorTest

parent 7b693758
No related branches found
No related tags found
1 merge request!319Issue #3471028: Add test for 'Field used in multiple entities of different types'
Pipeline #293353 failed with stages
in 9 minutes and 21 seconds
......@@ -8,8 +8,11 @@ use Drupal\Core\Database\Database;
use Drupal\Core\Extension\ModuleUninstallValidatorException;
use Drupal\experience_builder\Plugin\DataType\ComponentTreeStructure;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\KernelTests\KernelTestBase;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\Tests\experience_builder\Traits\ContribStrictConfigSchemaTestTrait;
use Drupal\Tests\experience_builder\Traits\TestDataUtilitiesTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;
......@@ -20,8 +23,6 @@ use Drupal\Tests\node\Traits\NodeCreationTrait;
*
* @todo Add extra test cases
* - Default value stores the expression unescaped(is that possible?).
* - Field used in multiple entities of different types.
* - Others?
* - Test with field that does not use dedicated storage.
*/
final class FieldTypeUninstallValidatorTest extends KernelTestBase {
......@@ -55,46 +56,117 @@ final class FieldTypeUninstallValidatorTest extends KernelTestBase {
$node = $this->createNode([
'title' => 'Test node',
'type' => 'article',
'field_xb_test' => [
'tree' => self::encodeXBData([
ComponentTreeStructure::ROOT_UUID => [
[
'uuid' => 'dynamic-static-card2df',
'component' => 'sdc_test+my-cta',
],
],
]),
'props' => self::encodeXBData([
'dynamic-static-card2df' => [
'text' => [
'sourceType' => 'dynamic',
'expression' => 'ℹ︎␜entity:node:article␝title␞␟value',
],
'href' => [
'sourceType' => 'static:field_item:link',
'value' => [
'uri' => 'https://drupal.org',
'title' => NULL,
'options' => [],
],
'expression' => 'ℹ︎link␟uri',
],
],
]),
],
'field_xb_test' => $this->getComponentTreeItemValue(TRUE),
]);
$this->assertInstanceOf(Node::class, $node);
$this->assertUninstallFailureReasons([
'Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">node</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>',
'Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">node</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>',
'Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test</em>',
]);
// Save a new revision that does not use the 'link' field.
$node->set('field_xb_test', $this->getComponentTreeItemValue(FALSE))->setNewRevision();
$node->save();
$this->assertUninstallFailureReasons([
'Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">node</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>',
'Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test</em>',
]);
// Delete the previous revision that used the 'link' field.
$storage = \Drupal::entityTypeManager()->getStorage('node');
$storage->deleteRevision(1);
$this->assertUninstallFailureReasons([
'Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test</em>',
]);
$this->updateFieldDefaultValue('node', 'article', 'field_xb_test', $this->getComponentTreeItemValue(FALSE));
$this->container->get('module_installer')->uninstall(['link']);
}
/**
* Test if the field is used in multiple entities of different types.
*/
public function testUninstallXbFieldMultipleEntityTypes(): void {
$this->container->get('module_installer')->install(['experience_builder', 'xb_test_config_node_article', 'field', 'sdc_test', 'taxonomy']);
$vocabulary = Vocabulary::create([
'vid' => 'tags',
'description' => 'Tags vocabulary',
'name' => 'Tags',
]);
$vocabulary->save();
FieldStorageConfig::create([
'entity_type' => 'taxonomy_term',
'field_name' => 'field_tag_test',
'type' => 'component_tree',
])->save();
FieldConfig::create([
'entity_type' => 'taxonomy_term',
'field_name' => 'field_tag_test',
'bundle' => 'tags',
'label' => 'Taxonomy Test Field',
'required' => TRUE,
])->setDefaultValue($this->getComponentTreeItemValue(TRUE))
->save();
$taxonomy = Term::create([
'name' => 'Tags',
'vid' => 'tags',
'field_tag_test' => $this->getComponentTreeItemValue(TRUE),
]);
$taxonomy->save();
$this->assertUninstallFailureReasons([
'Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">taxonomy_term</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>',
'Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">taxonomy_term</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>',
'Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test, field_tag_test</em>',
]);
// Save a new revision that does not use the 'link' field.
$taxonomy->set('field_tag_test', $this->getComponentTreeItemValue(FALSE))->setNewRevision();
$taxonomy->save();
$this->assertUninstallFailureReasons([
'Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">taxonomy_term</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>',
'Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test, field_tag_test</em>',
]);
// Delete the previous revision that used the 'link' field.
$storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
$storage->deleteRevision(1);
$this->updateFieldDefaultValue('taxonomy_term', 'tags', 'field_tag_test', $this->getComponentTreeItemValue(FALSE));
$this->assertUninstallFailureReasons([
'Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test</em>',
]);
$this->updateFieldDefaultValue('node', 'article', 'field_xb_test', $this->getComponentTreeItemValue(FALSE));
$this->container->get('module_installer')->uninstall(['link']);
}
private function updateFieldDefaultValue(string $entity_type, string $bundle, string $field_name, array $default_value): void {
$field_config = FieldConfig::loadByName($entity_type, $bundle, $field_name);
$this->assertInstanceOf(FieldConfig::class, $field_config);
$field_config->setDefaultValue($default_value);
$field_config->save();
}
private function assertUninstallFailureReasons(array $reasons): void {
// @todo Assert that there are no duplicated reasons in
// https://drupal.org/i/3476891.
$expected_message = 'The following reasons prevent the modules from being uninstalled: ' . implode(', ', $reasons);
try {
$this->container->get('module_installer')->uninstall(['link']);
$this->fail('Expected an exception');
}
catch (ModuleUninstallValidatorException $exception) {
// Assert exception message mentions but the content entity and the default value.
$this->assertStringContainsString('The following reasons prevent the modules from being uninstalled: Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">node</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>, Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">node</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>, Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test</em>', $exception->getMessage());
$this->assertStringContainsString($expected_message, $exception->getMessage());
}
}
$component_tree_without_link = [
private function getComponentTreeItemValue(bool $include_link): array {
$component_tree_item = [
'tree' => self::encodeXBData([
ComponentTreeStructure::ROOT_UUID => [
[
......@@ -103,51 +175,29 @@ final class FieldTypeUninstallValidatorTest extends KernelTestBase {
],
],
]),
'props' => self::encodeXBData([
'dynamic-static-card2df' => [
'text' => [
'sourceType' => 'dynamic',
'expression' => 'ℹ︎␜entity:node:article␝title␞␟value',
],
];
$props = [
'dynamic-static-card2df' => [
'text' => [
'sourceType' => 'static:field_item:string',
'value' => 'hello, world!',
'expression' => 'ℹ︎string␟value',
],
]),
],
];
// Save a new revision that does not use the 'link' field.
$node->set('field_xb_test', $component_tree_without_link)->setNewRevision();
$node->save();
try {
$this->container->get('module_installer')->uninstall(['link']);
$this->fail('Expected an exception');
}
catch (ModuleUninstallValidatorException $exception) {
// Assert exception message mentions but the content entity and the default value.
$this->assertStringContainsString('The following reasons prevent the modules from being uninstalled: Provides a field type, <em class="placeholder">link</em>, that is in use in the content of the following entities: <em class="placeholder">node</em> id=<em class="placeholder">1</em> revision=<em class="placeholder">1</em>, Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test</em>', $exception->getMessage());
}
// Delete the previous revision that used the 'link' field.
$storage = \Drupal::entityTypeManager()->getStorage('node');
$storage->deleteRevision(1);
try {
$this->container->get('module_installer')->uninstall(['link']);
$this->fail('Expected an exception');
}
catch (ModuleUninstallValidatorException $exception) {
// Assert exception message no longer mentions the content entity.
$this->assertStringContainsString('The following reasons prevent the modules from being uninstalled: Provides a field type, <em class="placeholder">link</em>, that is in use in the default value of the following fields: <em class="placeholder">field_xb_test</em>', $exception->getMessage());
if ($include_link) {
$props['dynamic-static-card2df']['href'] = [
'sourceType' => 'static:field_item:link',
'value' => [
'uri' => 'https://drupal.org',
'title' => NULL,
'options' => [],
],
'expression' => 'ℹ︎link␟uri',
];
}
// Update default value for component to not use the 'link' field.
$field_config = FieldConfig::loadByName('node', 'article', 'field_xb_test');
$this->assertInstanceOf(FieldConfig::class, $field_config);
$field_config->setDefaultValue($component_tree_without_link);
$field_config->save();
// Now since the neither the revision nor the default value contain the link
// field, the 'link' module can be uninstalled without an error.
$this->container->get('module_installer')->uninstall(['link']);
$component_tree_item['props'] = self::encodeXBData($props);
return $component_tree_item;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment