Completed
Push — stable8.2 ( 488e5b...aae839 )
by Thomas
18:12
created

Test_Files_Versioning::testRestoreNoPermission()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 20
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 32
ccs 21
cts 22
cp 0.9545
crap 1
rs 8.8571
1
<?php
2
/**
3
 * @author Björn Schießle <[email protected]>
4
 * @author Georg Ehrke <[email protected]>
5
 * @author Joas Schilling <[email protected]>
6
 * @author Jörn Friedrich Dreyer <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Robin Appelman <[email protected]>
10
 * @author Thomas Müller <[email protected]>
11
 * @author Vincent Petry <[email protected]>
12
 *
13
 * @copyright Copyright (c) 2015, ownCloud, Inc.
14
 * @license AGPL-3.0
15
 *
16
 * This code is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License, version 3,
18
 * as published by the Free Software Foundation.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License, version 3,
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
27
 *
28
 */
29
30
require_once __DIR__ . '/../appinfo/app.php';
31
32
use OC\Files\Storage\Temporary;
33
34
/**
35
 * Class Test_Files_versions
36
 * this class provide basic files versions test
37
 */
38
class Test_Files_Versioning extends \Test\TestCase {
39
40
	const TEST_VERSIONS_USER = 'test-versions-user';
41
	const TEST_VERSIONS_USER2 = 'test-versions-user2';
42
	const USERS_VERSIONS_ROOT = '/test-versions-user/files_versions';
43
44
	/**
45
	 * @var \OC\Files\View
46
	 */
47
	private $rootView;
48
49
	public static function setUpBeforeClass() {
50
		parent::setUpBeforeClass();
51
52
		$application = new \OCA\Files_Sharing\AppInfo\Application();
53
		$application->registerMountProviders();
54
		$application->setupPropagation();
55
56
		// create test user
57
		self::loginHelper(self::TEST_VERSIONS_USER2, true);
58
		self::loginHelper(self::TEST_VERSIONS_USER, true);
59
	}
60
61
	public static function tearDownAfterClass() {
62
		// cleanup test user
63
		\OC_User::deleteUser(self::TEST_VERSIONS_USER);
64
		\OC_User::deleteUser(self::TEST_VERSIONS_USER2);
65
66
		parent::tearDownAfterClass();
67
	}
68
69 18
	protected function setUp() {
70 18
		parent::setUp();
71
72
		// clear hooks
73 18
		\OC_Hook::clear();
74 18
		\OC::registerShareHooks();
75 18
		\OCA\Files_Versions\Hooks::connectHooks();
76
77 18
		self::loginHelper(self::TEST_VERSIONS_USER);
78 18
		$this->rootView = new \OC\Files\View();
79 18
		if (!$this->rootView->file_exists(self::USERS_VERSIONS_ROOT)) {
80 18
			$this->rootView->mkdir(self::USERS_VERSIONS_ROOT);
81 18
		}
82 18
	}
83
84 18
	protected function tearDown() {
85 18
		$this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files/');
86 18
		$this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files/');
87 18
		$this->rootView->deleteAll(self::TEST_VERSIONS_USER . '/files_versions/');
88 18
		$this->rootView->deleteAll(self::TEST_VERSIONS_USER2 . '/files_versions/');
89
90 18
		\OC_Hook::clear();
91
92 18
		parent::tearDown();
93 18
	}
94
95
	/**
96
	 * @medium
97
	 * test expire logic
98
	 * @dataProvider versionsProvider
99
	 */
100 3
	public function testGetExpireList($versions, $sizeOfAllDeletedFiles) {
101
102
		// last interval end at 2592000
103 3
		$startTime = 5000000;
104
105 3
		$testClass = new VersionStorageToTest();
106 3
		list($deleted, $size) = $testClass->callProtectedGetExpireList($startTime, $versions);
107
108
		// we should have deleted 16 files each of the size 1
109 3
		$this->assertEquals($sizeOfAllDeletedFiles, $size);
110
111
		// the deleted array should only contain versions which should be deleted
112 3
		foreach($deleted as $key => $path) {
113 3
			unset($versions[$key]);
114 3
			$this->assertEquals("delete", substr($path, 0, strlen("delete")));
115 3
		}
116
117
		// the versions array should only contain versions which should be kept
118 3
		foreach ($versions as $version) {
119 3
			$this->assertEquals("keep", $version['path']);
120 3
		}
121
122 3
	}
123
124
	public function versionsProvider() {
125
		return array(
126
			// first set of versions uniformly distributed versions
127
			array(
128
				array(
129
					// first slice (10sec) keep one version every 2 seconds
130
					array("version" => 4999999, "path" => "keep", "size" => 1),
131
					array("version" => 4999998, "path" => "delete", "size" => 1),
132
					array("version" => 4999997, "path" => "keep", "size" => 1),
133
					array("version" => 4999995, "path" => "keep", "size" => 1),
134
					array("version" => 4999994, "path" => "delete", "size" => 1),
135
					//next slice (60sec) starts at 4999990 keep one version every 10 secons
136
					array("version" => 4999988, "path" => "keep", "size" => 1),
137
					array("version" => 4999978, "path" => "keep", "size" => 1),
138
					array("version" => 4999975, "path" => "delete", "size" => 1),
139
					array("version" => 4999972, "path" => "delete", "size" => 1),
140
					array("version" => 4999967, "path" => "keep", "size" => 1),
141
					array("version" => 4999958, "path" => "delete", "size" => 1),
142
					array("version" => 4999957, "path" => "keep", "size" => 1),
143
					//next slice (3600sec) start at 4999940 keep one version every 60 seconds
144
					array("version" => 4999900, "path" => "keep", "size" => 1),
145
					array("version" => 4999841, "path" => "delete", "size" => 1),
146
					array("version" => 4999840, "path" => "keep", "size" => 1),
147
					array("version" => 4999780, "path" => "keep", "size" => 1),
148
					array("version" => 4996401, "path" => "keep", "size" => 1),
149
					// next slice (86400sec) start at 4996400 keep one version every 3600 seconds
150
					array("version" => 4996350, "path" => "delete", "size" => 1),
151
					array("version" => 4992800, "path" => "keep", "size" => 1),
152
					array("version" => 4989800, "path" => "delete", "size" => 1),
153
					array("version" => 4989700, "path" => "delete", "size" => 1),
154
					array("version" => 4989200, "path" => "keep", "size" => 1),
155
					// next slice (2592000sec) start at 4913600 keep one version every 86400 seconds
156
					array("version" => 4913600, "path" => "keep", "size" => 1),
157
					array("version" => 4852800, "path" => "delete", "size" => 1),
158
					array("version" => 4827201, "path" => "delete", "size" => 1),
159
					array("version" => 4827200, "path" => "keep", "size" => 1),
160
					array("version" => 4777201, "path" => "delete", "size" => 1),
161
					array("version" => 4777501, "path" => "delete", "size" => 1),
162
					array("version" => 4740000, "path" => "keep", "size" => 1),
163
					// final slice starts at 2408000 keep one version every 604800 secons
164
					array("version" => 2408000, "path" => "keep", "size" => 1),
165
					array("version" => 1803201, "path" => "delete", "size" => 1),
166
					array("version" => 1803200, "path" => "keep", "size" => 1),
167
					array("version" => 1800199, "path" => "delete", "size" => 1),
168
					array("version" => 1800100, "path" => "delete", "size" => 1),
169
					array("version" => 1198300, "path" => "keep", "size" => 1),
170
				),
171
				16 // size of all deleted files (every file has the size 1)
172
			),
173
			// second set of versions, here we have only really old versions
174
			array(
175
				array(
176
					// first slice (10sec) keep one version every 2 seconds
177
					// next slice (60sec) starts at 4999990 keep one version every 10 secons
178
					// next slice (3600sec) start at 4999940 keep one version every 60 seconds
179
					// next slice (86400sec) start at 4996400 keep one version every 3600 seconds
180
					array("version" => 4996400, "path" => "keep", "size" => 1),
181
					array("version" => 4996350, "path" => "delete", "size" => 1),
182
					array("version" => 4996350, "path" => "delete", "size" => 1),
183
					array("version" => 4992800, "path" => "keep", "size" => 1),
184
					array("version" => 4989800, "path" => "delete", "size" => 1),
185
					array("version" => 4989700, "path" => "delete", "size" => 1),
186
					array("version" => 4989200, "path" => "keep", "size" => 1),
187
					// next slice (2592000sec) start at 4913600 keep one version every 86400 seconds
188
					array("version" => 4913600, "path" => "keep", "size" => 1),
189
					array("version" => 4852800, "path" => "delete", "size" => 1),
190
					array("version" => 4827201, "path" => "delete", "size" => 1),
191
					array("version" => 4827200, "path" => "keep", "size" => 1),
192
					array("version" => 4777201, "path" => "delete", "size" => 1),
193
					array("version" => 4777501, "path" => "delete", "size" => 1),
194
					array("version" => 4740000, "path" => "keep", "size" => 1),
195
					// final slice starts at 2408000 keep one version every 604800 secons
196
					array("version" => 2408000, "path" => "keep", "size" => 1),
197
					array("version" => 1803201, "path" => "delete", "size" => 1),
198
					array("version" => 1803200, "path" => "keep", "size" => 1),
199
					array("version" => 1800199, "path" => "delete", "size" => 1),
200
					array("version" => 1800100, "path" => "delete", "size" => 1),
201
					array("version" => 1198300, "path" => "keep", "size" => 1),
202
				),
203
				11 // size of all deleted files (every file has the size 1)
204
			),
205
			// third set of versions, with some gaps inbetween
206
			array(
207
				array(
208
					// first slice (10sec) keep one version every 2 seconds
209
					array("version" => 4999999, "path" => "keep", "size" => 1),
210
					array("version" => 4999998, "path" => "delete", "size" => 1),
211
					array("version" => 4999997, "path" => "keep", "size" => 1),
212
					array("version" => 4999995, "path" => "keep", "size" => 1),
213
					array("version" => 4999994, "path" => "delete", "size" => 1),
214
					//next slice (60sec) starts at 4999990 keep one version every 10 secons
215
					array("version" => 4999988, "path" => "keep", "size" => 1),
216
					array("version" => 4999978, "path" => "keep", "size" => 1),
217
					//next slice (3600sec) start at 4999940 keep one version every 60 seconds
218
					// next slice (86400sec) start at 4996400 keep one version every 3600 seconds
219
					array("version" => 4989200, "path" => "keep", "size" => 1),
220
					// next slice (2592000sec) start at 4913600 keep one version every 86400 seconds
221
					array("version" => 4913600, "path" => "keep", "size" => 1),
222
					array("version" => 4852800, "path" => "delete", "size" => 1),
223
					array("version" => 4827201, "path" => "delete", "size" => 1),
224
					array("version" => 4827200, "path" => "keep", "size" => 1),
225
					array("version" => 4777201, "path" => "delete", "size" => 1),
226
					array("version" => 4777501, "path" => "delete", "size" => 1),
227
					array("version" => 4740000, "path" => "keep", "size" => 1),
228
					// final slice starts at 2408000 keep one version every 604800 secons
229
					array("version" => 2408000, "path" => "keep", "size" => 1),
230
					array("version" => 1803201, "path" => "delete", "size" => 1),
231
					array("version" => 1803200, "path" => "keep", "size" => 1),
232
					array("version" => 1800199, "path" => "delete", "size" => 1),
233
					array("version" => 1800100, "path" => "delete", "size" => 1),
234
					array("version" => 1198300, "path" => "keep", "size" => 1),
235
				),
236
				9 // size of all deleted files (every file has the size 1)
237
			),
238
239
		);
240
	}
241
242 1 View Code Duplication
	public function testRename() {
243
244 1
		\OC\Files\Filesystem::file_put_contents("test.txt", "test file");
245
246 1
		$t1 = time();
247
		// second version is two weeks older, this way we make sure that no
248
		// version will be expired
249 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
250
251
		// create some versions
252 1
		$v1 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t1;
253 1
		$v2 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t2;
254 1
		$v1Renamed = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t1;
255 1
		$v2Renamed = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t2;
256
257 1
		$this->rootView->file_put_contents($v1, 'version1');
258 1
		$this->rootView->file_put_contents($v2, 'version2');
259
260
		// execute rename hook of versions app
261 1
		\OC\Files\Filesystem::rename("test.txt", "test2.txt");
262
263 1
		$this->runCommands();
264
265 1
		$this->assertFalse($this->rootView->file_exists($v1));
266 1
		$this->assertFalse($this->rootView->file_exists($v2));
267
268 1
		$this->assertTrue($this->rootView->file_exists($v1Renamed));
269 1
		$this->assertTrue($this->rootView->file_exists($v2Renamed));
270 1
	}
271
272 1
	public function testRenameInSharedFolder() {
273
274 1
		\OC\Files\Filesystem::mkdir('folder1');
275 1
		\OC\Files\Filesystem::mkdir('folder1/folder2');
276 1
		\OC\Files\Filesystem::file_put_contents("folder1/test.txt", "test file");
277
278 1
		$fileInfo = \OC\Files\Filesystem::getFileInfo('folder1');
279
280 1
		$t1 = time();
281
		// second version is two weeks older, this way we make sure that no
282
		// version will be expired
283 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
284
285 1
		$this->rootView->mkdir(self::USERS_VERSIONS_ROOT . '/folder1');
286
		// create some versions
287 1
		$v1 = self::USERS_VERSIONS_ROOT . '/folder1/test.txt.v' . $t1;
288 1
		$v2 = self::USERS_VERSIONS_ROOT . '/folder1/test.txt.v' . $t2;
289 1
		$v1Renamed = self::USERS_VERSIONS_ROOT . '/folder1/folder2/test.txt.v' . $t1;
290 1
		$v2Renamed = self::USERS_VERSIONS_ROOT . '/folder1/folder2/test.txt.v' . $t2;
291
292 1
		$this->rootView->file_put_contents($v1, 'version1');
293 1
		$this->rootView->file_put_contents($v2, 'version2');
294
295 1
		\OCP\Share::shareItem('folder', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_VERSIONS_USER2, \OCP\Constants::PERMISSION_ALL);
296
297 1
		self::loginHelper(self::TEST_VERSIONS_USER2);
298
299 1
		$this->assertTrue(\OC\Files\Filesystem::file_exists('folder1/test.txt'));
300
301
		// execute rename hook of versions app
302 1
		\OC\Files\Filesystem::rename('/folder1/test.txt', '/folder1/folder2/test.txt');
303
304 1
		$this->runCommands();
305
306 1
		self::loginHelper(self::TEST_VERSIONS_USER);
307
308 1
		$this->assertFalse($this->rootView->file_exists($v1));
309 1
		$this->assertFalse($this->rootView->file_exists($v2));
310
311 1
		$this->assertTrue($this->rootView->file_exists($v1Renamed));
312 1
		$this->assertTrue($this->rootView->file_exists($v2Renamed));
313 1
	}
314
315 1
	public function testMoveFolder() {
316
317 1
		\OC\Files\Filesystem::mkdir('folder1');
318 1
		\OC\Files\Filesystem::mkdir('folder2');
319 1
		\OC\Files\Filesystem::file_put_contents('folder1/test.txt', 'test file');
320
321 1
		$t1 = time();
322
		// second version is two weeks older, this way we make sure that no
323
		// version will be expired
324 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
325
326
		// create some versions
327 1
		$this->rootView->mkdir(self::USERS_VERSIONS_ROOT . '/folder1');
328 1
		$v1 = self::USERS_VERSIONS_ROOT . '/folder1/test.txt.v' . $t1;
329 1
		$v2 = self::USERS_VERSIONS_ROOT . '/folder1/test.txt.v' . $t2;
330 1
		$v1Renamed = self::USERS_VERSIONS_ROOT . '/folder2/folder1/test.txt.v' . $t1;
331 1
		$v2Renamed = self::USERS_VERSIONS_ROOT . '/folder2/folder1/test.txt.v' . $t2;
332
333 1
		$this->rootView->file_put_contents($v1, 'version1');
334 1
		$this->rootView->file_put_contents($v2, 'version2');
335
336
		// execute rename hook of versions app
337 1
		\OC\Files\Filesystem::rename('folder1', 'folder2/folder1');
338
339 1
		$this->runCommands();
340
341 1
		$this->assertFalse($this->rootView->file_exists($v1));
342 1
		$this->assertFalse($this->rootView->file_exists($v2));
343
344 1
		$this->assertTrue($this->rootView->file_exists($v1Renamed));
345 1
		$this->assertTrue($this->rootView->file_exists($v2Renamed));
346 1
	}
347
348
349 1
	public function testMoveFileIntoSharedFolderAsRecipient() {
350
351 1
		\OC\Files\Filesystem::mkdir('folder1');
352 1
		$fileInfo = \OC\Files\Filesystem::getFileInfo('folder1');
353
354 1
		\OCP\Share::shareItem(
355 1
			'folder',
356 1
			$fileInfo['fileid'],
357 1
			\OCP\Share::SHARE_TYPE_USER,
358 1
			self::TEST_VERSIONS_USER2,
359
			\OCP\Constants::PERMISSION_ALL
360 1
		);
361
362 1
		self::loginHelper(self::TEST_VERSIONS_USER2);
363 1
		$versionsFolder2 = '/' . self::TEST_VERSIONS_USER2 . '/files_versions';
364 1
		\OC\Files\Filesystem::file_put_contents('test.txt', 'test file');
365
366 1
		$t1 = time();
367
		// second version is two weeks older, this way we make sure that no
368
		// version will be expired
369 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
370
371 1
		$this->rootView->mkdir($versionsFolder2);
372
		// create some versions
373 1
		$v1 = $versionsFolder2 . '/test.txt.v' . $t1;
374 1
		$v2 = $versionsFolder2 . '/test.txt.v' . $t2;
375
376 1
		$this->rootView->file_put_contents($v1, 'version1');
377 1
		$this->rootView->file_put_contents($v2, 'version2');
378
379
		// move file into the shared folder as recipient
380 1
		\OC\Files\Filesystem::rename('/test.txt', '/folder1/test.txt');
381
382 1
		$this->assertFalse($this->rootView->file_exists($v1));
383 1
		$this->assertFalse($this->rootView->file_exists($v2));
384
385 1
		self::loginHelper(self::TEST_VERSIONS_USER);
386
387 1
		$versionsFolder1 = '/' . self::TEST_VERSIONS_USER . '/files_versions';
388
389 1
		$v1Renamed = $versionsFolder1 . '/folder1/test.txt.v' . $t1;
390 1
		$v2Renamed = $versionsFolder1 . '/folder1/test.txt.v' . $t2;
391
392 1
		$this->assertTrue($this->rootView->file_exists($v1Renamed));
393 1
		$this->assertTrue($this->rootView->file_exists($v2Renamed));
394 1
	}
395
396 1
	public function testMoveFolderIntoSharedFolderAsRecipient() {
397
398 1
		\OC\Files\Filesystem::mkdir('folder1');
399 1
		$fileInfo = \OC\Files\Filesystem::getFileInfo('folder1');
400
401 1
		\OCP\Share::shareItem(
402 1
			'folder',
403 1
			$fileInfo['fileid'],
404 1
			\OCP\Share::SHARE_TYPE_USER,
405 1
			self::TEST_VERSIONS_USER2,
406
			\OCP\Constants::PERMISSION_ALL
407 1
		);
408
409 1
		self::loginHelper(self::TEST_VERSIONS_USER2);
410 1
		$versionsFolder2 = '/' . self::TEST_VERSIONS_USER2 . '/files_versions';
411 1
		\OC\Files\Filesystem::mkdir('folder2');
412 1
		\OC\Files\Filesystem::file_put_contents('folder2/test.txt', 'test file');
413
414 1
		$t1 = time();
415
		// second version is two weeks older, this way we make sure that no
416
		// version will be expired
417 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
418
419 1
		$this->rootView->mkdir($versionsFolder2);
420 1
		$this->rootView->mkdir($versionsFolder2 . '/folder2');
421
		// create some versions
422 1
		$v1 = $versionsFolder2 . '/folder2/test.txt.v' . $t1;
423 1
		$v2 = $versionsFolder2 . '/folder2/test.txt.v' . $t2;
424
425 1
		$this->rootView->file_put_contents($v1, 'version1');
426 1
		$this->rootView->file_put_contents($v2, 'version2');
427
428
		// move file into the shared folder as recipient
429 1
		\OC\Files\Filesystem::rename('/folder2', '/folder1/folder2');
430
431 1
		$this->assertFalse($this->rootView->file_exists($v1));
432 1
		$this->assertFalse($this->rootView->file_exists($v2));
433
434 1
		self::loginHelper(self::TEST_VERSIONS_USER);
435
436 1
		$versionsFolder1 = '/' . self::TEST_VERSIONS_USER . '/files_versions';
437
438 1
		$v1Renamed = $versionsFolder1 . '/folder1/folder2/test.txt.v' . $t1;
439 1
		$v2Renamed = $versionsFolder1 . '/folder1/folder2/test.txt.v' . $t2;
440
441 1
		$this->assertTrue($this->rootView->file_exists($v1Renamed));
442 1
		$this->assertTrue($this->rootView->file_exists($v2Renamed));
443 1
	}
444
445 1
	public function testRenameSharedFile() {
446
447 1
		\OC\Files\Filesystem::file_put_contents("test.txt", "test file");
448
449 1
		$fileInfo = \OC\Files\Filesystem::getFileInfo('test.txt');
450
451 1
		$t1 = time();
452
		// second version is two weeks older, this way we make sure that no
453
		// version will be expired
454 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
455
456 1
		$this->rootView->mkdir(self::USERS_VERSIONS_ROOT);
457
		// create some versions
458 1
		$v1 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t1;
459 1
		$v2 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t2;
460
		// the renamed versions should not exist! Because we only moved the mount point!
461 1
		$v1Renamed = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t1;
462 1
		$v2Renamed = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t2;
463
464 1
		$this->rootView->file_put_contents($v1, 'version1');
465 1
		$this->rootView->file_put_contents($v2, 'version2');
466
467 1
		\OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_USER, self::TEST_VERSIONS_USER2, \OCP\Constants::PERMISSION_ALL);
468
469 1
		self::loginHelper(self::TEST_VERSIONS_USER2);
470
471 1
		$this->assertTrue(\OC\Files\Filesystem::file_exists('test.txt'));
472
473
		// execute rename hook of versions app
474 1
		\OC\Files\Filesystem::rename('test.txt', 'test2.txt');
475
476 1
		self::loginHelper(self::TEST_VERSIONS_USER);
477
478 1
		$this->runCommands();
479
480 1
		$this->assertTrue($this->rootView->file_exists($v1));
481 1
		$this->assertTrue($this->rootView->file_exists($v2));
482
483 1
		$this->assertFalse($this->rootView->file_exists($v1Renamed));
484 1
		$this->assertFalse($this->rootView->file_exists($v2Renamed));
485 1
	}
