Completed
Push — stable8.2 ( 3b3780...cb9d0b )
by Lukas
29s
created

Encryption::testGetHeader()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 51
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 51
rs 9.4109
cc 2
eloc 35
nc 2
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Test\Files\Storage\Wrapper;
4
5
use OC\Encryption\Util;
6
use OC\Files\Storage\Temporary;
7
use OC\Files\View;
8
use Test\Files\Storage\Storage;
9
10
class Encryption extends Storage {
11
12
	/**
13
	 * block size will always be 8192 for a PHP stream
14
	 * @see https://bugs.php.net/bug.php?id=21641
15
	 * @var integer
16
	 */
17
	protected $headerSize = 8192;
18
19
	/**
20
	 * @var Temporary
21
	 */
22
	private $sourceStorage;
23
24
	/**
25
	 * @var \OC\Files\Storage\Wrapper\Encryption | \PHPUnit_Framework_MockObject_MockObject
26
	 */
27
	protected $instance;
28
29
	/**
30
	 * @var \OC\Encryption\Keys\Storage | \PHPUnit_Framework_MockObject_MockObject
31
	 */
32
	private $keyStore;
33
34
	/**
35
	 * @var \OC\Encryption\Util | \PHPUnit_Framework_MockObject_MockObject
36
	 */
37
	private $util;
38
39
	/**
40
	 * @var \OC\Encryption\Manager | \PHPUnit_Framework_MockObject_MockObject
41
	 */
42
	private $encryptionManager;
43
44
	/**
45
	 * @var \OCP\Encryption\IEncryptionModule | \PHPUnit_Framework_MockObject_MockObject
46
	 */
47
	private $encryptionModule;
48
49
	/**
50
	 * @var \OC\Encryption\Update | \PHPUnit_Framework_MockObject_MockObject
51
	 */
52
	private $update;
53
54
	/**
55
	 * @var \OC\Files\Cache\Cache | \PHPUnit_Framework_MockObject_MockObject
56
	 */
57
	private $cache;
58
59
	/**
60
	 * @var \OC\Log | \PHPUnit_Framework_MockObject_MockObject
61
	 */
62
	private $logger;
63
64
	/**
65
	 * @var \OC\Encryption\File | \PHPUnit_Framework_MockObject_MockObject
66
	 */
67
	private $file;
68
69
70
	/**
71
	 * @var \OC\Files\Mount\MountPoint | \PHPUnit_Framework_MockObject_MockObject
72
	 */
73
	private $mount;
74
75
	/**
76
	 * @var \OC\Files\Mount\Manager | \PHPUnit_Framework_MockObject_MockObject
77
	 */
78
	private $mountManager;
79
80
	/**
81
	 * @var \OC\Group\Manager | \PHPUnit_Framework_MockObject_MockObject
82
	 */
83
	private $groupManager;
84
85
	/**
86
	 * @var \OCP\IConfig | \PHPUnit_Framework_MockObject_MockObject
87
	 */
88
	private $config;
89
90
	/** @var  \OC\Memcache\ArrayCache | \PHPUnit_Framework_MockObject_MockObject */
91
	private $arrayCache;
92
93
94
	/** @var  integer dummy unencrypted size */
95
	private $dummySize = -1;
96
97
	protected function setUp() {
98
99
		parent::setUp();
100
101
		$mockModule = $this->buildMockModule();
102
		$this->encryptionManager = $this->getMockBuilder('\OC\Encryption\Manager')
103
			->disableOriginalConstructor()
104
			->setMethods(['getEncryptionModule', 'isEnabled'])
105
			->getMock();
106
		$this->encryptionManager->expects($this->any())
107
			->method('getEncryptionModule')
108
			->willReturn($mockModule);
109
110
		$this->arrayCache = $this->getMock('OC\Memcache\ArrayCache');
111
		$this->config = $this->getMockBuilder('\OCP\IConfig')
112
			->disableOriginalConstructor()
113
			->getMock();
114
		$this->groupManager = $this->getMockBuilder('\OC\Group\Manager')
115
			->disableOriginalConstructor()
116
			->getMock();
117
118
		$this->util = $this->getMock(
119
			'\OC\Encryption\Util',
120
			['getUidAndFilename', 'isFile', 'isExcluded'],
121
			[new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache]);
122
		$this->util->expects($this->any())
123
			->method('getUidAndFilename')
124
			->willReturnCallback(function ($path) {
125
				return ['user1', $path];
126
			});
127
128
		$this->file = $this->getMockBuilder('\OC\Encryption\File')
129
			->disableOriginalConstructor()
130
			->setMethods(['getAccessList'])
131
			->getMock();
132
		$this->file->expects($this->any())->method('getAccessList')->willReturn([]);
133
134
		$this->logger = $this->getMock('\OC\Log');
135
136
		$this->sourceStorage = new Temporary(array());
137
138
		$this->keyStore = $this->getMockBuilder('\OC\Encryption\Keys\Storage')
139
			->disableOriginalConstructor()->getMock();
140
141
		$this->update = $this->getMockBuilder('\OC\Encryption\Update')
142
			->disableOriginalConstructor()->getMock();
143
144
		$this->mount = $this->getMockBuilder('\OC\Files\Mount\MountPoint')
145
			->disableOriginalConstructor()
146
			->setMethods(['getOption'])
147
			->getMock();
148
		$this->mount->expects($this->any())->method('getOption')->willReturnCallback(function ($option, $default) {
149
			if ($option === 'encrypt' && $default === true) {
150
				global $mockedMountPointEncryptionEnabled;
151
				if ($mockedMountPointEncryptionEnabled !== null) {
152
					return $mockedMountPointEncryptionEnabled;
153
				}
154
			}
155
			return true;
156
		});
157
158
		$this->cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
159
			->disableOriginalConstructor()->getMock();
160
		$this->cache->expects($this->any())
161
			->method('get')
162
			->willReturnCallback(function($path) {return ['encrypted' => false, 'path' => $path];});
163
164
		$this->mountManager = $this->getMockBuilder('\OC\Files\Mount\Manager')
165
			->disableOriginalConstructor()->getMock();
166
167
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
168
			->setConstructorArgs(
169
				[
170
					[
171
						'storage' => $this->sourceStorage,
172
						'root' => 'foo',
173
						'mountPoint' => '/',
174
						'mount' => $this->mount
175
					],
176
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
177
				]
178
			)
179
			->setMethods(['getMetaData', 'getCache', 'getEncryptionModule'])
180
			->getMock();
181
182
		$this->instance->expects($this->any())
183
			->method('getMetaData')
184
			->willReturnCallback(function ($path) {
185
				return ['encrypted' => true, 'size' => $this->dummySize, 'path' => $path];
186
			});
187
188
		$this->instance->expects($this->any())
189
			->method('getCache')
190
			->willReturn($this->cache);
191
192
		$this->instance->expects($this->any())
193
			->method('getEncryptionModule')
194
			->willReturn($mockModule);
195
	}
196
197
	/**
198
	 * @return \PHPUnit_Framework_MockObject_MockObject
199
	 */
200
	protected function buildMockModule() {
201
		$this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule')
202
			->disableOriginalConstructor()
203
			->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable', 'encryptAll', 'prepareDecryptAll'])
204
			->getMock();
205
206
		$this->encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE');
207
		$this->encryptionModule->expects($this->any())->method('getDisplayName')->willReturn('Unit test module');
208
		$this->encryptionModule->expects($this->any())->method('begin')->willReturn([]);
209
		$this->encryptionModule->expects($this->any())->method('end')->willReturn('');
210
		$this->encryptionModule->expects($this->any())->method('encrypt')->willReturnArgument(0);
211
		$this->encryptionModule->expects($this->any())->method('decrypt')->willReturnArgument(0);
212
		$this->encryptionModule->expects($this->any())->method('update')->willReturn(true);
213
		$this->encryptionModule->expects($this->any())->method('shouldEncrypt')->willReturn(true);
214
		$this->encryptionModule->expects($this->any())->method('getUnencryptedBlockSize')->willReturn(8192);
215
		$this->encryptionModule->expects($this->any())->method('isReadable')->willReturn(true);
216
		return $this->encryptionModule;
217
	}
218
219
	/**
220
	 * @dataProvider dataTestGetMetaData
221
	 *
222
	 * @param string $path
223
	 * @param array $metaData
224
	 * @param bool $encrypted
225
	 * @param bool $unencryptedSizeSet
226
	 * @param int $storedUnencryptedSize
227
	 * @param array $expected
228
	 */
229
	public function testGetMetaData($path, $metaData, $encrypted, $unencryptedSizeSet, $storedUnencryptedSize, $expected) {
230
231
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
232
			->disableOriginalConstructor()->getMock();
233
234
		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
235
			->disableOriginalConstructor()->getMock();
236
		$cache->expects($this->any())
237
			->method('get')
238
			->willReturnCallback(
239
				function($path) use ($encrypted) {
240
					return ['encrypted' => $encrypted, 'path' => $path, 'size' => 0, 'fileid' => 1];
241
				}
242
			);
243
244
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
245
			->setConstructorArgs(
246
				[
247
					[
248
						'storage' => $sourceStorage,
249
						'root' => 'foo',
250
						'mountPoint' => '/',
251
						'mount' => $this->mount
252
					],
253
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
254
				]
255
			)
256
			->setMethods(['getCache', 'verifyUnencryptedSize'])
257
			->getMock();
258
259
		if($unencryptedSizeSet) {
260
			$this->invokePrivate($this->instance, 'unencryptedSize', [[$path => $storedUnencryptedSize]]);
261
		}
262
263
264
		$sourceStorage->expects($this->once())->method('getMetaData')->with($path)
265
			->willReturn($metaData);
266
267
		$this->instance->expects($this->any())->method('getCache')->willReturn($cache);
268
		$this->instance->expects($this->any())->method('verifyUnencryptedSize')
269
			->with($path, 0)->willReturn($expected['size']);
270
271
		$result = $this->instance->getMetaData($path);
272
		$this->assertSame($expected['encrypted'], $result['encrypted']);
273
		$this->assertSame($expected['size'], $result['size']);
274
	}
275
276
	public function dataTestGetMetaData() {
277
		return [
278
			['/test.txt', ['size' => 42, 'encrypted' => false], true, true, 12, ['size' => 12, 'encrypted' => true]],
279
			['/test.txt', null, true, true, 12, null],
280
			['/test.txt', ['size' => 42, 'encrypted' => false], false, false, 12, ['size' => 42, 'encrypted' => false]],
281
			['/test.txt', ['size' => 42, 'encrypted' => false], true, false, 12, ['size' => 12, 'encrypted' => true]]
282
		];
283
	}
284
285
	public function testFilesize() {
286
		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
287
			->disableOriginalConstructor()->getMock();
288
		$cache->expects($this->any())
289
			->method('get')
290
			->willReturn(['encrypted' => true, 'path' => '/test.txt', 'size' => 0, 'fileid' => 1]);
291
292
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
293
			->setConstructorArgs(
294
				[
295
					[
296
						'storage' => $this->sourceStorage,
297
						'root' => 'foo',
298
						'mountPoint' => '/',
299
						'mount' => $this->mount
300
					],
301
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
302
				]
303
			)
304
			->setMethods(['getCache', 'verifyUnencryptedSize'])
305
			->getMock();
306
307
		$this->instance->expects($this->any())->method('getCache')->willReturn($cache);
308
		$this->instance->expects($this->any())->method('verifyUnencryptedSize')
309
			->willReturn(42);
310
311
312
		$this->assertSame(42,
313
			$this->instance->filesize('/test.txt')
314
		);
315
316
	}
317
318
	/**
319
	 * @dataProvider dataTestVerifyUnencryptedSize
320
	 *
321
	 * @param int $encryptedSize
322
	 * @param int $unencryptedSize
323
	 * @param bool $failure
324
	 * @param int $expected
325
	 */
326
	public function testVerifyUnencryptedSize($encryptedSize, $unencryptedSize, $failure, $expected) {
327
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
328
			->disableOriginalConstructor()->getMock();
329
330
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
331
			->setConstructorArgs(
332
				[
333
					[
334
						'storage' => $sourceStorage,
335
						'root' => 'foo',
336
						'mountPoint' => '/',
337
						'mount' => $this->mount
338
					],
339
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
340
				]
341
			)
342
			->setMethods(['fixUnencryptedSize'])
343
			->getMock();
344
345
		$sourceStorage->expects($this->once())->method('filesize')->willReturn($encryptedSize);
346
347
		$this->instance->expects($this->any())->method('fixUnencryptedSize')
348
			->with('/test.txt', $encryptedSize, $unencryptedSize)
349
			->willReturnCallback(
350
				function() use ($failure, $expected) {
351
					if ($failure) {
352
						throw new \Exception();
353
					} else {
354
						return $expected;
355
					}
356
				}
357
			);
358
359
		$this->assertSame(
360
			$expected,
361
			$this->invokePrivate($this->instance, 'verifyUnencryptedSize', ['/test.txt', $unencryptedSize])
362
		);
363
	}
364
365
	public function dataTestVerifyUnencryptedSize() {
366
		return [
367
			[120, 80, false, 80],
368
			[120, 120, false, 80],
369
			[120, -1, false, 80],
370
			[120, -1, true, -1]
371
		];
372
	}
373
374
	/**
375
	 * @dataProvider dataTestCopyAndRename
376
	 *
377
	 * @param string $source
378
	 * @param string $target
379
	 * @param $encryptionEnabled
380
	 * @param boolean $renameKeysReturn
381
	 */
382
	public function testRename($source,
383
							   $target,
384
							   $encryptionEnabled,
385
							   $renameKeysReturn) {
386
		if ($encryptionEnabled) {
387
			$this->keyStore
388
				->expects($this->once())
389
				->method('renameKeys')
390
				->willReturn($renameKeysReturn);
391
		} else {
392
			$this->keyStore
393
				->expects($this->never())->method('renameKeys');
394
		}
395
		$this->util->expects($this->any())
396
			->method('isFile')->willReturn(true);
397
		$this->encryptionManager->expects($this->once())
398
			->method('isEnabled')->willReturn($encryptionEnabled);
399
400
		$this->instance->mkdir($source);
401
		$this->instance->mkdir(dirname($target));
402
		$this->instance->rename($source, $target);
403
	}
404
405
	public function testCopyEncryption() {
406
		$this->instance->file_put_contents('source.txt', 'bar');
407
		$this->instance->copy('source.txt', 'target.txt');
408
		$this->assertSame('bar', $this->instance->file_get_contents('target.txt'));
409
		$targetMeta = $this->instance->getMetaData('target.txt');
410
		$sourceMeta = $this->instance->getMetaData('source.txt');
411
		$this->assertSame($sourceMeta['encrypted'], $targetMeta['encrypted']);
412
		$this->assertSame($sourceMeta['size'], $targetMeta['size']);
413
	}
414
415
	/**
416
	 * data provider for testCopyTesting() and dataTestCopyAndRename()
417
	 *
418
	 * @return array
419
	 */
420
	public function dataTestCopyAndRename() {
421
		return array(
422
			array('source', 'target', true, false, false),
423
			array('source', 'target', true, true, false),
424
			array('source', '/subFolder/target', true, false, false),
425
			array('source', '/subFolder/target', true, true, true),
426
			array('source', '/subFolder/target', false, true, false),
427
		);
428
	}
429
430
	public function testIsLocal() {
431
		$this->encryptionManager->expects($this->once())
432
			->method('isEnabled')->willReturn(true);
433
		$this->assertFalse($this->instance->isLocal());
434
	}
435
436
	/**
437
	 * @dataProvider dataTestRmdir
438
	 *
439
	 * @param string $path
440
	 * @param boolean $rmdirResult
441
	 * @param boolean $isExcluded
442
	 * @param boolean $encryptionEnabled
443
	 */
444
	public function testRmdir($path, $rmdirResult, $isExcluded, $encryptionEnabled) {
445
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
446
			->disableOriginalConstructor()->getMock();
447
448
		$util = $this->getMockBuilder('\OC\Encryption\Util')->disableOriginalConstructor()->getMock();
449
450
		$sourceStorage->expects($this->once())->method('rmdir')->willReturn($rmdirResult);
451
		$util->expects($this->any())->method('isExcluded')-> willReturn($isExcluded);
452
		$this->encryptionManager->expects($this->any())->method('isEnabled')->willReturn($encryptionEnabled);
453
454
		$encryptionStorage = new \OC\Files\Storage\Wrapper\Encryption(
455
					[
456
						'storage' => $sourceStorage,
457
						'root' => 'foo',
458
						'mountPoint' => '/mountPoint',
459
						'mount' => $this->mount
460
					],
461
					$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update
462
		);
463
464
465
		if ($rmdirResult === true && $isExcluded === false && $encryptionEnabled === true) {
466
			$this->keyStore->expects($this->once())->method('deleteAllFileKeys')->with('/mountPoint' . $path);
467
		} else {
468
			$this->keyStore->expects($this->never())->method('deleteAllFileKeys');
469
		}
470
471
		$encryptionStorage->rmdir($path);
472
	}
473
474
	public function dataTestRmdir() {
475
		return array(
476
			array('/file.txt', true, true, true),
477
			array('/file.txt', false, true, true),
478
			array('/file.txt', true, false, true),
479
			array('/file.txt', false, false, true),
480
			array('/file.txt', true, true, false),
481
			array('/file.txt', false, true, false),
482
			array('/file.txt', true, false, false),
483
			array('/file.txt', false, false, false),
484
		);
485
	}
486
487
	/**
488
	 * @dataProvider dataTestCopyKeys
489
	 *
490
	 * @param boolean $excluded
491
	 * @param boolean $expected
492
	 */
493
	public function testCopyKeys($excluded, $expected) {
494
		$this->util->expects($this->once())
495
			->method('isExcluded')
496
			->willReturn($excluded);
497
498
		if ($excluded) {
499
			$this->keyStore->expects($this->never())->method('copyKeys');
500
		} else {
501
			$this->keyStore->expects($this->once())->method('copyKeys')->willReturn(true);
502
		}
503
504
		$this->assertSame($expected,
505
			self::invokePrivate($this->instance, 'copyKeys', ['/source', '/target'])
506
		);
507
	}
508
509
	public function dataTestCopyKeys() {
510
		return array(
511
			array(true, false),
512
			array(false, true),
513
		);
514
	}
515
516
	/**
517
	 * @dataProvider dataTestGetHeader
518
	 *
519
	 * @param string $path
520
	 * @param bool $strippedPathExists
521
	 * @param string $strippedPath
522
	 */
523
	public function testGetHeader($path, $strippedPathExists, $strippedPath) {
524
525
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
526
			->disableOriginalConstructor()->getMock();
527
528
		$util = $this->getMockBuilder('\OC\Encryption\Util')
529
			->setConstructorArgs(
530
				[
531
					new View(),
532
					new \OC\User\Manager(),
533
					$this->groupManager,
534
					$this->config,
535
					$this->arrayCache
536
				]
537
			)->getMock();
538
539
		$instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
540
			->setConstructorArgs(
541
				[
542
					[
543
						'storage' => $sourceStorage,
544
						'root' => 'foo',
545
						'mountPoint' => '/',
546
						'mount' => $this->mount
547
					],
548
					$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
549
				]
550
			)
551
			->setMethods(['readFirstBlock', 'parseRawHeader'])
552
			->getMock();
553
554
		$instance->expects($this->once())->method(('parseRawHeader'))
555
			->willReturn([Util::HEADER_ENCRYPTION_MODULE_KEY => 'OC_DEFAULT_MODULE']);
556
557
		if ($strippedPathExists) {
558
			$instance->expects($this->once())->method('readFirstBlock')
559
				->with($strippedPath)->willReturn('');
560
		} else {
561
			$instance->expects($this->once())->method('readFirstBlock')
562
				->with($path)->willReturn('');
563
		}
564
565
		$util->expects($this->once())->method('stripPartialFileExtension')
566
			->with($path)->willReturn($strippedPath);
567
		$sourceStorage->expects($this->once())
568
			->method('file_exists')
569
			->with($strippedPath)
570
			->willReturn($strippedPathExists);
571
572
		$this->invokePrivate($instance, 'getHeader', [$path]);
573
	}
574
575
	public function dataTestGetHeader() {
576
		return array(
577
			array('/foo/bar.txt', false, '/foo/bar.txt'),
578
			array('/foo/bar.txt.part', false, '/foo/bar.txt'),
579
			array('/foo/bar.txt.ocTransferId7437493.part', false, '/foo/bar.txt'),
580
			array('/foo/bar.txt.part', true, '/foo/bar.txt'),
581
			array('/foo/bar.txt.ocTransferId7437493.part', true, '/foo/bar.txt'),
582
		);
583
	}
584
585
	/**
586
	 * test if getHeader adds the default module correctly to the header for
587
	 * legacy files
588
	 *
589
	 * @dataProvider dataTestGetHeaderAddLegacyModule
590
	 */
591
	public function testGetHeaderAddLegacyModule($header, $isEncrypted, $expected) {
592
593
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
594
			->disableOriginalConstructor()->getMock();
595
596
		$util = $this->getMockBuilder('\OC\Encryption\Util')
597
			->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config, $this->arrayCache])
