Completed
Push — stable8.1 ( e0a38c...1aa653 )
by
unknown
80:54
created

Encryption::testFilesize()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 32
rs 8.8571
cc 1
eloc 20
nc 1
nop 0
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
91
	/** @var  integer dummy unencrypted size */
92
	private $dummySize = -1;
93
94
	protected function setUp() {
95
96
		parent::setUp();
97
98
		$mockModule = $this->buildMockModule();
99
		$this->encryptionManager = $this->getMockBuilder('\OC\Encryption\Manager')
100
			->disableOriginalConstructor()
101
			->setMethods(['getEncryptionModule', 'isEnabled'])
102
			->getMock();
103
		$this->encryptionManager->expects($this->any())
104
			->method('getEncryptionModule')
105
			->willReturn($mockModule);
106
107
		$this->config = $this->getMockBuilder('\OCP\IConfig')
108
			->disableOriginalConstructor()
109
			->getMock();
110
		$this->groupManager = $this->getMockBuilder('\OC\Group\Manager')
111
			->disableOriginalConstructor()
112
			->getMock();
113
114
		$this->util = $this->getMock('\OC\Encryption\Util',
115
			['getUidAndFilename', 'isFile', 'isExcluded'],
116
			[new View(), new \OC\User\Manager(), $this->groupManager, $this->config]);
117
		$this->util->expects($this->any())
118
			->method('getUidAndFilename')
119
			->willReturnCallback(function ($path) {
120
				return ['user1', $path];
121
			});
122
123
		$this->file = $this->getMockBuilder('\OC\Encryption\File')
124
			->disableOriginalConstructor()
125
			->setMethods(['getAccessList'])
126
			->getMock();
127
		$this->file->expects($this->any())->method('getAccessList')->willReturn([]);
128
129
		$this->logger = $this->getMock('\OC\Log');
130
131
		$this->sourceStorage = new Temporary(array());
132
133
		$this->keyStore = $this->getMockBuilder('\OC\Encryption\Keys\Storage')
134
			->disableOriginalConstructor()->getMock();
135
136
		$this->update = $this->getMockBuilder('\OC\Encryption\Update')
137
			->disableOriginalConstructor()->getMock();
138
139
		$this->mount = $this->getMockBuilder('\OC\Files\Mount\MountPoint')
140
			->disableOriginalConstructor()
141
			->setMethods(['getOption'])
142
			->getMock();
143
		$this->mount->expects($this->any())->method('getOption')->willReturnCallback(function ($option, $default) {
144
			if ($option === 'encrypt' && $default === true) {
145
				global $mockedMountPointEncryptionEnabled;
146
				if ($mockedMountPointEncryptionEnabled !== null) {
147
					return $mockedMountPointEncryptionEnabled;
148
				}
149
			}
150
			return true;
151
		});
152
153
		$this->cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
154
			->disableOriginalConstructor()->getMock();
155
		$this->cache->expects($this->any())
156
			->method('get')
157
			->willReturnCallback(function($path) {return ['encrypted' => false, 'path' => $path];});
158
159
		$this->mountManager = $this->getMockBuilder('\OC\Files\Mount\Manager')
160
			->disableOriginalConstructor()->getMock();
161
162
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
163
			->setConstructorArgs(
164
				[
165
					[
166
						'storage' => $this->sourceStorage,
167
						'root' => 'foo',
168
						'mountPoint' => '/',
169
						'mount' => $this->mount
170
					],
171
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager
172
				]
173
			)
174
			->setMethods(['getMetaData', 'getCache', 'getEncryptionModule'])
175
			->getMock();
176
177
		$this->instance->expects($this->any())
178
			->method('getMetaData')
179
			->willReturnCallback(function ($path) {
180
				return ['encrypted' => true, 'size' => $this->dummySize, 'path' => $path];
181
			});
182
183
		$this->instance->expects($this->any())
184
			->method('getCache')
185
			->willReturn($this->cache);
186
187
		$this->instance->expects($this->any())
188
			->method('getEncryptionModule')
189
			->willReturn($mockModule);
190
	}
191
192
	/**
193
	 * @return \PHPUnit_Framework_MockObject_MockObject
194
	 */