486
487 1 View Code Duplication
	public function testCopy() {
488
489 1
		\OC\Files\Filesystem::file_put_contents("test.txt", "test file");
490
491 1
		$t1 = time();
492
		// second version is two weeks older, this way we make sure that no
493
		// version will be expired
494 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
495
496
		// create some versions
497 1
		$v1 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t1;
498 1
		$v2 = self::USERS_VERSIONS_ROOT . '/test.txt.v' . $t2;
499 1
		$v1Copied = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t1;
500 1
		$v2Copied = self::USERS_VERSIONS_ROOT . '/test2.txt.v' . $t2;
501
502 1
		$this->rootView->file_put_contents($v1, 'version1');
503 1
		$this->rootView->file_put_contents($v2, 'version2');
504
505
		// execute copy hook of versions app
506 1
		\OC\Files\Filesystem::copy("test.txt", "test2.txt");
507
508 1
		$this->runCommands();
509
510 1
		$this->assertTrue($this->rootView->file_exists($v1));
511 1
		$this->assertTrue($this->rootView->file_exists($v2));
512
513 1
		$this->assertTrue($this->rootView->file_exists($v1Copied));
514 1
		$this->assertTrue($this->rootView->file_exists($v2Copied));
515 1
	}
516
517
	/**
518
	 * test if we find all versions and if the versions array contain
519
	 * the correct 'path' and 'name'
520
	 */