598
			->getMock();
599
600
		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
601
			->disableOriginalConstructor()->getMock();
602
		$cache->expects($this->any())
603
			->method('get')
604
			->willReturnCallback(function($path) use ($isEncrypted) {return ['encrypted' => $isEncrypted, 'path' => $path];});
605
606
		$instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
607
			->setConstructorArgs(
608
				[
609
					[
610
						'storage' => $sourceStorage,
611
						'root' => 'foo',
612
						'mountPoint' => '/',
613
						'mount' => $this->mount
614
					],
615
					$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
616
				]
617
			)
618
			->setMethods(['readFirstBlock', 'parseRawHeader', 'getCache'])
619
			->getMock();
620
621
		$instance->expects($this->once())->method(('parseRawHeader'))->willReturn($header);
622
		$instance->expects($this->any())->method('getCache')->willReturn($cache);
623
624
		$result = $this->invokePrivate($instance, 'getHeader', ['test.txt']);
625
		$this->assertSameSize($expected, $result);
626
		foreach ($result as $key => $value) {
627
			$this->assertArrayHasKey($key, $expected);
628
			$this->assertSame($expected[$key], $value);
629
		}
630
	}
631
632
	public function dataTestGetHeaderAddLegacyModule() {
633
		return [
634
			[['cipher' => 'AES-128'], true, ['cipher' => 'AES-128', Util::HEADER_ENCRYPTION_MODULE_KEY => 'OC_DEFAULT_MODULE']],
635
			[[], true, [Util::HEADER_ENCRYPTION_MODULE_KEY => 'OC_DEFAULT_MODULE']],
636
			[[], false, []],
637
		];
638
	}
