synonyms_provider_field.test 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873
  1. <?php
  2. /**
  3. * @file
  4. * Tests for the Synonyms field provider module.
  5. */
  6. /**
  7. * Base class for all tests that test field-based Synonyms providers.
  8. */
  9. abstract class AbstractSynonymsProviderFieldWebTestCase extends SynonymsWebTestCase {
  10. /**
  11. * Setup method.
  12. */
  13. public function setUp($modules = array()) {
  14. if (!$this->behavior_implementation['behavior']) {
  15. $this->behavior_implementation['behavior'] = 'autocomplete';
  16. }
  17. parent::setUp($modules);
  18. }
  19. /**
  20. * Test synonymsExtract() method.
  21. *
  22. * @param array $items
  23. * Array of field items to be saved in tested term
  24. * @param array $standard
  25. * Expected return of synonymsExtract() method
  26. * @param string $message
  27. * Any custom message to be added to the standard one and passed to
  28. * SimpleTest assertion method
  29. */
  30. protected function assertSynonymsExtract($items, $standard, $message = '') {
  31. $term = (object) array(
  32. 'name' => $this->randomName(),
  33. 'vid' => $this->vocabulary->vid,
  34. );
  35. $term->{$this->fields['enabled']['field']['field_name']} = $items;
  36. taxonomy_term_save($term);
  37. $synonyms = $this->behavior_implementation['object']->extractSynonyms($term);
  38. $this->assertTrue(count(array_intersect($standard, $synonyms)) == count($standard), $this->behavior_implementation['class'] . '::extractSynonyms() passed: ' . $message);
  39. // Cleaning up.
  40. taxonomy_term_delete($term->tid);
  41. }
  42. /**
  43. * Test mergeEntityAsSynonym method.
  44. *
  45. * @param array $items
  46. * Items array to place into the field on which synonyms provider is based
  47. * @param object $synonym_entity
  48. * Parameter will be passed directly to the behavior implementation object
  49. * @param string $synonym_entity_type
  50. * Parameter will be passed directly to the behavior implementation object
  51. * @param array $standard
  52. * Array that is expected to be returned by the tested method
  53. * @param string $message
  54. * Any custom message to be added to the standard one and passed to
  55. * SimpleTest assertion method
  56. */
  57. protected function assertMergeEntityAsSynonym($items, $synonym_entity, $synonym_entity_type, $standard, $message = '') {
  58. $message = $this->behavior_implementation['class'] . '::mergeEntityAsSynonym() passed: ' . $message;
  59. $term = (object) array(
  60. 'name' => $this->randomName(),
  61. 'vid' => $this->vocabulary->vid,
  62. );
  63. $term->{$this->fields['enabled']['field']['field_name']} = $items;
  64. taxonomy_term_save($term);
  65. $this->behavior_implementation['object']->mergeEntityAsSynonym($term, $synonym_entity, $synonym_entity_type);
  66. $merged_items = $term->{$this->fields['enabled']['field']['field_name']}[LANGUAGE_NONE];
  67. foreach ($standard as $k => $v) {
  68. if (count(array_intersect($standard[$k], $merged_items[$k])) != count($standard[$k])) {
  69. $this->fail($message);
  70. return;
  71. }
  72. }
  73. $this->pass($message);
  74. taxonomy_term_delete($term->tid);
  75. }
  76. /**
  77. * Test synonymFind method.
  78. *
  79. * @param array $meta_data
  80. * Array of meta data. Each subarray represents a single term and whether it
  81. * is expected to be included in the return of the method. Should have the
  82. * following structure:
  83. * - items: (array) Array of field items. Terms will be automatically
  84. * created with those items
  85. * - found_synonyms: (array) Array of synonyms that are expected to be found
  86. * for the given term, i.e. if "found_synonyms" is empty, it means the
  87. * term should not be found for the given $condition. If the
  88. * "found_synonyms" is not empty, then each element of this array should
  89. * trigger appearance of the term in the results for the given
  90. * $condition
  91. * @param QueryConditionInterface $condition
  92. * Database condition that will be passed to the synonymsFind method
  93. * @param string $message
  94. * Any custom message to be added to the standard one and passed to
  95. * SimpleTest assertion method
  96. */
  97. protected function assertSynonymsFind($meta_data, QueryConditionInterface $condition, $message = '') {
  98. $message = $this->behavior_implementation['class'] . '::synonymsFind() pass: ' . $message;
  99. $terms = array();
  100. foreach ($meta_data as $v) {
  101. $term = (object) array(
  102. 'name' => $this->randomName(),
  103. 'vid' => $this->vocabulary->vid,
  104. $this->fields['enabled']['field']['field_name'] => $v['items'],
  105. );
  106. taxonomy_term_save($term);
  107. $term->found_synonyms = $v['found_synonyms'];
  108. $terms[] = $term;
  109. }
  110. $return = $this->behavior_implementation['object']->synonymsFind($condition);
  111. $rows = array();
  112. foreach ($return as $row) {
  113. $rows[] = $row;
  114. }
  115. $success = TRUE;
  116. $total_rows_standard = 0;
  117. $total_rows = 0;
  118. foreach ($terms as $term) {
  119. foreach ($term->found_synonyms as $found_synonym) {
  120. $total_rows_standard++;
  121. $is_found = FALSE;
  122. $total_rows = 0;
  123. foreach ($rows as $row) {
  124. $total_rows++;
  125. if ($row->entity_id == $term->tid && $row->synonym == $found_synonym) {
  126. $is_found = TRUE;
  127. }
  128. }
  129. $success = $success && $is_found;
  130. }
  131. }
  132. $success = $success && $total_rows_standard == $total_rows;
  133. $this->assertTrue($success, $message);
  134. // Cleaning up.
  135. foreach ($terms as $term) {
  136. taxonomy_term_delete($term->tid);
  137. }
  138. }
  139. }
  140. /**
  141. * Test TextSynonymsBehavior class.
  142. */
  143. class TextSynonymsBehaviorWebTestCase extends AbstractSynonymsProviderFieldWebTestCase {
  144. /**
  145. * GetInfo method.
  146. */
  147. public static function getInfo() {
  148. return array(
  149. 'name' => 'TextSynonymsBehavior',
  150. 'description' => 'Ensure that the synonyms module extracts synonyms from text and number fields correctly.',
  151. 'group' => 'Synonyms',
  152. );
  153. }
  154. /**
  155. * Test synonyms extraction for 'text' field type.
  156. */
  157. public function testText() {
  158. // Testing synonymsExtract().
  159. $this->assertSynonymsExtract(array(), array(), 'on empty field.');
  160. $synonym = $this->randomName();
  161. $this->assertSynonymsExtract(array(
  162. LANGUAGE_NONE => array(
  163. 0 => array('value' => $synonym),
  164. ),
  165. ), array($synonym), 'on a field that holds one value.');
  166. // Testing mergeEntityAsSynonym() method.
  167. $node = (object) array(
  168. 'title' => $this->randomName(),
  169. 'type' => 'page',
  170. );
  171. node_save($node);
  172. $this->assertMergeEntityAsSynonym(array(), $node, 'node', array(array('value' => $node->title)), 'on a node entity.');
  173. // Testing synonymFind() method.
  174. $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on empty field.');
  175. $meta_data = array();
  176. $meta_data[] = array(
  177. 'items' => array(),
  178. 'found_synonyms' => array(),
  179. );
  180. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on a field without values.');
  181. $meta_data = array();
  182. $meta_data[] = array(
  183. 'items' => array(
  184. LANGUAGE_NONE => array(
  185. array('value' => $this->randomName()),
  186. ),
  187. ),
  188. 'found_synonyms' => array(),
  189. );
  190. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on a field with a value, but when searching for another string.');
  191. $meta_data = array();
  192. $synonym = $this->randomName();
  193. $meta_data[] = array(
  194. 'items' => array(
  195. LANGUAGE_NONE => array(
  196. array('value' => $synonym),
  197. ),
  198. ),
  199. 'found_synonyms' => array($synonym),
  200. );
  201. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym), 'on a field with a single value searching for that string');
  202. $meta_data = array();
  203. $synonym = $this->randomName();
  204. $meta_data[] = array(
  205. 'items' => array(
  206. LANGUAGE_NONE => array(
  207. array('value' => $synonym),
  208. array('value' => $this->randomName()),
  209. ),
  210. ),
  211. 'found_synonyms' => array($synonym),
  212. );
  213. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym), 'on a field with 2 values searching for one of those 2 values');
  214. $meta_data = array();
  215. $synonym = $this->randomName();
  216. $meta_data[] = array(
  217. 'items' => array(
  218. LANGUAGE_NONE => array(
  219. array('value' => $synonym),
  220. array('value' => $this->randomName()),
  221. ),
  222. ),
  223. 'found_synonyms' => array($synonym),
  224. );
  225. $meta_data[] = array(
  226. 'items' => array(
  227. LANGUAGE_NONE => array(
  228. array('value' => $this->randomName()),
  229. array('value' => $this->randomName()),
  230. ),
  231. ),
  232. 'found_synonyms' => array(),
  233. );
  234. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym), 'on 2 fields with 2 values each searching for one of those values');
  235. $meta_data = array();
  236. $synonym = $this->randomName();
  237. $meta_data[] = array(
  238. 'items' => array(
  239. LANGUAGE_NONE => array(
  240. array('value' => $synonym),
  241. ),
  242. ),
  243. 'found_synonyms' => array($synonym),
  244. );
  245. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like(drupal_substr($synonym, 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
  246. $meta_data = array();
  247. $tag = $this->randomName();
  248. $synonym1 = $tag . $this->randomName();
  249. $synonym2 = $tag . $this->randomName();
  250. $meta_data[] = array(
  251. 'items' => array(
  252. LANGUAGE_NONE => array(
  253. array('value' => $synonym1),
  254. array('value' => $synonym2),
  255. ),
  256. ),
  257. 'found_synonyms' => array($synonym1, $synonym2),
  258. );
  259. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
  260. $meta_data = array();
  261. $synonym1 = $this->randomName();
  262. $synonym2 = $this->randomName();
  263. $meta_data[] = array(
  264. 'items' => array(
  265. LANGUAGE_NONE => array(
  266. array('value' => $synonym1),
  267. array('value' => $synonym2),
  268. ),
  269. ),
  270. 'found_synonyms' => array($synonym1, $synonym2),
  271. );
  272. $this->assertSynonymsFind($meta_data, db_or()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym1)->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym2), 'on a field with 2 values searching for value1 or value2');
  273. $meta_data = array();
  274. $synonym = $this->randomName();
  275. $meta_data[] = array(
  276. 'items' => array(
  277. LANGUAGE_NONE => array(
  278. array('value' => $synonym),
  279. array('value' => $this->randomName()),
  280. ),
  281. ),
  282. 'found_synonyms' => array($synonym),
  283. );
  284. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym)->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, db_like(drupal_substr($synonym, 0, -1)) . '%', 'LIKE'), 'on a field with 2 values searching for value1 and LIKE value1%');
  285. $meta_data = array();
  286. $synonym1 = $this->randomName();
  287. $synonym2 = $this->randomName();
  288. $meta_data[] = array(
  289. 'items' => array(
  290. LANGUAGE_NONE => array(
  291. array('value' => $synonym1),
  292. array('value' => $synonym2),
  293. ),
  294. ),
  295. 'found_synonyms' => array($synonym1, $synonym2),
  296. );
  297. $condition = db_or();
  298. $condition->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym1);
  299. $condition->condition(db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym2)->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, db_like(drupal_substr($synonym2, 0, -1)) . '%', 'LIKE'));
  300. $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for (value1 or (value2 AND value2%))');
  301. $meta_data = array();
  302. $synonym1 = $this->randomName() . ' ' . $this->randomName() . ' ' . $this->randomName();
  303. $synonym2 = str_replace(' ', '-', $synonym1);
  304. $meta_data[] = array(
  305. 'items' => array(
  306. LANGUAGE_NONE => array(
  307. array('value' => $synonym1),
  308. array('value' => $synonym2),
  309. ),
  310. ),
  311. 'found_synonyms' => array($synonym1, $synonym2),
  312. );
  313. $condition = db_and()
  314. ->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER . ", ' ', '-') = :synonym", array(
  315. ':synonym' => $synonym2,
  316. ));
  317. $this->assertSynonymsFind($meta_data, $condition, "on a field with 2 values, where 2nd value replaces spaces with dashes in the 1st value, searching for REPLACE(column, ' ', '-') = value2");
  318. }
  319. }
  320. /**
  321. * Test TaxonomySynonymsBehavior class.
  322. */
  323. class TaxonomySynonymsBehaviorWebTestCase extends AbstractSynonymsProviderFieldWebTestCase {
  324. /**
  325. * Taxonomy vocabulary object terms.
  326. *
  327. * Terms of this vocabulary are synonyms of the main vocabulary terms.
  328. *
  329. * @var object
  330. */
  331. protected $vocabularySource;
  332. /**
  333. * GetInfo method.
  334. */
  335. public static function getInfo() {
  336. return array(
  337. 'name' => 'TaxonomySynonymsBehavior',
  338. 'description' => 'Ensure that the synonyms module extracts synonyms from taxonomy term reference fields correctly.',
  339. 'group' => 'Synonyms',
  340. );
  341. }
  342. /**
  343. * SetUp method.
  344. */
  345. public function setUp($modules = array()) {
  346. $this->fields['enabled']['field'] = array(
  347. 'field_name' => 'term',
  348. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  349. 'type' => 'taxonomy_term_reference',
  350. 'settings' => array(
  351. 'allowed_values' => array(
  352. array(
  353. 'vocabulary' => 'source_vocabulary',
  354. 'parent' => 0,
  355. ),
  356. ),
  357. ),
  358. );
  359. parent::setUp($modules);
  360. $this->vocabularySource = (object) array(
  361. 'name' => $this->randomName(),
  362. 'machine_name' => 'source_vocabulary',
  363. );
  364. taxonomy_vocabulary_save($this->vocabularySource);
  365. }
  366. /**
  367. * Test synonyms extraction for 'taxonomy_term_reference' field type.
  368. */
  369. public function testTaxonomyTermReference() {
  370. // Testing synonymsExtract().
  371. $this->assertSynonymsExtract(array(), array(), 'on empty field.');
  372. $synonym_term = $this->createSynonymTerm();
  373. $this->assertSynonymsExtract(array(
  374. LANGUAGE_NONE => array(
  375. 0 => array(
  376. 'tid' => $synonym_term->tid,
  377. ),
  378. ),
  379. ), array($synonym_term->name), 'on a field that holds one value.');
  380. // Testing mergeEntityAsSynonym() method.
  381. $synonym_term = $this->createSynonymTerm();
  382. $this->assertMergeEntityAsSynonym(array(), $synonym_term, 'taxonomy_term', array(array('tid' => $synonym_term->tid)), 'on a term from referenced vocabulary.');
  383. // Testing synonymFind() method.
  384. $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on empty field');
  385. $meta_data = array();
  386. $meta_data[] = array(
  387. 'items' => array(),
  388. 'found_synonyms' => array(),
  389. );
  390. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on a field without values');
  391. $meta_data = array();
  392. $meta_data[] = array(
  393. 'items' => array(
  394. LANGUAGE_NONE => array(
  395. array('tid' => $this->createSynonymTerm()->tid),
  396. ),
  397. ),
  398. 'found_synonyms' => array(),
  399. );
  400. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on a field with a value but searching for another string');
  401. $meta_data = array();
  402. $synonym_term = $this->createSynonymTerm();
  403. $meta_data[] = array(
  404. 'items' => array(
  405. LANGUAGE_NONE => array(
  406. array('tid' => $synonym_term->tid),
  407. ),
  408. ),
  409. 'found_synonyms' => array($synonym_term->name),
  410. );
  411. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term->name), 'on a field with a single value searching for that string');
  412. $meta_data = array();
  413. $synonym_term = $this->createSynonymTerm();
  414. $meta_data[] = array(
  415. 'items' => array(
  416. LANGUAGE_NONE => array(
  417. array('tid' => $this->createSynonymTerm()->tid),
  418. array('tid' => $synonym_term->tid),
  419. ),
  420. ),
  421. 'found_synonyms' => array($synonym_term->name),
  422. );
  423. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term->name), 'on a field with 2 values searching for one of those 2 values');
  424. $meta_data = array();
  425. $synonym_term = $this->createSynonymTerm();
  426. $meta_data[] = array(
  427. 'items' => array(
  428. LANGUAGE_NONE => array(
  429. array('tid' => $synonym_term->tid),
  430. array('tid' => $this->createSynonymTerm()->tid),
  431. ),
  432. ),
  433. 'found_synonyms' => array($synonym_term->name),
  434. );
  435. $meta_data[] = array(
  436. 'items' => array(
  437. LANGUAGE_NONE => array(
  438. array('tid' => $this->createSynonymTerm()->tid),
  439. array('tid' => $this->createSynonymTerm()->tid),
  440. ),
  441. ),
  442. 'found_synonyms' => array(),
  443. );
  444. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term->name), 'on 2 fields with 2 values each searching for one of those values');
  445. $meta_data = array();
  446. $synonym_term = $this->createSynonymTerm();
  447. $meta_data[] = array(
  448. 'items' => array(
  449. LANGUAGE_NONE => array(
  450. array('tid' => $synonym_term->tid),
  451. ),
  452. ),
  453. 'found_synonyms' => array($synonym_term->name),
  454. );
  455. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term->name, 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
  456. $meta_data = array();
  457. $tag = $this->randomName();
  458. $synonym_term1 = $this->createSynonymTerm($tag . $this->randomName());
  459. $synonym_term2 = $this->createSynonymTerm($tag . $this->randomName());
  460. $meta_data[] = array(
  461. 'items' => array(
  462. LANGUAGE_NONE => array(
  463. array('tid' => $synonym_term1->tid),
  464. array('tid' => $synonym_term2->tid),
  465. ),
  466. ),
  467. 'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
  468. );
  469. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
  470. $meta_data = array();
  471. $synonym_term1 = $this->createSynonymTerm();
  472. $synonym_term2 = $this->createSynonymTerm();
  473. $meta_data[] = array(
  474. 'items' => array(
  475. LANGUAGE_NONE => array(
  476. array('tid' => $synonym_term1->tid),
  477. array('tid' => $synonym_term2->tid),
  478. ),
  479. ),
  480. 'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
  481. );
  482. $this->assertSynonymsFind($meta_data, db_or()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term1->name)->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term2->name), 'on a field with 2 values searching for value1 or value2');
  483. $meta_data = array();
  484. $synonym_term = $this->createSynonymTerm();
  485. $meta_data[] = array(
  486. 'items' => array(
  487. LANGUAGE_NONE => array(
  488. array('tid' => $synonym_term->tid),
  489. array('tid' => $this->createSynonymTerm()->tid),
  490. ),
  491. ),
  492. 'found_synonyms' => array($synonym_term->name),
  493. );
  494. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term->name)->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term->name, 1, -1)) . '%', 'LIKE'), 'on a field with 2 values searching for value1 and LIKE value1%');
  495. $meta_data = array();
  496. $synonym_term1 = $this->createSynonymTerm();
  497. $synonym_term2 = $this->createSynonymTerm();
  498. $meta_data[] = array(
  499. 'items' => array(
  500. LANGUAGE_NONE => array(
  501. array('tid' => $synonym_term1->tid),
  502. array('tid' => $synonym_term2->tid),
  503. ),
  504. ),
  505. 'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
  506. );
  507. $condition = db_or();
  508. $condition->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term1->name);
  509. $condition->condition(db_and()
  510. ->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $synonym_term2->name)
  511. ->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like(drupal_substr($synonym_term2->name, 1 -1)) . '%', 'LIKE'));
  512. $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for (value1 or (value2 AND value2%))');
  513. $meta_data = array();
  514. $synonym_term1 = $this->createSynonymTerm($this->randomName() . ' ' . $this->randomName() . ' ' . $this->randomName());
  515. $synonym_term2 = $this->createSynonymTerm(str_replace(' ', '-', $synonym_term1->name));
  516. $meta_data[] = array(
  517. 'items' => array(
  518. LANGUAGE_NONE => array(
  519. array('tid' => $synonym_term1->tid),
  520. array('tid' => $synonym_term2->tid),
  521. ),
  522. ),
  523. 'found_synonyms' => array($synonym_term1->name, $synonym_term2->name),
  524. );
  525. $condition = db_and()
  526. ->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER . ", ' ', '-') = :synonym", array(
  527. ':synonym' => $synonym_term2->name,
  528. ));
  529. $this->assertSynonymsFind($meta_data, $condition, "on a field with 2 values, where 2nd value replaces spaces with dashes in the 1st value, searching for REPLACE(column, ' ', '-') = value2");
  530. }
  531. /**
  532. * Supportive function.
  533. *
  534. * Create a taxonomy term in the synonyms source vocabulary with the specified
  535. * name.
  536. *
  537. * @param string $name
  538. * Name of the term to be created. If nothing is supplied a random string
  539. * is used
  540. *
  541. * @return object
  542. * Fully loaded taxonomy term object of the just created term
  543. */
  544. protected function createSynonymTerm($name = NULL) {
  545. if (is_null($name)) {
  546. $name = $this->randomName();
  547. }
  548. $synonym_term = (object) array(
  549. 'name' => $name,
  550. 'vid' => $this->vocabularySource->vid,
  551. );
  552. taxonomy_term_save($synonym_term);
  553. return $synonym_term;
  554. }
  555. }
  556. /**
  557. * Test EntityReferenceSynonymsBehavior class.
  558. */
  559. class EntityReferenceSynonymsBehaviorWebTestCase extends AbstractSynonymsProviderFieldWebTestCase {
  560. /**
  561. * GetInfo method.
  562. */
  563. public static function getInfo() {
  564. return array(
  565. 'name' => 'EntityReferenceSynonymsBehavior',
  566. 'description' => 'Ensure that the synonyms module extracts synonyms from entity reference fields correctly.',
  567. 'group' => 'Synonyms',
  568. );
  569. }
  570. /**
  571. * SetUp method.
  572. */
  573. public function setUp($modules = array()) {
  574. $modules[] = 'entityreference';
  575. $this->fields['enabled']['field'] = array(
  576. 'field_name' => 'reference',
  577. 'cardinality' => FIELD_CARDINALITY_UNLIMITED,
  578. 'type' => 'entityreference',
  579. // For the sake of experiment we use entityreference field that references
  580. // nodes of a Drupal standard type to make things easier.
  581. 'settings' => array(
  582. 'target_type' => 'node',
  583. 'handler' => 'base',
  584. 'handler_settings' => array(
  585. 'target_bundles' => array('page' => 'page'),
  586. 'sort' => array('type' => 'none'),
  587. ),
  588. ),
  589. );
  590. parent::setUp($modules);
  591. }
  592. /**
  593. * Test synonyms extraction for 'entityreference' field type.
  594. */
  595. public function testEntityReference() {
  596. // Testing synonymsExtract().
  597. $this->assertSynonymsExtract(array(), array(), 'on empty field.');
  598. $synonym_entity = $this->createNode();
  599. $this->assertSynonymsExtract(array(
  600. LANGUAGE_NONE => array(
  601. 0 => array(
  602. 'target_id' => entity_id('node', $synonym_entity),
  603. ),
  604. ),
  605. ), array(entity_label('node', $synonym_entity)), 'on a field that holds one value.');
  606. // Testing mergeEntityAsSynonym() method.
  607. $node = $this->createNode();
  608. $this->assertMergeEntityAsSynonym(array(), $node, 'node', array(array('target_id' => $node->nid)), 'on a node.');
  609. // Testing synonymFind() method.
  610. $this->assertSynonymsFind(array(), db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on empty field');
  611. $meta_data = array();
  612. $meta_data[] = array(
  613. 'items' => array(),
  614. 'found_synonyms' => array(),
  615. );
  616. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on a field without values');
  617. $meta_data = array();
  618. $meta_data[] = array(
  619. 'items' => array(
  620. LANGUAGE_NONE => array(
  621. array('target_id' => entity_id('node', $this->createNode())),
  622. ),
  623. ),
  624. 'found_synonyms' => array(),
  625. );
  626. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, $this->randomName()), 'on a field with a value but searching for another string');
  627. $meta_data = array();
  628. $synonym_entity = $this->createNode();
  629. $meta_data[] = array(
  630. 'items' => array(
  631. LANGUAGE_NONE => array(
  632. array('target_id' => entity_id('node', $synonym_entity)),
  633. ),
  634. ),
  635. 'found_synonyms' => array(entity_label('node', $synonym_entity)),
  636. );
  637. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on a field with a single value searching for that string');
  638. $meta_data = array();
  639. $synonym_entity = $this->createNode();
  640. $meta_data[] = array(
  641. 'items' => array(
  642. LANGUAGE_NONE => array(
  643. array('target_id' => entity_id('node', $synonym_entity)),
  644. array('target_id' => entity_id('node', $this->createNode())),
  645. ),
  646. ),
  647. 'found_synonyms' => array(entity_label('node', $synonym_entity)),
  648. );
  649. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on a field with 2 values searching for one of those 2 values');
  650. $meta_data = array();
  651. $synonym_entity = $this->createNode();
  652. $meta_data[] = array(
  653. 'items' => array(
  654. LANGUAGE_NONE => array(
  655. array('target_id' => entity_id('node', $synonym_entity)),
  656. array('target_id' => entity_id('node', $this->createNode())),
  657. ),
  658. ),
  659. 'found_synonyms' => array(entity_label('node', $synonym_entity)),
  660. );
  661. $meta_data[] = array(
  662. 'items' => array(
  663. LANGUAGE_NONE => array(
  664. array('target_id' => entity_id('node', $this->createNode())),
  665. array('target_id' => entity_id('node', $this->createNode())),
  666. ),
  667. ),
  668. 'found_synonyms' => array(),
  669. );
  670. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity)), 'on 2 fields with 2 values each searching for one of those values');
  671. $meta_data = array();
  672. $synonym_entity = $this->createNode();
  673. $meta_data[] = array(
  674. 'items' => array(
  675. LANGUAGE_NONE => array(
  676. array('target_id' => entity_id('node', $synonym_entity)),
  677. ),
  678. ),
  679. 'found_synonyms' => array(entity_label('node', $synonym_entity)),
  680. );
  681. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity), 1, -1)) . '%', 'LIKE'), 'on a field with a value searching for a string LIKE the %value%');
  682. $meta_data = array();
  683. $tag = $this->randomName();
  684. $synonym_entity1 = $this->createNode($tag . $this->randomName());
  685. $synonym_entity2 = $this->createNode($tag . $this->randomName());
  686. $meta_data[] = array(
  687. 'items' => array(
  688. LANGUAGE_NONE => array(
  689. array('target_id' => entity_id('node', $synonym_entity1)),
  690. array('target_id' => entity_id('node', $synonym_entity2)),
  691. ),
  692. ),
  693. 'found_synonyms' => array(
  694. entity_label('node', $synonym_entity1),
  695. entity_label('node', $synonym_entity2),
  696. ),
  697. );
  698. $this->assertSynonymsFind($meta_data, db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, db_like($tag) . '%', 'LIKE'), 'on a field with 2 similar values searching a string like %both values%');
  699. $meta_data = array();
  700. $synonym_entity1 = $this->createNode();
  701. $synonym_entity2 = $this->createNode();
  702. $meta_data[] = array(
  703. 'items' => array(
  704. LANGUAGE_NONE => array(
  705. array('target_id' => entity_id('node', $synonym_entity1)),
  706. array('target_id' => entity_id('node', $synonym_entity2)),
  707. ),
  708. ),
  709. 'found_synonyms' => array(
  710. entity_label('node', $synonym_entity1),
  711. entity_label('node', $synonym_entity2),
  712. ),
  713. );
  714. $condition = db_or()
  715. ->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity1))
  716. ->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity2));
  717. $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for value1 or value2');
  718. $meta_data = array();
  719. $synonym_entity = $this->createNode();
  720. $meta_data[] = array(
  721. 'items' => array(
  722. LANGUAGE_NONE => array(
  723. array('target_id' => entity_id('node', $synonym_entity)),
  724. array('target_id' => entity_id('node', $this->createNode())),
  725. ),
  726. ),
  727. 'found_synonyms' => array(entity_label('node', $synonym_entity)),
  728. );
  729. $condition = db_and()
  730. ->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity))
  731. ->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity), 1, -1)) . '%', 'LIKE');
  732. $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for value1 and LIKE value1%');
  733. $meta_data = array();
  734. $synonym_entity1 = $this->createNode();
  735. $synonym_entity2 = $this->createNode();
  736. $meta_data[] = array(
  737. 'items' => array(
  738. LANGUAGE_NONE => array(
  739. array('target_id' => entity_id('node', $synonym_entity1)),
  740. array('target_id' => entity_id('node', $synonym_entity2)),
  741. ),
  742. ),
  743. 'found_synonyms' => array(
  744. entity_label('node', $synonym_entity1),
  745. entity_label('node', $synonym_entity2),
  746. ),
  747. );
  748. $condition = db_or()
  749. ->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity1))
  750. ->condition(db_and()->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, entity_label('node', $synonym_entity2))->condition(AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER, '%' . db_like(drupal_substr(entity_label('node', $synonym_entity2), 1, -1)) . '%', 'LIKE'));
  751. $this->assertSynonymsFind($meta_data, $condition, 'on a field with 2 values searching for (value1 or (value2 AND value2%))');
  752. $meta_data = array();
  753. $synonym_entity1 = $this->createNode($this->randomName() . ' ' . $this->randomName() . ' ' . $this->randomName());
  754. $synonym_entity2 = $this->createNode(str_replace(' ', '-', entity_label('node', $synonym_entity1)));
  755. $meta_data[] = array(
  756. 'items' => array(
  757. LANGUAGE_NONE => array(
  758. array('target_id' => entity_id('node', $synonym_entity1)),
  759. array('target_id' => entity_id('node', $synonym_entity2)),
  760. ),
  761. ),
  762. 'found_synonyms' => array(
  763. entity_label('node', $synonym_entity1),
  764. entity_label('node', $synonym_entity2),
  765. ),
  766. );
  767. $condition = db_and()
  768. ->where("REPLACE(" . AbstractSynonymsBehavior::COLUMN_SYNONYM_PLACEHOLDER . ", ' ', '-') = :synonym", array(
  769. ':synonym' => entity_label('node', $synonym_entity2),
  770. ));
  771. $this->assertSynonymsFind($meta_data, $condition, "on a field with 2 values, where 2nd value replaces spaces with dashes in the 1st value, searching for REPLACE(column, ' ', '-') = value2");
  772. }
  773. /**
  774. * Supportive function.
  775. *
  776. * Create an entity of necessary entity type (in our test it's node).
  777. *
  778. * @param string $label
  779. * Label to use for the entity that is about to be created
  780. * @param string $bundle
  781. * Bundle to use for the entity that is about to be created
  782. *
  783. * @return object
  784. * Fully loaded entity object of the just created entity
  785. */
  786. protected function createNode($label = NULL, $bundle = 'page') {
  787. if (is_null($label)) {
  788. $label = $this->randomName();
  789. }
  790. $entity = (object) array(
  791. 'type' => $bundle,
  792. 'title' => $label,
  793. );
  794. node_save($entity);
  795. return $entity;
  796. }
  797. }