521 1
	public function testGetVersions() {
522
523 1
		$t1 = time();
524
		// second version is two weeks older, this way we make sure that no
525
		// version will be expired
526 1
		$t2 = $t1 - 60 * 60 * 24 * 14;
527
528
		// create some versions
529 1
		$v1 = self::USERS_VERSIONS_ROOT . '/subfolder/test.txt.v' . $t1;
530 1
		$v2 = self::USERS_VERSIONS_ROOT . '/subfolder/test.txt.v' . $t2;
531
532 1
		$this->rootView->mkdir(self::USERS_VERSIONS_ROOT . '/subfolder/');
533
534 1
		$this->rootView->file_put_contents($v1, 'version1');
535 1
		$this->rootView->file_put_contents($v2, 'version2');
536
537
		// execute copy hook of versions app
538 1
		$versions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, '/subfolder/test.txt');
539
540 1
		$this->assertCount(2, $versions);
541
542 1
		foreach ($versions as $version) {
543 1
			$this->assertSame('/subfolder/test.txt', $version['path']);
544 1
			$this->assertSame('test.txt', $version['name']);
545 1
		}
546
547
		//cleanup
548 1
		$this->rootView->deleteAll(self::USERS_VERSIONS_ROOT . '/subfolder');
549 1
	}
