Pull merge.
[yaffs-website] / web / core / modules / path / tests / src / Functional / PathContentModerationTest.php
1 <?php
2
3 namespace Drupal\Tests\path\Functional;
4
5 use Drupal\language\Entity\ConfigurableLanguage;
6 use Drupal\Tests\BrowserTestBase;
7 use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
8
9 /**
10  * Tests path aliases with Content Moderation.
11  *
12  * @group content_moderation
13  * @group path
14  */
15 class PathContentModerationTest extends BrowserTestBase {
16
17   use ContentModerationTestTrait;
18
19   /**
20    * Modules to install.
21    *
22    * @var array
23    */
24   public static $modules = [
25     'node',
26     'path',
27     'content_moderation',
28     'content_translation',
29   ];
30
31   /**
32    * {@inheritdoc}
33    */
34   protected function setUp() {
35     parent::setUp();
36     ConfigurableLanguage::createFromLangcode('fr')->save();
37     $this->rebuildContainer();
38
39     // Created a content type.
40     $this->drupalCreateContentType([
41       'name' => 'moderated',
42       'type' => 'moderated',
43     ]);
44
45     // Set the content type as moderated.
46     $workflow = $this->createEditorialWorkflow();
47     $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated');
48     $workflow->save();
49
50     $this->drupalLogin($this->rootUser);
51
52     // Enable URL language detection and selection.
53     $edit = ['language_interface[enabled][language-url]' => 1];
54     $this->drupalPostForm('admin/config/regional/language/detection', $edit, 'Save settings');
55
56     // Enable translation for moderated node.
57     $edit = [
58       'entity_types[node]' => 1,
59       'settings[node][moderated][translatable]' => 1,
60       'settings[node][moderated][fields][path]' => 1,
61       'settings[node][moderated][fields][body]' => 1,
62       'settings[node][moderated][settings][language][language_alterable]' => 1,
63     ];
64     $this->drupalPostForm('admin/config/regional/content-language', $edit, 'Save configuration');
65     \Drupal::entityTypeManager()->clearCachedDefinitions();
66   }
67
68   /**
69    * Tests node path aliases on a moderated content type.
70    */
71   public function testNodePathAlias() {
72     // Create some moderated content with a path alias.
73     $this->drupalGet('node/add/moderated');
74     $this->assertSession()->fieldValueEquals('path[0][alias]', '');
75     $this->drupalPostForm(NULL, [
76       'title[0][value]' => 'moderated content',
77       'path[0][alias]' => '/moderated-content',
78       'moderation_state[0][state]' => 'published',
79     ], t('Save'));
80     $node = $this->getNodeByTitle('moderated content');
81
82     // Add a pending revision with the same alias.
83     $this->drupalGet('node/' . $node->id() . '/edit');
84     $this->assertSession()->fieldValueEquals('path[0][alias]', '/moderated-content');
85     $this->drupalPostForm(NULL, [
86       'title[0][value]' => 'pending revision',
87       'path[0][alias]' => '/moderated-content',
88       'moderation_state[0][state]' => 'draft',
89     ], t('Save'));
90     $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.');
91
92     // Create some moderated content with no path alias.
93     $this->drupalGet('node/add/moderated');
94     $this->assertSession()->fieldValueEquals('path[0][alias]', '');
95     $this->drupalPostForm(NULL, [
96       'title[0][value]' => 'moderated content 2',
97       'path[0][alias]' => '',
98       'moderation_state[0][state]' => 'published',
99     ], t('Save'));
100     $node = $this->getNodeByTitle('moderated content 2');
101
102     // Add a pending revision with a new alias.
103     $this->drupalGet('node/' . $node->id() . '/edit');
104     $this->assertSession()->fieldValueEquals('path[0][alias]', '');
105     $this->drupalPostForm(NULL, [
106       'title[0][value]' => 'pending revision',
107       'path[0][alias]' => '/pending-revision',
108       'moderation_state[0][state]' => 'draft',
109     ], t('Save'));
110     $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.');
111
112     // Create some moderated content with no path alias.
113     $this->drupalGet('node/add/moderated');
114     $this->assertSession()->fieldValueEquals('path[0][alias]', '');
115     $this->drupalPostForm(NULL, [
116       'title[0][value]' => 'moderated content 3',
117       'path[0][alias]' => '',
118       'moderation_state[0][state]' => 'published',
119     ], t('Save'));
120     $node = $this->getNodeByTitle('moderated content 3');
121
122     // Add a pending revision with no path alias.
123     $this->drupalGet('node/' . $node->id() . '/edit');
124     $this->assertSession()->fieldValueEquals('path[0][alias]', '');
125     $this->drupalPostForm(NULL, [
126       'title[0][value]' => 'pending revision',
127       'path[0][alias]' => '',
128       'moderation_state[0][state]' => 'draft',
129     ], t('Save'));
130     $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.');
131   }
132
133   /**
134    * Tests that translated and moderated node can get new draft revision.
135    */
136   public function testTranslatedModeratedNodeAlias() {
137     // Create one node with a random alias.
138     $default_node = $this->drupalCreateNode([
139       'type' => 'moderated',
140       'langcode' => 'en',
141       'moderation_state' => 'published',
142       'path' => '/' . $this->randomMachineName(),
143     ]);
144
145     // Add published translation with another alias.
146     $this->drupalGet('node/' . $default_node->id());
147     $this->drupalGet('node/' . $default_node->id() . '/translations');
148     $this->clickLink('Add');
149     $edit_translation = [
150       'body[0][value]' => $this->randomMachineName(),
151       'moderation_state[0][state]' => 'published',
152       'path[0][alias]' => '/' . $this->randomMachineName(),
153     ];
154     $this->drupalPostForm(NULL, $edit_translation, 'Save (this translation)');
155     // Confirm that the alias works.
156     $this->drupalGet('fr' . $edit_translation['path[0][alias]']);
157     $this->assertSession()->pageTextContains($edit_translation['body[0][value]']);
158
159     $default_path = $default_node->path->alias;
160     $translation_path = 'fr' . $edit_translation['path[0][alias]'];
161
162     $this->assertPathsAreAccessible([$default_path, $translation_path]);
163
164     // Try to create new draft revision for translation with a new path alias.
165     $edit_new_translation_draft_with_alias = [
166       'moderation_state[0][state]' => 'draft',
167       'path[0][alias]' => '/' . $this->randomMachineName(),
168     ];
169     $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_with_alias, 'Save (this translation)');
170     // Confirm the expected error.
171     $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.');
172
173     // Create new draft revision for translation without changing path alias.
174     $edit_new_translation_draft = [
175       'body[0][value]' => $this->randomMachineName(),
176       'moderation_state[0][state]' => 'draft',
177     ];
178     $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft, t('Save (this translation)'));
179     // Confirm that the new draft revision was created.
180     $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.');
181     $this->assertSession()->pageTextContains($edit_new_translation_draft['body[0][value]']);
182     $this->assertPathsAreAccessible([$default_path, $translation_path]);
183
184     // Try to create a new draft revision for translation with path alias from
185     // the original language's default revision.
186     $edit_new_translation_draft_with_defaults_alias = [
187       'moderation_state[0][state]' => 'draft',
188       'path[0][alias]' => $default_node->path->alias,
189     ];
190     $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_with_defaults_alias, 'Save (this translation)');
191     // Verify the expected error.
192     $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.');
193
194     // Try to create new draft revision for translation with deleted (empty)
195     // path alias.
196     $edit_new_translation_draft_empty_alias = [
197       'body[0][value]' => $this->randomMachineName(),
198       'moderation_state[0][state]' => 'draft',
199       'path[0][alias]' => '',
200     ];
201     $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_empty_alias, 'Save (this translation)');
202     // Confirm the expected error.
203     $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.');
204
205     // Create new default (published) revision for translation with new path
206     // alias.
207     $edit_new_translation = [
208       'body[0][value]' => $this->randomMachineName(),
209       'moderation_state[0][state]' => 'published',
210       'path[0][alias]' => '/' . $this->randomMachineName(),
211     ];
212     $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation, 'Save (this translation)');
213     // Confirm that the new published revision was created.
214     $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.');
215     $this->assertSession()->pageTextContains($edit_new_translation['body[0][value]']);
216     $this->assertSession()->addressEquals('fr' . $edit_new_translation['path[0][alias]']);
217     $this->assertPathsAreAccessible([$default_path]);
218   }
219
220   /**
221    * Helper callback to verify paths are responding with status 200.
222    *
223    * @param string[] $paths
224    *   An array of paths to check for.
225    */
226   public function assertPathsAreAccessible(array $paths) {
227     foreach ($paths as $path) {
228       $this->drupalGet($path);
229       $this->assertSession()->statusCodeEquals(200);
230     }
231   }
232
233 }