X-Git-Url: http://www.aleph1.co.uk/gitweb/?a=blobdiff_plain;ds=sidebyside;f=web%2Fcore%2Fmodules%2Fcontent_translation%2Ftests%2Fsrc%2FFunctional%2FContentTranslationWorkflowsTest.php;fp=web%2Fcore%2Fmodules%2Fcontent_translation%2Ftests%2Fsrc%2FFunctional%2FContentTranslationWorkflowsTest.php;h=759bd6dbbad6368661b6d280ce641a91719e0849;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hp=0000000000000000000000000000000000000000;hpb=aea91e65e895364e460983b890e295aa5d5540a5;p=yaffs-website diff --git a/web/core/modules/content_translation/tests/src/Functional/ContentTranslationWorkflowsTest.php b/web/core/modules/content_translation/tests/src/Functional/ContentTranslationWorkflowsTest.php new file mode 100644 index 000000000..759bd6dbb --- /dev/null +++ b/web/core/modules/content_translation/tests/src/Functional/ContentTranslationWorkflowsTest.php @@ -0,0 +1,259 @@ +setupEntity(); + } + + /** + * {@inheritdoc} + */ + protected function getTranslatorPermissions() { + $permissions = parent::getTranslatorPermissions(); + $permissions[] = 'view test entity'; + + return $permissions; + } + + /** + * {@inheritdoc} + */ + protected function getEditorPermissions() { + return ['administer entity_test content']; + } + + /** + * Creates a test entity and translate it. + */ + protected function setupEntity() { + $default_langcode = $this->langcodes[0]; + + // Create a test entity. + $user = $this->drupalCreateUser(); + $values = [ + 'name' => $this->randomMachineName(), + 'user_id' => $user->id(), + $this->fieldName => [['value' => $this->randomMachineName(16)]], + ]; + $id = $this->createEntity($values, $default_langcode); + $storage = $this->container->get('entity_type.manager') + ->getStorage($this->entityTypeId); + $storage->resetCache([$id]); + $this->entity = $storage->load($id); + + // Create a translation. + $this->drupalLogin($this->translator); + $add_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_add", [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $this->langcodes[2]]); + $this->drupalPostForm($add_translation_url, [], t('Save')); + $this->rebuildContainer(); + } + + /** + * Test simple and editorial translation workflows. + */ + public function testWorkflows() { + // Test workflows for the editor. + $expected_status = [ + 'edit' => 200, + 'delete' => 200, + 'overview' => 403, + 'add_translation' => 403, + 'edit_translation' => 403, + 'delete_translation' => 403, + ]; + $this->doTestWorkflows($this->editor, $expected_status); + + // Test workflows for the translator. + $expected_status = [ + 'edit' => 403, + 'delete' => 403, + 'overview' => 200, + 'add_translation' => 200, + 'edit_translation' => 200, + 'delete_translation' => 200, + ]; + $this->doTestWorkflows($this->translator, $expected_status); + + // Test workflows for the admin. + $expected_status = [ + 'edit' => 200, + 'delete' => 200, + 'overview' => 200, + 'add_translation' => 200, + 'edit_translation' => 403, + 'delete_translation' => 403, + ]; + $this->doTestWorkflows($this->administrator, $expected_status); + + // Check that translation permissions allow the associated operations. + $ops = ['create' => t('Add'), 'update' => t('Edit'), 'delete' => t('Delete')]; + $translations_url = $this->entity->urlInfo('drupal:content-translation-overview'); + foreach ($ops as $current_op => $item) { + $user = $this->drupalCreateUser([$this->getTranslatePermission(), "$current_op content translations", 'view test entity']); + $this->drupalLogin($user); + $this->drupalGet($translations_url); + + // Make sure that the user.permissions cache context and the cache tags + // for the entity are present. + $this->assertCacheContext('user.permissions'); + foreach ($this->entity->getCacheTags() as $cache_tag) { + $this->assertCacheTag($cache_tag); + } + + foreach ($ops as $op => $label) { + if ($op != $current_op) { + $this->assertNoLink($label, format_string('No %op link found.', ['%op' => $label])); + } + else { + $this->assertLink($label, 0, format_string('%op link found.', ['%op' => $label])); + } + } + } + } + + /** + * Checks that workflows have the expected behaviors for the given user. + * + * @param \Drupal\user\UserInterface $user + * The user to test the workflow behavior against. + * @param array $expected_status + * The an associative array with the operation name as key and the expected + * status as value. + */ + protected function doTestWorkflows(UserInterface $user, $expected_status) { + $default_langcode = $this->langcodes[0]; + $languages = $this->container->get('language_manager')->getLanguages(); + $args = ['@user_label' => $user->getUsername()]; + $options = ['language' => $languages[$default_langcode], 'absolute' => TRUE]; + $this->drupalLogin($user); + + // Check whether the user is allowed to access the entity form in edit mode. + $edit_url = $this->entity->urlInfo('edit-form', $options); + $this->drupalGet($edit_url, $options); + $this->assertResponse($expected_status['edit'], SafeMarkup::format('The @user_label has the expected edit access.', $args)); + + // Check whether the user is allowed to access the entity delete form. + $delete_url = $this->entity->urlInfo('delete-form', $options); + $this->drupalGet($delete_url, $options); + $this->assertResponse($expected_status['delete'], SafeMarkup::format('The @user_label has the expected delete access.', $args)); + + // Check whether the user is allowed to access the translation overview. + $langcode = $this->langcodes[1]; + $options['language'] = $languages[$langcode]; + $translations_url = $this->entity->url('drupal:content-translation-overview', $options); + $this->drupalGet($translations_url); + $this->assertResponse($expected_status['overview'], SafeMarkup::format('The @user_label has the expected translation overview access.', $args)); + + // Check whether the user is allowed to create a translation. + $add_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_add", [$this->entityTypeId => $this->entity->id(), 'source' => $default_langcode, 'target' => $langcode], $options); + if ($expected_status['add_translation'] == 200) { + $this->clickLink('Add'); + $this->assertUrl($add_translation_url->toString(), [], 'The translation overview points to the translation form when creating translations.'); + // Check that the translation form does not contain shared elements for + // translators. + if ($expected_status['edit'] == 403) { + $this->assertNoSharedElements(); + } + } + else { + $this->drupalGet($add_translation_url); + } + $this->assertResponse($expected_status['add_translation'], SafeMarkup::format('The @user_label has the expected translation creation access.', $args)); + + // Check whether the user is allowed to edit a translation. + $langcode = $this->langcodes[2]; + $options['language'] = $languages[$langcode]; + $edit_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_edit", [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options); + if ($expected_status['edit_translation'] == 200) { + $this->drupalGet($translations_url); + $editor = $expected_status['edit'] == 200; + + if ($editor) { + $this->clickLink('Edit', 2); + // An editor should be pointed to the entity form in multilingual mode. + // We need a new expected edit path with a new language. + $expected_edit_path = $this->entity->url('edit-form', $options); + $this->assertUrl($expected_edit_path, [], 'The translation overview points to the edit form for editors when editing translations.'); + } + else { + $this->clickLink('Edit'); + // While a translator should be pointed to the translation form. + $this->assertUrl($edit_translation_url->toString(), [], 'The translation overview points to the translation form for translators when editing translations.'); + // Check that the translation form does not contain shared elements. + $this->assertNoSharedElements(); + } + } + else { + $this->drupalGet($edit_translation_url); + } + $this->assertResponse($expected_status['edit_translation'], SafeMarkup::format('The @user_label has the expected translation edit access.', $args)); + + // Check whether the user is allowed to delete a translation. + $langcode = $this->langcodes[2]; + $options['language'] = $languages[$langcode]; + $delete_translation_url = Url::fromRoute("entity.$this->entityTypeId.content_translation_delete", [$this->entityTypeId => $this->entity->id(), 'language' => $langcode], $options); + if ($expected_status['delete_translation'] == 200) { + $this->drupalGet($translations_url); + $editor = $expected_status['delete'] == 200; + + if ($editor) { + $this->clickLink('Delete', 2); + // An editor should be pointed to the entity deletion form in + // multilingual mode. We need a new expected delete path with a new + // language. + $expected_delete_path = $this->entity->url('delete-form', $options); + $this->assertUrl($expected_delete_path, [], 'The translation overview points to the delete form for editors when deleting translations.'); + } + else { + $this->clickLink('Delete'); + // While a translator should be pointed to the translation deletion + // form. + $this->assertUrl($delete_translation_url->toString(), [], 'The translation overview points to the translation deletion form for translators when deleting translations.'); + } + } + else { + $this->drupalGet($delete_translation_url); + } + $this->assertResponse($expected_status['delete_translation'], SafeMarkup::format('The @user_label has the expected translation deletion access.', $args)); + } + + /** + * Assert that the current page does not contain shared form elements. + */ + protected function assertNoSharedElements() { + $language_none = LanguageInterface::LANGCODE_NOT_SPECIFIED; + return $this->assertNoFieldByXPath("//input[@name='field_test_text[$language_none][0][value]']", NULL, 'Shared elements are not available on the translation form.'); + } + +}