SearchResultTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. declare(strict_types=1);
  3. namespace Tests\Search;
  4. use MeiliSearch\Search\SearchResult;
  5. use PHPUnit\Framework\TestCase;
  6. use function strtoupper;
  7. final class SearchResultTest extends TestCase
  8. {
  9. protected function setUp(): void
  10. {
  11. parent::setUp();
  12. $this->basicServerResponse = [
  13. 'hits' => [
  14. [
  15. 'id' => '1',
  16. 'title' => 'American Pie 2',
  17. 'poster' => 'https://image.tmdb.org/t/p/w1280/q4LNgUnRfltxzp3gf1MAGiK5LhV.jpg',
  18. 'overview' => 'The whole gang are back and as close as ever. They decide to get even closer by spending the summer together at a beach house. They decide to hold the biggest...',
  19. 'release_date' => 997405200,
  20. ],
  21. [
  22. 'id' => '190859',
  23. 'title' => 'American Sniper',
  24. 'poster' => 'https://image.tmdb.org/t/p/w1280/svPHnYE7N5NAGO49dBmRhq0vDQ3.jpg',
  25. 'overview' => 'U.S. Navy SEAL Chris Kyle takes his sole mission—protect his comrades—to heart and becomes one of the most lethal snipers in American history. His pinpoint accuracy not only saves countless lives but also makes him a prime...',
  26. 'release_date' => 1418256000,
  27. ],
  28. ],
  29. 'offset' => 0,
  30. 'limit' => 20,
  31. 'nbHits' => 976,
  32. 'exhaustiveNbHits' => false,
  33. 'processingTimeMs' => 35,
  34. 'query' => 'american',
  35. ];
  36. $this->basicResult = new SearchResult($this->basicServerResponse);
  37. $this->serverResponseWithFacets = [
  38. 'hits' => [
  39. [
  40. 'genre' => 'adventure',
  41. 'id' => 456,
  42. 'title' => 'Le Petit Prince',
  43. 'author' => 'Antoine de Saint-Exupéry',
  44. ],
  45. [
  46. 'genre' => 'fantasy',
  47. 'id' => 4,
  48. 'title' => 'Harry Potter and the Half-Blood Prince',
  49. 'author' => 'J. K. Rowling',
  50. ],
  51. ],
  52. 'offset' => 0,
  53. 'limit' => 20,
  54. 'nbHits' => 2,
  55. 'exhaustiveNbHits' => false,
  56. 'processingTimeMs' => 1,
  57. 'query' => 'prinec',
  58. 'facetsDistribution' => [
  59. 'genre' => [
  60. 'fantasy' => 1,
  61. 'romance' => 0,
  62. 'adventure' => 1,
  63. ],
  64. ],
  65. 'exhaustiveFacetsCount' => true,
  66. ];
  67. $this->resultWithFacets = new SearchResult($this->serverResponseWithFacets);
  68. }
  69. public function testResultCanBeBuilt(): void
  70. {
  71. $this->assertSame(2, $this->basicResult->count());
  72. $this->assertNotEmpty($this->basicResult->getHits());
  73. $this->assertEquals([
  74. 'id' => '1',
  75. 'title' => 'American Pie 2',
  76. 'poster' => 'https://image.tmdb.org/t/p/w1280/q4LNgUnRfltxzp3gf1MAGiK5LhV.jpg',
  77. 'overview' => 'The whole gang are back and as close as ever. They decide to get even closer by spending the summer together at a beach house. They decide to hold the biggest...',
  78. 'release_date' => 997405200,
  79. ], $this->basicResult->getHit(0));
  80. $this->assertEquals([
  81. 'id' => '190859',
  82. 'title' => 'American Sniper',
  83. 'poster' => 'https://image.tmdb.org/t/p/w1280/svPHnYE7N5NAGO49dBmRhq0vDQ3.jpg',
  84. 'overview' => 'U.S. Navy SEAL Chris Kyle takes his sole mission—protect his comrades—to heart and becomes one of the most lethal snipers in American history. His pinpoint accuracy not only saves countless lives but also makes him a prime...',
  85. 'release_date' => 1418256000,
  86. ], $this->basicResult->getHit(1));
  87. $this->assertNull($this->basicResult->getHit(2));
  88. $this->assertSame(0, $this->basicResult->getOffset());
  89. $this->assertSame(20, $this->basicResult->getLimit());
  90. $this->assertSame(2, $this->basicResult->getHitsCount());
  91. $this->assertSame(976, $this->basicResult->getNbHits());
  92. $this->assertFalse($this->basicResult->getExhaustiveNbHits());
  93. $this->assertSame(35, $this->basicResult->getProcessingTimeMs());
  94. $this->assertSame('american', $this->basicResult->getQuery());
  95. $this->assertNull($this->basicResult->getExhaustiveFacetsCount());
  96. $this->assertEmpty($this->basicResult->getFacetsDistribution());
  97. $this->assertSame(2, $this->basicResult->getIterator()->count());
  98. $this->assertArrayHasKey('hits', $this->basicResult->toArray());
  99. $this->assertArrayHasKey('offset', $this->basicResult->toArray());
  100. $this->assertArrayHasKey('limit', $this->basicResult->toArray());
  101. $this->assertArrayHasKey('nbHits', $this->basicResult->toArray());
  102. $this->assertArrayHasKey('hitsCount', $this->basicResult->toArray());
  103. $this->assertArrayHasKey('exhaustiveNbHits', $this->basicResult->toArray());
  104. $this->assertArrayHasKey('processingTimeMs', $this->basicResult->toArray());
  105. $this->assertArrayHasKey('query', $this->basicResult->toArray());
  106. $this->assertArrayHasKey('exhaustiveFacetsCount', $this->basicResult->toArray());
  107. $this->assertArrayHasKey('facetsDistribution', $this->basicResult->toArray());
  108. }
  109. public function testSearchResultCanBeFiltered(): void
  110. {
  111. $keepAmericanSniperFunc = function (array $hits) {
  112. return array_filter(
  113. $hits,
  114. function (array $hit) { return 'American Sniper' === $hit['title']; }
  115. );
  116. };
  117. $options = ['transformHits' => $keepAmericanSniperFunc];
  118. $filteredResults = $this->basicResult->applyOptions($options);
  119. $this->assertSame(1, $filteredResults->count());
  120. $this->assertSame(1, $filteredResults->getHitsCount());
  121. $this->assertSame(976, $filteredResults->getNbHits());
  122. $this->assertEquals([
  123. 'id' => '190859',
  124. 'title' => 'American Sniper',
  125. 'poster' => 'https://image.tmdb.org/t/p/w1280/svPHnYE7N5NAGO49dBmRhq0vDQ3.jpg',
  126. 'overview' => 'U.S. Navy SEAL Chris Kyle takes his sole mission—protect his comrades—to heart and becomes one of the most lethal snipers in American history. His pinpoint accuracy not only saves countless lives but also makes him a prime...',
  127. 'release_date' => 1418256000,
  128. ], $filteredResults->getHit(1)); // Not getHits(0) because array_filter() does not reorder the indexes after filtering.
  129. }
  130. public function testResultCanBeReturnedAsJson(): void
  131. {
  132. $json = $this->basicResult->toJSON();
  133. $this->assertStringContainsString('hits', $json);
  134. $this->assertStringContainsString('offset', $json);
  135. $this->assertStringContainsString('limit', $json);
  136. $this->assertStringContainsString('hitsCount', $json);
  137. $this->assertStringContainsString('nbHits', $json);
  138. $this->assertStringContainsString('exhaustiveNbHits', $json);
  139. $this->assertStringContainsString('processingTimeMs', $json);
  140. $this->assertStringContainsString('query', $json);
  141. $this->assertStringContainsString('exhaustiveFacetsCount', $json);
  142. $this->assertStringContainsString('facetsDistribution', $json);
  143. }
  144. public function testGetRaw(): void
  145. {
  146. $this->assertEquals($this->basicServerResponse, $this->basicResult->getRaw());
  147. }
  148. public function testTransformHitsMethod(): void
  149. {
  150. $keepAmericanSniperFunc = function (array $hits) {
  151. return array_filter(
  152. $hits,
  153. function (array $hit) { return 'American Sniper' === $hit['title']; }
  154. );
  155. };
  156. $response = $this->basicResult->transformHits($keepAmericanSniperFunc);
  157. $this->assertArrayHasKey('hits', $response->toArray());
  158. $this->assertArrayHasKey('offset', $response->toArray());
  159. $this->assertArrayHasKey('limit', $response->toArray());
  160. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  161. $this->assertArrayHasKey('query', $response->toArray());
  162. $this->assertSame('American Sniper', $response->getHit(1)['title']); // Not getHits(0) because array_filter() does not reorder the indexes after filtering.
  163. $this->assertSame(976, $response->getNbHits());
  164. $this->assertSame(1, $response->getHitsCount());
  165. $this->assertSame(1, $response->count());
  166. }
  167. public function testTransformFacetsDritributionMethod(): void
  168. {
  169. $facetsToUpperFunc = function (array $facets) {
  170. $changeOneFacet = function (array $facet) {
  171. $result = [];
  172. foreach ($facet as $k => $v) {
  173. $result[strtoupper($k)] = $v;
  174. }
  175. return $result;
  176. };
  177. return array_map($changeOneFacet, $facets);
  178. };
  179. $response = $this->resultWithFacets->transformFacetsDistribution($facetsToUpperFunc);
  180. $this->assertArrayHasKey('hits', $response->toArray());
  181. $this->assertArrayHasKey('facetsDistribution', $response->toArray());
  182. $this->assertArrayHasKey('offset', $response->toArray());
  183. $this->assertArrayHasKey('limit', $response->toArray());
  184. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  185. $this->assertArrayHasKey('query', $response->toArray());
  186. $this->assertEquals($response->getRaw()['hits'], $response->getHits());
  187. $this->assertNotEquals($response->getRaw()['facetsDistribution'], $response->getFacetsDistribution());
  188. $this->assertCount(3, $response->getFacetsDistribution()['genre']);
  189. $this->assertEquals(0, $response->getFacetsDistribution()['genre']['ROMANCE']);
  190. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['FANTASY']);
  191. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['ADVENTURE']);
  192. }
  193. public function testRemoveZeroFacetsMethod(): void
  194. {
  195. $response = $this->resultWithFacets->removeZeroFacets();
  196. $this->assertCount(2, $response->getFacetsDistribution()['genre']);
  197. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['adventure']);
  198. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['fantasy']);
  199. $this->assertCount(3, $response->getRaw()['facetsDistribution']['genre']);
  200. $this->assertEquals($response->getRaw()['hits'], $response->getHits());
  201. $this->assertNotEquals($response->getRaw()['facetsDistribution'], $response->getFacetsDistribution());
  202. }
  203. }