550
551
	/**
552
	 * test if we find all versions and if the versions array contain
553
	 * the correct 'path' and 'name'
554
	 */
555 1
	public function testGetVersionsEmptyFile() {
556
		// execute copy hook of versions app
557 1
		$versions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, '');
558 1
		$this->assertCount(0, $versions);
559
560 1
		$versions = \OCA\Files_Versions\Storage::getVersions(self::TEST_VERSIONS_USER, null);
561 1
		$this->assertCount(0, $versions);
562 1
	}
563
564 1
	public function testExpireNonexistingFile() {
565 1
		$this->logout();
566
		// needed to have a FS setup (the background job does this)
567 1
		\OC_Util::setupFS(self::TEST_VERSIONS_USER);
568
569 1
		$this->assertFalse(\OCA\Files_Versions\Storage::expire('/void/unexist.txt'));
570 1
	}
571
572 1
	public function testRestoreSameStorage() {
573 1
		\OC\Files\Filesystem::mkdir('sub');
574 1
		$this->doTestRestore();
575 1
	}
576
577 1
	public function testRestoreCrossStorage() {
578 1
		$storage2 = new Temporary(array());
579 1
		\OC\Files\Filesystem::mount($storage2, array(), self::TEST_VERSIONS_USER . '/files/sub');
580
581 1
		$this->doTestRestore();
582 1
	}
