Chris@18
|
1 <?php
|
Chris@18
|
2
|
Chris@18
|
3 namespace Drupal\Tests\taxonomy\Kernel;
|
Chris@18
|
4
|
Chris@18
|
5 use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
Chris@18
|
6 use Drupal\taxonomy\Entity\Vocabulary;
|
Chris@18
|
7
|
Chris@18
|
8 /**
|
Chris@18
|
9 * Tests handling of pending revisions.
|
Chris@18
|
10 *
|
Chris@18
|
11 * @coversDefaultClass \Drupal\taxonomy\Plugin\Validation\Constraint\TaxonomyTermHierarchyConstraintValidator
|
Chris@18
|
12 *
|
Chris@18
|
13 * @group taxonomy
|
Chris@18
|
14 */
|
Chris@18
|
15 class TermHierarchyValidationTest extends EntityKernelTestBase {
|
Chris@18
|
16
|
Chris@18
|
17 /**
|
Chris@18
|
18 * {@inheritdoc}
|
Chris@18
|
19 */
|
Chris@18
|
20 public static $modules = ['taxonomy'];
|
Chris@18
|
21
|
Chris@18
|
22 /**
|
Chris@18
|
23 * {@inheritdoc}
|
Chris@18
|
24 */
|
Chris@18
|
25 protected function setUp() {
|
Chris@18
|
26 parent::setUp();
|
Chris@18
|
27
|
Chris@18
|
28 $this->installEntitySchema('taxonomy_term');
|
Chris@18
|
29 }
|
Chris@18
|
30
|
Chris@18
|
31 /**
|
Chris@18
|
32 * Tests the term hierarchy validation with re-parenting in pending revisions.
|
Chris@18
|
33 */
|
Chris@18
|
34 public function testTermHierarchyValidation() {
|
Chris@18
|
35 $vocabulary_id = mb_strtolower($this->randomMachineName());
|
Chris@18
|
36 $vocabulary = Vocabulary::create([
|
Chris@18
|
37 'name' => $vocabulary_id,
|
Chris@18
|
38 'vid' => $vocabulary_id,
|
Chris@18
|
39 ]);
|
Chris@18
|
40 $vocabulary->save();
|
Chris@18
|
41
|
Chris@18
|
42 // Create a simple hierarchy in the vocabulary, a root term and three parent
|
Chris@18
|
43 // terms.
|
Chris@18
|
44 /** @var \Drupal\Core\Entity\RevisionableStorageInterface $term_storage */
|
Chris@18
|
45 $term_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
|
Chris@18
|
46 $root = $term_storage->create([
|
Chris@18
|
47 'name' => $this->randomMachineName(),
|
Chris@18
|
48 'vid' => $vocabulary_id,
|
Chris@18
|
49 ]);
|
Chris@18
|
50 $root->save();
|
Chris@18
|
51 $parent1 = $term_storage->create([
|
Chris@18
|
52 'name' => $this->randomMachineName(),
|
Chris@18
|
53 'vid' => $vocabulary_id,
|
Chris@18
|
54 'parent' => $root->id(),
|
Chris@18
|
55 ]);
|
Chris@18
|
56 $parent1->save();
|
Chris@18
|
57 $parent2 = $term_storage->create([
|
Chris@18
|
58 'name' => $this->randomMachineName(),
|
Chris@18
|
59 'vid' => $vocabulary_id,
|
Chris@18
|
60 'parent' => $root->id(),
|
Chris@18
|
61 ]);
|
Chris@18
|
62 $parent2->save();
|
Chris@18
|
63 $parent3 = $term_storage->create([
|
Chris@18
|
64 'name' => $this->randomMachineName(),
|
Chris@18
|
65 'vid' => $vocabulary_id,
|
Chris@18
|
66 'parent' => $root->id(),
|
Chris@18
|
67 ]);
|
Chris@18
|
68 $parent3->save();
|
Chris@18
|
69
|
Chris@18
|
70 // Create a child term and assign one of the parents above.
|
Chris@18
|
71 $child1 = $term_storage->create([
|
Chris@18
|
72 'name' => $this->randomMachineName(),
|
Chris@18
|
73 'vid' => $vocabulary_id,
|
Chris@18
|
74 'parent' => $parent1->id(),
|
Chris@18
|
75 ]);
|
Chris@18
|
76 $violations = $child1->validate();
|
Chris@18
|
77 $this->assertEmpty($violations);
|
Chris@18
|
78 $child1->save();
|
Chris@18
|
79
|
Chris@18
|
80 $validation_message = 'You can only change the hierarchy for the <em>published</em> version of this term.';
|
Chris@18
|
81
|
Chris@18
|
82 // Add a pending revision without changing the term parent.
|
Chris@18
|
83 $pending_name = $this->randomMachineName();
|
Chris@18
|
84 $child_pending = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
85 $child_pending->name = $pending_name;
|
Chris@18
|
86 $violations = $child_pending->validate();
|
Chris@18
|
87 $this->assertEmpty($violations);
|
Chris@18
|
88
|
Chris@18
|
89 // Add a pending revision and change the parent.
|
Chris@18
|
90 $child_pending = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
91 $child_pending->parent = $parent2;
|
Chris@18
|
92 $violations = $child_pending->validate();
|
Chris@18
|
93 $this->assertCount(1, $violations);
|
Chris@18
|
94 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
95 $this->assertEquals('parent', $violations[0]->getPropertyPath());
|
Chris@18
|
96
|
Chris@18
|
97 // Add a pending revision and add a new parent.
|
Chris@18
|
98 $child_pending = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
99 $child_pending->parent[0] = $parent1;
|
Chris@18
|
100 $child_pending->parent[1] = $parent3;
|
Chris@18
|
101 $violations = $child_pending->validate();
|
Chris@18
|
102 $this->assertCount(1, $violations);
|
Chris@18
|
103 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
104 $this->assertEquals('parent', $violations[0]->getPropertyPath());
|
Chris@18
|
105
|
Chris@18
|
106 // Add a pending revision and use the root term as a parent.
|
Chris@18
|
107 $child_pending = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
108 $child_pending->parent[0] = $root;
|
Chris@18
|
109 $violations = $child_pending->validate();
|
Chris@18
|
110 $this->assertCount(1, $violations);
|
Chris@18
|
111 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
112 $this->assertEquals('parent', $violations[0]->getPropertyPath());
|
Chris@18
|
113
|
Chris@18
|
114 // Add a pending revision and remove the parent.
|
Chris@18
|
115 $child_pending = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
116 $child_pending->parent[0] = NULL;
|
Chris@18
|
117 $violations = $child_pending->validate();
|
Chris@18
|
118 $this->assertCount(1, $violations);
|
Chris@18
|
119 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
120 $this->assertEquals('parent', $violations[0]->getPropertyPath());
|
Chris@18
|
121
|
Chris@18
|
122 // Add a pending revision and change the weight.
|
Chris@18
|
123 $child_pending = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
124 $child_pending->weight = 10;
|
Chris@18
|
125 $violations = $child_pending->validate();
|
Chris@18
|
126 $this->assertCount(1, $violations);
|
Chris@18
|
127 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
128 $this->assertEquals('weight', $violations[0]->getPropertyPath());
|
Chris@18
|
129
|
Chris@18
|
130 // Add a pending revision and change both the parent and the weight.
|
Chris@18
|
131 $child_pending = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
132 $child_pending->parent = $parent2;
|
Chris@18
|
133 $child_pending->weight = 10;
|
Chris@18
|
134 $violations = $child_pending->validate();
|
Chris@18
|
135 $this->assertCount(2, $violations);
|
Chris@18
|
136 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
137 $this->assertEquals($validation_message, $violations[1]->getMessage());
|
Chris@18
|
138 $this->assertEquals('parent', $violations[0]->getPropertyPath());
|
Chris@18
|
139 $this->assertEquals('weight', $violations[1]->getPropertyPath());
|
Chris@18
|
140
|
Chris@18
|
141 // Add a published revision and change the parent.
|
Chris@18
|
142 $child_pending = $term_storage->createRevision($child1, TRUE);
|
Chris@18
|
143 $child_pending->parent[0] = $parent2;
|
Chris@18
|
144 $violations = $child_pending->validate();
|
Chris@18
|
145 $this->assertEmpty($violations);
|
Chris@18
|
146
|
Chris@18
|
147 // Add a new term as a third-level child.
|
Chris@18
|
148 // The taxonomy tree structure ends up as follows:
|
Chris@18
|
149 // root
|
Chris@18
|
150 // - parent1
|
Chris@18
|
151 // - parent2
|
Chris@18
|
152 // -- child1 <- this will be a term with a pending revision
|
Chris@18
|
153 // --- child2
|
Chris@18
|
154 // - parent3
|
Chris@18
|
155 $child2 = $term_storage->create([
|
Chris@18
|
156 'name' => $this->randomMachineName(),
|
Chris@18
|
157 'vid' => $vocabulary_id,
|
Chris@18
|
158 'parent' => $child1->id(),
|
Chris@18
|
159 ]);
|
Chris@18
|
160 $child2->save();
|
Chris@18
|
161
|
Chris@18
|
162 // Change 'child1' to be a pending revision.
|
Chris@18
|
163 $child1 = $term_storage->createRevision($child1, FALSE);
|
Chris@18
|
164 $child1->save();
|
Chris@18
|
165
|
Chris@18
|
166 // Check that a child of a pending term can not be re-parented.
|
Chris@18
|
167 $child2_pending = $term_storage->createRevision($child2, FALSE);
|
Chris@18
|
168 $child2_pending->parent = $parent3;
|
Chris@18
|
169 $violations = $child2_pending->validate();
|
Chris@18
|
170 $this->assertCount(1, $violations);
|
Chris@18
|
171 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
172 $this->assertEquals('parent', $violations[0]->getPropertyPath());
|
Chris@18
|
173
|
Chris@18
|
174 // Check that another term which has a pending revision can not moved under
|
Chris@18
|
175 // another term which has pending revision.
|
Chris@18
|
176 $parent3_pending = $term_storage->createRevision($parent3, FALSE);
|
Chris@18
|
177 $parent3_pending->parent = $child1;
|
Chris@18
|
178 $violations = $parent3_pending->validate();
|
Chris@18
|
179 $this->assertCount(1, $violations);
|
Chris@18
|
180 $this->assertEquals($validation_message, $violations[0]->getMessage());
|
Chris@18
|
181 $this->assertEquals('parent', $violations[0]->getPropertyPath());
|
Chris@18
|
182
|
Chris@18
|
183 // Check that a new term can be created under a term that has a pending
|
Chris@18
|
184 // revision.
|
Chris@18
|
185 $child3 = $term_storage->create([
|
Chris@18
|
186 'name' => $this->randomMachineName(),
|
Chris@18
|
187 'vid' => $vocabulary_id,
|
Chris@18
|
188 'parent' => $child1->id(),
|
Chris@18
|
189 ]);
|
Chris@18
|
190 $violations = $child3->validate();
|
Chris@18
|
191 $this->assertEmpty($violations);
|
Chris@18
|
192 }
|
Chris@18
|
193
|
Chris@18
|
194 }
|