195
	protected function buildMockModule() {
196
		$this->encryptionModule = $this->getMockBuilder('\OCP\Encryption\IEncryptionModule')
197
			->disableOriginalConstructor()
198
			->setMethods(['getId', 'getDisplayName', 'begin', 'end', 'encrypt', 'decrypt', 'update', 'shouldEncrypt', 'getUnencryptedBlockSize', 'isReadable'])
199
			->getMock();
200
201
		$this->encryptionModule->expects($this->any())->method('getId')->willReturn('UNIT_TEST_MODULE');
202
		$this->encryptionModule->expects($this->any())->method('getDisplayName')->willReturn('Unit test module');
203
		$this->encryptionModule->expects($this->any())->method('begin')->willReturn([]);
204
		$this->encryptionModule->expects($this->any())->method('end')->willReturn('');
205
		$this->encryptionModule->expects($this->any())->method('encrypt')->willReturnArgument(0);
206
		$this->encryptionModule->expects($this->any())->method('decrypt')->willReturnArgument(0);
207
		$this->encryptionModule->expects($this->any())->method('update')->willReturn(true);
208
		$this->encryptionModule->expects($this->any())->method('shouldEncrypt')->willReturn(true);
209
		$this->encryptionModule->expects($this->any())->method('getUnencryptedBlockSize')->willReturn(8192);
210
		$this->encryptionModule->expects($this->any())->method('isReadable')->willReturn(true);
211
		return $this->encryptionModule;
212
	}
213
214
	/**
215
	 * @dataProvider dataTestGetMetaData
216
	 *
217
	 * @param string $path
218
	 * @param array $metaData
219
	 * @param bool $encrypted
220
	 * @param bool $unencryptedSizeSet
221
	 * @param int $storedUnencryptedSize
222
	 * @param array $expected
223
	 */
224
	public function testGetMetaData($path, $metaData, $encrypted, $unencryptedSizeSet, $storedUnencryptedSize, $expected) {
225
226
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
227
			->disableOriginalConstructor()->getMock();
228
229
		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
230
			->disableOriginalConstructor()->getMock();
231
		$cache->expects($this->any())
232
			->method('get')
233
			->willReturnCallback(
234
				function($path) use ($encrypted) {
235
					return ['encrypted' => $encrypted, 'path' => $path, 'size' => 0, 'fileid' => 1];
236
				}
237
			);
238
239
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
240
			->setConstructorArgs(
241
				[
242
					[
243
						'storage' => $sourceStorage,
244
						'root' => 'foo',
245
						'mountPoint' => '/',
246
						'mount' => $this->mount
247
					],
248
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager
249
				]
250
			)
251
			->setMethods(['getCache', 'verifyUnencryptedSize'])
252
			->getMock();
253
254
		if($unencryptedSizeSet) {
255
			$this->invokePrivate($this->instance, 'unencryptedSize', [[$path => $storedUnencryptedSize]]);
256
		}
257
258
259
		$sourceStorage->expects($this->once())->method('getMetaData')->with($path)
260
			->willReturn($metaData);
261
262
		$this->instance->expects($this->any())->method('getCache')->willReturn($cache);
263
		$this->instance->expects($this->any())->method('verifyUnencryptedSize')
264
			->with($path, 0)->willReturn($expected['size']);
265
266
		$result = $this->instance->getMetaData($path);
267
		$this->assertSame($expected['encrypted'], $result['encrypted']);
268
		$this->assertSame($expected['size'], $result['size']);
269
	}
270
271
	public function dataTestGetMetaData() {
272
		return [
273
			['/test.txt', ['size' => 42, 'encrypted' => false], true, true, 12, ['size' => 12, 'encrypted' => true]],
274
			['/test.txt', null, true, true, 12, null],
275
			['/test.txt', ['size' => 42, 'encrypted' => false], false, false, 12, ['size' => 42, 'encrypted' => false]],
276
			['/test.txt', ['size' => 42, 'encrypted' => false], true, false, 12, ['size' => 12, 'encrypted' => true]]
277
		];
278
	}