583
584
	public function testRestoreNoPermission() {
585
		$this->loginAsUser(self::TEST_VERSIONS_USER);
586
587
		$userHome = \OC::$server->getUserFolder(self::TEST_VERSIONS_USER);
588 2
		$node = $userHome->newFolder('folder');
589 2
		$file = $node->newFile('test.txt');
590
591
		\OCP\Share::shareItem(
592
			'folder',
593 2
			$file->getId(),
594 2
			\OCP\Share::SHARE_TYPE_USER,
595 2
			self::TEST_VERSIONS_USER2,
596
			\OCP\Constants::PERMISSION_READ
597 2
		);
598 2
599 2
		$versions = $this->createAndCheckVersions(
600 2
			\OC\Files\Filesystem::getView(),
601 2
			'folder/test.txt'
602 2
		);
603 2
604
		$file->putContent('test file');
605 2
606 2
		$this->loginAsUser(self::TEST_VERSIONS_USER2);
607 2
608 2
		$firstVersion = current($versions);
609
610 2
		$this->assertFalse(\OCA\Files_Versions\Storage::rollback('folder/test.txt', $firstVersion['version']), 'Revert did not happen');
611 2
612
		$this->loginAsUser(self::TEST_VERSIONS_USER);
613 2
614 2
		$this->assertEquals('test file', $file->getContent(), 'File content has not changed');
615 2
	}
