webform_localization.test 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. <?php
  2. /**
  3. * @file
  4. * Webform localization module tests.
  5. */
  6. class WebformLocalizationWebTestCase extends DrupalWebTestCase {
  7. // Webform test class instance.
  8. public $wtc;
  9. // Users.
  10. public $admin_user;
  11. public $translator;
  12. public $normal_user;
  13. /**
  14. * Implements setUp().
  15. */
  16. function setUp($modules = array()) {
  17. $modules = array_merge($modules, array('locale', 'webform', 'webform_localization'));
  18. parent::setUp($modules);
  19. // We load webform test class to reuse webform and components creation functions.
  20. module_load_include('test', 'webform', 'tests/webform');
  21. $this->wtc = new WebformTestCase;
  22. // Setup users.
  23. $this->admin_user = $this->drupalCreateUser(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer blocks', 'access administration pages', 'translate content', 'create webform content',
  24. 'edit any webform content',
  25. 'access all webform results',
  26. 'edit all webform submissions',
  27. 'delete all webform submissions',
  28. 'translate interface',
  29. 'translate user-defined strings'));
  30. $this->translator = $this->drupalCreateUser(array('translate content',
  31. 'create webform content',
  32. 'edit any webform content',
  33. 'access all webform results',
  34. 'translate interface',
  35. 'translate user-defined strings'));
  36. $this->normal_user = $this->drupalCreateUser(array('access content', 'edit own webform submissions'));
  37. // Fix for reuse of webform test class.
  38. $this->wtc->webform_users['admin'] = $this->admin_user;
  39. $this->wtc->webform_users['admin']->profile_gender = array('Female', 'Male');
  40. $this->drupalLogin($this->admin_user);
  41. // Add languages.
  42. $this->addLanguage('en');
  43. $this->addLanguage('es');
  44. $this->addLanguage('de');
  45. // Enable URL language detection and selection.
  46. $edit = array('language[enabled][locale-url]' => TRUE);
  47. $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
  48. $this->assertRaw(t('Language negotiation configuration saved.'), 'URL language detection enabled.');
  49. drupal_static_reset('locale_url_outbound_alter');
  50. }
  51. /**
  52. * Create a webform node with test components.
  53. */
  54. function createWebformForm() {
  55. if (isset($this->_webform_node)) {
  56. return $this->_webform_node;
  57. }
  58. $settings = array(
  59. 'type' => 'webform',
  60. 'language' => 'en',
  61. 'uid' => '1',
  62. 'status' => '1',
  63. 'promote' => '1',
  64. 'moderate' => '0',
  65. 'sticky' => '0',
  66. 'tnid' => '0',
  67. 'translate' => '0',
  68. 'title' => 'Webform title in english',
  69. 'body' => array('en' => array(
  70. array('value' => 'Donec placerat. Nullam nibh dolor, blandit sed, fermentum id, imperdiet sit amet, neque. Nam mollis ultrices justo.
  71. Sed tempor. Sed vitae tellus. Etiam sem arcu, eleifend sit amet, gravida eget, porta at, wisi. Nam non lacus vitae ipsum viverra
  72. pretium. Phasellus massa. Fusce magna sem, gravida in, feugiat ac, molestie eget, wisi. Fusce consectetuer luctus ipsum.
  73. Vestibulum nunc. Suspendisse dignissim adipiscing libero. Integer leo. Sed pharetra ligula a dui. Quisque ipsum nibh,
  74. llamcorper eget, pulvinar sed, posuere vitae, nulla. Sed varius nibh ut lacus. Curabitur fringilla. Nunc est ipsum,
  75. retium quis, dapibus sed, varius non, lectus. Proin a quam. Praesent lacinia, eros quis aliquam porttitor, urna lacus
  76. volutpat urna, ut fermentum neque mi egestas dolor.'))),
  77. 'teaser' => array('en' => array(
  78. array('value' => 'Donec placerat. Nullam nibh dolor, blandit sed, fermentum id, imperdiet sit amet, neque. Nam mollis ultrices justo.
  79. Sed tempor. Sed vitae tellus. Etiam sem arcu, eleifend sit amet, gravida eget, porta at, wisi. Nam non lacus vitae ipsum
  80. viverra pretium. Phasellus massa. Fusce magna sem, gravida in, feugiat ac, molestie eget, wisi. Fusce consectetuer luctus
  81. ipsum. Vestibulum nunc. Suspendisse dignissim adipiscing libero. Integer leo. Sed pharetra ligula a dui. Quisque ipsum nibh,
  82. ullamcorper eget, pulvinar sed, posuere vitae, nulla. Sed varius nibh ut lacus. Curabitur fringilla.'))),
  83. 'log' => '',
  84. 'format' => '1',
  85. 'webform' => array(
  86. 'confirmation' => 'Thanks!',
  87. ) + webform_node_defaults(),
  88. );
  89. $components = $this->wtc->testWebformComponents();
  90. /*
  91. * @todo : We need further debug to find how to support
  92. * this components or why are they breaking everything
  93. */
  94. unset($components['select_no_default_zero']);
  95. unset($components['radios_zero']);
  96. unset($components['select_zero']);
  97. unset($components['select_optgroup']);
  98. $cid = 0;
  99. foreach ($components as $key => $component_info) {
  100. $cid++;
  101. $settings['webform']['components'][$cid] = $component_info['component'];
  102. $settings['webform']['components'][$cid]['cid'] = $cid;
  103. $settings['webform']['components'][$cid]['pid'] = 0;
  104. }
  105. $this->_webform_node = $this->drupalCreateNode($settings);
  106. return $this->_webform_node;
  107. }
  108. /**
  109. * Install a the specified language if it has not been already. Otherwise make sure that
  110. * the language is enabled.
  111. *
  112. * @param $language_code
  113. * The language code the check.
  114. */
  115. function addLanguage($language_code) {
  116. // Check to make sure that language has not already been installed.
  117. $this->drupalGet('admin/config/regional/language');
  118. if (strpos($this->drupalGetContent(), 'enabled[' . $language_code . ']') === FALSE) {
  119. // Doesn't have language installed so add it.
  120. $edit = array();
  121. $edit['langcode'] = $language_code;
  122. $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
  123. // Make sure we are not using a stale list.
  124. drupal_static_reset('language_list');
  125. $languages = language_list('language');
  126. $this->assertTrue(array_key_exists($language_code, $languages), 'Language was installed successfully.');
  127. if (array_key_exists($language_code, $languages)) {
  128. $this->assertRaw(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => $languages[$language_code]->name, '@locale-help' => url('admin/help/locale'))), 'Language has been created.');
  129. }
  130. }
  131. elseif ($this->xpath('//input[@type="checkbox" and @name=:name and @checked="checked"]', array(':name' => 'enabled[' . $language_code . ']'))) {
  132. // It's installed and enabled. No need to do anything.
  133. $this->assertTrue(TRUE, 'Language [' . $language_code . '] already installed and enabled.');
  134. }
  135. else {
  136. // It's installed but not enabled. Enable it.
  137. $this->assertTrue(TRUE, 'Language [' . $language_code . '] already installed.');
  138. $this->drupalPost(NULL, array('enabled[' . $language_code . ']' => TRUE), t('Save configuration'));
  139. $this->assertRaw(t('Configuration saved.'), 'Language successfully enabled.');
  140. }
  141. }
  142. /**
  143. * Create a translation for the specified webform in the specified
  144. * language.
  145. *
  146. * @param $node
  147. * The basic page to create translation for.
  148. * @param $title
  149. * Title of basic page in specified language.
  150. * @param $body
  151. * Body of basic page in specified language.
  152. * @param $language
  153. * Language code.
  154. */
  155. function createWebformTranslation($node, $title, $body, $language) {
  156. $this->drupalGet('node/add/webform', array('query' => array('translation' => $node->nid, 'target' => $language)));
  157. $langcode = $language;
  158. $body_key = "body[" . LANGUAGE_NONE . "][0][value]";
  159. //$this->assertFieldByXPath('//input[@id="edit-title"]', $node->title, "Original title value correctly populated.");
  160. //$this->assertFieldByXPath("//textarea[@name='$body_key']", $node->body[$node->language][0]['value'], "Original body value correctly populated.");
  161. $edit = array();
  162. $edit["title"] = $title;
  163. //$edit[$body_key] = $body;
  164. $this->drupalPost(NULL, $edit, t('Save'));
  165. $this->assertRaw(t('Webform %title has been created.', array('%title' => $title)), 'Translation created.');
  166. // Check to make sure that translation was successful.
  167. $translation = $this->drupalGetNodeByTitle($title);
  168. $this->assertTrue($translation, 'Node found in database.');
  169. $this->assertTrue($translation->tnid == $node->nid, 'Translation set id correctly stored.');
  170. return $translation;
  171. }
  172. /**
  173. * Create translation for string in textgroup
  174. *
  175. * @param $translations
  176. * Optional array of langcode => translation. If not present, it will be generated.
  177. */
  178. function createStringTranslation($textgroup, $name, $translations = NULL) {
  179. // This is the language indicator on the translation search screen for
  180. // untranslated strings. Copied straight from locale.inc.
  181. $language_indicator = "<em class=\"locale-untranslated\">";
  182. // Search for the name and translate it.
  183. $search = array(
  184. 'string' => $name,
  185. 'language' => 'all',
  186. 'translation' => 'untranslated',
  187. 'group' => $textgroup,
  188. );
  189. $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
  190. // assertText() seems to remove the input field where $name always could be
  191. // found, so this is not a false assert. See how assertNoText succeeds
  192. // later.
  193. $this->assertText(check_plain($name), 'Search found the name.');
  194. $this->assertRaw($language_indicator, 'Name is untranslated.');
  195. // Is not always the only result, if there is more than one click the first.
  196. if ($this->countString(check_plain($name)) > 1) {
  197. $this->clickLink(t('edit'), 0);
  198. }
  199. else {
  200. $this->clickLink(t('edit'));
  201. }
  202. // We save the lid from the path.
  203. $matches = array();
  204. preg_match('!admin/config/regional/translate/edit/(\d+)!', $this->getUrl(), $matches);
  205. $lid = $matches[1];
  206. /*
  207. * Using check_plain() and wordwrap() as i18n_string_locale_translate_edit_form().
  208. * Assert fails otherwise.
  209. */
  210. $this->assertRaw(check_plain(wordwrap($name, 0)), t($name . ' name found on edit screen.'));
  211. foreach ($translations as $langcode => $translation) {
  212. $edit["translations[$langcode]"] = $translation;
  213. }
  214. $this->drupalPost(NULL, $edit, t('Save translations'));
  215. $this->assertText(t('The string has been saved.'), 'The string has been saved.');
  216. $this->assertEqual($this->getUrl(), url('admin/config/regional/translate/translate', array('absolute' => TRUE)), 'Correct page redirection.');
  217. $search = array(
  218. 'string' => $name,
  219. 'language' => 'all',
  220. 'translation' => 'translated',
  221. 'group' => $textgroup,
  222. );
  223. $this->drupalPost('admin/config/regional/translate/translate', $search, t('Filter'));
  224. $this->assertText(check_plain($name), 'Search found the name.');
  225. $this->assertNoRaw($language_indicator, 'Name is translated.');
  226. return $translations;
  227. }
  228. /**
  229. * Get all languages that are not default
  230. */
  231. public function getOtherLanguages() {
  232. $languages = language_list();
  233. unset($languages[language_default('language')]);
  234. return $languages;
  235. }
  236. public function countString($string) {
  237. if ($this->plainTextContent === FALSE) {
  238. $this->plainTextContent = filter_xss($this->drupalGetContent(), array());
  239. }
  240. return substr_count($this->plainTextContent, $string);
  241. }
  242. }
  243. class WebformLocalizationStringTranslationTestCase extends WebformLocalizationWebTestCase {
  244. /**
  245. * Implements getInfo().
  246. */
  247. public static function getInfo() {
  248. return array(
  249. 'name' => 'Webform Localization',
  250. 'description' => 'Webform localization String Translations Tests.',
  251. 'group' => 'Webform Localization',
  252. );
  253. }
  254. /**
  255. * Set up test.
  256. */
  257. public function setUp($modules = array()) {
  258. parent::setUp(array('translation', 'i18n', 'i18n_string'));
  259. // Set "Webform" content type to use multilingual support with translation.
  260. $this->drupalGet('admin/structure/types/manage/webform');
  261. $edit = array();
  262. $edit['language_content_type'] = 2;
  263. $this->drupalPost('admin/structure/types/manage/webform', $edit, t('Save content type'));
  264. $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Webform')), 'Webform content type has been updated.');
  265. }
  266. /**
  267. * Test creating a webform and enabling localization by string translation
  268. */
  269. function testWebformLocalizationStringTranslation() {
  270. $this->drupalLogin($this->admin_user);
  271. /**
  272. * Create the Webform test node, and enable
  273. * localization by string translation feature
  274. */
  275. $node = $this->createWebformForm();
  276. // Submit translation in Spanish.
  277. $node_translation_title = 'Webform title in Spanish';
  278. $node_translation_body = 'Content in Spanish';
  279. $node_translation1 = $this->createWebformTranslation($node, $node_translation_title, $node_translation_body, 'es');
  280. // Submit translation in German.
  281. $node_translation_title = 'Webform title in German';
  282. $node_translation_body = 'Content in German';
  283. $node_translation2 = $this->createWebformTranslation($node, $node_translation_title, $node_translation_body, 'de');
  284. /**
  285. * Enables localization by string translation and reuse the single webform
  286. * across the translation set.
  287. */
  288. $edit = array();
  289. $edit['expose_strings'] = TRUE;
  290. $edit['single_webform'] = TRUE;
  291. $this->drupalPost('node/' . $node->nid . '/webform/configure', $edit, t('Save configuration'));
  292. $this->assertRaw(t('The form settings have been updated.'), 'Webform string translation and single webform enabled.');
  293. // Checks for webform components in the Spanish node
  294. $this->drupalGet('es/node/' . $node_translation1->nid);
  295. foreach ($node->webform['components'] as $key => $value) {
  296. if ($value['name'] == 'Hidden') {
  297. $this->assertNoRaw($value['name'], format_string('The %c webform component is not present.', array('%c' => $value['name'])), 'Spanish Webform translation');
  298. CONTINUE;
  299. }
  300. $this->assertRaw($value['name'], format_string('The %c webform component is present.', array('%c' => $value['name'])), 'Spanish Webform translation');
  301. }
  302. // Checks for webform components in the Deutsch node
  303. $this->drupalGet('de/node/' . $node_translation2->nid);
  304. foreach ($node->webform['components'] as $key => $value) {
  305. if ($value['name'] == 'Hidden') {
  306. $this->assertNoRaw($value['name'], format_string('The %c webform component is not present.', array('%c' => $value['name'])), 'German Webform translation');
  307. CONTINUE;
  308. }
  309. $this->assertRaw($value['name'], format_string('The %c webform component is present.', array('%c' => $value['name'])), 'Deutsch Webform translation');
  310. }
  311. // Refresh webform strings
  312. $edit = array();
  313. $edit['groups[webform]'] = 'webform';
  314. $this->drupalPost('admin/config/regional/translate/i18n_string', $edit, t('Refresh strings'));
  315. // Select webform localization options that match this node ID.
  316. $options = db_select('locales_source')
  317. ->fields('locales_source')
  318. ->condition('textgroup', 'webform', '=')
  319. ->execute()
  320. ->fetchAllAssoc('lid', PDO::FETCH_ASSOC);
  321. // Translates webform components.
  322. $translations = array();
  323. $extra_translations = array();
  324. foreach ($options as $key => $value) {
  325. $name = $value['source'];
  326. $translations['de'] = 'de:' . $name;
  327. $translations['es'] = 'es:' . $name;
  328. $this->createStringTranslation('webform', $name, $translations);
  329. // We take out confirmation to check after submit.
  330. if (strpos($value['location'], 'confirmation')) {
  331. $extra_translations['confirmation'] = $value['source'];
  332. unset($options[$key]);
  333. }
  334. }
  335. $this->drupalGet('es/node/' . $node_translation1->nid);
  336. foreach ($options as $key => $value) {
  337. list(, $cid, ) = explode(':', $value['context']);
  338. $component = $node->webform['components'][$cid];
  339. $name = $value['source'];
  340. $translation = 'es:' . $name;
  341. if ($name == 'Hidden') {
  342. CONTINUE;
  343. }
  344. $this->assertRaw($translation, format_string('%c translation is present.', array('%c' => $name)), 'Spanish Webform translation');
  345. }
  346. $this->drupalGet('de/node/' . $node_translation2->nid);
  347. foreach ($options as $key => $value) {
  348. $name = $value['source'];
  349. $translation = 'de:' . $name;
  350. if ($name == 'Hidden') {
  351. CONTINUE;
  352. }
  353. $this->assertRaw($translation, format_string('%c translation is present.', array('%c' => $name)), 'Deutsch Webform translation');
  354. }
  355. }
  356. }
  357. class WebformLocalizationApiTestCase extends WebformLocalizationWebTestCase {
  358. /**
  359. * Test info.
  360. */
  361. public static function getInfo() {
  362. return array(
  363. 'name' => 'Test Webform Localization API.',
  364. 'description' => 'Test webform and webform localization interaction at API level.',
  365. 'group' => 'Webform Localization',
  366. );
  367. }
  368. /**
  369. * Set up test.
  370. */
  371. public function setUp($modules = array()) {
  372. parent::setUp(array('translation', 'i18n', 'i18n_string'));
  373. // Set "Webform" content type to use multilingual support with translation.
  374. $this->drupalGet('admin/structure/types/manage/webform');
  375. $edit = array();
  376. $edit['language_content_type'] = 2;
  377. $this->drupalPost('admin/structure/types/manage/webform', $edit, t('Save content type'));
  378. $this->assertRaw(t('The content type %type has been updated.', array('%type' => 'Webform')), 'Webform content type has been updated.');
  379. }
  380. /**
  381. * Test submissions API function with webform localization presence.
  382. */
  383. function testWebformLocalizationApi() {
  384. $this->drupalLogin($this->admin_user);
  385. $node = $this->createWebformForm();
  386. /**
  387. * Enables localization by string translation and reuse the single webform
  388. * across the translation set.
  389. */
  390. $edit = array();
  391. $edit['expose_strings'] = TRUE;
  392. $edit['single_webform'] = TRUE;
  393. $this->drupalPost('node/' . $node->nid . '/webform/configure', $edit, t('Save configuration'));
  394. $this->assertRaw(t('The form settings have been updated.'), 'Webform string translation and single webform enabled.');
  395. module_load_include('inc', 'webform', 'includes/webform.submissions');
  396. $this->assertFalse(webform_get_submissions($node->nid), "Function webform_get_submission($node->nid,1000) work correctly with empty submissions.");
  397. }
  398. }