Chris@0: save(); Chris@17: $this->rebuildContainer(); Chris@0: Chris@0: // Created a content type. Chris@17: $this->drupalCreateContentType([ Chris@17: 'name' => 'moderated', Chris@17: 'type' => 'moderated', Chris@17: ]); Chris@0: Chris@0: // Set the content type as moderated. Chris@17: $workflow = $this->createEditorialWorkflow(); Chris@0: $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated'); Chris@0: $workflow->save(); Chris@0: Chris@0: $this->drupalLogin($this->rootUser); Chris@17: Chris@17: // Enable URL language detection and selection. Chris@17: $edit = ['language_interface[enabled][language-url]' => 1]; Chris@17: $this->drupalPostForm('admin/config/regional/language/detection', $edit, 'Save settings'); Chris@17: Chris@17: // Enable translation for moderated node. Chris@17: $edit = [ Chris@17: 'entity_types[node]' => 1, Chris@17: 'settings[node][moderated][translatable]' => 1, Chris@17: 'settings[node][moderated][fields][path]' => 1, Chris@17: 'settings[node][moderated][fields][body]' => 1, Chris@17: 'settings[node][moderated][settings][language][language_alterable]' => 1, Chris@17: ]; Chris@17: $this->drupalPostForm('admin/config/regional/content-language', $edit, 'Save configuration'); Chris@17: \Drupal::entityTypeManager()->clearCachedDefinitions(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Tests node path aliases on a moderated content type. Chris@0: */ Chris@0: public function testNodePathAlias() { Chris@0: // Create some moderated content with a path alias. Chris@0: $this->drupalGet('node/add/moderated'); Chris@0: $this->assertSession()->fieldValueEquals('path[0][alias]', ''); Chris@0: $this->drupalPostForm(NULL, [ Chris@0: 'title[0][value]' => 'moderated content', Chris@0: 'path[0][alias]' => '/moderated-content', Chris@0: 'moderation_state[0][state]' => 'published', Chris@0: ], t('Save')); Chris@0: $node = $this->getNodeByTitle('moderated content'); Chris@0: Chris@0: // Add a pending revision with the same alias. Chris@0: $this->drupalGet('node/' . $node->id() . '/edit'); Chris@0: $this->assertSession()->fieldValueEquals('path[0][alias]', '/moderated-content'); Chris@0: $this->drupalPostForm(NULL, [ Chris@0: 'title[0][value]' => 'pending revision', Chris@0: 'path[0][alias]' => '/moderated-content', Chris@0: 'moderation_state[0][state]' => 'draft', Chris@0: ], t('Save')); Chris@0: $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.'); Chris@0: Chris@0: // Create some moderated content with no path alias. Chris@0: $this->drupalGet('node/add/moderated'); Chris@0: $this->assertSession()->fieldValueEquals('path[0][alias]', ''); Chris@0: $this->drupalPostForm(NULL, [ Chris@0: 'title[0][value]' => 'moderated content 2', Chris@0: 'path[0][alias]' => '', Chris@0: 'moderation_state[0][state]' => 'published', Chris@0: ], t('Save')); Chris@0: $node = $this->getNodeByTitle('moderated content 2'); Chris@0: Chris@0: // Add a pending revision with a new alias. Chris@0: $this->drupalGet('node/' . $node->id() . '/edit'); Chris@0: $this->assertSession()->fieldValueEquals('path[0][alias]', ''); Chris@0: $this->drupalPostForm(NULL, [ Chris@0: 'title[0][value]' => 'pending revision', Chris@0: 'path[0][alias]' => '/pending-revision', Chris@0: 'moderation_state[0][state]' => 'draft', Chris@0: ], t('Save')); Chris@0: $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.'); Chris@0: Chris@0: // Create some moderated content with no path alias. Chris@0: $this->drupalGet('node/add/moderated'); Chris@0: $this->assertSession()->fieldValueEquals('path[0][alias]', ''); Chris@0: $this->drupalPostForm(NULL, [ Chris@0: 'title[0][value]' => 'moderated content 3', Chris@0: 'path[0][alias]' => '', Chris@0: 'moderation_state[0][state]' => 'published', Chris@0: ], t('Save')); Chris@0: $node = $this->getNodeByTitle('moderated content 3'); Chris@0: Chris@0: // Add a pending revision with no path alias. Chris@0: $this->drupalGet('node/' . $node->id() . '/edit'); Chris@0: $this->assertSession()->fieldValueEquals('path[0][alias]', ''); Chris@0: $this->drupalPostForm(NULL, [ Chris@0: 'title[0][value]' => 'pending revision', Chris@0: 'path[0][alias]' => '', Chris@0: 'moderation_state[0][state]' => 'draft', Chris@0: ], t('Save')); Chris@0: $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.'); Chris@0: } Chris@0: Chris@17: /** Chris@17: * Tests that translated and moderated node can get new draft revision. Chris@17: */ Chris@17: public function testTranslatedModeratedNodeAlias() { Chris@17: // Create one node with a random alias. Chris@17: $default_node = $this->drupalCreateNode([ Chris@17: 'type' => 'moderated', Chris@17: 'langcode' => 'en', Chris@17: 'moderation_state' => 'published', Chris@17: 'path' => '/' . $this->randomMachineName(), Chris@17: ]); Chris@17: Chris@17: // Add published translation with another alias. Chris@17: $this->drupalGet('node/' . $default_node->id()); Chris@17: $this->drupalGet('node/' . $default_node->id() . '/translations'); Chris@17: $this->clickLink('Add'); Chris@17: $edit_translation = [ Chris@17: 'body[0][value]' => $this->randomMachineName(), Chris@17: 'moderation_state[0][state]' => 'published', Chris@17: 'path[0][alias]' => '/' . $this->randomMachineName(), Chris@17: ]; Chris@17: $this->drupalPostForm(NULL, $edit_translation, 'Save (this translation)'); Chris@17: // Confirm that the alias works. Chris@17: $this->drupalGet('fr' . $edit_translation['path[0][alias]']); Chris@17: $this->assertSession()->pageTextContains($edit_translation['body[0][value]']); Chris@17: Chris@17: $default_path = $default_node->path->alias; Chris@17: $translation_path = 'fr' . $edit_translation['path[0][alias]']; Chris@17: Chris@17: $this->assertPathsAreAccessible([$default_path, $translation_path]); Chris@17: Chris@17: // Try to create new draft revision for translation with a new path alias. Chris@17: $edit_new_translation_draft_with_alias = [ Chris@17: 'moderation_state[0][state]' => 'draft', Chris@17: 'path[0][alias]' => '/' . $this->randomMachineName(), Chris@17: ]; Chris@17: $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_with_alias, 'Save (this translation)'); Chris@17: // Confirm the expected error. Chris@17: $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.'); Chris@17: Chris@17: // Create new draft revision for translation without changing path alias. Chris@17: $edit_new_translation_draft = [ Chris@17: 'body[0][value]' => $this->randomMachineName(), Chris@17: 'moderation_state[0][state]' => 'draft', Chris@17: ]; Chris@17: $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft, t('Save (this translation)')); Chris@17: // Confirm that the new draft revision was created. Chris@17: $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.'); Chris@17: $this->assertSession()->pageTextContains($edit_new_translation_draft['body[0][value]']); Chris@17: $this->assertPathsAreAccessible([$default_path, $translation_path]); Chris@17: Chris@17: // Try to create a new draft revision for translation with path alias from Chris@17: // the original language's default revision. Chris@17: $edit_new_translation_draft_with_defaults_alias = [ Chris@17: 'moderation_state[0][state]' => 'draft', Chris@17: 'path[0][alias]' => $default_node->path->alias, Chris@17: ]; Chris@17: $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_with_defaults_alias, 'Save (this translation)'); Chris@17: // Verify the expected error. Chris@17: $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.'); Chris@17: Chris@17: // Try to create new draft revision for translation with deleted (empty) Chris@17: // path alias. Chris@17: $edit_new_translation_draft_empty_alias = [ Chris@17: 'body[0][value]' => $this->randomMachineName(), Chris@17: 'moderation_state[0][state]' => 'draft', Chris@17: 'path[0][alias]' => '', Chris@17: ]; Chris@17: $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation_draft_empty_alias, 'Save (this translation)'); Chris@17: // Confirm the expected error. Chris@17: $this->assertSession()->pageTextContains('You can only change the URL alias for the published version of this content.'); Chris@17: Chris@17: // Create new default (published) revision for translation with new path Chris@17: // alias. Chris@17: $edit_new_translation = [ Chris@17: 'body[0][value]' => $this->randomMachineName(), Chris@17: 'moderation_state[0][state]' => 'published', Chris@17: 'path[0][alias]' => '/' . $this->randomMachineName(), Chris@17: ]; Chris@17: $this->drupalPostForm('fr/node/' . $default_node->id() . '/edit', $edit_new_translation, 'Save (this translation)'); Chris@17: // Confirm that the new published revision was created. Chris@17: $this->assertSession()->pageTextNotContains('You can only change the URL alias for the published version of this content.'); Chris@17: $this->assertSession()->pageTextContains($edit_new_translation['body[0][value]']); Chris@17: $this->assertSession()->addressEquals('fr' . $edit_new_translation['path[0][alias]']); Chris@17: $this->assertPathsAreAccessible([$default_path]); Chris@17: } Chris@17: Chris@17: /** Chris@17: * Helper callback to verify paths are responding with status 200. Chris@17: * Chris@17: * @param string[] $paths Chris@17: * An array of paths to check for. Chris@17: */ Chris@17: public function assertPathsAreAccessible(array $paths) { Chris@17: foreach ($paths as $path) { Chris@17: $this->drupalGet($path); Chris@17: $this->assertSession()->statusCodeEquals(200); Chris@17: } Chris@17: } Chris@17: Chris@0: }