diff --git a/composer.json b/composer.json index eabb4cc33b822642094d7d25e66111750f5b7efe..b125a656f9f03e41db9c3795af65b87432658cd7 100644 --- a/composer.json +++ b/composer.json @@ -173,7 +173,7 @@ "drupal/twitter_block": "3.0-alpha0", "drupal/userprotect": "1.1", "drupal/video_embed_field": "2.4", - "drupal/view_unpublished": "1.0-rc3", + "drupal/view_unpublished": "1.0", "drupal/views_accordion": "1.1", "drupal/views_ajax_history": "1.5", "drupal/views_autocomplete_filters": "1.3", diff --git a/composer.lock b/composer.lock index abfeef19f41544d91cf75d92709ebaa51fba3827..e1b933734dc3ed47c8315e65f844b0baec6336f8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8bbf1b75a83436fa7654bf0208a40f2d", + "content-hash": "37afa1114d45951a1c942227562ce65c", "packages": [ { "name": "alchemy/zippy", @@ -7937,17 +7937,17 @@ }, { "name": "drupal/view_unpublished", - "version": "1.0.0-rc3", + "version": "1.0.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/view_unpublished.git", - "reference": "8.x-1.0-rc3" + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/view_unpublished-8.x-1.0-rc3.zip", - "reference": "8.x-1.0-rc3", - "shasum": "6973708d48b76531fa9227d8b959a516e1cb9129" + "url": "https://ftp.drupal.org/files/projects/view_unpublished-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "74ebdf1b4f6963f7bb63192bc314014c0132d03c" }, "require": { "drupal/core": "^8 || ^9" @@ -7955,11 +7955,11 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.0-rc3", - "datestamp": "1595646359", + "version": "8.x-1.0", + "datestamp": "1597688978", "security-coverage": { - "status": "not-covered", - "message": "RC releases are not covered by Drupal security advisories." + "status": "covered", + "message": "Covered by Drupal's security advisory policy" } } }, diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index cce0268e72f5cecd7be1a9e5c7dfa35954c725f6..c2a894cc91e392e2c824d5bbdc2c5f3bc5a3c7bc 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -8184,18 +8184,18 @@ }, { "name": "drupal/view_unpublished", - "version": "1.0.0-rc3", - "version_normalized": "1.0.0.0-RC3", + "version": "1.0.0", + "version_normalized": "1.0.0.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/view_unpublished.git", - "reference": "8.x-1.0-rc3" + "reference": "8.x-1.0" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/view_unpublished-8.x-1.0-rc3.zip", - "reference": "8.x-1.0-rc3", - "shasum": "6973708d48b76531fa9227d8b959a516e1cb9129" + "url": "https://ftp.drupal.org/files/projects/view_unpublished-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "74ebdf1b4f6963f7bb63192bc314014c0132d03c" }, "require": { "drupal/core": "^8 || ^9" @@ -8203,11 +8203,11 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.0-rc3", - "datestamp": "1595646359", + "version": "8.x-1.0", + "datestamp": "1597688978", "security-coverage": { - "status": "not-covered", - "message": "RC releases are not covered by Drupal security advisories." + "status": "covered", + "message": "Covered by Drupal's security advisory policy" } } }, diff --git a/web/modules/view_unpublished/tests/src/Functional/ViewUnpublishedMultilingualTest.php b/web/modules/view_unpublished/tests/src/Functional/ViewUnpublishedMultilingualTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ec79a1cb812a6b13a243645d0785d48da200763b --- /dev/null +++ b/web/modules/view_unpublished/tests/src/Functional/ViewUnpublishedMultilingualTest.php @@ -0,0 +1,192 @@ +<?php + +namespace Drupal\Tests\view_unpublished\Functional; + +use Drupal\Core\Language\LanguageInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\Url; +use Drupal\language\Entity\ConfigurableLanguage; +use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl; +use Drupal\Tests\BrowserTestBase; + +/** + * Tests the View Unpublished module on a multilingual site. + * + * @group view_unpublished + */ +class ViewUnpublishedMultilingualTest extends BrowserTestBase { + + use StringTranslationTrait; + + /** + * Modules to install. + * + * @var array + */ + public static $modules = ['view_unpublished', 'node', 'content_translation']; + + /** + * {@inheritdoc} + */ + protected $defaultTheme = 'stark'; + + /** + * The test user. + * + * @var bool|\Drupal\user\Entity\User|false + */ + protected $adminUser; + + /** + * Sets up the test. + */ + protected function setUp() { + parent::setUp(); + + // Create Basic page node type. + $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']); + + $this->adminUser = $this->drupalCreateUser([ + 'access administration pages', + 'administer languages', + 'administer content types', + 'administer nodes', + 'create page content', + 'edit any page content', + 'translate any entity', + 'create content translations', + ]); + $this->drupalLogin($this->adminUser); + + ConfigurableLanguage::createFromLangcode('it')->save(); + + // Enable translation for the current entity type and ensure the change is + // picked up. + \Drupal::service('content_translation.manager')->setEnabled('node', 'page', TRUE); + \Drupal::service('router.builder')->rebuild(); + } + + /** + * Test view_unpublished with multilingual nodes. + */ + public function testIt() { + // Create Basic node content. + $langcode = language_get_default_langcode('node', 'page'); + $title_key = 'title[0][value]'; + $body_key = 'body[0][value]'; + $status_key = 'status[value]'; + // Create node to edit. + $edit = []; + $edit[$title_key] = $this->randomMachineName(8); + $edit[$body_key] = $this->randomMachineName(16); + $edit[$status_key] = 1; + $this->drupalPostForm('node/add/page', $edit, $this->t('Save')); + + // Check the node language. + $node = $this->getNodeByTitle($edit[$title_key]); + $this->assertTrue($node->language()->getId() == $langcode, 'Language correctly set.'); + + $this->drupalLogout(); + // Anonymous users should have access. + $this->drupalGet($node->toUrl()); + $this->assertSession()->statusCodeEquals(200); + + // Unpublish the node and now anonymous users should not. + $this->drupalLogin($this->adminUser); + $edit[$body_key] = $this->randomMachineName(16); + $edit[$status_key] = 0; + $this->drupalPostForm($node->toUrl('edit-form'), $edit, $this->t('Save')); + $this->drupalLogout(); + $this->drupalGet($node->toUrl()); + $this->assertSession()->statusCodeEquals(403); + + // Log in as a user who should have access to all unpublished content. + $this->drupalLogin($this->drupalCreateUser(['view any unpublished content'])); + $this->drupalGet($node->toUrl()); + $this->assertSession()->statusCodeEquals(200); + + // Publish the node again. + $this->drupalLogin($this->adminUser); + $edit[$body_key] = $this->randomMachineName(16); + $edit[$status_key] = 1; + $this->drupalPostForm($node->toUrl('edit-form'), $edit, $this->t('Save')); + $this->drupalLogout(); + + // Anonymous users should have access. + $this->drupalGet($node->toUrl()); + $this->assertSession()->statusCodeEquals(200); + + // Add an italian translation. + $this->drupalLogin($this->adminUser); + $add_translation_url = Url::fromRoute('entity.node.content_translation_add', + ['node' => $node->id(), 'source' => 'en', 'target' => 'it'], + [ + 'language' => ConfigurableLanguage::load('it'), + 'absolute' => FALSE, + ] + ); + $edit[$body_key] = $this->randomMachineName(16); + $edit[$status_key] = 0; + // Unpublish the node and now anonymous users should not have access. + $edit[$status_key] = 0; + $this->drupalPostForm($add_translation_url, $edit, $this->t('Save (this translation)')); + // Reset the node so we pick up the translation. + $node = $this->getNodeByTitle($edit[$title_key], TRUE); + $this->drupalLogout(); + + // Enable content language URL detection. + $this->container->get('language_negotiator')->saveConfiguration(LanguageInterface::TYPE_CONTENT, [LanguageNegotiationUrl::METHOD_ID => 0]); + + // Anonymous users should have access to the english node. + $this->drupalGet($node->toUrl()); + $this->assertSession()->statusCodeEquals(200); + + $translation_url = "it/node/{$node->id()}"; + + // Anonymous users should not have access to the italian node. + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(403); + + // Log in as a user who should have access to unpublished content. + $this->drupalLogin($this->drupalCreateUser(['view any unpublished content'])); + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(200); + + // Log in as a user who should have access to unpublished page content. + $this->drupalLogin($this->drupalCreateUser(['view any unpublished page content'])); + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(200); + + // Log in as a user without the unpublished permissions. + $this->drupalLogin($this->drupalCreateUser()); + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(403); + + // Ensure access remains correct after rebuilding node access. + node_access_rebuild(); + + // Anonymous users should have access to the english node. + $this->drupalGet($node->toUrl()); + $this->assertSession()->statusCodeEquals(200); + + // Anonymous users should not have access to the italian node. + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(403); + + // Log in as a user who should have access to unpublished content. + $this->drupalLogin($this->drupalCreateUser(['view any unpublished content'])); + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(200); + + // Log in as a user who should have access to unpublished page content. + $this->drupalLogin($this->drupalCreateUser(['view any unpublished page content'])); + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(200); + + // Log in as a user without the unpublished permissions. + $this->drupalLogin($this->drupalCreateUser()); + $this->drupalGet($translation_url); + $this->assertSession()->statusCodeEquals(403); + } + +} diff --git a/web/modules/view_unpublished/view_unpublished.info.yml b/web/modules/view_unpublished/view_unpublished.info.yml index ce33c2b77c31f57e39a9855ea3da7a695f66969c..1fc12ba4cb5871e33065a66a39c2f71c47be8c25 100644 --- a/web/modules/view_unpublished/view_unpublished.info.yml +++ b/web/modules/view_unpublished/view_unpublished.info.yml @@ -7,7 +7,7 @@ type: module dependencies: - drupal:node -# Information added by Drupal.org packaging script on 2020-07-25 -version: '8.x-1.0-rc3' +# Information added by Drupal.org packaging script on 2020-08-17 +version: '8.x-1.0' project: 'view_unpublished' -datestamp: 1595646337 +datestamp: 1597688980