616
617 2
	/**
618
	 * @param string $hookName name of hook called
619
	 * @param string $params variable to recieve parameters provided by hook
620 2
	 */
621
	private function connectMockHooks($hookName, &$params) {
622 2
		if ($hookName === null) {
623
			return;
624
		}
625 2
626 2
		$eventHandler = $this->getMockBuilder('\stdclass')
627
			->setMethods(['callback'])
628 2
			->getMock();
629 2
630 2
		$eventHandler->expects($this->any())
631
			->method('callback')
632 2
			->will($this->returnCallback(
633 2
				function($p) use (&$params) {
634 2
					$params = $p;
635
				}
636 2
			));
637
638 2
		\OCP\Util::connectHook(
639 2
			'\OCP\Versions',
640
			$hookName,
641 2
			$eventHandler,
642 2
			'callback'
643
		);
644 2
	}
645
646 2
	private function doTestRestore() {
647 2
		$filePath = self::TEST_VERSIONS_USER . '/files/sub/test.txt';
648
		$this->rootView->file_put_contents($filePath, 'test file');
649 2
650
		$t0 = $this->rootView->filemtime($filePath);
651 2
652 2
		// not exactly the same timestamp as the file
653
		$t1 = time() - 60;
654 2
		// second version is two weeks older
655 2
		$t2 = $t1 - 60 * 60 * 24 * 14;
656 2
657
		// create some versions
658 2
		$v1 = self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t1;
659 2
		$v2 = self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t2;
660 2
661 2
		$this->rootView->mkdir(self::USERS_VERSIONS_ROOT . '/sub');
662
		$this->rootView->file_put_contents($v1, 'version1');
663 2
		$this->rootView->file_put_contents($v2, 'version2');
664 2
665 2
		$oldVersions = \OCA\Files_Versions\Storage::getVersions(
666 2
			self::TEST_VERSIONS_USER, '/sub/test.txt'
667
		);
668 2
669
		$this->assertCount(2, $oldVersions);
670 2
671 2
		$this->assertEquals('test file', $this->rootView->file_get_contents($filePath));
672 2
		$info1 = $this->rootView->getFileInfo($filePath);
673
674 2
		$params = array();
675 2
		$this->connectMockHooks('rollback', $params);
676
677 2
		$this->assertTrue(\OCA\Files_Versions\Storage::rollback('sub/test.txt', $t2));
678 2
		$expectedParams = array(
679 2
			'path' => '/sub/test.txt',
680
		);
681 2
682 2
		$this->assertEquals($expectedParams, $params);
683 2
684
		$this->assertEquals('version2', $this->rootView->file_get_contents($filePath));
685 2
		$info2 = $this->rootView->getFileInfo($filePath);
686
687 2
		$this->assertNotEquals(
688
			$info2['etag'],
689 2
			$info1['etag'],
690 2
			'Etag must change after rolling back version'
691
		);
692 2
		$this->assertEquals(
693 2
			$info2['fileid'],
694 2
			$info1['fileid'],
695
			'File id must not change after rolling back version'
696 2
		);
697 2
		$this->assertEquals(
698 2
			$info2['mtime'],
699
			$t2,
700 2
			'Restored file has mtime from version'
701 2
		);
702
703
		$newVersions = \OCA\Files_Versions\Storage::getVersions(
704
			self::TEST_VERSIONS_USER, '/sub/test.txt'
705
		);
706 1
707 1
		$this->assertTrue(
708
			$this->rootView->file_exists(self::USERS_VERSIONS_ROOT . '/sub/test.txt.v' . $t0),
709 1
			'A version file was created for the file before restoration'
710 1
		);
711
		$this->assertTrue(
712 1
			$this->rootView->file_exists($v1),
713 1
			'Untouched version file is still there'
714
		);
715
		$this->assertFalse(
716
			$this->rootView->file_exists($v2),
717
			'Restored version file gone from files_version folder'
718 1
		);
719 1
720
		$this->assertCount(2, $newVersions, 'Additional version created');
721 1
722 1
		$this->assertTrue(
723 1
			isset($newVersions[$t0 . '#' . 'test.txt']),
724
			'A version was created for the file before restoration'
725 1
		);
726 1
		$this->assertTrue(
727 1
			isset($newVersions[$t1 . '#' . 'test.txt']),
728 1
			'Untouched version is still there'
729 1
		);
730
		$this->assertFalse(
731 1
			isset($newVersions[$t2 . '#' . 'test.txt']),
732
			'Restored version is not in the list any more'
733 1
		);
734
	}