279
280
	public function testFilesize() {
281
		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
282
			->disableOriginalConstructor()->getMock();
283
		$cache->expects($this->any())
284
			->method('get')
285
			->willReturn(['encrypted' => true, 'path' => '/test.txt', 'size' => 0, 'fileid' => 1]);
286
287
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
288
			->setConstructorArgs(
289
				[
290
					[
291
						'storage' => $this->sourceStorage,
292
						'root' => 'foo',
293
						'mountPoint' => '/',
294
						'mount' => $this->mount
295
					],
296
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager
297
				]
298
			)
299
			->setMethods(['getCache', 'verifyUnencryptedSize'])
300
			->getMock();
301
302
		$this->instance->expects($this->any())->method('getCache')->willReturn($cache);
303
		$this->instance->expects($this->any())->method('verifyUnencryptedSize')
304
			->willReturn(42);
305
306
307
		$this->assertSame(42,
308
			$this->instance->filesize('/test.txt')
309
		);
310
311
	}
312
313
	/**
314
	 * @dataProvider dataTestVerifyUnencryptedSize
315
	 *
316
	 * @param int $encryptedSize
317
	 * @param int $unencryptedSize
318
	 * @param bool $failure
319
	 * @param int $expected
320
	 */
321
	public function testVerifyUnencryptedSize($encryptedSize, $unencryptedSize, $failure, $expected) {
322
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
323
			->disableOriginalConstructor()->getMock();
324
325
		$this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
326
			->setConstructorArgs(
327
				[
328
					[
329
						'storage' => $sourceStorage,
330
						'root' => 'foo',
331
						'mountPoint' => '/',
332
						'mount' => $this->mount
333
					],
334
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager
335
				]
336
			)
337
			->setMethods(['fixUnencryptedSize'])
338
			->getMock();
339
340
		$sourceStorage->expects($this->once())->method('filesize')->willReturn($encryptedSize);
341
342
		$this->instance->expects($this->any())->method('fixUnencryptedSize')
343
			->with('/test.txt', $encryptedSize, $unencryptedSize)
344
			->willReturnCallback(
345
				function() use ($failure, $expected) {
346
					if ($failure) {
347
						throw new \Exception();
348
					} else {
349
						return $expected;
350
					}
351
				}
352
			);
353
354
		$this->assertSame(
355
			$expected,
356
			$this->invokePrivate($this->instance, 'verifyUnencryptedSize', ['/test.txt', $unencryptedSize])
357
		);
358
	}
359
360
	public function dataTestVerifyUnencryptedSize() {
361
		return [
362
			[120, 80, false, 80],
363
			[120, 120, false, 80],
364
			[120, -1, false, 80],
365
			[120, -1, true, -1]
366
		];
367
	}
368
369
	/**
370
	 * @dataProvider dataTestCopyAndRename
371
	 *
372
	 * @param string $source
373
	 * @param string $target
374
	 * @param $encryptionEnabled
375
	 * @param boolean $renameKeysReturn
376
	 */
377
	public function testRename($source,
378
							   $target,
379
							   $encryptionEnabled,
380
							   $renameKeysReturn) {
381
		if ($encryptionEnabled) {
382
			$this->keyStore
383
				->expects($this->once())
384
				->method('renameKeys')
385
				->willReturn($renameKeysReturn);
386
		} else {
387
			$this->keyStore
388
				->expects($this->never())->method('renameKeys');
389
		}
390
		$this->util->expects($this->any())
391
			->method('isFile')->willReturn(true);
392
		$this->encryptionManager->expects($this->once())
393
			->method('isEnabled')->willReturn($encryptionEnabled);
394
395
		$this->instance->mkdir($source);
396
		$this->instance->mkdir(dirname($target));
397
		$this->instance->rename($source, $target);
398
	}
399
400
	/**
401
	 * @dataProvider dataTestCopyAndRename
402
	 *
403
	 * @param string $source
404
	 * @param string $target
405
	 * @param $encryptionEnabled
406
	 * @param boolean $copyKeysReturn
407
	 * @param boolean $shouldUpdate
408
	 */
