QuerySearchHelperTest.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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), [0]
  133. ]), [0]],
  134. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
  135. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 100),
  136. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
  137. ]), [0, 1]],
  138. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  139. new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
  140. ]), [0]],
  141. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  142. new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125),
  143. ]), [0]],
  144. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  145. new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125),
  146. ]), [1]],
  147. [new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
  148. new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%bar'),
  149. ]), [1]],
  150. ];
  151. }
  152. /**
  153. * @dataProvider comparisonProvider
  154. *
  155. * @param ISearchOperator $operator
  156. * @param array $fileIds
  157. */
  158. public function testComparison(ISearchOperator $operator, array $fileIds) {
  159. $fileId = [];
  160. $fileId[] = $this->addCacheEntry([
  161. 'path' => 'foobar',
  162. 'mtime' => 100,
  163. 'size' => 50,
  164. 'mimetype' => 'image/jpg'
  165. ]);
  166. $fileId[] = $this->addCacheEntry([
  167. 'path' => 'fooasd',
  168. 'mtime' => 150,
  169. 'size' => 50,
  170. 'mimetype' => 'image/png'
  171. ]);
  172. $fileIds = array_map(function($i) use ($fileId) {
  173. return $fileId[$i];
  174. }, $fileIds);
  175. $results = $this->search($operator);
  176. sort($fileIds);
  177. sort($results);
  178. $this->assertEquals($fileIds, $results);
  179. }
  180. }