735 1
736 1
	/**
737
	 * Test whether versions are created when overwriting as owner
738 1
	 */
739 1
	public function testStoreVersionAsOwner() {
740
		$this->loginAsUser(self::TEST_VERSIONS_USER);
741
742
		$this->createAndCheckVersions(
743
			\OC\Files\Filesystem::getView(),
744
			'test.txt'
745
		);
746
	}
747
748 1
	/**
749 1
	 * Test whether versions are created when overwriting as share recipient
750
	 */
751
	public function testStoreVersionAsRecipient() {
752
		$this->loginAsUser(self::TEST_VERSIONS_USER);
753 1
754
		\OC\Files\Filesystem::mkdir('folder');
755 1
		\OC\Files\Filesystem::file_put_contents('folder/test.txt', 'test file');
756 1
		$fileInfo = \OC\Files\Filesystem::getFileInfo('folder');
757 1
758
		\OCP\Share::shareItem(
759 1
			'folder',
760 1
			$fileInfo['fileid'],
761
			\OCP\Share::SHARE_TYPE_USER,
762 3
			self::TEST_VERSIONS_USER2,
763 3
			\OCP\Constants::PERMISSION_ALL
764 3
		);
765 3
766
		$this->loginAsUser(self::TEST_VERSIONS_USER2);
767 3
768
		$this->createAndCheckVersions(
769
			\OC\Files\Filesystem::getView(),
770 3
			'folder/test.txt'
771 3
		);
772
	}