409
	public function testCopyEncryption($source,
410
							 $target,
411
							 $encryptionEnabled,
412
							 $copyKeysReturn,
413
							 $shouldUpdate) {
414
415
		if ($encryptionEnabled) {
416
			$this->keyStore
417
				->expects($this->once())
418
				->method('copyKeys')
419
				->willReturn($copyKeysReturn);
420
			$this->cache->expects($this->atLeastOnce())
421
				->method('put')
422
				->willReturnCallback(function($path, $data) {
423
					$this->assertArrayHasKey('encrypted', $data);
424
					$this->assertTrue($data['encrypted']);
425
				});
426
		} else {
427
			$this->cache->expects($this->never())->method('put');
428
			$this->keyStore->expects($this->never())->method('copyKeys');
429
		}
430
		$this->util->expects($this->any())
431
			->method('isFile')->willReturn(true);
432
		$this->util->expects($this->any())
433
			->method('isExcluded')->willReturn(false);
434
		$this->encryptionManager->expects($this->once())
435
			->method('isEnabled')->willReturn($encryptionEnabled);
436
		if ($shouldUpdate) {
437
			$this->update->expects($this->once())
438
				->method('update');
439
		} else {
440
			$this->update->expects($this->never())
441
				->method('update');
442
		}
443
444
		$this->instance->mkdir($source);
445
		$this->instance->mkdir(dirname($target));
446
		$this->instance->copy($source, $target);
447
448
		if ($encryptionEnabled) {
449
			$this->assertSame($this->dummySize,
450
				$this->instance->filesize($target)
451
			);
452
		}
453
	}
454
455
	/**
456
	 * data provider for testCopyTesting() and dataTestCopyAndRename()
457
	 *
458
	 * @return array
459
	 */
460
	public function dataTestCopyAndRename() {
461
		return array(
462
			array('source', 'target', true, false, false),
463
			array('source', 'target', true, true, false),
464
			array('source', '/subFolder/target', true, false, false),
465
			array('source', '/subFolder/target', true, true, true),
466
			array('source', '/subFolder/target', false, true, false),
467
		);
468
	}
469
470
	public function testIsLocal() {
471
		$this->encryptionManager->expects($this->once())
472
			->method('isEnabled')->willReturn(true);
473
		$this->assertFalse($this->instance->isLocal());
474
	}
475
476
	/**
477
	 * @dataProvider dataTestRmdir
478
	 *
479
	 * @param string $path
480
	 * @param boolean $rmdirResult
481
	 * @param boolean $isExcluded
482
	 * @param boolean $encryptionEnabled
483
	 */
484
	public function testRmdir($path, $rmdirResult, $isExcluded, $encryptionEnabled) {
485
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
486
			->disableOriginalConstructor()->getMock();
487
488
		$util = $this->getMockBuilder('\OC\Encryption\Util')->disableOriginalConstructor()->getMock();
489
490
		$sourceStorage->expects($this->once())->method('rmdir')->willReturn($rmdirResult);
491
		$util->expects($this->any())->method('isExcluded')-> willReturn($isExcluded);
492
		$this->encryptionManager->expects($this->any())->method('isEnabled')->willReturn($encryptionEnabled);
493
494
		$encryptionStorage = new \OC\Files\Storage\Wrapper\Encryption(
495
					[
496
						'storage' => $sourceStorage,
497
						'root' => 'foo',
498
						'mountPoint' => '/mountPoint',
499
						'mount' => $this->mount
500
					],
501
					$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update
502
		);
503
504
505
		if ($rmdirResult === true && $isExcluded === false && $encryptionEnabled === true) {
506
			$this->keyStore->expects($this->once())->method('deleteAllFileKeys')->with('/mountPoint' . $path);
507
		} else {
508
			$this->keyStore->expects($this->never())->method('deleteAllFileKeys');
509
		}
510
511
		$encryptionStorage->rmdir($path);
512
	}
513
514
	public function dataTestRmdir() {
515
		return array(
516
			array('/file.txt', true, true, true),
517
			array('/file.txt', false, true, true),
518
			array('/file.txt', true, false, true),
519
			array('/file.txt', false, false, true),
520
			array('/file.txt', true, true, false),
521
			array('/file.txt', false, true, false),
522
			array('/file.txt', true, false, false),
523
			array('/file.txt', false, false, false),
524
		);
525
	}
526
527
	/**
528
	 * @dataProvider dataTestCopyKeys
529
	 *
530
	 * @param boolean $excluded
531
	 * @param boolean $expected
532
	 */
533
	public function testCopyKeys($excluded, $expected) {
534
		$this->util->expects($this->once())
535
			->method('isExcluded')
536
			->willReturn($excluded);
537
538
		if ($excluded) {
539
			$this->keyStore->expects($this->never())->method('copyKeys');
540
		} else {
541
			$this->keyStore->expects($this->once())->method('copyKeys')->willReturn(true);
542
		}
543
544
		$this->assertSame($expected,
545
			self::invokePrivate($this->instance, 'copyKeys', ['/source', '/target'])
546
		);
547
	}
