synonyms.test 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247
  1. <?php
  2. /**
  3. * @file
  4. * Tests for the Synonyms module.
  5. */
  6. /**
  7. * Base class for all Synonyms web test cases.
  8. */
  9. abstract class SynonymsWebTestCase extends DrupalWebTestCase {
  10. /**
  11. * Fully loaded user object of an admin user that has required access rights.
  12. *
  13. * @var object
  14. */
  15. protected $admin;
  16. /**
  17. * SetUp method.
  18. */
  19. public function setUp() {
  20. parent::setUp(array('synonyms'));
  21. $this->admin = $this->drupalCreateUser(array(
  22. 'administer taxonomy',
  23. 'administer content types',
  24. 'bypass node access',
  25. 'search content',
  26. ));
  27. }
  28. /**
  29. * Return last inserted term into the specified vocabulary.
  30. *
  31. * @param object $vocabulary
  32. * Fully loaded taxonomy vocabulary object
  33. *
  34. * @return object
  35. * Fully loaded taxonomy term object of the last interted term into
  36. * the specified vocabulary
  37. */
  38. protected function getLastTerm($vocabulary) {
  39. drupal_static_reset();
  40. $tree = taxonomy_get_tree($vocabulary->vid);
  41. $max = 0;
  42. $term = NULL;
  43. foreach ($tree as $v) {
  44. if ($v->tid > $max) {
  45. $max = $v->tid;
  46. $term = $v;
  47. }
  48. }
  49. $term = entity_load_unchanged('taxonomy_term', $term->tid);
  50. return $term;
  51. }
  52. }
  53. /**
  54. * Test Synonyms functionality of synonyms module.
  55. */
  56. class SynonymsSynonymsWebTestCase extends SynonymsWebTestCase {
  57. protected $vocabularies = array(
  58. 'enabled' => TRUE,
  59. 'disabled' => FALSE,
  60. );
  61. /**
  62. * GetInfo method.
  63. */
  64. public function getInfo() {
  65. return array(
  66. 'name' => 'Taxonomy synonyms',
  67. 'description' => 'Ensure that the feature "synonyms" works correctly with taxonomy terms.',
  68. 'group' => 'Synonyms',
  69. );
  70. }
  71. /**
  72. * SetUp method.
  73. */
  74. public function setUp() {
  75. parent::setUp();
  76. // Creating vocabularies.
  77. $this->drupalLogin($this->admin);
  78. foreach ($this->vocabularies as $k => $v) {
  79. $name = $this->randomName();
  80. $this->drupalPost('admin/structure/taxonomy/add', array(
  81. 'name' => $name,
  82. 'machine_name' => $k,
  83. 'description' => $this->randomName(),
  84. 'synonyms[synonyms][' . SYNONYMS_DEFAULT_FIELD_NAME . ']' => $v,
  85. ), 'Save');
  86. $this->vocabularies[$k] = taxonomy_vocabulary_machine_name_load($k);
  87. }
  88. // Flushing cache.
  89. _field_info_collate_fields(TRUE);
  90. }
  91. /**
  92. * Test the disabled taxonomy synonyms feature.
  93. */
  94. public function testSynonymsDisabled() {
  95. $this->drupalGet('admin/structure/taxonomy/disabled/add');
  96. $this->assertNoFieldById('edit-synonyms-synonyms-und-0-value');
  97. $this->drupalGet('admin/structure/taxonomy/enabled/add');
  98. $this->assertFieldById('edit-synonyms-synonyms-und-0-value');
  99. // Making sure that after disabling "synonyms" the synonyms field
  100. // is no longer available on taxonomy term add page.
  101. $this->drupalPost('admin/structure/taxonomy/enabled/edit', array(
  102. 'synonyms[synonyms][' . SYNONYMS_DEFAULT_FIELD_NAME . ']' => FALSE,
  103. ), 'Save');
  104. $this->drupalGet('admin/structure/taxonomy/enabled/add');
  105. $this->assertNoFieldById('edit-synonyms-synonyms-und-0-value');
  106. }
  107. /**
  108. * Test the functionality of synonyms.
  109. */
  110. public function testSynonyms() {
  111. $name = $this->randomName();
  112. $synonym = $this->randomName();
  113. $parent_synonym = $this->randomName();
  114. // Creating terms for testing synonyms_get_term_synonyms().
  115. $synonym1 = $this->randomName();
  116. $synonym2 = $this->randomName();
  117. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  118. 'name' => $this->randomName(),
  119. 'description[value]' => $this->randomName(),
  120. ), 'Save');
  121. $no_synonyms_term = $this->getLastTerm($this->vocabularies['enabled']);
  122. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  123. 'name' => $this->randomName(),
  124. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $synonym1,
  125. ), 'Save');
  126. $one_synonym_term = $this->getLastTerm($this->vocabularies['enabled']);
  127. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  128. 'name' => $this->randomName(),
  129. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $synonym1,
  130. ), 'Add another item');
  131. $this->drupalPost(NULL, array(
  132. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][1][value]' => $synonym2,
  133. ), 'Save');
  134. $two_synonyms_term = $this->getLastTerm($this->vocabularies['enabled']);
  135. // Creating an identical parent term in order to test
  136. // $parent parameter in our functions.
  137. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  138. 'name' => $name,
  139. 'description[value]' => $this->randomName(),
  140. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $synonym,
  141. ), 'Add another item');
  142. $this->drupalPost(NULL, array(
  143. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][1][value]' => $parent_synonym,
  144. ), 'Save');
  145. $term_parent = $this->getLastTerm($this->vocabularies['enabled']);
  146. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  147. 'name' => $name,
  148. 'description[value]' => $this->randomName(),
  149. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $synonym,
  150. 'parent[]' => array($term_parent->tid),
  151. ), 'Save');
  152. $term = $this->getLastTerm($this->vocabularies['enabled']);
  153. $this->drupalGet('taxonomy/term/' . $term->tid);
  154. // Asserting the presence of synonym string.
  155. $this->assertText($synonym, 'The synonym string is present on taxonomy term view page');
  156. // Testing the function synonyms_get_term_synonyms().
  157. $synonyms = synonyms_get_term_synonyms($no_synonyms_term);
  158. $this->assertTrue(empty($synonyms), 'Successfully called synonyms_get_term_synonyms() for a term without synonyms.');
  159. $synonyms = synonyms_get_term_synonyms($one_synonym_term);
  160. $this->assertTrue(count($synonyms) == 1 && $synonyms[0]['value'] == $synonym1, 'Sucessfully called synonyms_get_term_synonyms for a term with single synonym.');
  161. $synonyms = synonyms_get_term_synonyms($two_synonyms_term);
  162. $this->assertTrue(count($synonyms) == 2 && $synonyms[0]['value'] == $synonym1 && $synonyms[1]['value'] == $synonym2, 'Sucessfully called synonyms_get_term_synonyms for a term with 2 synonyms.');
  163. // Testing the function synonyms_get_term_by_synonym().
  164. $tid = synonyms_get_term_by_synonym(drupal_strtoupper($synonym), $this->vocabularies['enabled'], $term_parent->tid);
  165. $this->assertEqual($tid, $term->tid, 'Sucessfully looked up term by its synonym.');
  166. $tid = synonyms_get_term_by_synonym(drupal_strtoupper($name), $this->vocabularies['enabled'], $term_parent->tid);
  167. $this->assertEqual($tid, $term->tid, 'Sucessfully looked up term by its name.');
  168. // Now submitting a non-existing name.
  169. $tid = synonyms_get_term_by_synonym($parent_synonym, $this->vocabularies['enabled'], $term_parent->tid);
  170. $this->assertEqual($tid, 0, 'synonyms_get_term_by_synonym() returns 0 if the term is not found (considering $parent parameter).');
  171. // Testing the function synonyms_add_term_by_synonym().
  172. $tid = synonyms_add_term_by_synonym(drupal_strtolower($name), $this->vocabularies['enabled'], $term_parent->tid);
  173. $this->assertEqual($tid, $term->tid, 'Sucessfully called synonyms_add_term_by_synonym() on an existing title and no new term was created.');
  174. $tid = synonyms_add_term_by_synonym(drupal_strtolower($synonym), $this->vocabularies['enabled'], $term_parent->tid);
  175. $this->assertEqual($tid, $term->tid, 'Sucessfully called synonyms_add_term_by_synonym() on an existing synonym and no new term was created.');
  176. drupal_static_reset();
  177. $tid = synonyms_add_term_by_synonym($parent_synonym, $this->vocabularies['enabled'], $term_parent->tid);
  178. $new_term = taxonomy_term_load($tid);
  179. $new_term_parents = array_keys(taxonomy_get_parents($new_term->tid));
  180. $this->assertEqual($parent_synonym, $new_term->name, 'Successfully called synonyms_add_term_by_synonym() on a new title and a new term was created.');
  181. $this->assertNotEqual($new_term->tid, $term_parent->tid, 'Successfully called synonyms_add_term_by_synonym() on a synonym of $parent. New term was created instead of returning $parent\'s tid.');
  182. $this->assertTrue(in_array($term_parent->tid, $new_term_parents), 'Successfully called synonyms_add_term_by_synonym(). New term is assigned as a child to supplied $parent parameter.');
  183. // Disabling functionality of synonyms for "enabled" vocabulary
  184. // and making sure it has cleaned up all its functionality.
  185. $this->drupalPost('admin/structure/taxonomy/enabled/edit', array(
  186. 'synonyms[synonyms][' . SYNONYMS_DEFAULT_FIELD_NAME . ']' => FALSE,
  187. ), 'Save');
  188. $this->drupalGet('taxonomy/term/' . $term->tid);
  189. // Asserting the absence of synonym string.
  190. $this->assertNoText($synonym, 'The synonym string is no longer present on taxonomy term view page after disabling "synonyms" feature for a vocabulary');
  191. $term = array_pop(entity_load('taxonomy_term', array($term->tid), array(), TRUE));
  192. $this->assertFalse(isset($term->{SYNONYMS_DEFAULT_FIELD_NAME}), 'The term no longer has synonyms field after disabling "synonyms" feature for a vocabulary');
  193. // Testing synonyms_get_term_synonums() function.
  194. $synonyms = synonyms_get_term_synonyms($no_synonyms_term);
  195. $this->assertTrue(empty($synonyms), 'Successfully called synonyms_get_term_synonyms() on a term without synonyms after disabling "synonyms" feature');
  196. $synonyms = synonyms_get_term_synonyms($one_synonym_term);
  197. $this->assertTrue(empty($synonyms), 'Successfully called synonyms_get_term_synonyms() on a term with single synonym after disabling "synonyms" feature');
  198. $synonyms = synonyms_get_term_synonyms($two_synonyms_term);
  199. $this->assertTrue(empty($synonyms), 'Successfully called synonyms_get_term_synonyms() on a term with 2 synonyms after disabling "synonyms" feature');
  200. $tid = synonyms_get_term_by_synonym(drupal_strtoupper($synonym), $this->vocabularies['enabled']);
  201. $this->assertEqual($tid, 0, 'synonyms_get_term_by_synonym() returns 0 after disabling "synonyms" feature for a vocabulary');
  202. $tid = synonyms_get_term_by_synonym(drupal_strtoupper($name), $this->vocabularies['enabled'], $term_parent->tid);
  203. $this->assertEqual($tid, $term->tid, 'synonyms_get_term_by_synonym() returns $term->tid even after disabling "synonyms" feature if looking up by term title');
  204. // Testing synonyms_add_term_by_synonym() function.
  205. $tid = synonyms_add_term_by_synonym(drupal_strtolower($name), $this->vocabularies['enabled'], $term_parent->tid);
  206. $this->assertEqual($tid, $term->tid, 'Successfully called synonyms_add_term_by_synonym() on an existing title and no new term was created after disabling "synonyms" feature.');
  207. $tid = synonyms_add_term_by_synonym(drupal_strtolower($synonym), $this->vocabularies['enabled'], $term_parent->tid);
  208. $new_term = taxonomy_term_load($tid);
  209. $new_term_parents = array_keys(taxonomy_get_parents($new_term->tid));
  210. $this->assertFalse(in_array($new_term->tid, array($term->tid, $term_parent->tid)), 'Successfully called synonyms_add_term_by_synonym() using previous synonym and a new term was created (because the vocabulary has disabled "synonyms" feature)');
  211. $this->assertTrue(in_array($term_parent->tid, $new_term_parents), 'Successfully called synonyms_add_term_by_synonym(). New term is assigned as a child to supplied $parent parameter with disabled "synonyms" feature.');
  212. $tid = synonyms_add_term_by_synonym($parent_synonym, $this->vocabularies['enabled']);
  213. $new_term = array_pop(entity_load('taxonomy_term', array($tid), array(), TRUE));
  214. $this->assertEqual($parent_synonym, $new_term->name, 'Successfully called synonyms_add_term_by_synonym() on an new title and a new term was created.');
  215. $this->assertFalse(in_array($new_term->tid, array($term->tid, $term_parent->tid)), 'Successfully called synonyms_add_term_by_synonym() on the synonyn of parent term. New term was created (because the vocabulary has disabled "synonyms" feature)');
  216. }
  217. }
  218. /**
  219. * Test "Synonym friednly autocomplete" widget of Synonyms module.
  220. */
  221. class AutocompleteSynonymsWebTestCase extends SynonymsWebTestCase {
  222. protected $vocabularies = array(
  223. 'enabled' => TRUE,
  224. 'disabled' => FALSE,
  225. );
  226. protected $terms = array(
  227. 'enabled' => array(),
  228. 'disabled' => array(),
  229. );
  230. /**
  231. * GetInfo method.
  232. */
  233. public function getInfo() {
  234. return array(
  235. 'name' => 'Taxonomy synonyms autocomplete',
  236. 'description' => 'Ensure that the "synonym friendly autocomplete" widget works correctly with taxonomy terms.',
  237. 'group' => 'Synonyms',
  238. );
  239. }
  240. /**
  241. * SetUp method.
  242. */
  243. public function setUp() {
  244. parent::setUp();
  245. // Creating vocabularies.
  246. $this->drupalLogin($this->admin);
  247. foreach ($this->vocabularies as $k => $v) {
  248. $name = $this->randomName();
  249. $this->drupalPost('admin/structure/taxonomy/add', array(
  250. 'name' => $name,
  251. 'machine_name' => $k,
  252. 'description' => $this->randomName(),
  253. 'synonyms[synonyms][' . SYNONYMS_DEFAULT_FIELD_NAME . ']' => $v,
  254. ), 'Save');
  255. $this->vocabularies[$k] = taxonomy_vocabulary_machine_name_load($k);
  256. }
  257. // Creating a test content type.
  258. $this->drupalPost('admin/structure/types/add', array(
  259. 'name' => 'Synonyms Test Content',
  260. 'type' => 'synonyms_test_content',
  261. ), 'Save content type');
  262. // Attaching each vocabulary term reference field to the new content type.
  263. foreach ($this->vocabularies as $k => $v) {
  264. $this->drupalPost('admin/structure/types/manage/synonyms_test_content/fields', array(
  265. 'fields[_add_new_field][label]' => 'Synonym Terms ' . $k,
  266. 'fields[_add_new_field][field_name]' => 'synonyms_term_' . $k,
  267. 'fields[_add_new_field][type]' => 'taxonomy_term_reference',
  268. 'fields[_add_new_field][widget_type]' => 'synonyms_autocomplete',
  269. ), 'Save');
  270. $this->drupalPost(NULL, array(
  271. 'field[settings][allowed_values][0][vocabulary]' => $v->machine_name,
  272. ), 'Save field settings');
  273. $this->drupalPost(NULL, array(
  274. 'field[cardinality]' => FIELD_CARDINALITY_UNLIMITED,
  275. ), 'Save settings');
  276. }
  277. // Flushing static cache.
  278. _field_info_collate_fields(TRUE);
  279. // Now creating taxonomy tree for each vocabularies.
  280. // For synonym-disbaled vocabulary just one term is good enough.
  281. $name = $this->randomName();
  282. $this->drupalPost('admin/structure/taxonomy/disabled/add', array(
  283. 'name' => $name,
  284. ), 'Save');
  285. $this->terms['disabled']['term1'] = $this->getLastTerm($this->vocabularies['disabled']);
  286. $name .= $this->randomName();
  287. $this->drupalPost('admin/structure/taxonomy/disabled/add', array(
  288. 'name' => $name,
  289. ), 'Save');
  290. $this->terms['disabled']['term1_longer_name'] = $this->getLastTerm($this->vocabularies['disabled']);
  291. $this->drupalPost('admin/structure/taxonomy/disabled/add', array(
  292. 'name' => $this->randomName(),
  293. ), 'Save');
  294. $this->terms['disabled']['term2'] = $this->getLastTerm($this->vocabularies['disabled']);
  295. // For synonym-enabled vocabulary we have to create such a set of input,
  296. // that would cover all possible branches of the autocomplete callback.
  297. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  298. 'name' => $this->randomName(),
  299. ), 'Save');
  300. $this->terms['enabled']['no_synonyms'] = $this->getLastTerm($this->vocabularies['enabled']);
  301. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  302. 'name' => $this->randomName(),
  303. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(),
  304. ), 'Save');
  305. $this->terms['enabled']['one_synonym'] = $this->getLastTerm($this->vocabularies['enabled']);
  306. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  307. 'name' => $this->randomName(),
  308. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(),
  309. ), 'Add another item');
  310. $this->drupalPost(NULL, array(
  311. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][1][value]' => $this->randomName(),
  312. ), 'Save');
  313. $this->terms['enabled']['two_synonyms'] = $this->getLastTerm($this->vocabularies['enabled']);
  314. $name = $this->randomName();
  315. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  316. 'name' => $name,
  317. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $name . $this->randomName(),
  318. ), 'Save');
  319. $this->terms['enabled']['name_similar_synonym'] = $this->getLastTerm($this->vocabularies['enabled']);
  320. $name = 'simiar_synonyms_';
  321. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  322. 'name' => $this->randomName(),
  323. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $name . $this->randomName(),
  324. ), 'Add another item');
  325. $this->drupalPost(NULL, array(
  326. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][1][value]' => $name . $this->randomName(),
  327. ), 'Save');
  328. $this->terms['enabled']['similar_synonyms'] = $this->getLastTerm($this->vocabularies['enabled']);
  329. $name = 'one_term_name_another_synonym_';
  330. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  331. 'name' => $name . $this->randomName(),
  332. ), 'Save');
  333. $this->terms['enabled']['name_another_synonym'] = $this->getLastTerm($this->vocabularies['enabled']);
  334. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  335. 'name' => $this->randomName(),
  336. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $name . $this->randomName(),
  337. ), 'Save');
  338. $this->terms['enabled']['synonym_another_name'] = $this->getLastTerm($this->vocabularies['enabled']);
  339. }
  340. /**
  341. * Test auto-creation functionality.
  342. *
  343. * Test the auto-creation funcationality of the synonym friendly autocomplete
  344. * widget type.
  345. */
  346. public function testAutoCreation() {
  347. // Trying enabled auto creation.
  348. $this->drupalPost('admin/structure/types/manage/synonyms-test-content/fields/field_synonyms_term_enabled', array(
  349. 'instance[widget][settings][auto_creation]' => TRUE,
  350. ), 'Save settings');
  351. $new_term_name = $this->randomName();
  352. $this->drupalPost('node/add/synonyms-test-content', array(
  353. 'title' => $this->randomName(),
  354. 'field_synonyms_term_enabled[' . LANGUAGE_NONE . ']' => $this->terms['enabled']['no_synonyms']->name . ', ' . $new_term_name,
  355. ), 'Save');
  356. $this->assertText($this->terms['enabled']['no_synonyms']->name, 'Existing term was assigned to the new node');
  357. $this->assertText($new_term_name, 'Auto created term was assigned to the new node');
  358. $term = $this->getLastTerm($this->vocabularies['enabled']);
  359. $this->assertEqual($term->name, $new_term_name, 'The auto created term has been created');
  360. // Trying disabled auto creation.
  361. $this->drupalPost('admin/structure/types/manage/synonyms-test-content/fields/field_synonyms_term_enabled', array(
  362. 'instance[widget][settings][auto_creation]' => FALSE,
  363. ), 'Save settings');
  364. $new_term_name = $this->randomName();
  365. $this->drupalPost('node/add/synonyms-test-content', array(
  366. 'title' => $this->randomName(),
  367. 'field_synonyms_term_enabled[und]' => $this->terms['enabled']['no_synonyms']->name . ', ' . $new_term_name,
  368. ), 'Save');
  369. $this->assertText($this->terms['enabled']['no_synonyms']->name, 'Existing term was assigned to the new node');
  370. $this->assertNoText($new_term_name, 'Auto created term was not assigned to the new node');
  371. $term = $this->getLastTerm($this->vocabularies['enabled']);
  372. $this->assertNotEqual($term->name, $new_term_name, 'The auto created term has not been created');
  373. }
  374. /**
  375. * Test autocomplete menu path.
  376. *
  377. * Feed all known "buggy" input to synonym friendly autocomplete menu path,
  378. * in order to test its performance.
  379. */
  380. public function testAutocompleteMenuPath() {
  381. $assertions = array();
  382. // Testing empty and non-existing name arguments.
  383. foreach ($this->vocabularies as $v) {
  384. $assertions[] = array(
  385. 'vocabulary' => $v->machine_name,
  386. 'input' => '',
  387. 'response' => array(),
  388. 'message' => 'Submitting empty string into a ' . $v->machine_name . ' synonyms vocabulary',
  389. );
  390. $assertions[] = array(
  391. 'vocabulary' => $v->machine_name,
  392. 'input' => $this->randomName(),
  393. 'response' => array(),
  394. 'message' => 'Submitting non existing name into a ' . $v->machine_name . ' synonyms vocabulary',
  395. );
  396. }
  397. // Testing the synonym-disabled vocabulary.
  398. $terms = $this->terms['disabled'];
  399. $assertions[] = array(
  400. 'vocabulary' => 'disabled',
  401. 'input' => drupal_strtoupper(drupal_substr($terms['term1']->name, 1, -1)),
  402. 'response' => array($terms['term1']->name => $terms['term1']->name, $terms['term1_longer_name']->name => $terms['term1_longer_name']->name),
  403. 'message' => 'Submitting a name similar to 2 existing term names into a disabled synonyms vocabulary',
  404. );
  405. $assertions[] = array(
  406. 'vocabulary' => 'disabled',
  407. 'input' => $terms['term1']->name . ',' . drupal_strtoupper(drupal_substr($terms['term1']->name, 1, -1)),
  408. 'response' => array($terms['term1']->name . ', ' . $this->terms['disabled']['term1_longer_name']->name => $this->terms['disabled']['term1_longer_name']->name),
  409. 'message' => 'Submitting one term already chosen along with a name similar to 2 existing term names into a disabled synonyms vocabulary',
  410. );
  411. $assertions[] = array(
  412. 'vocabulary' => 'disabled',
  413. 'input' => drupal_strtoupper(drupal_substr($terms['term2']->name, 1, -1)),
  414. 'response' => array($terms['term2']->name => $terms['term2']->name),
  415. 'message' => 'Submitting a name similar to one existing term name into a disabled synonyms vocabulary',
  416. );
  417. $assertions[] = array(
  418. 'vocabulary' => 'disabled',
  419. 'input' => drupal_strtolower($terms['term2']->name) . ',' . drupal_strtoupper(drupal_substr($terms['term2']->name, 1, -1)),
  420. 'response' => array(),
  421. 'message' => 'Submitting the same term over again into a disabled synonyms vocabulary',
  422. );
  423. // Testing the synonym-enabled vocabulary.
  424. $terms = $this->terms['enabled'];
  425. $assertions[] = array(
  426. 'vocabulary' => 'enabled',
  427. 'input' => drupal_strtoupper($terms['no_synonyms']->name) . ',' . drupal_strtolower(drupal_substr($terms['no_synonyms']->name, 1, -1)),
  428. 'response' => array(),
  429. 'message' => 'Submitting the same term over again into an enabled synonyms vocabulary',
  430. );
  431. $assertions[] = array(
  432. 'vocabulary' => 'enabled',
  433. 'input' => $terms['one_synonym']->name . ',' . $terms['one_synonym']->synonyms_synonyms[LANGUAGE_NONE][0]['safe_value'],
  434. 'response' => array(),
  435. 'message' => 'Submitting a synonym of a term over again into an enabled synonyms vocabulary',
  436. );
  437. foreach (array('no_synonyms', 'one_synonym', 'two_synonyms') as $k) {
  438. $assertions[] = array(
  439. 'vocabulary' => 'enabled',
  440. 'input' => drupal_strtolower(drupal_substr($terms[$k]->name, 1, -1)),
  441. 'response' => array($terms[$k]->name => $terms[$k]->name),
  442. 'message' => 'Submitting a name similar to ' . $k . ' term into an enabled synonyms vocabulary',
  443. );
  444. $synonyms = field_get_items('taxonomy_term', $terms[$k], 'synonyms_synonyms');
  445. if (is_array($synonyms)) {
  446. foreach ($synonyms as $delta => $item) {
  447. $assertions[] = array(
  448. 'vocabulary' => 'enabled',
  449. 'input' => drupal_strtolower(drupal_substr($item['safe_value'], 1, -1)),
  450. 'response' => array($terms[$k]->name => $this->synonymAutocompleteResult($terms[$k], $item['safe_value'])),
  451. 'message' => 'Submitting a name similar to synonym#' . $delta . ' of the term ' . $k . 'into an enabled synonyms vocabulary',
  452. );
  453. }
  454. }
  455. }
  456. $assertions[] = array(
  457. 'vocabulary' => 'enabled',
  458. 'input' => $terms['name_similar_synonym']->name,
  459. 'response' => array($terms['name_similar_synonym']->name => $terms['name_similar_synonym']->name),
  460. 'message' => 'Submitting a keyword similar to name and synonym of a term into an enabled synonyms vocabulary',
  461. );
  462. $assertions[] = array(
  463. 'vocabulary' => 'enabled',
  464. 'input' => 'simiar_synonyms_',
  465. 'response' => array($terms['similar_synonyms']->name => $this->synonymAutocompleteResult($terms['similar_synonyms'], $terms['similar_synonyms']->synonyms_synonyms[LANGUAGE_NONE][0]['safe_value'])),
  466. 'message' => 'Submitting a keyword similar to name and synonym of a term into an enabled synonyms vocabulary',
  467. );
  468. $assertions[] = array(
  469. 'vocabulary' => 'enabled',
  470. 'input' => 'one_term_name_another_synonym_',
  471. 'response' => array(
  472. $terms['name_another_synonym']->name => $terms['name_another_synonym']->name,
  473. $terms['synonym_another_name']->name => $this->synonymAutocompleteResult($terms['synonym_another_name'], $terms['synonym_another_name']->synonyms_synonyms[LANGUAGE_NONE][0]['safe_value']),
  474. ),
  475. 'message' => 'Submitting a keyword similar to name of one term and synonym of another into an enabled synonyms vocabulary yields both included in the results',
  476. );
  477. foreach ($assertions as $v) {
  478. $this->assertAutocompleteMenuPath($v);
  479. }
  480. }
  481. /**
  482. * Assert output of synonym friendly autocomplete path.
  483. *
  484. * @param array $assertion
  485. * Specially encoded array of assertion. Should include the follwing keys:
  486. * vocabulary - machine name of vocabulary whose field is asserted
  487. * input - input string to be fed to autocomplete menu path
  488. * response - JSON decoded expected response of autocomplete menu path
  489. * message - Drupal assertion message to be displayed on test results
  490. * page
  491. */
  492. protected function assertAutocompleteMenuPath($assertion) {
  493. $response = $this->drupalGet('synonyms/autocomplete/field_synonyms_term_' . $assertion['vocabulary'] . '/' . $assertion['input']);
  494. if (!$response) {
  495. $this->fail($assertion['message'], 'Autocomplete Menu Path');
  496. return;
  497. }
  498. $response = (array) json_decode($response);
  499. $is_the_same = count($response) == count($assertion['response']);
  500. $is_the_same = $is_the_same && count(array_intersect_assoc($response, $assertion['response'])) == count($assertion['response']);
  501. $this->assertTrue($is_the_same, $assertion['message'], 'Autocomplete Menu Path');
  502. }
  503. /**
  504. * Return expected autocomplete menu path result.
  505. *
  506. * The result is prepared as if the term was found by the supplied synonym.
  507. *
  508. * @param object $term
  509. * Fully loaded taxonomy term object for which the result is generated.
  510. * @param string $synonym
  511. * Synonym by which the term was hit in the search
  512. *
  513. * @return string
  514. * Formatted autocomplete result
  515. */
  516. protected function synonymAutocompleteResult($term, $synonym) {
  517. return t('@synonym, synonym of %term', array('@synonym' => $synonym, '%term' => $term->name));
  518. }
  519. }
  520. /**
  521. * Test Synonyms module integration with Drupal search functionality.
  522. */
  523. class SearchIndexSynonymsWebTestCase extends SynonymsWebTestCase {
  524. protected $vocabularies = array(
  525. 'enabled' => TRUE,
  526. );
  527. /**
  528. * GetInfo method.
  529. */
  530. public function getInfo() {
  531. return array(
  532. 'name' => 'Synonyms search integration',
  533. 'description' => 'Ensure that Synonyms module correctly integrates with the Drupal search functionality.',
  534. 'group' => 'Synonyms',
  535. );
  536. }
  537. /**
  538. * SetUp method.
  539. */
  540. public function setUp() {
  541. parent::setUp();
  542. // Creating vocabularies.
  543. $this->drupalLogin($this->admin);
  544. foreach ($this->vocabularies as $k => $v) {
  545. $name = $this->randomName();
  546. $this->drupalPost('admin/structure/taxonomy/add', array(
  547. 'name' => $name,
  548. 'machine_name' => $k,
  549. 'description' => $this->randomName(),
  550. 'synonyms[synonyms][' . SYNONYMS_DEFAULT_FIELD_NAME . ']' => $v,
  551. ), 'Save');
  552. $this->vocabularies[$k] = taxonomy_vocabulary_machine_name_load($k);
  553. }
  554. // Creating a test content type.
  555. $this->drupalPost('admin/structure/types/add', array(
  556. 'name' => 'Synonyms Test Content',
  557. 'type' => 'synonyms_test_content',
  558. ), 'Save content type');
  559. // Attaching each vocabulary term reference field to the new content type.
  560. foreach ($this->vocabularies as $k => $v) {
  561. $this->drupalPost('admin/structure/types/manage/synonyms_test_content/fields', array(
  562. 'fields[_add_new_field][label]' => 'Synonym Terms ' . $k,
  563. 'fields[_add_new_field][field_name]' => 'synonyms_term_' . $k,
  564. 'fields[_add_new_field][type]' => 'taxonomy_term_reference',
  565. 'fields[_add_new_field][widget_type]' => 'synonyms_autocomplete',
  566. ), 'Save');
  567. $this->drupalPost(NULL, array(
  568. 'field[settings][allowed_values][0][vocabulary]' => $v->machine_name,
  569. ), 'Save field settings');
  570. $this->drupalPost(NULL, array(
  571. 'field[cardinality]' => FIELD_CARDINALITY_UNLIMITED,
  572. ), 'Save settings');
  573. }
  574. // Flushing static cache.
  575. _field_info_collate_fields(TRUE);
  576. }
  577. /**
  578. * Test searching by a term synonym.
  579. *
  580. * Since logically term and its synonyms represent the same entity, the idea
  581. * is that searching by a term synonym should trigger all content referencing
  582. * that term to be included in search results.
  583. */
  584. public function testSearchTermSynonym() {
  585. // Create a few terms and synonyms.
  586. $terms = array();
  587. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  588. 'name' => $this->randomName(),
  589. ), 'Save');
  590. $terms['no_synonyms'] = $this->getLastTerm($this->vocabularies['enabled']);
  591. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  592. 'name' => $this->randomName(),
  593. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(),
  594. ), 'Save');
  595. $terms['one_synonym'] = $this->getLastTerm($this->vocabularies['enabled']);
  596. $this->drupalPost('admin/structure/taxonomy/enabled/add', array(
  597. 'name' => $this->randomName(),
  598. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][0][value]' => $this->randomName(),
  599. ), 'Add another item');
  600. $this->drupalPost(NULL, array(
  601. SYNONYMS_DEFAULT_FIELD_NAME . '[' . LANGUAGE_NONE . '][1][value]' => $this->randomName(),
  602. ), 'Save');
  603. $terms['two_synonyms'] = $this->getLastTerm($this->vocabularies['enabled']);
  604. $assertions = array();
  605. // Creating a node, which refereces to all the terms we have.
  606. $title = $this->randomName();
  607. $this->drupalPost('node/add/synonyms-test-content', array(
  608. 'title' => $title,
  609. 'field_synonyms_term_enabled[' . LANGUAGE_NONE . ']' => $terms['no_synonyms']->name . ', ' . $terms['one_synonym']->name . ', ' . $terms['two_synonyms']->name,
  610. ), 'Save');
  611. $node = $this->drupalGetNodeByTitle($title);
  612. // Rebuilding Search index.
  613. $this->cronRun();
  614. foreach ($terms as $k => $v) {
  615. $assertions[] = array(
  616. 'keyword' => $v->name,
  617. 'results' => array($node),
  618. 'message' => 'Searching by name of the term ' . $k,
  619. );
  620. foreach (synonyms_get_term_synonyms($v) as $delta => $synonym) {
  621. $assertions[] = array(
  622. 'keyword' => $synonym['value'],
  623. 'results' => array($node),
  624. 'message' => 'Searching by synonym #' . $delta . ' of the term ' . $k,
  625. );
  626. }
  627. }
  628. foreach ($assertions as $assertion) {
  629. $this->assertSearchResults($assertion);
  630. }
  631. }
  632. /**
  633. * Assert search results.
  634. *
  635. * @param array $assertion
  636. * Specially encoded array of assertion. Should include the follwing keys:
  637. * keyword - what keyword has to be supplied to the search mechanism
  638. * results - array of nodes that are expected to be on search results
  639. * message - Drupal assertion message to be displayed on test results
  640. * page
  641. */
  642. protected function assertSearchResults($assertion) {
  643. $response = $this->drupalGet('search/node/' . $assertion['keyword']);
  644. $matches = array();
  645. preg_match_all('#\<li[^>]+class="search-result"[^>]*\>(.*?)\</li\>#si', $response, $matches);
  646. $results = $matches[1];
  647. if (count($results) != count($assertion['results'])) {
  648. $this->fail($assertion['message']);
  649. return;
  650. }
  651. $results = implode('', $results);
  652. foreach ($assertion['results'] as $node) {
  653. if (strpos($results, 'node/' . $node->nid) === FALSE) {
  654. $this->fail($assertion['message']);
  655. return;
  656. }
  657. }
  658. $this->pass($assertion['message']);
  659. }
  660. }
  661. /**
  662. * Base class for all test cases that test Synonoyms Extractor classes.
  663. */
  664. abstract class AbstractSynonymsExtractorWebTestCase extends DrupalWebTestCase {
  665. /**
  666. * Taxonomy vocabulary object on whose term all synonyms extracting tests will
  667. * occur.
  668. *
  669. * @var object
  670. */
  671. protected $vocabulary;
  672. /**
  673. * Class name of a synonyms extractor that is being tested.
  674. *
  675. * @var string
  676. */
  677. protected $extractor;
  678. /**
  679. * Field API field definition array of the field that is tested right now.
  680. *
  681. * @var array
  682. */
  683. protected $field;
  684. /**
  685. * Field API instance definition array of the instance that is tested now.
  686. *
  687. * @var array
  688. */
  689. protected $instance;
  690. /**
  691. * SetUp method.
  692. *
  693. * @param string $class
  694. * Name of class that is being tested
  695. * @param array $modules
  696. * Array of extra modules to install for testing a particular synonyms
  697. * extractor
  698. */
  699. public function setUp($class, $modules = array()) {
  700. array_unshift($modules, 'synonyms');
  701. parent::setUp($modules);
  702. $this->vocabulary = (object) array(
  703. 'name' => 'Test Synonyms Extactor',
  704. 'machine_name' => 'synonyms_extractor',
  705. );
  706. taxonomy_vocabulary_save($this->vocabulary);
  707. $this->extractor = $class;
  708. }
  709. /**
  710. * Completely set field in the tested vocabulary.
  711. *
  712. * Create a field in Field API (if does not exist yet), then create an
  713. * instance and relate it to our tested vocabulary. Lastly enable this field
  714. * as a source of synonyms for our tested vocabulary.
  715. *
  716. * @param array $field
  717. * Field definition array as expected by Field API
  718. * @param array $instance
  719. * Instance defintion array as expected by Field API
  720. */
  721. protected function addFieldInstance($field, $instance) {
  722. $field = field_create_field($field);
  723. $instance['entity_type'] = 'taxonomy_term';
  724. $instance['bundle'] = field_extract_bundle('taxonomy_term', $this->vocabulary);
  725. field_create_instance($instance);
  726. $settings = synonyms_vocabulary_settings($this->vocabulary);
  727. $settings['synonyms'][] = $field['field_name'];
  728. synonyms_vocabulary_settings_save($this->vocabulary, $settings);
  729. $this->field = $field;
  730. $this->instance = $instance;
  731. }
  732. /**
  733. * Test synonymsExtract() method of class.
  734. *
  735. * @param array $items
  736. * Array of field items to be saved in tested term
  737. * @param array $etalon
  738. * Expected return of synonymsExtract() method of class
  739. * @param string $message
  740. * Any custom message to be added to the standard one and passed to
  741. * SimpleTest assertion method
  742. */
  743. protected function assertSynonymsExtract($items, $etalon, $message = '') {
  744. $term = (object) array(
  745. 'name' => $this->randomName(),
  746. 'vid' => $this->vocabulary->vid,
  747. );
  748. $term->{$this->field['field_name']} = $items;
  749. taxonomy_term_save($term);
  750. $items = field_get_items('taxonomy_term', $term, $this->field['field_name']);
  751. $synonyms = is_array($items) ? call_user_func($this->extractor . '::synonymsExtract', $items, $this->field, $this->instance, $term, 'taxonomy_term') : array();
  752. $this->assertTrue(count(array_intersect($etalon, $synonyms)) == count($etalon), 'Synonyms Extractor ' . $this->extractor . ' passed synonymsExtract() method: ' . $message);
  753. // Cleaning up.
  754. taxonomy_term_delete($term->tid);
  755. }
  756. /**
  757. * Test processEntityFieldQuery method of class.
  758. *
  759. * @param array $meta_data
  760. * Array of meta data. Each subarray represents a single term and whether it
  761. * is expected to be included in the results of EntityFieldQuery. Should
  762. * have the following structure:
  763. * items - array of field items. Terms will be automatically created with
  764. * those items
  765. * expected - bool, whether the created term should be expected in the
  766. * results of EntityFieldQuery
  767. * @param string $tag
  768. * Corresponding parameter to be passed to processEntityFieldQuery() method
  769. * @param string $message
  770. * Any custom message to be added to the standard one and passed to
  771. * SimpleTest assertion method
  772. */
  773. protected function assertProcessEntityFieldQuery($meta_data, $tag, $message = '') {
  774. // Creating taxonomy terms according to the meta data.
  775. $terms = array();
  776. foreach ($meta_data as $v) {
  777. $term = (object) array(
  778. 'name' => $this->randomName(),
  779. 'vid' => $this->vocabulary->vid,
  780. );
  781. taxonomy_term_save($term);
  782. $term->{$this->field['field_name']} = $v['items'];
  783. taxonomy_term_save($term);
  784. $term->expected = $v['expected'];
  785. $terms[] = $term;
  786. }
  787. // Preparing and running EntityFieldQuery.
  788. $efq = new EntityFieldQuery();
  789. $efq->entityCondition('entity_type', 'taxonomy_term')
  790. ->entityCondition('bundle', $this->vocabulary->machine_name);
  791. call_user_func($this->extractor . '::processEntityFieldQuery', $tag, $efq, $this->field, $this->instance);
  792. $result = $efq->execute();
  793. $result = isset($result['taxonomy_term']) ? array_keys($result['taxonomy_term']) : array();
  794. // Asserting results of EntityFieldQuery.
  795. $pass = TRUE;
  796. foreach ($terms as $term) {
  797. $tmp = $term->expected ? in_array($term->tid, $result) : !in_array($term->tid, $result);
  798. $pass = $pass && $tmp;
  799. }
  800. $this->assertTrue($pass, 'Synonyms Extractor ' . $this->extractor . ' passed processEntityFieldQuery() method: ' . $message);
  801. // Cleaning up.
  802. foreach ($terms as $term) {
  803. taxonomy_term_delete($term->tid);
  804. }
  805. }
  806. /**
  807. * Test mergeEntityAsSynonym method of class.
  808. *
  809. * @param array $items
  810. * Parameter will be passed directly to the extractor class method
  811. * @param object $synonym_entity
  812. * Parameter will be passed directly to the extractor class method
  813. * @param string $synonym_entity_type
  814. * Parameter will be passed directly to the extractor class method
  815. * @param array $etalon
  816. * Array that is expected to be returned by the tested method
  817. * @param string $message
  818. * Any custom message to be added to the standard one and passed to
  819. * SimpleTest assertion method
  820. */
  821. protected function assertMergeEntityAsSynonym($items, $synonym_entity, $synonym_entity_type, $etalon, $message = '') {
  822. $extra_items = call_user_func($this->extractor . '::mergeEntityAsSynonym', $items, $this->field, $this->instance, $synonym_entity, $synonym_entity_type);
  823. foreach ($etalon as $k => $v) {
  824. if (count(array_intersect($etalon[$k], $extra_items[$k])) != count($etalon[$k])) {
  825. $this->fail('Synonyms Extractor ' . $this->extractor . ' passed mergeEntityAsSynonym() method: ' . $message);
  826. return;
  827. }
  828. }
  829. $this->pass('Synonyms Extractor ' . $this->extractor . ' passed mergeEntityAsSynonym() method: ' . $message);
  830. }
  831. }
  832. /**
  833. * Test SynonymsSynonymsExtractor class.
  834. */
  835. class SynonymsSynonoymsExtractorWebTestCase extends AbstractSynonymsExtractorWebTestCase {
  836. /**
  837. * GetInfo method.
  838. */
  839. public function getInfo() {
  840. return array(
  841. 'name' => 'SynonymsSynonymsExtractor',
  842. 'description' => 'Ensure that the synonyms module extracts synonyms from text and number fields correctly.',
  843. 'group' => 'Synonyms',
  844. );
  845. }
  846. /**
  847. * SetUp method.
  848. */
  849. public function setUp() {
  850. parent::setUp('SynonymsSynonymsExtractor');
  851. }
  852. /**
  853. * Test synonyms extraction for 'text' field type.
  854. */
  855. public function testText() {
  856. $this->addFieldInstance(array(
  857. 'field_name' => 'text',
  858. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  859. 'type' => 'text',
  860. ), array(
  861. 'field_name' => 'text',
  862. 'entity_type' => 'taxonomy_term',
  863. 'bundle' => $this->vocabulary->machine_name,
  864. 'label' => $this->randomName(),
  865. ));
  866. // Testing synonymsExtract().
  867. $this->assertSynonymsExtract(array(), array(), 'on empty field.');
  868. $synonym = $this->randomName();
  869. $this->assertSynonymsExtract(array(
  870. LANGUAGE_NONE => array(
  871. 0 => array('value' => $synonym),
  872. ),
  873. ), array($synonym), 'on a field that holds one value.');
  874. // Testing processEntityFieldQuery().
  875. $this->assertProcessEntityFieldQuery(array(), $this->randomName(), 'on empty field.');
  876. $tag = $this->randomName();
  877. $meta_data = array();
  878. $meta_data[] = array(
  879. 'items' => array(
  880. LANGUAGE_NONE => array(
  881. 0 => array('value' => $tag . $this->randomName()),
  882. 1 => array('value' => $this->randomName()),
  883. ),
  884. ),
  885. 'expected' => TRUE,
  886. );
  887. $meta_data[] = array(
  888. 'items' => array(
  889. LANGUAGE_NONE => array(
  890. 0 => array('value' => $this->randomName()),
  891. ),
  892. ),
  893. 'expected' => FALSE,
  894. );
  895. $meta_data[] = array(
  896. 'items' => array(),
  897. 'expected' => FALSE,
  898. );
  899. $this->assertProcessEntityFieldQuery($meta_data, $tag, 'on a field with values.');
  900. // Testing mergeEntityAsSynonym() method.
  901. $node = (object) array(
  902. 'title' => $this->randomName(),
  903. 'type' => 'page',
  904. );
  905. node_save($node);
  906. $this->assertMergeEntityAsSynonym(array(), $node, 'node', array(array('value' => $node->title)), 'on a node entity.');
  907. }
  908. }
  909. /**
  910. * Test TaxonomySynonymsExtractor class.
  911. */
  912. class TaxonomySynonoymsExtractorWebTestCase extends AbstractSynonymsExtractorWebTestCase {
  913. /**
  914. * Taxonomy vocabulary object terms.
  915. *
  916. * Terms of this vocabulary are synonyms of the main vocabulary terms.
  917. *
  918. * @var object
  919. */
  920. protected $vocabularySource;
  921. /**
  922. * GetInfo method.
  923. */
  924. public function getInfo() {
  925. return array(
  926. 'name' => 'TaxonomySynonymsExtractor',
  927. 'description' => 'Ensure that the synonyms module extracts synonyms from taxonomy term reference fields correctly.',
  928. 'group' => 'Synonyms',
  929. );
  930. }
  931. /**
  932. * SetUp method.
  933. */
  934. public function setUp() {
  935. parent::setUp('TaxonomySynonymsExtractor');
  936. $this->vocabularySource = (object) array(
  937. 'name' => $this->randomName(),
  938. 'machine_name' => 'source_vocabulary',
  939. );
  940. taxonomy_vocabulary_save($this->vocabularySource);
  941. }
  942. /**
  943. * Test synonyms extraction for 'taxonomy_term_reference' field type.
  944. */
  945. public function testTaxonomyTermReference() {
  946. $this->addFieldInstance(array(
  947. 'field_name' => 'term',
  948. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  949. 'type' => 'taxonomy_term_reference',
  950. 'settings' => array(
  951. 'allowed_values' => array(
  952. array(
  953. 'vocabulary' => $this->vocabularySource->machine_name,
  954. 'parent' => 0,
  955. ),
  956. ),
  957. ),
  958. ), array(
  959. 'field_name' => 'term',
  960. 'entity_type' => 'taxonomy_term',
  961. 'bundle' => $this->vocabulary->machine_name,
  962. 'label' => $this->randomName(),
  963. ));
  964. // Testing synonymsExtract().
  965. $this->assertSynonymsExtract(array(), array(), 'on empty field.');
  966. $synonym_term = $this->createSynonymTerm();
  967. $this->assertSynonymsExtract(array(
  968. LANGUAGE_NONE => array(
  969. 0 => array(
  970. 'tid' => $synonym_term->tid,
  971. ),
  972. ),
  973. ), array($synonym_term->name), 'on a field that holds one value.');
  974. // Testing processEntityFieldQuery().
  975. $this->assertProcessEntityFieldQuery(array(), $this->randomName(), 'on empty field.');
  976. $tag = $this->randomName();
  977. $meta_data = array();
  978. $meta_data[] = array(
  979. 'items' => array(
  980. LANGUAGE_NONE => array(
  981. array('tid' => $this->createSynonymTerm($tag . $this->randomName())->tid),
  982. array('tid' => $this->createSynonymTerm()->tid),
  983. ),
  984. ),
  985. 'expected' => TRUE,
  986. );
  987. $meta_data[] = array(
  988. 'items' => array(
  989. LANGUAGE_NONE => array(
  990. array('tid' => $this->createSynonymTerm()->tid),
  991. ),
  992. ),
  993. 'expected' => FALSE,
  994. );
  995. $meta_data[] = array(
  996. 'items' => array(),
  997. 'expected' => FALSE,
  998. );
  999. $this->assertProcessEntityFieldQuery($meta_data, $tag, 'on a field with values.');
  1000. // Testing mergeEntityAsSynonym() method.
  1001. $synonym_term = $this->createSynonymTerm();
  1002. $this->assertMergeEntityAsSynonym(array(), $synonym_term, 'taxonomy_term', array(array('tid' => $synonym_term->tid)), 'on a term from referenced vocabulary.');
  1003. }
  1004. /**
  1005. * Supportive function.
  1006. *
  1007. * Create a taxonomy term in the synonyms source vocabulary with the specified
  1008. * name.
  1009. *
  1010. * @param string $name
  1011. * Name of the term to be created. If nothing is supplied a random string
  1012. * is used
  1013. *
  1014. * @return object
  1015. * Fully loaded taxonomy term object of the just created term
  1016. */
  1017. protected function createSynonymTerm($name = NULL) {
  1018. if (is_null($name)) {
  1019. $name = $this->randomName();
  1020. }
  1021. $synonym_term = (object) array(
  1022. 'name' => $name,
  1023. 'vid' => $this->vocabularySource->vid,
  1024. );
  1025. taxonomy_term_save($synonym_term);
  1026. return $synonym_term;
  1027. }
  1028. }
  1029. /**
  1030. * Test EntityReferenceSynonymsExtractor class.
  1031. */
  1032. class EntityReferenceSynonymsExtractorWebTestCase extends AbstractSynonymsExtractorWebTestCase {
  1033. /**
  1034. * GetInfo method.
  1035. */
  1036. public function getInfo() {
  1037. return array(
  1038. 'name' => 'EntityReferenceSynonymsExtractor',
  1039. 'description' => 'Ensure that the synonyms module extracts synonyms from entity reference fields correctly.',
  1040. 'group' => 'Synonyms',
  1041. );
  1042. }
  1043. /**
  1044. * SetUp method.
  1045. */
  1046. public function setUp() {
  1047. parent::setUp('EntityReferenceSynonymsExtractor', array('entityreference'));
  1048. }
  1049. /**
  1050. * Test synonyms extraction for 'entityreference' field type.
  1051. */
  1052. public function testEntityReference() {
  1053. $this->addFieldInstance(array(
  1054. 'field_name' => 'reference',
  1055. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  1056. 'type' => 'entityreference',
  1057. // For the sake of experiment we use entityreference field that references
  1058. // nodes of a Drupal standard type to make things easier.
  1059. 'settings' => array(
  1060. 'target_type' => 'node',
  1061. 'handler' => 'base',
  1062. 'handler_settings' => array(
  1063. 'target_bundles' => array('page' => 'page'),
  1064. 'sort' => array('type' => 'none'),
  1065. ),
  1066. ),
  1067. ), array(
  1068. 'field_name' => 'reference',
  1069. 'entity_type' => 'taxonomy_term',
  1070. 'bundle' => $this->vocabulary->machine_name,
  1071. 'label' => $this->randomName(),
  1072. ));
  1073. // Testing synonymsExtract().
  1074. $this->assertSynonymsExtract(array(), array(), 'on empty field.');
  1075. $synonym_entity = $this->createNode();
  1076. $this->assertSynonymsExtract(array(
  1077. LANGUAGE_NONE => array(
  1078. 0 => array(
  1079. 'target_id' => entity_id('node', $synonym_entity),
  1080. ),
  1081. ),
  1082. ), array(entity_label('node', $synonym_entity)), 'on a field that holds one value.');
  1083. // Testing processEntityFieldQuery().
  1084. $this->assertProcessEntityFieldQuery(array(), $this->randomName(), 'on empty field.');
  1085. $tag = $this->randomName();
  1086. $meta_data = array();
  1087. $meta_data[] = array(
  1088. 'items' => array(
  1089. LANGUAGE_NONE => array(
  1090. array(
  1091. 'target_id' => entity_id('node', $this->createNode($tag . $this->randomName())),
  1092. ),
  1093. array(
  1094. 'target_id' => entity_id('node', $this->createNode()),
  1095. ),
  1096. ),
  1097. ),
  1098. 'expected' => TRUE,
  1099. );
  1100. $meta_data[] = array(
  1101. 'items' => array(
  1102. LANGUAGE_NONE => array(
  1103. array('target_id' => entity_id('node', $this->createNode())),
  1104. ),
  1105. ),
  1106. 'expected' => FALSE,
  1107. );
  1108. $meta_data[] = array(
  1109. 'items' => array(),
  1110. 'expected' => FALSE,
  1111. );
  1112. $this->assertProcessEntityFieldQuery($meta_data, $tag, 'on a field with values.');
  1113. // Testing mergeEntityAsSynonym() method.
  1114. $node = $this->createNode();
  1115. $this->assertMergeEntityAsSynonym(array(), $node, 'node', array(array('target_id' => $node->nid)), 'on a node.');
  1116. }
  1117. /**
  1118. * Supportive function.
  1119. *
  1120. * Create an entity of necessary entity type (in our test it's node).
  1121. *
  1122. * @param string $label
  1123. * Label to use for the entity that is about to be created
  1124. * @param string $bundle
  1125. * Bundle to use for the entity that is about to be created
  1126. *
  1127. * @return object
  1128. * Fully loaded entity object of the just created entity
  1129. */
  1130. protected function createNode($label = NULL, $bundle = 'page') {
  1131. if (is_null($label)) {
  1132. $label = $this->randomName();
  1133. }
  1134. $entity = (object) array(
  1135. 'type' => $bundle,
  1136. 'title' => $label,
  1137. );
  1138. node_save($entity);
  1139. return $entity;
  1140. }
  1141. }