aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Build: remove dependency on grunt-contrib-concatAlexander Schmitz2015-08-081-1/+0
|
* Build: Remove grunt concat task its no longer usedAlexander Schmitz2015-08-081-42/+0
| | | | | | This task was only used to create the combined js file for sizer and for creating the combined files for the NPM package. The npm package is no longer maintained so there is no need for this any more.
* Build: Add requirejs build taskAlexander Schmitz2015-08-082-13/+25
| | | | | This more closely emulates what you get from the builder in terms of file order it also will error on any dependency issues.
* Tests: adjust jshint path for moving all widgets into folderAlexander Schmitz2015-08-081-1/+1
| | | | Ref #13885
* Tooltip: Move tooltip into widgets directoryAlexander Schmitz2015-08-089-13/+14
| | | | Ref #13885
* Tabs: Move tabs into widgets directoryAlexander Schmitz2015-08-088-13/+14
| | | | Ref #13885
* Spinner: Move spinner into widgets folderAlexander Schmitz2015-08-089-13/+14
| | | | Ref #13885
* Sortable: Move sortable into widgets folderAlexander Schmitz2015-08-088-14/+14
| | | | Ref #13885
* Slider: Move slider into widgets folderAlexander Schmitz2015-08-087-10/+11
| | | | Ref #13885
* Selectmenu: Move selectmenu into widgets folderAlexander Schmitz2015-08-087-15/+15
| | | | Ref #13885
* Selectable: Move selectable into widgets folderAlexander Schmitz2015-08-086-8/+9
| | | | Ref #13885
* Resizable: Move resizable into widgets folderAlexander Schmitz2015-08-089-14/+14
| | | | Ref #13885
* Mouse: Move mouse into widgets folderAlexander Schmitz2015-08-089-10/+12
| | | | Ref #13885
* Progressbar: Move progressbar into widgets folderAlexander Schmitz2015-08-087-8/+9
| | | | Ref #13885
* Menu: Move menu into widgets folderAlexander Schmitz2015-08-089-15/+15
| | | | Ref #13885
* Droppable: Move droppable into widgets folderAlexander Schmitz2015-08-0810-13/+14
| | | | Ref #13885
* Effects: Move individual effects into effects folderAlexander Schmitz2015-08-0819-62/+67
| | | | Ref #13885
* Draggable: Move draggable into widgets folderAlexander Schmitz2015-08-0811-18/+19
| | | | Ref #13885
* Dialog: Move dialog into widgets folderAlexander Schmitz2015-08-0810-23/+23
| | | | Ref #13885
* Datepicker: Move datepicker into widgets folderAlexander Schmitz2015-08-0881-82/+83
| | | | Ref #13885
* Button: Move button into widgets folderAlexander Schmitz2015-08-089-13/+14
| | | | Ref #13885
* Autocomplete: Move autocomplete into widgets folderAlexander Schmitz2015-08-087-13/+13
| | | | Ref #13885
* Accordion: Move accordion into widgets folderAlexander Schmitz2015-08-088-12/+13
| | | | Ref #13885
* Demos: bootstrap needs to account for widgets folderAlexander Schmitz2015-08-081-0/+18
| | | | Ref #13885
* Core: Movie uniqueId into its own module and deprecate core moduleAlexander Schmitz2015-08-089-62/+82
| | | | | | | uniqueId was the last thing in the core module, and it is now just a helper which require all the modules it used to contain. Closes #9647
* Core: Move scrollParent into its own moduleAlexander Schmitz2015-08-085-16/+47
| | | | Ref #9647
* Core: Move tabbable into its own moduleAlexander Schmitz2015-08-084-11/+41
| | | | Ref #9647
* Core: Move safe blur into its own moduleAlexander Schmitz2015-08-084-14/+25
| | | | Ref #9647
* Core: Move safeActiveElement into its own moduleAlexander Schmitz2015-08-088-36/+52
| | | | Ref #9647
* Core: Move plugin into its own moduleAlexander Schmitz2015-08-084-31/+46
| | | | Ref #9647
* Core: Move backcompat for core 1.7 into its own moduleAlexander Schmitz2015-08-082-62/+90
| | | | Ref #9647
* Core: Move labels into its own moduleAlexander Schmitz2015-08-085-39/+70
| | | | Ref #9647
* Core: Move keyCode into its own moduleAlexander Schmitz2015-08-0813-29/+63
| | | | Ref #9647
* Core: Move $.ui.ie into its own moduleAlexander Schmitz2015-08-084-3/+18
| | | | Ref #9647
* Core: Move form method into its own moduleAlexander Schmitz2015-08-084-9/+24
| | | | Ref #9647
* Core: Move escape selector into its own moduleAlexander Schmitz2015-08-084-9/+25
| | | | Ref #9647
* Core: Move focusable into its own moduleAlexander Schmitz2015-08-084-35/+69
| | | | Ref #9647
* Core: Move disable-selection into its own moduleAlexander Schmitz2015-08-083-20/+51
| | | | Ref #9647
* Core: Move data selector from core into its own moduleAlexander Schmitz2015-08-086-13/+45
| | | | Ref #9647
* Core: Move version and creation of the ui namespace into its own moduleAlexander Schmitz2015-08-0839-17/+60
| | | | Ref #9647
* Build: Update the licenses attribute to singular licenseJörn Zaefferer2015-07-241-6/+1
| | | | | Specifying the type and URL is deprecated: https://docs.npmjs.com/files/package.json#license
* Slider: Remove horizontal scrollbar demo from index it was removedAlexander Schmitz2015-07-211-1/+0
|
* Droppable: Remove shopping cart demo from index it was deletedAlexander Schmitz2015-07-211-1/+0
|
* Widget: Update demo to use AMDAlexander Schmitz2015-07-211-8/+2
| | | | Ref #10119
* Tooltip: Update demos to use AMDAlexander Schmitz2015-07-217-63/+14
| | | | Ref #10119
* Tabs: Update demos to use AMDAlexander Schmitz2015-07-217-54/+14
| | | | Ref #10119
* Sortable: Update demos to use AMDAlexander Schmitz2015-07-211-1/+0
| | | | Ref #10119
* Spinner: Update demos to use AMDAlexander Schmitz2015-07-216-83/+33
| | | | Ref #10119
* Sortable: Update demos to use AMDAlexander Schmitz2015-07-217-55/+14
| | | | Ref #10119
* Slider: Update demos to use AMDAlexander Schmitz2015-07-2110-95/+41
| | | | Ref #10119
Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
aboutsummaryrefslogtreecommitdiffstats
path: root/tests/lib/Files/Cache/QuerySearchHelperTest.php
blob: f458ef039e16df9f18512ea9df6a1e8b8d31dd83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
/**
 * @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

namespace Test\Files\Cache;

use OC\DB\QueryBuilder\Literal;
use OC\Files\Cache\QuerySearchHelper;
use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\Files\Search\ISearchOperator;
use Test\TestCase;

/**
 * @group DB
 */