548
549
	public function dataTestCopyKeys() {
550
		return array(
551
			array(true, false),
552
			array(false, true),
553
		);
554
	}
555
556
	/**
557
	 * @dataProvider dataTestGetHeader
558
	 *
559
	 * @param string $path
560
	 * @param bool $strippedPathExists
561
	 * @param string $strippedPath
562
	 */
563
	public function testGetHeader($path, $strippedPathExists, $strippedPath) {
564
565
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
566
			->disableOriginalConstructor()->getMock();
567
568
		$util = $this->getMockBuilder('\OC\Encryption\Util')
569
			->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config])
570
			->getMock();
571
572
		$instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
573
			->setConstructorArgs(
574
				[
575
					[
576
						'storage' => $sourceStorage,
577
						'root' => 'foo',
578
						'mountPoint' => '/',
579
						'mount' => $this->mount
580
					],
581
					$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager
582
				]
583
			)
584
			->setMethods(['readFirstBlock', 'parseRawHeader'])
585
			->getMock();
586
587
		$instance->expects($this->once())->method(('parseRawHeader'))
588
			->willReturn([Util::HEADER_ENCRYPTION_MODULE_KEY => 'OC_DEFAULT_MODULE']);
589
590
		if ($strippedPathExists) {
591
			$instance->expects($this->once())->method('readFirstBlock')
592
				->with($strippedPath)->willReturn('');
593
		} else {
594
			$instance->expects($this->once())->method('readFirstBlock')
595
				->with($path)->willReturn('');
596
		}
597
598
		$util->expects($this->once())->method('stripPartialFileExtension')
599
			->with($path)->willReturn($strippedPath);
600
		$sourceStorage->expects($this->once())
601
			->method('file_exists')
602
			->with($strippedPath)
603
			->willReturn($strippedPathExists);
604
605
		$this->invokePrivate($instance, 'getHeader', [$path]);
606
	}
607
608
	public function dataTestGetHeader() {
609
		return array(
610
			array('/foo/bar.txt', false, '/foo/bar.txt'),
611
			array('/foo/bar.txt.part', false, '/foo/bar.txt'),
612
			array('/foo/bar.txt.ocTransferId7437493.part', false, '/foo/bar.txt'),
613
			array('/foo/bar.txt.part', true, '/foo/bar.txt'),
614
			array('/foo/bar.txt.ocTransferId7437493.part', true, '/foo/bar.txt'),
615
		);
616
	}
617
618
	/**
619
	 * test if getHeader adds the default module correctly to the header for
620
	 * legacy files
621
	 *
622
	 * @dataProvider dataTestGetHeaderAddLegacyModule
623
	 */
624
	public function testGetHeaderAddLegacyModule($header, $isEncrypted, $expected) {
625
626
		$sourceStorage = $this->getMockBuilder('\OC\Files\Storage\Storage')
627
			->disableOriginalConstructor()->getMock();
628
629
		$util = $this->getMockBuilder('\OC\Encryption\Util')
630
			->setConstructorArgs([new View(), new \OC\User\Manager(), $this->groupManager, $this->config])
631
			->getMock();
632
633
		$cache = $this->getMockBuilder('\OC\Files\Cache\Cache')
634
			->disableOriginalConstructor()->getMock();
635
		$cache->expects($this->any())
636
			->method('get')
637
			->willReturnCallback(function($path) use ($isEncrypted) {return ['encrypted' => $isEncrypted, 'path' => $path];});
638
639
		$instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption')
640
			->setConstructorArgs(
641
				[
642
					[
643
						'storage' => $sourceStorage,
644
						'root' => 'foo',
645
						'mountPoint' => '/',
646
						'mount' => $this->mount
647
					],
648
					$this->encryptionManager, $util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager
649
				]
650
			)
651
			->setMethods(['readFirstBlock', 'parseRawHeader', 'getCache'])
652
			->getMock();
653
654
		$instance->expects($this->once())->method(('parseRawHeader'))->willReturn($header);
655
		$instance->expects($this->any())->method('getCache')->willReturn($cache);
656
657
		$result = $this->invokePrivate($instance, 'getHeader', ['test.txt']);
658
		$this->assertSameSize($expected, $result);
659
		foreach ($result as $key => $value) {
660
			$this->assertArrayHasKey($key, $expected);
661
			$this->assertSame($expected[$key], $value);
662
		}
663
	}