773 3
774 3
	/**
775 3
	 * Test whether versions are created when overwriting anonymously.
776
	 *
777
	 * When uploading through a public link or publicwebdav, no user
778
	 * is logged in. File modification must still be able to find
779 3
	 * the owner and create versions.
780 3
	 */
781
	public function testStoreVersionAsAnonymous() {
782
		$this->logout();
783
784
		// note: public link upload does this,
785
		// needed to make the hooks fire
786
		\OC_Util::setupFS(self::TEST_VERSIONS_USER);
787 18
788
		$userView = new \OC\Files\View('/' . self::TEST_VERSIONS_USER . '/files');
789 18
		$this->createAndCheckVersions(
790
			$userView,
791
			'test.txt'
792
		);
793
	}
794
795 18
	private function createAndCheckVersions($view, $path) {
796 18
		$view->file_put_contents($path, 'test file');
797 18
		$view->file_put_contents($path, 'version 1');
798 18
		$view->file_put_contents($path, 'version 2');
799 18
800
		$this->loginAsUser(self::TEST_VERSIONS_USER);
801 18
802 18
		// need to scan for the versions
803 18
		list($rootStorage,) = $this->rootView->resolvePath(self::TEST_VERSIONS_USER . '/files_versions');
804 18
		$rootStorage->getScanner()->scan('files_versions');
805 18
806 18
		$versions = \OCA\Files_Versions\Storage::getVersions(
807 18
			self::TEST_VERSIONS_USER, '/' . $path
808
		);
809
810
		// note: we cannot predict how many versions are created due to
811
		// test run timing
812
		$this->assertGreaterThan(0, count($versions));
813
814
		return $versions;
815
	}
816
817 3
	/**
818 3
	 * @param string $user
819
	 * @param bool $create
820
	 * @param bool $password
0 ignored issues
show
Bug introduced by
There is no parameter named $password. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
821
	 */
822
	public static function loginHelper($user, $create = false) {
823
824
		if ($create) {
825
			$backend  = new \Test\Util\User\Dummy();
826
			$backend->createUser($user, $user);
827
			\OC::$server->getUserManager()->registerBackend($backend);
0 ignored issues
show
Documentation introduced by
$backend is of type object<Test\Util\User\Dummy>, but the function expects a object<OCP\UserInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
828
		}
829
830
		$storage = new \ReflectionClass('\OC\Files\Storage\Shared');
831
		$isInitialized = $storage->getProperty('isInitialized');
832
		$isInitialized->setAccessible(true);
833
		$isInitialized->setValue(array());
834
		$isInitialized->setAccessible(false);
835
836
		\OC_Util::tearDownFS();
837
		\OC_User::setUserId('');
838
		\OC\Files\Filesystem::tearDown();
839
		\OC_User::setUserId($user);
840
		\OC_Util::setupFS($user);
841
		\OC::$server->getUserFolder($user);
842
	}
843
844
}
845
846
// extend the original class to make it possible to test protected methods
847
class VersionStorageToTest extends \OCA\Files_Versions\Storage {
848
849
	/**
850
	 * @param integer $time
851
	 */
852
	public function callProtectedGetExpireList($time, $versions) {
853
		return self::getExpireList($time, $versions);
854
855
	}
856
}
857