3 namespace Drupal\Tests\node\Functional;
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\language\Entity\ConfigurableLanguage;
7 use Drupal\node\Entity\NodeType;
8 use Drupal\user\Entity\User;
11 * Tests node_access and db_select() with node_access tag functionality with
12 * multiple languages with a test node access module that is not language-aware.
16 class NodeAccessLanguageTest extends NodeTestBase {
23 public static $modules = ['language', 'node_access_test'];
25 protected function setUp() {
28 node_access_test_add_field(NodeType::load('page'));
30 // After enabling a node access module, the access table has to be rebuild.
31 node_access_rebuild();
33 // Enable the private node feature of the node_access_test module.
34 \Drupal::state()->set('node_access_test.private', TRUE);
36 // Add Hungarian, Catalan and Croatian.
37 ConfigurableLanguage::createFromLangcode('hu')->save();
38 ConfigurableLanguage::createFromLangcode('ca')->save();
39 ConfigurableLanguage::createFromLangcode('hr')->save();
43 * Tests node access with multiple node languages and no private nodes.
45 public function testNodeAccess() {
46 $web_user = $this->drupalCreateUser(['access content']);
48 $expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE];
49 $expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE];
51 // Creating a public node with langcode Hungarian, will be saved as the
52 // fallback in node access table.
53 $node_public_hu = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => FALSE]);
54 $this->assertTrue($node_public_hu->language()->getId() == 'hu', 'Node created as Hungarian.');
56 // Tests the default access is provided for the public Hungarian node.
57 $this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
59 // Tests that Hungarian provided specifically results in the same.
60 $this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
62 // Creating a public node with no special langcode, like when no language
64 $node_public_no_language = $this->drupalCreateNode([
66 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
68 $this->assertTrue($node_public_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
70 // Tests that access is granted if requested with no language.
71 $this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
73 // Reset the node access cache and turn on our test node access code.
74 \Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
75 \Drupal::state()->set('node_access_test_secret_catalan', 1);
76 $node_public_ca = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'ca', 'private' => FALSE]);
77 $this->assertTrue($node_public_ca->language()->getId() == 'ca', 'Node created as Catalan.');
79 // Tests that access is granted if requested with no language.
80 $this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
81 $this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user);
83 // Tests that Hungarian node is still accessible.
84 $this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
85 $this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
87 // Tests that Catalan is still not accessible.
88 $this->assertNodeAccess($expected_node_access_no_access, $node_public_ca->getTranslation('ca'), $web_user);
90 // Make Catalan accessible.
91 \Drupal::state()->set('node_access_test_secret_catalan', 0);
93 // Tests that Catalan is accessible on a node with a Catalan version as the
94 // static cache has not been reset.
95 $this->assertNodeAccess($expected_node_access_no_access, $node_public_ca, $web_user);
96 $this->assertNodeAccess($expected_node_access_no_access, $node_public_ca->getTranslation('ca'), $web_user);
98 \Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
100 // Tests that access is granted if requested with no language.
101 $this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
102 $this->assertNodeAccess($expected_node_access, $node_public_ca, $web_user);
104 // Tests that Hungarian node is still accessible.
105 $this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
106 $this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
108 // Tests that Catalan is accessible on a node with a Catalan version.
109 $this->assertNodeAccess($expected_node_access, $node_public_ca->getTranslation('ca'), $web_user);
113 * Tests node access with multiple node languages and private nodes.
115 public function testNodeAccessPrivate() {
116 $web_user = $this->drupalCreateUser(['access content']);
117 $expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE];
118 $expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE];
120 // Creating a private node with langcode Hungarian, will be saved as the
121 // fallback in node access table.
122 $node_private_hu = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => TRUE]);
123 $this->assertTrue($node_private_hu->language()->getId() == 'hu', 'Node created as Hungarian.');
125 // Tests the default access is not provided for the private Hungarian node.
126 $this->assertNodeAccess($expected_node_access_no_access, $node_private_hu, $web_user);
128 // Tests that Hungarian provided specifically results in the same.
129 $this->assertNodeAccess($expected_node_access_no_access, $node_private_hu->getTranslation('hu'), $web_user);
131 // Creating a private node with no special langcode, like when no language
133 $node_private_no_language = $this->drupalCreateNode([
135 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
137 $this->assertTrue($node_private_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
139 // Tests that access is not granted if requested with no language.
140 $this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user);
142 // Reset the node access cache and turn on our test node access code.
143 \Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
144 \Drupal::state()->set('node_access_test_secret_catalan', 1);
146 // Tests that access is not granted if requested with no language.
147 $this->assertNodeAccess($expected_node_access_no_access, $node_private_no_language, $web_user);
149 // Creating a private node with langcode Catalan to test that the
150 // node_access_test_secret_catalan flag works.
151 $private_ca_user = $this->drupalCreateUser(['access content', 'node test view']);
152 $node_private_ca = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'ca', 'private' => TRUE]);
153 $this->assertTrue($node_private_ca->language()->getId() == 'ca', 'Node created as Catalan.');
155 // Tests that Catalan is still not accessible to either user.
156 $this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user);
157 $this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $web_user);
158 $this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $private_ca_user);
159 $this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $private_ca_user);
161 \Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
162 \Drupal::state()->set('node_access_test_secret_catalan', 0);
164 // Tests that Catalan is still not accessible for a user with no access to
166 $this->assertNodeAccess($expected_node_access_no_access, $node_private_ca, $web_user);
167 $this->assertNodeAccess($expected_node_access_no_access, $node_private_ca->getTranslation('ca'), $web_user);
169 // Tests that Catalan is accessible by a user with the permission to see
171 $this->assertNodeAccess($expected_node_access, $node_private_ca, $private_ca_user);
172 $this->assertNodeAccess($expected_node_access, $node_private_ca->getTranslation('ca'), $private_ca_user);
176 * Tests db_select() with a 'node_access' tag and langcode metadata.
178 public function testNodeAccessQueryTag() {
179 // Create a normal authenticated user.
180 $web_user = $this->drupalCreateUser(['access content']);
182 // Load the user 1 user for later use as an admin user with permission to
184 $admin_user = User::load(1);
186 // Creating a private node with langcode Hungarian, will be saved as
187 // the fallback in node access table.
188 $node_private = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => TRUE]);
189 $this->assertTrue($node_private->language()->getId() == 'hu', 'Node created as Hungarian.');
191 // Creating a public node with langcode Hungarian, will be saved as
192 // the fallback in node access table.
193 $node_public = $this->drupalCreateNode(['body' => [[]], 'langcode' => 'hu', 'private' => FALSE]);
194 $this->assertTrue($node_public->language()->getId() == 'hu', 'Node created as Hungarian.');
196 // Creating a public node with no special langcode, like when no language
198 $node_no_language = $this->drupalCreateNode([
200 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
202 $this->assertTrue($node_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
204 // Query the nodes table as the web user with the node access tag and no
205 // specific langcode.
206 $select = db_select('node', 'n')
207 ->fields('n', ['nid'])
208 ->addMetaData('account', $web_user)
209 ->addTag('node_access');
210 $nids = $select->execute()->fetchAllAssoc('nid');
212 // The public node and no language node should be returned. Because no
213 // langcode is given it will use the fallback node.
214 $this->assertEqual(count($nids), 2, 'db_select() returns 2 node');
215 $this->assertTrue(array_key_exists($node_public->id(), $nids), 'Returned node ID is public node.');
216 $this->assertTrue(array_key_exists($node_no_language->id(), $nids), 'Returned node ID is no language node.');
218 // Query the nodes table as the web user with the node access tag and
220 $select = db_select('node', 'n')
221 ->fields('n', ['nid'])
222 ->addMetaData('account', $web_user)
223 ->addMetaData('langcode', 'de')
224 ->addTag('node_access');
225 $nids = $select->execute()->fetchAllAssoc('nid');
227 // Because no nodes are created in German, no nodes are returned.
228 $this->assertTrue(empty($nids), 'db_select() returns an empty result.');
230 // Query the nodes table as admin user (full access) with the node access
231 // tag and no specific langcode.
232 $select = db_select('node', 'n')
233 ->fields('n', ['nid'])
234 ->addMetaData('account', $admin_user)
235 ->addTag('node_access');
236 $nids = $select->execute()->fetchAllAssoc('nid');
238 // All nodes are returned.
239 $this->assertEqual(count($nids), 3, 'db_select() returns all three nodes.');
241 // Query the nodes table as admin user (full access) with the node access
242 // tag and langcode de.
243 $select = db_select('node', 'n')
244 ->fields('n', ['nid'])
245 ->addMetaData('account', $admin_user)
246 ->addMetaData('langcode', 'de')
247 ->addTag('node_access');
248 $nids = $select->execute()->fetchAllAssoc('nid');
250 // All nodes are returned because node access tag is not invoked when the
252 $this->assertEqual(count($nids), 3, 'db_select() returns all three nodes.');