solr_base_query.test 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. /**
  3. * Unit tests for query object methods.
  4. */
  5. class SolrBaseQueryTests extends DrupalUnitTestCase {
  6. public static function getInfo() {
  7. return array(
  8. 'name' => 'SolrBaseQuery Unit tests',
  9. 'description' => 'Unit Tests for queries.',
  10. 'group' => 'ApacheSolr',
  11. );
  12. }
  13. function setUp() {
  14. parent::setUp();
  15. require_once dirname(dirname(realpath(__FILE__))) . '/apachesolr.module';
  16. require_once dirname(dirname(realpath(__FILE__))) . '/apachesolr.interface.inc';
  17. require_once dirname(dirname(realpath(__FILE__))) . '/Solr_Base_Query.php';
  18. require_once dirname(dirname(realpath(__FILE__))) . '/Drupal_Apache_Solr_Service.php';
  19. require_once dirname(dirname(realpath(__FILE__))) . '/tests/Dummy_Solr.php';
  20. }
  21. /**
  22. * Helper function to simulate the auto loading and other non-needed functions
  23. * that otherwise require a database
  24. * @see apachesolr_drupal_query().
  25. * @return SolrBaseQuery
  26. */
  27. private function _apachesolr_drupal_query($name, $params = array(), $solrsort = '', $base_path = '', $solr = NULL) {
  28. if (empty($solr)) {
  29. $solr = new DummySolr(NULL);
  30. }
  31. return new SolrBaseQuery($name, $solr, $params, $solrsort, $base_path);
  32. }
  33. private function _apachesolr_drupal_subquery($operator = 'OR') {
  34. return new SolrFilterSubQuery($operator);
  35. }
  36. /**
  37. * Test ordering of parsed filter positions.
  38. *
  39. * Regression test for http://drupal.org/node/891962
  40. */
  41. function testParseFilters() {
  42. $fq = array('tid:3', 'sort_label:hello', 'tid:11', 'tid:1', 'tid:12', 'label:hello');
  43. // Setup dummy Solr object.
  44. $query = $this->_apachesolr_drupal_query("apachesolr_tests", array('q' => 'mykeys', 'fq' => $fq), 'sort_label asc', 'search/test');
  45. // Check setSolrSort().
  46. $this->assertEqual(array('solrsort' => 'sort_label asc'), $query->getSolrsortUrlQuery());
  47. $query->setSolrsort('sort_name', 'desc');
  48. $this->assertEqual(array('solrsort' => 'sort_name desc'), $query->getSolrsortUrlQuery());
  49. $query->setSolrsort('score', 'desc');
  50. $this->assertEqual(array(), $query->getSolrsortUrlQuery());
  51. // We cannot set a sort if the sort was not made available.
  52. $query->setSolrsort('geodist()', 'asc');
  53. $this->assertNotEqual(array('solrsort' => 'geodist() asc'), $query->getSolrsortUrlQuery(), t('Sort was not applied as it was not available'));
  54. // Set the sort after it was made available.
  55. $query->setAvailableSort('geodist()', array('title' => 'Distance', 'default' => 'asc'));
  56. $query->setSolrsort('geodist()', 'asc');
  57. $this->assertEqual(array('solrsort' => 'geodist() asc'), $query->getSolrsortUrlQuery());
  58. // Check escaping of the setSolrSort functinality
  59. // Check getPath() functionality
  60. $this->assertEqual('search/test/mykeys', $query->getPath());
  61. $this->assertEqual('search/test/newkeys', $query->getPath('newkeys'));
  62. // Check hasFilter functionality
  63. $this->assertFalse($query->hasFilter('label', 'Jello'), "hasFilter('label', 'Jello') is FALSE");
  64. $this->assertTrue($query->hasFilter('label', 'hello'), "hasFilter('label', 'hello') is TRUE");
  65. $this->assertTrue($query->hasFilter('label', 'hello', FALSE), "hasFilter('label', 'hello', FALSE) is TRUE");
  66. $this->assertFalse($query->hasFilter('label', 'hello', TRUE), "hasFilter('label', 'hello', TRUE) is FALSE");
  67. $filters = $query->getFilters();
  68. $this->assertEqual(count($filters), 6, count($filters) . ' filters found, expected 6 filters');
  69. // Check positions of filters
  70. foreach ($fq as $idx => $filter) {
  71. $this->assertEqual($filter, $query->makeFilterQuery($filters[$idx]));
  72. }
  73. // Check that the query string is re-assembled correctly
  74. $this->assertEqual($fq, $query->getParam('fq'));
  75. $this->assertEqual('mykeys', $query->getParam('q'));
  76. $query->removeFilter('tid', '11');
  77. $filters = $query->getFilters();
  78. $this->assertEqual(count($filters), 5, count($filters) . ' filters found, expected 5 filters');
  79. $this->assertEqual(array('tid:3', 'sort_label:hello', 'tid:1', 'tid:12', 'label:hello'), $query->getParam('fq'));
  80. $query->removeFilter('tid');
  81. $filters = $query->getFilters();
  82. $this->assertEqual(count($filters), 2, count($filters) . ' filters found, expected 2 filters');
  83. $this->assertEqual(array('sort_label:hello', 'label:hello'), $query->getParam('fq'));
  84. $subquery = $this->_apachesolr_drupal_subquery();
  85. $subquery->addFilter('access__all', 0);
  86. $subquery->addFilter('hash', 'randomhash');
  87. $query->addFilterSubQuery($subquery);
  88. $this->assertEqual(count($query->getParam('fq')), 3, count($query->getParam('fq')) . ' fq params found, expected 3 after adding subquery');
  89. $this->assertEqual(array('sort_label:hello', 'label:hello', '(access__all:0 OR hash:randomhash' . ')'), $query->getParam('fq'));
  90. }
  91. function testAddParams() {
  92. $examples = array();
  93. $examples['{!cache=false}inStock:true'] = array(
  94. '#local' => 'cache=false',
  95. '#exclude' => FALSE,
  96. '#name' => 'inStock',
  97. '#value' => 'true',
  98. );
  99. $examples['{!frange l=1 u=4 cache=false}sqrt(popularity)'] = array(
  100. '#local' => 'frange l=1 u=4 cache=false',
  101. '#exclude' => FALSE,
  102. '#name' => NULL,
  103. '#value' => 'sqrt(popularity)',
  104. );
  105. $examples['{!cache=false cost=5}inStock:true'] = array(
  106. '#local' => 'cache=false cost=5',
  107. '#exclude' => FALSE,
  108. '#name' => 'inStock',
  109. '#value' => 'true',
  110. );
  111. $examples['{!tag=impala}model:Impala'] = array(
  112. '#local' => 'tag=impala',
  113. '#exclude' => FALSE,
  114. '#name' => 'model',
  115. '#value' => 'Impala',
  116. );
  117. $examples['{!anything that appears to be local}'] = array(
  118. '#local' => 'anything that appears to be local',
  119. '#exclude' => FALSE,
  120. '#name' => NULL,
  121. '#value' => NULL,
  122. );
  123. $examples['bundle:(article OR page)'] = array(
  124. '#local' => NULL,
  125. '#exclude' => FALSE,
  126. '#name' => 'bundle',
  127. '#value' => '(article OR page)',
  128. );
  129. $examples['-bundle:(article OR page)'] = array(
  130. '#local' => NULL,
  131. '#exclude' => TRUE,
  132. '#name' => 'bundle',
  133. '#value' => '(article OR page)',
  134. );
  135. $examples['-{!anything that appears to be local}'] = array(
  136. '#local' => 'anything that appears to be local',
  137. '#exclude' => TRUE,
  138. '#name' => NULL,
  139. '#value' => NULL,
  140. );
  141. $examples['title:"double words"'] = array(
  142. '#local' => NULL,
  143. '#exclude' => FALSE,
  144. '#name' => 'title',
  145. '#value' => '"double words"',
  146. );
  147. $examples['field_date:[1970-12-31T23:59:59Z TO NOW]'] = array(
  148. '#local' => NULL,
  149. '#exclude' => FALSE,
  150. '#name' => 'field_date',
  151. '#value' => '[1970-12-31T23:59:59Z TO NOW]',
  152. );
  153. $query = $this->_apachesolr_drupal_query("apachesolr_tests");
  154. foreach ($examples as $fq => $example) {
  155. $name = (!empty($example['#name'])) ? $example['#name'] : '_QUERY_';
  156. $value = (!empty($example['#value'])) ? $example['#value'] : '_VALUE_';
  157. $filter = $name . ':' . $value;
  158. // Check if filter is seen as a valid one
  159. $message = t('Filter (@fq) is Valid', array('@fq' => $filter));
  160. $this->assertTrue($query->validFilterValue($filter), $message);
  161. $query->addParam('fq', $fq);
  162. // Check if filter was added
  163. $message = t('hasFilter(@name, @value) is True', array('@name' => $example['#name'], '@value' => $example['#value']));
  164. $this->assertTrue($query->hasFilter($example['#name'], $example['#value'], $example['#exclude']), $message);
  165. $filters = $query->getFilters();
  166. $filter = reset($filters);
  167. $message = t('The filter "@fq" was added with all the given properties', array('@fq' => $fq));
  168. $this->assertTrue(!array_diff($example, $filter), $message);
  169. $query->removeFilter($example['#name']);
  170. $message = t('The filter "@fq" was correctly removed', array('@fq' => $fq));
  171. $this->assertFalse($query->hasFilter($example['#name'], $example['#value'], $example['#exclude']), $message);
  172. // Since we cannot remove filters without names yet we have to clear the whole fq array
  173. $query->removeParam('fq');
  174. // Check the ones without the name also
  175. }
  176. // Check for invalid combinations
  177. $bad_examples['wrong name:"double words"'] = array(
  178. '#local' => NULL,
  179. '#exclude' => FALSE,
  180. '#name' => 'wrong name',
  181. '#value' => '"double words"',
  182. );
  183. $bad_examples['field_date:[1970-12-31 TO NOW]'] = array(
  184. '#local' => NULL,
  185. '#exclude' => FALSE,
  186. '#name' => 'field_date',
  187. '#value' => '[1970-12-31 TO NOW]',
  188. );
  189. $bad_examples['bundle:((article OR page)]'] = array(
  190. '#local' => NULL,
  191. '#exclude' => FALSE,
  192. '#name' => 'bundle',
  193. '#value' => '((article OR page)]',
  194. );
  195. foreach ($bad_examples as $fq => $example) {
  196. $name = (!empty($example['#name'])) ? $example['#name'] : '_QUERY_';
  197. $value = (!empty($example['#value'])) ? $example['#value'] : '_VALUE_';
  198. $filter = $name . ':' . $value;
  199. // Check if filter is seen as a valid one
  200. $message = t('Filter (@fq) is not Valid', array('@fq' => $filter));
  201. $this->assertFalse($query->validFilterValue($filter), $message);
  202. }
  203. // Check parameter normalization.
  204. $query->addParam('spellcheck', TRUE);
  205. $this->assertTrue($query->getParam('spellcheck') === 'true', "TRUE normalized to string 'true'");
  206. $query->replaceParam('spellcheck', FALSE);
  207. $this->assertTrue($query->getParam('spellcheck') === 'false', "FALSE normalized to string 'false'");
  208. $query->addParam('fl', array(' x ', TRUE));
  209. $this->assertTrue($query->getParam('fl') === array('x', 'true'), "Array of params all normalized");
  210. }
  211. }