664
665
	public function dataTestGetHeaderAddLegacyModule() {
666
		return [
667
			[['cipher' => 'AES-128'], true, ['cipher' => 'AES-128', Util::HEADER_ENCRYPTION_MODULE_KEY => 'OC_DEFAULT_MODULE']],
668
			[[], true, [Util::HEADER_ENCRYPTION_MODULE_KEY => 'OC_DEFAULT_MODULE']],
669
			[[], false, []],
670
		];
671
	}
672
673
	/**
674
	 * @dataProvider dataTestParseRawHeader
675
	 */
676
	public function testParseRawHeader($rawHeader, $expected) {
677
		$instance = new \OC\Files\Storage\Wrapper\Encryption(
678
					[
679
						'storage' => $this->sourceStorage,
680
						'root' => 'foo',
681
						'mountPoint' => '/',
682
						'mount' => $this->mount
683
					],
684
					$this->encryptionManager, $this->util, $this->logger, $this->file, null, $this->keyStore, $this->update, $this->mountManager
685
686
			);
687
688
		$result = $this->invokePrivate($instance, 'parseRawHeader', [$rawHeader]);
689
		$this->assertSameSize($expected, $result);
690
		foreach ($result as $key => $value) {
691
			$this->assertArrayHasKey($key, $expected);
692
			$this->assertSame($expected[$key], $value);
693
		}
694
	}
695
696
	public function dataTestParseRawHeader() {
697
		return [
698
			[str_pad('HBEGIN:oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
699
				, [Util::HEADER_ENCRYPTION_MODULE_KEY => '0']],
700
			[str_pad('HBEGIN:oc_encryption_module:0:custom_header:foo:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
701
				, ['custom_header' => 'foo', Util::HEADER_ENCRYPTION_MODULE_KEY => '0']],
702
			[str_pad('HelloWorld', $this->headerSize, '-', STR_PAD_RIGHT), []],
703
			['', []],
704
			[str_pad('HBEGIN:oc_encryption_module:0', $this->headerSize, '-', STR_PAD_RIGHT)
705
				, []],
706
			[str_pad('oc_encryption_module:0:HEND', $this->headerSize, '-', STR_PAD_RIGHT)
707
				, []],
708
		];
709
	}
710
711
	public function dataCopyBetweenStorage() {
712
		return [
713
			[true, true, true],
714
			[true, false, false],
715
			[false, true, false],
716
			[false, false, false],
717
		];
718
	}
719
720
	/**
721
	 * @dataProvider dataCopyBetweenStorage
722
	 *
723
	 * @param bool $encryptionEnabled
724
	 * @param bool $mountPointEncryptionEnabled
725
	 * @param bool $expectedEncrypted
726
	 */
727
	public function testCopyBetweenStorage($encryptionEnabled, $mountPointEncryptionEnabled, $expectedEncrypted) {
728
		$storage2 = $this->getMockBuilder('OCP\Files\Storage')
729
			->disableOriginalConstructor()
730
			->getMock();
731
732
		$sourceInternalPath = $targetInternalPath = 'file.txt';
733
		$preserveMtime = $isRename = false;
734
735
		$storage2->expects($this->any())
736
			->method('fopen')
737
			->willReturnCallback(function($path, $mode) {
738
				$temp = \OC::$server->getTempManager();
739
				return fopen($temp->getTemporaryFile(), $mode);
740
			});
741
742
		$this->encryptionManager->expects($this->any())
743
			->method('isEnabled')
744
			->willReturn($encryptionEnabled);
745
746
		// FIXME can not overwrite the return after definition
747
//		$this->mount->expects($this->at(0))
748
//			->method('getOption')
749
//			->with('encrypt', true)
750
//			->willReturn($mountPointEncryptionEnabled);
751
		global $mockedMountPointEncryptionEnabled;
752
		$mockedMountPointEncryptionEnabled = $mountPointEncryptionEnabled;
753
754
		$this->cache->expects($this->once())
755
			->method('put')
756
			->with($sourceInternalPath, ['encrypted' => $expectedEncrypted]);
757
758
		$this->invokePrivate($this->instance, 'copyBetweenStorage', [$storage2, $sourceInternalPath, $targetInternalPath, $preserveMtime, $isRename]);
759
760
		$this->assertFalse(false);
761
	}
762
}
763