i18n_access.test 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <?php
  2. /**
  3. * @file
  4. * Test suite for i18n_access.module
  5. */
  6. class i18nAccessTestCase extends DrupalWebTestCase {
  7. protected $admin_user;
  8. protected $translator;
  9. protected $visitor;
  10. /**
  11. * Implementation of getInfo().
  12. */
  13. public static function getInfo() {
  14. return array(
  15. 'name' => t('Translation Access'),
  16. 'description' => t('Test suite for the i18n_access module.'),
  17. 'group' => t('i18n'),
  18. );
  19. }
  20. /**
  21. * Implementation of setUp().
  22. */
  23. public function setUp() {
  24. parent::setUp(array('locale', 'translation', 'i18n_access', 'i18n_node'));
  25. $this->admin_user = $this->drupalCreateUser(array('administer languages', 'administer site configuration', 'access administration pages', 'administer content types', 'administer users', 'bypass node access', 'translate content'));
  26. $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content'));
  27. $this->visitor = $this->drupalCreateUser(array('access content'));
  28. $this->drupalLogin($this->admin_user);
  29. $this->addLanguage('fr');
  30. $this->addLanguage('de');
  31. // Set Story content type to use multilingual support with translation.
  32. $edit['language_content_type'] = 2;
  33. $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type'));
  34. $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), 'Story content type has been updated.');
  35. }
  36. /**
  37. * Enable the specified language if it has not been already.
  38. *
  39. * @param string $language_code
  40. * The language code to enable.
  41. */
  42. function addLanguage($language_code) {
  43. // Check to make sure that language has not already been installed.
  44. $this->drupalGet('admin/config/regional/language');
  45. if (strpos($this->drupalGetContent(), 'enabled[' . $language_code . ']') === FALSE) {
  46. // Doesn't have language installed so add it.
  47. $edit = array();
  48. $edit['langcode'] = $language_code;
  49. $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
  50. drupal_static_reset('language_list'); // Make sure not using cached version.
  51. $languages = language_list('language');
  52. $this->assertTrue(array_key_exists($language_code, $languages), 'Language was installed successfully.');
  53. if (array_key_exists($language_code, $languages)) {
  54. $this->assertRaw(t('The language %language has been created and can now be used.', array('%language' => $languages[$language_code]->name)), 'Language has been created.');
  55. }
  56. }
  57. else {
  58. // Ensure that it is enabled.
  59. $this->drupalPost(NULL, array('enabled[' . $language_code . ']' => TRUE), t('Save configuration'));
  60. $this->assertRaw(t('Configuration saved.'), 'Language successfully enabled.');
  61. }
  62. }
  63. /**
  64. * Sets the language permission for the specified user. Must be logged in as
  65. * an 'administer users' privileged user before calling this.
  66. *
  67. * @param $account
  68. * The user account to modify
  69. * @param $languages
  70. * An array of language codes to give permission for
  71. */
  72. function setLanguagePermissions($account, $languages = array()) {
  73. $this->assertTrue(user_access('administer users'), 'User has permission to administer users');
  74. $expected = array();
  75. $edit = array();
  76. foreach ($languages as $langcode) {
  77. $key = 'i18n_access[' . $langcode . ']';
  78. $edit[$key] = $langcode;
  79. $expected[$langcode] = $langcode;
  80. }
  81. $this->drupalPost('user/' . $account->uid . '/edit', $edit, t('Save'));
  82. $actual = i18n_access_load_permissions($account->uid);
  83. $this->assertEqual($expected, $actual, 'Language permissions set correctly.', 'i18n_access');
  84. }
  85. /**
  86. * Unsets the language permission for the specified user. Must be logged in as
  87. * an 'administer users' privileged user before calling this.
  88. *
  89. * @param $account
  90. * The user account to modify
  91. * @param $languages
  92. * An array of language codes to remove permission for
  93. */
  94. function unsetLanguagePermissions($account, $languages = array()) {
  95. $this->assertTrue(user_access('administer users'), 'User has permission to administer users');
  96. $expected = array();
  97. $edit = array();
  98. foreach ($languages as $langcode) {
  99. $key = 'i18n_access[' . $langcode . ']';
  100. $edit[$key] = FALSE;
  101. }
  102. $this->drupalPost('user/' . $account->uid . '/edit', $edit, t('Save'));
  103. drupal_static_reset('i18n_access_load_permissions');
  104. drupal_static_reset('node_access');
  105. $actual = i18n_access_load_permissions($account->uid);
  106. $this->assertEqual($expected, $actual, 'Language permissions unset correctly.', 'i18n_access');
  107. }
  108. /**
  109. * Assert that a language option exists in the language select field on the
  110. * current page.
  111. * @param $langcode
  112. * Value of the language option to assert.
  113. * @param $message
  114. * Message to display.
  115. * @param $group
  116. * The group this message belongs to.
  117. * @return
  118. * TRUE on pass, FALSE on fail.
  119. */
  120. function assertLanguageOption($langcode, $message, $group = 'Other') {
  121. $xpath = '//select[@name="language"]/option';
  122. $fields = $this->xpath($xpath);
  123. // If value specified then check array for match.
  124. $found = TRUE;
  125. if (isset($langcode)) {
  126. $found = FALSE;
  127. if ($fields) {
  128. foreach ($fields as $field) {
  129. if ($field['value'] == $langcode) {
  130. $found = TRUE;
  131. }
  132. }
  133. }
  134. }
  135. return $this->assertTrue($fields && $found, $message, $group);
  136. }
  137. /**
  138. * Assert that a language option does not exist in the language select field
  139. * on the current page.
  140. * @param $langcode
  141. * Value of the language option to assert.
  142. * @param $message
  143. * Message to display.
  144. * @param $group
  145. * The group this message belongs to.
  146. * @return
  147. * TRUE on pass, FALSE on fail.
  148. */
  149. function assertNoLanguageOption($langcode, $message, $group = 'Other') {
  150. $xpath = '//select[@name="language"]/option';
  151. $fields = $this->xpath($xpath);
  152. // If value specified then check array for match.
  153. $found = TRUE;
  154. if (isset($langcode)) {
  155. $found = FALSE;
  156. if ($fields) {
  157. foreach ($fields as $field) {
  158. if ($field['value'] == $langcode) {
  159. $found = TRUE;
  160. }
  161. }
  162. }
  163. }
  164. return $this->assertFalse($fields && $found, $message, $group);
  165. }
  166. /**
  167. * Test translator user. User with 'create article content' permission
  168. * should be able to create and edit article nodes only in/for
  169. * the languages that they have permissions for.
  170. */
  171. function testTranslatorUser() {
  172. $this->_testTranslatorNodeAccess();
  173. $this->_testTranslatorNodeAccess(TRUE);
  174. }
  175. function _testTranslatorNodeAccess($via_role = FALSE) {
  176. $this->drupalLogin($this->admin_user);
  177. if (!$via_role) {
  178. $this->setLanguagePermissions($this->translator, array('en', 'fr'));
  179. }
  180. else{
  181. $edit = array(
  182. 'i18n_access_languages[]' => array('en', 'fr'),
  183. );
  184. $this->drupalPost('admin/config/regional/language/access', $edit, t('Save configuration'));
  185. $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content', 'access selected languages'));
  186. }
  187. $this->drupalLogin($this->translator);
  188. $this->drupalGet('node/add/article');
  189. $this->assertField('language', 'Found language selector.');
  190. $perms = i18n_access_load_permissions($this->translator->uid);
  191. $languages = language_list();
  192. $languages[LANGUAGE_NONE] = (object)array('language' => LANGUAGE_NONE, 'name' => 'Language Neutral');
  193. foreach ($languages as $key => $language) {
  194. // TODO: Add in check for language neutral
  195. if (isset($perms[$key]) && $perms[$key]) {
  196. $this->assertLanguageOption($language->language, format_string('Option found for %language in language selector.', array('%language' => $language->name)));
  197. }
  198. else {
  199. $this->assertNoLanguageOption($language->language, format_string('Option not found for %language in language selector.', array('%language' => $language->name)));
  200. }
  201. }
  202. $this->drupalLogin($this->admin_user);
  203. $node = $this->drupalCreateNode(array('type' => 'article', 'language' => 'de', 'body' => array('de' => array(array()))));
  204. $this->drupalLogin($this->translator);
  205. $this->assertFalse(node_access('update', $node, $this->loggedInUser));
  206. $this->drupalGet('node/' . $node->nid . '/edit');
  207. $this->assertResponse(403);
  208. $this->assertFalse(node_access('delete', $node, $this->loggedInUser));
  209. $this->drupalGet('node/' . $node->nid . '/delete');
  210. $this->assertResponse(403);
  211. $this->drupalLogin($this->admin_user);
  212. $node = $this->drupalCreateNode(array('type' => 'article', 'language' => 'fr', 'body' => array('fr' => array(array()))));
  213. $this->drupalLogin($this->translator);
  214. $this->assertTrue(node_access('update', $node, $this->loggedInUser));
  215. $this->drupalGet('node/' . $node->nid . '/edit');
  216. $this->assertResponse(200);
  217. $this->assertTrue(node_access('delete', $node, $this->loggedInUser));
  218. $this->drupalGet('node/' . $node->nid . '/delete');
  219. $this->assertResponse(200);
  220. $this->drupalGet('node/' . $node->nid . '/translate');
  221. $query = array('query' => array('translation' => $node->nid, 'target' => 'de'));
  222. $this->assertNoRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'de', $query));
  223. $query = array('query' => array('translation' => $node->nid, 'target' => 'en'));
  224. $this->assertRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'en', $query));
  225. $this->assertRaw(i18n_node_translation_link(t('edit'), 'node/' . $node->nid . '/edit', 'fr'));
  226. $this->drupalLogin($this->admin_user);
  227. if (!$via_role) {
  228. $this->unsetLanguagePermissions($this->translator, array('fr', 'en'));
  229. }
  230. else{
  231. $edit = array(
  232. 'i18n_access_languages[]' => array(),
  233. );
  234. $this->drupalPost('admin/config/regional/language/access', $edit, t('Save configuration'));
  235. $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content', 'access selected languages'));
  236. drupal_static_reset('i18n_access_load_permissions');
  237. drupal_static_reset('node_access');
  238. }
  239. $this->drupalLogin($this->translator);
  240. $this->assertFalse(node_access('update', $node, $this->loggedInUser));
  241. $this->drupalGet('node/' . $node->nid . '/edit');
  242. $this->assertResponse(403);
  243. $this->assertFalse(node_access('delete', $node, $this->loggedInUser));
  244. $this->drupalGet('node/' . $node->nid . '/delete');
  245. $this->assertResponse(403);
  246. $this->drupalGet('node/' . $node->nid . '/translate');
  247. $query = array('query' => array('translation' => $node->nid, 'target' => 'de'));
  248. $this->assertNoRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'de', $query));
  249. $query = array('query' => array('translation' => $node->nid, 'target' => 'en'));
  250. $this->assertNoRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'en', $query));
  251. $this->assertNoRaw(i18n_node_translation_link(t('edit'), 'node/' . $node->nid . '/edit', 'fr'));
  252. }
  253. /**
  254. * Test admin user. User with 'bypass node access' permission should be able to
  255. * update, delete nodes regardless of the language.
  256. */
  257. function testAdminUser() {
  258. $this->drupalLogin($this->admin_user);
  259. $this->drupalGet('node/add/article');
  260. $this->assertField('language', 'Found language selector.');
  261. $languages = language_list();
  262. $languages[LANGUAGE_NONE] = (object)array('language' => LANGUAGE_NONE, 'name' => 'Language Neutral');
  263. foreach ($languages as $language) {
  264. $this->assertLanguageOption($language->language, format_string('Option found for %language, regardless of permission, for administrator.', array('%language' => $language->name)));
  265. }
  266. $this->drupalLogin($this->translator);
  267. $node = $this->drupalCreateNode(array('type' => 'article', 'language' => 'de', 'body' => array('de' => array(array()))));
  268. $this->drupalLogin($this->admin_user);
  269. $this->assertTrue(node_access('update', $node, $this->loggedInUser));
  270. $this->drupalGet('node/' . $node->nid . '/edit');
  271. $this->assertResponse(200);
  272. $this->assertTrue(node_access('delete', $node, $this->loggedInUser));
  273. $this->drupalGet('node/' . $node->nid . '/delete');
  274. $this->assertResponse(200);
  275. $this->drupalGet('node/' . $node->nid . '/translate');
  276. $query = array('query' => array('translation' => $node->nid, 'target' => 'fr'));
  277. $this->assertRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'fr', $query));
  278. $query = array('query' => array('translation' => $node->nid, 'target' => 'en'));
  279. $this->assertRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'en', $query));
  280. $this->assertRaw(i18n_node_translation_link(t('edit'), 'node/' . $node->nid . '/edit', 'de'));
  281. }
  282. }