i18n_menu.test 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. /**
  3. * @file
  4. * Test case for multilingual menus.
  5. */
  6. class i18nMenuTestCase extends Drupali18nTestCase {
  7. public static function getInfo() {
  8. return array(
  9. 'name' => 'Menu translation',
  10. 'group' => 'Internationalization',
  11. 'description' => 'Menu translation functions',
  12. );
  13. }
  14. function setUp() {
  15. parent::setUp(array('i18n_menu', 'translation'));
  16. parent::setUpLanguages(array('administer menu'));
  17. $this->translator = $this->drupalCreateUser(array('translate interface', 'translate user-defined strings'));
  18. }
  19. function testMenuTranslateLocalize() {
  20. // Test filtering for menu blocks.
  21. $menu = $this->createMenu(array('i18n_mode' => I18N_MODE_MULTIPLE));
  22. $neutral_item = $this->createMenuLink(array('menu_name' => $menu['menu_name']));
  23. $default_item = $this->createMenuLink(array('menu_name' => $menu['menu_name'], 'language' => $this->default_language));
  24. $secondary_item = $this->createMenuLink(array('menu_name' => $menu['menu_name'], 'language' => $this->secondary_language));
  25. $block['title'] = $menu['title'];
  26. $block['module'] = 'menu';
  27. $block['delta'] = $menu['menu_name'];
  28. $this->moveBlockToRegion($block, 'sidebar_first');
  29. $this->drupalGet('<front>');
  30. $this->assertText($neutral_item['link_title']);
  31. $this->assertText($default_item['link_title']);
  32. $this->assertNoText($secondary_item['link_title']);
  33. $this->i18nGet($this->secondary_language, '<front>');
  34. $this->assertText($neutral_item['link_title']);
  35. $this->assertNoText($default_item['link_title']);
  36. $this->assertText($secondary_item['link_title']);
  37. // Test filtering for built-in menus.
  38. $edit = array(
  39. 'i18n_mode' => I18N_MODE_MULTIPLE,
  40. );
  41. $this->drupalPost('admin/structure/menu/manage/main-menu/edit', $edit, t('Save'));
  42. $neutral_item = $this->createMenuLink(array('menu_name' => 'main-menu'));
  43. $default_item = $this->createMenuLink(array('menu_name' => 'main-menu', 'language' => $this->default_language));
  44. $secondary_item = $this->createMenuLink(array('menu_name' => 'main-menu', 'language' => $this->secondary_language));
  45. $this->drupalGet('<front>');
  46. $this->assertText($neutral_item['link_title']);
  47. $this->assertText($default_item['link_title']);
  48. $this->assertNoText($secondary_item['link_title']);
  49. $this->i18nGet($this->secondary_language, '<front>');
  50. $this->assertText($neutral_item['link_title']);
  51. $this->assertNoText($default_item['link_title']);
  52. $this->assertText($secondary_item['link_title']);
  53. // Test the same thing with a system menu used as a block.
  54. $block['title'] = $menu['title'];
  55. $block['module'] = 'system';
  56. $block['delta'] = 'main-menu';
  57. $this->moveBlockToRegion($block, 'sidebar_first');
  58. $this->drupalGet('<front>');
  59. $this->assertText($neutral_item['link_title']);
  60. $this->assertText($default_item['link_title']);
  61. $this->assertNoText($secondary_item['link_title']);
  62. $this->i18nGet($this->secondary_language, '<front>');
  63. $this->assertText($neutral_item['link_title']);
  64. $this->assertNoText($default_item['link_title']);
  65. $this->assertText($secondary_item['link_title']);
  66. }
  67. /**
  68. * Test menu items for nodes.
  69. */
  70. function testNodeMenuItems() {
  71. // Create menu and display it in a block.
  72. $menu = $this->createMenu(array(
  73. 'i18n_mode' => I18N_MODE_MULTIPLE,
  74. 'language' => LANGUAGE_NONE,
  75. 'menu_name' => 'test',
  76. ));
  77. $neutral_item = $this->createMenuLink(array('menu_name' => $menu['menu_name']));
  78. $block['title'] = $menu['title'];
  79. $block['module'] = 'menu';
  80. $block['delta'] = $menu['menu_name'];
  81. $this->moveBlockToRegion($block, 'sidebar_first');
  82. $menu_parent = $menu['menu_name'] . ':0';
  83. // Create content type 'page', translation enabled, login as translator
  84. parent::setUpContentTranslation();
  85. $settings = array(
  86. 'menu_options[' . $menu['menu_name'] . ']' => TRUE,
  87. 'menu_parent' => $menu_parent,
  88. 'node_options[promote]' => FALSE,
  89. );
  90. $this->drupalPost('admin/structure/types/manage/page/edit', $settings, t('Save content type'));
  91. // Create nodes with language and menu item: es, en, und
  92. $edit = array(
  93. 'menu[enabled]' => TRUE,
  94. 'menu[parent]' => $menu_parent,
  95. 'promote' => FALSE,
  96. );
  97. // English Page => English menu item
  98. $en_title = $this->randomName(10);
  99. $en_body = $this->randomString(50);
  100. $nodes[] = $en_node = $this->createNode('page', $en_title, $en_body, 'en', $edit + array('menu[link_title]' => $en_title));
  101. // Spanish page => Spanish menu item
  102. $es_title = $this->randomName(10);
  103. $es_body = $this->randomString(50);
  104. $nodes[] = $es_node = $this->createNode('page', $es_title, $es_body, 'es', $edit + array('menu[link_title]' => $es_title));
  105. // Language neutral page, localicable menu item
  106. $und_title = $this->randomName(10);
  107. $und_body = $this->randomString(50);
  108. $nodes[] = $und_node = $this->createNode('page', $und_title, $und_body, LANGUAGE_NONE, $edit + array('menu[link_title]' => $und_title));
  109. // Check menu items have right language and we cannot edit them.
  110. foreach ($nodes as $node) {
  111. menu_node_prepare($node);
  112. $this->assertEqual($node->menu['language'], $node->language, 'Menu item has the same language that the node it belongs to.');
  113. $this->drupalGet('admin/structure/menu/item/' . $node->menu['mlid'] . '/edit');
  114. $this->assertText(t('This menu item belongs to a node, so it will have the same language as the node and cannot be localized.'));
  115. $this->assertNoField('language', 'We cannot edit language for menu items that belong to nodes.');
  116. // Edit the node and submit it to see if the menu link stays enabled.
  117. $this->drupalPost('node/' . $node->nid . '/edit', array(), t('Save'));
  118. }
  119. // Check menu items show up for the right language.
  120. $this->drupalGet('<front>');
  121. $this->assertText($en_title);
  122. $this->assertNoText($es_title);
  123. $this->assertText($und_title);
  124. $this->i18nGet('es', '<front>');
  125. $this->assertText($es_title);
  126. $this->assertNoText($en_title);
  127. $this->assertText($und_title);
  128. // Create string translation for neutral menu item and check it shows up
  129. $translation = $this->randomName(10);
  130. $this->createStringTranslation('menu', $und_title, array('es' => $translation));
  131. $this->drupalGet('<front>');
  132. $this->assertText($und_title);
  133. $this->i18nGet('es', '<front>');
  134. $this->assertText($translation);
  135. }
  136. /**
  137. * Tests if the translation set management works.
  138. */
  139. function testMenuTranslationSets() {
  140. $menu = $this->createMenu(array('i18n_mode' => I18N_MODE_MULTIPLE));
  141. $neutral_item = $this->createMenuLink(array('menu_name' => $menu['menu_name']));
  142. $default_item = $this->createMenuLink(array('menu_name' => $menu['menu_name'], 'language' => $this->default_language));
  143. $secondary_item = $this->createMenuLink(array('menu_name' => $menu['menu_name'], 'language' => $this->secondary_language));
  144. $translationset_edit = array(
  145. 'translations[' . $this->default_language . ']' => $default_item['menu_name'] . ':' . $default_item['mlid'],
  146. 'translations[' . $this->secondary_language . ']' => $secondary_item['menu_name'] . ':' . $secondary_item['mlid'],
  147. );
  148. $translation_set = $this->createMenuLinkTranslationSet($translationset_edit);
  149. // Check if the overview works
  150. $this->drupalGet('admin/structure/menu/manage/translation');
  151. $link = $this->xpath('//*/a[contains(@href,"admin/structure/menu/manage/translation/edit/' . $translation_set->tsid . '")]');
  152. $this->assertTrue(!empty($link), 'Created translation-set found.');
  153. // Check if the edit mode works
  154. $this->drupalGet('admin/structure/menu/manage/translation/edit/' . $translation_set->tsid);
  155. $this->assertFieldByXPath(
  156. "//*[@id='edit-translations-" . $this->default_language . "']/option[@selected]/@value",
  157. $menu['menu_name'] . ':' . $default_item['mlid'],
  158. 'Expected option selection for language ' . $this->default_language . ' found.'
  159. );
  160. $this->assertFieldByXPath(
  161. "//*[@id='edit-translations-" . $this->secondary_language . "']/option[@selected]/@value",
  162. $menu['menu_name'] . ':' . $secondary_item['mlid'],
  163. 'Expected option selection for language ' . $this->secondary_language . ' found.'
  164. );
  165. }
  166. /**
  167. * Tests if on a switch from translatable to non translatable the translation
  168. * sets and links are cleaned up.
  169. */
  170. function testMenuTranslateLocalizeSwitchToNonTranslatable() {
  171. // Test filtering for menu blocks.
  172. $menu = $this->createMenu(array('i18n_mode' => I18N_MODE_MULTIPLE));
  173. // Check current menu mode
  174. $this->drupalGet('admin/structure/menu/manage/' . $menu['menu_name'] . '/edit');
  175. $this->assertFieldByName('i18n_mode', I18N_MODE_MULTIPLE, 'Menu i18n mode set to I18N_MODE_MULTIPLE');
  176. // Setup menu links for testing.
  177. $neutral_item = $this->createMenuLink(array('menu_name' => $menu['menu_name']));
  178. $default_item = $this->createMenuLink(array('menu_name' => $menu['menu_name'], 'language' => $this->default_language));
  179. $secondary_item = $this->createMenuLink(array('menu_name' => $menu['menu_name'], 'language' => $this->secondary_language));
  180. $translationset_edit = array(
  181. 'translations[' . $this->default_language . ']' => $default_item['menu_name'] . ':' . $default_item['mlid'],
  182. 'translations[' . $this->secondary_language . ']' => $secondary_item['menu_name'] . ':' . $secondary_item['mlid'],
  183. );
  184. $translation_set = $this->createMenuLinkTranslationSet($translationset_edit);
  185. $tsid = $translation_set->tsid;
  186. // Test language mode switch
  187. $edit = array(
  188. 'i18n_mode' => I18N_MODE_LANGUAGE,
  189. 'language' => $this->secondary_language,
  190. );
  191. $this->drupalPost('admin/structure/menu/manage/' . $menu['menu_name'] . '/edit', $edit, t('Save'));
  192. $this->drupalGet('admin/structure/menu/manage/' . $menu['menu_name'] . '/edit');
  193. $this->assertFieldByName('i18n_mode', I18N_MODE_LANGUAGE, 'Menu i18n mode changed to I18N_MODE_LANGUAGE');
  194. $this->assertTrue(!empty(i18n_translation_set_load($tsid)->tsid), 'Translation set kept.');
  195. $menu_link_languages = db_select('menu_links')
  196. ->fields('menu_links', array('language'))
  197. ->condition('menu_name', $menu['menu_name'])
  198. ->groupBy('language')
  199. ->execute()
  200. ->fetchCol();
  201. $this->assertTrue((count($menu_link_languages) == 1 && reset($menu_link_languages) === $this->secondary_language), 'Menu link language changed to menu language.');
  202. // Test cleanup.
  203. $edit = array(
  204. 'i18n_mode' => I18N_MODE_NONE,
  205. );
  206. $this->drupalPost('admin/structure/menu/manage/' . $menu['menu_name'] . '/edit', $edit, t('Save'));
  207. $this->drupalGet('admin/structure/menu/manage/' . $menu['menu_name'] . '/edit');
  208. $this->assertFieldByName('i18n_mode', I18N_MODE_NONE, 'Menu i18n mode changed to I18N_MODE_NONE');
  209. $translation_sets = entity_load('i18n_translation', FALSE, array('tsid' => $tsid), TRUE);
  210. $this->assertTrue(empty($translation_sets), 'Translation set deleted.');
  211. $menu_link_languages = db_select('menu_links')
  212. ->fields('menu_links', array('language'))
  213. ->condition('menu_name', $menu['menu_name'])
  214. ->groupBy('language')
  215. ->execute()
  216. ->fetchCol();
  217. $this->assertTrue(((count($menu_link_languages) == 1) && reset($menu_link_languages) === LANGUAGE_NONE), 'Menu link language switched to LANGUAGE_NONE.');
  218. }
  219. /**
  220. * Helper function to create a menu.
  221. */
  222. function createMenu($edit = array()) {
  223. $edit += array(
  224. 'title' => $this->randomName(),
  225. 'menu_name' => substr(hash('sha256', $this->randomName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI),
  226. 'language' => $this->secondary_language,
  227. );
  228. $this->drupalPost('admin/structure/menu/add', $edit, t('Save'));
  229. return menu_load('menu-' . $edit['menu_name']);
  230. }
  231. /**
  232. * Helper function to create a menu link.
  233. */
  234. function createMenuLink($item = array()) {
  235. $item += array(
  236. 'link_title' => $this->randomName(),
  237. 'link_path' => '<front>',
  238. 'customized' => TRUE,
  239. );
  240. return menu_link_load(menu_link_save($item));
  241. }
  242. /**
  243. * Helper function to create a translation set.
  244. */
  245. function createMenuLinkTranslationSet($edit = array()) {
  246. $edit += array(
  247. 'title' => $this->randomName(16),
  248. );
  249. $this->drupalPost('admin/structure/menu/manage/translation/add', $edit, t('Save'));
  250. // Load translation set entity.
  251. $entity = entity_load('i18n_translation', FALSE, array('title' => $edit['title']), TRUE);
  252. if (empty($entity)) {
  253. $this->fail('Could not create a translation set.', 'i18n_translation');
  254. return FALSE;
  255. }
  256. return reset($entity);
  257. }
  258. }