Completed
Pull Request — stable8 (#25330)
by
unknown
16:49
created

Test_Files_Versioning::connectMockHooks()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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