Completed
Push — master ( ca1fc2...aba39c )
by Joas
31:19 queued 16s
created
tests/lib/IntegrityCheck/CheckerTest.php 2 patches
Indentation   +955 added lines, -955 removed lines patch added patch discarded remove patch
@@ -23,107 +23,107 @@  discard block
 block discarded – undo
23 23
 use Test\TestCase;
24 24
 
25 25
 class CheckerTest extends TestCase {
26
-	/** @var ServerVersion|\PHPUnit\Framework\MockObject\MockObject */
27
-	private $serverVersion;
28
-	/** @var EnvironmentHelper|\PHPUnit\Framework\MockObject\MockObject */
29
-	private $environmentHelper;
30
-	/** @var AppLocator|\PHPUnit\Framework\MockObject\MockObject */
31
-	private $appLocator;
32
-	/** @var Checker */
33
-	private $checker;
34
-	/** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
35
-	private $fileAccessHelper;
36
-	/** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
37
-	private $config;
38
-	/** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
39
-	private $appConfig;
40
-	/** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */
41
-	private $cacheFactory;
42
-	/** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */
43
-	private $appManager;
44
-	/** @var \OC\Files\Type\Detection|\PHPUnit\Framework\MockObject\MockObject */
45
-	private $mimeTypeDetector;
46
-
47
-	protected function setUp(): void {
48
-		parent::setUp();
49
-		$this->serverVersion = $this->createMock(ServerVersion::class);
50
-		$this->environmentHelper = $this->createMock(EnvironmentHelper::class);
51
-		$this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
52
-		$this->appLocator = $this->createMock(AppLocator::class);
53
-		$this->config = $this->createMock(IConfig::class);
54
-		$this->appConfig = $this->createMock(IAppConfig::class);
55
-		$this->cacheFactory = $this->createMock(ICacheFactory::class);
56
-		$this->appManager = $this->createMock(IAppManager::class);
57
-		$this->mimeTypeDetector = $this->createMock(\OC\Files\Type\Detection::class);
58
-
59
-		$this->config->method('getAppValue')
60
-			->willReturnArgument(2);
61
-
62
-		$this->cacheFactory
63
-			->expects($this->any())
64
-			->method('createDistributed')
65
-			->with('oc.integritycheck.checker')
66
-			->willReturn(new NullCache());
67
-
68
-		$this->checker = new Checker(
69
-			$this->serverVersion,
70
-			$this->environmentHelper,
71
-			$this->fileAccessHelper,
72
-			$this->appLocator,
73
-			$this->config,
74
-			$this->appConfig,
75
-			$this->cacheFactory,
76
-			$this->appManager,
77
-			$this->mimeTypeDetector
78
-		);
79
-	}
80
-
81
-
82
-	public function testWriteAppSignatureOfNotExistingApp(): void {
83
-		$this->expectException(\Exception::class);
84
-		$this->expectExceptionMessage('Exception message');
85
-
86
-		$this->fileAccessHelper
87
-			->expects($this->once())
88
-			->method('assertDirectoryExists')
89
-			->with('NotExistingApp/appinfo')
90
-			->willThrowException(new \Exception('Exception message'));
91
-		$this->fileAccessHelper
92
-			->expects($this->once())
93
-			->method('is_writable')
94
-			->with('NotExistingApp/appinfo')
95
-			->willReturn(true);
96
-
97
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
98
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
99
-		$rsa = new RSA();
100
-		$rsa->loadKey($rsaPrivateKey);
101
-		$x509 = new X509();
102
-		$x509->loadX509($keyBundle);
103
-		$this->checker->writeAppSignature('NotExistingApp', $x509, $rsa);
104
-	}
105
-
106
-
107
-	public function testWriteAppSignatureWrongPermissions(): void {
108
-		$this->expectException(\Exception::class);
109
-		$this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/');
110
-
111
-		$this->fileAccessHelper
112
-			->expects($this->once())
113
-			->method('file_put_contents')
114
-			->will($this->throwException(new \Exception('Exception message')));
115
-
116
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
117
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
118
-		$rsa = new RSA();
119
-		$rsa->loadKey($rsaPrivateKey);
120
-		$x509 = new X509();
121
-		$x509->loadX509($keyBundle);
122
-		$this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa);
123
-	}
124
-
125
-	public function testWriteAppSignature(): void {
126
-		$expectedSignatureFileData = '{
26
+    /** @var ServerVersion|\PHPUnit\Framework\MockObject\MockObject */
27
+    private $serverVersion;
28
+    /** @var EnvironmentHelper|\PHPUnit\Framework\MockObject\MockObject */
29
+    private $environmentHelper;
30
+    /** @var AppLocator|\PHPUnit\Framework\MockObject\MockObject */
31
+    private $appLocator;
32
+    /** @var Checker */
33
+    private $checker;
34
+    /** @var FileAccessHelper|\PHPUnit\Framework\MockObject\MockObject */
35
+    private $fileAccessHelper;
36
+    /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
37
+    private $config;
38
+    /** @var IAppConfig|\PHPUnit\Framework\MockObject\MockObject */
39
+    private $appConfig;
40
+    /** @var ICacheFactory|\PHPUnit\Framework\MockObject\MockObject */
41
+    private $cacheFactory;
42
+    /** @var IAppManager|\PHPUnit\Framework\MockObject\MockObject */
43
+    private $appManager;
44
+    /** @var \OC\Files\Type\Detection|\PHPUnit\Framework\MockObject\MockObject */
45
+    private $mimeTypeDetector;
46
+
47
+    protected function setUp(): void {
48
+        parent::setUp();
49
+        $this->serverVersion = $this->createMock(ServerVersion::class);
50
+        $this->environmentHelper = $this->createMock(EnvironmentHelper::class);
51
+        $this->fileAccessHelper = $this->createMock(FileAccessHelper::class);
52
+        $this->appLocator = $this->createMock(AppLocator::class);
53
+        $this->config = $this->createMock(IConfig::class);
54
+        $this->appConfig = $this->createMock(IAppConfig::class);
55
+        $this->cacheFactory = $this->createMock(ICacheFactory::class);
56
+        $this->appManager = $this->createMock(IAppManager::class);
57
+        $this->mimeTypeDetector = $this->createMock(\OC\Files\Type\Detection::class);
58
+
59
+        $this->config->method('getAppValue')
60
+            ->willReturnArgument(2);
61
+
62
+        $this->cacheFactory
63
+            ->expects($this->any())
64
+            ->method('createDistributed')
65
+            ->with('oc.integritycheck.checker')
66
+            ->willReturn(new NullCache());
67
+
68
+        $this->checker = new Checker(
69
+            $this->serverVersion,
70
+            $this->environmentHelper,
71
+            $this->fileAccessHelper,
72
+            $this->appLocator,
73
+            $this->config,
74
+            $this->appConfig,
75
+            $this->cacheFactory,
76
+            $this->appManager,
77
+            $this->mimeTypeDetector
78
+        );
79
+    }
80
+
81
+
82
+    public function testWriteAppSignatureOfNotExistingApp(): void {
83
+        $this->expectException(\Exception::class);
84
+        $this->expectExceptionMessage('Exception message');
85
+
86
+        $this->fileAccessHelper
87
+            ->expects($this->once())
88
+            ->method('assertDirectoryExists')
89
+            ->with('NotExistingApp/appinfo')
90
+            ->willThrowException(new \Exception('Exception message'));
91
+        $this->fileAccessHelper
92
+            ->expects($this->once())
93
+            ->method('is_writable')
94
+            ->with('NotExistingApp/appinfo')
95
+            ->willReturn(true);
96
+
97
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
98
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
99
+        $rsa = new RSA();
100
+        $rsa->loadKey($rsaPrivateKey);
101
+        $x509 = new X509();
102
+        $x509->loadX509($keyBundle);
103
+        $this->checker->writeAppSignature('NotExistingApp', $x509, $rsa);
104
+    }
105
+
106
+
107
+    public function testWriteAppSignatureWrongPermissions(): void {
108
+        $this->expectException(\Exception::class);
109
+        $this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/');
110
+
111
+        $this->fileAccessHelper
112
+            ->expects($this->once())
113
+            ->method('file_put_contents')
114
+            ->will($this->throwException(new \Exception('Exception message')));
115
+
116
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
117
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
118
+        $rsa = new RSA();
119
+        $rsa->loadKey($rsaPrivateKey);
120
+        $x509 = new X509();
121
+        $x509->loadX509($keyBundle);
122
+        $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa);
123
+    }
124
+
125
+    public function testWriteAppSignature(): void {
126
+        $expectedSignatureFileData = '{
127 127
     "hashes": {
128 128
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
129 129
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -131,65 +131,65 @@  discard block
 block discarded – undo
131 131
     "signature": "Y5yvXvcGHVPuRRatKVDUONWq1FpLXugZd6Km\/+aEHsQj7coVl9FeMj9OsWamBf7yRIw3dtNLguTLlAA9QAv\/b0uHN3JnbNZN+dwFOve4NMtqXfSDlWftqKN00VS+RJXpG1S2IIx9Poyp2NoghL\/5AuTv4GHiNb7zU\/DT\/kt71pUGPgPR6IIFaE+zHOD96vjYkrH+GfWZzKR0FCdLib9yyNvk+EGrcjKM6qjs2GKfS\/XFjj\/\/neDnh\/0kcPuKE3ZbofnI4TIDTv0CGqvOp7PtqVNc3Vy\/UKa7uF1PT0MAUKMww6EiMUSFZdUVP4WWF0Y72W53Qdtf1hrAZa2kfKyoK5kd7sQmCSKUPSU8978AUVZlBtTRlyT803IKwMV0iHMkw+xYB1sN2FlHup\/DESADqxhdgYuK35bCPvgkb4SBe4B8Voz\/izTvcP7VT5UvkYdAO+05\/jzdaHEmzmsD92CFfvX0q8O\/Y\/29ubftUJsqcHeMDKgcR4eZOE8+\/QVc\/89QO6WnKNuNuV+5bybO6g6PAdC9ZPsCvnihS61O2mwRXHLR3jv2UleFWm+lZEquPKtkhi6SLtDiijA4GV6dmS+dzujSLb7hGeD5o1plZcZ94uhWljl+QIp82+zU\/lYB1Zfr4Mb4e+V7r2gv7Fbv7y6YtjE2GIQwRhC5jq56bD0ZB+I=",
132 132
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----"
133 133
 }';
134
-		$this->fileAccessHelper
135
-			->expects($this->once())
136
-			->method('file_put_contents')
137
-			->with(
138
-				$this->equalTo(\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'),
139
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
140
-					$expectedArray = json_decode($expectedSignatureFileData, true);
141
-					$actualArray = json_decode($signature, true);
142
-					$this->assertEquals($expectedArray, $actualArray);
143
-					return true;
144
-				})
145
-			);
146
-
147
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
148
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
149
-		$rsa = new RSA();
150
-		$rsa->loadKey($rsaPrivateKey);
151
-		$x509 = new X509();
152
-		$x509->loadX509($keyBundle);
153
-		$this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa);
154
-	}
155
-
156
-	public function testVerifyAppSignatureWithoutSignatureData(): void {
157
-		$this->serverVersion
158
-			->expects($this->once())
159
-			->method('getChannel')
160
-			->willReturn('stable');
161
-		$this->config
162
-			->expects($this->any())
163
-			->method('getSystemValueBool')
164
-			->with('integrity.check.disabled', false)
165
-			->willReturn(false);
166
-
167
-		$expected = [
168
-			'EXCEPTION' => [
169
-				'class' => 'OC\IntegrityCheck\Exceptions\InvalidSignatureException',
170
-				'message' => 'Signature data not found.',
171
-			],
172
-		];
173
-		$this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
174
-	}
175
-
176
-	public function testVerifyAppSignatureWithValidSignatureData(): void {
177
-		$this->serverVersion
178
-			->expects($this->once())
179
-			->method('getChannel')
180
-			->willReturn('stable');
181
-		$this->config
182
-			->expects($this->any())
183
-			->method('getSystemValueBool')
184
-			->with('integrity.check.disabled', false)
185
-			->willReturn(false);
186
-
187
-		$this->appLocator
188
-			->expects($this->once())
189
-			->method('getAppPath')
190
-			->with('SomeApp')
191
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
192
-		$signatureDataFile = '{
134
+        $this->fileAccessHelper
135
+            ->expects($this->once())
136
+            ->method('file_put_contents')
137
+            ->with(
138
+                $this->equalTo(\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'),
139
+                $this->callback(function ($signature) use ($expectedSignatureFileData) {
140
+                    $expectedArray = json_decode($expectedSignatureFileData, true);
141
+                    $actualArray = json_decode($signature, true);
142
+                    $this->assertEquals($expectedArray, $actualArray);
143
+                    return true;
144
+                })
145
+            );
146
+
147
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
148
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
149
+        $rsa = new RSA();
150
+        $rsa->loadKey($rsaPrivateKey);
151
+        $x509 = new X509();
152
+        $x509->loadX509($keyBundle);
153
+        $this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa);
154
+    }
155
+
156
+    public function testVerifyAppSignatureWithoutSignatureData(): void {
157
+        $this->serverVersion
158
+            ->expects($this->once())
159
+            ->method('getChannel')
160
+            ->willReturn('stable');
161
+        $this->config
162
+            ->expects($this->any())
163
+            ->method('getSystemValueBool')
164
+            ->with('integrity.check.disabled', false)
165
+            ->willReturn(false);
166
+
167
+        $expected = [
168
+            'EXCEPTION' => [
169
+                'class' => 'OC\IntegrityCheck\Exceptions\InvalidSignatureException',
170
+                'message' => 'Signature data not found.',
171
+            ],
172
+        ];
173
+        $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
174
+    }
175
+
176
+    public function testVerifyAppSignatureWithValidSignatureData(): void {
177
+        $this->serverVersion
178
+            ->expects($this->once())
179
+            ->method('getChannel')
180
+            ->willReturn('stable');
181
+        $this->config
182
+            ->expects($this->any())
183
+            ->method('getSystemValueBool')
184
+            ->with('integrity.check.disabled', false)
185
+            ->willReturn(false);
186
+
187
+        $this->appLocator
188
+            ->expects($this->once())
189
+            ->method('getAppPath')
190
+            ->with('SomeApp')
191
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
192
+        $signatureDataFile = '{
193 193
     "hashes": {
194 194
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
195 195
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -197,34 +197,34 @@  discard block
 block discarded – undo
197 197
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
198 198
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
199 199
 }';
200
-		$this->fileAccessHelper
201
-			->expects($this->exactly(2))
202
-			->method('file_get_contents')
203
-			->willReturnMap([
204
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
205
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
206
-			]);
207
-
208
-		$this->assertSame([], $this->checker->verifyAppSignature('SomeApp'));
209
-	}
210
-
211
-	public function testVerifyAppSignatureWithTamperedSignatureData(): void {
212
-		$this->serverVersion
213
-			->expects($this->once())
214
-			->method('getChannel')
215
-			->willReturn('stable');
216
-		$this->config
217
-			->expects($this->any())
218
-			->method('getSystemValueBool')
219
-			->with('integrity.check.disabled', false)
220
-			->willReturn(false);
221
-
222
-		$this->appLocator
223
-			->expects($this->once())
224
-			->method('getAppPath')
225
-			->with('SomeApp')
226
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
227
-		$signatureDataFile = '{
200
+        $this->fileAccessHelper
201
+            ->expects($this->exactly(2))
202
+            ->method('file_get_contents')
203
+            ->willReturnMap([
204
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
205
+                ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
206
+            ]);
207
+
208
+        $this->assertSame([], $this->checker->verifyAppSignature('SomeApp'));
209
+    }
210
+
211
+    public function testVerifyAppSignatureWithTamperedSignatureData(): void {
212
+        $this->serverVersion
213
+            ->expects($this->once())
214
+            ->method('getChannel')
215
+            ->willReturn('stable');
216
+        $this->config
217
+            ->expects($this->any())
218
+            ->method('getSystemValueBool')
219
+            ->with('integrity.check.disabled', false)
220
+            ->willReturn(false);
221
+
222
+        $this->appLocator
223
+            ->expects($this->once())
224
+            ->method('getAppPath')
225
+            ->with('SomeApp')
226
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
227
+        $signatureDataFile = '{
228 228
     "hashes": {
229 229
         "AnotherFile.txt": "tampered",
230 230
         "subfolder\/file.txt": "tampered"
@@ -232,40 +232,40 @@  discard block
 block discarded – undo
232 232
     "signature": "EL49UaSeyMAqyMtqId+tgOhhwgOevPZsRLX4j2blnybAB6fN07z0936JqZV7+eMPiE30Idx+UCY6rCFN531Kqe9vAOCdgtHUSOjjKyKc+lvULESlMb6YQcrZrvDlEMMjzjH49ewG7Ai8sNN6HrRUd9U8ws+ewSkW2DOOBItj\/21RBnkrSt+2AtGXGigEvuTm57HrCYDj8\/lSkumC2GVkjLUHeLOKYo4PRNOr6yP5mED5v7zo66AWvXl2fKv54InZcdxsAk35lyK9DGZbk\/027ZRd0AOHT3LImRLvQ+8EAg3XLlRUy0hOFGgPC+jYonMzgYvsAXAXi2j8LnLJlsLwpFwu1k1B+kZVPMumKZvP9OvJb70EirecXmz62V+Jiyuaq7ne4y7Kp5gKZT\/T8SeZ0lFtCmPfYyzBB0y8s5ldmTTmdVYHs54t\/OCCW82HzQZxnFNPzDTRa8HglsaMKrqPtW59+R4UvRKSWhB8M\/Ah57qgzycvPV4KMz\/FbD4l\/\/9chRKSlCfc2k3b8ZSHNmi+EzCKgJjWIoKdgN1yax94puU8jfn8UW+G7H9Y1Jsf\/jox6QLyYEgtV1vOHY2xLT7fVs2vhyvkN2MNjJnmQ70gFG5Qz2lBz5wi6ZpB+tOfCcpbLxWAkoWoIrmC\/Ilqh7mfmRZ43g5upjkepHNd93ONuY8=",
233 233
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----"
234 234
 }';
235
-		$this->fileAccessHelper
236
-			->expects($this->exactly(2))
237
-			->method('file_get_contents')
238
-			->willReturnMap([
239
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
240
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
241
-			]);
242
-
243
-		$expected = [
244
-			'EXCEPTION' => [
245
-				'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
246
-				'message' => 'Signature could not get verified.',
247
-			],
248
-		];
249
-		$this->assertEquals($expected, $this->checker->verifyAppSignature('SomeApp'));
250
-	}
251
-
252
-	public function testVerifyAppSignatureWithTamperedFiles(): void {
253
-		$this->serverVersion
254
-			->expects($this->once())
255
-			->method('getChannel')
256
-			->willReturn('stable');
257
-		$this->config
258
-			->expects($this->any())
259
-			->method('getSystemValueBool')
260
-			->with('integrity.check.disabled', false)
261
-			->willReturn(false);
262
-
263
-		$this->appLocator
264
-			->expects($this->once())
265
-			->method('getAppPath')
266
-			->with('SomeApp')
267
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
268
-		$signatureDataFile = '{
235
+        $this->fileAccessHelper
236
+            ->expects($this->exactly(2))
237
+            ->method('file_get_contents')
238
+            ->willReturnMap([
239
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
240
+                ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
241
+            ]);
242
+
243
+        $expected = [
244
+            'EXCEPTION' => [
245
+                'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
246
+                'message' => 'Signature could not get verified.',
247
+            ],
248
+        ];
249
+        $this->assertEquals($expected, $this->checker->verifyAppSignature('SomeApp'));
250
+    }
251
+
252
+    public function testVerifyAppSignatureWithTamperedFiles(): void {
253
+        $this->serverVersion
254
+            ->expects($this->once())
255
+            ->method('getChannel')
256
+            ->willReturn('stable');
257
+        $this->config
258
+            ->expects($this->any())
259
+            ->method('getSystemValueBool')
260
+            ->with('integrity.check.disabled', false)
261
+            ->willReturn(false);
262
+
263
+        $this->appLocator
264
+            ->expects($this->once())
265
+            ->method('getAppPath')
266
+            ->with('SomeApp')
267
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
268
+        $signatureDataFile = '{
269 269
     "hashes": {
270 270
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
271 271
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -273,55 +273,55 @@  discard block
 block discarded – undo
273 273
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
274 274
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
275 275
 }';
276
-		$this->fileAccessHelper
277
-			->expects($this->exactly(2))
278
-			->method('file_get_contents')
279
-			->willReturnMap([
280
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
281
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
282
-			]);
283
-
284
-
285
-		$expected = [
286
-			'INVALID_HASH' => [
287
-				'AnotherFile.txt' => [
288
-					'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112',
289
-					'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c',
290
-				],
291
-			],
292
-			'FILE_MISSING' => [
293
-				'subfolder/file.txt' => [
294
-					'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b',
295
-					'current' => '',
296
-				],
297
-			],
298
-			'EXTRA_FILE' => [
299
-				'UnecessaryFile' => [
300
-					'expected' => '',
301
-					'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
302
-				],
303
-			],
304
-
305
-		];
306
-		$this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
307
-	}
308
-
309
-	public function testVerifyAppSignatureWithTamperedFilesAndAlternatePath(): void {
310
-		$this->serverVersion
311
-			->expects($this->once())
312
-			->method('getChannel')
313
-			->willReturn('stable');
314
-		$this->config
315
-			->expects($this->any())
316
-			->method('getSystemValueBool')
317
-			->with('integrity.check.disabled', false)
318
-			->willReturn(false);
319
-
320
-		$this->appLocator
321
-			->expects($this->never())
322
-			->method('getAppPath')
323
-			->with('SomeApp');
324
-		$signatureDataFile = '{
276
+        $this->fileAccessHelper
277
+            ->expects($this->exactly(2))
278
+            ->method('file_get_contents')
279
+            ->willReturnMap([
280
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
281
+                ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
282
+            ]);
283
+
284
+
285
+        $expected = [
286
+            'INVALID_HASH' => [
287
+                'AnotherFile.txt' => [
288
+                    'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112',
289
+                    'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c',
290
+                ],
291
+            ],
292
+            'FILE_MISSING' => [
293
+                'subfolder/file.txt' => [
294
+                    'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b',
295
+                    'current' => '',
296
+                ],
297
+            ],
298
+            'EXTRA_FILE' => [
299
+                'UnecessaryFile' => [
300
+                    'expected' => '',
301
+                    'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
302
+                ],
303
+            ],
304
+
305
+        ];
306
+        $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
307
+    }
308
+
309
+    public function testVerifyAppSignatureWithTamperedFilesAndAlternatePath(): void {
310
+        $this->serverVersion
311
+            ->expects($this->once())
312
+            ->method('getChannel')
313
+            ->willReturn('stable');
314
+        $this->config
315
+            ->expects($this->any())
316
+            ->method('getSystemValueBool')
317
+            ->with('integrity.check.disabled', false)
318
+            ->willReturn(false);
319
+
320
+        $this->appLocator
321
+            ->expects($this->never())
322
+            ->method('getAppPath')
323
+            ->with('SomeApp');
324
+        $signatureDataFile = '{
325 325
     "hashes": {
326 326
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
327 327
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -329,55 +329,55 @@  discard block
 block discarded – undo
329 329
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
330 330
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
331 331
 }';
332
-		$this->fileAccessHelper
333
-			->expects($this->exactly(2))
334
-			->method('file_get_contents')
335
-			->willReturnMap([
336
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
337
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
338
-			]);
339
-
340
-		$expected = [
341
-			'INVALID_HASH' => [
342
-				'AnotherFile.txt' => [
343
-					'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112',
344
-					'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c',
345
-				],
346
-			],
347
-			'FILE_MISSING' => [
348
-				'subfolder/file.txt' => [
349
-					'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b',
350
-					'current' => '',
351
-				],
352
-			],
353
-			'EXTRA_FILE' => [
354
-				'UnecessaryFile' => [
355
-					'expected' => '',
356
-					'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
357
-				],
358
-			],
359
-
360
-		];
361
-		$this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'));
362
-	}
363
-
364
-	public function testVerifyAppWithDifferentScope(): void {
365
-		$this->serverVersion
366
-			->expects($this->once())
367
-			->method('getChannel')
368
-			->willReturn('stable');
369
-		$this->config
370
-			->expects($this->any())
371
-			->method('getSystemValueBool')
372
-			->with('integrity.check.disabled', false)
373
-			->willReturn(false);
374
-
375
-		$this->appLocator
376
-			->expects($this->once())
377
-			->method('getAppPath')
378
-			->with('SomeApp')
379
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
380
-		$signatureDataFile = '{
332
+        $this->fileAccessHelper
333
+            ->expects($this->exactly(2))
334
+            ->method('file_get_contents')
335
+            ->willReturnMap([
336
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
337
+                ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
338
+            ]);
339
+
340
+        $expected = [
341
+            'INVALID_HASH' => [
342
+                'AnotherFile.txt' => [
343
+                    'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112',
344
+                    'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c',
345
+                ],
346
+            ],
347
+            'FILE_MISSING' => [
348
+                'subfolder/file.txt' => [
349
+                    'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b',
350
+                    'current' => '',
351
+                ],
352
+            ],
353
+            'EXTRA_FILE' => [
354
+                'UnecessaryFile' => [
355
+                    'expected' => '',
356
+                    'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
357
+                ],
358
+            ],
359
+
360
+        ];
361
+        $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'));
362
+    }
363
+
364
+    public function testVerifyAppWithDifferentScope(): void {
365
+        $this->serverVersion
366
+            ->expects($this->once())
367
+            ->method('getChannel')
368
+            ->willReturn('stable');
369
+        $this->config
370
+            ->expects($this->any())
371
+            ->method('getSystemValueBool')
372
+            ->with('integrity.check.disabled', false)
373
+            ->willReturn(false);
374
+
375
+        $this->appLocator
376
+            ->expects($this->once())
377
+            ->method('getAppPath')
378
+            ->with('SomeApp')
379
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
380
+        $signatureDataFile = '{
381 381
     "hashes": {
382 382
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
383 383
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -385,40 +385,40 @@  discard block
 block discarded – undo
385 385
     "signature": "eXesvDm3pkek12xSwMG10y9suRES79Nye3jYNe5KYq1tTUPqRRNgxmMGAfcUro0zpLeAr2YgHeSMWtglblGOW7pmwGVPZ0O1Y4r1fE6jnep0kW+35PLIaqCorIOnCAtSzDNKBhwd1ow3zW2wC0DFouuEkIO8u5Fw28g8E8dp8zEk1xMblNPy+xtWkmYHrVJ\/dQgun1bYOF2ZFtAzatwndTI\/bGsy1i3Wsl+x6HyWKQdq8y8VObtOqKDH7uERBEpB9DHVyKflj1v1gQuEH6BhaRdATc7ee0MiQdGblraIySwYRdfo2d8i82OVKrenMB3SLwyCvDPyQ9iKpTOnSF52ZBqaqSXKM2N\/RAkweeBFQQCwcHhqxvB0cfbyHcbkOLeCZe\/tsh68IxwTiYgzvLfl7sOZ5arnZbzrPpZmB+hfV2omkoJ1tDwOWz9hEmLLNtfo2OxyUH1m0+XFaC+Gbn4WkVDgf7YZkwUcG+Qoa3oKDNMss8MEyZxewl2iDGZcf402dlidHRprlfmXbAYuVQ08\/a0HxIKYPGh\/nsMGmwnO15CWtFpAbhUA\/D5oRjsIxnvXaMDg0iAFpdu\/5Ffsj7g3EPdBkiQHNYK7YU1RRx609eH0bZyiIYHdUPw7ikLupvrebZmELqi3mqDFO99u4eISlxFJlUbUND3L4BtmWTWrKwI=",
386 386
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIExjCCAq6gAwIBAgIUHSJjhJqMwr+3TkoiQFg4SVVYQ1gwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIzMjc1NVoXDTE2MTEwMzIzMjc1NVowFzEVMBMGA1UEAwwMQW5vdGhlclNjb3Bl\r\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA33npb5RmUkXrDT+TbwMf\r\n0zQ33SlzsjoGxCrbSwJOn6leGGInJ6ZrdzLL0WTi\/dTpg+Y\/JS+72XWm5NSjaTxo\r\n7OHc3cQBwXQj4tN6j\/y5qqY0GDLYufEkx2rpazqt9lBSJ72u1bGl2yoOXzYCz5i0\r\n60KsJXC9K44LKzGsarzbwAgskSVNkjAsPgjnCWZmcl6icpLi5Fz9rs2UMOWbdvdI\r\nAROsn0eC9E\/akmXTy5YMu6bAIGpvjZFHzyA83FQRbvv5o1V5Gsye\/VQLEgh7rqfz\r\nT\/jgWifP+JgoeB6otzuRZ3fFsmbBiyCIRtIOzQQflozhUlWtmiEGwg4GySuMUjEH\r\nA1LF86LO+ZzDQgd2oYNKmrQ8O+EcLqx9BpV4AFhEvqdk7uycJYPHs6yl+yfbzTeJ\r\n2Xd0yVAfd9r\/iDr36clLj2bzEObdl9xzKjcCIXE4Q0G4Pur41\/BJUDK9PI390ccQ\r\nnFjjVYBMsC859OwW64tMP0zkM9Vv72LCaEzaR8jqH0j11catqxunr+StfMcmxLTN\r\nbqBJbSEq4ER3mJxCTI2UrIVmdQ7+wRxgv3QTDNOZyqrz2L8A1Rpb3h0APxtQv+oA\r\n8KIZYID5\/qsS2V2jITkMQ8Nd1W3b0cZhZ600z+znh3jLJ0TYLvwN6\/qBQTUDaM2o\r\ng1+icMqXIXIeKuoPCVVsG7cCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAHc4F\/kOV\r\nHc8In5MmGg2YtjwZzjdeoC5TIPZczRqz0B+wRbJzN6aYryKZKLmP+wKpgRnJWDzp\r\nrgKGyyEQIAfK63DEv4B9p4N1B+B3aeMKsSpVcw7wbFTD57V5A7pURGoo31d0mw5L\r\nUIXZ2u+TUfGbzucMxLdFhTwjGpz9M6Kkm\/POxmV0tvLija5LdbdKnYR9BFmyu4IX\r\nqyoIAtComATNLl+3URu3SZxhE3NxhzMz+eAeNfh1KuIf2gWIIeDCXalVSJLym+OQ\r\nHFDpqRhJqfTMprrRlmmU7Zntgbj8\/RRZuXnBvH9cQ2KykLOb4UoCPlGUqOqKyP9m\r\nDJSFRiMJfpgMQUaJk1TLhKF+IR6FnmwURLEtkONJumtDQju9KaWPlhueONdyGi0p\r\nqxLVUo1Vb52XnPhk2GEEduxpDc9V5ePJ+pdcEdMifY\/uPNBRuBj2c87yq1DLH+U4\r\n3XzP1MlwjnBWZYuoFo0j6Jq0r\/MG6HjGdmkGIsRoheRi8Z8Scz5AW5QRkNz8pKop\r\nTELFqQy9g6TyQzzC8t6HZcpNe842ZUk4raEAbCZe\/XqxWMw5svPgNceBqM3fh7sZ\r\nBSykOHLaL8kiRO\/IS3y1yZEAuiWBvtxcTNLzBb+hdRpm2y8\/qH\/pKo+CMj1VzjNT\r\nD8YRQg0cjmDytJzHDrtV\/aTc9W1aPHun0vw=\r\n-----END CERTIFICATE-----"
387 387
 }';
388
-		$this->fileAccessHelper
389
-			->expects($this->exactly(2))
390
-			->method('file_get_contents')
391
-			->willReturnMap([
392
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
393
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
394
-			]);
395
-
396
-		$expected = [
397
-			'EXCEPTION' => [
398
-				'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
399
-				'message' => 'Certificate is not valid for required scope. (Requested: SomeApp, current: CN=AnotherScope)',
400
-			],
401
-		];
402
-		$this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
403
-	}
404
-
405
-	public function testVerifyAppWithDifferentScopeAndAlwaysTrustedCore(): void {
406
-		$this->serverVersion
407
-			->expects($this->once())
408
-			->method('getChannel')
409
-			->willReturn('stable');
410
-		$this->config
411
-			->expects($this->any())
412
-			->method('getSystemValueBool')
413
-			->with('integrity.check.disabled', false)
414
-			->willReturn(false);
415
-
416
-		$this->appLocator
417
-			->expects($this->once())
418
-			->method('getAppPath')
419
-			->with('SomeApp')
420
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
421
-		$signatureDataFile = '{
388
+        $this->fileAccessHelper
389
+            ->expects($this->exactly(2))
390
+            ->method('file_get_contents')
391
+            ->willReturnMap([
392
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
393
+                ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
394
+            ]);
395
+
396
+        $expected = [
397
+            'EXCEPTION' => [
398
+                'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
399
+                'message' => 'Certificate is not valid for required scope. (Requested: SomeApp, current: CN=AnotherScope)',
400
+            ],
401
+        ];
402
+        $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
403
+    }
404
+
405
+    public function testVerifyAppWithDifferentScopeAndAlwaysTrustedCore(): void {
406
+        $this->serverVersion
407
+            ->expects($this->once())
408
+            ->method('getChannel')
409
+            ->willReturn('stable');
410
+        $this->config
411
+            ->expects($this->any())
412
+            ->method('getSystemValueBool')
413
+            ->with('integrity.check.disabled', false)
414
+            ->willReturn(false);
415
+
416
+        $this->appLocator
417
+            ->expects($this->once())
418
+            ->method('getAppPath')
419
+            ->with('SomeApp')
420
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
421
+        $signatureDataFile = '{
422 422
     "hashes": {
423 423
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
424 424
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -426,67 +426,67 @@  discard block
 block discarded – undo
426 426
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
427 427
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
428 428
 }';
429
-		$this->fileAccessHelper
430
-			->expects($this->exactly(2))
431
-			->method('file_get_contents')
432
-			->willReturnMap([
433
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
434
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
435
-			]);
436
-
437
-		$this->assertSame([], $this->checker->verifyAppSignature('SomeApp'));
438
-	}
439
-
440
-
441
-	public function testWriteCoreSignatureWithException(): void {
442
-		$this->expectException(\Exception::class);
443
-		$this->expectExceptionMessage('Exception message');
444
-
445
-		$this->fileAccessHelper
446
-			->expects($this->once())
447
-			->method('assertDirectoryExists')
448
-			->will($this->throwException(new \Exception('Exception message')));
449
-		$this->fileAccessHelper
450
-			->expects($this->once())
451
-			->method('is_writable')
452
-			->with(__DIR__ . '/core')
453
-			->willReturn(true);
454
-
455
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
456
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
457
-		$rsa = new RSA();
458
-		$rsa->loadKey($rsaPrivateKey);
459
-		$x509 = new X509();
460
-		$x509->loadX509($keyBundle);
461
-		$this->checker->writeCoreSignature($x509, $rsa, __DIR__);
462
-	}
463
-
464
-
465
-	public function testWriteCoreSignatureWrongPermissions(): void {
466
-		$this->expectException(\Exception::class);
467
-		$this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/');
468
-
469
-		$this->fileAccessHelper
470
-			->expects($this->once())
471
-			->method('assertDirectoryExists')
472
-			->will($this->throwException(new \Exception('Exception message')));
473
-		$this->fileAccessHelper
474
-			->expects($this->once())
475
-			->method('is_writable')
476
-			->with(__DIR__ . '/core')
477
-			->willReturn(false);
478
-
479
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
480
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
481
-		$rsa = new RSA();
482
-		$rsa->loadKey($rsaPrivateKey);
483
-		$x509 = new X509();
484
-		$x509->loadX509($keyBundle);
485
-		$this->checker->writeCoreSignature($x509, $rsa, __DIR__);
486
-	}
487
-
488
-	public function testWriteCoreSignature(): void {
489
-		$expectedSignatureFileData = '{
429
+        $this->fileAccessHelper
430
+            ->expects($this->exactly(2))
431
+            ->method('file_get_contents')
432
+            ->willReturnMap([
433
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
434
+                ['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
435
+            ]);
436
+
437
+        $this->assertSame([], $this->checker->verifyAppSignature('SomeApp'));
438
+    }
439
+
440
+
441
+    public function testWriteCoreSignatureWithException(): void {
442
+        $this->expectException(\Exception::class);
443
+        $this->expectExceptionMessage('Exception message');
444
+
445
+        $this->fileAccessHelper
446
+            ->expects($this->once())
447
+            ->method('assertDirectoryExists')
448
+            ->will($this->throwException(new \Exception('Exception message')));
449
+        $this->fileAccessHelper
450
+            ->expects($this->once())
451
+            ->method('is_writable')
452
+            ->with(__DIR__ . '/core')
453
+            ->willReturn(true);
454
+
455
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
456
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
457
+        $rsa = new RSA();
458
+        $rsa->loadKey($rsaPrivateKey);
459
+        $x509 = new X509();
460
+        $x509->loadX509($keyBundle);
461
+        $this->checker->writeCoreSignature($x509, $rsa, __DIR__);
462
+    }
463
+
464
+
465
+    public function testWriteCoreSignatureWrongPermissions(): void {
466
+        $this->expectException(\Exception::class);
467
+        $this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/');
468
+
469
+        $this->fileAccessHelper
470
+            ->expects($this->once())
471
+            ->method('assertDirectoryExists')
472
+            ->will($this->throwException(new \Exception('Exception message')));
473
+        $this->fileAccessHelper
474
+            ->expects($this->once())
475
+            ->method('is_writable')
476
+            ->with(__DIR__ . '/core')
477
+            ->willReturn(false);
478
+
479
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
480
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
481
+        $rsa = new RSA();
482
+        $rsa->loadKey($rsaPrivateKey);
483
+        $x509 = new X509();
484
+        $x509->loadX509($keyBundle);
485
+        $this->checker->writeCoreSignature($x509, $rsa, __DIR__);
486
+    }
487
+
488
+    public function testWriteCoreSignature(): void {
489
+        $expectedSignatureFileData = '{
490 490
     "hashes": {
491 491
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
492 492
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -494,34 +494,34 @@  discard block
 block discarded – undo
494 494
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
495 495
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
496 496
 }';
497
-		$this->environmentHelper
498
-			->expects($this->any())
499
-			->method('getServerRoot')
500
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
501
-		$this->fileAccessHelper
502
-			->expects($this->once())
503
-			->method('file_put_contents')
504
-			->with(
505
-				\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json',
506
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
507
-					$expectedArray = json_decode($expectedSignatureFileData, true);
508
-					$actualArray = json_decode($signature, true);
509
-					$this->assertEquals($expectedArray, $actualArray);
510
-					return true;
511
-				})
512
-			);
513
-
514
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
515
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
516
-		$rsa = new RSA();
517
-		$rsa->loadKey($rsaPrivateKey);
518
-		$x509 = new X509();
519
-		$x509->loadX509($keyBundle);
520
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/app/');
521
-	}
522
-
523
-	public function testWriteCoreSignatureWithUnmodifiedHtaccess(): void {
524
-		$expectedSignatureFileData = '{
497
+        $this->environmentHelper
498
+            ->expects($this->any())
499
+            ->method('getServerRoot')
500
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
501
+        $this->fileAccessHelper
502
+            ->expects($this->once())
503
+            ->method('file_put_contents')
504
+            ->with(
505
+                \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json',
506
+                $this->callback(function ($signature) use ($expectedSignatureFileData) {
507
+                    $expectedArray = json_decode($expectedSignatureFileData, true);
508
+                    $actualArray = json_decode($signature, true);
509
+                    $this->assertEquals($expectedArray, $actualArray);
510
+                    return true;
511
+                })
512
+            );
513
+
514
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
515
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
516
+        $rsa = new RSA();
517
+        $rsa->loadKey($rsaPrivateKey);
518
+        $x509 = new X509();
519
+        $x509->loadX509($keyBundle);
520
+        $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/app/');
521
+    }
522
+
523
+    public function testWriteCoreSignatureWithUnmodifiedHtaccess(): void {
524
+        $expectedSignatureFileData = '{
525 525
     "hashes": {
526 526
         ".htaccess": "dc479770a6232061e04a768ee1f9133fdb3aea7b3a99f7105b0e0b6197474733e8d14b5b2bbad054e6b62a410fe5d0b3d790242dee1e0f11274af2100f5289e2",
527 527
         "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1"
@@ -529,64 +529,64 @@  discard block
 block discarded – undo
529 529
     "signature": "nRtR377DB\/I\/4hmh9q3elMQYfSHnQFlNtjchNgrdfmUQqVmgkU\/4qgGyxDqYkV8mSMbH2gYysfP42nx\/3zSo7n0dBYDfU87Q6f96Cv597vEV27do8CaBkEk8Xjn2SxhHw8hVxracvE2OBAPxk0H3sRp\/cQBgjoXpju4kQin0N5E+DEJMh7Sp+u8aKoFpb+2FaAZJFn\/hnqxLTlVi2nyDxGL3U0eobWY+jWH9XPt52v3Hyh8TDhcAnQ1cN30B8Jn2+jkrm8ib+buchaCXHk0cPX72xuPECdwOEKLCBNrJa3FGSvO1zWiecnCgxCXgt+R8hUgsVPTsbrdFY2YRJGIhHndYZL98XzgG7cw85SnnMMe2SulzeL7xANGF8qiEVyiC7x83bbj5xOkeM\/CUTajrLBO3vyZ23KKOxvskjgI0t+Zw1zFsl+sYW0\/O\/V5WzPOwMwV8+iApQ8k9gEMiYQg98QLEMYnSohncmp0Z9qx2qFcQuHLcKJVa1J6wGtE\/EHR\/4d0aYPd6IRjg+qshCJmdzud\/12xjpGTl+BT0Hi0VsU5o7ZMi7WhmukZmmv8u0uZsvKREQNATm4cO4WCkYySt5O9gZEJOF+jjgeynDoAh09lyrNXIgMpM9ufm\/XEG\/I\/f2zIwbAUc6J6qks5OuYlJzW5vscTiOKhwcGZU9WBLgh0=",
530 530
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
531 531
 }';
532
-		$this->environmentHelper
533
-			->expects($this->any())
534
-			->method('getServerRoot')
535
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/');
536
-		$this->fileAccessHelper
537
-			->expects($this->once())
538
-			->method('file_put_contents')
539
-			->with(
540
-				\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified//core/signature.json',
541
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
542
-					$expectedArray = json_decode($expectedSignatureFileData, true);
543
-					$actualArray = json_decode($signature, true);
544
-					$this->assertEquals($expectedArray, $actualArray);
545
-					return true;
546
-				})
547
-			);
548
-
549
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
550
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
551
-		$rsa = new RSA();
552
-		$rsa->loadKey($rsaPrivateKey);
553
-		$x509 = new X509();
554
-		$x509->loadX509($keyBundle);
555
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/');
556
-	}
557
-
558
-	public function testWriteCoreSignatureWithInvalidModifiedHtaccess(): void {
559
-		$expectedSignatureFileData = '{
532
+        $this->environmentHelper
533
+            ->expects($this->any())
534
+            ->method('getServerRoot')
535
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/');
536
+        $this->fileAccessHelper
537
+            ->expects($this->once())
538
+            ->method('file_put_contents')
539
+            ->with(
540
+                \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified//core/signature.json',
541
+                $this->callback(function ($signature) use ($expectedSignatureFileData) {
542
+                    $expectedArray = json_decode($expectedSignatureFileData, true);
543
+                    $actualArray = json_decode($signature, true);
544
+                    $this->assertEquals($expectedArray, $actualArray);
545
+                    return true;
546
+                })
547
+            );
548
+
549
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
550
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
551
+        $rsa = new RSA();
552
+        $rsa->loadKey($rsaPrivateKey);
553
+        $x509 = new X509();
554
+        $x509->loadX509($keyBundle);
555
+        $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/');
556
+    }
557
+
558
+    public function testWriteCoreSignatureWithInvalidModifiedHtaccess(): void {
559
+        $expectedSignatureFileData = '{
560 560
     "hashes": {
561 561
         ".htaccess": "4a54273dc8d697b2ca615acf2ae2c1ee3c1c643492cb04f42b10984fa9aacff1420dc829fd82f93ad3476fbd0cdab0251142c887dc8f872d03e39a3a3eb6d381"
562 562
     },
563 563
     "signature": "qpDddYGgAKNR3TszOgjPXRphUl2P9Ym5OQaetltocgZASGDkOun5D64+1D0QJRKb4SG2+48muxGOHyL2Ngos4NUrrSR+SIkywZacay82YQBCEdr7\/4MjW1WHRPjvboLwEJwViw0EdAjsWRpD68aPnzUGrGsy2BsCo06P5iwjk9cXcHxdjC9R39npvoC3QNvQ2jmNIbh1Lc4U97dbb+CsXEQCLU1OSa9p3q6cEFV98Easwt7uF\/DzHK+CbeZlxVZ0DwLh2\/ylT1PyGou8QC1b3vKAnPjLWMO+UsCPpCKhk3C5pV+5etQ8puGd+0x2t5tEU+qXxLzek91zWNC+rqgC\/WlqLKbwPb\/BCHs4zLGV55Q2fEQmT21x0KCUELdPs4dBnYP4Ox5tEDugtJujWFzOHzoY6gGa\/BY\/78pSZXmq9o8dWkBEtioWWvaNZ1rM0ddE83GBlBTgjigi9Ay1D++bUW\/FCBB7CMk6qyNlV81H+cBuIEODw2aymmkM9LLDD2Qbmvo8gHEPRjiQxPC5OpDlcdSNiL+zcxVxeuX4FpT+9xzz\/\/DRONhufxRpsbuCOMxd96RW7y9U2N2Uxb3Bzn\/BIqEayUUsdgZjfaGcXXYKR+chu\/LOwNYN6RlnLsgqL\/dhGKwlRVKXw1RA2\/af\/CpqyR7uVP6al1YJo\/YJ+5XJ6zE=",
564 564
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
565 565
 }';
566
-		$this->fileAccessHelper
567
-			->expects($this->once())
568
-			->method('file_put_contents')
569
-			->with(
570
-				\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json',
571
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
572
-					$expectedArray = json_decode($expectedSignatureFileData, true);
573
-					$actualArray = json_decode($signature, true);
574
-					$this->assertEquals($expectedArray, $actualArray);
575
-					return true;
576
-				})
577
-			);
578
-
579
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
580
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
581
-		$rsa = new RSA();
582
-		$rsa->loadKey($rsaPrivateKey);
583
-		$x509 = new X509();
584
-		$x509->loadX509($keyBundle);
585
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/');
586
-	}
587
-
588
-	public function testWriteCoreSignatureWithValidModifiedHtaccess(): void {
589
-		$expectedSignatureFileData = '{
566
+        $this->fileAccessHelper
567
+            ->expects($this->once())
568
+            ->method('file_put_contents')
569
+            ->with(
570
+                \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json',
571
+                $this->callback(function ($signature) use ($expectedSignatureFileData) {
572
+                    $expectedArray = json_decode($expectedSignatureFileData, true);
573
+                    $actualArray = json_decode($signature, true);
574
+                    $this->assertEquals($expectedArray, $actualArray);
575
+                    return true;
576
+                })
577
+            );
578
+
579
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
580
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
581
+        $rsa = new RSA();
582
+        $rsa->loadKey($rsaPrivateKey);
583
+        $x509 = new X509();
584
+        $x509->loadX509($keyBundle);
585
+        $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/');
586
+    }
587
+
588
+    public function testWriteCoreSignatureWithValidModifiedHtaccess(): void {
589
+        $expectedSignatureFileData = '{
590 590
     "hashes": {
591 591
         ".htaccess": "7e6a7a4d8ee4f3fbc45dd579407c643471575a9d127d1c75f6d0a49e80766c3c587104b2139ef76d2a4bffce3f45777900605aaa49519c9532909b71e5030227",
592 592
         "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1"
@@ -594,68 +594,68 @@  discard block
 block discarded – undo
594 594
     "signature": "YVwQvl9Dh8UebCumfgzFxfz3NiZJLmYG8oJVTfEBhulI4KXBnTG1jZTprf4XxG2XIriEYAZXsoXpu9xWsUFe9QfdncwoEpqJtGq7l6aVDTofX5Be5b03MQFJr4cflgllqW77QZ84D9O9qWF\/vNDAofXcwrzT04CxLDhyQgTCgYUnRjG9pnuP\/gtbDKbTjRvxhTyfg3T0Phv1+XAvpTPnH2q5A+1+LmiqziUJ1sMipsKo+jQP614eCi9qjmqhHIgLRgcuOBvsi4g5WUcdcAIZ6qLt5gm2Y3r6rKNVchosU9ZydMUTfjuejDbVwE2fNH5UUnV57fQBxwg9CfX7iFHqKv1bfv5Zviu12paShgWCB12uR3iH\/3lmTJn8K5Xqit3G4eymFaJ5IChdUThBp\/jhQSI2r8sPcZDYSJ\/UZKuFnezFdKhEBd5hMXe8aKAd6ijGDjLARksFuqpi1sS8llC5K1Q+DzktSL\/o64TY4Vuvykiwe\/BAk2SkL9voOtrvU7vfDBcuCPbDJnSBBC0ESpcXeClTBIn6xZ9WaxqoS7sinE\/kUwtWsRd04I7d79\/ouotyNb+mBhTuRsZT12p\/gn4JHXXNUAIpTwchYzGxbfNJ4kxnYBFZWVmvsSqOLFZu1yi5BP3ktA9yhFyWIa5659azRFEKRdXpVHtQVa4IgdhxEqA=",
595 595
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
596 596
 }';
597
-		$this->environmentHelper
598
-			->expects($this->any())
599
-			->method('getServerRoot')
600
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
601
-		$this->fileAccessHelper
602
-			->expects($this->once())
603
-			->method('file_put_contents')
604
-			->with(
605
-				\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json',
606
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
607
-					$expectedArray = json_decode($expectedSignatureFileData, true);
608
-					$actualArray = json_decode($signature, true);
609
-					$this->assertEquals($expectedArray, $actualArray);
610
-					return true;
611
-				})
612
-			);
613
-
614
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
615
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
616
-		$rsa = new RSA();
617
-		$rsa->loadKey($rsaPrivateKey);
618
-		$x509 = new X509();
619
-		$x509->loadX509($keyBundle);
620
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
621
-	}
622
-
623
-	public function testVerifyCoreSignatureWithoutSignatureData(): void {
624
-		$this->serverVersion
625
-			->expects($this->once())
626
-			->method('getChannel')
627
-			->willReturn('stable');
628
-		$this->config
629
-			->expects($this->any())
630
-			->method('getSystemValueBool')
631
-			->with('integrity.check.disabled', false)
632
-			->willReturn(false);
633
-
634
-		$expected = [
635
-			'EXCEPTION' => [
636
-				'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
637
-				'message' => 'Signature data not found.',
638
-			],
639
-		];
640
-		$this->assertSame($expected, $this->checker->verifyCoreSignature());
641
-	}
642
-
643
-	public function testVerifyCoreSignatureWithValidSignatureData(): void {
644
-		$this->serverVersion
645
-			->expects($this->once())
646
-			->method('getChannel')
647
-			->willReturn('stable');
648
-		$this->config
649
-			->expects($this->any())
650
-			->method('getSystemValueBool')
651
-			->with('integrity.check.disabled', false)
652
-			->willReturn(false);
653
-
654
-		$this->environmentHelper
655
-			->expects($this->any())
656
-			->method('getServerRoot')
657
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
658
-		$signatureDataFile = '{
597
+        $this->environmentHelper
598
+            ->expects($this->any())
599
+            ->method('getServerRoot')
600
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
601
+        $this->fileAccessHelper
602
+            ->expects($this->once())
603
+            ->method('file_put_contents')
604
+            ->with(
605
+                \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json',
606
+                $this->callback(function ($signature) use ($expectedSignatureFileData) {
607
+                    $expectedArray = json_decode($expectedSignatureFileData, true);
608
+                    $actualArray = json_decode($signature, true);
609
+                    $this->assertEquals($expectedArray, $actualArray);
610
+                    return true;
611
+                })
612
+            );
613
+
614
+        $keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
615
+        $rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
616
+        $rsa = new RSA();
617
+        $rsa->loadKey($rsaPrivateKey);
618
+        $x509 = new X509();
619
+        $x509->loadX509($keyBundle);
620
+        $this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
621
+    }
622
+
623
+    public function testVerifyCoreSignatureWithoutSignatureData(): void {
624
+        $this->serverVersion
625
+            ->expects($this->once())
626
+            ->method('getChannel')
627
+            ->willReturn('stable');
628
+        $this->config
629
+            ->expects($this->any())
630
+            ->method('getSystemValueBool')
631
+            ->with('integrity.check.disabled', false)
632
+            ->willReturn(false);
633
+
634
+        $expected = [
635
+            'EXCEPTION' => [
636
+                'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
637
+                'message' => 'Signature data not found.',
638
+            ],
639
+        ];
640
+        $this->assertSame($expected, $this->checker->verifyCoreSignature());
641
+    }
642
+
643
+    public function testVerifyCoreSignatureWithValidSignatureData(): void {
644
+        $this->serverVersion
645
+            ->expects($this->once())
646
+            ->method('getChannel')
647
+            ->willReturn('stable');
648
+        $this->config
649
+            ->expects($this->any())
650
+            ->method('getSystemValueBool')
651
+            ->with('integrity.check.disabled', false)
652
+            ->willReturn(false);
653
+
654
+        $this->environmentHelper
655
+            ->expects($this->any())
656
+            ->method('getServerRoot')
657
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
658
+        $signatureDataFile = '{
659 659
     "hashes": {
660 660
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
661 661
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -663,33 +663,33 @@  discard block
 block discarded – undo
663 663
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
664 664
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
665 665
 }';
666
-		$this->fileAccessHelper
667
-			->expects($this->exactly(2))
668
-			->method('file_get_contents')
669
-			->willReturnMap([
670
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
671
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
672
-			]);
673
-
674
-		$this->assertSame([], $this->checker->verifyCoreSignature());
675
-	}
676
-
677
-	public function testVerifyCoreSignatureWithValidModifiedHtaccessSignatureData(): void {
678
-		$this->serverVersion
679
-			->expects($this->once())
680
-			->method('getChannel')
681
-			->willReturn('stable');
682
-		$this->config
683
-			->expects($this->any())
684
-			->method('getSystemValueBool')
685
-			->with('integrity.check.disabled', false)
686
-			->willReturn(false);
687
-
688
-		$this->environmentHelper
689
-			->expects($this->any())
690
-			->method('getServerRoot')
691
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
692
-		$signatureDataFile = '{
666
+        $this->fileAccessHelper
667
+            ->expects($this->exactly(2))
668
+            ->method('file_get_contents')
669
+            ->willReturnMap([
670
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
671
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
672
+            ]);
673
+
674
+        $this->assertSame([], $this->checker->verifyCoreSignature());
675
+    }
676
+
677
+    public function testVerifyCoreSignatureWithValidModifiedHtaccessSignatureData(): void {
678
+        $this->serverVersion
679
+            ->expects($this->once())
680
+            ->method('getChannel')
681
+            ->willReturn('stable');
682
+        $this->config
683
+            ->expects($this->any())
684
+            ->method('getSystemValueBool')
685
+            ->with('integrity.check.disabled', false)
686
+            ->willReturn(false);
687
+
688
+        $this->environmentHelper
689
+            ->expects($this->any())
690
+            ->method('getServerRoot')
691
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
692
+        $signatureDataFile = '{
693 693
     "hashes": {
694 694
         ".htaccess": "7e6a7a4d8ee4f3fbc45dd579407c643471575a9d127d1c75f6d0a49e80766c3c587104b2139ef76d2a4bffce3f45777900605aaa49519c9532909b71e5030227",
695 695
         "subfolder\/.htaccess": "2c57b1e25050e11dc3ae975832f378c452159f7b69f818e47eeeafadd6ba568517461dcb4d843b90b906cd7c89d161bc1b89dff8e3ae0eb6f5088508c47befd1"
@@ -697,85 +697,85 @@  discard block
 block discarded – undo
697 697
     "signature": "YVwQvl9Dh8UebCumfgzFxfz3NiZJLmYG8oJVTfEBhulI4KXBnTG1jZTprf4XxG2XIriEYAZXsoXpu9xWsUFe9QfdncwoEpqJtGq7l6aVDTofX5Be5b03MQFJr4cflgllqW77QZ84D9O9qWF\/vNDAofXcwrzT04CxLDhyQgTCgYUnRjG9pnuP\/gtbDKbTjRvxhTyfg3T0Phv1+XAvpTPnH2q5A+1+LmiqziUJ1sMipsKo+jQP614eCi9qjmqhHIgLRgcuOBvsi4g5WUcdcAIZ6qLt5gm2Y3r6rKNVchosU9ZydMUTfjuejDbVwE2fNH5UUnV57fQBxwg9CfX7iFHqKv1bfv5Zviu12paShgWCB12uR3iH\/3lmTJn8K5Xqit3G4eymFaJ5IChdUThBp\/jhQSI2r8sPcZDYSJ\/UZKuFnezFdKhEBd5hMXe8aKAd6ijGDjLARksFuqpi1sS8llC5K1Q+DzktSL\/o64TY4Vuvykiwe\/BAk2SkL9voOtrvU7vfDBcuCPbDJnSBBC0ESpcXeClTBIn6xZ9WaxqoS7sinE\/kUwtWsRd04I7d79\/ouotyNb+mBhTuRsZT12p\/gn4JHXXNUAIpTwchYzGxbfNJ4kxnYBFZWVmvsSqOLFZu1yi5BP3ktA9yhFyWIa5659azRFEKRdXpVHtQVa4IgdhxEqA=",
698 698
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
699 699
 }';
700
-		$this->fileAccessHelper
701
-			->expects($this->exactly(2))
702
-			->method('file_get_contents')
703
-			->willReturnMap([
704
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile],
705
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
706
-			]);
707
-
708
-		$this->assertSame([], $this->checker->verifyCoreSignature());
709
-	}
710
-
711
-	/**
712
-	 * See inline instruction on how to update the test assets when changing mimetypealiases.dist.json
713
-	 */
714
-	public function testVerifyCoreSignatureWithModifiedMimetypelistSignatureData(): void {
715
-		$shippedMimetypeAliases = (array)json_decode(file_get_contents(\OC::$SERVERROOT . '/resources/config/mimetypealiases.dist.json'));
716
-		$allAliases = array_merge($shippedMimetypeAliases, ['my-custom/mimetype' => 'custom']);
717
-
718
-		$this->mimeTypeDetector
719
-			->method('getOnlyDefaultAliases')
720
-			->willReturn($shippedMimetypeAliases);
721
-
722
-		$this->mimeTypeDetector
723
-			->method('getAllAliases')
724
-			->willReturn($allAliases);
725
-
726
-		$oldMimetypeList = new GenerateMimetypeFileBuilder();
727
-		$all = $this->mimeTypeDetector->getAllAliases();
728
-		$newFile = $oldMimetypeList->generateFile($all);
729
-
730
-		// When updating the mimetype list the test assets need to be updated as well
731
-		// 1. Update core/js/mimetypelist.js with the new generated js by running the test with the next line uncommented:
732
-		// file_put_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js', $newFile);
733
-		// 2. Update signature.json using the following occ command:
734
-		// occ integrity:sign-core --privateKey=./tests/data/integritycheck/core.key --certificate=./tests/data/integritycheck/core.crt --path=./tests/data/integritycheck/mimetypeListModified
735
-		self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js'));
736
-
737
-		$this->serverVersion
738
-			->expects($this->once())
739
-			->method('getChannel')
740
-			->willReturn('stable');
741
-		$this->config
742
-			->expects($this->any())
743
-			->method('getSystemValueBool')
744
-			->with('integrity.check.disabled', false)
745
-			->willReturn(false);
746
-
747
-		$this->environmentHelper
748
-			->expects($this->any())
749
-			->method('getServerRoot')
750
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified');
751
-
752
-		$signatureDataFile = file_get_contents(__DIR__ . '/../../data/integritycheck/mimetypeListModified/core/signature.json');
753
-		$this->fileAccessHelper
754
-			->method('file_get_contents')
755
-			->willReturnMap([
756
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile],
757
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
758
-			]);
759
-
760
-		$this->assertSame([], $this->checker->verifyCoreSignature());
761
-	}
762
-
763
-	public function testVerifyCoreSignatureWithValidSignatureDataAndNotAlphabeticOrder(): void {
764
-		$this->serverVersion
765
-			->expects($this->once())
766
-			->method('getChannel')
767
-			->willReturn('stable');
768
-		$this->config
769
-			->expects($this->any())
770
-			->method('getSystemValueBool')
771
-			->with('integrity.check.disabled', false)
772
-			->willReturn(false);
773
-
774
-		$this->environmentHelper
775
-			->expects($this->any())
776
-			->method('getServerRoot')
777
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
778
-		$signatureDataFile = '{
700
+        $this->fileAccessHelper
701
+            ->expects($this->exactly(2))
702
+            ->method('file_get_contents')
703
+            ->willReturnMap([
704
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile],
705
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
706
+            ]);
707
+
708
+        $this->assertSame([], $this->checker->verifyCoreSignature());
709
+    }
710
+
711
+    /**
712
+     * See inline instruction on how to update the test assets when changing mimetypealiases.dist.json
713
+     */
714
+    public function testVerifyCoreSignatureWithModifiedMimetypelistSignatureData(): void {
715
+        $shippedMimetypeAliases = (array)json_decode(file_get_contents(\OC::$SERVERROOT . '/resources/config/mimetypealiases.dist.json'));
716
+        $allAliases = array_merge($shippedMimetypeAliases, ['my-custom/mimetype' => 'custom']);
717
+
718
+        $this->mimeTypeDetector
719
+            ->method('getOnlyDefaultAliases')
720
+            ->willReturn($shippedMimetypeAliases);
721
+
722
+        $this->mimeTypeDetector
723
+            ->method('getAllAliases')
724
+            ->willReturn($allAliases);
725
+
726
+        $oldMimetypeList = new GenerateMimetypeFileBuilder();
727
+        $all = $this->mimeTypeDetector->getAllAliases();
728
+        $newFile = $oldMimetypeList->generateFile($all);
729
+
730
+        // When updating the mimetype list the test assets need to be updated as well
731
+        // 1. Update core/js/mimetypelist.js with the new generated js by running the test with the next line uncommented:
732
+        // file_put_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js', $newFile);
733
+        // 2. Update signature.json using the following occ command:
734
+        // occ integrity:sign-core --privateKey=./tests/data/integritycheck/core.key --certificate=./tests/data/integritycheck/core.crt --path=./tests/data/integritycheck/mimetypeListModified
735
+        self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js'));
736
+
737
+        $this->serverVersion
738
+            ->expects($this->once())
739
+            ->method('getChannel')
740
+            ->willReturn('stable');
741
+        $this->config
742
+            ->expects($this->any())
743
+            ->method('getSystemValueBool')
744
+            ->with('integrity.check.disabled', false)
745
+            ->willReturn(false);
746
+
747
+        $this->environmentHelper
748
+            ->expects($this->any())
749
+            ->method('getServerRoot')
750
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified');
751
+
752
+        $signatureDataFile = file_get_contents(__DIR__ . '/../../data/integritycheck/mimetypeListModified/core/signature.json');
753
+        $this->fileAccessHelper
754
+            ->method('file_get_contents')
755
+            ->willReturnMap([
756
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile],
757
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
758
+            ]);
759
+
760
+        $this->assertSame([], $this->checker->verifyCoreSignature());
761
+    }
762
+
763
+    public function testVerifyCoreSignatureWithValidSignatureDataAndNotAlphabeticOrder(): void {
764
+        $this->serverVersion
765
+            ->expects($this->once())
766
+            ->method('getChannel')
767
+            ->willReturn('stable');
768
+        $this->config
769
+            ->expects($this->any())
770
+            ->method('getSystemValueBool')
771
+            ->with('integrity.check.disabled', false)
772
+            ->willReturn(false);
773
+
774
+        $this->environmentHelper
775
+            ->expects($this->any())
776
+            ->method('getServerRoot')
777
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
778
+        $signatureDataFile = '{
779 779
     "hashes": {
780 780
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
781 781
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -783,33 +783,33 @@  discard block
 block discarded – undo
783 783
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
784 784
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
785 785
 }';
786
-		$this->fileAccessHelper
787
-			->expects($this->exactly(2))
788
-			->method('file_get_contents')
789
-			->willReturnMap([
790
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
791
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
792
-			]);
793
-
794
-		$this->assertSame([], $this->checker->verifyCoreSignature());
795
-	}
796
-
797
-	public function testVerifyCoreSignatureWithTamperedSignatureData(): void {
798
-		$this->serverVersion
799
-			->expects($this->once())
800
-			->method('getChannel')
801
-			->willReturn('stable');
802
-		$this->config
803
-			->expects($this->any())
804
-			->method('getSystemValueBool')
805
-			->with('integrity.check.disabled', false)
806
-			->willReturn(false);
807
-
808
-		$this->environmentHelper
809
-			->expects($this->any())
810
-			->method('getServerRoot')
811
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
812
-		$signatureDataFile = '{
786
+        $this->fileAccessHelper
787
+            ->expects($this->exactly(2))
788
+            ->method('file_get_contents')
789
+            ->willReturnMap([
790
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
791
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
792
+            ]);
793
+
794
+        $this->assertSame([], $this->checker->verifyCoreSignature());
795
+    }
796
+
797
+    public function testVerifyCoreSignatureWithTamperedSignatureData(): void {
798
+        $this->serverVersion
799
+            ->expects($this->once())
800
+            ->method('getChannel')
801
+            ->willReturn('stable');
802
+        $this->config
803
+            ->expects($this->any())
804
+            ->method('getSystemValueBool')
805
+            ->with('integrity.check.disabled', false)
806
+            ->willReturn(false);
807
+
808
+        $this->environmentHelper
809
+            ->expects($this->any())
810
+            ->method('getServerRoot')
811
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
812
+        $signatureDataFile = '{
813 813
     "hashes": {
814 814
         "AnotherFile.txt": "tampered",
815 815
         "subfolder\/file.txt": "tampered"
@@ -817,39 +817,39 @@  discard block
 block discarded – undo
817 817
     "signature": "eXesvDm3pkek12xSwMG10y9suRES79Nye3jYNe5KYq1tTUPqRRNgxmMGAfcUro0zpLeAr2YgHeSMWtglblGOW7pmwGVPZ0O1Y4r1fE6jnep0kW+35PLIaqCorIOnCAtSzDNKBhwd1ow3zW2wC0DFouuEkIO8u5Fw28g8E8dp8zEk1xMblNPy+xtWkmYHrVJ\/dQgun1bYOF2ZFtAzatwndTI\/bGsy1i3Wsl+x6HyWKQdq8y8VObtOqKDH7uERBEpB9DHVyKflj1v1gQuEH6BhaRdATc7ee0MiQdGblraIySwYRdfo2d8i82OVKrenMB3SLwyCvDPyQ9iKpTOnSF52ZBqaqSXKM2N\/RAkweeBFQQCwcHhqxvB0cfbyHcbkOLeCZe\/tsh68IxwTiYgzvLfl7sOZ5arnZbzrPpZmB+hfV2omkoJ1tDwOWz9hEmLLNtfo2OxyUH1m0+XFaC+Gbn4WkVDgf7YZkwUcG+Qoa3oKDNMss8MEyZxewl2iDGZcf402dlidHRprlfmXbAYuVQ08\/a0HxIKYPGh\/nsMGmwnO15CWtFpAbhUA\/D5oRjsIxnvXaMDg0iAFpdu\/5Ffsj7g3EPdBkiQHNYK7YU1RRx609eH0bZyiIYHdUPw7ikLupvrebZmELqi3mqDFO99u4eISlxFJlUbUND3L4BtmWTWrKwI=",
818 818
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
819 819
 }';
820
-		$this->fileAccessHelper
821
-			->expects($this->exactly(2))
822
-			->method('file_get_contents')
823
-			->willReturnMap([
824
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
825
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
826
-			]);
827
-
828
-		$expected = [
829
-			'EXCEPTION' => [
830
-				'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
831
-				'message' => 'Signature could not get verified.',
832
-			]
833
-		];
834
-		$this->assertSame($expected, $this->checker->verifyCoreSignature());
835
-	}
836
-
837
-	public function testVerifyCoreSignatureWithTamperedFiles(): void {
838
-		$this->serverVersion
839
-			->expects($this->once())
840
-			->method('getChannel')
841
-			->willReturn('stable');
842
-		$this->config
843
-			->expects($this->any())
844
-			->method('getSystemValueBool')
845
-			->with('integrity.check.disabled', false)
846
-			->willReturn(false);
847
-
848
-		$this->environmentHelper
849
-			->expects($this->any())
850
-			->method('getServerRoot')
851
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
852
-		$signatureDataFile = '{
820
+        $this->fileAccessHelper
821
+            ->expects($this->exactly(2))
822
+            ->method('file_get_contents')
823
+            ->willReturnMap([
824
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
825
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
826
+            ]);
827
+
828
+        $expected = [
829
+            'EXCEPTION' => [
830
+                'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
831
+                'message' => 'Signature could not get verified.',
832
+            ]
833
+        ];
834
+        $this->assertSame($expected, $this->checker->verifyCoreSignature());
835
+    }
836
+
837
+    public function testVerifyCoreSignatureWithTamperedFiles(): void {
838
+        $this->serverVersion
839
+            ->expects($this->once())
840
+            ->method('getChannel')
841
+            ->willReturn('stable');
842
+        $this->config
843
+            ->expects($this->any())
844
+            ->method('getSystemValueBool')
845
+            ->with('integrity.check.disabled', false)
846
+            ->willReturn(false);
847
+
848
+        $this->environmentHelper
849
+            ->expects($this->any())
850
+            ->method('getServerRoot')
851
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
852
+        $signatureDataFile = '{
853 853
     "hashes": {
854 854
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
855 855
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -857,54 +857,54 @@  discard block
 block discarded – undo
857 857
     "signature": "dYoohBaWIFR\/To1FXEbMQB5apUhVYlEauBGSPo12nq84wxWkBx2EM3KDRgkB5Sub2tr0CgmAc2EVjPhKIEzAam26cyUb48bJziz1V6wvW7z4GZAfaJpzLkyHdSfV5117VSf5w1rDcAeZDXfGUaaNEJPWytaF4ZIxVge7f3NGshHy4odFVPADy\/u6c43BWvaOtJ4m3aJQbP6sxCO9dxwcm5yJJJR3n36jfh229sdWBxyl8BhwhH1e1DEv78\/aiL6ckKFPVNzx01R6yDFt3TgEMR97YZ\/R6lWiXG+dsJ305jNFlusLu518zBUvl7g5yjzGN778H29b2C8VLZKmi\/h1CH9jGdD72fCqCYdenD2uZKzb6dsUtXtvBmVcVT6BUGz41W1pkkEEB+YJpMrHILIxAiHRGv1+aZa9\/Oz8LWFd+BEUQjC2LJgojPnpzaG\/msw1nBkX16NNVDWWtJ25Bc\/r\/mG46rwjWB\/cmV6Lwt6KODiqlxgrC4lm9ALOCEWw+23OcYhLwNfQTYevXqHqsFfXOkhUnM8z5vDUb\/HBraB1DjFXN8iLK+1YewD4P495e+SRzrR79Oi3F8SEqRIzRLfN2rnW1BTms\/wYsz0p67cup1Slk1XlNmHwbWX25NVd2PPlLOvZRGoqcKFpIjC5few8THiZfyjiNFwt3RM0AFdZcXY=",
858 858
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----"
859 859
 }';
860
-		$this->fileAccessHelper
861
-			->expects($this->exactly(2))
862
-			->method('file_get_contents')
863
-			->willReturnMap([
864
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
865
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
866
-			]);
867
-
868
-		$expected = [
869
-			'INVALID_HASH' => [
870
-				'AnotherFile.txt' => [
871
-					'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112',
872
-					'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c',
873
-				],
874
-			],
875
-			'FILE_MISSING' => [
876
-				'subfolder/file.txt' => [
877
-					'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b',
878
-					'current' => '',
879
-				],
880
-			],
881
-			'EXTRA_FILE' => [
882
-				'UnecessaryFile' => [
883
-					'expected' => '',
884
-					'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
885
-				],
886
-			],
887
-
888
-		];
889
-		$this->assertSame($expected, $this->checker->verifyCoreSignature());
890
-	}
891
-
892
-	public function testVerifyCoreWithInvalidCertificate(): void {
893
-		$this->serverVersion
894
-			->expects($this->once())
895
-			->method('getChannel')
896
-			->willReturn('stable');
897
-		$this->config
898
-			->expects($this->any())
899
-			->method('getSystemValueBool')
900
-			->with('integrity.check.disabled', false)
901
-			->willReturn(false);
902
-
903
-		$this->environmentHelper
904
-			->expects($this->any())
905
-			->method('getServerRoot')
906
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
907
-		$signatureDataFile = '{
860
+        $this->fileAccessHelper
861
+            ->expects($this->exactly(2))
862
+            ->method('file_get_contents')
863
+            ->willReturnMap([
864
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
865
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
866
+            ]);
867
+
868
+        $expected = [
869
+            'INVALID_HASH' => [
870
+                'AnotherFile.txt' => [
871
+                    'expected' => '1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112',
872
+                    'current' => '7322348ba269c6d5522efe02f424fa3a0da319a7cd9c33142a5afe32a2d9af2da3a411f086fcfc96ff4301ea566f481dba0960c2abeef3594c4d930462f6584c',
873
+                ],
874
+            ],
875
+            'FILE_MISSING' => [
876
+                'subfolder/file.txt' => [
877
+                    'expected' => '410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b',
878
+                    'current' => '',
879
+                ],
880
+            ],
881
+            'EXTRA_FILE' => [
882
+                'UnecessaryFile' => [
883
+                    'expected' => '',
884
+                    'current' => 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
885
+                ],
886
+            ],
887
+
888
+        ];
889
+        $this->assertSame($expected, $this->checker->verifyCoreSignature());
890
+    }
891
+
892
+    public function testVerifyCoreWithInvalidCertificate(): void {
893
+        $this->serverVersion
894
+            ->expects($this->once())
895
+            ->method('getChannel')
896
+            ->willReturn('stable');
897
+        $this->config
898
+            ->expects($this->any())
899
+            ->method('getSystemValueBool')
900
+            ->with('integrity.check.disabled', false)
901
+            ->willReturn(false);
902
+
903
+        $this->environmentHelper
904
+            ->expects($this->any())
905
+            ->method('getServerRoot')
906
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
907
+        $signatureDataFile = '{
908 908
     "hashes": {
909 909
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
910 910
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -912,39 +912,39 @@  discard block
 block discarded – undo
912 912
     "signature": "eXesvDm3pkek12xSwMG10y9suRES79Nye3jYNe5KYq1tTUPqRRNgxmMGAfcUro0zpLeAr2YgHeSMWtglblGOW7pmwGVPZ0O1Y4r1fE6jnep0kW+35PLIaqCorIOnCAtSzDNKBhwd1ow3zW2wC0DFouuEkIO8u5Fw28g8E8dp8zEk1xMblNPy+xtWkmYHrVJ\/dQgun1bYOF2ZFtAzatwndTI\/bGsy1i3Wsl+x6HyWKQdq8y8VObtOqKDH7uERBEpB9DHVyKflj1v1gQuEH6BhaRdATc7ee0MiQdGblraIySwYRdfo2d8i82OVKrenMB3SLwyCvDPyQ9iKpTOnSF52ZBqaqSXKM2N\/RAkweeBFQQCwcHhqxvB0cfbyHcbkOLeCZe\/tsh68IxwTiYgzvLfl7sOZ5arnZbzrPpZmB+hfV2omkoJ1tDwOWz9hEmLLNtfo2OxyUH1m0+XFaC+Gbn4WkVDgf7YZkwUcG+Qoa3oKDNMss8MEyZxewl2iDGZcf402dlidHRprlfmXbAYuVQ08\/a0HxIKYPGh\/nsMGmwnO15CWtFpAbhUA\/D5oRjsIxnvXaMDg0iAFpdu\/5Ffsj7g3EPdBkiQHNYK7YU1RRx609eH0bZyiIYHdUPw7ikLupvrebZmELqi3mqDFO99u4eISlxFJlUbUND3L4BtmWTWrKwI=",
913 913
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUPYoweUxCPqbDW4ntuh7QvgyqSrgwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDIwNloXDTE2MTEwMzIyNDIwNlowDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJui3nDbjOIjxNnthdBZplphujsN6u8K\r\nQ\/62zAuSwzXVp0+3IMgM\/2sepklVE8YfCyVJ5+SUJqnqHoUWVRVfs8jL0wW6nrHM\r\n\/lsscAguWCee4iAdNOqI9kq4+DUau8J45e62XA9mrAo\/8\/NKzFE2y2WduDoQZcm+\r\n8+dwcUUHXw2jl8dfrmvEMYSqTNDdb4rGmQpeV+dr9BLqr+x03U1Q08qCG9j7mSOz\r\ncvJENjOvC5uzAh5LCuCgxqG4o+mPzB0FtNnwoRRu6IsF3Y3KacRqPc30fB\/iXDn5\r\nBPr14uNxTTYWoZJ1F0tZrLzRbXdjJJOC+dnQurTtXWZ8WjPB1BWQYK7fW6t82mkN\r\n2Qe2xen99gs9nX5yY\/sHM3TKSJdM7AVCEv\/emW3gNjkvWTtRlN\/Nc7X2ckNwXcvo\r\n0yi3fSPjzXpDgLbhp1FzrMlHDn1VzmRT3r8wLByWa\/hsxrJDsBzwunMJYhXhmeKb\r\n3wX0tN\/EUJTWBntpwVOIGnRPD51oBoQUOMaEAq\/kz8PgN181bWZkJbRuf+FWkijQ\r\no+HR2lVF1jWXXst5Uc+s9HN81Uly7X4O9MMg0QxT4+wymtGDs6AOkwMi9rgBTrRB\r\n3tLU3XL2UIwRXgmd8cPtTu\/I6Bm7LdyaYtZ3yJTxRewq3nZdWypqBhD8uhpIYVkf\r\no4bxmGkVAQVTAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAKKAX5EHgU1grODnJ0of\r\nspFpgB1K67YvclNUyuU6NQ6zBJx1\/w1RnM7uxLcxiiWj1BbUhwZQ0ojmEHeUyi6O\r\nGrDVajwhTccDMmja3u5adhEncx65\/H+lD85IPRRkS2qBDssMDdJHhZ0uI+40nI7M\r\nMq1kFjl+6wiuqZXqps66DuLbk45g\/ZlrFIrIo3Ix5vj0OVqwT+gO4LYirJK6KgVS\r\nUttbcEsc\/yKU9ThnM8\/n4m2jstZXfzKPgOsJrQcZrFOtpj+CWmBzVElBSPlDT3Nh\r\nHSgOeTFJ8bQBxj2iG5dLA+JZJQKxyJ1gy2ZtxIJ2GyvLtSe8NUSqvfPWOaAKEUV2\r\ngniytnEFLr+PcD+9EGux6jZNuj6HmtWVThTfD5VGFmtlVU2z71ZRYY0kn6J3mmFc\r\nS2ecEcCUwqG5YNLncEUCyZhC2klWql2SHyGctCEyWWY7ikIDjVzYt2EbcFvLNBnP\r\ntybN1TYHRRZxlug00CCoOE9EZfk46FkZpDvU6KmqJRofkNZ5sj+SffyGcwYwNrDH\r\nKqe8m+9lHf3CRTIDeMu8r2xl1I6M6ZZfjabbmVP9Jd6WN4s6f1FlXDWzhlT1N0Qw\r\nGzJj6xB+SPtS3UV05tBlvbfA4e06D5G9uD7Q8ONcINtMS0xsSJ2oo82AqlpvlF\/q\r\noj7YKHsaTVGA+FxBktZHfoxD\r\n-----END CERTIFICATE-----"
914 914
 }';
915
-		$this->fileAccessHelper
916
-			->expects($this->exactly(2))
917
-			->method('file_get_contents')
918
-			->willReturnMap([
919
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
920
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
921
-			]);
922
-
923
-		$expected = [
924
-			'EXCEPTION' => [
925
-				'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
926
-				'message' => 'Certificate is not valid.',
927
-			]
928
-		];
929
-		$this->assertSame($expected, $this->checker->verifyCoreSignature());
930
-	}
931
-
932
-	public function testVerifyCoreWithDifferentScope(): void {
933
-		$this->serverVersion
934
-			->expects($this->once())
935
-			->method('getChannel')
936
-			->willReturn('stable');
937
-		$this->config
938
-			->expects($this->any())
939
-			->method('getSystemValueBool')
940
-			->with('integrity.check.disabled', false)
941
-			->willReturn(false);
942
-
943
-		$this->environmentHelper
944
-			->expects($this->any())
945
-			->method('getServerRoot')
946
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
947
-		$signatureDataFile = '{
915
+        $this->fileAccessHelper
916
+            ->expects($this->exactly(2))
917
+            ->method('file_get_contents')
918
+            ->willReturnMap([
919
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
920
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
921
+            ]);
922
+
923
+        $expected = [
924
+            'EXCEPTION' => [
925
+                'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
926
+                'message' => 'Certificate is not valid.',
927
+            ]
928
+        ];
929
+        $this->assertSame($expected, $this->checker->verifyCoreSignature());
930
+    }
931
+
932
+    public function testVerifyCoreWithDifferentScope(): void {
933
+        $this->serverVersion
934
+            ->expects($this->once())
935
+            ->method('getChannel')
936
+            ->willReturn('stable');
937
+        $this->config
938
+            ->expects($this->any())
939
+            ->method('getSystemValueBool')
940
+            ->with('integrity.check.disabled', false)
941
+            ->willReturn(false);
942
+
943
+        $this->environmentHelper
944
+            ->expects($this->any())
945
+            ->method('getServerRoot')
946
+            ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
947
+        $signatureDataFile = '{
948 948
     "hashes": {
949 949
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
950 950
         "subfolder\/file.txt": "410738545fb623c0a5c8a71f561e48ea69e3ada0981a455e920a5ae9bf17c6831ae654df324f9328ff8453de179276ae51931cca0fa71fe8ccde6c083ca0574b"
@@ -952,155 +952,155 @@  discard block
 block discarded – undo
952 952
     "signature": "EL49UaSeyMAqyMtqId+tgOhhwgOevPZsRLX4j2blnybAB6fN07z0936JqZV7+eMPiE30Idx+UCY6rCFN531Kqe9vAOCdgtHUSOjjKyKc+lvULESlMb6YQcrZrvDlEMMjzjH49ewG7Ai8sNN6HrRUd9U8ws+ewSkW2DOOBItj\/21RBnkrSt+2AtGXGigEvuTm57HrCYDj8\/lSkumC2GVkjLUHeLOKYo4PRNOr6yP5mED5v7zo66AWvXl2fKv54InZcdxsAk35lyK9DGZbk\/027ZRd0AOHT3LImRLvQ+8EAg3XLlRUy0hOFGgPC+jYonMzgYvsAXAXi2j8LnLJlsLwpFwu1k1B+kZVPMumKZvP9OvJb70EirecXmz62V+Jiyuaq7ne4y7Kp5gKZT\/T8SeZ0lFtCmPfYyzBB0y8s5ldmTTmdVYHs54t\/OCCW82HzQZxnFNPzDTRa8HglsaMKrqPtW59+R4UvRKSWhB8M\/Ah57qgzycvPV4KMz\/FbD4l\/\/9chRKSlCfc2k3b8ZSHNmi+EzCKgJjWIoKdgN1yax94puU8jfn8UW+G7H9Y1Jsf\/jox6QLyYEgtV1vOHY2xLT7fVs2vhyvkN2MNjJnmQ70gFG5Qz2lBz5wi6ZpB+tOfCcpbLxWAkoWoIrmC\/Ilqh7mfmRZ43g5upjkepHNd93ONuY8=",
953 953
     "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----"
954 954
 }';
955
-		$this->fileAccessHelper
956
-			->expects($this->exactly(2))
957
-			->method('file_get_contents')
958
-			->willReturnMap([
959
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
960
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
961
-			]);
962
-
963
-		$expected = [
964
-			'EXCEPTION' => [
965
-				'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
966
-				'message' => 'Certificate is not valid for required scope. (Requested: core, current: CN=SomeApp)',
967
-			]
968
-		];
969
-		$this->assertSame($expected, $this->checker->verifyCoreSignature());
970
-	}
971
-
972
-	public function testRunInstanceVerification(): void {
973
-		$this->checker = $this->getMockBuilder('\OC\IntegrityCheck\Checker')
974
-			->setConstructorArgs([
975
-				$this->serverVersion,
976
-				$this->environmentHelper,
977
-				$this->fileAccessHelper,
978
-				$this->appLocator,
979
-				$this->config,
980
-				$this->appConfig,
981
-				$this->cacheFactory,
982
-				$this->appManager,
983
-				$this->mimeTypeDetector,
984
-			])
985
-			->onlyMethods([
986
-				'verifyCoreSignature',
987
-				'verifyAppSignature',
988
-			])
989
-			->getMock();
990
-
991
-		$this->checker
992
-			->expects($this->once())
993
-			->method('verifyCoreSignature');
994
-		$this->appManager
995
-			->expects($this->once())
996
-			->method('getAllAppsInAppsFolders')
997
-			->willReturn([
998
-				'files',
999
-				'calendar',
1000
-				'contacts',
1001
-				'dav',
1002
-			]);
1003
-		$this->appManager
1004
-			->expects($this->exactly(4))
1005
-			->method('isShipped')
1006
-			->willReturnMap([
1007
-				['files', true],
1008
-				['calendar', false],
1009
-				['contacts', false],
1010
-				['dav', true],
1011
-			]);
1012
-
1013
-		$calls = [
1014
-			'files',
1015
-			'calendar',
1016
-			'dav',
1017
-		];
1018
-		$this->checker
1019
-			->expects($this->exactly(3))
1020
-			->method('verifyAppSignature')
1021
-			->willReturnCallback(function ($app) use (&$calls) {
1022
-				$expected = array_shift($calls);
1023
-				$this->assertSame($expected, $app);
1024
-				return [];
1025
-			});
1026
-		$this->appLocator
1027
-			->expects($this->exactly(2))
1028
-			->method('getAppPath')
1029
-			->willReturnMap([
1030
-				['calendar', '/apps/calendar'],
1031
-				['contacts', '/apps/contacts'],
1032
-			]);
1033
-		$this->fileAccessHelper
1034
-			->expects($this->exactly(2))
1035
-			->method('file_exists')
1036
-			->willReturnMap([
1037
-				['/apps/calendar/appinfo/signature.json', true],
1038
-				['/apps/contacts/appinfo/signature.json', false],
1039
-			]);
1040
-		$this->appConfig
1041
-			->expects($this->once())
1042
-			->method('deleteKey')
1043
-			->with('core', 'oc.integritycheck.checker');
1044
-
1045
-		$this->checker->runInstanceVerification();
1046
-	}
1047
-
1048
-	public function testVerifyAppSignatureWithoutSignatureDataAndCodeCheckerDisabled(): void {
1049
-		$this->serverVersion
1050
-			->expects($this->once())
1051
-			->method('getChannel')
1052
-			->willReturn('stable');
1053
-		$this->config
1054
-			->expects($this->any())
1055
-			->method('getSystemValueBool')
1056
-			->with('integrity.check.disabled', false)
1057
-			->willReturn(true);
1058
-
1059
-		$expected = [];
1060
-		$this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
1061
-	}
1062
-
1063
-	public static function channelDataProvider(): array {
1064
-		return [
1065
-			['stable', true],
1066
-			['git', false],
1067
-		];
1068
-	}
1069
-
1070
-	/**
1071
-	 * @param string $channel
1072
-	 * @param bool $isCodeSigningEnforced
1073
-	 * @dataProvider channelDataProvider
1074
-	 */
1075
-	public function testIsCodeCheckEnforced($channel, $isCodeSigningEnforced): void {
1076
-		$this->serverVersion
1077
-			->expects($this->once())
1078
-			->method('getChannel')
1079
-			->willReturn($channel);
1080
-		$this->config
1081
-			->expects($this->any())
1082
-			->method('getSystemValueBool')
1083
-			->with('integrity.check.disabled', false)
1084
-			->willReturn(false);
1085
-
1086
-		$this->assertSame($isCodeSigningEnforced, $this->checker->isCodeCheckEnforced());
1087
-	}
1088
-
1089
-	/**
1090
-	 * @param string $channel
1091
-	 * @dataProvider channelDataProvider
1092
-	 */
1093
-	public function testIsCodeCheckEnforcedWithDisabledConfigSwitch($channel): void {
1094
-		$this->serverVersion
1095
-			->expects($this->once())
1096
-			->method('getChannel')
1097
-			->willReturn($channel);
1098
-		$this->config
1099
-			->expects($this->any())
1100
-			->method('getSystemValueBool')
1101
-			->with('integrity.check.disabled', false)
1102
-			->willReturn(true);
1103
-
1104
-		$this->assertFalse(self::invokePrivate($this->checker, 'isCodeCheckEnforced'));
1105
-	}
955
+        $this->fileAccessHelper
956
+            ->expects($this->exactly(2))
957
+            ->method('file_get_contents')
958
+            ->willReturnMap([
959
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
960
+                [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
961
+            ]);
962
+
963
+        $expected = [
964
+            'EXCEPTION' => [
965
+                'class' => 'OC\\IntegrityCheck\\Exceptions\\InvalidSignatureException',
966
+                'message' => 'Certificate is not valid for required scope. (Requested: core, current: CN=SomeApp)',
967
+            ]
968
+        ];
969
+        $this->assertSame($expected, $this->checker->verifyCoreSignature());
970
+    }
971
+
972
+    public function testRunInstanceVerification(): void {
973
+        $this->checker = $this->getMockBuilder('\OC\IntegrityCheck\Checker')
974
+            ->setConstructorArgs([
975
+                $this->serverVersion,
976
+                $this->environmentHelper,
977
+                $this->fileAccessHelper,
978
+                $this->appLocator,
979
+                $this->config,
980
+                $this->appConfig,
981
+                $this->cacheFactory,
982
+                $this->appManager,
983
+                $this->mimeTypeDetector,
984
+            ])
985
+            ->onlyMethods([
986
+                'verifyCoreSignature',
987
+                'verifyAppSignature',
988
+            ])
989
+            ->getMock();
990
+
991
+        $this->checker
992
+            ->expects($this->once())
993
+            ->method('verifyCoreSignature');
994
+        $this->appManager
995
+            ->expects($this->once())
996
+            ->method('getAllAppsInAppsFolders')
997
+            ->willReturn([
998
+                'files',
999
+                'calendar',
1000
+                'contacts',
1001
+                'dav',
1002
+            ]);
1003
+        $this->appManager
1004
+            ->expects($this->exactly(4))
1005
+            ->method('isShipped')
1006
+            ->willReturnMap([
1007
+                ['files', true],
1008
+                ['calendar', false],
1009
+                ['contacts', false],
1010
+                ['dav', true],
1011
+            ]);
1012
+
1013
+        $calls = [
1014
+            'files',
1015
+            'calendar',
1016
+            'dav',
1017
+        ];
1018
+        $this->checker
1019
+            ->expects($this->exactly(3))
1020
+            ->method('verifyAppSignature')
1021
+            ->willReturnCallback(function ($app) use (&$calls) {
1022
+                $expected = array_shift($calls);
1023
+                $this->assertSame($expected, $app);
1024
+                return [];
1025
+            });
1026
+        $this->appLocator
1027
+            ->expects($this->exactly(2))
1028
+            ->method('getAppPath')
1029
+            ->willReturnMap([
1030
+                ['calendar', '/apps/calendar'],
1031
+                ['contacts', '/apps/contacts'],
1032
+            ]);
1033
+        $this->fileAccessHelper
1034
+            ->expects($this->exactly(2))
1035
+            ->method('file_exists')
1036
+            ->willReturnMap([
1037
+                ['/apps/calendar/appinfo/signature.json', true],
1038
+                ['/apps/contacts/appinfo/signature.json', false],
1039
+            ]);
1040
+        $this->appConfig
1041
+            ->expects($this->once())
1042
+            ->method('deleteKey')
1043
+            ->with('core', 'oc.integritycheck.checker');
1044
+
1045
+        $this->checker->runInstanceVerification();
1046
+    }
1047
+
1048
+    public function testVerifyAppSignatureWithoutSignatureDataAndCodeCheckerDisabled(): void {
1049
+        $this->serverVersion
1050
+            ->expects($this->once())
1051
+            ->method('getChannel')
1052
+            ->willReturn('stable');
1053
+        $this->config
1054
+            ->expects($this->any())
1055
+            ->method('getSystemValueBool')
1056
+            ->with('integrity.check.disabled', false)
1057
+            ->willReturn(true);
1058
+
1059
+        $expected = [];
1060
+        $this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp'));
1061
+    }
1062
+
1063
+    public static function channelDataProvider(): array {
1064
+        return [
1065
+            ['stable', true],
1066
+            ['git', false],
1067
+        ];
1068
+    }
1069
+
1070
+    /**
1071
+     * @param string $channel
1072
+     * @param bool $isCodeSigningEnforced
1073
+     * @dataProvider channelDataProvider
1074
+     */
1075
+    public function testIsCodeCheckEnforced($channel, $isCodeSigningEnforced): void {
1076
+        $this->serverVersion
1077
+            ->expects($this->once())
1078
+            ->method('getChannel')
1079
+            ->willReturn($channel);
1080
+        $this->config
1081
+            ->expects($this->any())
1082
+            ->method('getSystemValueBool')
1083
+            ->with('integrity.check.disabled', false)
1084
+            ->willReturn(false);
1085
+
1086
+        $this->assertSame($isCodeSigningEnforced, $this->checker->isCodeCheckEnforced());
1087
+    }
1088
+
1089
+    /**
1090
+     * @param string $channel
1091
+     * @dataProvider channelDataProvider
1092
+     */
1093
+    public function testIsCodeCheckEnforcedWithDisabledConfigSwitch($channel): void {
1094
+        $this->serverVersion
1095
+            ->expects($this->once())
1096
+            ->method('getChannel')
1097
+            ->willReturn($channel);
1098
+        $this->config
1099
+            ->expects($this->any())
1100
+            ->method('getSystemValueBool')
1101
+            ->with('integrity.check.disabled', false)
1102
+            ->willReturn(true);
1103
+
1104
+        $this->assertFalse(self::invokePrivate($this->checker, 'isCodeCheckEnforced'));
1105
+    }
1106 1106
 }
Please login to merge, or discard this patch.
Spacing   +85 added lines, -85 removed lines patch added patch discarded remove patch
@@ -94,8 +94,8 @@  discard block
 block discarded – undo
94 94
 			->with('NotExistingApp/appinfo')
95 95
 			->willReturn(true);
96 96
 
97
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
98
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
97
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt');
98
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key');
99 99
 		$rsa = new RSA();
100 100
 		$rsa->loadKey($rsaPrivateKey);
101 101
 		$x509 = new X509();
@@ -113,13 +113,13 @@  discard block
 block discarded – undo
113 113
 			->method('file_put_contents')
114 114
 			->will($this->throwException(new \Exception('Exception message')));
115 115
 
116
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
117
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
116
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt');
117
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key');
118 118
 		$rsa = new RSA();
119 119
 		$rsa->loadKey($rsaPrivateKey);
120 120
 		$x509 = new X509();
121 121
 		$x509->loadX509($keyBundle);
122
-		$this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa);
122
+		$this->checker->writeAppSignature(\OC::$SERVERROOT.'/tests/data/integritycheck/app/', $x509, $rsa);
123 123
 	}
124 124
 
125 125
 	public function testWriteAppSignature(): void {
@@ -135,8 +135,8 @@  discard block
 block discarded – undo
135 135
 			->expects($this->once())
136 136
 			->method('file_put_contents')
137 137
 			->with(
138
-				$this->equalTo(\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'),
139
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
138
+				$this->equalTo(\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json'),
139
+				$this->callback(function($signature) use ($expectedSignatureFileData) {
140 140
 					$expectedArray = json_decode($expectedSignatureFileData, true);
141 141
 					$actualArray = json_decode($signature, true);
142 142
 					$this->assertEquals($expectedArray, $actualArray);
@@ -144,13 +144,13 @@  discard block
 block discarded – undo
144 144
 				})
145 145
 			);
146 146
 
147
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
148
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
147
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt');
148
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key');
149 149
 		$rsa = new RSA();
150 150
 		$rsa->loadKey($rsaPrivateKey);
151 151
 		$x509 = new X509();
152 152
 		$x509->loadX509($keyBundle);
153
-		$this->checker->writeAppSignature(\OC::$SERVERROOT . '/tests/data/integritycheck/app/', $x509, $rsa);
153
+		$this->checker->writeAppSignature(\OC::$SERVERROOT.'/tests/data/integritycheck/app/', $x509, $rsa);
154 154
 	}
155 155
 
156 156
 	public function testVerifyAppSignatureWithoutSignatureData(): void {
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
 			->expects($this->once())
189 189
 			->method('getAppPath')
190 190
 			->with('SomeApp')
191
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
191
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
192 192
 		$signatureDataFile = '{
193 193
     "hashes": {
194 194
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -201,8 +201,8 @@  discard block
 block discarded – undo
201 201
 			->expects($this->exactly(2))
202 202
 			->method('file_get_contents')
203 203
 			->willReturnMap([
204
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
205
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
204
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
205
+				['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
206 206
 			]);
207 207
 
208 208
 		$this->assertSame([], $this->checker->verifyAppSignature('SomeApp'));
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
 			->expects($this->once())
224 224
 			->method('getAppPath')
225 225
 			->with('SomeApp')
226
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
226
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
227 227
 		$signatureDataFile = '{
228 228
     "hashes": {
229 229
         "AnotherFile.txt": "tampered",
@@ -236,8 +236,8 @@  discard block
 block discarded – undo
236 236
 			->expects($this->exactly(2))
237 237
 			->method('file_get_contents')
238 238
 			->willReturnMap([
239
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
240
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
239
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
240
+				['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
241 241
 			]);
242 242
 
243 243
 		$expected = [
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
 			->expects($this->once())
265 265
 			->method('getAppPath')
266 266
 			->with('SomeApp')
267
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
267
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/');
268 268
 		$signatureDataFile = '{
269 269
     "hashes": {
270 270
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -277,8 +277,8 @@  discard block
 block discarded – undo
277 277
 			->expects($this->exactly(2))
278 278
 			->method('file_get_contents')
279 279
 			->willReturnMap([
280
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
281
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
280
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
281
+				['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
282 282
 			]);
283 283
 
284 284
 
@@ -333,8 +333,8 @@  discard block
 block discarded – undo
333 333
 			->expects($this->exactly(2))
334 334
 			->method('file_get_contents')
335 335
 			->willReturnMap([
336
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
337
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
336
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
337
+				['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
338 338
 			]);
339 339
 
340 340
 		$expected = [
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
 			],
359 359
 
360 360
 		];
361
-		$this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/'));
361
+		$this->assertSame($expected, $this->checker->verifyAppSignature('SomeApp', \OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/'));
362 362
 	}
363 363
 
364 364
 	public function testVerifyAppWithDifferentScope(): void {
@@ -376,7 +376,7 @@  discard block
 block discarded – undo
376 376
 			->expects($this->once())
377 377
 			->method('getAppPath')
378 378
 			->with('SomeApp')
379
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
379
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/');
380 380
 		$signatureDataFile = '{
381 381
     "hashes": {
382 382
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -389,8 +389,8 @@  discard block
 block discarded – undo
389 389
 			->expects($this->exactly(2))
390 390
 			->method('file_get_contents')
391 391
 			->willReturnMap([
392
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
393
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
392
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json', $signatureDataFile],
393
+				['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
394 394
 			]);
395 395
 
396 396
 		$expected = [
@@ -417,7 +417,7 @@  discard block
 block discarded – undo
417 417
 			->expects($this->once())
418 418
 			->method('getAppPath')
419 419
 			->with('SomeApp')
420
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
420
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
421 421
 		$signatureDataFile = '{
422 422
     "hashes": {
423 423
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -430,8 +430,8 @@  discard block
 block discarded – undo
430 430
 			->expects($this->exactly(2))
431 431
 			->method('file_get_contents')
432 432
 			->willReturnMap([
433
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
434
-				['/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
433
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//appinfo/signature.json', $signatureDataFile],
434
+				['/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
435 435
 			]);
436 436
 
437 437
 		$this->assertSame([], $this->checker->verifyAppSignature('SomeApp'));
@@ -449,11 +449,11 @@  discard block
 block discarded – undo
449 449
 		$this->fileAccessHelper
450 450
 			->expects($this->once())
451 451
 			->method('is_writable')
452
-			->with(__DIR__ . '/core')
452
+			->with(__DIR__.'/core')
453 453
 			->willReturn(true);
454 454
 
455
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
456
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
455
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt');
456
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key');
457 457
 		$rsa = new RSA();
458 458
 		$rsa->loadKey($rsaPrivateKey);
459 459
 		$x509 = new X509();
@@ -473,11 +473,11 @@  discard block
 block discarded – undo
473 473
 		$this->fileAccessHelper
474 474
 			->expects($this->once())
475 475
 			->method('is_writable')
476
-			->with(__DIR__ . '/core')
476
+			->with(__DIR__.'/core')
477 477
 			->willReturn(false);
478 478
 
479
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.crt');
480
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/SomeApp.key');
479
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.crt');
480
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/SomeApp.key');
481 481
 		$rsa = new RSA();
482 482
 		$rsa->loadKey($rsaPrivateKey);
483 483
 		$x509 = new X509();
@@ -497,13 +497,13 @@  discard block
 block discarded – undo
497 497
 		$this->environmentHelper
498 498
 			->expects($this->any())
499 499
 			->method('getServerRoot')
500
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
500
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
501 501
 		$this->fileAccessHelper
502 502
 			->expects($this->once())
503 503
 			->method('file_put_contents')
504 504
 			->with(
505
-				\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json',
506
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
505
+				\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json',
506
+				$this->callback(function($signature) use ($expectedSignatureFileData) {
507 507
 					$expectedArray = json_decode($expectedSignatureFileData, true);
508 508
 					$actualArray = json_decode($signature, true);
509 509
 					$this->assertEquals($expectedArray, $actualArray);
@@ -511,13 +511,13 @@  discard block
 block discarded – undo
511 511
 				})
512 512
 			);
513 513
 
514
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
515
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
514
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt');
515
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key');
516 516
 		$rsa = new RSA();
517 517
 		$rsa->loadKey($rsaPrivateKey);
518 518
 		$x509 = new X509();
519 519
 		$x509->loadX509($keyBundle);
520
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/app/');
520
+		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/app/');
521 521
 	}
522 522
 
523 523
 	public function testWriteCoreSignatureWithUnmodifiedHtaccess(): void {
@@ -532,13 +532,13 @@  discard block
 block discarded – undo
532 532
 		$this->environmentHelper
533 533
 			->expects($this->any())
534 534
 			->method('getServerRoot')
535
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/');
535
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessUnmodified/');
536 536
 		$this->fileAccessHelper
537 537
 			->expects($this->once())
538 538
 			->method('file_put_contents')
539 539
 			->with(
540
-				\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified//core/signature.json',
541
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
540
+				\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessUnmodified//core/signature.json',
541
+				$this->callback(function($signature) use ($expectedSignatureFileData) {
542 542
 					$expectedArray = json_decode($expectedSignatureFileData, true);
543 543
 					$actualArray = json_decode($signature, true);
544 544
 					$this->assertEquals($expectedArray, $actualArray);
@@ -546,13 +546,13 @@  discard block
 block discarded – undo
546 546
 				})
547 547
 			);
548 548
 
549
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
550
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
549
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt');
550
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key');
551 551
 		$rsa = new RSA();
552 552
 		$rsa->loadKey($rsaPrivateKey);
553 553
 		$x509 = new X509();
554 554
 		$x509->loadX509($keyBundle);
555
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessUnmodified/');
555
+		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessUnmodified/');
556 556
 	}
557 557
 
558 558
 	public function testWriteCoreSignatureWithInvalidModifiedHtaccess(): void {
@@ -567,8 +567,8 @@  discard block
 block discarded – undo
567 567
 			->expects($this->once())
568 568
 			->method('file_put_contents')
569 569
 			->with(
570
-				\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json',
571
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
570
+				\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithInvalidModifiedContent//core/signature.json',
571
+				$this->callback(function($signature) use ($expectedSignatureFileData) {
572 572
 					$expectedArray = json_decode($expectedSignatureFileData, true);
573 573
 					$actualArray = json_decode($signature, true);
574 574
 					$this->assertEquals($expectedArray, $actualArray);
@@ -576,13 +576,13 @@  discard block
 block discarded – undo
576 576
 				})
577 577
 			);
578 578
 
579
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
580
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
579
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt');
580
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key');
581 581
 		$rsa = new RSA();
582 582
 		$rsa->loadKey($rsaPrivateKey);
583 583
 		$x509 = new X509();
584 584
 		$x509->loadX509($keyBundle);
585
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithInvalidModifiedContent/');
585
+		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithInvalidModifiedContent/');
586 586
 	}
587 587
 
588 588
 	public function testWriteCoreSignatureWithValidModifiedHtaccess(): void {
@@ -597,13 +597,13 @@  discard block
 block discarded – undo
597 597
 		$this->environmentHelper
598 598
 			->expects($this->any())
599 599
 			->method('getServerRoot')
600
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
600
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent');
601 601
 		$this->fileAccessHelper
602 602
 			->expects($this->once())
603 603
 			->method('file_put_contents')
604 604
 			->with(
605
-				\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json',
606
-				$this->callback(function ($signature) use ($expectedSignatureFileData) {
605
+				\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json',
606
+				$this->callback(function($signature) use ($expectedSignatureFileData) {
607 607
 					$expectedArray = json_decode($expectedSignatureFileData, true);
608 608
 					$actualArray = json_decode($signature, true);
609 609
 					$this->assertEquals($expectedArray, $actualArray);
@@ -611,13 +611,13 @@  discard block
 block discarded – undo
611 611
 				})
612 612
 			);
613 613
 
614
-		$keyBundle = file_get_contents(__DIR__ . '/../../data/integritycheck/core.crt');
615
-		$rsaPrivateKey = file_get_contents(__DIR__ . '/../../data/integritycheck/core.key');
614
+		$keyBundle = file_get_contents(__DIR__.'/../../data/integritycheck/core.crt');
615
+		$rsaPrivateKey = file_get_contents(__DIR__.'/../../data/integritycheck/core.key');
616 616
 		$rsa = new RSA();
617 617
 		$rsa->loadKey($rsaPrivateKey);
618 618
 		$x509 = new X509();
619 619
 		$x509->loadX509($keyBundle);
620
-		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
620
+		$this->checker->writeCoreSignature($x509, $rsa, \OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent');
621 621
 	}
622 622
 
623 623
 	public function testVerifyCoreSignatureWithoutSignatureData(): void {
@@ -654,7 +654,7 @@  discard block
 block discarded – undo
654 654
 		$this->environmentHelper
655 655
 			->expects($this->any())
656 656
 			->method('getServerRoot')
657
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
657
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
658 658
 		$signatureDataFile = '{
659 659
     "hashes": {
660 660
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -667,8 +667,8 @@  discard block
 block discarded – undo
667 667
 			->expects($this->exactly(2))
668 668
 			->method('file_get_contents')
669 669
 			->willReturnMap([
670
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
671
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
670
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
671
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
672 672
 			]);
673 673
 
674 674
 		$this->assertSame([], $this->checker->verifyCoreSignature());
@@ -688,7 +688,7 @@  discard block
 block discarded – undo
688 688
 		$this->environmentHelper
689 689
 			->expects($this->any())
690 690
 			->method('getServerRoot')
691
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent');
691
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent');
692 692
 		$signatureDataFile = '{
693 693
     "hashes": {
694 694
         ".htaccess": "7e6a7a4d8ee4f3fbc45dd579407c643471575a9d127d1c75f6d0a49e80766c3c587104b2139ef76d2a4bffce3f45777900605aaa49519c9532909b71e5030227",
@@ -701,8 +701,8 @@  discard block
 block discarded – undo
701 701
 			->expects($this->exactly(2))
702 702
 			->method('file_get_contents')
703 703
 			->willReturnMap([
704
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile],
705
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
704
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json', $signatureDataFile],
705
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
706 706
 			]);
707 707
 
708 708
 		$this->assertSame([], $this->checker->verifyCoreSignature());
@@ -712,7 +712,7 @@  discard block
 block discarded – undo
712 712
 	 * See inline instruction on how to update the test assets when changing mimetypealiases.dist.json
713 713
 	 */
714 714
 	public function testVerifyCoreSignatureWithModifiedMimetypelistSignatureData(): void {
715
-		$shippedMimetypeAliases = (array)json_decode(file_get_contents(\OC::$SERVERROOT . '/resources/config/mimetypealiases.dist.json'));
715
+		$shippedMimetypeAliases = (array) json_decode(file_get_contents(\OC::$SERVERROOT.'/resources/config/mimetypealiases.dist.json'));
716 716
 		$allAliases = array_merge($shippedMimetypeAliases, ['my-custom/mimetype' => 'custom']);
717 717
 
718 718
 		$this->mimeTypeDetector
@@ -732,7 +732,7 @@  discard block
 block discarded – undo
732 732
 		// file_put_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js', $newFile);
733 733
 		// 2. Update signature.json using the following occ command:
734 734
 		// occ integrity:sign-core --privateKey=./tests/data/integritycheck/core.key --certificate=./tests/data/integritycheck/core.crt --path=./tests/data/integritycheck/mimetypeListModified
735
-		self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js'));
735
+		self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js'));
736 736
 
737 737
 		$this->serverVersion
738 738
 			->expects($this->once())
@@ -747,14 +747,14 @@  discard block
 block discarded – undo
747 747
 		$this->environmentHelper
748 748
 			->expects($this->any())
749 749
 			->method('getServerRoot')
750
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified');
750
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified');
751 751
 
752
-		$signatureDataFile = file_get_contents(__DIR__ . '/../../data/integritycheck/mimetypeListModified/core/signature.json');
752
+		$signatureDataFile = file_get_contents(__DIR__.'/../../data/integritycheck/mimetypeListModified/core/signature.json');
753 753
 		$this->fileAccessHelper
754 754
 			->method('file_get_contents')
755 755
 			->willReturnMap([
756
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile],
757
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
756
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile],
757
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
758 758
 			]);
759 759
 
760 760
 		$this->assertSame([], $this->checker->verifyCoreSignature());
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
 		$this->environmentHelper
775 775
 			->expects($this->any())
776 776
 			->method('getServerRoot')
777
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
777
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
778 778
 		$signatureDataFile = '{
779 779
     "hashes": {
780 780
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -787,8 +787,8 @@  discard block
 block discarded – undo
787 787
 			->expects($this->exactly(2))
788 788
 			->method('file_get_contents')
789 789
 			->willReturnMap([
790
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
791
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
790
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
791
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
792 792
 			]);
793 793
 
794 794
 		$this->assertSame([], $this->checker->verifyCoreSignature());
@@ -808,7 +808,7 @@  discard block
 block discarded – undo
808 808
 		$this->environmentHelper
809 809
 			->expects($this->any())
810 810
 			->method('getServerRoot')
811
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
811
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/');
812 812
 		$signatureDataFile = '{
813 813
     "hashes": {
814 814
         "AnotherFile.txt": "tampered",
@@ -821,8 +821,8 @@  discard block
 block discarded – undo
821 821
 			->expects($this->exactly(2))
822 822
 			->method('file_get_contents')
823 823
 			->willReturnMap([
824
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
825
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
824
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
825
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
826 826
 			]);
827 827
 
828 828
 		$expected = [
@@ -848,7 +848,7 @@  discard block
 block discarded – undo
848 848
 		$this->environmentHelper
849 849
 			->expects($this->any())
850 850
 			->method('getServerRoot')
851
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData/');
851
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData/');
852 852
 		$signatureDataFile = '{
853 853
     "hashes": {
854 854
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -861,8 +861,8 @@  discard block
 block discarded – undo
861 861
 			->expects($this->exactly(2))
862 862
 			->method('file_get_contents')
863 863
 			->willReturnMap([
864
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
865
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
864
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//core/signature.json', $signatureDataFile],
865
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
866 866
 			]);
867 867
 
868 868
 		$expected = [
@@ -903,7 +903,7 @@  discard block
 block discarded – undo
903 903
 		$this->environmentHelper
904 904
 			->expects($this->any())
905 905
 			->method('getServerRoot')
906
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
906
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
907 907
 		$signatureDataFile = '{
908 908
     "hashes": {
909 909
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -916,8 +916,8 @@  discard block
 block discarded – undo
916 916
 			->expects($this->exactly(2))
917 917
 			->method('file_get_contents')
918 918
 			->willReturnMap([
919
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
920
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
919
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
920
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
921 921
 			]);
922 922
 
923 923
 		$expected = [
@@ -943,7 +943,7 @@  discard block
 block discarded – undo
943 943
 		$this->environmentHelper
944 944
 			->expects($this->any())
945 945
 			->method('getServerRoot')
946
-			->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/app/');
946
+			->willReturn(\OC::$SERVERROOT.'/tests/data/integritycheck/app/');
947 947
 		$signatureDataFile = '{
948 948
     "hashes": {
949 949
         "AnotherFile.txt": "1570ca9420e37629de4328f48c51da29840ddeaa03ae733da4bf1d854b8364f594aac560601270f9e1797ed4cd57c1aea87bf44cf4245295c94f2e935a2f0112",
@@ -956,8 +956,8 @@  discard block
 block discarded – undo
956 956
 			->expects($this->exactly(2))
957 957
 			->method('file_get_contents')
958 958
 			->willReturnMap([
959
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
960
-				[\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__ . '/../../data/integritycheck/root.crt')],
959
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//core/signature.json', $signatureDataFile],
960
+				[\OC::$SERVERROOT.'/tests/data/integritycheck/app//resources/codesigning/root.crt', file_get_contents(__DIR__.'/../../data/integritycheck/root.crt')],
961 961
 			]);
962 962
 
963 963
 		$expected = [
@@ -1018,7 +1018,7 @@  discard block
 block discarded – undo
1018 1018
 		$this->checker
1019 1019
 			->expects($this->exactly(3))
1020 1020
 			->method('verifyAppSignature')
1021
-			->willReturnCallback(function ($app) use (&$calls) {
1021
+			->willReturnCallback(function($app) use (&$calls) {
1022 1022
 				$expected = array_shift($calls);
1023 1023
 				$this->assertSame($expected, $app);
1024 1024
 				return [];
Please login to merge, or discard this patch.
tests/lib/DirectEditing/ManagerTest.php 1 patch
Indentation   +261 added lines, -261 removed lines patch added patch discarded remove patch
@@ -26,55 +26,55 @@  discard block
 block discarded – undo
26 26
 use Test\TestCase;
27 27
 
28 28
 class CreateEmpty extends ACreateEmpty {
29
-	public function getId(): string {
30
-		return 'createEmpty';
31
-	}
29
+    public function getId(): string {
30
+        return 'createEmpty';
31
+    }
32 32
 
33
-	public function getName(): string {
34
-		return 'create empty file';
35
-	}
33
+    public function getName(): string {
34
+        return 'create empty file';
35
+    }
36 36
 
37
-	public function getExtension(): string {
38
-		return '.txt';
39
-	}
37
+    public function getExtension(): string {
38
+        return '.txt';
39
+    }
40 40
 
41
-	public function getMimetype(): string {
42
-		return 'text/plain';
43
-	}
41
+    public function getMimetype(): string {
42
+        return 'text/plain';
43
+    }
44 44
 }
45 45
 
46 46
 class Editor implements IEditor {
47
-	public function getId(): string {
48
-		return 'testeditor';
49
-	}
47
+    public function getId(): string {
48
+        return 'testeditor';
49
+    }
50 50
 
51
-	public function getName(): string {
52
-		return 'Test editor';
53
-	}
51
+    public function getName(): string {
52
+        return 'Test editor';
53
+    }
54 54
 
55
-	public function getMimetypes(): array {
56
-		return [ 'text/plain' ];
57
-	}
55
+    public function getMimetypes(): array {
56
+        return [ 'text/plain' ];
57
+    }
58 58
 
59 59
 
60
-	public function getMimetypesOptional(): array {
61
-		return [];
62
-	}
60
+    public function getMimetypesOptional(): array {
61
+        return [];
62
+    }
63 63
 
64
-	public function getCreators(): array {
65
-		return [
66
-			new CreateEmpty()
67
-		];
68
-	}
64
+    public function getCreators(): array {
65
+        return [
66
+            new CreateEmpty()
67
+        ];
68
+    }
69 69
 
70
-	public function isSecure(): bool {
71
-		return false;
72
-	}
70
+    public function isSecure(): bool {
71
+        return false;
72
+    }
73 73
 
74 74
 
75
-	public function open(IToken $token): Response {
76
-		return new DataResponse('edit page');
77
-	}
75
+    public function open(IToken $token): Response {
76
+        return new DataResponse('edit page');
77
+    }
78 78
 }
79 79
 
80 80
 /**
@@ -84,230 +84,230 @@  discard block
 block discarded – undo
84 84
  * @group DB
85 85
  */
86 86
 class ManagerTest extends TestCase {
87
-	private $manager;
88
-	/**
89
-	 * @var Editor
90
-	 */
91
-	private $editor;
92
-	/**
93
-	 * @var MockObject|ISecureRandom
94
-	 */
95
-	private $random;
96
-	/**
97
-	 * @var IDBConnection
98
-	 */
99
-	private $connection;
100
-	/**
101
-	 * @var MockObject|IUserSession
102
-	 */
103
-	private $userSession;
104
-	/**
105
-	 * @var MockObject|IRootFolder
106
-	 */
107
-	private $rootFolder;
108
-	/**
109
-	 * @var MockObject|Folder
110
-	 */
111
-	private $userFolder;
112
-	/**
113
-	 * @var MockObject|IL10N
114
-	 */
115
-	private $l10n;
116
-	/**
117
-	 * @var MockObject|IManager
118
-	 */
119
-	private $encryptionManager;
120
-
121
-	protected function setUp(): void {
122
-		parent::setUp();
123
-
124
-		$this->editor = new Editor();
125
-
126
-		$this->random = $this->createMock(ISecureRandom::class);
127
-		$this->connection = \OC::$server->getDatabaseConnection();
128
-		$this->userSession = $this->createMock(IUserSession::class);
129
-		$this->rootFolder = $this->createMock(IRootFolder::class);
130
-		$this->userFolder = $this->createMock(Folder::class);
131
-		$this->l10n = $this->createMock(IL10N::class);
132
-		$this->encryptionManager = $this->createMock(IManager::class);
133
-
134
-		$l10nFactory = $this->createMock(IFactory::class);
135
-		$l10nFactory->expects($this->once())
136
-			->method('get')
137
-			->willReturn($this->l10n);
138
-
139
-
140
-		$this->rootFolder->expects($this->any())
141
-			->method('getUserFolder')
142
-			->willReturn($this->userFolder);
143
-
144
-		$user = $this->createMock(IUser::class);
145
-		$user->expects(self::any())
146
-			->method('getUID')
147
-			->willReturn('admin');
148
-		$this->userSession->expects(self::any())
149
-			->method('getUser')
150
-			->willReturn($user);
151
-
152
-		$this->manager = new Manager(
153
-			$this->random, $this->connection, $this->userSession, $this->rootFolder, $l10nFactory, $this->encryptionManager
154
-		);
155
-
156
-		$this->manager->registerDirectEditor($this->editor);
157
-	}
158
-
159
-	public function testEditorRegistration(): void {
160
-		$this->assertEquals($this->manager->getEditors(), ['testeditor' => $this->editor]);
161
-	}
162
-
163
-
164
-	public function testCreateToken(): void {
165
-		$expectedToken = 'TOKEN' . time();
166
-		$file = $this->createMock(File::class);
167
-		$file->expects($this->any())
168
-			->method('getId')
169
-			->willReturn(123);
170
-		$this->random->expects($this->once())
171
-			->method('generate')
172
-			->willReturn($expectedToken);
173
-		$folder = $this->createMock(Folder::class);
174
-		$this->userFolder
175
-			->method('nodeExists')
176
-			->willReturnMap([
177
-				['/File.txt', false],
178
-				['/', true],
179
-			]);
180
-		$this->userFolder
181
-			->method('get')
182
-			->with('/')
183
-			->willReturn($folder);
184
-		$folder->expects($this->once())
185
-			->method('newFile')
186
-			->willReturn($file);
187
-		$token = $this->manager->create('/File.txt', 'testeditor', 'createEmpty');
188
-		$this->assertEquals($token, $expectedToken);
189
-	}
190
-
191
-	public function testCreateTokenAccess(): void {
192
-		$expectedToken = 'TOKEN' . time();
193
-		$file = $this->createMock(File::class);
194
-		$file->expects($this->any())
195
-			->method('getId')
196
-			->willReturn(123);
197
-		$this->random->expects($this->once())
198
-			->method('generate')
199
-			->willReturn($expectedToken);
200
-		$folder = $this->createMock(Folder::class);
201
-		$this->userFolder
202
-			->method('nodeExists')
203
-			->willReturnMap([
204
-				['/File.txt', false],
205
-				['/', true],
206
-			]);
207
-		$this->userFolder
208
-			->method('get')
209
-			->with('/')
210
-			->willReturn($folder);
211
-		$folder->expects($this->once())
212
-			->method('newFile')
213
-			->willReturn($file);
214
-		$this->manager->create('/File.txt', 'testeditor', 'createEmpty');
215
-		$firstResult = $this->manager->edit($expectedToken);
216
-		$secondResult = $this->manager->edit($expectedToken);
217
-		$this->assertInstanceOf(DataResponse::class, $firstResult);
218
-		$this->assertInstanceOf(NotFoundResponse::class, $secondResult);
219
-	}
220
-
221
-	public function testOpenByPath(): void {
222
-		$expectedToken = 'TOKEN' . time();
223
-		$file = $this->createMock(File::class);
224
-		$file->expects($this->any())
225
-			->method('getId')
226
-			->willReturn(123);
227
-		$file->expects($this->any())
228
-			->method('getPath')
229
-			->willReturn('/admin/files/File.txt');
230
-		$this->random->expects($this->once())
231
-			->method('generate')
232
-			->willReturn($expectedToken);
233
-		$this->userFolder
234
-			->method('nodeExists')
235
-			->willReturnMap([
236
-				['/File.txt', false],
237
-				['/', true],
238
-			]);
239
-		$this->userFolder
240
-			->method('get')
241
-			->with('/File.txt')
242
-			->willReturn($file);
243
-		$this->userFolder
244
-			->method('getRelativePath')
245
-			->willReturn('/File.txt');
246
-		$this->manager->open('/File.txt', 'testeditor');
247
-		$firstResult = $this->manager->edit($expectedToken);
248
-		$secondResult = $this->manager->edit($expectedToken);
249
-		$this->assertInstanceOf(DataResponse::class, $firstResult);
250
-		$this->assertInstanceOf(NotFoundResponse::class, $secondResult);
251
-	}
252
-
253
-	public function testOpenById(): void {
254
-		$expectedToken = 'TOKEN' . time();
255
-		$fileRead = $this->createMock(File::class);
256
-		$fileRead->method('getPermissions')
257
-			->willReturn(1);
258
-		$fileRead->expects($this->any())
259
-			->method('getId')
260
-			->willReturn(123);
261
-		$fileRead->expects($this->any())
262
-			->method('getPath')
263
-			->willReturn('/admin/files/shared_file.txt');
264
-		$file = $this->createMock(File::class);
265
-		$file->method('getPermissions')
266
-			->willReturn(1);
267
-		$file->expects($this->any())
268
-			->method('getId')
269
-			->willReturn(123);
270
-		$file->expects($this->any())
271
-			->method('getPath')
272
-			->willReturn('/admin/files/File.txt');
273
-		$this->random->expects($this->once())
274
-			->method('generate')
275
-			->willReturn($expectedToken);
276
-		$folder = $this->createMock(Folder::class);
277
-		$folder->expects($this->any())
278
-			->method('getById')
279
-			->willReturn([
280
-				$fileRead,
281
-				$file
282
-			]);
283
-		$this->userFolder
284
-			->method('nodeExists')
285
-			->willReturnMap([
286
-				['/File.txt', false],
287
-				['/', true],
288
-			]);
289
-		$this->userFolder
290
-			->method('get')
291
-			->with('/')
292
-			->willReturn($folder);
293
-		$this->userFolder
294
-			->method('getRelativePath')
295
-			->willReturn('/File.txt');
296
-
297
-		$this->manager->open('/', 'testeditor', 123);
298
-		$firstResult = $this->manager->edit($expectedToken);
299
-		$secondResult = $this->manager->edit($expectedToken);
300
-		$this->assertInstanceOf(DataResponse::class, $firstResult);
301
-		$this->assertInstanceOf(NotFoundResponse::class, $secondResult);
302
-	}
303
-
304
-	public function testCreateFileAlreadyExists(): void {
305
-		$this->expectException(\RuntimeException::class);
306
-		$this->userFolder
307
-			->method('nodeExists')
308
-			->with('/File.txt')
309
-			->willReturn(true);
310
-
311
-		$this->manager->create('/File.txt', 'testeditor', 'createEmpty');
312
-	}
87
+    private $manager;
88
+    /**
89
+     * @var Editor
90
+     */
91
+    private $editor;
92
+    /**
93
+     * @var MockObject|ISecureRandom
94
+     */
95
+    private $random;
96
+    /**
97
+     * @var IDBConnection
98
+     */
99
+    private $connection;
100
+    /**
101
+     * @var MockObject|IUserSession
102
+     */
103
+    private $userSession;
104
+    /**
105
+     * @var MockObject|IRootFolder
106
+     */
107
+    private $rootFolder;
108
+    /**
109
+     * @var MockObject|Folder
110
+     */
111
+    private $userFolder;
112
+    /**
113
+     * @var MockObject|IL10N
114
+     */
115
+    private $l10n;
116
+    /**
117
+     * @var MockObject|IManager
118
+     */
119
+    private $encryptionManager;
120
+
121
+    protected function setUp(): void {
122
+        parent::setUp();
123
+
124
+        $this->editor = new Editor();
125
+
126
+        $this->random = $this->createMock(ISecureRandom::class);
127
+        $this->connection = \OC::$server->getDatabaseConnection();
128
+        $this->userSession = $this->createMock(IUserSession::class);
129
+        $this->rootFolder = $this->createMock(IRootFolder::class);
130
+        $this->userFolder = $this->createMock(Folder::class);
131
+        $this->l10n = $this->createMock(IL10N::class);
132
+        $this->encryptionManager = $this->createMock(IManager::class);
133
+
134
+        $l10nFactory = $this->createMock(IFactory::class);
135
+        $l10nFactory->expects($this->once())
136
+            ->method('get')
137
+            ->willReturn($this->l10n);
138
+
139
+
140
+        $this->rootFolder->expects($this->any())
141
+            ->method('getUserFolder')
142
+            ->willReturn($this->userFolder);
143
+
144
+        $user = $this->createMock(IUser::class);
145
+        $user->expects(self::any())
146
+            ->method('getUID')
147
+            ->willReturn('admin');
148
+        $this->userSession->expects(self::any())
149
+            ->method('getUser')
150
+            ->willReturn($user);
151
+
152
+        $this->manager = new Manager(
153
+            $this->random, $this->connection, $this->userSession, $this->rootFolder, $l10nFactory, $this->encryptionManager
154
+        );
155
+
156
+        $this->manager->registerDirectEditor($this->editor);
157
+    }
158
+
159
+    public function testEditorRegistration(): void {
160
+        $this->assertEquals($this->manager->getEditors(), ['testeditor' => $this->editor]);
161
+    }
162
+
163
+
164
+    public function testCreateToken(): void {
165
+        $expectedToken = 'TOKEN' . time();
166
+        $file = $this->createMock(File::class);
167
+        $file->expects($this->any())
168
+            ->method('getId')
169
+            ->willReturn(123);
170
+        $this->random->expects($this->once())
171
+            ->method('generate')
172
+            ->willReturn($expectedToken);
173
+        $folder = $this->createMock(Folder::class);
174
+        $this->userFolder
175
+            ->method('nodeExists')
176
+            ->willReturnMap([
177
+                ['/File.txt', false],
178
+                ['/', true],
179
+            ]);
180
+        $this->userFolder
181
+            ->method('get')
182
+            ->with('/')
183
+            ->willReturn($folder);
184
+        $folder->expects($this->once())
185
+            ->method('newFile')
186
+            ->willReturn($file);
187
+        $token = $this->manager->create('/File.txt', 'testeditor', 'createEmpty');
188
+        $this->assertEquals($token, $expectedToken);
189
+    }
190
+
191
+    public function testCreateTokenAccess(): void {
192
+        $expectedToken = 'TOKEN' . time();
193
+        $file = $this->createMock(File::class);
194
+        $file->expects($this->any())
195
+            ->method('getId')
196
+            ->willReturn(123);
197
+        $this->random->expects($this->once())
198
+            ->method('generate')
199
+            ->willReturn($expectedToken);
200
+        $folder = $this->createMock(Folder::class);
201
+        $this->userFolder
202
+            ->method('nodeExists')
203
+            ->willReturnMap([
204
+                ['/File.txt', false],
205
+                ['/', true],
206
+            ]);
207
+        $this->userFolder
208
+            ->method('get')
209
+            ->with('/')
210
+            ->willReturn($folder);
211
+        $folder->expects($this->once())
212
+            ->method('newFile')
213
+            ->willReturn($file);
214
+        $this->manager->create('/File.txt', 'testeditor', 'createEmpty');
215
+        $firstResult = $this->manager->edit($expectedToken);
216
+        $secondResult = $this->manager->edit($expectedToken);
217
+        $this->assertInstanceOf(DataResponse::class, $firstResult);
218
+        $this->assertInstanceOf(NotFoundResponse::class, $secondResult);
219
+    }
220
+
221
+    public function testOpenByPath(): void {
222
+        $expectedToken = 'TOKEN' . time();
223
+        $file = $this->createMock(File::class);
224
+        $file->expects($this->any())
225
+            ->method('getId')
226
+            ->willReturn(123);
227
+        $file->expects($this->any())
228
+            ->method('getPath')
229
+            ->willReturn('/admin/files/File.txt');
230
+        $this->random->expects($this->once())
231
+            ->method('generate')
232
+            ->willReturn($expectedToken);
233
+        $this->userFolder
234
+            ->method('nodeExists')
235
+            ->willReturnMap([
236
+                ['/File.txt', false],
237
+                ['/', true],
238
+            ]);
239
+        $this->userFolder
240
+            ->method('get')
241
+            ->with('/File.txt')
242
+            ->willReturn($file);
243
+        $this->userFolder
244
+            ->method('getRelativePath')
245
+            ->willReturn('/File.txt');
246
+        $this->manager->open('/File.txt', 'testeditor');
247
+        $firstResult = $this->manager->edit($expectedToken);
248
+        $secondResult = $this->manager->edit($expectedToken);
249
+        $this->assertInstanceOf(DataResponse::class, $firstResult);
250
+        $this->assertInstanceOf(NotFoundResponse::class, $secondResult);
251
+    }
252
+
253
+    public function testOpenById(): void {
254
+        $expectedToken = 'TOKEN' . time();
255
+        $fileRead = $this->createMock(File::class);
256
+        $fileRead->method('getPermissions')
257
+            ->willReturn(1);
258
+        $fileRead->expects($this->any())
259
+            ->method('getId')
260
+            ->willReturn(123);
261
+        $fileRead->expects($this->any())
262
+            ->method('getPath')
263
+            ->willReturn('/admin/files/shared_file.txt');
264
+        $file = $this->createMock(File::class);
265
+        $file->method('getPermissions')
266
+            ->willReturn(1);
267
+        $file->expects($this->any())
268
+            ->method('getId')
269
+            ->willReturn(123);
270
+        $file->expects($this->any())
271
+            ->method('getPath')
272
+            ->willReturn('/admin/files/File.txt');
273
+        $this->random->expects($this->once())
274
+            ->method('generate')
275
+            ->willReturn($expectedToken);
276
+        $folder = $this->createMock(Folder::class);
277
+        $folder->expects($this->any())
278
+            ->method('getById')
279
+            ->willReturn([
280
+                $fileRead,
281
+                $file
282
+            ]);
283
+        $this->userFolder
284
+            ->method('nodeExists')
285
+            ->willReturnMap([
286
+                ['/File.txt', false],
287
+                ['/', true],
288
+            ]);
289
+        $this->userFolder
290
+            ->method('get')
291
+            ->with('/')
292
+            ->willReturn($folder);
293
+        $this->userFolder
294
+            ->method('getRelativePath')
295
+            ->willReturn('/File.txt');
296
+
297
+        $this->manager->open('/', 'testeditor', 123);
298
+        $firstResult = $this->manager->edit($expectedToken);
299
+        $secondResult = $this->manager->edit($expectedToken);
300
+        $this->assertInstanceOf(DataResponse::class, $firstResult);
301
+        $this->assertInstanceOf(NotFoundResponse::class, $secondResult);
302
+    }
303
+
304
+    public function testCreateFileAlreadyExists(): void {
305
+        $this->expectException(\RuntimeException::class);
306
+        $this->userFolder
307
+            ->method('nodeExists')
308
+            ->with('/File.txt')
309
+            ->willReturn(true);
310
+
311
+        $this->manager->create('/File.txt', 'testeditor', 'createEmpty');
312
+    }
313 313
 }
Please login to merge, or discard this patch.
tests/lib/Encryption/Keys/StorageTest.php 2 patches
Indentation   +595 added lines, -595 removed lines patch added patch discarded remove patch
@@ -17,599 +17,599 @@
 block discarded – undo
17 17
 use Test\TestCase;
18 18
 
19 19
 class StorageTest extends TestCase {
20
-	/** @var Storage */
21
-	protected $storage;
22
-
23
-	/** @var MockObject|\OC\Encryption\Util */
24
-	protected $util;
25
-
26
-	/** @var MockObject|View */
27
-	protected $view;
28
-
29
-	/** @var MockObject|IConfig */
30
-	protected $config;
31
-
32
-	/** @var MockObject|ICrypto */
33
-	protected $crypto;
34
-
35
-	private array $mkdirStack = [];
36
-
37
-	protected function setUp(): void {
38
-		parent::setUp();
39
-
40
-		$this->util = $this->getMockBuilder(Util::class)
41
-			->disableOriginalConstructor()
42
-			->onlyMethods(array_diff(get_class_methods(Util::class), ['getFileKeyDir']))
43
-			->getMock();
44
-
45
-		$this->view = $this->getMockBuilder(View::class)
46
-			->disableOriginalConstructor()
47
-			->getMock();
48
-
49
-		$this->crypto = $this->createMock(ICrypto::class);
50
-		$this->crypto->method('encrypt')
51
-			->willReturnCallback(function ($data, $pass) {
52
-				return $data;
53
-			});
54
-		$this->crypto->method('decrypt')
55
-			->willReturnCallback(function ($data, $pass) {
56
-				return $data;
57
-			});
58
-
59
-		$this->config = $this->getMockBuilder(IConfig::class)
60
-			->disableOriginalConstructor()
61
-			->getMock();
62
-
63
-		$this->storage = new Storage($this->view, $this->util, $this->crypto, $this->config);
64
-	}
65
-
66
-	public function testSetFileKey(): void {
67
-		$this->config->method('getSystemValueString')
68
-			->with('version')
69
-			->willReturn('20.0.0.2');
70
-		$this->util->expects($this->any())
71
-			->method('getUidAndFilename')
72
-			->willReturn(['user1', '/files/foo.txt']);
73
-		$this->util->expects($this->any())
74
-			->method('stripPartialFileExtension')
75
-			->willReturnArgument(0);
76
-		$this->util->expects($this->any())
77
-			->method('isSystemWideMountPoint')
78
-			->willReturn(false);
79
-
80
-		$data = json_encode(['key' => base64_encode('key')]);
81
-		$this->view->expects($this->once())
82
-			->method('file_put_contents')
83
-			->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'),
84
-				$this->equalTo($data))
85
-			->willReturn(strlen($data));
86
-
87
-		$this->assertTrue(
88
-			$this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule')
89
-		);
90
-	}
91
-
92
-	public function testSetFileOld(): void {
93
-		$this->config->method('getSystemValueString')
94
-			->with('version')
95
-			->willReturn('20.0.0.0');
96
-		$this->util->expects($this->any())
97
-			->method('getUidAndFilename')
98
-			->willReturn(['user1', '/files/foo.txt']);
99
-		$this->util->expects($this->any())
100
-			->method('stripPartialFileExtension')
101
-			->willReturnArgument(0);
102
-		$this->util->expects($this->any())
103
-			->method('isSystemWideMountPoint')
104
-			->willReturn(false);
105
-		$this->crypto->expects($this->never())
106
-			->method('encrypt');
107
-		$this->view->expects($this->once())
108
-			->method('file_put_contents')
109
-			->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'),
110
-				$this->equalTo('key'))
111
-			->willReturn(strlen('key'));
112
-
113
-		$this->assertTrue(
114
-			$this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule')
115
-		);
116
-	}
117
-
118
-	public static function dataTestGetFileKey() {
119
-		return [
120
-			['/files/foo.txt', '/files/foo.txt', true, 'key'],
121
-			['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', true, 'key'],
122
-			['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', false, 'key2'],
123
-		];
124
-	}
125
-
126
-	/**
127
-	 * @dataProvider dataTestGetFileKey
128
-	 *
129
-	 * @param string $path
130
-	 * @param string $strippedPartialName
131
-	 * @param bool $originalKeyExists
132
-	 * @param string $expectedKeyContent
133
-	 */
134
-	public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent): void {
135
-		$this->config->method('getSystemValueString')
136
-			->with('version')
137
-			->willReturn('20.0.0.2');
138
-		$this->util->expects($this->any())
139
-			->method('getUidAndFilename')
140
-			->willReturnMap([
141
-				['user1/files/foo.txt', ['user1', '/files/foo.txt']],
142
-				['user1/files/foo.txt.ocTransferId2111130212.part', ['user1', '/files/foo.txt.ocTransferId2111130212.part']],
143
-			]);
144
-		// we need to strip away the part file extension in order to reuse a
145
-		// existing key if it exists, otherwise versions will break
146
-		$this->util->expects($this->once())
147
-			->method('stripPartialFileExtension')
148
-			->willReturn('user1' . $strippedPartialName);
149
-		$this->util->expects($this->any())
150
-			->method('isSystemWideMountPoint')
151
-			->willReturn(false);
152
-
153
-		$this->crypto->method('decrypt')
154
-			->willReturnCallback(function ($data, $pass) {
155
-				return $data;
156
-			});
157
-
158
-		if (!$originalKeyExists) {
159
-			$this->view->expects($this->exactly(2))
160
-				->method('file_exists')
161
-				->willReturnMap([
162
-					['/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey', $originalKeyExists],
163
-					['/user1/files_encryption/keys' . $path . '/encModule/fileKey', true],
164
-				]);
165
-
166
-			$this->view->expects($this->once())
167
-				->method('file_get_contents')
168
-				->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey'))
169
-				->willReturn(json_encode(['key' => base64_encode('key2')]));
170
-		} else {
171
-			$this->view->expects($this->once())
172
-				->method('file_exists')
173
-				->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey'))
174
-				->willReturn($originalKeyExists);
175
-
176
-			$this->view->expects($this->once())
177
-				->method('file_get_contents')
178
-				->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey'))
179
-				->willReturn(json_encode(['key' => base64_encode('key')]));
180
-		}
181
-
182
-		$this->assertSame($expectedKeyContent,
183
-			$this->storage->getFileKey('user1' . $path, 'fileKey', 'encModule')
184
-		);
185
-	}
186
-
187
-	public function testSetFileKeySystemWide(): void {
188
-		$this->config->method('getSystemValueString')
189
-			->with('version')
190
-			->willReturn('20.0.0.2');
191
-
192
-		$this->util->expects($this->any())
193
-			->method('getUidAndFilename')
194
-			->willReturn(['user1', '/files/foo.txt']);
195
-		$this->util->expects($this->any())
196
-			->method('isSystemWideMountPoint')
197
-			->willReturn(true);
198
-		$this->util->expects($this->any())
199
-			->method('stripPartialFileExtension')
200
-			->willReturnArgument(0);
201
-
202
-		$this->crypto->method('encrypt')
203
-			->willReturnCallback(function ($data, $pass) {
204
-				return $data;
205
-			});
206
-
207
-		$data = json_encode(['key' => base64_encode('key')]);
208
-		$this->view->expects($this->once())
209
-			->method('file_put_contents')
210
-			->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'),
211
-				$this->equalTo($data))
212
-			->willReturn(strlen($data));
213
-
214
-		$this->assertTrue(
215
-			$this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule')
216
-		);
217
-	}
218
-
219
-	public function testGetFileKeySystemWide(): void {
220
-		$this->config->method('getSystemValueString')
221
-			->with('version')
222
-			->willReturn('20.0.0.2');
223
-
224
-		$this->util->expects($this->any())
225
-			->method('getUidAndFilename')
226
-			->willReturn(['user1', '/files/foo.txt']);
227
-		$this->util->expects($this->any())
228
-			->method('stripPartialFileExtension')
229
-			->willReturnArgument(0);
230
-		$this->util->expects($this->any())
231
-			->method('isSystemWideMountPoint')
232
-			->willReturn(true);
233
-		$this->view->expects($this->once())
234
-			->method('file_get_contents')
235
-			->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
236
-			->willReturn(json_encode(['key' => base64_encode('key')]));
237
-		$this->view->expects($this->once())
238
-			->method('file_exists')
239
-			->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
240
-			->willReturn(true);
241
-
242
-		$this->assertSame('key',
243
-			$this->storage->getFileKey('user1/files/foo.txt', 'fileKey', 'encModule')
244
-		);
245
-	}
246
-
247
-	public function testSetSystemUserKey(): void {
248
-		$this->config->method('getSystemValueString')
249
-			->with('version')
250
-			->willReturn('20.0.0.2');
251
-
252
-		$data = json_encode([
253
-			'key' => base64_encode('key'),
254
-			'uid' => null]
255
-		);
256
-		$this->view->expects($this->once())
257
-			->method('file_put_contents')
258
-			->with($this->equalTo('/files_encryption/encModule/shareKey_56884'),
259
-				$this->equalTo($data))
260
-			->willReturn(strlen($data));
261
-
262
-		$this->assertTrue(
263
-			$this->storage->setSystemUserKey('shareKey_56884', 'key', 'encModule')
264
-		);
265
-	}
266
-
267
-	public function testSetUserKey(): void {
268
-		$this->config->method('getSystemValueString')
269
-			->with('version')
270
-			->willReturn('20.0.0.2');
271
-
272
-		$data = json_encode([
273
-			'key' => base64_encode('key'),
274
-			'uid' => 'user1']
275
-		);
276
-		$this->view->expects($this->once())
277
-			->method('file_put_contents')
278
-			->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'),
279
-				$this->equalTo($data))
280
-			->willReturn(strlen($data));
281
-
282
-		$this->assertTrue(
283
-			$this->storage->setUserKey('user1', 'publicKey', 'key', 'encModule')
284
-		);
285
-	}
286
-
287
-	public function testGetSystemUserKey(): void {
288
-		$this->config->method('getSystemValueString')
289
-			->with('version')
290
-			->willReturn('20.0.0.2');
291
-
292
-		$data = json_encode([
293
-			'key' => base64_encode('key'),
294
-			'uid' => null]
295
-		);
296
-		$this->view->expects($this->once())
297
-			->method('file_get_contents')
298
-			->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
299
-			->willReturn($data);
300
-		$this->view->expects($this->once())
301
-			->method('file_exists')
302
-			->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
303
-			->willReturn(true);
304
-
305
-		$this->assertSame('key',
306
-			$this->storage->getSystemUserKey('shareKey_56884', 'encModule')
307
-		);
308
-	}
309
-
310
-	public function testGetUserKey(): void {
311
-		$this->config->method('getSystemValueString')
312
-			->with('version')
313
-			->willReturn('20.0.0.2');
314
-
315
-		$data = json_encode([
316
-			'key' => base64_encode('key'),
317
-			'uid' => 'user1']
318
-		);
319
-		$this->view->expects($this->once())
320
-			->method('file_get_contents')
321
-			->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
322
-			->willReturn($data);
323
-		$this->view->expects($this->once())
324
-			->method('file_exists')
325
-			->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
326
-			->willReturn(true);
327
-
328
-		$this->assertSame('key',
329
-			$this->storage->getUserKey('user1', 'publicKey', 'encModule')
330
-		);
331
-	}
332
-
333
-	public function testDeleteUserKey(): void {
334
-		$this->view->expects($this->once())
335
-			->method('file_exists')
336
-			->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
337
-			->willReturn(true);
338
-		$this->view->expects($this->once())
339
-			->method('unlink')
340
-			->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
341
-			->willReturn(true);
342
-
343
-		$this->assertTrue(
344
-			$this->storage->deleteUserKey('user1', 'publicKey', 'encModule')
345
-		);
346
-	}
347
-
348
-	public function testDeleteSystemUserKey(): void {
349
-		$this->view->expects($this->once())
350
-			->method('file_exists')
351
-			->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
352
-			->willReturn(true);
353
-		$this->view->expects($this->once())
354
-			->method('unlink')
355
-			->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
356
-			->willReturn(true);
357
-
358
-		$this->assertTrue(
359
-			$this->storage->deleteSystemUserKey('shareKey_56884', 'encModule')
360
-		);
361
-	}
362
-
363
-	public function testDeleteFileKeySystemWide(): void {
364
-		$this->util->expects($this->any())
365
-			->method('getUidAndFilename')
366
-			->willReturn(['user1', '/files/foo.txt']);
367
-		$this->util->expects($this->any())
368
-			->method('stripPartialFileExtension')
369
-			->willReturnArgument(0);
370
-		$this->util->expects($this->any())
371
-			->method('isSystemWideMountPoint')
372
-			->willReturn(true);
373
-		$this->view->expects($this->once())
374
-			->method('file_exists')
375
-			->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
376
-			->willReturn(true);
377
-		$this->view->expects($this->once())
378
-			->method('unlink')
379
-			->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
380
-			->willReturn(true);
381
-
382
-		$this->assertTrue(
383
-			$this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule')
384
-		);
385
-	}
386
-
387
-	public function testDeleteFileKey(): void {
388
-		$this->util->expects($this->any())
389
-			->method('getUidAndFilename')
390
-			->willReturn(['user1', '/files/foo.txt']);
391
-		$this->util->expects($this->any())
392
-			->method('stripPartialFileExtension')
393
-			->willReturnArgument(0);
394
-		$this->util->expects($this->any())
395
-			->method('isSystemWideMountPoint')
396
-			->willReturn(false);
397
-		$this->view->expects($this->once())
398
-			->method('file_exists')
399
-			->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'))
400
-			->willReturn(true);
401
-		$this->view->expects($this->once())
402
-			->method('unlink')
403
-			->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'))
404
-			->willReturn(true);
405
-
406
-		$this->assertTrue(
407
-			$this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule')
408
-		);
409
-	}
410
-
411
-	/**
412
-	 * @dataProvider dataProviderCopyRename
413
-	 */
414
-	public function testRenameKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void {
415
-		$this->view->expects($this->any())
416
-			->method('file_exists')
417
-			->willReturn(true);
418
-		$this->view->expects($this->any())
419
-			->method('is_dir')
420
-			->willReturn(true);
421
-		$this->view->expects($this->once())
422
-			->method('rename')
423
-			->with(
424
-				$this->equalTo($expectedSource),
425
-				$this->equalTo($expectedTarget))
426
-			->willReturn(true);
427
-		$this->util->expects($this->any())
428
-			->method('getUidAndFilename')
429
-			->willReturnCallback([$this, 'getUidAndFilenameCallback']);
430
-		$this->util->expects($this->any())
431
-			->method('isSystemWideMountPoint')
432
-			->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
433
-				if (strpos($path, 'source.txt') !== false) {
434
-					return $systemWideMountSource;
435
-				}
436
-				return $systemWideMountTarget;
437
-			});
438
-
439
-		$this->storage->renameKeys($source, $target);
440
-	}
441
-
442
-	/**
443
-	 * @dataProvider dataProviderCopyRename
444
-	 */
445
-	public function testCopyKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void {
446
-		$this->view->expects($this->any())
447
-			->method('file_exists')
448
-			->willReturn(true);
449
-		$this->view->expects($this->any())
450
-			->method('is_dir')
451
-			->willReturn(true);
452
-		$this->view->expects($this->once())
453
-			->method('copy')
454
-			->with(
455
-				$this->equalTo($expectedSource),
456
-				$this->equalTo($expectedTarget))
457
-			->willReturn(true);
458
-		$this->util->expects($this->any())
459
-			->method('getUidAndFilename')
460
-			->willReturnCallback([$this, 'getUidAndFilenameCallback']);
461
-		$this->util->expects($this->any())
462
-			->method('isSystemWideMountPoint')
463
-			->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
464
-				if (strpos($path, 'source.txt') !== false) {
465
-					return $systemWideMountSource;
466
-				}
467
-				return $systemWideMountTarget;
468
-			});
469
-
470
-		$this->storage->copyKeys($source, $target);
471
-	}
472
-
473
-	public function getUidAndFilenameCallback() {
474
-		$args = func_get_args();
475
-
476
-		$path = $args[0];
477
-		$parts = explode('/', $path);
478
-
479
-		return [$parts[1], '/' . implode('/', array_slice($parts, 2))];
480
-	}
481
-
482
-	public static function dataProviderCopyRename() {
483
-		return [
484
-			['/user1/files/source.txt', '/user1/files/target.txt', false, false,
485
-				'/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
486
-			['/user1/files/foo/source.txt', '/user1/files/target.txt', false, false,
487
-				'/user1/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
488
-			['/user1/files/source.txt', '/user1/files/foo/target.txt', false, false,
489
-				'/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'],
490
-			['/user1/files/source.txt', '/user1/files/foo/target.txt', true, true,
491
-				'/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'],
492
-			['/user1/files/source.txt', '/user1/files/target.txt', false, true,
493
-				'/user1/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'],
494
-			['/user1/files/source.txt', '/user1/files/target.txt', true, false,
495
-				'/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
496
-
497
-			['/user2/files/source.txt', '/user1/files/target.txt', false, false,
498
-				'/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
499
-			['/user2/files/foo/source.txt', '/user1/files/target.txt', false, false,
500
-				'/user2/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
501
-			['/user2/files/source.txt', '/user1/files/foo/target.txt', false, false,
502
-				'/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'],
503
-			['/user2/files/source.txt', '/user1/files/foo/target.txt', true, true,
504
-				'/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'],
505
-			['/user2/files/source.txt', '/user1/files/target.txt', false, true,
506
-				'/user2/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'],
507
-			['/user2/files/source.txt', '/user1/files/target.txt', true, false,
508
-				'/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
509
-		];
510
-	}
511
-
512
-	/**
513
-	 * @dataProvider dataTestGetPathToKeys
514
-	 *
515
-	 * @param string $path
516
-	 * @param boolean $systemWideMountPoint
517
-	 * @param string $storageRoot
518
-	 * @param string $expected
519
-	 */
520
-	public function testGetPathToKeys($path, $systemWideMountPoint, $storageRoot, $expected): void {
521
-		$this->invokePrivate($this->storage, 'root_dir', [$storageRoot]);
522
-
523
-		$this->util->expects($this->any())
524
-			->method('getUidAndFilename')
525
-			->willReturnCallback([$this, 'getUidAndFilenameCallback']);
526
-		$this->util->expects($this->any())
527
-			->method('isSystemWideMountPoint')
528
-			->willReturn($systemWideMountPoint);
529
-
530
-		$this->assertSame($expected,
531
-			self::invokePrivate($this->storage, 'getPathToKeys', [$path])
532
-		);
533
-	}
534
-
535
-	public static function dataTestGetPathToKeys() {
536
-		return [
537
-			['/user1/files/source.txt', false, '', '/user1/files_encryption/keys/files/source.txt/'],
538
-			['/user1/files/source.txt', true, '', '/files_encryption/keys/files/source.txt/'],
539
-			['/user1/files/source.txt', false, 'storageRoot', '/storageRoot/user1/files_encryption/keys/files/source.txt/'],
540
-			['/user1/files/source.txt', true, 'storageRoot', '/storageRoot/files_encryption/keys/files/source.txt/'],
541
-		];
542
-	}
543
-
544
-	public function testKeySetPreparation(): void {
545
-		$this->view->expects($this->any())
546
-			->method('file_exists')
547
-			->willReturn(false);
548
-		$this->view->expects($this->any())
549
-			->method('is_dir')
550
-			->willReturn(false);
551
-		$this->view->expects($this->any())
552
-			->method('mkdir')
553
-			->willReturnCallback([$this, 'mkdirCallback']);
554
-
555
-		$this->mkdirStack = [
556
-			'/user1/files_encryption/keys/foo',
557
-			'/user1/files_encryption/keys',
558
-			'/user1/files_encryption',
559
-			'/user1'];
560
-
561
-		self::invokePrivate($this->storage, 'keySetPreparation', ['/user1/files_encryption/keys/foo']);
562
-	}
563
-
564
-	public function mkdirCallback() {
565
-		$args = func_get_args();
566
-		$expected = array_pop($this->mkdirStack);
567
-		$this->assertSame($expected, $args[0]);
568
-	}
569
-
570
-
571
-	/**
572
-	 * @dataProvider dataTestBackupUserKeys
573
-	 * @param bool $createBackupDir
574
-	 */
575
-	public function testBackupUserKeys($createBackupDir): void {
576
-		$storage = $this->getMockBuilder('OC\Encryption\Keys\Storage')
577
-			->setConstructorArgs([$this->view, $this->util, $this->crypto, $this->config])
578
-			->onlyMethods(['getTimestamp'])
579
-			->getMock();
580
-
581
-		$storage->expects($this->any())->method('getTimestamp')->willReturn('1234567');
582
-
583
-		$this->view->expects($this->once())->method('file_exists')
584
-			->with('user1/files_encryption/backup')->willReturn(!$createBackupDir);
585
-
586
-		if ($createBackupDir) {
587
-			$calls = [
588
-				'user1/files_encryption/backup',
589
-				'user1/files_encryption/backup/test.encryptionModule.1234567',
590
-			];
591
-			$this->view->expects($this->exactly(2))->method('mkdir')
592
-				->willReturnCallback(function ($path) use (&$calls) {
593
-					$expected = array_shift($calls);
594
-					$this->assertEquals($expected, $path);
595
-				});
596
-		} else {
597
-			$this->view->expects($this->once())->method('mkdir')
598
-				->with('user1/files_encryption/backup/test.encryptionModule.1234567');
599
-		}
600
-
601
-		$this->view->expects($this->once())->method('copy')
602
-			->with(
603
-				'user1/files_encryption/encryptionModule',
604
-				'user1/files_encryption/backup/test.encryptionModule.1234567'
605
-			)->willReturn(true);
606
-
607
-		$this->assertTrue($storage->backupUserKeys('encryptionModule', 'test', 'user1'));
608
-	}
609
-
610
-	public static function dataTestBackupUserKeys() {
611
-		return [
612
-			[true], [false]
613
-		];
614
-	}
20
+    /** @var Storage */
21
+    protected $storage;
22
+
23
+    /** @var MockObject|\OC\Encryption\Util */
24
+    protected $util;
25
+
26
+    /** @var MockObject|View */
27
+    protected $view;
28
+
29
+    /** @var MockObject|IConfig */
30
+    protected $config;
31
+
32
+    /** @var MockObject|ICrypto */
33
+    protected $crypto;
34
+
35
+    private array $mkdirStack = [];
36
+
37
+    protected function setUp(): void {
38
+        parent::setUp();
39
+
40
+        $this->util = $this->getMockBuilder(Util::class)
41
+            ->disableOriginalConstructor()
42
+            ->onlyMethods(array_diff(get_class_methods(Util::class), ['getFileKeyDir']))
43
+            ->getMock();
44
+
45
+        $this->view = $this->getMockBuilder(View::class)
46
+            ->disableOriginalConstructor()
47
+            ->getMock();
48
+
49
+        $this->crypto = $this->createMock(ICrypto::class);
50
+        $this->crypto->method('encrypt')
51
+            ->willReturnCallback(function ($data, $pass) {
52
+                return $data;
53
+            });
54
+        $this->crypto->method('decrypt')
55
+            ->willReturnCallback(function ($data, $pass) {
56
+                return $data;
57
+            });
58
+
59
+        $this->config = $this->getMockBuilder(IConfig::class)
60
+            ->disableOriginalConstructor()
61
+            ->getMock();
62
+
63
+        $this->storage = new Storage($this->view, $this->util, $this->crypto, $this->config);
64
+    }
65
+
66
+    public function testSetFileKey(): void {
67
+        $this->config->method('getSystemValueString')
68
+            ->with('version')
69
+            ->willReturn('20.0.0.2');
70
+        $this->util->expects($this->any())
71
+            ->method('getUidAndFilename')
72
+            ->willReturn(['user1', '/files/foo.txt']);
73
+        $this->util->expects($this->any())
74
+            ->method('stripPartialFileExtension')
75
+            ->willReturnArgument(0);
76
+        $this->util->expects($this->any())
77
+            ->method('isSystemWideMountPoint')
78
+            ->willReturn(false);
79
+
80
+        $data = json_encode(['key' => base64_encode('key')]);
81
+        $this->view->expects($this->once())
82
+            ->method('file_put_contents')
83
+            ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'),
84
+                $this->equalTo($data))
85
+            ->willReturn(strlen($data));
86
+
87
+        $this->assertTrue(
88
+            $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule')
89
+        );
90
+    }
91
+
92
+    public function testSetFileOld(): void {
93
+        $this->config->method('getSystemValueString')
94
+            ->with('version')
95
+            ->willReturn('20.0.0.0');
96
+        $this->util->expects($this->any())
97
+            ->method('getUidAndFilename')
98
+            ->willReturn(['user1', '/files/foo.txt']);
99
+        $this->util->expects($this->any())
100
+            ->method('stripPartialFileExtension')
101
+            ->willReturnArgument(0);
102
+        $this->util->expects($this->any())
103
+            ->method('isSystemWideMountPoint')
104
+            ->willReturn(false);
105
+        $this->crypto->expects($this->never())
106
+            ->method('encrypt');
107
+        $this->view->expects($this->once())
108
+            ->method('file_put_contents')
109
+            ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'),
110
+                $this->equalTo('key'))
111
+            ->willReturn(strlen('key'));
112
+
113
+        $this->assertTrue(
114
+            $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule')
115
+        );
116
+    }
117
+
118
+    public static function dataTestGetFileKey() {
119
+        return [
120
+            ['/files/foo.txt', '/files/foo.txt', true, 'key'],
121
+            ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', true, 'key'],
122
+            ['/files/foo.txt.ocTransferId2111130212.part', '/files/foo.txt', false, 'key2'],
123
+        ];
124
+    }
125
+
126
+    /**
127
+     * @dataProvider dataTestGetFileKey
128
+     *
129
+     * @param string $path
130
+     * @param string $strippedPartialName
131
+     * @param bool $originalKeyExists
132
+     * @param string $expectedKeyContent
133
+     */
134
+    public function testGetFileKey($path, $strippedPartialName, $originalKeyExists, $expectedKeyContent): void {
135
+        $this->config->method('getSystemValueString')
136
+            ->with('version')
137
+            ->willReturn('20.0.0.2');
138
+        $this->util->expects($this->any())
139
+            ->method('getUidAndFilename')
140
+            ->willReturnMap([
141
+                ['user1/files/foo.txt', ['user1', '/files/foo.txt']],
142
+                ['user1/files/foo.txt.ocTransferId2111130212.part', ['user1', '/files/foo.txt.ocTransferId2111130212.part']],
143
+            ]);
144
+        // we need to strip away the part file extension in order to reuse a
145
+        // existing key if it exists, otherwise versions will break
146
+        $this->util->expects($this->once())
147
+            ->method('stripPartialFileExtension')
148
+            ->willReturn('user1' . $strippedPartialName);
149
+        $this->util->expects($this->any())
150
+            ->method('isSystemWideMountPoint')
151
+            ->willReturn(false);
152
+
153
+        $this->crypto->method('decrypt')
154
+            ->willReturnCallback(function ($data, $pass) {
155
+                return $data;
156
+            });
157
+
158
+        if (!$originalKeyExists) {
159
+            $this->view->expects($this->exactly(2))
160
+                ->method('file_exists')
161
+                ->willReturnMap([
162
+                    ['/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey', $originalKeyExists],
163
+                    ['/user1/files_encryption/keys' . $path . '/encModule/fileKey', true],
164
+                ]);
165
+
166
+            $this->view->expects($this->once())
167
+                ->method('file_get_contents')
168
+                ->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey'))
169
+                ->willReturn(json_encode(['key' => base64_encode('key2')]));
170
+        } else {
171
+            $this->view->expects($this->once())
172
+                ->method('file_exists')
173
+                ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey'))
174
+                ->willReturn($originalKeyExists);
175
+
176
+            $this->view->expects($this->once())
177
+                ->method('file_get_contents')
178
+                ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey'))
179
+                ->willReturn(json_encode(['key' => base64_encode('key')]));
180
+        }
181
+
182
+        $this->assertSame($expectedKeyContent,
183
+            $this->storage->getFileKey('user1' . $path, 'fileKey', 'encModule')
184
+        );
185
+    }
186
+
187
+    public function testSetFileKeySystemWide(): void {
188
+        $this->config->method('getSystemValueString')
189
+            ->with('version')
190
+            ->willReturn('20.0.0.2');
191
+
192
+        $this->util->expects($this->any())
193
+            ->method('getUidAndFilename')
194
+            ->willReturn(['user1', '/files/foo.txt']);
195
+        $this->util->expects($this->any())
196
+            ->method('isSystemWideMountPoint')
197
+            ->willReturn(true);
198
+        $this->util->expects($this->any())
199
+            ->method('stripPartialFileExtension')
200
+            ->willReturnArgument(0);
201
+
202
+        $this->crypto->method('encrypt')
203
+            ->willReturnCallback(function ($data, $pass) {
204
+                return $data;
205
+            });
206
+
207
+        $data = json_encode(['key' => base64_encode('key')]);
208
+        $this->view->expects($this->once())
209
+            ->method('file_put_contents')
210
+            ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'),
211
+                $this->equalTo($data))
212
+            ->willReturn(strlen($data));
213
+
214
+        $this->assertTrue(
215
+            $this->storage->setFileKey('user1/files/foo.txt', 'fileKey', 'key', 'encModule')
216
+        );
217
+    }
218
+
219
+    public function testGetFileKeySystemWide(): void {
220
+        $this->config->method('getSystemValueString')
221
+            ->with('version')
222
+            ->willReturn('20.0.0.2');
223
+
224
+        $this->util->expects($this->any())
225
+            ->method('getUidAndFilename')
226
+            ->willReturn(['user1', '/files/foo.txt']);
227
+        $this->util->expects($this->any())
228
+            ->method('stripPartialFileExtension')
229
+            ->willReturnArgument(0);
230
+        $this->util->expects($this->any())
231
+            ->method('isSystemWideMountPoint')
232
+            ->willReturn(true);
233
+        $this->view->expects($this->once())
234
+            ->method('file_get_contents')
235
+            ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
236
+            ->willReturn(json_encode(['key' => base64_encode('key')]));
237
+        $this->view->expects($this->once())
238
+            ->method('file_exists')
239
+            ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
240
+            ->willReturn(true);
241
+
242
+        $this->assertSame('key',
243
+            $this->storage->getFileKey('user1/files/foo.txt', 'fileKey', 'encModule')
244
+        );
245
+    }
246
+
247
+    public function testSetSystemUserKey(): void {
248
+        $this->config->method('getSystemValueString')
249
+            ->with('version')
250
+            ->willReturn('20.0.0.2');
251
+
252
+        $data = json_encode([
253
+            'key' => base64_encode('key'),
254
+            'uid' => null]
255
+        );
256
+        $this->view->expects($this->once())
257
+            ->method('file_put_contents')
258
+            ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'),
259
+                $this->equalTo($data))
260
+            ->willReturn(strlen($data));
261
+
262
+        $this->assertTrue(
263
+            $this->storage->setSystemUserKey('shareKey_56884', 'key', 'encModule')
264
+        );
265
+    }
266
+
267
+    public function testSetUserKey(): void {
268
+        $this->config->method('getSystemValueString')
269
+            ->with('version')
270
+            ->willReturn('20.0.0.2');
271
+
272
+        $data = json_encode([
273
+            'key' => base64_encode('key'),
274
+            'uid' => 'user1']
275
+        );
276
+        $this->view->expects($this->once())
277
+            ->method('file_put_contents')
278
+            ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'),
279
+                $this->equalTo($data))
280
+            ->willReturn(strlen($data));
281
+
282
+        $this->assertTrue(
283
+            $this->storage->setUserKey('user1', 'publicKey', 'key', 'encModule')
284
+        );
285
+    }
286
+
287
+    public function testGetSystemUserKey(): void {
288
+        $this->config->method('getSystemValueString')
289
+            ->with('version')
290
+            ->willReturn('20.0.0.2');
291
+
292
+        $data = json_encode([
293
+            'key' => base64_encode('key'),
294
+            'uid' => null]
295
+        );
296
+        $this->view->expects($this->once())
297
+            ->method('file_get_contents')
298
+            ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
299
+            ->willReturn($data);
300
+        $this->view->expects($this->once())
301
+            ->method('file_exists')
302
+            ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
303
+            ->willReturn(true);
304
+
305
+        $this->assertSame('key',
306
+            $this->storage->getSystemUserKey('shareKey_56884', 'encModule')
307
+        );
308
+    }
309
+
310
+    public function testGetUserKey(): void {
311
+        $this->config->method('getSystemValueString')
312
+            ->with('version')
313
+            ->willReturn('20.0.0.2');
314
+
315
+        $data = json_encode([
316
+            'key' => base64_encode('key'),
317
+            'uid' => 'user1']
318
+        );
319
+        $this->view->expects($this->once())
320
+            ->method('file_get_contents')
321
+            ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
322
+            ->willReturn($data);
323
+        $this->view->expects($this->once())
324
+            ->method('file_exists')
325
+            ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
326
+            ->willReturn(true);
327
+
328
+        $this->assertSame('key',
329
+            $this->storage->getUserKey('user1', 'publicKey', 'encModule')
330
+        );
331
+    }
332
+
333
+    public function testDeleteUserKey(): void {
334
+        $this->view->expects($this->once())
335
+            ->method('file_exists')
336
+            ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
337
+            ->willReturn(true);
338
+        $this->view->expects($this->once())
339
+            ->method('unlink')
340
+            ->with($this->equalTo('/user1/files_encryption/encModule/user1.publicKey'))
341
+            ->willReturn(true);
342
+
343
+        $this->assertTrue(
344
+            $this->storage->deleteUserKey('user1', 'publicKey', 'encModule')
345
+        );
346
+    }
347
+
348
+    public function testDeleteSystemUserKey(): void {
349
+        $this->view->expects($this->once())
350
+            ->method('file_exists')
351
+            ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
352
+            ->willReturn(true);
353
+        $this->view->expects($this->once())
354
+            ->method('unlink')
355
+            ->with($this->equalTo('/files_encryption/encModule/shareKey_56884'))
356
+            ->willReturn(true);
357
+
358
+        $this->assertTrue(
359
+            $this->storage->deleteSystemUserKey('shareKey_56884', 'encModule')
360
+        );
361
+    }
362
+
363
+    public function testDeleteFileKeySystemWide(): void {
364
+        $this->util->expects($this->any())
365
+            ->method('getUidAndFilename')
366
+            ->willReturn(['user1', '/files/foo.txt']);
367
+        $this->util->expects($this->any())
368
+            ->method('stripPartialFileExtension')
369
+            ->willReturnArgument(0);
370
+        $this->util->expects($this->any())
371
+            ->method('isSystemWideMountPoint')
372
+            ->willReturn(true);
373
+        $this->view->expects($this->once())
374
+            ->method('file_exists')
375
+            ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
376
+            ->willReturn(true);
377
+        $this->view->expects($this->once())
378
+            ->method('unlink')
379
+            ->with($this->equalTo('/files_encryption/keys/files/foo.txt/encModule/fileKey'))
380
+            ->willReturn(true);
381
+
382
+        $this->assertTrue(
383
+            $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule')
384
+        );
385
+    }
386
+
387
+    public function testDeleteFileKey(): void {
388
+        $this->util->expects($this->any())
389
+            ->method('getUidAndFilename')
390
+            ->willReturn(['user1', '/files/foo.txt']);
391
+        $this->util->expects($this->any())
392
+            ->method('stripPartialFileExtension')
393
+            ->willReturnArgument(0);
394
+        $this->util->expects($this->any())
395
+            ->method('isSystemWideMountPoint')
396
+            ->willReturn(false);
397
+        $this->view->expects($this->once())
398
+            ->method('file_exists')
399
+            ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'))
400
+            ->willReturn(true);
401
+        $this->view->expects($this->once())
402
+            ->method('unlink')
403
+            ->with($this->equalTo('/user1/files_encryption/keys/files/foo.txt/encModule/fileKey'))
404
+            ->willReturn(true);
405
+
406
+        $this->assertTrue(
407
+            $this->storage->deleteFileKey('user1/files/foo.txt', 'fileKey', 'encModule')
408
+        );
409
+    }
410
+
411
+    /**
412
+     * @dataProvider dataProviderCopyRename
413
+     */
414
+    public function testRenameKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void {
415
+        $this->view->expects($this->any())
416
+            ->method('file_exists')
417
+            ->willReturn(true);
418
+        $this->view->expects($this->any())
419
+            ->method('is_dir')
420
+            ->willReturn(true);
421
+        $this->view->expects($this->once())
422
+            ->method('rename')
423
+            ->with(
424
+                $this->equalTo($expectedSource),
425
+                $this->equalTo($expectedTarget))
426
+            ->willReturn(true);
427
+        $this->util->expects($this->any())
428
+            ->method('getUidAndFilename')
429
+            ->willReturnCallback([$this, 'getUidAndFilenameCallback']);
430
+        $this->util->expects($this->any())
431
+            ->method('isSystemWideMountPoint')
432
+            ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
433
+                if (strpos($path, 'source.txt') !== false) {
434
+                    return $systemWideMountSource;
435
+                }
436
+                return $systemWideMountTarget;
437
+            });
438
+
439
+        $this->storage->renameKeys($source, $target);
440
+    }
441
+
442
+    /**
443
+     * @dataProvider dataProviderCopyRename
444
+     */
445
+    public function testCopyKeys($source, $target, $systemWideMountSource, $systemWideMountTarget, $expectedSource, $expectedTarget): void {
446
+        $this->view->expects($this->any())
447
+            ->method('file_exists')
448
+            ->willReturn(true);
449
+        $this->view->expects($this->any())
450
+            ->method('is_dir')
451
+            ->willReturn(true);
452
+        $this->view->expects($this->once())
453
+            ->method('copy')
454
+            ->with(
455
+                $this->equalTo($expectedSource),
456
+                $this->equalTo($expectedTarget))
457
+            ->willReturn(true);
458
+        $this->util->expects($this->any())
459
+            ->method('getUidAndFilename')
460
+            ->willReturnCallback([$this, 'getUidAndFilenameCallback']);
461
+        $this->util->expects($this->any())
462
+            ->method('isSystemWideMountPoint')
463
+            ->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
464
+                if (strpos($path, 'source.txt') !== false) {
465
+                    return $systemWideMountSource;
466
+                }
467
+                return $systemWideMountTarget;
468
+            });
469
+
470
+        $this->storage->copyKeys($source, $target);
471
+    }
472
+
473
+    public function getUidAndFilenameCallback() {
474
+        $args = func_get_args();
475
+
476
+        $path = $args[0];
477
+        $parts = explode('/', $path);
478
+
479
+        return [$parts[1], '/' . implode('/', array_slice($parts, 2))];
480
+    }
481
+
482
+    public static function dataProviderCopyRename() {
483
+        return [
484
+            ['/user1/files/source.txt', '/user1/files/target.txt', false, false,
485
+                '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
486
+            ['/user1/files/foo/source.txt', '/user1/files/target.txt', false, false,
487
+                '/user1/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
488
+            ['/user1/files/source.txt', '/user1/files/foo/target.txt', false, false,
489
+                '/user1/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'],
490
+            ['/user1/files/source.txt', '/user1/files/foo/target.txt', true, true,
491
+                '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'],
492
+            ['/user1/files/source.txt', '/user1/files/target.txt', false, true,
493
+                '/user1/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'],
494
+            ['/user1/files/source.txt', '/user1/files/target.txt', true, false,
495
+                '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
496
+
497
+            ['/user2/files/source.txt', '/user1/files/target.txt', false, false,
498
+                '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
499
+            ['/user2/files/foo/source.txt', '/user1/files/target.txt', false, false,
500
+                '/user2/files_encryption/keys/files/foo/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
501
+            ['/user2/files/source.txt', '/user1/files/foo/target.txt', false, false,
502
+                '/user2/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/foo/target.txt/'],
503
+            ['/user2/files/source.txt', '/user1/files/foo/target.txt', true, true,
504
+                '/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/foo/target.txt/'],
505
+            ['/user2/files/source.txt', '/user1/files/target.txt', false, true,
506
+                '/user2/files_encryption/keys/files/source.txt/', '/files_encryption/keys/files/target.txt/'],
507
+            ['/user2/files/source.txt', '/user1/files/target.txt', true, false,
508
+                '/files_encryption/keys/files/source.txt/', '/user1/files_encryption/keys/files/target.txt/'],
509
+        ];
510
+    }
511
+
512
+    /**
513
+     * @dataProvider dataTestGetPathToKeys
514
+     *
515
+     * @param string $path
516
+     * @param boolean $systemWideMountPoint
517
+     * @param string $storageRoot
518
+     * @param string $expected
519
+     */
520
+    public function testGetPathToKeys($path, $systemWideMountPoint, $storageRoot, $expected): void {
521
+        $this->invokePrivate($this->storage, 'root_dir', [$storageRoot]);
522
+
523
+        $this->util->expects($this->any())
524
+            ->method('getUidAndFilename')
525
+            ->willReturnCallback([$this, 'getUidAndFilenameCallback']);
526
+        $this->util->expects($this->any())
527
+            ->method('isSystemWideMountPoint')
528
+            ->willReturn($systemWideMountPoint);
529
+
530
+        $this->assertSame($expected,
531
+            self::invokePrivate($this->storage, 'getPathToKeys', [$path])
532
+        );
533
+    }
534
+
535
+    public static function dataTestGetPathToKeys() {
536
+        return [
537
+            ['/user1/files/source.txt', false, '', '/user1/files_encryption/keys/files/source.txt/'],
538
+            ['/user1/files/source.txt', true, '', '/files_encryption/keys/files/source.txt/'],
539
+            ['/user1/files/source.txt', false, 'storageRoot', '/storageRoot/user1/files_encryption/keys/files/source.txt/'],
540
+            ['/user1/files/source.txt', true, 'storageRoot', '/storageRoot/files_encryption/keys/files/source.txt/'],
541
+        ];
542
+    }
543
+
544
+    public function testKeySetPreparation(): void {
545
+        $this->view->expects($this->any())
546
+            ->method('file_exists')
547
+            ->willReturn(false);
548
+        $this->view->expects($this->any())
549
+            ->method('is_dir')
550
+            ->willReturn(false);
551
+        $this->view->expects($this->any())
552
+            ->method('mkdir')
553
+            ->willReturnCallback([$this, 'mkdirCallback']);
554
+
555
+        $this->mkdirStack = [
556
+            '/user1/files_encryption/keys/foo',
557
+            '/user1/files_encryption/keys',
558
+            '/user1/files_encryption',
559
+            '/user1'];
560
+
561
+        self::invokePrivate($this->storage, 'keySetPreparation', ['/user1/files_encryption/keys/foo']);
562
+    }
563
+
564
+    public function mkdirCallback() {
565
+        $args = func_get_args();
566
+        $expected = array_pop($this->mkdirStack);
567
+        $this->assertSame($expected, $args[0]);
568
+    }
569
+
570
+
571
+    /**
572
+     * @dataProvider dataTestBackupUserKeys
573
+     * @param bool $createBackupDir
574
+     */
575
+    public function testBackupUserKeys($createBackupDir): void {
576
+        $storage = $this->getMockBuilder('OC\Encryption\Keys\Storage')
577
+            ->setConstructorArgs([$this->view, $this->util, $this->crypto, $this->config])
578
+            ->onlyMethods(['getTimestamp'])
579
+            ->getMock();
580
+
581
+        $storage->expects($this->any())->method('getTimestamp')->willReturn('1234567');
582
+
583
+        $this->view->expects($this->once())->method('file_exists')
584
+            ->with('user1/files_encryption/backup')->willReturn(!$createBackupDir);
585
+
586
+        if ($createBackupDir) {
587
+            $calls = [
588
+                'user1/files_encryption/backup',
589
+                'user1/files_encryption/backup/test.encryptionModule.1234567',
590
+            ];
591
+            $this->view->expects($this->exactly(2))->method('mkdir')
592
+                ->willReturnCallback(function ($path) use (&$calls) {
593
+                    $expected = array_shift($calls);
594
+                    $this->assertEquals($expected, $path);
595
+                });
596
+        } else {
597
+            $this->view->expects($this->once())->method('mkdir')
598
+                ->with('user1/files_encryption/backup/test.encryptionModule.1234567');
599
+        }
600
+
601
+        $this->view->expects($this->once())->method('copy')
602
+            ->with(
603
+                'user1/files_encryption/encryptionModule',
604
+                'user1/files_encryption/backup/test.encryptionModule.1234567'
605
+            )->willReturn(true);
606
+
607
+        $this->assertTrue($storage->backupUserKeys('encryptionModule', 'test', 'user1'));
608
+    }
609
+
610
+    public static function dataTestBackupUserKeys() {
611
+        return [
612
+            [true], [false]
613
+        ];
614
+    }
615 615
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -48,11 +48,11 @@  discard block
 block discarded – undo
48 48
 
49 49
 		$this->crypto = $this->createMock(ICrypto::class);
50 50
 		$this->crypto->method('encrypt')
51
-			->willReturnCallback(function ($data, $pass) {
51
+			->willReturnCallback(function($data, $pass) {
52 52
 				return $data;
53 53
 			});
54 54
 		$this->crypto->method('decrypt')
55
-			->willReturnCallback(function ($data, $pass) {
55
+			->willReturnCallback(function($data, $pass) {
56 56
 				return $data;
57 57
 			});
58 58
 
@@ -145,13 +145,13 @@  discard block
 block discarded – undo
145 145
 		// existing key if it exists, otherwise versions will break
146 146
 		$this->util->expects($this->once())
147 147
 			->method('stripPartialFileExtension')
148
-			->willReturn('user1' . $strippedPartialName);
148
+			->willReturn('user1'.$strippedPartialName);
149 149
 		$this->util->expects($this->any())
150 150
 			->method('isSystemWideMountPoint')
151 151
 			->willReturn(false);
152 152
 
153 153
 		$this->crypto->method('decrypt')
154
-			->willReturnCallback(function ($data, $pass) {
154
+			->willReturnCallback(function($data, $pass) {
155 155
 				return $data;
156 156
 			});
157 157
 
@@ -159,28 +159,28 @@  discard block
 block discarded – undo
159 159
 			$this->view->expects($this->exactly(2))
160 160
 				->method('file_exists')
161 161
 				->willReturnMap([
162
-					['/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey', $originalKeyExists],
163
-					['/user1/files_encryption/keys' . $path . '/encModule/fileKey', true],
162
+					['/user1/files_encryption/keys'.$strippedPartialName.'/encModule/fileKey', $originalKeyExists],
163
+					['/user1/files_encryption/keys'.$path.'/encModule/fileKey', true],
164 164
 				]);
165 165
 
166 166
 			$this->view->expects($this->once())
167 167
 				->method('file_get_contents')
168
-				->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey'))
168
+				->with($this->equalTo('/user1/files_encryption/keys'.$path.'/encModule/fileKey'))
169 169
 				->willReturn(json_encode(['key' => base64_encode('key2')]));
170 170
 		} else {
171 171
 			$this->view->expects($this->once())
172 172
 				->method('file_exists')
173
-				->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey'))
173
+				->with($this->equalTo('/user1/files_encryption/keys'.$strippedPartialName.'/encModule/fileKey'))
174 174
 				->willReturn($originalKeyExists);
175 175
 
176 176
 			$this->view->expects($this->once())
177 177
 				->method('file_get_contents')
178
-				->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey'))
178
+				->with($this->equalTo('/user1/files_encryption/keys'.$strippedPartialName.'/encModule/fileKey'))
179 179
 				->willReturn(json_encode(['key' => base64_encode('key')]));
180 180
 		}
181 181
 
182 182
 		$this->assertSame($expectedKeyContent,
183
-			$this->storage->getFileKey('user1' . $path, 'fileKey', 'encModule')
183
+			$this->storage->getFileKey('user1'.$path, 'fileKey', 'encModule')
184 184
 		);
185 185
 	}
186 186
 
@@ -200,7 +200,7 @@  discard block
 block discarded – undo
200 200
 			->willReturnArgument(0);
201 201
 
202 202
 		$this->crypto->method('encrypt')
203
-			->willReturnCallback(function ($data, $pass) {
203
+			->willReturnCallback(function($data, $pass) {
204 204
 				return $data;
205 205
 			});
206 206
 
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
 			->willReturnCallback([$this, 'getUidAndFilenameCallback']);
430 430
 		$this->util->expects($this->any())
431 431
 			->method('isSystemWideMountPoint')
432
-			->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
432
+			->willReturnCallback(function($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
433 433
 				if (strpos($path, 'source.txt') !== false) {
434 434
 					return $systemWideMountSource;
435 435
 				}
@@ -460,7 +460,7 @@  discard block
 block discarded – undo
460 460
 			->willReturnCallback([$this, 'getUidAndFilenameCallback']);
461 461
 		$this->util->expects($this->any())
462 462
 			->method('isSystemWideMountPoint')
463
-			->willReturnCallback(function ($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
463
+			->willReturnCallback(function($path, $owner) use ($systemWideMountSource, $systemWideMountTarget) {
464 464
 				if (strpos($path, 'source.txt') !== false) {
465 465
 					return $systemWideMountSource;
466 466
 				}
@@ -476,7 +476,7 @@  discard block
 block discarded – undo
476 476
 		$path = $args[0];
477 477
 		$parts = explode('/', $path);
478 478
 
479
-		return [$parts[1], '/' . implode('/', array_slice($parts, 2))];
479
+		return [$parts[1], '/'.implode('/', array_slice($parts, 2))];
480 480
 	}
481 481
 
482 482
 	public static function dataProviderCopyRename() {
@@ -589,7 +589,7 @@  discard block
 block discarded – undo
589 589
 				'user1/files_encryption/backup/test.encryptionModule.1234567',
590 590
 			];
591 591
 			$this->view->expects($this->exactly(2))->method('mkdir')
592
-				->willReturnCallback(function ($path) use (&$calls) {
592
+				->willReturnCallback(function($path) use (&$calls) {
593 593
 					$expected = array_shift($calls);
594 594
 					$this->assertEquals($expected, $path);
595 595
 				});
Please login to merge, or discard this patch.
tests/lib/Encryption/DecryptAllTest.php 2 patches
Indentation   +375 added lines, -375 removed lines patch added patch discarded remove patch
@@ -29,379 +29,379 @@
 block discarded – undo
29 29
  * @package Test\Encryption
30 30
  */
31 31
 class DecryptAllTest extends TestCase {
32
-	/** @var \PHPUnit\Framework\MockObject\MockObject | IUserManager */
33
-	protected $userManager;
34
-
35
-	/** @var \PHPUnit\Framework\MockObject\MockObject | Manager */
36
-	protected $encryptionManager;
37
-
38
-	/** @var \PHPUnit\Framework\MockObject\MockObject | View */
39
-	protected $view;
40
-
41
-	/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */
42
-	protected $inputInterface;
43
-
44
-	/** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */
45
-	protected $outputInterface;
46
-
47
-	/** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\UserInterface */
48
-	protected $userInterface;
49
-
50
-	/** @var DecryptAll */
51
-	protected $instance;
52
-
53
-	protected function setUp(): void {
54
-		parent::setUp();
55
-
56
-		$this->userManager = $this->getMockBuilder(IUserManager::class)
57
-			->disableOriginalConstructor()->getMock();
58
-		$this->encryptionManager = $this->getMockBuilder('OC\Encryption\Manager')
59
-			->disableOriginalConstructor()->getMock();
60
-		$this->view = $this->getMockBuilder(View::class)
61
-			->disableOriginalConstructor()->getMock();
62
-		$this->inputInterface = $this->getMockBuilder(InputInterface::class)
63
-			->disableOriginalConstructor()->getMock();
64
-		$this->outputInterface = $this->getMockBuilder(OutputInterface::class)
65
-			->disableOriginalConstructor()->getMock();
66
-		$this->outputInterface->expects($this->any())->method('isDecorated')
67
-			->willReturn(false);
68
-		$this->userInterface = $this->getMockBuilder(UserInterface::class)
69
-			->disableOriginalConstructor()->getMock();
70
-
71
-		/* We need format method to return a string */
72
-		$outputFormatter = $this->createMock(OutputFormatterInterface::class);
73
-		$outputFormatter->method('format')->willReturn('foo');
74
-		$outputFormatter->method('isDecorated')->willReturn(false);
75
-
76
-		$this->outputInterface->expects($this->any())->method('getFormatter')
77
-			->willReturn($outputFormatter);
78
-
79
-		$this->instance = new DecryptAll($this->encryptionManager, $this->userManager, $this->view);
80
-
81
-		$this->invokePrivate($this->instance, 'input', [$this->inputInterface]);
82
-		$this->invokePrivate($this->instance, 'output', [$this->outputInterface]);
83
-	}
84
-
85
-	public static function dataDecryptAll(): array {
86
-		return [
87
-			[true, 'user1', true],
88
-			[false, 'user1', true],
89
-			[true, '0', true],
90
-			[false, '0', true],
91
-			[true, '', false],
92
-		];
93
-	}
94
-
95
-	/**
96
-	 * @dataProvider dataDecryptAll
97
-	 * @param bool $prepareResult
98
-	 * @param string $user
99
-	 * @param bool $userExistsChecked
100
-	 */
101
-	public function testDecryptAll($prepareResult, $user, $userExistsChecked): void {
102
-		if ($userExistsChecked) {
103
-			$this->userManager->expects($this->once())->method('userExists')->willReturn(true);
104
-		} else {
105
-			$this->userManager->expects($this->never())->method('userExists');
106
-		}
107
-		/** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject |  $instance */
108
-		$instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
109
-			->setConstructorArgs(
110
-				[
111
-					$this->encryptionManager,
112
-					$this->userManager,
113
-					$this->view
114
-				]
115
-			)
116
-			->onlyMethods(['prepareEncryptionModules', 'decryptAllUsersFiles'])
117
-			->getMock();
118
-
119
-		$instance->expects($this->once())
120
-			->method('prepareEncryptionModules')
121
-			->with($user)
122
-			->willReturn($prepareResult);
123
-
124
-		if ($prepareResult) {
125
-			$instance->expects($this->once())
126
-				->method('decryptAllUsersFiles')
127
-				->with($user);
128
-		} else {
129
-			$instance->expects($this->never())->method('decryptAllUsersFiles');
130
-		}
131
-
132
-		$instance->decryptAll($this->inputInterface, $this->outputInterface, $user);
133
-	}
134
-
135
-	/**
136
-	 * test decrypt all call with a user who doesn't exists
137
-	 */
138
-	public function testDecryptAllWrongUser(): void {
139
-		$this->userManager->expects($this->once())->method('userExists')->willReturn(false);
140
-		$this->outputInterface->expects($this->once())->method('writeln')
141
-			->with('User "user1" does not exist. Please check the username and try again');
142
-
143
-		$this->assertFalse(
144
-			$this->instance->decryptAll($this->inputInterface, $this->outputInterface, 'user1')
145
-		);
146
-	}
147
-
148
-	public static function dataTrueFalse(): array {
149
-		return [
150
-			[true],
151
-			[false],
152
-		];
153
-	}
154
-
155
-	/**
156
-	 * @dataProvider dataTrueFalse
157
-	 * @param bool $success
158
-	 */
159
-	public function testPrepareEncryptionModules($success): void {
160
-		$user = 'user1';
161
-
162
-		$dummyEncryptionModule = $this->getMockBuilder('OCP\Encryption\IEncryptionModule')
163
-			->disableOriginalConstructor()->getMock();
164
-
165
-		$dummyEncryptionModule->expects($this->once())
166
-			->method('prepareDecryptAll')
167
-			->with($this->inputInterface, $this->outputInterface, $user)
168
-			->willReturn($success);
169
-
170
-		$callback = function () use ($dummyEncryptionModule) {
171
-			return $dummyEncryptionModule;
172
-		};
173
-		$moduleDescription = [
174
-			'id' => 'id',
175
-			'displayName' => 'displayName',
176
-			'callback' => $callback
177
-		];
178
-
179
-		$this->encryptionManager->expects($this->once())
180
-			->method('getEncryptionModules')
181
-			->willReturn([$moduleDescription]);
182
-
183
-		$this->assertSame($success,
184
-			$this->invokePrivate($this->instance, 'prepareEncryptionModules', [$user])
185
-		);
186
-	}
187
-
188
-	/**
189
-	 * @dataProvider dataTestDecryptAllUsersFiles
190
-	 */
191
-	public function testDecryptAllUsersFiles($user): void {
192
-		/** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject |  $instance */
193
-		$instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
194
-			->setConstructorArgs(
195
-				[
196
-					$this->encryptionManager,
197
-					$this->userManager,
198
-					$this->view
199
-				]
200
-			)
201
-			->onlyMethods(['decryptUsersFiles'])
202
-			->getMock();
203
-
204
-		$this->invokePrivate($instance, 'input', [$this->inputInterface]);
205
-		$this->invokePrivate($instance, 'output', [$this->outputInterface]);
206
-
207
-		if (empty($user)) {
208
-			$this->userManager->expects($this->once())
209
-				->method('getBackends')
210
-				->willReturn([$this->userInterface]);
211
-			$this->userInterface->expects($this->any())
212
-				->method('getUsers')
213
-				->willReturn(['user1', 'user2']);
214
-			$calls = [
215
-				'user1',
216
-				'user2',
217
-			];
218
-			$instance->expects($this->exactly(2))
219
-				->method('decryptUsersFiles')
220
-				->willReturnCallback(function ($user) use (&$calls) {
221
-					$expected = array_shift($calls);
222
-					$this->assertEquals($expected, $user);
223
-				});
224
-		} else {
225
-			$instance->expects($this->once())
226
-				->method('decryptUsersFiles')
227
-				->with($user);
228
-		}
229
-
230
-		$this->invokePrivate($instance, 'decryptAllUsersFiles', [$user]);
231
-	}
232
-
233
-	public static function dataTestDecryptAllUsersFiles(): array {
234
-		return [
235
-			['user1'],
236
-			['']
237
-		];
238
-	}
239
-
240
-	public function testDecryptUsersFiles(): void {
241
-		/** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject  $instance */
242
-		$instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
243
-			->setConstructorArgs(
244
-				[
245
-					$this->encryptionManager,
246
-					$this->userManager,
247
-					$this->view
248
-				]
249
-			)
250
-			->onlyMethods(['decryptFile'])
251
-			->getMock();
252
-
253
-		$storage = $this->getMockBuilder(IStorage::class)
254
-			->disableOriginalConstructor()->getMock();
255
-
256
-
257
-		$sharedStorage = $this->getMockBuilder(IStorage::class)
258
-			->disableOriginalConstructor()->getMock();
259
-
260
-		$sharedStorage->expects($this->once())
261
-			->method('instanceOfStorage')
262
-			->with('OCA\Files_Sharing\SharedStorage')
263
-			->willReturn(true);
264
-
265
-		$this->view->expects($this->exactly(2))
266
-			->method('getDirectoryContent')
267
-			->willReturnMap([
268
-				[
269
-					'/user1/files', '', null,
270
-					[
271
-						new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null),
272
-						new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null),
273
-						new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null),
274
-					],
275
-				],
276
-				[
277
-					'/user1/files/foo', '', null,
278
-					[
279
-						new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null)
280
-					],
281
-				],
282
-			]);
283
-
284
-		$this->view->expects($this->any())->method('is_dir')
285
-			->willReturnCallback(
286
-				function ($path) {
287
-					if ($path === '/user1/files/foo') {
288
-						return true;
289
-					}
290
-					return false;
291
-				}
292
-			);
293
-
294
-		$calls = [
295
-			'/user1/files/bar',
296
-			'/user1/files/foo/subfile',
297
-		];
298
-		$instance->expects($this->exactly(2))
299
-			->method('decryptFile')
300
-			->willReturnCallback(function ($path) use (&$calls) {
301
-				$expected = array_shift($calls);
302
-				$this->assertEquals($expected, $path);
303
-			});
304
-
305
-
306
-		/* We need format method to return a string */
307
-		$outputFormatter = $this->createMock(OutputFormatterInterface::class);
308
-		$outputFormatter->method('isDecorated')->willReturn(false);
309
-		$outputFormatter->method('format')->willReturn('foo');
310
-
311
-		$output = $this->createMock(OutputInterface::class);
312
-		$output->expects($this->any())
313
-			->method('getFormatter')
314
-			->willReturn($outputFormatter);
315
-		$progressBar = new ProgressBar($output);
316
-
317
-		$this->invokePrivate($instance, 'decryptUsersFiles', ['user1', $progressBar, '']);
318
-	}
319
-
320
-	/**
321
-	 * @dataProvider dataTrueFalse
322
-	 */
323
-	public function testDecryptFile($isEncrypted): void {
324
-		$path = 'test.txt';
325
-
326
-		/** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject  $instance */
327
-		$instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
328
-			->setConstructorArgs(
329
-				[
330
-					$this->encryptionManager,
331
-					$this->userManager,
332
-					$this->view
333
-				]
334
-			)
335
-			->onlyMethods(['getTimestamp'])
336
-			->getMock();
337
-
338
-		$fileInfo = $this->createMock(FileInfo::class);
339
-		$fileInfo->expects($this->any())->method('isEncrypted')
340
-			->willReturn($isEncrypted);
341
-		$this->view->expects($this->any())->method('getFileInfo')
342
-			->willReturn($fileInfo);
343
-
344
-		if ($isEncrypted) {
345
-			$instance->expects($this->any())->method('getTimestamp')->willReturn(42);
346
-
347
-			$this->view->expects($this->once())
348
-				->method('copy')
349
-				->with($path, $path . '.decrypted.42');
350
-			$this->view->expects($this->once())
351
-				->method('rename')
352
-				->with($path . '.decrypted.42', $path);
353
-		} else {
354
-			$instance->expects($this->never())->method('getTimestamp');
355
-			$this->view->expects($this->never())->method('copy');
356
-			$this->view->expects($this->never())->method('rename');
357
-		}
358
-		$this->assertTrue(
359
-			$this->invokePrivate($instance, 'decryptFile', [$path])
360
-		);
361
-	}
362
-
363
-	public function testDecryptFileFailure(): void {
364
-		$path = 'test.txt';
365
-
366
-		/** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject  $instance */
367
-		$instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
368
-			->setConstructorArgs(
369
-				[
370
-					$this->encryptionManager,
371
-					$this->userManager,
372
-					$this->view
373
-				]
374
-			)
375
-			->onlyMethods(['getTimestamp'])
376
-			->getMock();
377
-
378
-
379
-		$fileInfo = $this->createMock(FileInfo::class);
380
-		$fileInfo->expects($this->any())->method('isEncrypted')
381
-			->willReturn(true);
382
-		$this->view->expects($this->any())->method('getFileInfo')
383
-			->willReturn($fileInfo);
384
-
385
-		$instance->expects($this->any())->method('getTimestamp')->willReturn(42);
386
-
387
-		$this->view->expects($this->once())
388
-			->method('copy')
389
-			->with($path, $path . '.decrypted.42')
390
-			->willReturnCallback(function () {
391
-				throw new DecryptionFailedException();
392
-			});
393
-
394
-		$this->view->expects($this->never())->method('rename');
395
-		$this->view->expects($this->once())
396
-			->method('file_exists')
397
-			->with($path . '.decrypted.42')
398
-			->willReturn(true);
399
-		$this->view->expects($this->once())
400
-			->method('unlink')
401
-			->with($path . '.decrypted.42');
402
-
403
-		$this->assertFalse(
404
-			$this->invokePrivate($instance, 'decryptFile', [$path])
405
-		);
406
-	}
32
+    /** @var \PHPUnit\Framework\MockObject\MockObject | IUserManager */
33
+    protected $userManager;
34
+
35
+    /** @var \PHPUnit\Framework\MockObject\MockObject | Manager */
36
+    protected $encryptionManager;
37
+
38
+    /** @var \PHPUnit\Framework\MockObject\MockObject | View */
39
+    protected $view;
40
+
41
+    /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Input\InputInterface */
42
+    protected $inputInterface;
43
+
44
+    /** @var \PHPUnit\Framework\MockObject\MockObject | \Symfony\Component\Console\Output\OutputInterface */
45
+    protected $outputInterface;
46
+
47
+    /** @var \PHPUnit\Framework\MockObject\MockObject | \OCP\UserInterface */
48
+    protected $userInterface;
49
+
50
+    /** @var DecryptAll */
51
+    protected $instance;
52
+
53
+    protected function setUp(): void {
54
+        parent::setUp();
55
+
56
+        $this->userManager = $this->getMockBuilder(IUserManager::class)
57
+            ->disableOriginalConstructor()->getMock();
58
+        $this->encryptionManager = $this->getMockBuilder('OC\Encryption\Manager')
59
+            ->disableOriginalConstructor()->getMock();
60
+        $this->view = $this->getMockBuilder(View::class)
61
+            ->disableOriginalConstructor()->getMock();
62
+        $this->inputInterface = $this->getMockBuilder(InputInterface::class)
63
+            ->disableOriginalConstructor()->getMock();
64
+        $this->outputInterface = $this->getMockBuilder(OutputInterface::class)
65
+            ->disableOriginalConstructor()->getMock();
66
+        $this->outputInterface->expects($this->any())->method('isDecorated')
67
+            ->willReturn(false);
68
+        $this->userInterface = $this->getMockBuilder(UserInterface::class)
69
+            ->disableOriginalConstructor()->getMock();
70
+
71
+        /* We need format method to return a string */
72
+        $outputFormatter = $this->createMock(OutputFormatterInterface::class);
73
+        $outputFormatter->method('format')->willReturn('foo');
74
+        $outputFormatter->method('isDecorated')->willReturn(false);
75
+
76
+        $this->outputInterface->expects($this->any())->method('getFormatter')
77
+            ->willReturn($outputFormatter);
78
+
79
+        $this->instance = new DecryptAll($this->encryptionManager, $this->userManager, $this->view);
80
+
81
+        $this->invokePrivate($this->instance, 'input', [$this->inputInterface]);
82
+        $this->invokePrivate($this->instance, 'output', [$this->outputInterface]);
83
+    }
84
+
85
+    public static function dataDecryptAll(): array {
86
+        return [
87
+            [true, 'user1', true],
88
+            [false, 'user1', true],
89
+            [true, '0', true],
90
+            [false, '0', true],
91
+            [true, '', false],
92
+        ];
93
+    }
94
+
95
+    /**
96
+     * @dataProvider dataDecryptAll
97
+     * @param bool $prepareResult
98
+     * @param string $user
99
+     * @param bool $userExistsChecked
100
+     */
101
+    public function testDecryptAll($prepareResult, $user, $userExistsChecked): void {
102
+        if ($userExistsChecked) {
103
+            $this->userManager->expects($this->once())->method('userExists')->willReturn(true);
104
+        } else {
105
+            $this->userManager->expects($this->never())->method('userExists');
106
+        }
107
+        /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject |  $instance */
108
+        $instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
109
+            ->setConstructorArgs(
110
+                [
111
+                    $this->encryptionManager,
112
+                    $this->userManager,
113
+                    $this->view
114
+                ]
115
+            )
116
+            ->onlyMethods(['prepareEncryptionModules', 'decryptAllUsersFiles'])
117
+            ->getMock();
118
+
119
+        $instance->expects($this->once())
120
+            ->method('prepareEncryptionModules')
121
+            ->with($user)
122
+            ->willReturn($prepareResult);
123
+
124
+        if ($prepareResult) {
125
+            $instance->expects($this->once())
126
+                ->method('decryptAllUsersFiles')
127
+                ->with($user);
128
+        } else {
129
+            $instance->expects($this->never())->method('decryptAllUsersFiles');
130
+        }
131
+
132
+        $instance->decryptAll($this->inputInterface, $this->outputInterface, $user);
133
+    }
134
+
135
+    /**
136
+     * test decrypt all call with a user who doesn't exists
137
+     */
138
+    public function testDecryptAllWrongUser(): void {
139
+        $this->userManager->expects($this->once())->method('userExists')->willReturn(false);
140
+        $this->outputInterface->expects($this->once())->method('writeln')
141
+            ->with('User "user1" does not exist. Please check the username and try again');
142
+
143
+        $this->assertFalse(
144
+            $this->instance->decryptAll($this->inputInterface, $this->outputInterface, 'user1')
145
+        );
146
+    }
147
+
148
+    public static function dataTrueFalse(): array {
149
+        return [
150
+            [true],
151
+            [false],
152
+        ];
153
+    }
154
+
155
+    /**
156
+     * @dataProvider dataTrueFalse
157
+     * @param bool $success
158
+     */
159
+    public function testPrepareEncryptionModules($success): void {
160
+        $user = 'user1';
161
+
162
+        $dummyEncryptionModule = $this->getMockBuilder('OCP\Encryption\IEncryptionModule')
163
+            ->disableOriginalConstructor()->getMock();
164
+
165
+        $dummyEncryptionModule->expects($this->once())
166
+            ->method('prepareDecryptAll')
167
+            ->with($this->inputInterface, $this->outputInterface, $user)
168
+            ->willReturn($success);
169
+
170
+        $callback = function () use ($dummyEncryptionModule) {
171
+            return $dummyEncryptionModule;
172
+        };
173
+        $moduleDescription = [
174
+            'id' => 'id',
175
+            'displayName' => 'displayName',
176
+            'callback' => $callback
177
+        ];
178
+
179
+        $this->encryptionManager->expects($this->once())
180
+            ->method('getEncryptionModules')
181
+            ->willReturn([$moduleDescription]);
182
+
183
+        $this->assertSame($success,
184
+            $this->invokePrivate($this->instance, 'prepareEncryptionModules', [$user])
185
+        );
186
+    }
187
+
188
+    /**
189
+     * @dataProvider dataTestDecryptAllUsersFiles
190
+     */
191
+    public function testDecryptAllUsersFiles($user): void {
192
+        /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject |  $instance */
193
+        $instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
194
+            ->setConstructorArgs(
195
+                [
196
+                    $this->encryptionManager,
197
+                    $this->userManager,
198
+                    $this->view
199
+                ]
200
+            )
201
+            ->onlyMethods(['decryptUsersFiles'])
202
+            ->getMock();
203
+
204
+        $this->invokePrivate($instance, 'input', [$this->inputInterface]);
205
+        $this->invokePrivate($instance, 'output', [$this->outputInterface]);
206
+
207
+        if (empty($user)) {
208
+            $this->userManager->expects($this->once())
209
+                ->method('getBackends')
210
+                ->willReturn([$this->userInterface]);
211
+            $this->userInterface->expects($this->any())
212
+                ->method('getUsers')
213
+                ->willReturn(['user1', 'user2']);
214
+            $calls = [
215
+                'user1',
216
+                'user2',
217
+            ];
218
+            $instance->expects($this->exactly(2))
219
+                ->method('decryptUsersFiles')
220
+                ->willReturnCallback(function ($user) use (&$calls) {
221
+                    $expected = array_shift($calls);
222
+                    $this->assertEquals($expected, $user);
223
+                });
224
+        } else {
225
+            $instance->expects($this->once())
226
+                ->method('decryptUsersFiles')
227
+                ->with($user);
228
+        }
229
+
230
+        $this->invokePrivate($instance, 'decryptAllUsersFiles', [$user]);
231
+    }
232
+
233
+    public static function dataTestDecryptAllUsersFiles(): array {
234
+        return [
235
+            ['user1'],
236
+            ['']
237
+        ];
238
+    }
239
+
240
+    public function testDecryptUsersFiles(): void {
241
+        /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject  $instance */
242
+        $instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
243
+            ->setConstructorArgs(
244
+                [
245
+                    $this->encryptionManager,
246
+                    $this->userManager,
247
+                    $this->view
248
+                ]
249
+            )
250
+            ->onlyMethods(['decryptFile'])
251
+            ->getMock();
252
+
253
+        $storage = $this->getMockBuilder(IStorage::class)
254
+            ->disableOriginalConstructor()->getMock();
255
+
256
+
257
+        $sharedStorage = $this->getMockBuilder(IStorage::class)
258
+            ->disableOriginalConstructor()->getMock();
259
+
260
+        $sharedStorage->expects($this->once())
261
+            ->method('instanceOfStorage')
262
+            ->with('OCA\Files_Sharing\SharedStorage')
263
+            ->willReturn(true);
264
+
265
+        $this->view->expects($this->exactly(2))
266
+            ->method('getDirectoryContent')
267
+            ->willReturnMap([
268
+                [
269
+                    '/user1/files', '', null,
270
+                    [
271
+                        new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null),
272
+                        new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null),
273
+                        new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null),
274
+                    ],
275
+                ],
276
+                [
277
+                    '/user1/files/foo', '', null,
278
+                    [
279
+                        new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null)
280
+                    ],
281
+                ],
282
+            ]);
283
+
284
+        $this->view->expects($this->any())->method('is_dir')
285
+            ->willReturnCallback(
286
+                function ($path) {
287
+                    if ($path === '/user1/files/foo') {
288
+                        return true;
289
+                    }
290
+                    return false;
291
+                }
292
+            );
293
+
294
+        $calls = [
295
+            '/user1/files/bar',
296
+            '/user1/files/foo/subfile',
297
+        ];
298
+        $instance->expects($this->exactly(2))
299
+            ->method('decryptFile')
300
+            ->willReturnCallback(function ($path) use (&$calls) {
301
+                $expected = array_shift($calls);
302
+                $this->assertEquals($expected, $path);
303
+            });
304
+
305
+
306
+        /* We need format method to return a string */
307
+        $outputFormatter = $this->createMock(OutputFormatterInterface::class);
308
+        $outputFormatter->method('isDecorated')->willReturn(false);
309
+        $outputFormatter->method('format')->willReturn('foo');
310
+
311
+        $output = $this->createMock(OutputInterface::class);
312
+        $output->expects($this->any())
313
+            ->method('getFormatter')
314
+            ->willReturn($outputFormatter);
315
+        $progressBar = new ProgressBar($output);
316
+
317
+        $this->invokePrivate($instance, 'decryptUsersFiles', ['user1', $progressBar, '']);
318
+    }
319
+
320
+    /**
321
+     * @dataProvider dataTrueFalse
322
+     */
323
+    public function testDecryptFile($isEncrypted): void {
324
+        $path = 'test.txt';
325
+
326
+        /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject  $instance */
327
+        $instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
328
+            ->setConstructorArgs(
329
+                [
330
+                    $this->encryptionManager,
331
+                    $this->userManager,
332
+                    $this->view
333
+                ]
334
+            )
335
+            ->onlyMethods(['getTimestamp'])
336
+            ->getMock();
337
+
338
+        $fileInfo = $this->createMock(FileInfo::class);
339
+        $fileInfo->expects($this->any())->method('isEncrypted')
340
+            ->willReturn($isEncrypted);
341
+        $this->view->expects($this->any())->method('getFileInfo')
342
+            ->willReturn($fileInfo);
343
+
344
+        if ($isEncrypted) {
345
+            $instance->expects($this->any())->method('getTimestamp')->willReturn(42);
346
+
347
+            $this->view->expects($this->once())
348
+                ->method('copy')
349
+                ->with($path, $path . '.decrypted.42');
350
+            $this->view->expects($this->once())
351
+                ->method('rename')
352
+                ->with($path . '.decrypted.42', $path);
353
+        } else {
354
+            $instance->expects($this->never())->method('getTimestamp');
355
+            $this->view->expects($this->never())->method('copy');
356
+            $this->view->expects($this->never())->method('rename');
357
+        }
358
+        $this->assertTrue(
359
+            $this->invokePrivate($instance, 'decryptFile', [$path])
360
+        );
361
+    }
362
+
363
+    public function testDecryptFileFailure(): void {
364
+        $path = 'test.txt';
365
+
366
+        /** @var DecryptAll | \PHPUnit\Framework\MockObject\MockObject  $instance */
367
+        $instance = $this->getMockBuilder('OC\Encryption\DecryptAll')
368
+            ->setConstructorArgs(
369
+                [
370
+                    $this->encryptionManager,
371
+                    $this->userManager,
372
+                    $this->view
373
+                ]
374
+            )
375
+            ->onlyMethods(['getTimestamp'])
376
+            ->getMock();
377
+
378
+
379
+        $fileInfo = $this->createMock(FileInfo::class);
380
+        $fileInfo->expects($this->any())->method('isEncrypted')
381
+            ->willReturn(true);
382
+        $this->view->expects($this->any())->method('getFileInfo')
383
+            ->willReturn($fileInfo);
384
+
385
+        $instance->expects($this->any())->method('getTimestamp')->willReturn(42);
386
+
387
+        $this->view->expects($this->once())
388
+            ->method('copy')
389
+            ->with($path, $path . '.decrypted.42')
390
+            ->willReturnCallback(function () {
391
+                throw new DecryptionFailedException();
392
+            });
393
+
394
+        $this->view->expects($this->never())->method('rename');
395
+        $this->view->expects($this->once())
396
+            ->method('file_exists')
397
+            ->with($path . '.decrypted.42')
398
+            ->willReturn(true);
399
+        $this->view->expects($this->once())
400
+            ->method('unlink')
401
+            ->with($path . '.decrypted.42');
402
+
403
+        $this->assertFalse(
404
+            $this->invokePrivate($instance, 'decryptFile', [$path])
405
+        );
406
+    }
407 407
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -167,7 +167,7 @@  discard block
 block discarded – undo
167 167
 			->with($this->inputInterface, $this->outputInterface, $user)
168 168
 			->willReturn($success);
169 169
 
170
-		$callback = function () use ($dummyEncryptionModule) {
170
+		$callback = function() use ($dummyEncryptionModule) {
171 171
 			return $dummyEncryptionModule;
172 172
 		};
173 173
 		$moduleDescription = [
@@ -217,7 +217,7 @@  discard block
 block discarded – undo
217 217
 			];
218 218
 			$instance->expects($this->exactly(2))
219 219
 				->method('decryptUsersFiles')
220
-				->willReturnCallback(function ($user) use (&$calls) {
220
+				->willReturnCallback(function($user) use (&$calls) {
221 221
 					$expected = array_shift($calls);
222 222
 					$this->assertEquals($expected, $user);
223 223
 				});
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
 
284 284
 		$this->view->expects($this->any())->method('is_dir')
285 285
 			->willReturnCallback(
286
-				function ($path) {
286
+				function($path) {
287 287
 					if ($path === '/user1/files/foo') {
288 288
 						return true;
289 289
 					}
@@ -297,7 +297,7 @@  discard block
 block discarded – undo
297 297
 		];
298 298
 		$instance->expects($this->exactly(2))
299 299
 			->method('decryptFile')
300
-			->willReturnCallback(function ($path) use (&$calls) {
300
+			->willReturnCallback(function($path) use (&$calls) {
301 301
 				$expected = array_shift($calls);
302 302
 				$this->assertEquals($expected, $path);
303 303
 			});
@@ -346,10 +346,10 @@  discard block
 block discarded – undo
346 346
 
347 347
 			$this->view->expects($this->once())
348 348
 				->method('copy')
349
-				->with($path, $path . '.decrypted.42');
349
+				->with($path, $path.'.decrypted.42');
350 350
 			$this->view->expects($this->once())
351 351
 				->method('rename')
352
-				->with($path . '.decrypted.42', $path);
352
+				->with($path.'.decrypted.42', $path);
353 353
 		} else {
354 354
 			$instance->expects($this->never())->method('getTimestamp');
355 355
 			$this->view->expects($this->never())->method('copy');
@@ -386,19 +386,19 @@  discard block
 block discarded – undo
386 386
 
387 387
 		$this->view->expects($this->once())
388 388
 			->method('copy')
389
-			->with($path, $path . '.decrypted.42')
390
-			->willReturnCallback(function () {
389
+			->with($path, $path.'.decrypted.42')
390
+			->willReturnCallback(function() {
391 391
 				throw new DecryptionFailedException();
392 392
 			});
393 393
 
394 394
 		$this->view->expects($this->never())->method('rename');
395 395
 		$this->view->expects($this->once())
396 396
 			->method('file_exists')
397
-			->with($path . '.decrypted.42')
397
+			->with($path.'.decrypted.42')
398 398
 			->willReturn(true);
399 399
 		$this->view->expects($this->once())
400 400
 			->method('unlink')
401
-			->with($path . '.decrypted.42');
401
+			->with($path.'.decrypted.42');
402 402
 
403 403
 		$this->assertFalse(
404 404
 			$this->invokePrivate($instance, 'decryptFile', [$path])
Please login to merge, or discard this patch.
tests/lib/Contacts/ContactsMenu/ContactsStoreTest.php 2 patches
Indentation   +1040 added lines, -1040 removed lines patch added patch discarded remove patch
@@ -25,1044 +25,1044 @@
 block discarded – undo
25 25
 use Test\TestCase;
26 26
 
27 27
 class ContactsStoreTest extends TestCase {
28
-	private ContactsStore $contactsStore;
29
-	private StatusService|MockObject $statusService;
30
-	/** @var IManager|MockObject */
31
-	private $contactsManager;
32
-	/** @var ProfileManager */
33
-	private $profileManager;
34
-	/** @var IUserManager|MockObject */
35
-	private $userManager;
36
-	/** @var IURLGenerator */
37
-	private $urlGenerator;
38
-	/** @var IGroupManager|MockObject */
39
-	private $groupManager;
40
-	/** @var IConfig|MockObject */
41
-	private $config;
42
-	/** @var KnownUserService|MockObject */
43
-	private $knownUserService;
44
-	/** @var IL10NFactory */
45
-	private $l10nFactory;
46
-
47
-	protected function setUp(): void {
48
-		parent::setUp();
49
-
50
-		$this->contactsManager = $this->createMock(IManager::class);
51
-		$this->statusService = $this->createMock(StatusService::class);
52
-		$this->userManager = $this->createMock(IUserManager::class);
53
-		$this->profileManager = $this->createMock(ProfileManager::class);
54
-		$this->urlGenerator = $this->createMock(IURLGenerator::class);
55
-		$this->groupManager = $this->createMock(IGroupManager::class);
56
-		$this->config = $this->createMock(IConfig::class);
57
-		$this->knownUserService = $this->createMock(KnownUserService::class);
58
-		$this->l10nFactory = $this->createMock(IL10NFactory::class);
59
-		$this->contactsStore = new ContactsStore(
60
-			$this->contactsManager,
61
-			$this->statusService,
62
-			$this->config,
63
-			$this->profileManager,
64
-			$this->userManager,
65
-			$this->urlGenerator,
66
-			$this->groupManager,
67
-			$this->knownUserService,
68
-			$this->l10nFactory,
69
-		);
70
-	}
71
-
72
-	public function testGetContactsWithoutFilter(): void {
73
-		/** @var IUser|MockObject $user */
74
-		$user = $this->createMock(IUser::class);
75
-		$this->contactsManager->expects($this->once())
76
-			->method('search')
77
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
78
-			->willReturn([
79
-				[
80
-					'UID' => 123,
81
-				],
82
-				[
83
-					'UID' => 567,
84
-					'FN' => 'Darren Roner',
85
-					'EMAIL' => [
86
-						'[email protected]'
87
-					],
88
-				],
89
-			]);
90
-		$user->expects($this->exactly(2))
91
-			->method('getUID')
92
-			->willReturn('user123');
93
-
94
-		$entries = $this->contactsStore->getContacts($user, '');
95
-
96
-		$this->assertCount(2, $entries);
97
-		$this->assertEquals([
98
-			'[email protected]'
99
-		], $entries[1]->getEMailAddresses());
100
-	}
101
-
102
-	public function testGetContactsHidesOwnEntry(): void {
103
-		/** @var IUser|MockObject $user */
104
-		$user = $this->createMock(IUser::class);
105
-		$this->contactsManager->expects($this->once())
106
-			->method('search')
107
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
108
-			->willReturn([
109
-				[
110
-					'UID' => 'user123',
111
-				],
112
-				[
113
-					'UID' => 567,
114
-					'FN' => 'Darren Roner',
115
-					'EMAIL' => [
116
-						'[email protected]'
117
-					],
118
-				],
119
-			]);
120
-		$user->expects($this->exactly(2))
121
-			->method('getUID')
122
-			->willReturn('user123');
123
-
124
-		$entries = $this->contactsStore->getContacts($user, '');
125
-
126
-		$this->assertCount(1, $entries);
127
-	}
128
-
129
-	public function testGetContactsWithoutBinaryImage(): void {
130
-		/** @var IUser|MockObject $user */
131
-		$user = $this->createMock(IUser::class);
132
-		$this->urlGenerator->expects($this->any())
133
-			->method('linkToRouteAbsolute')
134
-			->with('core.GuestAvatar.getAvatar', $this->anything())
135
-			->willReturn('https://urlToNcAvatar.test');
136
-		$this->contactsManager->expects($this->once())
137
-			->method('search')
138
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
139
-			->willReturn([
140
-				[
141
-					'UID' => 123,
142
-				],
143
-				[
144
-					'UID' => 567,
145
-					'FN' => 'Darren Roner',
146
-					'EMAIL' => [
147
-						'[email protected]'
148
-					],
149
-					'PHOTO' => base64_encode('photophotophoto'),
150
-				],
151
-			]);
152
-		$user->expects($this->exactly(2))
153
-			->method('getUID')
154
-			->willReturn('user123');
155
-
156
-		$entries = $this->contactsStore->getContacts($user, '');
157
-
158
-		$this->assertCount(2, $entries);
159
-		$this->assertSame('https://urlToNcAvatar.test', $entries[1]->getAvatar());
160
-	}
161
-
162
-	public function testGetContactsWithoutAvatarURI(): void {
163
-		/** @var IUser|MockObject $user */
164
-		$user = $this->createMock(IUser::class);
165
-		$this->contactsManager->expects($this->once())
166
-			->method('search')
167
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
168
-			->willReturn([
169
-				[
170
-					'UID' => 123,
171
-				],
172
-				[
173
-					'UID' => 567,
174
-					'FN' => 'Darren Roner',
175
-					'EMAIL' => [
176
-						'[email protected]'
177
-					],
178
-					'PHOTO' => 'VALUE=uri:https://photo',
179
-				],
180
-			]);
181
-		$user->expects($this->exactly(2))
182
-			->method('getUID')
183
-			->willReturn('user123');
184
-
185
-		$entries = $this->contactsStore->getContacts($user, '');
186
-
187
-		$this->assertCount(2, $entries);
188
-		$this->assertEquals('https://photo', $entries[1]->getAvatar());
189
-	}
190
-
191
-	public function testGetContactsWhenUserIsInExcludeGroups(): void {
192
-		$this->config
193
-			->method('getAppValue')
194
-			->willReturnMap([
195
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
196
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
197
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
198
-				['core', 'shareapi_exclude_groups', 'no', 'yes'],
199
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
200
-				['core', 'shareapi_exclude_groups_list', '', '["group1", "group5", "group6"]'],
201
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
202
-			]);
203
-
204
-		/** @var IUser|MockObject $currentUser */
205
-		$currentUser = $this->createMock(IUser::class);
206
-		$currentUser->expects($this->exactly(2))
207
-			->method('getUID')
208
-			->willReturn('user001');
209
-
210
-		$this->groupManager->expects($this->once())
211
-			->method('getUserGroupIds')
212
-			->with($this->equalTo($currentUser))
213
-			->willReturn(['group1', 'group2', 'group3']);
214
-
215
-
216
-		$this->contactsManager->expects($this->once())
217
-			->method('search')
218
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
219
-			->willReturn([
220
-				[
221
-					'UID' => 'user123',
222
-					'isLocalSystemBook' => true
223
-				],
224
-				[
225
-					'UID' => 'user12345',
226
-					'isLocalSystemBook' => true
227
-				],
228
-			]);
229
-
230
-
231
-		$entries = $this->contactsStore->getContacts($currentUser, '');
232
-
233
-		$this->assertCount(0, $entries);
234
-	}
235
-
236
-	public function testGetContactsOnlyShareIfInTheSameGroup(): void {
237
-		$this->config
238
-			->method('getAppValue')
239
-			->willReturnMap([
240
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
241
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
242
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
243
-				['core', 'shareapi_exclude_groups', 'no', 'no'],
244
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
245
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
246
-			]);
247
-
248
-		/** @var IUser|MockObject $currentUser */
249
-		$currentUser = $this->createMock(IUser::class);
250
-		$currentUser->expects($this->exactly(2))
251
-			->method('getUID')
252
-			->willReturn('user001');
253
-
254
-		$user1 = $this->createMock(IUser::class);
255
-		$user2 = $this->createMock(IUser::class);
256
-		$user3 = $this->createMock(IUser::class);
257
-
258
-		$calls = [
259
-			[[$currentUser], ['group1', 'group2', 'group3']],
260
-			[[$user1], ['group1']],
261
-			[[$user2], ['group2', 'group3']],
262
-			[[$user3], ['group8', 'group9']],
263
-		];
264
-		$this->groupManager->expects($this->exactly(4))
265
-			->method('getUserGroupIds')
266
-			->willReturnCallback(function () use (&$calls): array {
267
-				$expected = array_shift($calls);
268
-				$this->assertEquals($expected[0], func_get_args());
269
-				return $expected[1];
270
-			});
271
-
272
-		$this->userManager->expects($this->exactly(3))
273
-			->method('get')
274
-			->willReturnMap([
275
-				['user1', $user1],
276
-				['user2', $user2],
277
-				['user3', $user3],
278
-			]);
279
-
280
-		$this->contactsManager->expects($this->once())
281
-			->method('search')
282
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
283
-			->willReturn([
284
-				[
285
-					'UID' => 'user1',
286
-					'isLocalSystemBook' => true
287
-				],
288
-				[
289
-					'UID' => 'user2',
290
-					'isLocalSystemBook' => true
291
-				],
292
-				[
293
-					'UID' => 'user3',
294
-					'isLocalSystemBook' => true
295
-				],
296
-				[
297
-					'UID' => 'contact',
298
-				],
299
-			]);
300
-
301
-		$entries = $this->contactsStore->getContacts($currentUser, '');
302
-
303
-		$this->assertCount(3, $entries);
304
-		$this->assertEquals('user1', $entries[0]->getProperty('UID'));
305
-		$this->assertEquals('user2', $entries[1]->getProperty('UID'));
306
-		$this->assertEquals('contact', $entries[2]->getProperty('UID'));
307
-	}
308
-
309
-	public function testGetContactsOnlyEnumerateIfInTheSameGroup(): void {
310
-		$this->config
311
-			->method('getAppValue')
312
-			->willReturnMap([
313
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
314
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
315
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
316
-				['core', 'shareapi_exclude_groups', 'no', 'no'],
317
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
318
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
319
-			]);
320
-
321
-		/** @var IUser|MockObject $currentUser */
322
-		$currentUser = $this->createMock(IUser::class);
323
-		$currentUser->expects($this->exactly(2))
324
-			->method('getUID')
325
-			->willReturn('user001');
326
-
327
-		$user1 = $this->createMock(IUser::class);
328
-		$user2 = $this->createMock(IUser::class);
329
-		$user3 = $this->createMock(IUser::class);
330
-
331
-		$calls = [
332
-			[[$currentUser], ['group1', 'group2', 'group3']],
333
-			[[$user1], ['group1']],
334
-			[[$user2], ['group2', 'group3']],
335
-			[[$user3], ['group8', 'group9']],
336
-		];
337
-		$this->groupManager->expects($this->exactly(4))
338
-			->method('getUserGroupIds')
339
-			->willReturnCallback(function () use (&$calls): array {
340
-				$expected = array_shift($calls);
341
-				$this->assertEquals($expected[0], func_get_args());
342
-				return $expected[1];
343
-			});
344
-
345
-		$this->userManager->expects($this->exactly(3))
346
-			->method('get')
347
-			->willReturnMap([
348
-				['user1', $user1],
349
-				['user2', $user2],
350
-				['user3', $user3],
351
-			]);
352
-
353
-		$this->contactsManager->expects($this->once())
354
-			->method('search')
355
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
356
-			->willReturn([
357
-				[
358
-					'UID' => 'user1',
359
-					'isLocalSystemBook' => true
360
-				],
361
-				[
362
-					'UID' => 'user2',
363
-					'isLocalSystemBook' => true
364
-				],
365
-				[
366
-					'UID' => 'user3',
367
-					'isLocalSystemBook' => true
368
-				],
369
-				[
370
-					'UID' => 'contact',
371
-				],
372
-			]);
373
-
374
-		$entries = $this->contactsStore->getContacts($currentUser, '');
375
-
376
-		$this->assertCount(3, $entries);
377
-		$this->assertEquals('user1', $entries[0]->getProperty('UID'));
378
-		$this->assertEquals('user2', $entries[1]->getProperty('UID'));
379
-		$this->assertEquals('contact', $entries[2]->getProperty('UID'));
380
-	}
381
-
382
-	public function testGetContactsOnlyEnumerateIfPhoneBookMatch(): void {
383
-		$this->config
384
-			->method('getAppValue')
385
-			->willReturnMap([
386
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
387
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
388
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
389
-				['core', 'shareapi_exclude_groups', 'no', 'no'],
390
-				['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
391
-			]);
392
-
393
-		/** @var IUser|MockObject $currentUser */
394
-		$currentUser = $this->createMock(IUser::class);
395
-		$currentUser->expects($this->exactly(2))
396
-			->method('getUID')
397
-			->willReturn('user001');
398
-
399
-		$this->groupManager->expects($this->once())
400
-			->method('getUserGroupIds')
401
-			->with($this->equalTo($currentUser))
402
-			->willReturn(['group1', 'group2', 'group3']);
403
-
404
-		$this->knownUserService->method('isKnownToUser')
405
-			->willReturnMap([
406
-				['user001', 'user1', true],
407
-				['user001', 'user2', true],
408
-				['user001', 'user3', false],
409
-			]);
410
-
411
-		$this->contactsManager->expects($this->once())
412
-			->method('search')
413
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
414
-			->willReturn([
415
-				[
416
-					'UID' => 'user1',
417
-					'isLocalSystemBook' => true
418
-				],
419
-				[
420
-					'UID' => 'user2',
421
-					'isLocalSystemBook' => true
422
-				],
423
-				[
424
-					'UID' => 'user3',
425
-					'isLocalSystemBook' => true
426
-				],
427
-				[
428
-					'UID' => 'contact',
429
-				],
430
-			]);
431
-
432
-		$entries = $this->contactsStore->getContacts($currentUser, '');
433
-
434
-		$this->assertCount(3, $entries);
435
-		$this->assertEquals('user1', $entries[0]->getProperty('UID'));
436
-		$this->assertEquals('user2', $entries[1]->getProperty('UID'));
437
-		$this->assertEquals('contact', $entries[2]->getProperty('UID'));
438
-	}
439
-
440
-	public function testGetContactsOnlyEnumerateIfPhoneBookMatchWithOwnGroupsOnly(): void {
441
-		$this->config
442
-			->method('getAppValue')
443
-			->willReturnMap([
444
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
445
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
446
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
447
-				['core', 'shareapi_exclude_groups', 'no', 'no'],
448
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
449
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
450
-			]);
451
-
452
-		/** @var IUser|MockObject $currentUser */
453
-		$currentUser = $this->createMock(IUser::class);
454
-		$currentUser->expects($this->exactly(2))
455
-			->method('getUID')
456
-			->willReturn('user001');
457
-
458
-		$user1 = $this->createMock(IUser::class);
459
-		$user2 = $this->createMock(IUser::class);
460
-		$user3 = $this->createMock(IUser::class);
461
-
462
-		$calls = [
463
-			[[$currentUser], ['group1', 'group2', 'group3']],
464
-			[[$user1], ['group1']],
465
-			[[$user2], ['group2', 'group3']],
466
-			[[$user3], ['group8', 'group9']],
467
-		];
468
-		$this->groupManager->expects($this->exactly(4))
469
-			->method('getUserGroupIds')
470
-			->willReturnCallback(function () use (&$calls): array {
471
-				$expected = array_shift($calls);
472
-				$this->assertEquals($expected[0], func_get_args());
473
-				return $expected[1];
474
-			});
475
-
476
-		$this->userManager->expects($this->exactly(3))
477
-			->method('get')
478
-			->willReturnMap([
479
-				['user1', $user1],
480
-				['user2', $user2],
481
-				['user3', $user3],
482
-			]);
483
-
484
-		$this->knownUserService->method('isKnownToUser')
485
-			->willReturnMap([
486
-				['user001', 'user1', true],
487
-				['user001', 'user2', true],
488
-				['user001', 'user3', true],
489
-			]);
490
-
491
-		$this->contactsManager->expects($this->once())
492
-			->method('search')
493
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
494
-			->willReturn([
495
-				[
496
-					'UID' => 'user1',
497
-					'isLocalSystemBook' => true
498
-				],
499
-				[
500
-					'UID' => 'user2',
501
-					'isLocalSystemBook' => true
502
-				],
503
-				[
504
-					'UID' => 'user3',
505
-					'isLocalSystemBook' => true
506
-				],
507
-				[
508
-					'UID' => 'contact',
509
-				],
510
-			]);
511
-
512
-		$entries = $this->contactsStore->getContacts($currentUser, '');
513
-
514
-		$this->assertCount(3, $entries);
515
-		$this->assertEquals('user1', $entries[0]->getProperty('UID'));
516
-		$this->assertEquals('user2', $entries[1]->getProperty('UID'));
517
-		$this->assertEquals('contact', $entries[2]->getProperty('UID'));
518
-	}
519
-
520
-	public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroup(): void {
521
-		$this->config
522
-			->method('getAppValue')
523
-			->willReturnMap([
524
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
525
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
526
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
527
-				['core', 'shareapi_exclude_groups', 'no', 'no'],
528
-				['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
529
-			]);
530
-
531
-		/** @var IUser|MockObject $currentUser */
532
-		$currentUser = $this->createMock(IUser::class);
533
-		$currentUser->expects($this->exactly(2))
534
-			->method('getUID')
535
-			->willReturn('user001');
536
-
537
-		$user1 = $this->createMock(IUser::class);
538
-
539
-		$calls = [
540
-			[[$currentUser], ['group1', 'group2', 'group3']],
541
-			[[$user1], ['group1']],
542
-		];
543
-		$this->groupManager->expects($this->exactly(2))
544
-			->method('getUserGroupIds')
545
-			->willReturnCallback(function () use (&$calls): array {
546
-				$expected = array_shift($calls);
547
-				$this->assertEquals($expected[0], func_get_args());
548
-				return $expected[1];
549
-			});
550
-
551
-		$this->userManager->expects($this->once())
552
-			->method('get')
553
-			->with('user1')
554
-			->willReturn($user1);
555
-
556
-		$this->knownUserService->method('isKnownToUser')
557
-			->willReturnMap([
558
-				['user001', 'user1', false],
559
-				['user001', 'user2', true],
560
-				['user001', 'user3', true],
561
-			]);
562
-
563
-		$this->contactsManager->expects($this->once())
564
-			->method('search')
565
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
566
-			->willReturn([
567
-				[
568
-					'UID' => 'user1',
569
-					'isLocalSystemBook' => true
570
-				],
571
-				[
572
-					'UID' => 'user2',
573
-					'isLocalSystemBook' => true
574
-				],
575
-				[
576
-					'UID' => 'user3',
577
-					'isLocalSystemBook' => true
578
-				],
579
-				[
580
-					'UID' => 'contact',
581
-				],
582
-			]);
583
-
584
-		$entries = $this->contactsStore->getContacts($currentUser, '');
585
-
586
-		$this->assertCount(4, $entries);
587
-		$this->assertEquals('user1', $entries[0]->getProperty('UID'));
588
-		$this->assertEquals('user2', $entries[1]->getProperty('UID'));
589
-		$this->assertEquals('user3', $entries[2]->getProperty('UID'));
590
-		$this->assertEquals('contact', $entries[3]->getProperty('UID'));
591
-	}
592
-
593
-	public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroupInOwnGroupsOnly(): void {
594
-		$this->config
595
-			->method('getAppValue')
596
-			->willReturnMap([
597
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
598
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
599
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
600
-				['core', 'shareapi_exclude_groups', 'no', 'no'],
601
-				['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
602
-				['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
603
-			]);
604
-
605
-		/** @var IUser|MockObject $currentUser */
606
-		$currentUser = $this->createMock(IUser::class);
607
-		$currentUser->expects($this->exactly(2))
608
-			->method('getUID')
609
-			->willReturn('user001');
610
-
611
-		$user1 = $this->createMock(IUser::class);
612
-		$user2 = $this->createMock(IUser::class);
613
-		$user3 = $this->createMock(IUser::class);
614
-
615
-		$calls = [
616
-			[[$currentUser], ['group1', 'group2', 'group3']],
617
-			[[$user1], ['group1']],
618
-			[[$user2], ['group2', 'group3']],
619
-			[[$user3], ['group8', 'group9']],
620
-		];
621
-		$this->groupManager->expects($this->exactly(4))
622
-			->method('getUserGroupIds')
623
-			->willReturnCallback(function () use (&$calls): array {
624
-				$expected = array_shift($calls);
625
-				$this->assertEquals($expected[0], func_get_args());
626
-				return $expected[1];
627
-			});
628
-
629
-		$this->userManager->expects($this->exactly(3))
630
-			->method('get')
631
-			->willReturnMap([
632
-				['user1', $user1],
633
-				['user2', $user2],
634
-				['user3', $user3],
635
-			]);
636
-
637
-		$this->knownUserService->method('isKnownToUser')
638
-			->willReturnMap([
639
-				['user001', 'user1', false],
640
-				['user001', 'user2', true],
641
-				['user001', 'user3', true],
642
-			]);
643
-
644
-		$this->contactsManager->expects($this->once())
645
-			->method('search')
646
-			->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
647
-			->willReturn([
648
-				[
649
-					'UID' => 'user1',
650
-					'isLocalSystemBook' => true
651
-				],
652
-				[
653
-					'UID' => 'user2',
654
-					'isLocalSystemBook' => true
655
-				],
656
-				[
657
-					'UID' => 'user3',
658
-					'isLocalSystemBook' => true
659
-				],
660
-				[
661
-					'UID' => 'contact',
662
-				],
663
-			]);
664
-
665
-		$entries = $this->contactsStore->getContacts($currentUser, '');
666
-
667
-		$this->assertCount(3, $entries);
668
-		$this->assertEquals('user1', $entries[0]->getProperty('UID'));
669
-		$this->assertEquals('user2', $entries[1]->getProperty('UID'));
670
-		$this->assertEquals('contact', $entries[2]->getProperty('UID'));
671
-	}
672
-
673
-	public function testGetContactsWithFilter(): void {
674
-		$this->config
675
-			->method('getAppValue')
676
-			->willReturnMap([
677
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
678
-				['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
679
-			]);
680
-
681
-		/** @var IUser|MockObject $user */
682
-		$user = $this->createMock(IUser::class);
683
-		$this->contactsManager->expects($this->any())
684
-			->method('search')
685
-			->willReturn([
686
-				[
687
-					'UID' => 'a567',
688
-					'FN' => 'Darren Roner',
689
-					'EMAIL' => [
690
-						'[email protected]',
691
-					],
692
-					'isLocalSystemBook' => true,
693
-				],
694
-				[
695
-					'UID' => 'john',
696
-					'FN' => 'John Doe',
697
-					'EMAIL' => [
698
-						'[email protected]',
699
-					],
700
-					'isLocalSystemBook' => true,
701
-				],
702
-				[
703
-					'FN' => 'Anne D',
704
-					'EMAIL' => [
705
-						'[email protected]',
706
-					],
707
-					'isLocalSystemBook' => false,
708
-				],
709
-			]);
710
-		$user->expects($this->any())
711
-			->method('getUID')
712
-			->willReturn('user123');
713
-
714
-		// Complete match on UID should match
715
-		$entry = $this->contactsStore->getContacts($user, 'a567');
716
-		$this->assertSame(2, count($entry));
717
-		$this->assertEquals([
718
-			'[email protected]'
719
-		], $entry[0]->getEMailAddresses());
720
-
721
-		// Partial match on UID should not match
722
-		$entry = $this->contactsStore->getContacts($user, 'a56');
723
-		$this->assertSame(1, count($entry));
724
-		$this->assertEquals([
725
-			'[email protected]'
726
-		], $entry[0]->getEMailAddresses());
727
-
728
-		// Complete match on email should match
729
-		$entry = $this->contactsStore->getContacts($user, '[email protected]');
730
-		$this->assertSame(2, count($entry));
731
-		$this->assertEquals([
732
-			'[email protected]'
733
-		], $entry[0]->getEMailAddresses());
734
-		$this->assertEquals([
735
-			'[email protected]'
736
-		], $entry[1]->getEMailAddresses());
737
-
738
-		// Partial match on email should not match
739
-		$entry = $this->contactsStore->getContacts($user, '[email protected]');
740
-		$this->assertSame(1, count($entry));
741
-		$this->assertEquals([
742
-			'[email protected]'
743
-		], $entry[0]->getEMailAddresses());
744
-
745
-		// Match on FN should not match
746
-		$entry = $this->contactsStore->getContacts($user, 'Darren Roner');
747
-		$this->assertSame(1, count($entry));
748
-		$this->assertEquals([
749
-			'[email protected]'
750
-		], $entry[0]->getEMailAddresses());
751
-
752
-		// Don't filter users in local addressbook
753
-		$entry = $this->contactsStore->getContacts($user, 'Anne D');
754
-		$this->assertSame(1, count($entry));
755
-		$this->assertEquals([
756
-			'[email protected]'
757
-		], $entry[0]->getEMailAddresses());
758
-	}
759
-
760
-	public function testGetContactsWithFilterWithoutFullMatch(): void {
761
-		$this->config
762
-			->method('getAppValue')
763
-			->willReturnMap([
764
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
765
-				['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'no'],
766
-			]);
767
-
768
-		/** @var IUser|MockObject $user */
769
-		$user = $this->createMock(IUser::class);
770
-		$this->contactsManager->expects($this->any())
771
-			->method('search')
772
-			->willReturn([
773
-				[
774
-					'UID' => 'a567',
775
-					'FN' => 'Darren Roner',
776
-					'EMAIL' => [
777
-						'[email protected]',
778
-					],
779
-					'isLocalSystemBook' => true,
780
-				],
781
-				[
782
-					'UID' => 'john',
783
-					'FN' => 'John Doe',
784
-					'EMAIL' => [
785
-						'[email protected]',
786
-					],
787
-					'isLocalSystemBook' => true,
788
-				],
789
-				[
790
-					'FN' => 'Anne D',
791
-					'EMAIL' => [
792
-						'[email protected]',
793
-					],
794
-					'isLocalSystemBook' => false,
795
-				],
796
-			]);
797
-		$user->expects($this->any())
798
-			->method('getUID')
799
-			->willReturn('user123');
800
-
801
-		// Complete match on UID should not match
802
-		$entry = $this->contactsStore->getContacts($user, 'a567');
803
-		$this->assertSame(1, count($entry));
804
-		$this->assertEquals([
805
-			'[email protected]'
806
-		], $entry[0]->getEMailAddresses());
807
-
808
-		// Partial match on UID should not match
809
-		$entry = $this->contactsStore->getContacts($user, 'a56');
810
-		$this->assertSame(1, count($entry));
811
-		$this->assertEquals([
812
-			'[email protected]'
813
-		], $entry[0]->getEMailAddresses());
814
-
815
-		// Complete match on email should not match
816
-		$entry = $this->contactsStore->getContacts($user, '[email protected]');
817
-		$this->assertSame(1, count($entry));
818
-		$this->assertEquals([
819
-			'[email protected]'
820
-		], $entry[0]->getEMailAddresses());
821
-
822
-		// Partial match on email should not match
823
-		$entry = $this->contactsStore->getContacts($user, '[email protected]');
824
-		$this->assertSame(1, count($entry));
825
-		$this->assertEquals([
826
-			'[email protected]'
827
-		], $entry[0]->getEMailAddresses());
828
-
829
-		// Match on FN should not match
830
-		$entry = $this->contactsStore->getContacts($user, 'Darren Roner');
831
-		$this->assertSame(1, count($entry));
832
-		$this->assertEquals([
833
-			'[email protected]'
834
-		], $entry[0]->getEMailAddresses());
835
-
836
-		// Don't filter users in local addressbook
837
-		$entry = $this->contactsStore->getContacts($user, 'Anne D');
838
-		$this->assertSame(1, count($entry));
839
-		$this->assertEquals([
840
-			'[email protected]'
841
-		], $entry[0]->getEMailAddresses());
842
-	}
843
-
844
-	public function testFindOneUser(): void {
845
-		$this->config
846
-			->method('getAppValue')
847
-			->willReturnMap([
848
-				['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
849
-				['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
850
-				['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
851
-				['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
852
-				['core', 'shareapi_exclude_groups', 'no', 'yes'],
853
-				['core', 'shareapi_exclude_groups_list', '', ''],
854
-				['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
855
-			]);
856
-
857
-		/** @var IUser|MockObject $user */
858
-		$user = $this->createMock(IUser::class);
859
-		$this->contactsManager->expects($this->once())
860
-			->method('search')
861
-			->with($this->equalTo('a567'), $this->equalTo(['UID']))
862
-			->willReturn([
863
-				[
864
-					'UID' => 123,
865
-					'isLocalSystemBook' => false
866
-				],
867
-				[
868
-					'UID' => 'a567',
869
-					'FN' => 'Darren Roner',
870
-					'EMAIL' => [
871
-						'[email protected]'
872
-					],
873
-					'isLocalSystemBook' => true
874
-				],
875
-			]);
876
-		$user->expects($this->any())
877
-			->method('getUID')
878
-			->willReturn('user123');
879
-
880
-		$entry = $this->contactsStore->findOne($user, 0, 'a567');
881
-
882
-		$this->assertEquals([
883
-			'[email protected]'
884
-		], $entry->getEMailAddresses());
885
-	}
886
-
887
-	public function testFindOneEMail(): void {
888
-		/** @var IUser|MockObject $user */
889
-		$user = $this->createMock(IUser::class);
890
-		$this->contactsManager->expects($this->once())
891
-			->method('search')
892
-			->with($this->equalTo('[email protected]'), $this->equalTo(['EMAIL']))
893
-			->willReturn([
894
-				[
895
-					'UID' => 123,
896
-					'isLocalSystemBook' => false
897
-				],
898
-				[
899
-					'UID' => 'a567',
900
-					'FN' => 'Darren Roner',
901
-					'EMAIL' => [
902
-						'[email protected]'
903
-					],
904
-					'isLocalSystemBook' => false
905
-				],
906
-			]);
907
-		$user->expects($this->any())
908
-			->method('getUID')
909
-			->willReturn('user123');
910
-
911
-		$entry = $this->contactsStore->findOne($user, 4, '[email protected]');
912
-
913
-		$this->assertEquals([
914
-			'[email protected]'
915
-		], $entry->getEMailAddresses());
916
-	}
917
-
918
-	public function testFindOneNotSupportedType(): void {
919
-		/** @var IUser|MockObject $user */
920
-		$user = $this->createMock(IUser::class);
921
-
922
-		$entry = $this->contactsStore->findOne($user, 42, '[email protected]');
923
-
924
-		$this->assertEquals(null, $entry);
925
-	}
926
-
927
-	public function testFindOneNoMatches(): void {
928
-		/** @var IUser|MockObject $user */
929
-		$user = $this->createMock(IUser::class);
930
-		$this->contactsManager->expects($this->once())
931
-			->method('search')
932
-			->with($this->equalTo('a567'), $this->equalTo(['UID']))
933
-			->willReturn([
934
-				[
935
-					'UID' => 123,
936
-					'isLocalSystemBook' => false
937
-				],
938
-				[
939
-					'UID' => 'a567',
940
-					'FN' => 'Darren Roner',
941
-					'EMAIL' => [
942
-						'[email protected]'
943
-					],
944
-					'isLocalSystemBook' => false
945
-				],
946
-			]);
947
-		$user->expects($this->never())
948
-			->method('getUID');
949
-
950
-		$entry = $this->contactsStore->findOne($user, 0, 'a567');
951
-
952
-		$this->assertEquals(null, $entry);
953
-	}
954
-
955
-	public function testGetRecentStatusFirst(): void {
956
-		$user = $this->createMock(IUser::class);
957
-		$status1 = new UserStatus();
958
-		$status1->setUserId('user1');
959
-		$status2 = new UserStatus();
960
-		$status2->setUserId('user2');
961
-		$this->statusService->expects(self::once())
962
-			->method('findAllRecentStatusChanges')
963
-			->willReturn([
964
-				$status1,
965
-				$status2,
966
-			]);
967
-		$user1 = $this->createMock(IUser::class);
968
-		$user1->method('getCloudId')->willReturn('user1@localcloud');
969
-		$user2 = $this->createMock(IUser::class);
970
-		$user2->method('getCloudId')->willReturn('user2@localcloud');
971
-		$this->userManager->expects(self::exactly(2))
972
-			->method('get')
973
-			->willReturnCallback(function ($uid) use ($user1, $user2) {
974
-				return match ($uid) {
975
-					'user1' => $user1,
976
-					'user2' => $user2,
977
-				};
978
-			});
979
-		$this->contactsManager
980
-			->expects(self::exactly(3))
981
-			->method('search')
982
-			->willReturnCallback(function ($uid, $searchProps, $options) {
983
-				return match ([$uid, $options['limit'] ?? null]) {
984
-					['user1@localcloud', 1] => [
985
-						[
986
-							'UID' => 'user1',
987
-							'URI' => 'user1.vcf',
988
-						],
989
-					],
990
-					['user2@localcloud' => [], 1], // Simulate not found
991
-					['', 4] => [
992
-						[
993
-							'UID' => 'contact1',
994
-							'URI' => 'contact1.vcf',
995
-						],
996
-						[
997
-							'UID' => 'contact2',
998
-							'URI' => 'contact2.vcf',
999
-						],
1000
-					],
1001
-					default => [],
1002
-				};
1003
-			});
1004
-
1005
-		$contacts = $this->contactsStore->getContacts(
1006
-			$user,
1007
-			null,
1008
-			5,
1009
-		);
1010
-
1011
-		self::assertCount(3, $contacts);
1012
-		self::assertEquals('user1', $contacts[0]->getProperty('UID'));
1013
-		self::assertEquals('contact1', $contacts[1]->getProperty('UID'));
1014
-		self::assertEquals('contact2', $contacts[2]->getProperty('UID'));
1015
-	}
1016
-
1017
-	public function testPaginateRecentStatus(): void {
1018
-		$user = $this->createMock(IUser::class);
1019
-		$status1 = new UserStatus();
1020
-		$status1->setUserId('user1');
1021
-		$status2 = new UserStatus();
1022
-		$status2->setUserId('user2');
1023
-		$status3 = new UserStatus();
1024
-		$status3->setUserId('user3');
1025
-		$this->statusService->expects(self::never())
1026
-			->method('findAllRecentStatusChanges');
1027
-		$this->contactsManager
1028
-			->expects(self::exactly(2))
1029
-			->method('search')
1030
-			->willReturnCallback(function ($uid, $searchProps, $options) {
1031
-				return match ([$uid, $options['limit'] ?? null, $options['offset'] ?? null]) {
1032
-					['', 2, 0] => [
1033
-						[
1034
-							'UID' => 'contact1',
1035
-							'URI' => 'contact1.vcf',
1036
-						],
1037
-						[
1038
-							'UID' => 'contact2',
1039
-							'URI' => 'contact2.vcf',
1040
-						],
1041
-					],
1042
-					['', 2, 3] => [
1043
-						[
1044
-							'UID' => 'contact3',
1045
-							'URI' => 'contact3.vcf',
1046
-						],
1047
-					],
1048
-					default => [],
1049
-				};
1050
-			});
1051
-
1052
-		$page1 = $this->contactsStore->getContacts(
1053
-			$user,
1054
-			null,
1055
-			2,
1056
-			0,
1057
-		);
1058
-		$page2 = $this->contactsStore->getContacts(
1059
-			$user,
1060
-			null,
1061
-			2,
1062
-			3,
1063
-		);
1064
-
1065
-		self::assertCount(2, $page1);
1066
-		self::assertCount(1, $page2);
1067
-	}
28
+    private ContactsStore $contactsStore;
29
+    private StatusService|MockObject $statusService;
30
+    /** @var IManager|MockObject */
31
+    private $contactsManager;
32
+    /** @var ProfileManager */
33
+    private $profileManager;
34
+    /** @var IUserManager|MockObject */
35
+    private $userManager;
36
+    /** @var IURLGenerator */
37
+    private $urlGenerator;
38
+    /** @var IGroupManager|MockObject */
39
+    private $groupManager;
40
+    /** @var IConfig|MockObject */
41
+    private $config;
42
+    /** @var KnownUserService|MockObject */
43
+    private $knownUserService;
44
+    /** @var IL10NFactory */
45
+    private $l10nFactory;
46
+
47
+    protected function setUp(): void {
48
+        parent::setUp();
49
+
50
+        $this->contactsManager = $this->createMock(IManager::class);
51
+        $this->statusService = $this->createMock(StatusService::class);
52
+        $this->userManager = $this->createMock(IUserManager::class);
53
+        $this->profileManager = $this->createMock(ProfileManager::class);
54
+        $this->urlGenerator = $this->createMock(IURLGenerator::class);
55
+        $this->groupManager = $this->createMock(IGroupManager::class);
56
+        $this->config = $this->createMock(IConfig::class);
57
+        $this->knownUserService = $this->createMock(KnownUserService::class);
58
+        $this->l10nFactory = $this->createMock(IL10NFactory::class);
59
+        $this->contactsStore = new ContactsStore(
60
+            $this->contactsManager,
61
+            $this->statusService,
62
+            $this->config,
63
+            $this->profileManager,
64
+            $this->userManager,
65
+            $this->urlGenerator,
66
+            $this->groupManager,
67
+            $this->knownUserService,
68
+            $this->l10nFactory,
69
+        );
70
+    }
71
+
72
+    public function testGetContactsWithoutFilter(): void {
73
+        /** @var IUser|MockObject $user */
74
+        $user = $this->createMock(IUser::class);
75
+        $this->contactsManager->expects($this->once())
76
+            ->method('search')
77
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
78
+            ->willReturn([
79
+                [
80
+                    'UID' => 123,
81
+                ],
82
+                [
83
+                    'UID' => 567,
84
+                    'FN' => 'Darren Roner',
85
+                    'EMAIL' => [
86
+                        '[email protected]'
87
+                    ],
88
+                ],
89
+            ]);
90
+        $user->expects($this->exactly(2))
91
+            ->method('getUID')
92
+            ->willReturn('user123');
93
+
94
+        $entries = $this->contactsStore->getContacts($user, '');
95
+
96
+        $this->assertCount(2, $entries);
97
+        $this->assertEquals([
98
+            '[email protected]'
99
+        ], $entries[1]->getEMailAddresses());
100
+    }
101
+
102
+    public function testGetContactsHidesOwnEntry(): void {
103
+        /** @var IUser|MockObject $user */
104
+        $user = $this->createMock(IUser::class);
105
+        $this->contactsManager->expects($this->once())
106
+            ->method('search')
107
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
108
+            ->willReturn([
109
+                [
110
+                    'UID' => 'user123',
111
+                ],
112
+                [
113
+                    'UID' => 567,
114
+                    'FN' => 'Darren Roner',
115
+                    'EMAIL' => [
116
+                        '[email protected]'
117
+                    ],
118
+                ],
119
+            ]);
120
+        $user->expects($this->exactly(2))
121
+            ->method('getUID')
122
+            ->willReturn('user123');
123
+
124
+        $entries = $this->contactsStore->getContacts($user, '');
125
+
126
+        $this->assertCount(1, $entries);
127
+    }
128
+
129
+    public function testGetContactsWithoutBinaryImage(): void {
130
+        /** @var IUser|MockObject $user */
131
+        $user = $this->createMock(IUser::class);
132
+        $this->urlGenerator->expects($this->any())
133
+            ->method('linkToRouteAbsolute')
134
+            ->with('core.GuestAvatar.getAvatar', $this->anything())
135
+            ->willReturn('https://urlToNcAvatar.test');
136
+        $this->contactsManager->expects($this->once())
137
+            ->method('search')
138
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
139
+            ->willReturn([
140
+                [
141
+                    'UID' => 123,
142
+                ],
143
+                [
144
+                    'UID' => 567,
145
+                    'FN' => 'Darren Roner',
146
+                    'EMAIL' => [
147
+                        '[email protected]'
148
+                    ],
149
+                    'PHOTO' => base64_encode('photophotophoto'),
150
+                ],
151
+            ]);
152
+        $user->expects($this->exactly(2))
153
+            ->method('getUID')
154
+            ->willReturn('user123');
155
+
156
+        $entries = $this->contactsStore->getContacts($user, '');
157
+
158
+        $this->assertCount(2, $entries);
159
+        $this->assertSame('https://urlToNcAvatar.test', $entries[1]->getAvatar());
160
+    }
161
+
162
+    public function testGetContactsWithoutAvatarURI(): void {
163
+        /** @var IUser|MockObject $user */
164
+        $user = $this->createMock(IUser::class);
165
+        $this->contactsManager->expects($this->once())
166
+            ->method('search')
167
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
168
+            ->willReturn([
169
+                [
170
+                    'UID' => 123,
171
+                ],
172
+                [
173
+                    'UID' => 567,
174
+                    'FN' => 'Darren Roner',
175
+                    'EMAIL' => [
176
+                        '[email protected]'
177
+                    ],
178
+                    'PHOTO' => 'VALUE=uri:https://photo',
179
+                ],
180
+            ]);
181
+        $user->expects($this->exactly(2))
182
+            ->method('getUID')
183
+            ->willReturn('user123');
184
+
185
+        $entries = $this->contactsStore->getContacts($user, '');
186
+
187
+        $this->assertCount(2, $entries);
188
+        $this->assertEquals('https://photo', $entries[1]->getAvatar());
189
+    }
190
+
191
+    public function testGetContactsWhenUserIsInExcludeGroups(): void {
192
+        $this->config
193
+            ->method('getAppValue')
194
+            ->willReturnMap([
195
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
196
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
197
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
198
+                ['core', 'shareapi_exclude_groups', 'no', 'yes'],
199
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
200
+                ['core', 'shareapi_exclude_groups_list', '', '["group1", "group5", "group6"]'],
201
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
202
+            ]);
203
+
204
+        /** @var IUser|MockObject $currentUser */
205
+        $currentUser = $this->createMock(IUser::class);
206
+        $currentUser->expects($this->exactly(2))
207
+            ->method('getUID')
208
+            ->willReturn('user001');
209
+
210
+        $this->groupManager->expects($this->once())
211
+            ->method('getUserGroupIds')
212
+            ->with($this->equalTo($currentUser))
213
+            ->willReturn(['group1', 'group2', 'group3']);
214
+
215
+
216
+        $this->contactsManager->expects($this->once())
217
+            ->method('search')
218
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
219
+            ->willReturn([
220
+                [
221
+                    'UID' => 'user123',
222
+                    'isLocalSystemBook' => true
223
+                ],
224
+                [
225
+                    'UID' => 'user12345',
226
+                    'isLocalSystemBook' => true
227
+                ],
228
+            ]);
229
+
230
+
231
+        $entries = $this->contactsStore->getContacts($currentUser, '');
232
+
233
+        $this->assertCount(0, $entries);
234
+    }
235
+
236
+    public function testGetContactsOnlyShareIfInTheSameGroup(): void {
237
+        $this->config
238
+            ->method('getAppValue')
239
+            ->willReturnMap([
240
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
241
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
242
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
243
+                ['core', 'shareapi_exclude_groups', 'no', 'no'],
244
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
245
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
246
+            ]);
247
+
248
+        /** @var IUser|MockObject $currentUser */
249
+        $currentUser = $this->createMock(IUser::class);
250
+        $currentUser->expects($this->exactly(2))
251
+            ->method('getUID')
252
+            ->willReturn('user001');
253
+
254
+        $user1 = $this->createMock(IUser::class);
255
+        $user2 = $this->createMock(IUser::class);
256
+        $user3 = $this->createMock(IUser::class);
257
+
258
+        $calls = [
259
+            [[$currentUser], ['group1', 'group2', 'group3']],
260
+            [[$user1], ['group1']],
261
+            [[$user2], ['group2', 'group3']],
262
+            [[$user3], ['group8', 'group9']],
263
+        ];
264
+        $this->groupManager->expects($this->exactly(4))
265
+            ->method('getUserGroupIds')
266
+            ->willReturnCallback(function () use (&$calls): array {
267
+                $expected = array_shift($calls);
268
+                $this->assertEquals($expected[0], func_get_args());
269
+                return $expected[1];
270
+            });
271
+
272
+        $this->userManager->expects($this->exactly(3))
273
+            ->method('get')
274
+            ->willReturnMap([
275
+                ['user1', $user1],
276
+                ['user2', $user2],
277
+                ['user3', $user3],
278
+            ]);
279
+
280
+        $this->contactsManager->expects($this->once())
281
+            ->method('search')
282
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
283
+            ->willReturn([
284
+                [
285
+                    'UID' => 'user1',
286
+                    'isLocalSystemBook' => true
287
+                ],
288
+                [
289
+                    'UID' => 'user2',
290
+                    'isLocalSystemBook' => true
291
+                ],
292
+                [
293
+                    'UID' => 'user3',
294
+                    'isLocalSystemBook' => true
295
+                ],
296
+                [
297
+                    'UID' => 'contact',
298
+                ],
299
+            ]);
300
+
301
+        $entries = $this->contactsStore->getContacts($currentUser, '');
302
+
303
+        $this->assertCount(3, $entries);
304
+        $this->assertEquals('user1', $entries[0]->getProperty('UID'));
305
+        $this->assertEquals('user2', $entries[1]->getProperty('UID'));
306
+        $this->assertEquals('contact', $entries[2]->getProperty('UID'));
307
+    }
308
+
309
+    public function testGetContactsOnlyEnumerateIfInTheSameGroup(): void {
310
+        $this->config
311
+            ->method('getAppValue')
312
+            ->willReturnMap([
313
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
314
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
315
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
316
+                ['core', 'shareapi_exclude_groups', 'no', 'no'],
317
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
318
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
319
+            ]);
320
+
321
+        /** @var IUser|MockObject $currentUser */
322
+        $currentUser = $this->createMock(IUser::class);
323
+        $currentUser->expects($this->exactly(2))
324
+            ->method('getUID')
325
+            ->willReturn('user001');
326
+
327
+        $user1 = $this->createMock(IUser::class);
328
+        $user2 = $this->createMock(IUser::class);
329
+        $user3 = $this->createMock(IUser::class);
330
+
331
+        $calls = [
332
+            [[$currentUser], ['group1', 'group2', 'group3']],
333
+            [[$user1], ['group1']],
334
+            [[$user2], ['group2', 'group3']],
335
+            [[$user3], ['group8', 'group9']],
336
+        ];
337
+        $this->groupManager->expects($this->exactly(4))
338
+            ->method('getUserGroupIds')
339
+            ->willReturnCallback(function () use (&$calls): array {
340
+                $expected = array_shift($calls);
341
+                $this->assertEquals($expected[0], func_get_args());
342
+                return $expected[1];
343
+            });
344
+
345
+        $this->userManager->expects($this->exactly(3))
346
+            ->method('get')
347
+            ->willReturnMap([
348
+                ['user1', $user1],
349
+                ['user2', $user2],
350
+                ['user3', $user3],
351
+            ]);
352
+
353
+        $this->contactsManager->expects($this->once())
354
+            ->method('search')
355
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
356
+            ->willReturn([
357
+                [
358
+                    'UID' => 'user1',
359
+                    'isLocalSystemBook' => true
360
+                ],
361
+                [
362
+                    'UID' => 'user2',
363
+                    'isLocalSystemBook' => true
364
+                ],
365
+                [
366
+                    'UID' => 'user3',
367
+                    'isLocalSystemBook' => true
368
+                ],
369
+                [
370
+                    'UID' => 'contact',
371
+                ],
372
+            ]);
373
+
374
+        $entries = $this->contactsStore->getContacts($currentUser, '');
375
+
376
+        $this->assertCount(3, $entries);
377
+        $this->assertEquals('user1', $entries[0]->getProperty('UID'));
378
+        $this->assertEquals('user2', $entries[1]->getProperty('UID'));
379
+        $this->assertEquals('contact', $entries[2]->getProperty('UID'));
380
+    }
381
+
382
+    public function testGetContactsOnlyEnumerateIfPhoneBookMatch(): void {
383
+        $this->config
384
+            ->method('getAppValue')
385
+            ->willReturnMap([
386
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
387
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
388
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
389
+                ['core', 'shareapi_exclude_groups', 'no', 'no'],
390
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
391
+            ]);
392
+
393
+        /** @var IUser|MockObject $currentUser */
394
+        $currentUser = $this->createMock(IUser::class);
395
+        $currentUser->expects($this->exactly(2))
396
+            ->method('getUID')
397
+            ->willReturn('user001');
398
+
399
+        $this->groupManager->expects($this->once())
400
+            ->method('getUserGroupIds')
401
+            ->with($this->equalTo($currentUser))
402
+            ->willReturn(['group1', 'group2', 'group3']);
403
+
404
+        $this->knownUserService->method('isKnownToUser')
405
+            ->willReturnMap([
406
+                ['user001', 'user1', true],
407
+                ['user001', 'user2', true],
408
+                ['user001', 'user3', false],
409
+            ]);
410
+
411
+        $this->contactsManager->expects($this->once())
412
+            ->method('search')
413
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
414
+            ->willReturn([
415
+                [
416
+                    'UID' => 'user1',
417
+                    'isLocalSystemBook' => true
418
+                ],
419
+                [
420
+                    'UID' => 'user2',
421
+                    'isLocalSystemBook' => true
422
+                ],
423
+                [
424
+                    'UID' => 'user3',
425
+                    'isLocalSystemBook' => true
426
+                ],
427
+                [
428
+                    'UID' => 'contact',
429
+                ],
430
+            ]);
431
+
432
+        $entries = $this->contactsStore->getContacts($currentUser, '');
433
+
434
+        $this->assertCount(3, $entries);
435
+        $this->assertEquals('user1', $entries[0]->getProperty('UID'));
436
+        $this->assertEquals('user2', $entries[1]->getProperty('UID'));
437
+        $this->assertEquals('contact', $entries[2]->getProperty('UID'));
438
+    }
439
+
440
+    public function testGetContactsOnlyEnumerateIfPhoneBookMatchWithOwnGroupsOnly(): void {
441
+        $this->config
442
+            ->method('getAppValue')
443
+            ->willReturnMap([
444
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
445
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
446
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
447
+                ['core', 'shareapi_exclude_groups', 'no', 'no'],
448
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
449
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
450
+            ]);
451
+
452
+        /** @var IUser|MockObject $currentUser */
453
+        $currentUser = $this->createMock(IUser::class);
454
+        $currentUser->expects($this->exactly(2))
455
+            ->method('getUID')
456
+            ->willReturn('user001');
457
+
458
+        $user1 = $this->createMock(IUser::class);
459
+        $user2 = $this->createMock(IUser::class);
460
+        $user3 = $this->createMock(IUser::class);
461
+
462
+        $calls = [
463
+            [[$currentUser], ['group1', 'group2', 'group3']],
464
+            [[$user1], ['group1']],
465
+            [[$user2], ['group2', 'group3']],
466
+            [[$user3], ['group8', 'group9']],
467
+        ];
468
+        $this->groupManager->expects($this->exactly(4))
469
+            ->method('getUserGroupIds')
470
+            ->willReturnCallback(function () use (&$calls): array {
471
+                $expected = array_shift($calls);
472
+                $this->assertEquals($expected[0], func_get_args());
473
+                return $expected[1];
474
+            });
475
+
476
+        $this->userManager->expects($this->exactly(3))
477
+            ->method('get')
478
+            ->willReturnMap([
479
+                ['user1', $user1],
480
+                ['user2', $user2],
481
+                ['user3', $user3],
482
+            ]);
483
+
484
+        $this->knownUserService->method('isKnownToUser')
485
+            ->willReturnMap([
486
+                ['user001', 'user1', true],
487
+                ['user001', 'user2', true],
488
+                ['user001', 'user3', true],
489
+            ]);
490
+
491
+        $this->contactsManager->expects($this->once())
492
+            ->method('search')
493
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
494
+            ->willReturn([
495
+                [
496
+                    'UID' => 'user1',
497
+                    'isLocalSystemBook' => true
498
+                ],
499
+                [
500
+                    'UID' => 'user2',
501
+                    'isLocalSystemBook' => true
502
+                ],
503
+                [
504
+                    'UID' => 'user3',
505
+                    'isLocalSystemBook' => true
506
+                ],
507
+                [
508
+                    'UID' => 'contact',
509
+                ],
510
+            ]);
511
+
512
+        $entries = $this->contactsStore->getContacts($currentUser, '');
513
+
514
+        $this->assertCount(3, $entries);
515
+        $this->assertEquals('user1', $entries[0]->getProperty('UID'));
516
+        $this->assertEquals('user2', $entries[1]->getProperty('UID'));
517
+        $this->assertEquals('contact', $entries[2]->getProperty('UID'));
518
+    }
519
+
520
+    public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroup(): void {
521
+        $this->config
522
+            ->method('getAppValue')
523
+            ->willReturnMap([
524
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
525
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
526
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
527
+                ['core', 'shareapi_exclude_groups', 'no', 'no'],
528
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
529
+            ]);
530
+
531
+        /** @var IUser|MockObject $currentUser */
532
+        $currentUser = $this->createMock(IUser::class);
533
+        $currentUser->expects($this->exactly(2))
534
+            ->method('getUID')
535
+            ->willReturn('user001');
536
+
537
+        $user1 = $this->createMock(IUser::class);
538
+
539
+        $calls = [
540
+            [[$currentUser], ['group1', 'group2', 'group3']],
541
+            [[$user1], ['group1']],
542
+        ];
543
+        $this->groupManager->expects($this->exactly(2))
544
+            ->method('getUserGroupIds')
545
+            ->willReturnCallback(function () use (&$calls): array {
546
+                $expected = array_shift($calls);
547
+                $this->assertEquals($expected[0], func_get_args());
548
+                return $expected[1];
549
+            });
550
+
551
+        $this->userManager->expects($this->once())
552
+            ->method('get')
553
+            ->with('user1')
554
+            ->willReturn($user1);
555
+
556
+        $this->knownUserService->method('isKnownToUser')
557
+            ->willReturnMap([
558
+                ['user001', 'user1', false],
559
+                ['user001', 'user2', true],
560
+                ['user001', 'user3', true],
561
+            ]);
562
+
563
+        $this->contactsManager->expects($this->once())
564
+            ->method('search')
565
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
566
+            ->willReturn([
567
+                [
568
+                    'UID' => 'user1',
569
+                    'isLocalSystemBook' => true
570
+                ],
571
+                [
572
+                    'UID' => 'user2',
573
+                    'isLocalSystemBook' => true
574
+                ],
575
+                [
576
+                    'UID' => 'user3',
577
+                    'isLocalSystemBook' => true
578
+                ],
579
+                [
580
+                    'UID' => 'contact',
581
+                ],
582
+            ]);
583
+
584
+        $entries = $this->contactsStore->getContacts($currentUser, '');
585
+
586
+        $this->assertCount(4, $entries);
587
+        $this->assertEquals('user1', $entries[0]->getProperty('UID'));
588
+        $this->assertEquals('user2', $entries[1]->getProperty('UID'));
589
+        $this->assertEquals('user3', $entries[2]->getProperty('UID'));
590
+        $this->assertEquals('contact', $entries[3]->getProperty('UID'));
591
+    }
592
+
593
+    public function testGetContactsOnlyEnumerateIfPhoneBookOrSameGroupInOwnGroupsOnly(): void {
594
+        $this->config
595
+            ->method('getAppValue')
596
+            ->willReturnMap([
597
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
598
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'yes'],
599
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'yes'],
600
+                ['core', 'shareapi_exclude_groups', 'no', 'no'],
601
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'yes'],
602
+                ['core', 'shareapi_only_share_with_group_members_exclude_group_list', '', '[]'],
603
+            ]);
604
+
605
+        /** @var IUser|MockObject $currentUser */
606
+        $currentUser = $this->createMock(IUser::class);
607
+        $currentUser->expects($this->exactly(2))
608
+            ->method('getUID')
609
+            ->willReturn('user001');
610
+
611
+        $user1 = $this->createMock(IUser::class);
612
+        $user2 = $this->createMock(IUser::class);
613
+        $user3 = $this->createMock(IUser::class);
614
+
615
+        $calls = [
616
+            [[$currentUser], ['group1', 'group2', 'group3']],
617
+            [[$user1], ['group1']],
618
+            [[$user2], ['group2', 'group3']],
619
+            [[$user3], ['group8', 'group9']],
620
+        ];
621
+        $this->groupManager->expects($this->exactly(4))
622
+            ->method('getUserGroupIds')
623
+            ->willReturnCallback(function () use (&$calls): array {
624
+                $expected = array_shift($calls);
625
+                $this->assertEquals($expected[0], func_get_args());
626
+                return $expected[1];
627
+            });
628
+
629
+        $this->userManager->expects($this->exactly(3))
630
+            ->method('get')
631
+            ->willReturnMap([
632
+                ['user1', $user1],
633
+                ['user2', $user2],
634
+                ['user3', $user3],
635
+            ]);
636
+
637
+        $this->knownUserService->method('isKnownToUser')
638
+            ->willReturnMap([
639
+                ['user001', 'user1', false],
640
+                ['user001', 'user2', true],
641
+                ['user001', 'user3', true],
642
+            ]);
643
+
644
+        $this->contactsManager->expects($this->once())
645
+            ->method('search')
646
+            ->with($this->equalTo(''), $this->equalTo(['FN', 'EMAIL']))
647
+            ->willReturn([
648
+                [
649
+                    'UID' => 'user1',
650
+                    'isLocalSystemBook' => true
651
+                ],
652
+                [
653
+                    'UID' => 'user2',
654
+                    'isLocalSystemBook' => true
655
+                ],
656
+                [
657
+                    'UID' => 'user3',
658
+                    'isLocalSystemBook' => true
659
+                ],
660
+                [
661
+                    'UID' => 'contact',
662
+                ],
663
+            ]);
664
+
665
+        $entries = $this->contactsStore->getContacts($currentUser, '');
666
+
667
+        $this->assertCount(3, $entries);
668
+        $this->assertEquals('user1', $entries[0]->getProperty('UID'));
669
+        $this->assertEquals('user2', $entries[1]->getProperty('UID'));
670
+        $this->assertEquals('contact', $entries[2]->getProperty('UID'));
671
+    }
672
+
673
+    public function testGetContactsWithFilter(): void {
674
+        $this->config
675
+            ->method('getAppValue')
676
+            ->willReturnMap([
677
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
678
+                ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
679
+            ]);
680
+
681
+        /** @var IUser|MockObject $user */
682
+        $user = $this->createMock(IUser::class);
683
+        $this->contactsManager->expects($this->any())
684
+            ->method('search')
685
+            ->willReturn([
686
+                [
687
+                    'UID' => 'a567',
688
+                    'FN' => 'Darren Roner',
689
+                    'EMAIL' => [
690
+                        '[email protected]',
691
+                    ],
692
+                    'isLocalSystemBook' => true,
693
+                ],
694
+                [
695
+                    'UID' => 'john',
696
+                    'FN' => 'John Doe',
697
+                    'EMAIL' => [
698
+                        '[email protected]',
699
+                    ],
700
+                    'isLocalSystemBook' => true,
701
+                ],
702
+                [
703
+                    'FN' => 'Anne D',
704
+                    'EMAIL' => [
705
+                        '[email protected]',
706
+                    ],
707
+                    'isLocalSystemBook' => false,
708
+                ],
709
+            ]);
710
+        $user->expects($this->any())
711
+            ->method('getUID')
712
+            ->willReturn('user123');
713
+
714
+        // Complete match on UID should match
715
+        $entry = $this->contactsStore->getContacts($user, 'a567');
716
+        $this->assertSame(2, count($entry));
717
+        $this->assertEquals([
718
+            '[email protected]'
719
+        ], $entry[0]->getEMailAddresses());
720
+
721
+        // Partial match on UID should not match
722
+        $entry = $this->contactsStore->getContacts($user, 'a56');
723
+        $this->assertSame(1, count($entry));
724
+        $this->assertEquals([
725
+            '[email protected]'
726
+        ], $entry[0]->getEMailAddresses());
727
+
728
+        // Complete match on email should match
729
+        $entry = $this->contactsStore->getContacts($user, '[email protected]');
730
+        $this->assertSame(2, count($entry));
731
+        $this->assertEquals([
732
+            '[email protected]'
733
+        ], $entry[0]->getEMailAddresses());
734
+        $this->assertEquals([
735
+            '[email protected]'
736
+        ], $entry[1]->getEMailAddresses());
737
+
738
+        // Partial match on email should not match
739
+        $entry = $this->contactsStore->getContacts($user, '[email protected]');
740
+        $this->assertSame(1, count($entry));
741
+        $this->assertEquals([
742
+            '[email protected]'
743
+        ], $entry[0]->getEMailAddresses());
744
+
745
+        // Match on FN should not match
746
+        $entry = $this->contactsStore->getContacts($user, 'Darren Roner');
747
+        $this->assertSame(1, count($entry));
748
+        $this->assertEquals([
749
+            '[email protected]'
750
+        ], $entry[0]->getEMailAddresses());
751
+
752
+        // Don't filter users in local addressbook
753
+        $entry = $this->contactsStore->getContacts($user, 'Anne D');
754
+        $this->assertSame(1, count($entry));
755
+        $this->assertEquals([
756
+            '[email protected]'
757
+        ], $entry[0]->getEMailAddresses());
758
+    }
759
+
760
+    public function testGetContactsWithFilterWithoutFullMatch(): void {
761
+        $this->config
762
+            ->method('getAppValue')
763
+            ->willReturnMap([
764
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'no'],
765
+                ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'no'],
766
+            ]);
767
+
768
+        /** @var IUser|MockObject $user */
769
+        $user = $this->createMock(IUser::class);
770
+        $this->contactsManager->expects($this->any())
771
+            ->method('search')
772
+            ->willReturn([
773
+                [
774
+                    'UID' => 'a567',
775
+                    'FN' => 'Darren Roner',
776
+                    'EMAIL' => [
777
+                        '[email protected]',
778
+                    ],
779
+                    'isLocalSystemBook' => true,
780
+                ],
781
+                [
782
+                    'UID' => 'john',
783
+                    'FN' => 'John Doe',
784
+                    'EMAIL' => [
785
+                        '[email protected]',
786
+                    ],
787
+                    'isLocalSystemBook' => true,
788
+                ],
789
+                [
790
+                    'FN' => 'Anne D',
791
+                    'EMAIL' => [
792
+                        '[email protected]',
793
+                    ],
794
+                    'isLocalSystemBook' => false,
795
+                ],
796
+            ]);
797
+        $user->expects($this->any())
798
+            ->method('getUID')
799
+            ->willReturn('user123');
800
+
801
+        // Complete match on UID should not match
802
+        $entry = $this->contactsStore->getContacts($user, 'a567');
803
+        $this->assertSame(1, count($entry));
804
+        $this->assertEquals([
805
+            '[email protected]'
806
+        ], $entry[0]->getEMailAddresses());
807
+
808
+        // Partial match on UID should not match
809
+        $entry = $this->contactsStore->getContacts($user, 'a56');
810
+        $this->assertSame(1, count($entry));
811
+        $this->assertEquals([
812
+            '[email protected]'
813
+        ], $entry[0]->getEMailAddresses());
814
+
815
+        // Complete match on email should not match
816
+        $entry = $this->contactsStore->getContacts($user, '[email protected]');
817
+        $this->assertSame(1, count($entry));
818
+        $this->assertEquals([
819
+            '[email protected]'
820
+        ], $entry[0]->getEMailAddresses());
821
+
822
+        // Partial match on email should not match
823
+        $entry = $this->contactsStore->getContacts($user, '[email protected]');
824
+        $this->assertSame(1, count($entry));
825
+        $this->assertEquals([
826
+            '[email protected]'
827
+        ], $entry[0]->getEMailAddresses());
828
+
829
+        // Match on FN should not match
830
+        $entry = $this->contactsStore->getContacts($user, 'Darren Roner');
831
+        $this->assertSame(1, count($entry));
832
+        $this->assertEquals([
833
+            '[email protected]'
834
+        ], $entry[0]->getEMailAddresses());
835
+
836
+        // Don't filter users in local addressbook
837
+        $entry = $this->contactsStore->getContacts($user, 'Anne D');
838
+        $this->assertSame(1, count($entry));
839
+        $this->assertEquals([
840
+            '[email protected]'
841
+        ], $entry[0]->getEMailAddresses());
842
+    }
843
+
844
+    public function testFindOneUser(): void {
845
+        $this->config
846
+            ->method('getAppValue')
847
+            ->willReturnMap([
848
+                ['core', 'shareapi_allow_share_dialog_user_enumeration', 'yes', 'yes'],
849
+                ['core', 'shareapi_restrict_user_enumeration_to_group', 'no', 'no'],
850
+                ['core', 'shareapi_restrict_user_enumeration_to_phone', 'no', 'no'],
851
+                ['core', 'shareapi_restrict_user_enumeration_full_match', 'yes', 'yes'],
852
+                ['core', 'shareapi_exclude_groups', 'no', 'yes'],
853
+                ['core', 'shareapi_exclude_groups_list', '', ''],
854
+                ['core', 'shareapi_only_share_with_group_members', 'no', 'no'],
855
+            ]);
856
+
857
+        /** @var IUser|MockObject $user */
858
+        $user = $this->createMock(IUser::class);
859
+        $this->contactsManager->expects($this->once())
860
+            ->method('search')
861
+            ->with($this->equalTo('a567'), $this->equalTo(['UID']))
862
+            ->willReturn([
863
+                [
864
+                    'UID' => 123,
865
+                    'isLocalSystemBook' => false
866
+                ],
867
+                [
868
+                    'UID' => 'a567',
869
+                    'FN' => 'Darren Roner',
870
+                    'EMAIL' => [
871
+                        '[email protected]'
872
+                    ],
873
+                    'isLocalSystemBook' => true
874
+                ],
875
+            ]);
876
+        $user->expects($this->any())
877
+            ->method('getUID')
878
+            ->willReturn('user123');
879
+
880
+        $entry = $this->contactsStore->findOne($user, 0, 'a567');
881
+
882
+        $this->assertEquals([
883
+            '[email protected]'
884
+        ], $entry->getEMailAddresses());
885
+    }
886
+
887
+    public function testFindOneEMail(): void {
888
+        /** @var IUser|MockObject $user */
889
+        $user = $this->createMock(IUser::class);
890
+        $this->contactsManager->expects($this->once())
891
+            ->method('search')
892
+            ->with($this->equalTo('[email protected]'), $this->equalTo(['EMAIL']))
893
+            ->willReturn([
894
+                [
895
+                    'UID' => 123,
896
+                    'isLocalSystemBook' => false
897
+                ],
898
+                [
899
+                    'UID' => 'a567',
900
+                    'FN' => 'Darren Roner',
901
+                    'EMAIL' => [
902
+                        '[email protected]'
903
+                    ],
904
+                    'isLocalSystemBook' => false
905
+                ],
906
+            ]);
907
+        $user->expects($this->any())
908
+            ->method('getUID')
909
+            ->willReturn('user123');
910
+
911
+        $entry = $this->contactsStore->findOne($user, 4, '[email protected]');
912
+
913
+        $this->assertEquals([
914
+            '[email protected]'
915
+        ], $entry->getEMailAddresses());
916
+    }
917
+
918
+    public function testFindOneNotSupportedType(): void {
919
+        /** @var IUser|MockObject $user */
920
+        $user = $this->createMock(IUser::class);
921
+
922
+        $entry = $this->contactsStore->findOne($user, 42, '[email protected]');
923
+
924
+        $this->assertEquals(null, $entry);
925
+    }
926
+
927
+    public function testFindOneNoMatches(): void {
928
+        /** @var IUser|MockObject $user */
929
+        $user = $this->createMock(IUser::class);
930
+        $this->contactsManager->expects($this->once())
931
+            ->method('search')
932
+            ->with($this->equalTo('a567'), $this->equalTo(['UID']))
933
+            ->willReturn([
934
+                [
935
+                    'UID' => 123,
936
+                    'isLocalSystemBook' => false
937
+                ],
938
+                [
939
+                    'UID' => 'a567',
940
+                    'FN' => 'Darren Roner',
941
+                    'EMAIL' => [
942
+                        '[email protected]'
943
+                    ],
944
+                    'isLocalSystemBook' => false
945
+                ],
946
+            ]);
947
+        $user->expects($this->never())
948
+            ->method('getUID');
949
+
950
+        $entry = $this->contactsStore->findOne($user, 0, 'a567');
951
+
952
+        $this->assertEquals(null, $entry);
953
+    }
954
+
955
+    public function testGetRecentStatusFirst(): void {
956
+        $user = $this->createMock(IUser::class);
957
+        $status1 = new UserStatus();
958
+        $status1->setUserId('user1');
959
+        $status2 = new UserStatus();
960
+        $status2->setUserId('user2');
961
+        $this->statusService->expects(self::once())
962
+            ->method('findAllRecentStatusChanges')
963
+            ->willReturn([
964
+                $status1,
965
+                $status2,
966
+            ]);
967
+        $user1 = $this->createMock(IUser::class);
968
+        $user1->method('getCloudId')->willReturn('user1@localcloud');
969
+        $user2 = $this->createMock(IUser::class);
970
+        $user2->method('getCloudId')->willReturn('user2@localcloud');
971
+        $this->userManager->expects(self::exactly(2))
972
+            ->method('get')
973
+            ->willReturnCallback(function ($uid) use ($user1, $user2) {
974
+                return match ($uid) {
975
+                    'user1' => $user1,
976
+                    'user2' => $user2,
977
+                };
978
+            });
979
+        $this->contactsManager
980
+            ->expects(self::exactly(3))
981
+            ->method('search')
982
+            ->willReturnCallback(function ($uid, $searchProps, $options) {
983
+                return match ([$uid, $options['limit'] ?? null]) {
984
+                    ['user1@localcloud', 1] => [
985
+                        [
986
+                            'UID' => 'user1',
987
+                            'URI' => 'user1.vcf',
988
+                        ],
989
+                    ],
990
+                    ['user2@localcloud' => [], 1], // Simulate not found
991
+                    ['', 4] => [
992
+                        [
993
+                            'UID' => 'contact1',
994
+                            'URI' => 'contact1.vcf',
995
+                        ],
996
+                        [
997
+                            'UID' => 'contact2',
998
+                            'URI' => 'contact2.vcf',
999
+                        ],
1000
+                    ],
1001
+                    default => [],
1002
+                };
1003
+            });
1004
+
1005
+        $contacts = $this->contactsStore->getContacts(
1006
+            $user,
1007
+            null,
1008
+            5,
1009
+        );
1010
+
1011
+        self::assertCount(3, $contacts);
1012
+        self::assertEquals('user1', $contacts[0]->getProperty('UID'));
1013
+        self::assertEquals('contact1', $contacts[1]->getProperty('UID'));
1014
+        self::assertEquals('contact2', $contacts[2]->getProperty('UID'));
1015
+    }
1016
+
1017
+    public function testPaginateRecentStatus(): void {
1018
+        $user = $this->createMock(IUser::class);
1019
+        $status1 = new UserStatus();
1020
+        $status1->setUserId('user1');
1021
+        $status2 = new UserStatus();
1022
+        $status2->setUserId('user2');
1023
+        $status3 = new UserStatus();
1024
+        $status3->setUserId('user3');
1025
+        $this->statusService->expects(self::never())
1026
+            ->method('findAllRecentStatusChanges');
1027
+        $this->contactsManager
1028
+            ->expects(self::exactly(2))
1029
+            ->method('search')
1030
+            ->willReturnCallback(function ($uid, $searchProps, $options) {
1031
+                return match ([$uid, $options['limit'] ?? null, $options['offset'] ?? null]) {
1032
+                    ['', 2, 0] => [
1033
+                        [
1034
+                            'UID' => 'contact1',
1035
+                            'URI' => 'contact1.vcf',
1036
+                        ],
1037
+                        [
1038
+                            'UID' => 'contact2',
1039
+                            'URI' => 'contact2.vcf',
1040
+                        ],
1041
+                    ],
1042
+                    ['', 2, 3] => [
1043
+                        [
1044
+                            'UID' => 'contact3',
1045
+                            'URI' => 'contact3.vcf',
1046
+                        ],
1047
+                    ],
1048
+                    default => [],
1049
+                };
1050
+            });
1051
+
1052
+        $page1 = $this->contactsStore->getContacts(
1053
+            $user,
1054
+            null,
1055
+            2,
1056
+            0,
1057
+        );
1058
+        $page2 = $this->contactsStore->getContacts(
1059
+            $user,
1060
+            null,
1061
+            2,
1062
+            3,
1063
+        );
1064
+
1065
+        self::assertCount(2, $page1);
1066
+        self::assertCount(1, $page2);
1067
+    }
1068 1068
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -26,7 +26,7 @@  discard block
 block discarded – undo
26 26
 
27 27
 class ContactsStoreTest extends TestCase {
28 28
 	private ContactsStore $contactsStore;
29
-	private StatusService|MockObject $statusService;
29
+	private StatusService | MockObject $statusService;
30 30
 	/** @var IManager|MockObject */
31 31
 	private $contactsManager;
32 32
 	/** @var ProfileManager */
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
 		];
264 264
 		$this->groupManager->expects($this->exactly(4))
265 265
 			->method('getUserGroupIds')
266
-			->willReturnCallback(function () use (&$calls): array {
266
+			->willReturnCallback(function() use (&$calls): array {
267 267
 				$expected = array_shift($calls);
268 268
 				$this->assertEquals($expected[0], func_get_args());
269 269
 				return $expected[1];
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
 		];
337 337
 		$this->groupManager->expects($this->exactly(4))
338 338
 			->method('getUserGroupIds')
339
-			->willReturnCallback(function () use (&$calls): array {
339
+			->willReturnCallback(function() use (&$calls): array {
340 340
 				$expected = array_shift($calls);
341 341
 				$this->assertEquals($expected[0], func_get_args());
342 342
 				return $expected[1];
@@ -467,7 +467,7 @@  discard block
 block discarded – undo
467 467
 		];
468 468
 		$this->groupManager->expects($this->exactly(4))
469 469
 			->method('getUserGroupIds')
470
-			->willReturnCallback(function () use (&$calls): array {
470
+			->willReturnCallback(function() use (&$calls): array {
471 471
 				$expected = array_shift($calls);
472 472
 				$this->assertEquals($expected[0], func_get_args());
473 473
 				return $expected[1];
@@ -542,7 +542,7 @@  discard block
 block discarded – undo
542 542
 		];
543 543
 		$this->groupManager->expects($this->exactly(2))
544 544
 			->method('getUserGroupIds')
545
-			->willReturnCallback(function () use (&$calls): array {
545
+			->willReturnCallback(function() use (&$calls): array {
546 546
 				$expected = array_shift($calls);
547 547
 				$this->assertEquals($expected[0], func_get_args());
548 548
 				return $expected[1];
@@ -620,7 +620,7 @@  discard block
 block discarded – undo
620 620
 		];
621 621
 		$this->groupManager->expects($this->exactly(4))
622 622
 			->method('getUserGroupIds')
623
-			->willReturnCallback(function () use (&$calls): array {
623
+			->willReturnCallback(function() use (&$calls): array {
624 624
 				$expected = array_shift($calls);
625 625
 				$this->assertEquals($expected[0], func_get_args());
626 626
 				return $expected[1];
@@ -970,7 +970,7 @@  discard block
 block discarded – undo
970 970
 		$user2->method('getCloudId')->willReturn('user2@localcloud');
971 971
 		$this->userManager->expects(self::exactly(2))
972 972
 			->method('get')
973
-			->willReturnCallback(function ($uid) use ($user1, $user2) {
973
+			->willReturnCallback(function($uid) use ($user1, $user2) {
974 974
 				return match ($uid) {
975 975
 					'user1' => $user1,
976 976
 					'user2' => $user2,
@@ -979,7 +979,7 @@  discard block
 block discarded – undo
979 979
 		$this->contactsManager
980 980
 			->expects(self::exactly(3))
981 981
 			->method('search')
982
-			->willReturnCallback(function ($uid, $searchProps, $options) {
982
+			->willReturnCallback(function($uid, $searchProps, $options) {
983 983
 				return match ([$uid, $options['limit'] ?? null]) {
984 984
 					['user1@localcloud', 1] => [
985 985
 						[
@@ -1027,7 +1027,7 @@  discard block
 block discarded – undo
1027 1027
 		$this->contactsManager
1028 1028
 			->expects(self::exactly(2))
1029 1029
 			->method('search')
1030
-			->willReturnCallback(function ($uid, $searchProps, $options) {
1030
+			->willReturnCallback(function($uid, $searchProps, $options) {
1031 1031
 				return match ([$uid, $options['limit'] ?? null, $options['offset'] ?? null]) {
1032 1032
 					['', 2, 0] => [
1033 1033
 						[
Please login to merge, or discard this patch.
tests/lib/Contacts/ContactsMenu/ManagerTest.php 1 patch
Indentation   +178 added lines, -178 removed lines patch added patch discarded remove patch
@@ -20,182 +20,182 @@
 block discarded – undo
20 20
 use Test\TestCase;
21 21
 
22 22
 class ManagerTest extends TestCase {
23
-	/** @var ContactsStore|MockObject */
24
-	private $contactsStore;
25
-
26
-	/** @var IAppManager|MockObject */
27
-	private $appManager;
28
-
29
-	/** @var IConfig|MockObject */
30
-	private $config;
31
-
32
-	/** @var ActionProviderStore|MockObject */
33
-	private $actionProviderStore;
34
-
35
-	private Manager $manager;
36
-
37
-	protected function setUp(): void {
38
-		parent::setUp();
39
-
40
-		$this->contactsStore = $this->createMock(ContactsStore::class);
41
-		$this->actionProviderStore = $this->createMock(ActionProviderStore::class);
42
-		$this->appManager = $this->createMock(IAppManager::class);
43
-		$this->config = $this->createMock(IConfig::class);
44
-
45
-		$this->manager = new Manager($this->contactsStore, $this->actionProviderStore, $this->appManager, $this->config);
46
-	}
47
-
48
-	private function generateTestEntries(): array {
49
-		$entries = [];
50
-		foreach (range('Z', 'A') as $char) {
51
-			$entry = $this->createMock(Entry::class);
52
-			$entry->expects($this->any())
53
-				->method('getFullName')
54
-				->willReturn('Contact ' . $char);
55
-			$entries[] = $entry;
56
-		}
57
-		return $entries;
58
-	}
59
-
60
-	public function testGetFilteredEntries(): void {
61
-		$filter = 'con';
62
-		$user = $this->createMock(IUser::class);
63
-		$entries = $this->generateTestEntries();
64
-		$provider = $this->createMock(IProvider::class);
65
-
66
-		$this->config->expects($this->exactly(2))
67
-			->method('getSystemValueInt')
68
-			->willReturnMap([
69
-				['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 25],
70
-				['sharing.minSearchStringLength', 0, 0],
71
-			]);
72
-		$this->contactsStore->expects($this->once())
73
-			->method('getContacts')
74
-			->with($user, $filter)
75
-			->willReturn($entries);
76
-		$this->actionProviderStore->expects($this->once())
77
-			->method('getProviders')
78
-			->with($user)
79
-			->willReturn([$provider]);
80
-		$provider->expects($this->exactly(25))
81
-			->method('process');
82
-		$this->appManager->expects($this->once())
83
-			->method('isEnabledForUser')
84
-			->with($this->equalTo('contacts'), $user)
85
-			->willReturn(false);
86
-		$expected = [
87
-			'contacts' => array_slice($entries, 0, 25),
88
-			'contactsAppEnabled' => false,
89
-		];
90
-
91
-		$data = $this->manager->getEntries($user, $filter);
92
-
93
-		$this->assertEquals($expected, $data);
94
-	}
95
-
96
-	public function testGetFilteredEntriesLimit(): void {
97
-		$filter = 'con';
98
-		$user = $this->createMock(IUser::class);
99
-		$entries = $this->generateTestEntries();
100
-		$provider = $this->createMock(IProvider::class);
101
-
102
-		$this->config->expects($this->exactly(2))
103
-			->method('getSystemValueInt')
104
-			->willReturnMap([
105
-				['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3],
106
-				['sharing.minSearchStringLength', 0, 0],
107
-			]);
108
-		$this->contactsStore->expects($this->once())
109
-			->method('getContacts')
110
-			->with($user, $filter)
111
-			->willReturn($entries);
112
-		$this->actionProviderStore->expects($this->once())
113
-			->method('getProviders')
114
-			->with($user)
115
-			->willReturn([$provider]);
116
-		$provider->expects($this->exactly(3))
117
-			->method('process');
118
-		$this->appManager->expects($this->once())
119
-			->method('isEnabledForUser')
120
-			->with($this->equalTo('contacts'), $user)
121
-			->willReturn(false);
122
-		$expected = [
123
-			'contacts' => array_slice($entries, 0, 3),
124
-			'contactsAppEnabled' => false,
125
-		];
126
-
127
-		$data = $this->manager->getEntries($user, $filter);
128
-
129
-		$this->assertEquals($expected, $data);
130
-	}
131
-
132
-	public function testGetFilteredEntriesMinSearchStringLength(): void {
133
-		$filter = 'con';
134
-		$user = $this->createMock(IUser::class);
135
-		$provider = $this->createMock(IProvider::class);
136
-
137
-		$this->config->expects($this->exactly(2))
138
-			->method('getSystemValueInt')
139
-			->willReturnMap([
140
-				['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3],
141
-				['sharing.minSearchStringLength', 0, 4],
142
-			]);
143
-		$this->appManager->expects($this->once())
144
-			->method('isEnabledForUser')
145
-			->with($this->equalTo('contacts'), $user)
146
-			->willReturn(false);
147
-		$expected = [
148
-			'contacts' => [],
149
-			'contactsAppEnabled' => false,
150
-		];
151
-
152
-		$data = $this->manager->getEntries($user, $filter);
153
-
154
-		$this->assertEquals($expected, $data);
155
-	}
156
-
157
-	public function testFindOne(): void {
158
-		$shareTypeFilter = 42;
159
-		$shareWithFilter = 'foobar';
160
-
161
-		$user = $this->createMock(IUser::class);
162
-		$entry = current($this->generateTestEntries());
163
-		$provider = $this->createMock(IProvider::class);
164
-		$this->contactsStore->expects($this->once())
165
-			->method('findOne')
166
-			->with($user, $shareTypeFilter, $shareWithFilter)
167
-			->willReturn($entry);
168
-		$this->actionProviderStore->expects($this->once())
169
-			->method('getProviders')
170
-			->with($user)
171
-			->willReturn([$provider]);
172
-		$provider->expects($this->once())
173
-			->method('process');
174
-
175
-		$data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter);
176
-
177
-		$this->assertEquals($entry, $data);
178
-	}
179
-
180
-	public function testFindOne404(): void {
181
-		$shareTypeFilter = 42;
182
-		$shareWithFilter = 'foobar';
183
-
184
-		$user = $this->createMock(IUser::class);
185
-		$provider = $this->createMock(IProvider::class);
186
-		$this->contactsStore->expects($this->once())
187
-			->method('findOne')
188
-			->with($user, $shareTypeFilter, $shareWithFilter)
189
-			->willReturn(null);
190
-		$this->actionProviderStore->expects($this->never())
191
-			->method('getProviders')
192
-			->with($user)
193
-			->willReturn([$provider]);
194
-		$provider->expects($this->never())
195
-			->method('process');
196
-
197
-		$data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter);
198
-
199
-		$this->assertEquals(null, $data);
200
-	}
23
+    /** @var ContactsStore|MockObject */
24
+    private $contactsStore;
25
+
26
+    /** @var IAppManager|MockObject */
27
+    private $appManager;
28
+
29
+    /** @var IConfig|MockObject */
30
+    private $config;
31
+
32
+    /** @var ActionProviderStore|MockObject */
33
+    private $actionProviderStore;
34
+
35
+    private Manager $manager;
36
+
37
+    protected function setUp(): void {
38
+        parent::setUp();
39
+
40
+        $this->contactsStore = $this->createMock(ContactsStore::class);
41
+        $this->actionProviderStore = $this->createMock(ActionProviderStore::class);
42
+        $this->appManager = $this->createMock(IAppManager::class);
43
+        $this->config = $this->createMock(IConfig::class);
44
+
45
+        $this->manager = new Manager($this->contactsStore, $this->actionProviderStore, $this->appManager, $this->config);
46
+    }
47
+
48
+    private function generateTestEntries(): array {
49
+        $entries = [];
50
+        foreach (range('Z', 'A') as $char) {
51
+            $entry = $this->createMock(Entry::class);
52
+            $entry->expects($this->any())
53
+                ->method('getFullName')
54
+                ->willReturn('Contact ' . $char);
55
+            $entries[] = $entry;
56
+        }
57
+        return $entries;
58
+    }
59
+
60
+    public function testGetFilteredEntries(): void {
61
+        $filter = 'con';
62
+        $user = $this->createMock(IUser::class);
63
+        $entries = $this->generateTestEntries();
64
+        $provider = $this->createMock(IProvider::class);
65
+
66
+        $this->config->expects($this->exactly(2))
67
+            ->method('getSystemValueInt')
68
+            ->willReturnMap([
69
+                ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 25],
70
+                ['sharing.minSearchStringLength', 0, 0],
71
+            ]);
72
+        $this->contactsStore->expects($this->once())
73
+            ->method('getContacts')
74
+            ->with($user, $filter)
75
+            ->willReturn($entries);
76
+        $this->actionProviderStore->expects($this->once())
77
+            ->method('getProviders')
78
+            ->with($user)
79
+            ->willReturn([$provider]);
80
+        $provider->expects($this->exactly(25))
81
+            ->method('process');
82
+        $this->appManager->expects($this->once())
83
+            ->method('isEnabledForUser')
84
+            ->with($this->equalTo('contacts'), $user)
85
+            ->willReturn(false);
86
+        $expected = [
87
+            'contacts' => array_slice($entries, 0, 25),
88
+            'contactsAppEnabled' => false,
89
+        ];
90
+
91
+        $data = $this->manager->getEntries($user, $filter);
92
+
93
+        $this->assertEquals($expected, $data);
94
+    }
95
+
96
+    public function testGetFilteredEntriesLimit(): void {
97
+        $filter = 'con';
98
+        $user = $this->createMock(IUser::class);
99
+        $entries = $this->generateTestEntries();
100
+        $provider = $this->createMock(IProvider::class);
101
+
102
+        $this->config->expects($this->exactly(2))
103
+            ->method('getSystemValueInt')
104
+            ->willReturnMap([
105
+                ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3],
106
+                ['sharing.minSearchStringLength', 0, 0],
107
+            ]);
108
+        $this->contactsStore->expects($this->once())
109
+            ->method('getContacts')
110
+            ->with($user, $filter)
111
+            ->willReturn($entries);
112
+        $this->actionProviderStore->expects($this->once())
113
+            ->method('getProviders')
114
+            ->with($user)
115
+            ->willReturn([$provider]);
116
+        $provider->expects($this->exactly(3))
117
+            ->method('process');
118
+        $this->appManager->expects($this->once())
119
+            ->method('isEnabledForUser')
120
+            ->with($this->equalTo('contacts'), $user)
121
+            ->willReturn(false);
122
+        $expected = [
123
+            'contacts' => array_slice($entries, 0, 3),
124
+            'contactsAppEnabled' => false,
125
+        ];
126
+
127
+        $data = $this->manager->getEntries($user, $filter);
128
+
129
+        $this->assertEquals($expected, $data);
130
+    }
131
+
132
+    public function testGetFilteredEntriesMinSearchStringLength(): void {
133
+        $filter = 'con';
134
+        $user = $this->createMock(IUser::class);
135
+        $provider = $this->createMock(IProvider::class);
136
+
137
+        $this->config->expects($this->exactly(2))
138
+            ->method('getSystemValueInt')
139
+            ->willReturnMap([
140
+                ['sharing.maxAutocompleteResults', Constants::SHARING_MAX_AUTOCOMPLETE_RESULTS_DEFAULT, 3],
141
+                ['sharing.minSearchStringLength', 0, 4],
142
+            ]);
143
+        $this->appManager->expects($this->once())
144
+            ->method('isEnabledForUser')
145
+            ->with($this->equalTo('contacts'), $user)
146
+            ->willReturn(false);
147
+        $expected = [
148
+            'contacts' => [],
149
+            'contactsAppEnabled' => false,
150
+        ];
151
+
152
+        $data = $this->manager->getEntries($user, $filter);
153
+
154
+        $this->assertEquals($expected, $data);
155
+    }
156
+
157
+    public function testFindOne(): void {
158
+        $shareTypeFilter = 42;
159
+        $shareWithFilter = 'foobar';
160
+
161
+        $user = $this->createMock(IUser::class);
162
+        $entry = current($this->generateTestEntries());
163
+        $provider = $this->createMock(IProvider::class);
164
+        $this->contactsStore->expects($this->once())
165
+            ->method('findOne')
166
+            ->with($user, $shareTypeFilter, $shareWithFilter)
167
+            ->willReturn($entry);
168
+        $this->actionProviderStore->expects($this->once())
169
+            ->method('getProviders')
170
+            ->with($user)
171
+            ->willReturn([$provider]);
172
+        $provider->expects($this->once())
173
+            ->method('process');
174
+
175
+        $data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter);
176
+
177
+        $this->assertEquals($entry, $data);
178
+    }
179
+
180
+    public function testFindOne404(): void {
181
+        $shareTypeFilter = 42;
182
+        $shareWithFilter = 'foobar';
183
+
184
+        $user = $this->createMock(IUser::class);
185
+        $provider = $this->createMock(IProvider::class);
186
+        $this->contactsStore->expects($this->once())
187
+            ->method('findOne')
188
+            ->with($user, $shareTypeFilter, $shareWithFilter)
189
+            ->willReturn(null);
190
+        $this->actionProviderStore->expects($this->never())
191
+            ->method('getProviders')
192
+            ->with($user)
193
+            ->willReturn([$provider]);
194
+        $provider->expects($this->never())
195
+            ->method('process');
196
+
197
+        $data = $this->manager->findOne($user, $shareTypeFilter, $shareWithFilter);
198
+
199
+        $this->assertEquals(null, $data);
200
+    }
201 201
 }
Please login to merge, or discard this patch.
tests/lib/Http/Client/ClientTest.php 1 patch
Indentation   +564 added lines, -564 removed lines patch added patch discarded remove patch
@@ -25,568 +25,568 @@
 block discarded – undo
25 25
  * Class ClientTest
26 26
  */
27 27
 class ClientTest extends \Test\TestCase {
28
-	/** @var \GuzzleHttp\Client|MockObject */
29
-	private $guzzleClient;
30
-	/** @var CertificateManager|MockObject */
31
-	private $certificateManager;
32
-	/** @var Client */
33
-	private $client;
34
-	/** @var IConfig|MockObject */
35
-	private $config;
36
-	/** @var IRemoteHostValidator|MockObject */
37
-	private IRemoteHostValidator $remoteHostValidator;
38
-	private LoggerInterface $logger;
39
-	/** @var array */
40
-	private $defaultRequestOptions;
41
-
42
-	protected function setUp(): void {
43
-		parent::setUp();
44
-		$this->config = $this->createMock(IConfig::class);
45
-		$this->guzzleClient = $this->createMock(\GuzzleHttp\Client::class);
46
-		$this->certificateManager = $this->createMock(ICertificateManager::class);
47
-		$this->remoteHostValidator = $this->createMock(IRemoteHostValidator::class);
48
-		$this->logger = $this->createMock(LoggerInterface::class);
49
-		$this->client = new Client(
50
-			$this->config,
51
-			$this->certificateManager,
52
-			$this->guzzleClient,
53
-			$this->remoteHostValidator,
54
-			$this->logger,
55
-		);
56
-	}
57
-
58
-	public function testGetProxyUri(): void {
59
-		$this->config
60
-			->method('getSystemValueString')
61
-			->with('proxy', '')
62
-			->willReturn('');
63
-		$this->assertNull(self::invokePrivate($this->client, 'getProxyUri'));
64
-	}
65
-
66
-	public function testGetProxyUriProxyHostEmptyPassword(): void {
67
-		$this->config
68
-			->method('getSystemValue')
69
-			->will($this->returnValueMap([
70
-				['proxyexclude', [], []],
71
-			]));
72
-
73
-		$this->config
74
-			->method('getSystemValueString')
75
-			->will($this->returnValueMap([
76
-				['proxy', '', 'foo'],
77
-				['proxyuserpwd', '', ''],
78
-			]));
79
-
80
-		$this->assertEquals([
81
-			'http' => 'foo',
82
-			'https' => 'foo'
83
-		], self::invokePrivate($this->client, 'getProxyUri'));
84
-	}
85
-
86
-	public function testGetProxyUriProxyHostWithPassword(): void {
87
-		$this->config
88
-			->expects($this->once())
89
-			->method('getSystemValue')
90
-			->with('proxyexclude', [])
91
-			->willReturn([]);
92
-		$this->config
93
-			->expects($this->exactly(2))
94
-			->method('getSystemValueString')
95
-			->willReturnMap([
96
-				['proxy', '', 'foo'],
97
-				['proxyuserpwd', '', 'username:password'],
98
-			]);
99
-		$this->assertEquals([
100
-			'http' => 'username:password@foo',
101
-			'https' => 'username:password@foo'
102
-		], self::invokePrivate($this->client, 'getProxyUri'));
103
-	}
104
-
105
-	public function testGetProxyUriProxyHostWithPasswordAndExclude(): void {
106
-		$this->config
107
-			->expects($this->once())
108
-			->method('getSystemValue')
109
-			->with('proxyexclude', [])
110
-			->willReturn(['bar']);
111
-		$this->config
112
-			->expects($this->exactly(2))
113
-			->method('getSystemValueString')
114
-			->willReturnMap([
115
-				['proxy', '', 'foo'],
116
-				['proxyuserpwd', '', 'username:password'],
117
-			]);
118
-		$this->assertEquals([
119
-			'http' => 'username:password@foo',
120
-			'https' => 'username:password@foo',
121
-			'no' => ['bar']
122
-		], self::invokePrivate($this->client, 'getProxyUri'));
123
-	}
124
-
125
-	public function testPreventLocalAddressThrowOnInvalidUri(): void {
126
-		$this->expectException(LocalServerException::class);
127
-		$this->expectExceptionMessage('Could not detect any host');
128
-
129
-		self::invokePrivate($this->client, 'preventLocalAddress', ['!@#$', []]);
130
-	}
131
-
132
-	public static function dataPreventLocalAddress(): array {
133
-		return [
134
-			['https://localhost/foo.bar'],
135
-			['https://localHost/foo.bar'],
136
-			['https://random-host/foo.bar'],
137
-			['https://[::1]/bla.blub'],
138
-			['https://[::]/bla.blub'],
139
-			['https://192.168.0.1'],
140
-			['https://172.16.42.1'],
141
-			['https://[fdf8:f53b:82e4::53]/secret.ics'],
142
-			['https://[fe80::200:5aee:feaa:20a2]/secret.ics'],
143
-			['https://[0:0:0:0:0:0:10.0.0.1]/secret.ics'],
144
-			['https://[0:0:0:0:0:ffff:127.0.0.0]/secret.ics'],
145
-			['https://10.0.0.1'],
146
-			['https://another-host.local'],
147
-			['https://service.localhost'],
148
-			['https://normal.host.com'],
149
-			['https://com.one-.nextcloud-one.com'],
150
-		];
151
-	}
152
-
153
-	/**
154
-	 * @dataProvider dataPreventLocalAddress
155
-	 * @param string $uri
156
-	 */
157
-	public function testPreventLocalAddressDisabledByGlobalConfig(string $uri): void {
158
-		$this->config->expects($this->once())
159
-			->method('getSystemValueBool')
160
-			->with('allow_local_remote_servers', false)
161
-			->willReturn(true);
162
-
163
-		self::invokePrivate($this->client, 'preventLocalAddress', [$uri, []]);
164
-	}
165
-
166
-	/**
167
-	 * @dataProvider dataPreventLocalAddress
168
-	 * @param string $uri
169
-	 */
170
-	public function testPreventLocalAddressDisabledByOption(string $uri): void {
171
-		$this->config->expects($this->never())
172
-			->method('getSystemValueBool');
173
-
174
-		self::invokePrivate($this->client, 'preventLocalAddress', [$uri, [
175
-			'nextcloud' => ['allow_local_address' => true],
176
-		]]);
177
-	}
178
-
179
-	/**
180
-	 * @dataProvider dataPreventLocalAddress
181
-	 * @param string $uri
182
-	 */
183
-	public function testPreventLocalAddressOnGet(string $uri): void {
184
-		$host = parse_url($uri, PHP_URL_HOST);
185
-		$this->expectException(LocalServerException::class);
186
-		$this->remoteHostValidator
187
-			->method('isValid')
188
-			->with($host)
189
-			->willReturn(false);
190
-
191
-		$this->client->get($uri);
192
-	}
193
-
194
-	/**
195
-	 * @dataProvider dataPreventLocalAddress
196
-	 * @param string $uri
197
-	 */
198
-	public function testPreventLocalAddressOnHead(string $uri): void {
199
-		$host = parse_url($uri, PHP_URL_HOST);
200
-		$this->expectException(LocalServerException::class);
201
-		$this->remoteHostValidator
202
-			->method('isValid')
203
-			->with($host)
204
-			->willReturn(false);
205
-
206
-		$this->client->head($uri);
207
-	}
208
-
209
-	/**
210
-	 * @dataProvider dataPreventLocalAddress
211
-	 * @param string $uri
212
-	 */
213
-	public function testPreventLocalAddressOnPost(string $uri): void {
214
-		$host = parse_url($uri, PHP_URL_HOST);
215
-		$this->expectException(LocalServerException::class);
216
-		$this->remoteHostValidator
217
-			->method('isValid')
218
-			->with($host)
219
-			->willReturn(false);
220
-
221
-		$this->client->post($uri);
222
-	}
223
-
224
-	/**
225
-	 * @dataProvider dataPreventLocalAddress
226
-	 * @param string $uri
227
-	 */
228
-	public function testPreventLocalAddressOnPut(string $uri): void {
229
-		$host = parse_url($uri, PHP_URL_HOST);
230
-		$this->expectException(LocalServerException::class);
231
-		$this->remoteHostValidator
232
-			->method('isValid')
233
-			->with($host)
234
-			->willReturn(false);
235
-
236
-		$this->client->put($uri);
237
-	}
238
-
239
-	/**
240
-	 * @dataProvider dataPreventLocalAddress
241
-	 * @param string $uri
242
-	 */
243
-	public function testPreventLocalAddressOnDelete(string $uri): void {
244
-		$host = parse_url($uri, PHP_URL_HOST);
245
-		$this->expectException(LocalServerException::class);
246
-		$this->remoteHostValidator
247
-			->method('isValid')
248
-			->with($host)
249
-			->willReturn(false);
250
-
251
-		$this->client->delete($uri);
252
-	}
253
-
254
-	private function setUpDefaultRequestOptions(): void {
255
-		$this->config
256
-			->method('getSystemValue')
257
-			->will($this->returnValueMap([
258
-				['proxyexclude', [], []],
259
-			]));
260
-		$this->config
261
-			->method('getSystemValueString')
262
-			->will($this->returnValueMap([
263
-				['proxy', '', 'foo'],
264
-				['proxyuserpwd', '', ''],
265
-			]));
266
-		$this->config
267
-			->method('getSystemValueBool')
268
-			->will($this->returnValueMap([
269
-				['installed', false, true],
270
-				['allow_local_remote_servers', false, true],
271
-			]));
272
-
273
-		$this->certificateManager
274
-			->expects($this->once())
275
-			->method('getAbsoluteBundlePath')
276
-			->with()
277
-			->willReturn('/my/path.crt');
278
-
279
-		$this->defaultRequestOptions = [
280
-			'verify' => '/my/path.crt',
281
-			'proxy' => [
282
-				'http' => 'foo',
283
-				'https' => 'foo'
284
-			],
285
-			'headers' => [
286
-				'User-Agent' => 'Nextcloud Server Crawler',
287
-				'Accept-Encoding' => 'gzip',
288
-			],
289
-			'timeout' => 30,
290
-			'nextcloud' => [
291
-				'allow_local_address' => true,
292
-			],
293
-		];
294
-	}
295
-
296
-	public function testGet(): void {
297
-		$this->setUpDefaultRequestOptions();
298
-
299
-		$this->guzzleClient->method('request')
300
-			->with('get', 'http://localhost/', $this->defaultRequestOptions)
301
-			->willReturn(new Response(418));
302
-		$this->assertEquals(418, $this->client->get('http://localhost/', [])->getStatusCode());
303
-	}
304
-
305
-	public function testGetWithOptions(): void {
306
-		$this->setUpDefaultRequestOptions();
307
-
308
-		$options = array_merge($this->defaultRequestOptions, [
309
-			'verify' => false,
310
-			'proxy' => [
311
-				'http' => 'bar',
312
-				'https' => 'bar'
313
-			],
314
-		]);
315
-
316
-		$this->guzzleClient->method('request')
317
-			->with('get', 'http://localhost/', $options)
318
-			->willReturn(new Response(418));
319
-		$this->assertEquals(418, $this->client->get('http://localhost/', $options)->getStatusCode());
320
-	}
321
-
322
-	public function testPost(): void {
323
-		$this->setUpDefaultRequestOptions();
324
-
325
-		$this->guzzleClient->method('request')
326
-			->with('post', 'http://localhost/', $this->defaultRequestOptions)
327
-			->willReturn(new Response(418));
328
-		$this->assertEquals(418, $this->client->post('http://localhost/', [])->getStatusCode());
329
-	}
330
-
331
-	public function testPostWithOptions(): void {
332
-		$this->setUpDefaultRequestOptions();
333
-
334
-		$options = array_merge($this->defaultRequestOptions, [
335
-			'verify' => false,
336
-			'proxy' => [
337
-				'http' => 'bar',
338
-				'https' => 'bar'
339
-			],
340
-		]);
341
-
342
-		$this->guzzleClient->method('request')
343
-			->with('post', 'http://localhost/', $options)
344
-			->willReturn(new Response(418));
345
-		$this->assertEquals(418, $this->client->post('http://localhost/', $options)->getStatusCode());
346
-	}
347
-
348
-	public function testPut(): void {
349
-		$this->setUpDefaultRequestOptions();
350
-
351
-		$this->guzzleClient->method('request')
352
-			->with('put', 'http://localhost/', $this->defaultRequestOptions)
353
-			->willReturn(new Response(418));
354
-		$this->assertEquals(418, $this->client->put('http://localhost/', [])->getStatusCode());
355
-	}
356
-
357
-	public function testPutWithOptions(): void {
358
-		$this->setUpDefaultRequestOptions();
359
-
360
-		$options = array_merge($this->defaultRequestOptions, [
361
-			'verify' => false,
362
-			'proxy' => [
363
-				'http' => 'bar',
364
-				'https' => 'bar'
365
-			],
366
-		]);
367
-
368
-		$this->guzzleClient->method('request')
369
-			->with('put', 'http://localhost/', $options)
370
-			->willReturn(new Response(418));
371
-		$this->assertEquals(418, $this->client->put('http://localhost/', $options)->getStatusCode());
372
-	}
373
-
374
-	public function testDelete(): void {
375
-		$this->setUpDefaultRequestOptions();
376
-
377
-		$this->guzzleClient->method('request')
378
-			->with('delete', 'http://localhost/', $this->defaultRequestOptions)
379
-			->willReturn(new Response(418));
380
-		$this->assertEquals(418, $this->client->delete('http://localhost/', [])->getStatusCode());
381
-	}
382
-
383
-	public function testDeleteWithOptions(): void {
384
-		$this->setUpDefaultRequestOptions();
385
-
386
-		$options = array_merge($this->defaultRequestOptions, [
387
-			'verify' => false,
388
-			'proxy' => [
389
-				'http' => 'bar',
390
-				'https' => 'bar'
391
-			],
392
-		]);
393
-
394
-		$this->guzzleClient->method('request')
395
-			->with('delete', 'http://localhost/', $options)
396
-			->willReturn(new Response(418));
397
-		$this->assertEquals(418, $this->client->delete('http://localhost/', $options)->getStatusCode());
398
-	}
399
-
400
-	public function testOptions(): void {
401
-		$this->setUpDefaultRequestOptions();
402
-
403
-		$this->guzzleClient->method('request')
404
-			->with('options', 'http://localhost/', $this->defaultRequestOptions)
405
-			->willReturn(new Response(418));
406
-		$this->assertEquals(418, $this->client->options('http://localhost/', [])->getStatusCode());
407
-	}
408
-
409
-	public function testOptionsWithOptions(): void {
410
-		$this->setUpDefaultRequestOptions();
411
-
412
-		$options = array_merge($this->defaultRequestOptions, [
413
-			'verify' => false,
414
-			'proxy' => [
415
-				'http' => 'bar',
416
-				'https' => 'bar'
417
-			],
418
-		]);
419
-
420
-		$this->guzzleClient->method('request')
421
-			->with('options', 'http://localhost/', $options)
422
-			->willReturn(new Response(418));
423
-		$this->assertEquals(418, $this->client->options('http://localhost/', $options)->getStatusCode());
424
-	}
425
-
426
-	public function testHead(): void {
427
-		$this->setUpDefaultRequestOptions();
428
-
429
-		$this->guzzleClient->method('request')
430
-			->with('head', 'http://localhost/', $this->defaultRequestOptions)
431
-			->willReturn(new Response(418));
432
-		$this->assertEquals(418, $this->client->head('http://localhost/', [])->getStatusCode());
433
-	}
434
-
435
-	public function testHeadWithOptions(): void {
436
-		$this->setUpDefaultRequestOptions();
437
-
438
-		$options = array_merge($this->defaultRequestOptions, [
439
-			'verify' => false,
440
-			'proxy' => [
441
-				'http' => 'bar',
442
-				'https' => 'bar'
443
-			],
444
-		]);
445
-
446
-		$this->guzzleClient->method('request')
447
-			->with('head', 'http://localhost/', $options)
448
-			->willReturn(new Response(418));
449
-		$this->assertEquals(418, $this->client->head('http://localhost/', $options)->getStatusCode());
450
-	}
451
-
452
-	public function testSetDefaultOptionsWithNotInstalled(): void {
453
-		$this->config
454
-			->expects($this->exactly(2))
455
-			->method('getSystemValueBool')
456
-			->willReturnMap([
457
-				['installed', false, false],
458
-				['allow_local_remote_servers', false, false],
459
-			]);
460
-		$this->config
461
-			->expects($this->once())
462
-			->method('getSystemValueString')
463
-			->with('proxy', '')
464
-			->willReturn('');
465
-		$this->certificateManager
466
-			->expects($this->never())
467
-			->method('listCertificates');
468
-
469
-		$this->assertEquals([
470
-			'verify' => \OC::$SERVERROOT . '/resources/config/ca-bundle.crt',
471
-			'headers' => [
472
-				'User-Agent' => 'Nextcloud Server Crawler',
473
-				'Accept-Encoding' => 'gzip',
474
-			],
475
-			'timeout' => 30,
476
-			'nextcloud' => [
477
-				'allow_local_address' => false,
478
-			],
479
-			'allow_redirects' => [
480
-				'on_redirect' => function (
481
-					\Psr\Http\Message\RequestInterface $request,
482
-					\Psr\Http\Message\ResponseInterface $response,
483
-					\Psr\Http\Message\UriInterface $uri,
484
-				) {
485
-				},
486
-			],
487
-		], self::invokePrivate($this->client, 'buildRequestOptions', [[]]));
488
-	}
489
-
490
-	public function testSetDefaultOptionsWithProxy(): void {
491
-		$this->config
492
-			->expects($this->exactly(2))
493
-			->method('getSystemValueBool')
494
-			->willReturnMap([
495
-				['installed', false, true],
496
-				['allow_local_remote_servers', false, false],
497
-			]);
498
-		$this->config
499
-			->expects($this->once())
500
-			->method('getSystemValue')
501
-			->with('proxyexclude', [])
502
-			->willReturn([]);
503
-		$this->config
504
-			->expects($this->exactly(2))
505
-			->method('getSystemValueString')
506
-			->willReturnMap([
507
-				['proxy', '', 'foo'],
508
-				['proxyuserpwd', '', ''],
509
-			]);
510
-		$this->certificateManager
511
-			->expects($this->once())
512
-			->method('getAbsoluteBundlePath')
513
-			->with()
514
-			->willReturn('/my/path.crt');
515
-
516
-		$this->assertEquals([
517
-			'verify' => '/my/path.crt',
518
-			'proxy' => [
519
-				'http' => 'foo',
520
-				'https' => 'foo'
521
-			],
522
-			'headers' => [
523
-				'User-Agent' => 'Nextcloud Server Crawler',
524
-				'Accept-Encoding' => 'gzip',
525
-			],
526
-			'timeout' => 30,
527
-			'nextcloud' => [
528
-				'allow_local_address' => false,
529
-			],
530
-			'allow_redirects' => [
531
-				'on_redirect' => function (
532
-					\Psr\Http\Message\RequestInterface $request,
533
-					\Psr\Http\Message\ResponseInterface $response,
534
-					\Psr\Http\Message\UriInterface $uri,
535
-				) {
536
-				},
537
-			],
538
-		], self::invokePrivate($this->client, 'buildRequestOptions', [[]]));
539
-	}
540
-
541
-	public function testSetDefaultOptionsWithProxyAndExclude(): void {
542
-		$this->config
543
-			->expects($this->exactly(2))
544
-			->method('getSystemValueBool')
545
-			->willReturnMap([
546
-				['installed', false, true],
547
-				['allow_local_remote_servers', false, false],
548
-			]);
549
-		$this->config
550
-			->expects($this->once())
551
-			->method('getSystemValue')
552
-			->with('proxyexclude', [])
553
-			->willReturn(['bar']);
554
-		$this->config
555
-			->expects($this->exactly(2))
556
-			->method('getSystemValueString')
557
-			->willReturnMap([
558
-				['proxy', '', 'foo'],
559
-				['proxyuserpwd', '', ''],
560
-			]);
561
-		$this->certificateManager
562
-			->expects($this->once())
563
-			->method('getAbsoluteBundlePath')
564
-			->with()
565
-			->willReturn('/my/path.crt');
566
-
567
-		$this->assertEquals([
568
-			'verify' => '/my/path.crt',
569
-			'proxy' => [
570
-				'http' => 'foo',
571
-				'https' => 'foo',
572
-				'no' => ['bar']
573
-			],
574
-			'headers' => [
575
-				'User-Agent' => 'Nextcloud Server Crawler',
576
-				'Accept-Encoding' => 'gzip',
577
-			],
578
-			'timeout' => 30,
579
-			'nextcloud' => [
580
-				'allow_local_address' => false,
581
-			],
582
-			'allow_redirects' => [
583
-				'on_redirect' => function (
584
-					\Psr\Http\Message\RequestInterface $request,
585
-					\Psr\Http\Message\ResponseInterface $response,
586
-					\Psr\Http\Message\UriInterface $uri,
587
-				) {
588
-				},
589
-			],
590
-		], self::invokePrivate($this->client, 'buildRequestOptions', [[]]));
591
-	}
28
+    /** @var \GuzzleHttp\Client|MockObject */
29
+    private $guzzleClient;
30
+    /** @var CertificateManager|MockObject */
31
+    private $certificateManager;
32
+    /** @var Client */
33
+    private $client;
34
+    /** @var IConfig|MockObject */
35
+    private $config;
36
+    /** @var IRemoteHostValidator|MockObject */
37
+    private IRemoteHostValidator $remoteHostValidator;
38
+    private LoggerInterface $logger;
39
+    /** @var array */
40
+    private $defaultRequestOptions;
41
+
42
+    protected function setUp(): void {
43
+        parent::setUp();
44
+        $this->config = $this->createMock(IConfig::class);
45
+        $this->guzzleClient = $this->createMock(\GuzzleHttp\Client::class);
46
+        $this->certificateManager = $this->createMock(ICertificateManager::class);
47
+        $this->remoteHostValidator = $this->createMock(IRemoteHostValidator::class);
48
+        $this->logger = $this->createMock(LoggerInterface::class);
49
+        $this->client = new Client(
50
+            $this->config,
51
+            $this->certificateManager,
52
+            $this->guzzleClient,
53
+            $this->remoteHostValidator,
54
+            $this->logger,
55
+        );
56
+    }
57
+
58
+    public function testGetProxyUri(): void {
59
+        $this->config
60
+            ->method('getSystemValueString')
61
+            ->with('proxy', '')
62
+            ->willReturn('');
63
+        $this->assertNull(self::invokePrivate($this->client, 'getProxyUri'));
64
+    }
65
+
66
+    public function testGetProxyUriProxyHostEmptyPassword(): void {
67
+        $this->config
68
+            ->method('getSystemValue')
69
+            ->will($this->returnValueMap([
70
+                ['proxyexclude', [], []],
71
+            ]));
72
+
73
+        $this->config
74
+            ->method('getSystemValueString')
75
+            ->will($this->returnValueMap([
76
+                ['proxy', '', 'foo'],
77
+                ['proxyuserpwd', '', ''],
78
+            ]));
79
+
80
+        $this->assertEquals([
81
+            'http' => 'foo',
82
+            'https' => 'foo'
83
+        ], self::invokePrivate($this->client, 'getProxyUri'));
84
+    }
85
+
86
+    public function testGetProxyUriProxyHostWithPassword(): void {
87
+        $this->config
88
+            ->expects($this->once())
89
+            ->method('getSystemValue')
90
+            ->with('proxyexclude', [])
91
+            ->willReturn([]);
92
+        $this->config
93
+            ->expects($this->exactly(2))
94
+            ->method('getSystemValueString')
95
+            ->willReturnMap([
96
+                ['proxy', '', 'foo'],
97
+                ['proxyuserpwd', '', 'username:password'],
98
+            ]);
99
+        $this->assertEquals([
100
+            'http' => 'username:password@foo',
101
+            'https' => 'username:password@foo'
102
+        ], self::invokePrivate($this->client, 'getProxyUri'));
103
+    }
104
+
105
+    public function testGetProxyUriProxyHostWithPasswordAndExclude(): void {
106
+        $this->config
107
+            ->expects($this->once())
108
+            ->method('getSystemValue')
109
+            ->with('proxyexclude', [])
110
+            ->willReturn(['bar']);
111
+        $this->config
112
+            ->expects($this->exactly(2))
113
+            ->method('getSystemValueString')
114
+            ->willReturnMap([
115
+                ['proxy', '', 'foo'],
116
+                ['proxyuserpwd', '', 'username:password'],
117
+            ]);
118
+        $this->assertEquals([
119
+            'http' => 'username:password@foo',
120
+            'https' => 'username:password@foo',
121
+            'no' => ['bar']
122
+        ], self::invokePrivate($this->client, 'getProxyUri'));
123
+    }
124
+
125
+    public function testPreventLocalAddressThrowOnInvalidUri(): void {
126
+        $this->expectException(LocalServerException::class);
127
+        $this->expectExceptionMessage('Could not detect any host');
128
+
129
+        self::invokePrivate($this->client, 'preventLocalAddress', ['!@#$', []]);
130
+    }
131
+
132
+    public static function dataPreventLocalAddress(): array {
133
+        return [
134
+            ['https://localhost/foo.bar'],
135
+            ['https://localHost/foo.bar'],
136
+            ['https://random-host/foo.bar'],
137
+            ['https://[::1]/bla.blub'],
138
+            ['https://[::]/bla.blub'],
139
+            ['https://192.168.0.1'],
140
+            ['https://172.16.42.1'],
141
+            ['https://[fdf8:f53b:82e4::53]/secret.ics'],
142
+            ['https://[fe80::200:5aee:feaa:20a2]/secret.ics'],
143
+            ['https://[0:0:0:0:0:0:10.0.0.1]/secret.ics'],
144
+            ['https://[0:0:0:0:0:ffff:127.0.0.0]/secret.ics'],
145
+            ['https://10.0.0.1'],
146
+            ['https://another-host.local'],
147
+            ['https://service.localhost'],
148
+            ['https://normal.host.com'],
149
+            ['https://com.one-.nextcloud-one.com'],
150
+        ];
151
+    }
152
+
153
+    /**
154
+     * @dataProvider dataPreventLocalAddress
155
+     * @param string $uri
156
+     */
157
+    public function testPreventLocalAddressDisabledByGlobalConfig(string $uri): void {
158
+        $this->config->expects($this->once())
159
+            ->method('getSystemValueBool')
160
+            ->with('allow_local_remote_servers', false)
161
+            ->willReturn(true);
162
+
163
+        self::invokePrivate($this->client, 'preventLocalAddress', [$uri, []]);
164
+    }
165
+
166
+    /**
167
+     * @dataProvider dataPreventLocalAddress
168
+     * @param string $uri
169
+     */
170
+    public function testPreventLocalAddressDisabledByOption(string $uri): void {
171
+        $this->config->expects($this->never())
172
+            ->method('getSystemValueBool');
173
+
174
+        self::invokePrivate($this->client, 'preventLocalAddress', [$uri, [
175
+            'nextcloud' => ['allow_local_address' => true],
176
+        ]]);
177
+    }
178
+
179
+    /**
180
+     * @dataProvider dataPreventLocalAddress
181
+     * @param string $uri
182
+     */
183
+    public function testPreventLocalAddressOnGet(string $uri): void {
184
+        $host = parse_url($uri, PHP_URL_HOST);
185
+        $this->expectException(LocalServerException::class);
186
+        $this->remoteHostValidator
187
+            ->method('isValid')
188
+            ->with($host)
189
+            ->willReturn(false);
190
+
191
+        $this->client->get($uri);
192
+    }
193
+
194
+    /**
195
+     * @dataProvider dataPreventLocalAddress
196
+     * @param string $uri
197
+     */
198
+    public function testPreventLocalAddressOnHead(string $uri): void {
199
+        $host = parse_url($uri, PHP_URL_HOST);
200
+        $this->expectException(LocalServerException::class);
201
+        $this->remoteHostValidator
202
+            ->method('isValid')
203
+            ->with($host)
204
+            ->willReturn(false);
205
+
206
+        $this->client->head($uri);
207
+    }
208
+
209
+    /**
210
+     * @dataProvider dataPreventLocalAddress
211
+     * @param string $uri
212
+     */
213
+    public function testPreventLocalAddressOnPost(string $uri): void {
214
+        $host = parse_url($uri, PHP_URL_HOST);
215
+        $this->expectException(LocalServerException::class);
216
+        $this->remoteHostValidator
217
+            ->method('isValid')
218
+            ->with($host)
219
+            ->willReturn(false);
220
+
221
+        $this->client->post($uri);
222
+    }
223
+
224
+    /**
225
+     * @dataProvider dataPreventLocalAddress
226
+     * @param string $uri
227
+     */
228
+    public function testPreventLocalAddressOnPut(string $uri): void {
229
+        $host = parse_url($uri, PHP_URL_HOST);
230
+        $this->expectException(LocalServerException::class);
231
+        $this->remoteHostValidator
232
+            ->method('isValid')
233
+            ->with($host)
234
+            ->willReturn(false);
235
+
236
+        $this->client->put($uri);
237
+    }
238
+
239
+    /**
240
+     * @dataProvider dataPreventLocalAddress
241
+     * @param string $uri
242
+     */
243
+    public function testPreventLocalAddressOnDelete(string $uri): void {
244
+        $host = parse_url($uri, PHP_URL_HOST);
245
+        $this->expectException(LocalServerException::class);
246
+        $this->remoteHostValidator
247
+            ->method('isValid')
248
+            ->with($host)
249
+            ->willReturn(false);
250
+
251
+        $this->client->delete($uri);
252
+    }
253
+
254
+    private function setUpDefaultRequestOptions(): void {
255
+        $this->config
256
+            ->method('getSystemValue')
257
+            ->will($this->returnValueMap([
258
+                ['proxyexclude', [], []],
259
+            ]));
260
+        $this->config
261
+            ->method('getSystemValueString')
262
+            ->will($this->returnValueMap([
263
+                ['proxy', '', 'foo'],
264
+                ['proxyuserpwd', '', ''],
265
+            ]));
266
+        $this->config
267
+            ->method('getSystemValueBool')
268
+            ->will($this->returnValueMap([
269
+                ['installed', false, true],
270
+                ['allow_local_remote_servers', false, true],
271
+            ]));
272
+
273
+        $this->certificateManager
274
+            ->expects($this->once())
275
+            ->method('getAbsoluteBundlePath')
276
+            ->with()
277
+            ->willReturn('/my/path.crt');
278
+
279
+        $this->defaultRequestOptions = [
280
+            'verify' => '/my/path.crt',
281
+            'proxy' => [
282
+                'http' => 'foo',
283
+                'https' => 'foo'
284
+            ],
285
+            'headers' => [
286
+                'User-Agent' => 'Nextcloud Server Crawler',
287
+                'Accept-Encoding' => 'gzip',
288
+            ],
289
+            'timeout' => 30,
290
+            'nextcloud' => [
291
+                'allow_local_address' => true,
292
+            ],
293
+        ];
294
+    }
295
+
296
+    public function testGet(): void {
297
+        $this->setUpDefaultRequestOptions();
298
+
299
+        $this->guzzleClient->method('request')
300
+            ->with('get', 'http://localhost/', $this->defaultRequestOptions)
301
+            ->willReturn(new Response(418));
302
+        $this->assertEquals(418, $this->client->get('http://localhost/', [])->getStatusCode());
303
+    }
304
+
305
+    public function testGetWithOptions(): void {
306
+        $this->setUpDefaultRequestOptions();
307
+
308
+        $options = array_merge($this->defaultRequestOptions, [
309
+            'verify' => false,
310
+            'proxy' => [
311
+                'http' => 'bar',
312
+                'https' => 'bar'
313
+            ],
314
+        ]);
315
+
316
+        $this->guzzleClient->method('request')
317
+            ->with('get', 'http://localhost/', $options)
318
+            ->willReturn(new Response(418));
319
+        $this->assertEquals(418, $this->client->get('http://localhost/', $options)->getStatusCode());
320
+    }
321
+
322
+    public function testPost(): void {
323
+        $this->setUpDefaultRequestOptions();
324
+
325
+        $this->guzzleClient->method('request')
326
+            ->with('post', 'http://localhost/', $this->defaultRequestOptions)
327
+            ->willReturn(new Response(418));
328
+        $this->assertEquals(418, $this->client->post('http://localhost/', [])->getStatusCode());
329
+    }
330
+
331
+    public function testPostWithOptions(): void {
332
+        $this->setUpDefaultRequestOptions();
333
+
334
+        $options = array_merge($this->defaultRequestOptions, [
335
+            'verify' => false,
336
+            'proxy' => [
337
+                'http' => 'bar',
338
+                'https' => 'bar'
339
+            ],
340
+        ]);
341
+
342
+        $this->guzzleClient->method('request')
343
+            ->with('post', 'http://localhost/', $options)
344
+            ->willReturn(new Response(418));
345
+        $this->assertEquals(418, $this->client->post('http://localhost/', $options)->getStatusCode());
346
+    }
347
+
348
+    public function testPut(): void {
349
+        $this->setUpDefaultRequestOptions();
350
+
351
+        $this->guzzleClient->method('request')
352
+            ->with('put', 'http://localhost/', $this->defaultRequestOptions)
353
+            ->willReturn(new Response(418));
354
+        $this->assertEquals(418, $this->client->put('http://localhost/', [])->getStatusCode());
355
+    }
356
+
357
+    public function testPutWithOptions(): void {
358
+        $this->setUpDefaultRequestOptions();
359
+
360
+        $options = array_merge($this->defaultRequestOptions, [
361
+            'verify' => false,
362
+            'proxy' => [
363
+                'http' => 'bar',
364
+                'https' => 'bar'
365
+            ],
366
+        ]);
367
+
368
+        $this->guzzleClient->method('request')
369
+            ->with('put', 'http://localhost/', $options)
370
+            ->willReturn(new Response(418));
371
+        $this->assertEquals(418, $this->client->put('http://localhost/', $options)->getStatusCode());
372
+    }
373
+
374
+    public function testDelete(): void {
375
+        $this->setUpDefaultRequestOptions();
376
+
377
+        $this->guzzleClient->method('request')
378
+            ->with('delete', 'http://localhost/', $this->defaultRequestOptions)
379
+            ->willReturn(new Response(418));
380
+        $this->assertEquals(418, $this->client->delete('http://localhost/', [])->getStatusCode());
381
+    }
382
+
383
+    public function testDeleteWithOptions(): void {
384
+        $this->setUpDefaultRequestOptions();
385
+
386
+        $options = array_merge($this->defaultRequestOptions, [
387
+            'verify' => false,
388
+            'proxy' => [
389
+                'http' => 'bar',
390
+                'https' => 'bar'
391
+            ],
392
+        ]);
393
+
394
+        $this->guzzleClient->method('request')
395
+            ->with('delete', 'http://localhost/', $options)
396
+            ->willReturn(new Response(418));
397
+        $this->assertEquals(418, $this->client->delete('http://localhost/', $options)->getStatusCode());
398
+    }
399
+
400
+    public function testOptions(): void {
401
+        $this->setUpDefaultRequestOptions();
402
+
403
+        $this->guzzleClient->method('request')
404
+            ->with('options', 'http://localhost/', $this->defaultRequestOptions)
405
+            ->willReturn(new Response(418));
406
+        $this->assertEquals(418, $this->client->options('http://localhost/', [])->getStatusCode());
407
+    }
408
+
409
+    public function testOptionsWithOptions(): void {
410
+        $this->setUpDefaultRequestOptions();
411
+
412
+        $options = array_merge($this->defaultRequestOptions, [
413
+            'verify' => false,
414
+            'proxy' => [
415
+                'http' => 'bar',
416
+                'https' => 'bar'
417
+            ],
418
+        ]);
419
+
420
+        $this->guzzleClient->method('request')
421
+            ->with('options', 'http://localhost/', $options)
422
+            ->willReturn(new Response(418));
423
+        $this->assertEquals(418, $this->client->options('http://localhost/', $options)->getStatusCode());
424
+    }
425
+
426
+    public function testHead(): void {
427
+        $this->setUpDefaultRequestOptions();
428
+
429
+        $this->guzzleClient->method('request')
430
+            ->with('head', 'http://localhost/', $this->defaultRequestOptions)
431
+            ->willReturn(new Response(418));
432
+        $this->assertEquals(418, $this->client->head('http://localhost/', [])->getStatusCode());
433
+    }
434
+
435
+    public function testHeadWithOptions(): void {
436
+        $this->setUpDefaultRequestOptions();
437
+
438
+        $options = array_merge($this->defaultRequestOptions, [
439
+            'verify' => false,
440
+            'proxy' => [
441
+                'http' => 'bar',
442
+                'https' => 'bar'
443
+            ],
444
+        ]);
445
+
446
+        $this->guzzleClient->method('request')
447
+            ->with('head', 'http://localhost/', $options)
448
+            ->willReturn(new Response(418));
449
+        $this->assertEquals(418, $this->client->head('http://localhost/', $options)->getStatusCode());
450
+    }
451
+
452
+    public function testSetDefaultOptionsWithNotInstalled(): void {
453
+        $this->config
454
+            ->expects($this->exactly(2))
455
+            ->method('getSystemValueBool')
456
+            ->willReturnMap([
457
+                ['installed', false, false],
458
+                ['allow_local_remote_servers', false, false],
459
+            ]);
460
+        $this->config
461
+            ->expects($this->once())
462
+            ->method('getSystemValueString')
463
+            ->with('proxy', '')
464
+            ->willReturn('');
465
+        $this->certificateManager
466
+            ->expects($this->never())
467
+            ->method('listCertificates');
468
+
469
+        $this->assertEquals([
470
+            'verify' => \OC::$SERVERROOT . '/resources/config/ca-bundle.crt',
471
+            'headers' => [
472
+                'User-Agent' => 'Nextcloud Server Crawler',
473
+                'Accept-Encoding' => 'gzip',
474
+            ],
475
+            'timeout' => 30,
476
+            'nextcloud' => [
477
+                'allow_local_address' => false,
478
+            ],
479
+            'allow_redirects' => [
480
+                'on_redirect' => function (
481
+                    \Psr\Http\Message\RequestInterface $request,
482
+                    \Psr\Http\Message\ResponseInterface $response,
483
+                    \Psr\Http\Message\UriInterface $uri,
484
+                ) {
485
+                },
486
+            ],
487
+        ], self::invokePrivate($this->client, 'buildRequestOptions', [[]]));
488
+    }
489
+
490
+    public function testSetDefaultOptionsWithProxy(): void {
491
+        $this->config
492
+            ->expects($this->exactly(2))
493
+            ->method('getSystemValueBool')
494
+            ->willReturnMap([
495
+                ['installed', false, true],
496
+                ['allow_local_remote_servers', false, false],
497
+            ]);
498
+        $this->config
499
+            ->expects($this->once())
500
+            ->method('getSystemValue')
501
+            ->with('proxyexclude', [])
502
+            ->willReturn([]);
503
+        $this->config
504
+            ->expects($this->exactly(2))
505
+            ->method('getSystemValueString')
506
+            ->willReturnMap([
507
+                ['proxy', '', 'foo'],
508
+                ['proxyuserpwd', '', ''],
509
+            ]);
510
+        $this->certificateManager
511
+            ->expects($this->once())
512
+            ->method('getAbsoluteBundlePath')
513
+            ->with()
514
+            ->willReturn('/my/path.crt');
515
+
516
+        $this->assertEquals([
517
+            'verify' => '/my/path.crt',
518
+            'proxy' => [
519
+                'http' => 'foo',
520
+                'https' => 'foo'
521
+            ],
522
+            'headers' => [
523
+                'User-Agent' => 'Nextcloud Server Crawler',
524
+                'Accept-Encoding' => 'gzip',
525
+            ],
526
+            'timeout' => 30,
527
+            'nextcloud' => [
528
+                'allow_local_address' => false,
529
+            ],
530
+            'allow_redirects' => [
531
+                'on_redirect' => function (
532
+                    \Psr\Http\Message\RequestInterface $request,
533
+                    \Psr\Http\Message\ResponseInterface $response,
534
+                    \Psr\Http\Message\UriInterface $uri,
535
+                ) {
536
+                },
537
+            ],
538
+        ], self::invokePrivate($this->client, 'buildRequestOptions', [[]]));
539
+    }
540
+
541
+    public function testSetDefaultOptionsWithProxyAndExclude(): void {
542
+        $this->config
543
+            ->expects($this->exactly(2))
544
+            ->method('getSystemValueBool')
545
+            ->willReturnMap([
546
+                ['installed', false, true],
547
+                ['allow_local_remote_servers', false, false],
548
+            ]);
549
+        $this->config
550
+            ->expects($this->once())
551
+            ->method('getSystemValue')
552
+            ->with('proxyexclude', [])
553
+            ->willReturn(['bar']);
554
+        $this->config
555
+            ->expects($this->exactly(2))
556
+            ->method('getSystemValueString')
557
+            ->willReturnMap([
558
+                ['proxy', '', 'foo'],
559
+                ['proxyuserpwd', '', ''],
560
+            ]);
561
+        $this->certificateManager
562
+            ->expects($this->once())
563
+            ->method('getAbsoluteBundlePath')
564
+            ->with()
565
+            ->willReturn('/my/path.crt');
566
+
567
+        $this->assertEquals([
568
+            'verify' => '/my/path.crt',
569
+            'proxy' => [
570
+                'http' => 'foo',
571
+                'https' => 'foo',
572
+                'no' => ['bar']
573
+            ],
574
+            'headers' => [
575
+                'User-Agent' => 'Nextcloud Server Crawler',
576
+                'Accept-Encoding' => 'gzip',
577
+            ],
578
+            'timeout' => 30,
579
+            'nextcloud' => [
580
+                'allow_local_address' => false,
581
+            ],
582
+            'allow_redirects' => [
583
+                'on_redirect' => function (
584
+                    \Psr\Http\Message\RequestInterface $request,
585
+                    \Psr\Http\Message\ResponseInterface $response,
586
+                    \Psr\Http\Message\UriInterface $uri,
587
+                ) {
588
+                },
589
+            ],
590
+        ], self::invokePrivate($this->client, 'buildRequestOptions', [[]]));
591
+    }
592 592
 }
Please login to merge, or discard this patch.
tests/lib/Collaboration/Collaborators/LookupPluginTest.php 1 patch
Indentation   +470 added lines, -470 removed lines patch added patch discarded remove patch
@@ -24,474 +24,474 @@
 block discarded – undo
24 24
 use Test\TestCase;
25 25
 
26 26
 class LookupPluginTest extends TestCase {
27
-	/** @var IConfig|MockObject */
28
-	protected $config;
29
-	/** @var IClientService|MockObject */
30
-	protected $clientService;
31
-	/** @var IUserSession|MockObject */
32
-	protected $userSession;
33
-	/** @var ICloudIdManager|MockObject */
34
-	protected $cloudIdManager;
35
-	/** @var LookupPlugin */
36
-	protected $plugin;
37
-	/** @var LoggerInterface|MockObject */
38
-	protected $logger;
39
-
40
-	protected function setUp(): void {
41
-		parent::setUp();
42
-
43
-		$this->userSession = $this->createMock(IUserSession::class);
44
-		$this->cloudIdManager = $this->createMock(ICloudIdManager::class);
45
-		$this->config = $this->createMock(IConfig::class);
46
-		$this->logger = $this->createMock(LoggerInterface::class);
47
-		$this->clientService = $this->createMock(IClientService::class);
48
-		$cloudId = $this->createMock(ICloudId::class);
49
-		$cloudId->expects($this->any())->method('getRemote')->willReturn('myNextcloud.net');
50
-		$user = $this->createMock(IUser::class);
51
-		$user->expects($this->any())->method('getCloudId')->willReturn('[email protected]');
52
-		$this->userSession->expects($this->any())->method('getUser')
53
-			->willReturn($user);
54
-		$this->cloudIdManager->expects($this->any())->method('resolveCloudId')
55
-			->willReturnCallback(function ($cloudId) {
56
-				if ($cloudId === '[email protected]') {
57
-					return new CloudId('[email protected]', 'user', 'myNextcloud.net');
58
-				}
59
-				return new CloudId('[email protected]', 'user', 'someNextcloud.net');
60
-			});
61
-
62
-
63
-		$this->plugin = new LookupPlugin(
64
-			$this->config,
65
-			$this->clientService,
66
-			$this->userSession,
67
-			$this->cloudIdManager,
68
-			$this->logger
69
-		);
70
-	}
71
-
72
-	public function testSearchNoLookupServerURI(): void {
73
-		$this->config->expects($this->once())
74
-			->method('getAppValue')
75
-			->with('files_sharing', 'lookupServerEnabled', 'no')
76
-			->willReturn('yes');
77
-		$this->config->expects($this->exactly(2))
78
-			->method('getSystemValueBool')
79
-			->willReturnMap([
80
-				['gs.enabled', false, true],
81
-				['has_internet_connection', true, true],
82
-			]);
83
-
84
-		$this->config->expects($this->once())
85
-			->method('getSystemValueString')
86
-			->with('lookup_server', 'https://lookup.nextcloud.com')
87
-			->willReturn('');
88
-
89
-		$this->clientService->expects($this->never())
90
-			->method('newClient');
91
-
92
-		/** @var ISearchResult|MockObject $searchResult */
93
-		$searchResult = $this->createMock(ISearchResult::class);
94
-
95
-		$this->plugin->search('foobar', 10, 0, $searchResult);
96
-	}
97
-
98
-	public function testSearchNoInternet(): void {
99
-		$this->config->expects($this->once())
100
-			->method('getAppValue')
101
-			->with('files_sharing', 'lookupServerEnabled', 'no')
102
-			->willReturn('yes');
103
-		$this->config->expects($this->exactly(2))
104
-			->method('getSystemValueBool')
105
-			->willReturnMap([
106
-				['gs.enabled', false, false],
107
-				['has_internet_connection', true, false],
108
-			]);
109
-
110
-		$this->clientService->expects($this->never())
111
-			->method('newClient');
112
-
113
-		/** @var ISearchResult|MockObject $searchResult */
114
-		$searchResult = $this->createMock(ISearchResult::class);
115
-
116
-		$this->plugin->search('foobar', 10, 0, $searchResult);
117
-	}
118
-
119
-	/**
120
-	 * @dataProvider searchDataProvider
121
-	 * @param array $searchParams
122
-	 */
123
-	public function testSearch(array $searchParams): void {
124
-		$type = new SearchResultType('lookup');
125
-
126
-		/** @var ISearchResult|MockObject $searchResult */
127
-		$searchResult = $this->createMock(ISearchResult::class);
128
-		$searchResult->expects($this->once())
129
-			->method('addResultSet')
130
-			->with($type, $searchParams['expectedResult'], []);
131
-
132
-		$this->config->expects($this->once())
133
-			->method('getAppValue')
134
-			->with('files_sharing', 'lookupServerEnabled', 'no')
135
-			->willReturn('yes');
136
-		$this->config->expects($this->exactly(2))
137
-			->method('getSystemValueBool')
138
-			->willReturnMap([
139
-				['gs.enabled', false, true],
140
-				['has_internet_connection', true, true],
141
-			]);
142
-
143
-		$this->config->expects($this->once())
144
-			->method('getSystemValueString')
145
-			->with('lookup_server', 'https://lookup.nextcloud.com')
146
-			->willReturn($searchParams['server']);
147
-
148
-		$response = $this->createMock(IResponse::class);
149
-		$response->expects($this->once())
150
-			->method('getBody')
151
-			->willReturn(json_encode($searchParams['resultBody']));
152
-
153
-		$client = $this->createMock(IClient::class);
154
-		$client->expects($this->once())
155
-			->method('get')
156
-			->willReturnCallback(function ($url) use ($searchParams, $response) {
157
-				$this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0);
158
-				$this->assertNotFalse(strpos($url, urlencode($searchParams['search'])));
159
-				return $response;
160
-			});
161
-
162
-		$this->clientService->expects($this->once())
163
-			->method('newClient')
164
-			->willReturn($client);
165
-
166
-		$moreResults = $this->plugin->search(
167
-			$searchParams['search'],
168
-			$searchParams['limit'],
169
-			$searchParams['offset'],
170
-			$searchResult
171
-		);
172
-
173
-		$this->assertFalse($moreResults);
174
-	}
175
-
176
-
177
-	/**
178
-	 * @dataProvider dataSearchEnableDisableLookupServer
179
-	 * @param array $searchParams
180
-	 * @param bool $GSEnabled
181
-	 * @param bool $LookupEnabled
182
-	 */
183
-	public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnabled, $LookupEnabled): void {
184
-		$type = new SearchResultType('lookup');
185
-
186
-		/** @var ISearchResult|MockObject $searchResult */
187
-		$searchResult = $this->createMock(ISearchResult::class);
188
-
189
-		$this->config->expects($this->once())
190
-			->method('getAppValue')
191
-			->with('files_sharing', 'lookupServerEnabled', 'no')
192
-			->willReturn($LookupEnabled ? 'yes' : 'no');
193
-		if ($GSEnabled) {
194
-			$searchResult->expects($this->once())
195
-				->method('addResultSet')
196
-				->with($type, $searchParams['expectedResult'], []);
197
-
198
-			$this->config->expects($this->exactly(2))
199
-				->method('getSystemValueBool')
200
-				->willReturnMap([
201
-					['gs.enabled', false, $GSEnabled],
202
-					['has_internet_connection', true, true],
203
-				]);
204
-			$this->config->expects($this->once())
205
-				->method('getSystemValueString')
206
-				->with('lookup_server', 'https://lookup.nextcloud.com')
207
-				->willReturn($searchParams['server']);
208
-
209
-			$response = $this->createMock(IResponse::class);
210
-			$response->expects($this->once())
211
-				->method('getBody')
212
-				->willReturn(json_encode($searchParams['resultBody']));
213
-
214
-			$client = $this->createMock(IClient::class);
215
-			$client->expects($this->once())
216
-				->method('get')
217
-				->willReturnCallback(function ($url) use ($searchParams, $response) {
218
-					$this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0);
219
-					$this->assertNotFalse(strpos($url, urlencode($searchParams['search'])));
220
-					return $response;
221
-				});
222
-
223
-			$this->clientService->expects($this->once())
224
-				->method('newClient')
225
-				->willReturn($client);
226
-		} else {
227
-			$searchResult->expects($this->never())->method('addResultSet');
228
-			$this->config->expects($this->exactly(2))
229
-				->method('getSystemValueBool')
230
-				->willReturnMap([
231
-					['gs.enabled', false, $GSEnabled],
232
-					['has_internet_connection', true, true],
233
-				]);
234
-		}
235
-		$moreResults = $this->plugin->search(
236
-			$searchParams['search'],
237
-			$searchParams['limit'],
238
-			$searchParams['offset'],
239
-			$searchResult
240
-		);
241
-
242
-		$this->assertFalse($moreResults);
243
-	}
244
-
245
-
246
-	public function testSearchGSDisabled(): void {
247
-		$this->config->expects($this->atLeastOnce())
248
-			->method('getSystemValueBool')
249
-			->willReturnMap([
250
-				['has_internet_connection', true, true],
251
-				['gs.enabled', false, false],
252
-			]);
253
-
254
-		/** @var ISearchResult|MockObject $searchResult */
255
-		$searchResult = $this->createMock(ISearchResult::class);
256
-		$searchResult->expects($this->never())
257
-			->method('addResultSet');
258
-		$searchResult->expects($this->never())
259
-			->method('markExactIdMatch');
260
-
261
-		$this->assertFalse($this->plugin->search('irr', 10, 0, $searchResult));
262
-	}
263
-
264
-	public static function dataSearchEnableDisableLookupServer(): array {
265
-		$fedIDs = [
266
-			'[email protected]',
267
-			'[email protected]',
268
-			'[email protected]',
269
-		];
270
-
271
-		return [
272
-			[[
273
-				'search' => 'foo',
274
-				'limit' => 10,
275
-				'offset' => 0,
276
-				'server' => 'https://lookup.example.io',
277
-				'resultBody' => [
278
-					['federationId' => $fedIDs[0]],
279
-					['federationId' => $fedIDs[1]],
280
-					['federationId' => $fedIDs[2]],
281
-				],
282
-				'expectedResult' => [
283
-					[
284
-						'label' => $fedIDs[0],
285
-						'value' => [
286
-							'shareType' => IShare::TYPE_REMOTE,
287
-							'globalScale' => true,
288
-							'shareWith' => $fedIDs[0]
289
-						],
290
-						'extra' => ['federationId' => $fedIDs[0]],
291
-					],
292
-					[
293
-						'label' => $fedIDs[1],
294
-						'value' => [
295
-							'shareType' => IShare::TYPE_REMOTE,
296
-							'globalScale' => true,
297
-							'shareWith' => $fedIDs[1]
298
-						],
299
-						'extra' => ['federationId' => $fedIDs[1]],
300
-					],
301
-					[
302
-						'label' => $fedIDs[2],
303
-						'value' => [
304
-							'shareType' => IShare::TYPE_REMOTE,
305
-							'globalScale' => true,
306
-							'shareWith' => $fedIDs[2]
307
-						],
308
-						'extra' => ['federationId' => $fedIDs[2]],
309
-					],
310
-				]
311
-			],// GS , Lookup
312
-				true, true
313
-			],
314
-			[[
315
-				'search' => 'foo',
316
-				'limit' => 10,
317
-				'offset' => 0,
318
-				'server' => 'https://lookup.example.io',
319
-				'resultBody' => [
320
-					['federationId' => $fedIDs[0]],
321
-					['federationId' => $fedIDs[1]],
322
-					['federationId' => $fedIDs[2]],
323
-				],
324
-				'expectedResult' => [
325
-					[
326
-						'label' => $fedIDs[0],
327
-						'value' => [
328
-							'shareType' => IShare::TYPE_REMOTE,
329
-							'globalScale' => true,
330
-							'shareWith' => $fedIDs[0]
331
-						],
332
-						'extra' => ['federationId' => $fedIDs[0]],
333
-					],
334
-					[
335
-						'label' => $fedIDs[1],
336
-						'value' => [
337
-							'shareType' => IShare::TYPE_REMOTE,
338
-							'globalScale' => true,
339
-							'shareWith' => $fedIDs[1]
340
-						],
341
-						'extra' => ['federationId' => $fedIDs[1]],
342
-					],
343
-					[
344
-						'label' => $fedIDs[2],
345
-						'value' => [
346
-							'shareType' => IShare::TYPE_REMOTE,
347
-							'globalScale' => true,
348
-							'shareWith' => $fedIDs[2]
349
-						],
350
-						'extra' => ['federationId' => $fedIDs[2]],
351
-					],
352
-				]
353
-			],// GS , Lookup
354
-				true, false
355
-			],
356
-			[[
357
-				'search' => 'foo',
358
-				'limit' => 10,
359
-				'offset' => 0,
360
-				'server' => 'https://lookup.example.io',
361
-				'resultBody' => [
362
-					['federationId' => $fedIDs[0]],
363
-					['federationId' => $fedIDs[1]],
364
-					['federationId' => $fedIDs[2]],
365
-				],
366
-				'expectedResult' => [
367
-					[
368
-						'label' => $fedIDs[0],
369
-						'value' => [
370
-							'shareType' => IShare::TYPE_REMOTE,
371
-							'shareWith' => $fedIDs[0]
372
-						],
373
-						'extra' => ['federationId' => $fedIDs[0]],
374
-					],
375
-					[
376
-						'label' => $fedIDs[1],
377
-						'value' => [
378
-							'shareType' => IShare::TYPE_REMOTE,
379
-							'shareWith' => $fedIDs[1]
380
-						],
381
-						'extra' => ['federationId' => $fedIDs[1]],
382
-					],
383
-					[
384
-						'label' => $fedIDs[2],
385
-						'value' => [
386
-							'shareType' => IShare::TYPE_REMOTE,
387
-							'shareWith' => $fedIDs[2]
388
-						],
389
-						'extra' => ['federationId' => $fedIDs[2]],
390
-					],
391
-				]
392
-			],// GS , Lookup
393
-				false, true
394
-			],
395
-			[[
396
-				'search' => 'foo',
397
-				'limit' => 10,
398
-				'offset' => 0,
399
-				'server' => 'https://lookup.example.io',
400
-				'resultBody' => [
401
-					['federationId' => $fedIDs[0]],
402
-					['federationId' => $fedIDs[1]],
403
-					['federationId' => $fedIDs[2]],
404
-				],
405
-				'expectedResult' => [
406
-					[
407
-						'label' => $fedIDs[0],
408
-						'value' => [
409
-							'shareType' => IShare::TYPE_REMOTE,
410
-							'shareWith' => $fedIDs[0]
411
-						],
412
-						'extra' => ['federationId' => $fedIDs[0]],
413
-					],
414
-					[
415
-						'label' => $fedIDs[1],
416
-						'value' => [
417
-							'shareType' => IShare::TYPE_REMOTE,
418
-							'shareWith' => $fedIDs[1]
419
-						],
420
-						'extra' => ['federationId' => $fedIDs[1]],
421
-					],
422
-					[
423
-						'label' => $fedIDs[2],
424
-						'value' => [
425
-							'shareType' => IShare::TYPE_REMOTE,
426
-							'shareWith' => $fedIDs[2]
427
-						],
428
-						'extra' => ['federationId' => $fedIDs[2]],
429
-					],
430
-				]
431
-			],// GS , Lookup
432
-				false, false
433
-			],
434
-		];
435
-	}
436
-
437
-	public static function searchDataProvider(): array {
438
-		$fedIDs = [
439
-			'[email protected]',
440
-			'[email protected]',
441
-			'[email protected]',
442
-		];
443
-
444
-		return [
445
-			// #0, standard search with results
446
-			[[
447
-				'search' => 'foo',
448
-				'limit' => 10,
449
-				'offset' => 0,
450
-				'server' => 'https://lookup.example.io',
451
-				'resultBody' => [
452
-					['federationId' => $fedIDs[0]],
453
-					['federationId' => $fedIDs[1]],
454
-					['federationId' => $fedIDs[2]],
455
-				],
456
-				'expectedResult' => [
457
-					[
458
-						'label' => $fedIDs[0],
459
-						'value' => [
460
-							'shareType' => IShare::TYPE_REMOTE,
461
-							'globalScale' => true,
462
-							'shareWith' => $fedIDs[0]
463
-						],
464
-						'extra' => ['federationId' => $fedIDs[0]],
465
-					],
466
-					[
467
-						'label' => $fedIDs[1],
468
-						'value' => [
469
-							'shareType' => IShare::TYPE_REMOTE,
470
-							'globalScale' => true,
471
-							'shareWith' => $fedIDs[1]
472
-						],
473
-						'extra' => ['federationId' => $fedIDs[1]],
474
-					],
475
-					[
476
-						'label' => $fedIDs[2],
477
-						'value' => [
478
-							'shareType' => IShare::TYPE_REMOTE,
479
-							'globalScale' => true,
480
-							'shareWith' => $fedIDs[2]
481
-						],
482
-						'extra' => ['federationId' => $fedIDs[2]],
483
-					],
484
-				]
485
-			]],
486
-			// #1, search without results
487
-			[[
488
-				'search' => 'foo',
489
-				'limit' => 10,
490
-				'offset' => 0,
491
-				'server' => 'https://lookup.example.io',
492
-				'resultBody' => [],
493
-				'expectedResult' => [],
494
-			]],
495
-		];
496
-	}
27
+    /** @var IConfig|MockObject */
28
+    protected $config;
29
+    /** @var IClientService|MockObject */
30
+    protected $clientService;
31
+    /** @var IUserSession|MockObject */
32
+    protected $userSession;
33
+    /** @var ICloudIdManager|MockObject */
34
+    protected $cloudIdManager;
35
+    /** @var LookupPlugin */
36
+    protected $plugin;
37
+    /** @var LoggerInterface|MockObject */
38
+    protected $logger;
39
+
40
+    protected function setUp(): void {
41
+        parent::setUp();
42
+
43
+        $this->userSession = $this->createMock(IUserSession::class);
44
+        $this->cloudIdManager = $this->createMock(ICloudIdManager::class);
45
+        $this->config = $this->createMock(IConfig::class);
46
+        $this->logger = $this->createMock(LoggerInterface::class);
47
+        $this->clientService = $this->createMock(IClientService::class);
48
+        $cloudId = $this->createMock(ICloudId::class);
49
+        $cloudId->expects($this->any())->method('getRemote')->willReturn('myNextcloud.net');
50
+        $user = $this->createMock(IUser::class);
51
+        $user->expects($this->any())->method('getCloudId')->willReturn('[email protected]');
52
+        $this->userSession->expects($this->any())->method('getUser')
53
+            ->willReturn($user);
54
+        $this->cloudIdManager->expects($this->any())->method('resolveCloudId')
55
+            ->willReturnCallback(function ($cloudId) {
56
+                if ($cloudId === '[email protected]') {
57
+                    return new CloudId('[email protected]', 'user', 'myNextcloud.net');
58
+                }
59
+                return new CloudId('[email protected]', 'user', 'someNextcloud.net');
60
+            });
61
+
62
+
63
+        $this->plugin = new LookupPlugin(
64
+            $this->config,
65
+            $this->clientService,
66
+            $this->userSession,
67
+            $this->cloudIdManager,
68
+            $this->logger
69
+        );
70
+    }
71
+
72
+    public function testSearchNoLookupServerURI(): void {
73
+        $this->config->expects($this->once())
74
+            ->method('getAppValue')
75
+            ->with('files_sharing', 'lookupServerEnabled', 'no')
76
+            ->willReturn('yes');
77
+        $this->config->expects($this->exactly(2))
78
+            ->method('getSystemValueBool')
79
+            ->willReturnMap([
80
+                ['gs.enabled', false, true],
81
+                ['has_internet_connection', true, true],
82
+            ]);
83
+
84
+        $this->config->expects($this->once())
85
+            ->method('getSystemValueString')
86
+            ->with('lookup_server', 'https://lookup.nextcloud.com')
87
+            ->willReturn('');
88
+
89
+        $this->clientService->expects($this->never())
90
+            ->method('newClient');
91
+
92
+        /** @var ISearchResult|MockObject $searchResult */
93
+        $searchResult = $this->createMock(ISearchResult::class);
94
+
95
+        $this->plugin->search('foobar', 10, 0, $searchResult);
96
+    }
97
+
98
+    public function testSearchNoInternet(): void {
99
+        $this->config->expects($this->once())
100
+            ->method('getAppValue')
101
+            ->with('files_sharing', 'lookupServerEnabled', 'no')
102
+            ->willReturn('yes');
103
+        $this->config->expects($this->exactly(2))
104
+            ->method('getSystemValueBool')
105
+            ->willReturnMap([
106
+                ['gs.enabled', false, false],
107
+                ['has_internet_connection', true, false],
108
+            ]);
109
+
110
+        $this->clientService->expects($this->never())
111
+            ->method('newClient');
112
+
113
+        /** @var ISearchResult|MockObject $searchResult */
114
+        $searchResult = $this->createMock(ISearchResult::class);
115
+
116
+        $this->plugin->search('foobar', 10, 0, $searchResult);
117
+    }
118
+
119
+    /**
120
+     * @dataProvider searchDataProvider
121
+     * @param array $searchParams
122
+     */
123
+    public function testSearch(array $searchParams): void {
124
+        $type = new SearchResultType('lookup');
125
+
126
+        /** @var ISearchResult|MockObject $searchResult */
127
+        $searchResult = $this->createMock(ISearchResult::class);
128
+        $searchResult->expects($this->once())
129
+            ->method('addResultSet')
130
+            ->with($type, $searchParams['expectedResult'], []);
131
+
132
+        $this->config->expects($this->once())
133
+            ->method('getAppValue')
134
+            ->with('files_sharing', 'lookupServerEnabled', 'no')
135
+            ->willReturn('yes');
136
+        $this->config->expects($this->exactly(2))
137
+            ->method('getSystemValueBool')
138
+            ->willReturnMap([
139
+                ['gs.enabled', false, true],
140
+                ['has_internet_connection', true, true],
141
+            ]);
142
+
143
+        $this->config->expects($this->once())
144
+            ->method('getSystemValueString')
145
+            ->with('lookup_server', 'https://lookup.nextcloud.com')
146
+            ->willReturn($searchParams['server']);
147
+
148
+        $response = $this->createMock(IResponse::class);
149
+        $response->expects($this->once())
150
+            ->method('getBody')
151
+            ->willReturn(json_encode($searchParams['resultBody']));
152
+
153
+        $client = $this->createMock(IClient::class);
154
+        $client->expects($this->once())
155
+            ->method('get')
156
+            ->willReturnCallback(function ($url) use ($searchParams, $response) {
157
+                $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0);
158
+                $this->assertNotFalse(strpos($url, urlencode($searchParams['search'])));
159
+                return $response;
160
+            });
161
+
162
+        $this->clientService->expects($this->once())
163
+            ->method('newClient')
164
+            ->willReturn($client);
165
+
166
+        $moreResults = $this->plugin->search(
167
+            $searchParams['search'],
168
+            $searchParams['limit'],
169
+            $searchParams['offset'],
170
+            $searchResult
171
+        );
172
+
173
+        $this->assertFalse($moreResults);
174
+    }
175
+
176
+
177
+    /**
178
+     * @dataProvider dataSearchEnableDisableLookupServer
179
+     * @param array $searchParams
180
+     * @param bool $GSEnabled
181
+     * @param bool $LookupEnabled
182
+     */
183
+    public function testSearchEnableDisableLookupServer(array $searchParams, $GSEnabled, $LookupEnabled): void {
184
+        $type = new SearchResultType('lookup');
185
+
186
+        /** @var ISearchResult|MockObject $searchResult */
187
+        $searchResult = $this->createMock(ISearchResult::class);
188
+
189
+        $this->config->expects($this->once())
190
+            ->method('getAppValue')
191
+            ->with('files_sharing', 'lookupServerEnabled', 'no')
192
+            ->willReturn($LookupEnabled ? 'yes' : 'no');
193
+        if ($GSEnabled) {
194
+            $searchResult->expects($this->once())
195
+                ->method('addResultSet')
196
+                ->with($type, $searchParams['expectedResult'], []);
197
+
198
+            $this->config->expects($this->exactly(2))
199
+                ->method('getSystemValueBool')
200
+                ->willReturnMap([
201
+                    ['gs.enabled', false, $GSEnabled],
202
+                    ['has_internet_connection', true, true],
203
+                ]);
204
+            $this->config->expects($this->once())
205
+                ->method('getSystemValueString')
206
+                ->with('lookup_server', 'https://lookup.nextcloud.com')
207
+                ->willReturn($searchParams['server']);
208
+
209
+            $response = $this->createMock(IResponse::class);
210
+            $response->expects($this->once())
211
+                ->method('getBody')
212
+                ->willReturn(json_encode($searchParams['resultBody']));
213
+
214
+            $client = $this->createMock(IClient::class);
215
+            $client->expects($this->once())
216
+                ->method('get')
217
+                ->willReturnCallback(function ($url) use ($searchParams, $response) {
218
+                    $this->assertSame(strpos($url, $searchParams['server'] . '/users?search='), 0);
219
+                    $this->assertNotFalse(strpos($url, urlencode($searchParams['search'])));
220
+                    return $response;
221
+                });
222
+
223
+            $this->clientService->expects($this->once())
224
+                ->method('newClient')
225
+                ->willReturn($client);
226
+        } else {
227
+            $searchResult->expects($this->never())->method('addResultSet');
228
+            $this->config->expects($this->exactly(2))
229
+                ->method('getSystemValueBool')
230
+                ->willReturnMap([
231
+                    ['gs.enabled', false, $GSEnabled],
232
+                    ['has_internet_connection', true, true],
233
+                ]);
234
+        }
235
+        $moreResults = $this->plugin->search(
236
+            $searchParams['search'],
237
+            $searchParams['limit'],
238
+            $searchParams['offset'],
239
+            $searchResult
240
+        );
241
+
242
+        $this->assertFalse($moreResults);
243
+    }
244
+
245
+
246
+    public function testSearchGSDisabled(): void {
247
+        $this->config->expects($this->atLeastOnce())
248
+            ->method('getSystemValueBool')
249
+            ->willReturnMap([
250
+                ['has_internet_connection', true, true],
251
+                ['gs.enabled', false, false],
252
+            ]);
253
+
254
+        /** @var ISearchResult|MockObject $searchResult */
255
+        $searchResult = $this->createMock(ISearchResult::class);
256
+        $searchResult->expects($this->never())
257
+            ->method('addResultSet');
258
+        $searchResult->expects($this->never())
259
+            ->method('markExactIdMatch');
260
+
261
+        $this->assertFalse($this->plugin->search('irr', 10, 0, $searchResult));
262
+    }
263
+
264
+    public static function dataSearchEnableDisableLookupServer(): array {
265
+        $fedIDs = [
266
+            '[email protected]',
267
+            '[email protected]',
268
+            '[email protected]',
269
+        ];
270
+
271
+        return [
272
+            [[
273
+                'search' => 'foo',
274
+                'limit' => 10,
275
+                'offset' => 0,
276
+                'server' => 'https://lookup.example.io',
277
+                'resultBody' => [
278
+                    ['federationId' => $fedIDs[0]],
279
+                    ['federationId' => $fedIDs[1]],
280
+                    ['federationId' => $fedIDs[2]],
281
+                ],
282
+                'expectedResult' => [
283
+                    [
284
+                        'label' => $fedIDs[0],
285
+                        'value' => [
286
+                            'shareType' => IShare::TYPE_REMOTE,
287
+                            'globalScale' => true,
288
+                            'shareWith' => $fedIDs[0]
289
+                        ],
290
+                        'extra' => ['federationId' => $fedIDs[0]],
291
+                    ],
292
+                    [
293
+                        'label' => $fedIDs[1],
294
+                        'value' => [
295
+                            'shareType' => IShare::TYPE_REMOTE,
296
+                            'globalScale' => true,
297
+                            'shareWith' => $fedIDs[1]
298
+                        ],
299
+                        'extra' => ['federationId' => $fedIDs[1]],
300
+                    ],
301
+                    [
302
+                        'label' => $fedIDs[2],
303
+                        'value' => [
304
+                            'shareType' => IShare::TYPE_REMOTE,
305
+                            'globalScale' => true,
306
+                            'shareWith' => $fedIDs[2]
307
+                        ],
308
+                        'extra' => ['federationId' => $fedIDs[2]],
309
+                    ],
310
+                ]
311
+            ],// GS , Lookup
312
+                true, true
313
+            ],
314
+            [[
315
+                'search' => 'foo',
316
+                'limit' => 10,
317
+                'offset' => 0,
318
+                'server' => 'https://lookup.example.io',
319
+                'resultBody' => [
320
+                    ['federationId' => $fedIDs[0]],
321
+                    ['federationId' => $fedIDs[1]],
322
+                    ['federationId' => $fedIDs[2]],
323
+                ],
324
+                'expectedResult' => [
325
+                    [
326
+                        'label' => $fedIDs[0],
327
+                        'value' => [
328
+                            'shareType' => IShare::TYPE_REMOTE,
329
+                            'globalScale' => true,
330
+                            'shareWith' => $fedIDs[0]
331
+                        ],
332
+                        'extra' => ['federationId' => $fedIDs[0]],
333
+                    ],
334
+                    [
335
+                        'label' => $fedIDs[1],
336
+                        'value' => [
337
+                            'shareType' => IShare::TYPE_REMOTE,
338
+                            'globalScale' => true,
339
+                            'shareWith' => $fedIDs[1]
340
+                        ],
341
+                        'extra' => ['federationId' => $fedIDs[1]],
342
+                    ],
343
+                    [
344
+                        'label' => $fedIDs[2],
345
+                        'value' => [
346
+                            'shareType' => IShare::TYPE_REMOTE,
347
+                            'globalScale' => true,
348
+                            'shareWith' => $fedIDs[2]
349
+                        ],
350
+                        'extra' => ['federationId' => $fedIDs[2]],
351
+                    ],
352
+                ]
353
+            ],// GS , Lookup
354
+                true, false
355
+            ],
356
+            [[
357
+                'search' => 'foo',
358
+                'limit' => 10,
359
+                'offset' => 0,
360
+                'server' => 'https://lookup.example.io',
361
+                'resultBody' => [
362
+                    ['federationId' => $fedIDs[0]],
363
+                    ['federationId' => $fedIDs[1]],
364
+                    ['federationId' => $fedIDs[2]],
365
+                ],
366
+                'expectedResult' => [
367
+                    [
368
+                        'label' => $fedIDs[0],
369
+                        'value' => [
370
+                            'shareType' => IShare::TYPE_REMOTE,
371
+                            'shareWith' => $fedIDs[0]
372
+                        ],
373
+                        'extra' => ['federationId' => $fedIDs[0]],
374
+                    ],
375
+                    [
376
+                        'label' => $fedIDs[1],
377
+                        'value' => [
378
+                            'shareType' => IShare::TYPE_REMOTE,
379
+                            'shareWith' => $fedIDs[1]
380
+                        ],
381
+                        'extra' => ['federationId' => $fedIDs[1]],
382
+                    ],
383
+                    [
384
+                        'label' => $fedIDs[2],
385
+                        'value' => [
386
+                            'shareType' => IShare::TYPE_REMOTE,
387
+                            'shareWith' => $fedIDs[2]
388
+                        ],
389
+                        'extra' => ['federationId' => $fedIDs[2]],
390
+                    ],
391
+                ]
392
+            ],// GS , Lookup
393
+                false, true
394
+            ],
395
+            [[
396
+                'search' => 'foo',
397
+                'limit' => 10,
398
+                'offset' => 0,
399
+                'server' => 'https://lookup.example.io',
400
+                'resultBody' => [
401
+                    ['federationId' => $fedIDs[0]],
402
+                    ['federationId' => $fedIDs[1]],
403
+                    ['federationId' => $fedIDs[2]],
404
+                ],
405
+                'expectedResult' => [
406
+                    [
407
+                        'label' => $fedIDs[0],
408
+                        'value' => [
409
+                            'shareType' => IShare::TYPE_REMOTE,
410
+                            'shareWith' => $fedIDs[0]
411
+                        ],
412
+                        'extra' => ['federationId' => $fedIDs[0]],
413
+                    ],
414
+                    [
415
+                        'label' => $fedIDs[1],
416
+                        'value' => [
417
+                            'shareType' => IShare::TYPE_REMOTE,
418
+                            'shareWith' => $fedIDs[1]
419
+                        ],
420
+                        'extra' => ['federationId' => $fedIDs[1]],
421
+                    ],
422
+                    [
423
+                        'label' => $fedIDs[2],
424
+                        'value' => [
425
+                            'shareType' => IShare::TYPE_REMOTE,
426
+                            'shareWith' => $fedIDs[2]
427
+                        ],
428
+                        'extra' => ['federationId' => $fedIDs[2]],
429
+                    ],
430
+                ]
431
+            ],// GS , Lookup
432
+                false, false
433
+            ],
434
+        ];
435
+    }
436
+
437
+    public static function searchDataProvider(): array {
438
+        $fedIDs = [
439
+            '[email protected]',
440
+            '[email protected]',
441
+            '[email protected]',
442
+        ];
443
+
444
+        return [
445
+            // #0, standard search with results
446
+            [[
447
+                'search' => 'foo',
448
+                'limit' => 10,
449
+                'offset' => 0,
450
+                'server' => 'https://lookup.example.io',
451
+                'resultBody' => [
452
+                    ['federationId' => $fedIDs[0]],
453
+                    ['federationId' => $fedIDs[1]],
454
+                    ['federationId' => $fedIDs[2]],
455
+                ],
456
+                'expectedResult' => [
457
+                    [
458
+                        'label' => $fedIDs[0],
459
+                        'value' => [
460
+                            'shareType' => IShare::TYPE_REMOTE,
461
+                            'globalScale' => true,
462
+                            'shareWith' => $fedIDs[0]
463
+                        ],
464
+                        'extra' => ['federationId' => $fedIDs[0]],
465
+                    ],
466
+                    [
467
+                        'label' => $fedIDs[1],
468
+                        'value' => [
469
+                            'shareType' => IShare::TYPE_REMOTE,
470
+                            'globalScale' => true,
471
+                            'shareWith' => $fedIDs[1]
472
+                        ],
473
+                        'extra' => ['federationId' => $fedIDs[1]],
474
+                    ],
475
+                    [
476
+                        'label' => $fedIDs[2],
477
+                        'value' => [
478
+                            'shareType' => IShare::TYPE_REMOTE,
479
+                            'globalScale' => true,
480
+                            'shareWith' => $fedIDs[2]
481
+                        ],
482
+                        'extra' => ['federationId' => $fedIDs[2]],
483
+                    ],
484
+                ]
485
+            ]],
486
+            // #1, search without results
487
+            [[
488
+                'search' => 'foo',
489
+                'limit' => 10,
490
+                'offset' => 0,
491
+                'server' => 'https://lookup.example.io',
492
+                'resultBody' => [],
493
+                'expectedResult' => [],
494
+            ]],
495
+        ];
496
+    }
497 497
 }
Please login to merge, or discard this patch.
tests/lib/Files/Type/DetectionTest.php 2 patches
Indentation   +294 added lines, -294 removed lines patch added patch discarded remove patch
@@ -12,346 +12,346 @@
 block discarded – undo
12 12
 use Psr\Log\LoggerInterface;
13 13
 
14 14
 class DetectionTest extends \Test\TestCase {
15
-	/** @var Detection */
16
-	private $detection;
17
-
18
-	protected function setUp(): void {
19
-		parent::setUp();
20
-		$this->detection = new Detection(
21
-			\OC::$server->getURLGenerator(),
22
-			\OC::$server->get(LoggerInterface::class),
23
-			\OC::$SERVERROOT . '/config/',
24
-			\OC::$SERVERROOT . '/resources/config/'
25
-		);
26
-	}
27
-
28
-	public static function dataDetectPath(): array {
29
-		return [
30
-			['foo.txt', 'text/plain'],
31
-			['foo.png', 'image/png'],
32
-			['foo.bar.png', 'image/png'],
33
-			['.hidden.png', 'image/png'],
34
-			['.hidden.foo.png', 'image/png'],
35
-			['.hidden/foo.png', 'image/png'],
36
-			['.hidden/.hidden.png', 'image/png'],
37
-			['test.jpg/foo.png', 'image/png'],
38
-			['.png', 'application/octet-stream'],
39
-			['..hidden', 'application/octet-stream'],
40
-			['foo', 'application/octet-stream'],
41
-			['', 'application/octet-stream'],
42
-			['foo.png.ocTransferId123456789.part', 'image/png'],
43
-			['foo.png.v1234567890', 'image/png'],
44
-		];
45
-	}
46
-
47
-	/**
48
-	 * @dataProvider dataDetectPath
49
-	 *
50
-	 * @param string $path
51
-	 * @param string $expected
52
-	 */
53
-	public function testDetectPath(string $path, string $expected): void {
54
-		$this->assertEquals($expected, $this->detection->detectPath($path));
55
-	}
56
-
57
-	public static function dataDetectContent(): array {
58
-		return [
59
-			['/', 'httpd/unix-directory'],
60
-			['/data.tar.gz', 'application/gzip'],
61
-			['/data.zip', 'application/zip'],
62
-			['/testimage.mp3', 'audio/mpeg'],
63
-			['/testimage.png', 'image/png'],
64
-		];
65
-	}
66
-
67
-	/**
68
-	 * @dataProvider dataDetectContent
69
-	 *
70
-	 * @param string $path
71
-	 * @param string $expected
72
-	 */
73
-	public function testDetectContent(string $path, string $expected): void {
74
-		$this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT . '/tests/data' . $path));
75
-	}
76
-
77
-	public static function dataDetect(): array {
78
-		return [
79
-			['/', 'httpd/unix-directory'],
80
-			['/data.tar.gz', 'application/gzip'],
81
-			['/data.zip', 'application/zip'],
82
-			['/testimagelarge.svg', 'image/svg+xml'],
83
-			['/testimage.png', 'image/png'],
84
-		];
85
-	}
86
-
87
-	/**
88
-	 * @dataProvider dataDetect
89
-	 *
90
-	 * @param string $path
91
-	 * @param string $expected
92
-	 */
93
-	public function testDetect(string $path, string $expected): void {
94
-		$this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT . '/tests/data' . $path));
95
-	}
96
-
97
-	public function testDetectString(): void {
98
-		$result = $this->detection->detectString('/data/data.tar.gz');
99
-		$expected = 'text/plain';
100
-		$this->assertEquals($expected, $result);
101
-	}
102
-
103
-	public static function dataMimeTypeCustom(): array {
104
-		return [
105
-			['123', 'foobar/123'],
106
-			['a123', 'foobar/123'],
107
-			['bar', 'foobar/bar'],
108
-		];
109
-	}
110
-
111
-	/**
112
-	 * @dataProvider dataMimeTypeCustom
113
-	 *
114
-	 * @param string $ext
115
-	 * @param string $mime
116
-	 */
117
-	public function testDetectMimeTypeCustom(string $ext, string $mime): void {
118
-		$confDir = sys_get_temp_dir();
119
-		file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([]));
120
-
121
-		/** @var IURLGenerator $urlGenerator */
122
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
123
-			->disableOriginalConstructor()
124
-			->getMock();
125
-
126
-		/** @var LoggerInterface $logger */
127
-		$logger = $this->createMock(LoggerInterface::class);
128
-
129
-		// Create new mapping file
130
-		file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]]));
131
-
132
-		$detection = new Detection($urlGenerator, $logger, $confDir, $confDir);
133
-		$mappings = $detection->getAllMappings();
134
-		$this->assertArrayHasKey($ext, $mappings);
135
-		$this->assertEquals($mime, $detection->detectPath('foo.' . $ext));
136
-	}
137
-
138
-	public static function dataGetSecureMimeType(): array {
139
-		return [
140
-			['image/svg+xml', 'text/plain'],
141
-			['image/png', 'image/png'],
142
-		];
143
-	}
144
-
145
-	/**
146
-	 * @dataProvider dataGetSecureMimeType
147
-	 *
148
-	 * @param string $mimeType
149
-	 * @param string $expected
150
-	 */
151
-	public function testGetSecureMimeType(string $mimeType, string $expected): void {
152
-		$this->assertEquals($expected, $this->detection->getSecureMimeType($mimeType));
153
-	}
154
-
155
-	public function testMimeTypeIcon(): void {
156
-		if (!class_exists('org\\bovigo\\vfs\\vfsStream')) {
157
-			$this->markTestSkipped('Package vfsStream not installed');
158
-		}
159
-		$confDir = \org\bovigo\vfs\vfsStream::setup();
160
-		$mimetypealiases_dist = \org\bovigo\vfs\vfsStream::newFile('mimetypealiases.dist.json')->at($confDir);
161
-
162
-		//Empty alias file
163
-		$mimetypealiases_dist->setContent(json_encode([], JSON_FORCE_OBJECT));
164
-
165
-
166
-		/*
15
+    /** @var Detection */
16
+    private $detection;
17
+
18
+    protected function setUp(): void {
19
+        parent::setUp();
20
+        $this->detection = new Detection(
21
+            \OC::$server->getURLGenerator(),
22
+            \OC::$server->get(LoggerInterface::class),
23
+            \OC::$SERVERROOT . '/config/',
24
+            \OC::$SERVERROOT . '/resources/config/'
25
+        );
26
+    }
27
+
28
+    public static function dataDetectPath(): array {
29
+        return [
30
+            ['foo.txt', 'text/plain'],
31
+            ['foo.png', 'image/png'],
32
+            ['foo.bar.png', 'image/png'],
33
+            ['.hidden.png', 'image/png'],
34
+            ['.hidden.foo.png', 'image/png'],
35
+            ['.hidden/foo.png', 'image/png'],
36
+            ['.hidden/.hidden.png', 'image/png'],
37
+            ['test.jpg/foo.png', 'image/png'],
38
+            ['.png', 'application/octet-stream'],
39
+            ['..hidden', 'application/octet-stream'],
40
+            ['foo', 'application/octet-stream'],
41
+            ['', 'application/octet-stream'],
42
+            ['foo.png.ocTransferId123456789.part', 'image/png'],
43
+            ['foo.png.v1234567890', 'image/png'],
44
+        ];
45
+    }
46
+
47
+    /**
48
+     * @dataProvider dataDetectPath
49
+     *
50
+     * @param string $path
51
+     * @param string $expected
52
+     */
53
+    public function testDetectPath(string $path, string $expected): void {
54
+        $this->assertEquals($expected, $this->detection->detectPath($path));
55
+    }
56
+
57
+    public static function dataDetectContent(): array {
58
+        return [
59
+            ['/', 'httpd/unix-directory'],
60
+            ['/data.tar.gz', 'application/gzip'],
61
+            ['/data.zip', 'application/zip'],
62
+            ['/testimage.mp3', 'audio/mpeg'],
63
+            ['/testimage.png', 'image/png'],
64
+        ];
65
+    }
66
+
67
+    /**
68
+     * @dataProvider dataDetectContent
69
+     *
70
+     * @param string $path
71
+     * @param string $expected
72
+     */
73
+    public function testDetectContent(string $path, string $expected): void {
74
+        $this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT . '/tests/data' . $path));
75
+    }
76
+
77
+    public static function dataDetect(): array {
78
+        return [
79
+            ['/', 'httpd/unix-directory'],
80
+            ['/data.tar.gz', 'application/gzip'],
81
+            ['/data.zip', 'application/zip'],
82
+            ['/testimagelarge.svg', 'image/svg+xml'],
83
+            ['/testimage.png', 'image/png'],
84
+        ];
85
+    }
86
+
87
+    /**
88
+     * @dataProvider dataDetect
89
+     *
90
+     * @param string $path
91
+     * @param string $expected
92
+     */
93
+    public function testDetect(string $path, string $expected): void {
94
+        $this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT . '/tests/data' . $path));
95
+    }
96
+
97
+    public function testDetectString(): void {
98
+        $result = $this->detection->detectString('/data/data.tar.gz');
99
+        $expected = 'text/plain';
100
+        $this->assertEquals($expected, $result);
101
+    }
102
+
103
+    public static function dataMimeTypeCustom(): array {
104
+        return [
105
+            ['123', 'foobar/123'],
106
+            ['a123', 'foobar/123'],
107
+            ['bar', 'foobar/bar'],
108
+        ];
109
+    }
110
+
111
+    /**
112
+     * @dataProvider dataMimeTypeCustom
113
+     *
114
+     * @param string $ext
115
+     * @param string $mime
116
+     */
117
+    public function testDetectMimeTypeCustom(string $ext, string $mime): void {
118
+        $confDir = sys_get_temp_dir();
119
+        file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([]));
120
+
121
+        /** @var IURLGenerator $urlGenerator */
122
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
123
+            ->disableOriginalConstructor()
124
+            ->getMock();
125
+
126
+        /** @var LoggerInterface $logger */
127
+        $logger = $this->createMock(LoggerInterface::class);
128
+
129
+        // Create new mapping file
130
+        file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]]));
131
+
132
+        $detection = new Detection($urlGenerator, $logger, $confDir, $confDir);
133
+        $mappings = $detection->getAllMappings();
134
+        $this->assertArrayHasKey($ext, $mappings);
135
+        $this->assertEquals($mime, $detection->detectPath('foo.' . $ext));
136
+    }
137
+
138
+    public static function dataGetSecureMimeType(): array {
139
+        return [
140
+            ['image/svg+xml', 'text/plain'],
141
+            ['image/png', 'image/png'],
142
+        ];
143
+    }
144
+
145
+    /**
146
+     * @dataProvider dataGetSecureMimeType
147
+     *
148
+     * @param string $mimeType
149
+     * @param string $expected
150
+     */
151
+    public function testGetSecureMimeType(string $mimeType, string $expected): void {
152
+        $this->assertEquals($expected, $this->detection->getSecureMimeType($mimeType));
153
+    }
154
+
155
+    public function testMimeTypeIcon(): void {
156
+        if (!class_exists('org\\bovigo\\vfs\\vfsStream')) {
157
+            $this->markTestSkipped('Package vfsStream not installed');
158
+        }
159
+        $confDir = \org\bovigo\vfs\vfsStream::setup();
160
+        $mimetypealiases_dist = \org\bovigo\vfs\vfsStream::newFile('mimetypealiases.dist.json')->at($confDir);
161
+
162
+        //Empty alias file
163
+        $mimetypealiases_dist->setContent(json_encode([], JSON_FORCE_OBJECT));
164
+
165
+
166
+        /*
167 167
 		 * Test dir mimetype
168 168
 		 */
169 169
 
170
-		//Mock UrlGenerator
171
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
172
-			->disableOriginalConstructor()
173
-			->getMock();
170
+        //Mock UrlGenerator
171
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
172
+            ->disableOriginalConstructor()
173
+            ->getMock();
174 174
 
175
-		/** @var LoggerInterface $logger */
176
-		$logger = $this->createMock(LoggerInterface::class);
175
+        /** @var LoggerInterface $logger */
176
+        $logger = $this->createMock(LoggerInterface::class);
177 177
 
178
-		//Only call the url generator once
179
-		$urlGenerator->expects($this->once())
180
-			->method('imagePath')
181
-			->with($this->equalTo('core'), $this->equalTo('filetypes/folder.png'))
182
-			->willReturn('folder.svg');
178
+        //Only call the url generator once
179
+        $urlGenerator->expects($this->once())
180
+            ->method('imagePath')
181
+            ->with($this->equalTo('core'), $this->equalTo('filetypes/folder.png'))
182
+            ->willReturn('folder.svg');
183 183
 
184
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
185
-		$mimeType = $detection->mimeTypeIcon('dir');
186
-		$this->assertEquals('folder.svg', $mimeType);
184
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
185
+        $mimeType = $detection->mimeTypeIcon('dir');
186
+        $this->assertEquals('folder.svg', $mimeType);
187 187
 
188 188
 
189
-		/*
189
+        /*
190 190
 		 * Test dir-shareed mimetype
191 191
 		 */
192
-		//Mock UrlGenerator
193
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
194
-			->disableOriginalConstructor()
195
-			->getMock();
192
+        //Mock UrlGenerator
193
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
194
+            ->disableOriginalConstructor()
195
+            ->getMock();
196 196
 
197
-		//Only call the url generator once
198
-		$urlGenerator->expects($this->once())
199
-			->method('imagePath')
200
-			->with($this->equalTo('core'), $this->equalTo('filetypes/folder-shared.png'))
201
-			->willReturn('folder-shared.svg');
197
+        //Only call the url generator once
198
+        $urlGenerator->expects($this->once())
199
+            ->method('imagePath')
200
+            ->with($this->equalTo('core'), $this->equalTo('filetypes/folder-shared.png'))
201
+            ->willReturn('folder-shared.svg');
202 202
 
203
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
204
-		$mimeType = $detection->mimeTypeIcon('dir-shared');
205
-		$this->assertEquals('folder-shared.svg', $mimeType);
203
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
204
+        $mimeType = $detection->mimeTypeIcon('dir-shared');
205
+        $this->assertEquals('folder-shared.svg', $mimeType);
206 206
 
207 207
 
208
-		/*
208
+        /*
209 209
 		 * Test dir external
210 210
 		 */
211 211
 
212
-		//Mock UrlGenerator
213
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
214
-			->disableOriginalConstructor()
215
-			->getMock();
212
+        //Mock UrlGenerator
213
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
214
+            ->disableOriginalConstructor()
215
+            ->getMock();
216 216
 
217
-		//Only call the url generator once
218
-		$urlGenerator->expects($this->once())
219
-			->method('imagePath')
220
-			->with($this->equalTo('core'), $this->equalTo('filetypes/folder-external.png'))
221
-			->willReturn('folder-external.svg');
217
+        //Only call the url generator once
218
+        $urlGenerator->expects($this->once())
219
+            ->method('imagePath')
220
+            ->with($this->equalTo('core'), $this->equalTo('filetypes/folder-external.png'))
221
+            ->willReturn('folder-external.svg');
222 222
 
223
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
224
-		$mimeType = $detection->mimeTypeIcon('dir-external');
225
-		$this->assertEquals('folder-external.svg', $mimeType);
223
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
224
+        $mimeType = $detection->mimeTypeIcon('dir-external');
225
+        $this->assertEquals('folder-external.svg', $mimeType);
226 226
 
227 227
 
228
-		/*
228
+        /*
229 229
 		 * Test complete mimetype
230 230
 		 */
231 231
 
232
-		//Mock UrlGenerator
233
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
234
-			->disableOriginalConstructor()
235
-			->getMock();
232
+        //Mock UrlGenerator
233
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
234
+            ->disableOriginalConstructor()
235
+            ->getMock();
236 236
 
237
-		//Only call the url generator once
238
-		$urlGenerator->expects($this->once())
239
-			->method('imagePath')
240
-			->with($this->equalTo('core'), $this->equalTo('filetypes/my-type.png'))
241
-			->willReturn('my-type.svg');
237
+        //Only call the url generator once
238
+        $urlGenerator->expects($this->once())
239
+            ->method('imagePath')
240
+            ->with($this->equalTo('core'), $this->equalTo('filetypes/my-type.png'))
241
+            ->willReturn('my-type.svg');
242 242
 
243
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
244
-		$mimeType = $detection->mimeTypeIcon('my-type');
245
-		$this->assertEquals('my-type.svg', $mimeType);
243
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
244
+        $mimeType = $detection->mimeTypeIcon('my-type');
245
+        $this->assertEquals('my-type.svg', $mimeType);
246 246
 
247 247
 
248
-		/*
248
+        /*
249 249
 		 * Test subtype
250 250
 		 */
251 251
 
252
-		//Mock UrlGenerator
253
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
254
-			->disableOriginalConstructor()
255
-			->getMock();
256
-
257
-		//Only call the url generator once
258
-		$calls = [
259
-			['core', 'filetypes/my-type.png'],
260
-			['core', 'filetypes/my.png'],
261
-		];
262
-		$urlGenerator->expects($this->exactly(2))
263
-			->method('imagePath')
264
-			->willReturnCallback(
265
-				function ($appName, $file) use (&$calls) {
266
-					$expected = array_shift($calls);
267
-					$this->assertEquals($expected, [$appName, $file]);
268
-					if ($file === 'filetypes/my.png') {
269
-						return 'my.svg';
270
-					}
271
-					throw new \RuntimeException();
272
-				}
273
-			);
274
-
275
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
276
-		$mimeType = $detection->mimeTypeIcon('my-type');
277
-		$this->assertEquals('my.svg', $mimeType);
278
-
279
-
280
-		/*
252
+        //Mock UrlGenerator
253
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
254
+            ->disableOriginalConstructor()
255
+            ->getMock();
256
+
257
+        //Only call the url generator once
258
+        $calls = [
259
+            ['core', 'filetypes/my-type.png'],
260
+            ['core', 'filetypes/my.png'],
261
+        ];
262
+        $urlGenerator->expects($this->exactly(2))
263
+            ->method('imagePath')
264
+            ->willReturnCallback(
265
+                function ($appName, $file) use (&$calls) {
266
+                    $expected = array_shift($calls);
267
+                    $this->assertEquals($expected, [$appName, $file]);
268
+                    if ($file === 'filetypes/my.png') {
269
+                        return 'my.svg';
270
+                    }
271
+                    throw new \RuntimeException();
272
+                }
273
+            );
274
+
275
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
276
+        $mimeType = $detection->mimeTypeIcon('my-type');
277
+        $this->assertEquals('my.svg', $mimeType);
278
+
279
+
280
+        /*
281 281
 		 * Test default mimetype
282 282
 		 */
283 283
 
284
-		//Mock UrlGenerator
285
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
286
-			->disableOriginalConstructor()
287
-			->getMock();
288
-
289
-		//Only call the url generator once
290
-		$calls = [
291
-			['core', 'filetypes/foo-bar.png'],
292
-			['core', 'filetypes/foo.png'],
293
-			['core', 'filetypes/file.png'],
294
-		];
295
-		$urlGenerator->expects($this->exactly(3))
296
-			->method('imagePath')
297
-			->willReturnCallback(
298
-				function ($appName, $file) use (&$calls) {
299
-					$expected = array_shift($calls);
300
-					$this->assertEquals($expected, [$appName, $file]);
301
-					if ($file === 'filetypes/file.png') {
302
-						return 'file.svg';
303
-					}
304
-					throw new \RuntimeException();
305
-				}
306
-			);
307
-
308
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
309
-		$mimeType = $detection->mimeTypeIcon('foo-bar');
310
-		$this->assertEquals('file.svg', $mimeType);
311
-
312
-		/*
284
+        //Mock UrlGenerator
285
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
286
+            ->disableOriginalConstructor()
287
+            ->getMock();
288
+
289
+        //Only call the url generator once
290
+        $calls = [
291
+            ['core', 'filetypes/foo-bar.png'],
292
+            ['core', 'filetypes/foo.png'],
293
+            ['core', 'filetypes/file.png'],
294
+        ];
295
+        $urlGenerator->expects($this->exactly(3))
296
+            ->method('imagePath')
297
+            ->willReturnCallback(
298
+                function ($appName, $file) use (&$calls) {
299
+                    $expected = array_shift($calls);
300
+                    $this->assertEquals($expected, [$appName, $file]);
301
+                    if ($file === 'filetypes/file.png') {
302
+                        return 'file.svg';
303
+                    }
304
+                    throw new \RuntimeException();
305
+                }
306
+            );
307
+
308
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
309
+        $mimeType = $detection->mimeTypeIcon('foo-bar');
310
+        $this->assertEquals('file.svg', $mimeType);
311
+
312
+        /*
313 313
 		 * Test chaching
314 314
 		 */
315 315
 
316
-		//Mock UrlGenerator
317
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
318
-			->disableOriginalConstructor()
319
-			->getMock();
316
+        //Mock UrlGenerator
317
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
318
+            ->disableOriginalConstructor()
319
+            ->getMock();
320 320
 
321
-		//Only call the url generator once
322
-		$urlGenerator->expects($this->once())
323
-			->method('imagePath')
324
-			->with($this->equalTo('core'), $this->equalTo('filetypes/foo-bar.png'))
325
-			->willReturn('foo-bar.svg');
321
+        //Only call the url generator once
322
+        $urlGenerator->expects($this->once())
323
+            ->method('imagePath')
324
+            ->with($this->equalTo('core'), $this->equalTo('filetypes/foo-bar.png'))
325
+            ->willReturn('foo-bar.svg');
326 326
 
327
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
328
-		$mimeType = $detection->mimeTypeIcon('foo-bar');
329
-		$this->assertEquals('foo-bar.svg', $mimeType);
330
-		$mimeType = $detection->mimeTypeIcon('foo-bar');
331
-		$this->assertEquals('foo-bar.svg', $mimeType);
327
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
328
+        $mimeType = $detection->mimeTypeIcon('foo-bar');
329
+        $this->assertEquals('foo-bar.svg', $mimeType);
330
+        $mimeType = $detection->mimeTypeIcon('foo-bar');
331
+        $this->assertEquals('foo-bar.svg', $mimeType);
332 332
 
333 333
 
334 334
 
335
-		/*
335
+        /*
336 336
 		 * Test aliases
337 337
 		 */
338 338
 
339
-		//Put alias
340
-		$mimetypealiases_dist->setContent(json_encode(['foo' => 'foobar/baz'], JSON_FORCE_OBJECT));
339
+        //Put alias
340
+        $mimetypealiases_dist->setContent(json_encode(['foo' => 'foobar/baz'], JSON_FORCE_OBJECT));
341 341
 
342
-		//Mock UrlGenerator
343
-		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
344
-			->disableOriginalConstructor()
345
-			->getMock();
342
+        //Mock UrlGenerator
343
+        $urlGenerator = $this->getMockBuilder(IURLGenerator::class)
344
+            ->disableOriginalConstructor()
345
+            ->getMock();
346 346
 
347
-		//Only call the url generator once
348
-		$urlGenerator->expects($this->once())
349
-			->method('imagePath')
350
-			->with($this->equalTo('core'), $this->equalTo('filetypes/foobar-baz.png'))
351
-			->willReturn('foobar-baz.svg');
347
+        //Only call the url generator once
348
+        $urlGenerator->expects($this->once())
349
+            ->method('imagePath')
350
+            ->with($this->equalTo('core'), $this->equalTo('filetypes/foobar-baz.png'))
351
+            ->willReturn('foobar-baz.svg');
352 352
 
353
-		$detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
354
-		$mimeType = $detection->mimeTypeIcon('foo');
355
-		$this->assertEquals('foobar-baz.svg', $mimeType);
356
-	}
353
+        $detection = new Detection($urlGenerator, $logger, $confDir->url(), $confDir->url());
354
+        $mimeType = $detection->mimeTypeIcon('foo');
355
+        $this->assertEquals('foobar-baz.svg', $mimeType);
356
+    }
357 357
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -20,8 +20,8 @@  discard block
 block discarded – undo
20 20
 		$this->detection = new Detection(
21 21
 			\OC::$server->getURLGenerator(),
22 22
 			\OC::$server->get(LoggerInterface::class),
23
-			\OC::$SERVERROOT . '/config/',
24
-			\OC::$SERVERROOT . '/resources/config/'
23
+			\OC::$SERVERROOT.'/config/',
24
+			\OC::$SERVERROOT.'/resources/config/'
25 25
 		);
26 26
 	}
27 27
 
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
 	 * @param string $expected
72 72
 	 */
73 73
 	public function testDetectContent(string $path, string $expected): void {
74
-		$this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT . '/tests/data' . $path));
74
+		$this->assertEquals($expected, $this->detection->detectContent(\OC::$SERVERROOT.'/tests/data'.$path));
75 75
 	}
76 76
 
77 77
 	public static function dataDetect(): array {
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
 	 * @param string $expected
92 92
 	 */
93 93
 	public function testDetect(string $path, string $expected): void {
94
-		$this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT . '/tests/data' . $path));
94
+		$this->assertEquals($expected, $this->detection->detect(\OC::$SERVERROOT.'/tests/data'.$path));
95 95
 	}
96 96
 
97 97
 	public function testDetectString(): void {
@@ -116,7 +116,7 @@  discard block
 block discarded – undo
116 116
 	 */
117 117
 	public function testDetectMimeTypeCustom(string $ext, string $mime): void {
118 118
 		$confDir = sys_get_temp_dir();
119
-		file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([]));
119
+		file_put_contents($confDir.'/mimetypemapping.dist.json', json_encode([]));
120 120
 
121 121
 		/** @var IURLGenerator $urlGenerator */
122 122
 		$urlGenerator = $this->getMockBuilder(IURLGenerator::class)
@@ -127,12 +127,12 @@  discard block
 block discarded – undo
127 127
 		$logger = $this->createMock(LoggerInterface::class);
128 128
 
129 129
 		// Create new mapping file
130
-		file_put_contents($confDir . '/mimetypemapping.dist.json', json_encode([$ext => [$mime]]));
130
+		file_put_contents($confDir.'/mimetypemapping.dist.json', json_encode([$ext => [$mime]]));
131 131
 
132 132
 		$detection = new Detection($urlGenerator, $logger, $confDir, $confDir);
133 133
 		$mappings = $detection->getAllMappings();
134 134
 		$this->assertArrayHasKey($ext, $mappings);
135
-		$this->assertEquals($mime, $detection->detectPath('foo.' . $ext));
135
+		$this->assertEquals($mime, $detection->detectPath('foo.'.$ext));
136 136
 	}
137 137
 
138 138
 	public static function dataGetSecureMimeType(): array {
@@ -262,7 +262,7 @@  discard block
 block discarded – undo
262 262
 		$urlGenerator->expects($this->exactly(2))
263 263
 			->method('imagePath')
264 264
 			->willReturnCallback(
265
-				function ($appName, $file) use (&$calls) {
265
+				function($appName, $file) use (&$calls) {
266 266
 					$expected = array_shift($calls);
267 267
 					$this->assertEquals($expected, [$appName, $file]);
268 268
 					if ($file === 'filetypes/my.png') {
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
 		$urlGenerator->expects($this->exactly(3))
296 296
 			->method('imagePath')
297 297
 			->willReturnCallback(
298
-				function ($appName, $file) use (&$calls) {
298
+				function($appName, $file) use (&$calls) {
299 299
 					$expected = array_shift($calls);
300 300
 					$this->assertEquals($expected, [$appName, $file]);
301 301
 					if ($file === 'filetypes/file.png') {
Please login to merge, or discard this patch.