Version 1
[yaffs-website] / web / core / modules / node / tests / src / Functional / NodeAccessLanguageTest.php
1 <?php
2
3 namespace Drupal\Tests\node\Functional;
4
5 use Drupal\Core\Language\LanguageInterface;
6 use Drupal\language\Entity\ConfigurableLanguage;
7 use Drupal\node\Entity\NodeType;
8 use Drupal\user\Entity\User;
9
10 /**
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.
13  *
14  * @group node
15  */
16 class NodeAccessLanguageTest extends NodeTestBase {
17
18   /**
19    * Modules to enable.
20    *
21    * @var array
22    */
23   public static $modules = ['language', 'node_access_test'];
24
25   protected function setUp() {
26     parent::setUp();
27
28     node_access_test_add_field(NodeType::load('page'));
29
30     // After enabling a node access module, the access table has to be rebuild.
31     node_access_rebuild();
32
33     // Enable the private node feature of the node_access_test module.
34     \Drupal::state()->set('node_access_test.private', TRUE);
35
36     // Add Hungarian, Catalan and Croatian.
37     ConfigurableLanguage::createFromLangcode('hu')->save();
38     ConfigurableLanguage::createFromLangcode('ca')->save();
39     ConfigurableLanguage::createFromLangcode('hr')->save();
40   }
41
42   /**
43    * Tests node access with multiple node languages and no private nodes.
44    */
45   public function testNodeAccess() {
46     $web_user = $this->drupalCreateUser(['access content']);
47
48     $expected_node_access = ['view' => TRUE, 'update' => FALSE, 'delete' => FALSE];
49     $expected_node_access_no_access = ['view' => FALSE, 'update' => FALSE, 'delete' => FALSE];
50
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.');
55
56     // Tests the default access is provided for the public Hungarian node.
57     $this->assertNodeAccess($expected_node_access, $node_public_hu, $web_user);
58
59     // Tests that Hungarian provided specifically results in the same.
60     $this->assertNodeAccess($expected_node_access, $node_public_hu->getTranslation('hu'), $web_user);
61
62     // Creating a public node with no special langcode, like when no language
63     // module enabled.
64     $node_public_no_language = $this->drupalCreateNode([
65       'private' => FALSE,
66       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
67     ]);
68     $this->assertTrue($node_public_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
69
70     // Tests that access is granted if requested with no language.
71     $this->assertNodeAccess($expected_node_access, $node_public_no_language, $web_user);
72
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.');
78
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);
82
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);
86
87     // Tests that Catalan is still not accessible.
88     $this->assertNodeAccess($expected_node_access_no_access, $node_public_ca->getTranslation('ca'), $web_user);
89
90     // Make Catalan accessible.
91     \Drupal::state()->set('node_access_test_secret_catalan', 0);
92
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);
97
98     \Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
99
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);
103
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);
107
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);
110   }
111
112   /**
113    * Tests node access with multiple node languages and private nodes.
114    */
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];
119
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.');
124
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);
127
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);
130
131     // Creating a private node with no special langcode, like when no language
132     // module enabled.
133     $node_private_no_language = $this->drupalCreateNode([
134       'private' => TRUE,
135       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
136     ]);
137     $this->assertTrue($node_private_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
138
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);
141
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);
145
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);
148
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.');
154
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);
160
161     \Drupal::entityManager()->getAccessControlHandler('node')->resetCache();
162     \Drupal::state()->set('node_access_test_secret_catalan', 0);
163
164     // Tests that Catalan is still not accessible for a user with no access to
165     // private nodes.
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);
168
169     // Tests that Catalan is accessible by a user with the permission to see
170     // private nodes.
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);
173   }
174
175   /**
176    * Tests db_select() with a 'node_access' tag and langcode metadata.
177    */
178   public function testNodeAccessQueryTag() {
179     // Create a normal authenticated user.
180     $web_user = $this->drupalCreateUser(['access content']);
181
182     // Load the user 1 user for later use as an admin user with permission to
183     // see everything.
184     $admin_user = User::load(1);
185
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.');
190
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.');
195
196     // Creating a public node with no special langcode, like when no language
197     // module enabled.
198     $node_no_language = $this->drupalCreateNode([
199       'private' => FALSE,
200       'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED,
201     ]);
202     $this->assertTrue($node_no_language->language()->getId() == LanguageInterface::LANGCODE_NOT_SPECIFIED, 'Node created with not specified language.');
203
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');
211
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.');
217
218     // Query the nodes table as the web user with the node access tag and
219     // langcode de.
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');
226
227     // Because no nodes are created in German, no nodes are returned.
228     $this->assertTrue(empty($nids), 'db_select() returns an empty result.');
229
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');
237
238     // All nodes are returned.
239     $this->assertEqual(count($nids), 3, 'db_select() returns all three nodes.');
240
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');
249
250     // All nodes are returned because node access tag is not invoked when the
251     // user is user 1.
252     $this->assertEqual(count($nids), 3, 'db_select() returns all three nodes.');
253   }
254
255 }