t('Translation Access'), 'description' => t('Test suite for the i18n_access module.'), 'group' => t('i18n'), ); } /** * Implementation of setUp(). */ public function setUp() { parent::setUp(array('locale', 'translation', 'i18n_access', 'i18n_node')); $this->admin_user = $this->drupalCreateUser(array('administer languages', 'administer site configuration', 'access administration pages', 'administer content types', 'administer users', 'bypass node access', 'translate content')); $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content')); $this->visitor = $this->drupalCreateUser(array('access content')); $this->drupalLogin($this->admin_user); $this->addLanguage('fr'); $this->addLanguage('de'); // Set Story content type to use multilingual support with translation. $edit['language_content_type'] = 2; $this->drupalPost('admin/structure/types/manage/article', $edit, t('Save content type')); $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Article')), 'Story content type has been updated.'); } /** * Enable the specified language if it has not been already. * * @param string $language_code * The language code to enable. */ function addLanguage($language_code) { // Check to make sure that language has not already been installed. $this->drupalGet('admin/config/regional/language'); if (strpos($this->drupalGetContent(), 'enabled[' . $language_code . ']') === FALSE) { // Doesn't have language installed so add it. $edit = array(); $edit['langcode'] = $language_code; $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language')); drupal_static_reset('language_list'); // Make sure not using cached version. $languages = language_list('language'); $this->assertTrue(array_key_exists($language_code, $languages), 'Language was installed successfully.'); if (array_key_exists($language_code, $languages)) { $this->assertRaw(t('The language %language has been created and can now be used.', array('%language' => $languages[$language_code]->name)), 'Language has been created.'); } } else { // Ensure that it is enabled. $this->drupalPost(NULL, array('enabled[' . $language_code . ']' => TRUE), t('Save configuration')); $this->assertRaw(t('Configuration saved.'), 'Language successfully enabled.'); } } /** * Sets the language permission for the specified user. Must be logged in as * an 'administer users' privileged user before calling this. * * @param $account * The user account to modify * @param $languages * An array of language codes to give permission for */ function setLanguagePermissions($account, $languages = array()) { $this->assertTrue(user_access('administer users'), 'User has permission to administer users'); $expected = array(); $edit = array(); foreach ($languages as $langcode) { $key = 'i18n_access[' . $langcode . ']'; $edit[$key] = $langcode; $expected[$langcode] = $langcode; } $this->drupalPost('user/' . $account->uid . '/edit', $edit, t('Save')); $actual = i18n_access_load_permissions($account->uid); $this->assertEqual($expected, $actual, 'Language permissions set correctly.', 'i18n_access'); } /** * Unsets the language permission for the specified user. Must be logged in as * an 'administer users' privileged user before calling this. * * @param $account * The user account to modify * @param $languages * An array of language codes to remove permission for */ function unsetLanguagePermissions($account, $languages = array()) { $this->assertTrue(user_access('administer users'), 'User has permission to administer users'); $expected = array(); $edit = array(); foreach ($languages as $langcode) { $key = 'i18n_access[' . $langcode . ']'; $edit[$key] = FALSE; } $this->drupalPost('user/' . $account->uid . '/edit', $edit, t('Save')); drupal_static_reset('i18n_access_load_permissions'); drupal_static_reset('node_access'); $actual = i18n_access_load_permissions($account->uid); $this->assertEqual($expected, $actual, 'Language permissions unset correctly.', 'i18n_access'); } /** * Assert that a language option exists in the language select field on the * current page. * @param $langcode * Value of the language option to assert. * @param $message * Message to display. * @param $group * The group this message belongs to. * @return * TRUE on pass, FALSE on fail. */ function assertLanguageOption($langcode, $message, $group = 'Other') { $xpath = '//select[@name="language"]/option'; $fields = $this->xpath($xpath); // If value specified then check array for match. $found = TRUE; if (isset($langcode)) { $found = FALSE; if ($fields) { foreach ($fields as $field) { if ($field['value'] == $langcode) { $found = TRUE; } } } } return $this->assertTrue($fields && $found, $message, $group); } /** * Assert that a language option does not exist in the language select field * on the current page. * @param $langcode * Value of the language option to assert. * @param $message * Message to display. * @param $group * The group this message belongs to. * @return * TRUE on pass, FALSE on fail. */ function assertNoLanguageOption($langcode, $message, $group = 'Other') { $xpath = '//select[@name="language"]/option'; $fields = $this->xpath($xpath); // If value specified then check array for match. $found = TRUE; if (isset($langcode)) { $found = FALSE; if ($fields) { foreach ($fields as $field) { if ($field['value'] == $langcode) { $found = TRUE; } } } } return $this->assertFalse($fields && $found, $message, $group); } /** * Test translator user. User with 'create article content' permission * should be able to create and edit article nodes only in/for * the languages that they have permissions for. */ function testTranslatorUser() { $this->_testTranslatorNodeAccess(); $this->_testTranslatorNodeAccess(TRUE); } function _testTranslatorNodeAccess($via_role = FALSE) { $this->drupalLogin($this->admin_user); if (!$via_role) { $this->setLanguagePermissions($this->translator, array('en', 'fr')); } else{ $edit = array( 'i18n_access_languages[]' => array('en', 'fr'), ); $this->drupalPost('admin/config/regional/language/access', $edit, t('Save configuration')); $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content', 'access selected languages')); } $this->drupalLogin($this->translator); $this->drupalGet('node/add/article'); $this->assertField('language', 'Found language selector.'); $perms = i18n_access_load_permissions($this->translator->uid); $languages = language_list(); $languages[LANGUAGE_NONE] = (object)array('language' => LANGUAGE_NONE, 'name' => 'Language Neutral'); foreach ($languages as $key => $language) { // TODO: Add in check for language neutral if (isset($perms[$key]) && $perms[$key]) { $this->assertLanguageOption($language->language, format_string('Option found for %language in language selector.', array('%language' => $language->name))); } else { $this->assertNoLanguageOption($language->language, format_string('Option not found for %language in language selector.', array('%language' => $language->name))); } } $this->drupalLogin($this->admin_user); $node = $this->drupalCreateNode(array('type' => 'article', 'language' => 'de', 'body' => array('de' => array(array())))); $this->drupalLogin($this->translator); $this->assertFalse(node_access('update', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/edit'); $this->assertResponse(403); $this->assertFalse(node_access('delete', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/delete'); $this->assertResponse(403); $this->drupalLogin($this->admin_user); $node = $this->drupalCreateNode(array('type' => 'article', 'language' => 'fr', 'body' => array('fr' => array(array())))); $this->drupalLogin($this->translator); $this->assertTrue(node_access('update', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/edit'); $this->assertResponse(200); $this->assertTrue(node_access('delete', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/delete'); $this->assertResponse(200); $this->drupalGet('node/' . $node->nid . '/translate'); $query = array('query' => array('translation' => $node->nid, 'target' => 'de')); $this->assertNoRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'de', $query)); $query = array('query' => array('translation' => $node->nid, 'target' => 'en')); $this->assertRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'en', $query)); $this->assertRaw(i18n_node_translation_link(t('edit'), 'node/' . $node->nid . '/edit', 'fr')); $this->drupalLogin($this->admin_user); if (!$via_role) { $this->unsetLanguagePermissions($this->translator, array('fr', 'en')); } else{ $edit = array( 'i18n_access_languages[]' => array(), ); $this->drupalPost('admin/config/regional/language/access', $edit, t('Save configuration')); $this->translator = $this->drupalCreateUser(array('create article content', 'edit own article content', 'translate content', 'access selected languages')); drupal_static_reset('i18n_access_load_permissions'); drupal_static_reset('node_access'); } $this->drupalLogin($this->translator); $this->assertFalse(node_access('update', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/edit'); $this->assertResponse(403); $this->assertFalse(node_access('delete', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/delete'); $this->assertResponse(403); $this->drupalGet('node/' . $node->nid . '/translate'); $query = array('query' => array('translation' => $node->nid, 'target' => 'de')); $this->assertNoRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'de', $query)); $query = array('query' => array('translation' => $node->nid, 'target' => 'en')); $this->assertNoRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'en', $query)); $this->assertNoRaw(i18n_node_translation_link(t('edit'), 'node/' . $node->nid . '/edit', 'fr')); } /** * Test admin user. User with 'bypass node access' permission should be able to * update, delete nodes regardless of the language. */ function testAdminUser() { $this->drupalLogin($this->admin_user); $this->drupalGet('node/add/article'); $this->assertField('language', 'Found language selector.'); $languages = language_list(); $languages[LANGUAGE_NONE] = (object)array('language' => LANGUAGE_NONE, 'name' => 'Language Neutral'); foreach ($languages as $language) { $this->assertLanguageOption($language->language, format_string('Option found for %language, regardless of permission, for administrator.', array('%language' => $language->name))); } $this->drupalLogin($this->translator); $node = $this->drupalCreateNode(array('type' => 'article', 'language' => 'de', 'body' => array('de' => array(array())))); $this->drupalLogin($this->admin_user); $this->assertTrue(node_access('update', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/edit'); $this->assertResponse(200); $this->assertTrue(node_access('delete', $node, $this->loggedInUser)); $this->drupalGet('node/' . $node->nid . '/delete'); $this->assertResponse(200); $this->drupalGet('node/' . $node->nid . '/translate'); $query = array('query' => array('translation' => $node->nid, 'target' => 'fr')); $this->assertRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'fr', $query)); $query = array('query' => array('translation' => $node->nid, 'target' => 'en')); $this->assertRaw(i18n_node_translation_link(t('add translation'), 'node/add/article', 'en', $query)); $this->assertRaw(i18n_node_translation_link(t('edit'), 'node/' . $node->nid . '/edit', 'de')); } }