class QuerySearchHelperTest extends TestCase {
	/** @var  IQueryBuilder */
	private $builder;

	/** @var  IMimeTypeLoader|\PHPUnit_Framework_MockObject_MockObject */
	private $mimetypeLoader;

	/** @var  QuerySearchHelper */
	private $querySearchHelper;

	/** @var  integer */
	private $numericStorageId;

	public function setUp() {
		parent::setUp();
		$this->builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
		$this->mimetypeLoader = $this->createMock(IMimeTypeLoader::class);

		$this->mimetypeLoader->expects($this->any())
			->method('getId')
			->willReturnMap([
				['text', 1],
				['text/plain', 2],
				['text/xml', 3],
				['image/jpg', 4],
				['image/png', 5],
				['image', 6],
			]);

		$this->mimetypeLoader->expects($this->any())
			->method('getMimetypeById')
			->willReturnMap([
				[1, 'text'],
				[2, 'text/plain'],
				[3, 'text/xml'],
				[4, 'image/jpg'],
				[5, 'image/png'],
				[6, 'image']
			]);

		$this->querySearchHelper = new QuerySearchHelper($this->mimetypeLoader);
		$this->numericStorageId = 10000;

		$this->builder->select(['fileid'])
			->from('filecache')
			->where($this->builder->expr()->eq('storage', new Literal($this->numericStorageId)));
	}

