diff --git a/core/modules/node/src/Tests/NodeAccessJoinTest.php b/core/modules/node/src/Tests/NodeAccessJoinTest.php index 2db44f8..19d1050 100644 --- a/core/modules/node/src/Tests/NodeAccessJoinTest.php +++ b/core/modules/node/src/Tests/NodeAccessJoinTest.php @@ -31,7 +31,7 @@ class NodeAccessJoinTest extends NodeTestBase { * * @var \Drupal\user\UserInterface */ - protected $ownerUser; + protected $authorUser; /** * A user with just access content permissions. @@ -110,69 +110,189 @@ protected function setUp() { ]) ->save(); + $field = FieldConfig::create([ + 'field_name' => 'related_article', + 'entity_type' => 'node', + 'bundle' => 'article', + 'label' => 'Related Article', + 'settings' => [ + 'handler' => 'default', + 'handler_settings' => [ + // Reference a single vocabulary. + 'target_bundles' => [ + 'article', + ], + ], + ], + ]); + $field->save(); + + entity_get_display('node', 'article', 'default') + ->setComponent('related_article') + ->save(); + entity_get_form_display('node', 'article', 'default') + ->setComponent('related_article', [ + 'type' => 'entity_reference_autocomplete', + ]) + ->save(); + node_access_rebuild(); \Drupal::state()->set('node_access_test.private', TRUE); } + /** + * Tests the "private" node access functionality. + * + * - Create user with "access content" and "create article" permissions which + * will be author having access to some private articles but not others. + * - Create articles with and without reference for the "author" user and + * anonymous user. + * - Create pages with articles as reference for any combination of article + * (private or private by author, reference being both private both public, + * etc.). + * + * - Login with author and check that it doesn't have access to private nodes + * he is not the author of. + * - Use the page titles to be sure the user sees what it should see and that + * results count is not just a fluke. + * - Create and login with user with only "access content" permission. + * - Test that he sees only public nodes. Use the page titles to be sure the + * user sees what it should see and that results count is not just a fluke. + * - Create and login with user with "access content" and "node test view" + * permissions. + * - Test that the user sees all the rows. + */ function testNodeAccessJoin() { - // User to add articles and test owner access. - $this->ownerUser = $this->drupalCreateUser(['access content', 'create article content']); - - foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) { - $edit = [ - 'title' => t('@private_public Article', ['@private_public' => $type]), - 'type' => 'article', - 'uid' => $this->ownerUser->id(), - ]; - if ($is_private) { - $edit['private'][0]['value'] = TRUE; - } - else { - $edit['private'][0]['value'] = FALSE; - } + // User to add articles and test author access. + $this->authorUser = $this->drupalCreateUser(['access content', 'create article content']); + + foreach (['no reference', 'public', 'private'] as $reference) { + foreach ([0 => 'public', 1 => 'private'] as $is_private => $type) { + $edit = [ + 'title' => t('author @private_public article - @reference', ['@private_public' => $type, '@reference' => ($reference != 'no reference') ? 'author ' . $reference : $reference]), + 'type' => 'article', + 'uid' => $this->authorUser->id(), + ]; + if ($is_private) { + $edit['private'][0]['value'] = TRUE; + } + else { + $edit['private'][0]['value'] = FALSE; + } + if ($reference != 'no reference') { + $edit['related_article'][0]['target_id'] = $this->articles['author no reference']['author ' . $reference]; + } - $node = $this->drupalCreateNode($edit); - $this->assertEqual($is_private, (int)$node->private->value, 'The private status of the node was properly set in the node_access_test table.' . $node->uid->target_id); - $this->articles[$is_private] = $node->id(); + $node = $this->drupalCreateNode($edit); + $this->assertEqual($is_private, (int)$node->private->value, 'The private status of the node was properly set in the node_access_test table.' . $node->uid->target_id); + $this->articles['author ' . $reference]['author ' . $type] = $node->id(); + if ($reference != 'no reference') { + $this->assertEqual((int)$this->articles['author no reference']['author ' . $reference], (int)$node->related_article->target_id, 'Proper article attached to article.'); + } + + $edit = [ + 'title' => t('@private_public article - @reference', ['@private_public' => $type, '@reference' => $reference]), + 'type' => 'article', + ]; + if ($is_private) { + $edit['private'][0]['value'] = TRUE; + } + else { + $edit['private'][0]['value'] = FALSE; + } + if ($reference != 'no reference') { + $edit['related_article'][0]['target_id'] = $this->articles['no reference'][$reference]; + } + + $node = $this->drupalCreateNode($edit); + $this->assertEqual($is_private, (int)$node->private->value, 'The private status of the node was properly set in the node_access_test table.' . $node->uid->target_id); + $this->articles[$reference][$type] = $node->id(); + if ($reference != 'no reference') { + $this->assertEqual((int)$this->articles['no reference'][$reference], (int)$node->related_article->target_id, 'Proper article attached to article.'); + } + } } $edit = [ 'type' => 'page', - 'title' => 'Page with no article', + 'title' => 'Page - no reference', ]; $this->drupalCreateNode($edit); - foreach ([0 => 'Public', 1 => 'Private'] as $is_private => $type) { - $edit['title'] = t('Page with @private_public article', ['@private_public' => strtolower($type)]); - $edit['related_article'][0]['target_id'] = $this->articles[$is_private]; + $total = 1; + $total_public = 1; + $total_author = 0; + foreach ([0 => 'public', 1 => 'private'] as $is_private => $type) { + foreach (['no reference', 'public', 'private'] as $reference) { + foreach (['author', 'regular'] as $author) { + foreach (['author', 'regular'] as $author1) { + if ($author == 'author') { + $title = 'author '; + } + else { + $title = ''; + } + if ($author1 == 'author') { + $title1 = 'author '; + } + else { + $title1 = ''; + } + if (isset($this->articles[$title . $reference]) && isset($this->articles[$title . $reference][$title1 . $type])) { + $edit['title'] = t('Page - @title1@private_public - @title2@reference', ['@private_public' => $type, '@reference' => $reference, '@title1' => $title, '@title2' => ($reference != 'no reference') ? $title1 : '']); + $edit['related_article'][0]['target_id'] = $this->articles[$title . $reference][$title1 . $type]; - $node = $this->drupalCreateNode($edit); - $this->assertEqual((int)$this->articles[$is_private], (int)$node->related_article->target_id, 'Proper article attached to page.'); + $node = $this->drupalCreateNode($edit); + $total++; + if (($type == 'private' || $reference == 'private') && ($author == 'author' || $author1 == 'author')) { + $total_author++; + } + if ($type != 'private' && $reference != 'private') { + $total_public++; + } + $this->assertEqual((int)$this->articles[$title . $reference][$title1 . $type], (int)$node->related_article->target_id, 'Proper article attached to page.'); + } + } + } + } } + $total_author += $total_public; ViewTestData::createTestViews(get_class($this), ['node_test_views']); - $this->drupalLogin($this->ownerUser); + // User to check if entries with private references are hidden, but that his + // own private references are visible. + $this->drupalLogin($this->authorUser); $this->drupalGet('test-node-access-join'); - $this->assertText('Page with no article', 'Node with null reference visible'); - $this->assertText('Page with private article', "Node with owner's private reference visible"); - $this->assertText('Page with public article', 'Node with public reference visible'); + $this->verbose('Viewing page with author'); + $this->assertText('Page - no reference', 'Node with null reference visible'); + $this->assertText('Page - public - no reference', 'Node with public reference visible'); + $this->assertText('Page - public - public', 'Node with 2 public joins visible'); + $this->assertText('Page - author private - no reference', "Node with author's private reference visible"); + $this->assertNoText('- private', "Node author doesn't see private nodes he's not the author of"); + $this->assertText('Page - public - no reference', 'Node with public reference visible'); + $rows = count($this->xpath("//td[@headers='view-title-table-column']")); + $this->assertTrue($rows == $total_author, "Author sees all rows he has access to. $rows - $total_author"); - // User to check if entry with private reference is hidden. + // User to check if entries with private references are hidden. $this->regularUser = $this->drupalCreateUser(['access content']); $this->drupalLogin($this->regularUser); $this->drupalGet('test-node-access-join'); - $this->assertText('Page with no article', 'Node with null reference visible'); - $this->assertNoText('Page with private article', "Node with private reference hidden"); - $this->assertText('Page with public article', 'Node with public reference visible'); + $this->verbose('Viewing page with regular user'); + $this->assertText('Page - no reference', 'Node with null reference visible'); + $this->assertNoText('private', "Node with private reference hidden"); + $this->assertText('Page - public - no reference', 'Node with public reference visible'); + $this->assertText('Page - public - public', 'Node with 2 public joins visible'); + $rows = count($this->xpath("//td[@headers='view-title-table-column']")); + $this->assertTrue($rows == $total_public, "User with no access sees only public rows."); - // User to check if entry with private reference is visible. + // User to check if entries with private references are visible. $this->accessUser = $this->drupalCreateUser(['access content', 'node test view']); $this->drupalLogin($this->accessUser); $this->drupalGet('test-node-access-join'); - $this->assertText('Page with no article', 'Node with null reference visible'); - $this->assertText('Page with private article', "Node with private reference visible"); - $this->assertText('Page with public article', 'Node with public reference visible'); + $this->verbose('Viewing page with access user'); + $rows = count($this->xpath("//td[@headers='view-title-table-column']")); + $this->assertTrue($rows == $total, "User with access sees all rows."); } diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_access_join.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_access_join.yml index 3027a5a..be876e0 100644 --- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_access_join.yml +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_access_join.yml @@ -1,3 +1,4 @@ +uuid: 0a62a0f4-8322-49c3-964d-770997ac5ac0 langcode: en status: true dependencies: @@ -49,7 +50,7 @@ display: pager: type: full options: - items_per_page: 10 + items_per_page: 1000 offset: 0 id: 0 total_pages: null @@ -184,6 +185,71 @@ display: entity_type: node entity_field: title plugin_id: field + title_2: + id: title_2 + table: node_field_data + field: title + relationship: related_article_1 + group_type: group + admin_label: '' + label: 'Article 1' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + entity_type: node + entity_field: title + plugin_id: field filters: status: value: true @@ -220,7 +286,7 @@ display: entity_type: node entity_field: title plugin_id: standard - title: 'Test Node Access Join' + title: 'Test Reference Access' header: { } footer: { } empty: { } @@ -231,7 +297,16 @@ display: field: related_article relationship: none group_type: group - admin_label: 'related_article: Content' + admin_label: 'Page related article' + required: false + plugin_id: standard + related_article_1: + id: related_article_1 + table: node__related_article + field: related_article + relationship: related_article + group_type: group + admin_label: 'Article related article' required: false plugin_id: standard arguments: { }