639
640
	/**
641
	 * @dataProvider dataTestParseRawHeader
642
	 */
643
	public function testParseRawHeader($rawHeader, $expected) {
644
		$instance = new \OC\Files\Storage\Wrapper\Encryption(
645
					[
646
						'storage' => $this->sourceStorage,
647
						'root' => 'foo',
648
						'mountPoint' => '/',
649
						'mount' => $this->mount
650
					],
651
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager, $this->arrayCache
652
653
			);
654
655
		$result = $this->invokePrivate($instance, 'parseRawHeader', [$rawHeader]);
656
		$this->assertSameSize($expected, $result);
657
		foreach ($result as $key => $value) {
658
			$this->assertArrayHasKey($key, $expected);
659
			$this->assertSame($expected[$key], $value);
660
		}
661
	}
662
663
	public function dataTestParseRawHeader() {
664
		return [
665
			[str_pad('HBEGIN:oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
666
				, [Util::HEADER_ENCRYPTION_MODULE_KEY => '0']],
667
			[str_pad('HBEGIN:oc_encryption_module:0:custom_header:foo:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
668
				, ['custom_header' => 'foo', Util::HEADER_ENCRYPTION_MODULE_KEY => '0']],
669
			[str_pad('HelloWorld', $this->headerSize, '-', STR_PAD_RIGHT), []],
670
			['', []],
671
			[str_pad('HBEGIN:oc_encryption_module:0', $this->headerSize, '-', STR_PAD_RIGHT)
672
				, []],
673
			[str_pad('oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
674
				, []],
675
		];
676
	}
677
678 View Code Duplication
	public function dataCopyBetweenStorage() {
679
		return [
680
			[true, true, true],
681
			[true, false, false],
682
			[false, true, false],
683
			[false, false, false],
684
		];
685
	}
686
687
	/**
688
	 * @dataProvider dataCopyBetweenStorage
689
	 *
690
	 * @param bool $encryptionEnabled
691
	 * @param bool $mountPointEncryptionEnabled
692
	 * @param bool $expectedEncrypted
693
	 */
694
	public function testCopyBetweenStorage($encryptionEnabled, $mountPointEncryptionEnabled, $expectedEncrypted) {
695
		$storage2 = $this->getMockBuilder('OCP\Files\Storage')
696
			->disableOriginalConstructor()
697
			->getMock();
698
699
		$sourceInternalPath = $targetInternalPath = 'file.txt';
700
		$preserveMtime = $isRename = false;
701
702
		$storage2->expects($this->any())
703
			->method('fopen')
704
			->willReturnCallback(function($path, $mode) {
705
				$temp = \OC::$server->getTempManager();
706
				return fopen($temp->getTemporaryFile(), $mode);
707
			});
708
709
		$this->encryptionManager->expects($this->any())
710
			->method('isEnabled')
711
			->willReturn($encryptionEnabled);
712
713
		// FIXME can not overwrite the return after definition
714
//		$this->mount->expects($this->at(0))
715
//			->method('getOption')
716
//			->with('encrypt', true)
717
//			->willReturn($mountPointEncryptionEnabled);
718
		global $mockedMountPointEncryptionEnabled;
719
		$mockedMountPointEncryptionEnabled = $mountPointEncryptionEnabled;
720
721
		$expectedCachePut = [
722
			'encrypted' => $expectedEncrypted,
723
		];
724
		if($expectedEncrypted === true) {
725
			$expectedCachePut['encryptedVersion'] = 12345;
726
		}
727
728
		$this->arrayCache->expects($this->never())->method('set');
729
730
		$this->cache->expects($this->once())
731
			->method('put')
732
			->with($sourceInternalPath, ['encrypted' => $expectedEncrypted]);
733
734
		$this->invokePrivate($this->instance, 'copyBetweenStorage', [$storage2, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename]);
735
736
		$this->assertFalse(false);
737
	}
738
739
	/**
740
	 * @dataProvider dataTestCopyBetweenStorageVersions
741
	 *
742
	 * @param string $sourceInternalPath
743
	 * @param string $targetInternalPath
744
	 * @param bool $copyResult
745
	 * @param bool $encrypted
746
	 */
747
	public function  testCopyBetweenStorageVersions($sourceInternalPath, $targetInternalPath, $copyResult, $encrypted) {
748
749
		$sourceStorage = $this->getMockBuilder('OCP\Files\Storage')
750
			->disableOriginalConstructor()
751
			->getMock();
752
753
		$targetStorage = $this->getMockBuilder('OCP\Files\Storage')
754
			->disableOriginalConstructor()
755
			->getMock();
756
757
		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
758
			->disableOriginalConstructor()->getMock();
759
760
		$mountPoint = '/mountPoint';
761
762
		/** @var \OC\Files\Storage\Wrapper\Encryption |\PHPUnit_Framework_MockObject_MockObject  $instance */
763
		$instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
764
			->setConstructorArgs(
765
				[
766
					[
767
						'storage' => $targetStorage,
768
						'root' => 'foo',
769
						'mountPoint' => $mountPoint,
770
						'mount' => $this->mount
771
					],
772
					$this->encryptionManager,
773
					$this->util,
774
					$this->logger,
775
					$this->file,
776
					null,
777
					$this->keyStore,
778
					$this->update,
779
					$this->mountManager,
780
					$this->arrayCache
781
				]
782
			)
783
			->setMethods(['updateUnencryptedSize', 'getCache'])
784
			->getMock();
785
786
		$targetStorage->expects($this->once())->method('copyFromStorage')
787
			->with($sourceStorage, $sourceInternalPath, $targetInternalPath)
788
			->willReturn($copyResult);
789
790
		$instance->expects($this->any())->method('getCache')
791
			->willReturn($cache);
792
793
		$this->arrayCache->expects($this->once())->method('set')
794
			->with('encryption_copy_version_' . $sourceInternalPath, true);
795
796
		if ($copyResult) {
797
			$instance->expects($this->once())->method('getCache')
798
				->with('', $sourceStorage)
799
				->willReturn($cache);
800
			$cache->expects($this->once())->method('get')
801
				->with($sourceInternalPath)
802
				->willReturn(['encrypted' => $encrypted, 'size' => 42]);
803
			if ($encrypted) {
804
				$instance->expects($this->once())->method('updateUnencryptedSize')
805
					->with($mountPoint . $targetInternalPath, 42);
806
			} else {
807
				$instance->expects($this->never())->method('updateUnencryptedSize');
808
			}
809
		} else {
810
			$instance->expects($this->never())->method('updateUnencryptedSize');
811
		}
812
813
		$result = $this->invokePrivate(
814
			$instance,
815
			'copyBetweenStorage',
816
			[
817
				$sourceStorage,
818
				$sourceInternalPath,
819
				$targetInternalPath,
820
				false,
821
				false
822
			]
823
		);
824
825
		$this->assertSame($copyResult, $result);
826
	}
827
828
	public function dataTestCopyBetweenStorageVersions() {
829
		return [
830
			['/files/foo.txt', '/files_versions/foo.txt.768743', true, true],
831
			['/files/foo.txt', '/files_versions/foo.txt.768743', true, false],
832
			['/files/foo.txt', '/files_versions/foo.txt.768743', false, true],
833
			['/files/foo.txt', '/files_versions/foo.txt.768743', false, false],
834
			['/files_versions/foo.txt.6487634', '/files/foo.txt', true, true],
835
			['/files_versions/foo.txt.6487634', '/files/foo.txt', true, false],
836
			['/files_versions/foo.txt.6487634', '/files/foo.txt', false, true],
837
			['/files_versions/foo.txt.6487634', '/files/foo.txt', false, false],
838
839
		];
840
	}
841
842
	/**
843
	 * @dataProvider dataTestIsVersion
844
	 * @param string $path
845
	 * @param bool $expected
846
	 */
847
	public function testIsVersion($path, $expected) {
848
		$this->assertSame($expected,
849
			$this->invokePrivate($this->instance, 'isVersion', [$path])
850
		);
851
	}
852
853 View Code Duplication
	public function dataTestIsVersion() {
854
		return [
855
			['files_versions/foo', true],
856
			['/files_versions/foo', true],
857
			['//files_versions/foo', true],
858
			['files/versions/foo', false],
859
			['files/files_versions/foo', false],
860
			['files_versions_test/foo', false],
861
		];
862
	}
863
864
}
865