	public function tearDown() {
		parent::tearDown();

		$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();

		$builder->delete('filecache')
			->where($builder->expr()->eq('storage', $builder->createNamedParameter($this->numericStorageId, IQueryBuilder::PARAM_INT)));

		$builder->execute();
	}

	private function addCacheEntry(array $data) {
		$data['storage'] = $this->numericStorageId;
		$data['etag'] = 'unimportant';
		$data['storage_mtime'] = $data['mtime'];
		if (!isset($data['path'])) {
			$data['path'] = 'random/' . $this->getUniqueID();
		}
		$data['path_hash'] = md5($data['path']);
		if (!isset($data['mtime'])) {
			$data['mtime'] = 100;
		}
		if (!isset($data['size'])) {
			$data['size'] = 100;
		}
		$data['name'] = basename($data['path']);
		$data['parent'] = -1;
		if (isset($data['mimetype'])) {
			list($mimepart,) = explode('/', $data['mimetype']);
			$data['mimepart'] = $this->mimetypeLoader->getId($mimepart);
			$data['mimetype'] = $this->mimetypeLoader->getId($data['mimetype']);
		} else {
			$data['mimepart'] = 1;
			$data['mimetype'] = 1;
		}

		$builder = \OC::$server->getDatabaseConnection()->getQueryBuilder();

		$values = [];
		foreach ($data as $key => $value) {
			$values[$key] = $builder->createNamedParameter($value);
		}

		$builder->insert('filecache')
			->values($values)
			->execute();
	}

	private function search(ISearchOperator $operator) {
		$dbOperator = $this->querySearchHelper->searchOperatorToDBExpr($this->builder, $operator);
		$this->builder->andWhere($dbOperator);
		return $this->builder->execute()->fetchAll(\PDO::FETCH_COLUMN);
	}

	public function comparisonProvider() {
		return [
			[new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125), [1002]],
			[new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125), [1001]],
			[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 125), []],
			[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50), [1001, 1002]],
			[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', 'foobar'), [1001]],
			[new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', 'foo%'), [1001, 1002]],
			[new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'image/jpg'), [1001]],
			[new SearchComparison(ISearchComparison::COMPARE_LIKE, 'mimetype', 'image/%'), [1001, 1002]],
			[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
				new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'size', 50),
				new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125), [1001]
			]), [1001]],
			[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
				new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 100),
				new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
			]), [1001, 1002]],
			[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
				new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mtime', 150),
			]), [1001]],
			[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
				new SearchComparison(ISearchComparison::COMPARE_GREATER_THAN, 'mtime', 125),
			]), [1001]],
			[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
				new SearchComparison(ISearchComparison::COMPARE_LESS_THAN, 'mtime', 125),
			]), [1002]],
			[new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_NOT, [
				new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%bar'),
			]), [1002]],

		];
	}

	/**
	 * @dataProvider comparisonProvider
	 *
	 * @param ISearchOperator $operator
	 * @param array $fileIds
	 */
	public function testComparison(ISearchOperator $operator, array $fileIds) {
		$this->addCacheEntry([
			'path' => 'foobar',
			'fileid' => 1001,
			'mtime' => 100,
			'size' => 50,
			'mimetype' => 'image/jpg'
		]);

		$this->addCacheEntry([
			'path' => 'fooasd',
			'fileid' => 1002,
			'mtime' => 150,
			'size' => 50,
			'mimetype' => 'image/png'
		]);

		$results = $this->search($operator);

		sort($fileIds);
		sort($results);

		$this->assertEquals($fileIds, $results);
	}
}