webform_localization.test 21 KB

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