QuerySearchHelperTest.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
  4. *
  5. * @license GNU AGPL version 3 or any later version
  6. *
  7. * This program is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Affero General Public License as
  9. * published by the Free Software Foundation, either version 3 of the
  10. * License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU Affero General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Affero General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. */
  21. namespace Test\Files\Cache;
  22. use OC\DB\QueryBuilder\Literal;
  23. use OC\Files\Cache\QuerySearchHelper;
  24. use OC\Files\Search\SearchBinaryOperator;
  25. use OC\Files\Search\SearchComparison;
  26. use OCP\DB\QueryBuilder\IQueryBuilder;
  27. use OCP\Files\IMimeTypeLoader;
  28. use OCP\Files\Search\ISearchBinaryOperator;
  29. use OCP\Files\Search\ISearchComparison;
  30. use OCP\Files\Search\ISearchOperator;
  31. use Test\TestCase;
  32. /**
  33. * @group DB
  34. */
  35. class QuerySearchHelperTest extends TestCase {
  36. /** @var IQueryBuilder */
  37. private $builder;
  38. /** @var IMimeTypeLoader|\PHPUnit_Framework_MockObject_MockObject */
  39. private $mimetypeLoader;
  40. /** @var QuerySearchHelper */
  41. private $querySearchHelper;
  42. /** @var integer */
  43. private $numericStorageId;
  44. public function setUp() {
  45. parent::setUp();
  46. $this->builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
  47. $this->mimetypeLoader = $this->createMock(IMimeTypeLoader::class);
  48. $this->mimetypeLoader->expects($this->any())
  49. ->method('getId')
  50. ->willReturnMap([
  51. ['text', 1],
  52. ['text/plain', 2],
  53. ['text/xml', 3],
  54. ['image/jpg', 4],
  55. ['image/png', 5],
  56. ['image', 6],
  57. ]);
  58. $this->mimetypeLoader->expects($this->any())
  59. ->method('getMimetypeById')
  60. ->willReturnMap([
  61. [1, 'text'],
  62. [2, 'text/plain'],
  63. [3, 'text/xml'],
  64. [4, 'image/jpg'],
  65. [5, 'image/png'],
  66. [6, 'image']
  67. ]);
  68. $this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
  69. $this->numericStorageId = 10000;
  70. $this->builder->select(['fileid'])
  71. ->from('filecache')
  72. ->where($this->builder->expr()->eq('storage', new Literal($this->numericStorageId)));
  73. }
  74. public function tearDown() {
  75. parent::tearDown();
  76. $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
  77. $builder->delete('filecache')
  78. ->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->numericStorageId, IQueryBuilder::PARAM_INT)));
  79. $builder->execute();
  80. }
  81. private function addCacheEntry(array $data) {
  82. $data['storage'] = $this->numericStorageId;
  83. $data['etag'] = 'unimportant';
  84. $data['storage_mtime'] = $data['mtime'];
  85. if (!isset($data['path'])) {
  86. $data['path'] = 'random/' . $this->getUniqueID();
  87. }
  88. $data['path_hash'] = md5($data['path']);
  89. if (!isset($data['mtime'])) {
  90. $data['mtime'] = 100;
  91. }
  92. if (!isset($data['size'])) {
  93. $data['size'] = 100;
  94. }
  95. $data['name'] = basename($data['path']);
  96. $data['parent'] = -1;
  97. if (isset($data['mimetype'])) {
  98. list($mimepart,) = explode('/', $data['mimetype']);
  99. $data['mimepart'] = $this->mimetypeLoader->getId($mimepart);
  100. $data['mimetype'] = $this->mimetypeLoader->getId($data['mimetype']);
  101. } else {
  102. $data['mimepart'] = 1;
  103. $data['mimetype'] = 1;
  104. }
  105. $builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
  106. $values = [];
  107. foreach ($data as $key => $value) {
  108. $values[$key] = $builder->createNamedParameter($value);
  109. }
  110. $builder->insert('filecache')
  111. ->values($values)
  112. ->execute();
  113. return $builder->getLastInsertId();
  114. }
  115. private function search(ISearchOperator $operator) {
  116. $dbOperator = $this->querySearchHelper->searchOperatorToDBExpr($this->builder, $operator);
  117. $this->builder->andWhere($dbOperator);
  118. return $this->builder->execute()->fetchAll(\PDO::FETCH_COLUMN);
  119. }
  120. public function comparisonProvider() {
  121. return [
  122. [new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125), [1]],
  123. [new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125), [0]],
  124. [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 125), []],
  125. [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50), [0, 1]],
  126. [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), [0]],
  127. [new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', 'foo%'), [0, 1]],
  128. [new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/jpg'), [0]],
  129. [new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'image/%'), [0, 1]],
  130. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  131. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50),
  132. new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125)
  133. ]), [0]],
  134. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
  135. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50),
  136. new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125),
  137. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'text/%')
  138. ]), []],
  139. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  140. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 100),
  141. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
  142. ]), [0, 1]],
  143. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  144. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
  145. ]), [0]],
  146. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  147. new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125),
  148. ]), [0]],
  149. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  150. new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125),
  151. ]), [1]],
  152. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  153. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%bar'),
  154. ]), [1]],
  155. ];
  156. }
  157. /**
  158. * @dataProvider comparisonProvider
  159. *
  160. * @param ISearchOperator $operator
  161. * @param array $fileIds
  162. */
  163. public function testComparison(ISearchOperator $operator, array $fileIds) {
  164. $fileId = [];
  165. $fileId[] = $this->addCacheEntry([
  166. 'path' => 'foobar',
  167. 'mtime' => 100,
  168. 'size' => 50,
  169. 'mimetype' => 'image/jpg'
  170. ]);
  171. $fileId[] = $this->addCacheEntry([
  172. 'path' => 'fooasd',
  173. 'mtime' => 150,
  174. 'size' => 50,
  175. 'mimetype' => 'image/png'
  176. ]);
  177. $fileIds = array_map(function($i) use ($fileId) {
  178. return $fileId[$i];
  179. }, $fileIds);
  180. $results = $this->search($operator);
  181. sort($fileIds);
  182. sort($results);
  183. $this->assertEquals($fileIds, $results);
  184. }
  185. }