Completed
Push — master ( 5d14f8...2337bd )
by Robin
27:19 queued 16s
created
apps/files_external/tests/Service/UserStoragesServiceTest.php 1 patch
Indentation   +164 added lines, -164 removed lines patch added patch discarded remove patch
@@ -26,168 +26,168 @@
 block discarded – undo
26 26
  * @group DB
27 27
  */
28 28
 class UserStoragesServiceTest extends StoragesServiceTestCase {
29
-	use UserTrait;
30
-
31
-	protected User $user;
32
-
33
-	protected string $userId;
34
-	protected StoragesService $globalStoragesService;
35
-
36
-	protected function setUp(): void {
37
-		parent::setUp();
38
-
39
-		$this->globalStoragesService = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache, $this->eventDispatcher);
40
-
41
-		$this->userId = $this->getUniqueID('user_');
42
-		$this->createUser($this->userId, $this->userId);
43
-		$this->user = Server::get(IUserManager::class)->get($this->userId);
44
-
45
-		/** @var IUserSession&MockObject $userSession */
46
-		$userSession = $this->createMock(IUserSession::class);
47
-		$userSession
48
-			->expects($this->any())
49
-			->method('getUser')
50
-			->willReturn($this->user);
51
-
52
-		$this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession, $this->mountCache, $this->eventDispatcher);
53
-	}
54
-
55
-	private function makeTestStorageData() {
56
-		return $this->makeStorageConfig([
57
-			'mountPoint' => 'mountpoint',
58
-			'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
59
-			'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
60
-			'backendOptions' => [
61
-				'option1' => 'value1',
62
-				'option2' => 'value2',
63
-				'password' => 'testPassword',
64
-			],
65
-			'mountOptions' => [
66
-				'preview' => false,
67
-			]
68
-		]);
69
-	}
70
-
71
-	public function testAddStorage(): void {
72
-		$storage = $this->makeTestStorageData();
73
-
74
-		$newStorage = $this->service->addStorage($storage);
75
-
76
-		$id = $newStorage->getId();
77
-
78
-		$newStorage = $this->service->getStorage($id);
79
-
80
-		$this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
81
-		$this->assertEquals($storage->getBackend(), $newStorage->getBackend());
82
-		$this->assertEquals($storage->getAuthMechanism(), $newStorage->getAuthMechanism());
83
-		$this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
84
-		$this->assertEquals(0, $newStorage->getStatus());
85
-
86
-		// hook called once for user
87
-		$this->assertHookCall(
88
-			current(self::$hookCalls),
89
-			Filesystem::signal_create_mount,
90
-			$storage->getMountPoint(),
91
-			MountConfig::MOUNT_TYPE_USER,
92
-			$this->userId
93
-		);
94
-
95
-		$nextStorage = $this->service->addStorage($storage);
96
-		$this->assertEquals($id + 1, $nextStorage->getId());
97
-	}
98
-
99
-	public function testUpdateStorage(): void {
100
-		$storage = $this->makeStorageConfig([
101
-			'mountPoint' => 'mountpoint',
102
-			'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
103
-			'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
104
-			'backendOptions' => [
105
-				'option1' => 'value1',
106
-				'option2' => 'value2',
107
-				'password' => 'testPassword',
108
-			],
109
-		]);
110
-
111
-		$newStorage = $this->service->addStorage($storage);
112
-
113
-		$backendOptions = $newStorage->getBackendOptions();
114
-		$backendOptions['password'] = 'anotherPassword';
115
-		$newStorage->setBackendOptions($backendOptions);
116
-
117
-		self::$hookCalls = [];
118
-
119
-		$newStorage = $this->service->updateStorage($newStorage);
120
-
121
-		$this->assertEquals('anotherPassword', $newStorage->getBackendOptions()['password']);
122
-		$this->assertEquals([$this->userId], $newStorage->getApplicableUsers());
123
-		// these attributes are unused for user storages
124
-		$this->assertEmpty($newStorage->getApplicableGroups());
125
-		$this->assertEquals(0, $newStorage->getStatus());
126
-
127
-		// no hook calls
128
-		$this->assertEmpty(self::$hookCalls);
129
-	}
130
-
131
-	#[\PHPUnit\Framework\Attributes\DataProvider('deleteStorageDataProvider')]
132
-	public function testDeleteStorage($backendOptions, $rustyStorageId): void {
133
-		parent::testDeleteStorage($backendOptions, $rustyStorageId);
134
-
135
-		// hook called once for user (first one was during test creation)
136
-		$this->assertHookCall(
137
-			self::$hookCalls[1],
138
-			Filesystem::signal_delete_mount,
139
-			'/mountpoint',
140
-			MountConfig::MOUNT_TYPE_USER,
141
-			$this->userId
142
-		);
143
-	}
144
-
145
-	public function testHooksRenameMountPoint(): void {
146
-		$storage = $this->makeTestStorageData();
147
-		$storage = $this->service->addStorage($storage);
148
-
149
-		$storage->setMountPoint('renamedMountpoint');
150
-
151
-		// reset calls
152
-		self::$hookCalls = [];
153
-
154
-		$this->service->updateStorage($storage);
155
-
156
-		// hook called twice
157
-		$this->assertHookCall(
158
-			self::$hookCalls[0],
159
-			Filesystem::signal_delete_mount,
160
-			'/mountpoint',
161
-			MountConfig::MOUNT_TYPE_USER,
162
-			$this->userId
163
-		);
164
-		$this->assertHookCall(
165
-			self::$hookCalls[1],
166
-			Filesystem::signal_create_mount,
167
-			'/renamedMountpoint',
168
-			MountConfig::MOUNT_TYPE_USER,
169
-			$this->userId
170
-		);
171
-	}
172
-
173
-
174
-	public function testGetAdminStorage(): void {
175
-		$this->expectException(NotFoundException::class);
176
-
177
-		$backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
178
-		$authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
179
-
180
-		$storage = new StorageConfig();
181
-		$storage->setMountPoint('mountpoint');
182
-		$storage->setBackend($backend);
183
-		$storage->setAuthMechanism($authMechanism);
184
-		$storage->setBackendOptions(['password' => 'testPassword']);
185
-		$storage->setApplicableUsers([$this->userId]);
186
-
187
-		$newStorage = $this->globalStoragesService->addStorage($storage);
188
-
189
-		$this->assertInstanceOf('\OCA\Files_External\Lib\StorageConfig', $this->globalStoragesService->getStorage($newStorage->getId()));
190
-
191
-		$this->service->getStorage($newStorage->getId());
192
-	}
29
+    use UserTrait;
30
+
31
+    protected User $user;
32
+
33
+    protected string $userId;
34
+    protected StoragesService $globalStoragesService;
35
+
36
+    protected function setUp(): void {
37
+        parent::setUp();
38
+
39
+        $this->globalStoragesService = new GlobalStoragesService($this->backendService, $this->dbConfig, $this->mountCache, $this->eventDispatcher);
40
+
41
+        $this->userId = $this->getUniqueID('user_');
42
+        $this->createUser($this->userId, $this->userId);
43
+        $this->user = Server::get(IUserManager::class)->get($this->userId);
44
+
45
+        /** @var IUserSession&MockObject $userSession */
46
+        $userSession = $this->createMock(IUserSession::class);
47
+        $userSession
48
+            ->expects($this->any())
49
+            ->method('getUser')
50
+            ->willReturn($this->user);
51
+
52
+        $this->service = new UserStoragesService($this->backendService, $this->dbConfig, $userSession, $this->mountCache, $this->eventDispatcher);
53
+    }
54
+
55
+    private function makeTestStorageData() {
56
+        return $this->makeStorageConfig([
57
+            'mountPoint' => 'mountpoint',
58
+            'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
59
+            'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
60
+            'backendOptions' => [
61
+                'option1' => 'value1',
62
+                'option2' => 'value2',
63
+                'password' => 'testPassword',
64
+            ],
65
+            'mountOptions' => [
66
+                'preview' => false,
67
+            ]
68
+        ]);
69
+    }
70
+
71
+    public function testAddStorage(): void {
72
+        $storage = $this->makeTestStorageData();
73
+
74
+        $newStorage = $this->service->addStorage($storage);
75
+
76
+        $id = $newStorage->getId();
77
+
78
+        $newStorage = $this->service->getStorage($id);
79
+
80
+        $this->assertEquals($storage->getMountPoint(), $newStorage->getMountPoint());
81
+        $this->assertEquals($storage->getBackend(), $newStorage->getBackend());
82
+        $this->assertEquals($storage->getAuthMechanism(), $newStorage->getAuthMechanism());
83
+        $this->assertEquals($storage->getBackendOptions(), $newStorage->getBackendOptions());
84
+        $this->assertEquals(0, $newStorage->getStatus());
85
+
86
+        // hook called once for user
87
+        $this->assertHookCall(
88
+            current(self::$hookCalls),
89
+            Filesystem::signal_create_mount,
90
+            $storage->getMountPoint(),
91
+            MountConfig::MOUNT_TYPE_USER,
92
+            $this->userId
93
+        );
94
+
95
+        $nextStorage = $this->service->addStorage($storage);
96
+        $this->assertEquals($id + 1, $nextStorage->getId());
97
+    }
98
+
99
+    public function testUpdateStorage(): void {
100
+        $storage = $this->makeStorageConfig([
101
+            'mountPoint' => 'mountpoint',
102
+            'backendIdentifier' => 'identifier:\OCA\Files_External\Lib\Backend\SMB',
103
+            'authMechanismIdentifier' => 'identifier:\Auth\Mechanism',
104
+            'backendOptions' => [
105
+                'option1' => 'value1',
106
+                'option2' => 'value2',
107
+                'password' => 'testPassword',
108
+            ],
109
+        ]);
110
+
111
+        $newStorage = $this->service->addStorage($storage);
112
+
113
+        $backendOptions = $newStorage->getBackendOptions();
114
+        $backendOptions['password'] = 'anotherPassword';
115
+        $newStorage->setBackendOptions($backendOptions);
116
+
117
+        self::$hookCalls = [];
118
+
119
+        $newStorage = $this->service->updateStorage($newStorage);
120
+
121
+        $this->assertEquals('anotherPassword', $newStorage->getBackendOptions()['password']);
122
+        $this->assertEquals([$this->userId], $newStorage->getApplicableUsers());
123
+        // these attributes are unused for user storages
124
+        $this->assertEmpty($newStorage->getApplicableGroups());
125
+        $this->assertEquals(0, $newStorage->getStatus());
126
+
127
+        // no hook calls
128
+        $this->assertEmpty(self::$hookCalls);
129
+    }
130
+
131
+    #[\PHPUnit\Framework\Attributes\DataProvider('deleteStorageDataProvider')]
132
+    public function testDeleteStorage($backendOptions, $rustyStorageId): void {
133
+        parent::testDeleteStorage($backendOptions, $rustyStorageId);
134
+
135
+        // hook called once for user (first one was during test creation)
136
+        $this->assertHookCall(
137
+            self::$hookCalls[1],
138
+            Filesystem::signal_delete_mount,
139
+            '/mountpoint',
140
+            MountConfig::MOUNT_TYPE_USER,
141
+            $this->userId
142
+        );
143
+    }
144
+
145
+    public function testHooksRenameMountPoint(): void {
146
+        $storage = $this->makeTestStorageData();
147
+        $storage = $this->service->addStorage($storage);
148
+
149
+        $storage->setMountPoint('renamedMountpoint');
150
+
151
+        // reset calls
152
+        self::$hookCalls = [];
153
+
154
+        $this->service->updateStorage($storage);
155
+
156
+        // hook called twice
157
+        $this->assertHookCall(
158
+            self::$hookCalls[0],
159
+            Filesystem::signal_delete_mount,
160
+            '/mountpoint',
161
+            MountConfig::MOUNT_TYPE_USER,
162
+            $this->userId
163
+        );
164
+        $this->assertHookCall(
165
+            self::$hookCalls[1],
166
+            Filesystem::signal_create_mount,
167
+            '/renamedMountpoint',
168
+            MountConfig::MOUNT_TYPE_USER,
169
+            $this->userId
170
+        );
171
+    }
172
+
173
+
174
+    public function testGetAdminStorage(): void {
175
+        $this->expectException(NotFoundException::class);
176
+
177
+        $backend = $this->backendService->getBackend('identifier:\OCA\Files_External\Lib\Backend\SMB');
178
+        $authMechanism = $this->backendService->getAuthMechanism('identifier:\Auth\Mechanism');
179
+
180
+        $storage = new StorageConfig();
181
+        $storage->setMountPoint('mountpoint');
182
+        $storage->setBackend($backend);
183
+        $storage->setAuthMechanism($authMechanism);
184
+        $storage->setBackendOptions(['password' => 'testPassword']);
185
+        $storage->setApplicableUsers([$this->userId]);
186
+
187
+        $newStorage = $this->globalStoragesService->addStorage($storage);
188
+
189
+        $this->assertInstanceOf('\OCA\Files_External\Lib\StorageConfig', $this->globalStoragesService->getStorage($newStorage->getId()));
190
+
191
+        $this->service->getStorage($newStorage->getId());
192
+    }
193 193
 }
Please login to merge, or discard this patch.
apps/files_external/tests/Service/BackendServiceTest.php 1 patch
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -17,228 +17,228 @@
 block discarded – undo
17 17
 use PHPUnit\Framework\MockObject\MockObject;
18 18
 
19 19
 class BackendServiceTest extends \Test\TestCase {
20
-	protected IAppConfig&MockObject $appConfig;
21
-
22
-	protected function setUp(): void {
23
-		$this->appConfig = $this->createMock(IAppConfig::class);
24
-	}
25
-
26
-	/**
27
-	 * @return \OCA\Files_External\Lib\Backend\Backend&MockObject
28
-	 */
29
-	protected function getBackendMock(string $class) {
30
-		$backend = $this->createMock(Backend::class);
31
-		$backend->method('getIdentifier')->willReturn('identifier:' . $class);
32
-		$backend->method('getIdentifierAliases')->willReturn(['identifier:' . $class]);
33
-		return $backend;
34
-	}
35
-
36
-	/**
37
-	 * @param string $class
38
-	 *
39
-	 * @return AuthMechanism&MockObject
40
-	 */
41
-	protected function getAuthMechanismMock($class) {
42
-		$backend = $this->createMock(AuthMechanism::class);
43
-		$backend->method('getIdentifier')->willReturn('identifier:' . $class);
44
-		$backend->method('getIdentifierAliases')->willReturn(['identifier:' . $class]);
45
-		return $backend;
46
-	}
47
-
48
-	public function testRegisterBackend(): void {
49
-		$service = new BackendService($this->appConfig);
50
-
51
-		$backend = $this->getBackendMock('\Foo\Bar');
52
-
53
-		/** @var \OCA\Files_External\Lib\Backend\Backend&MockObject $backendAlias */
54
-		$backendAlias = $this->createMock(Backend::class);
55
-		$backendAlias->method('getIdentifierAliases')
56
-			->willReturn(['identifier_real', 'identifier_alias']);
57
-		$backendAlias->method('getIdentifier')
58
-			->willReturn('identifier_real');
59
-
60
-		$service->registerBackend($backend);
61
-		$service->registerBackend($backendAlias);
62
-
63
-		$this->assertEquals($backend, $service->getBackend('identifier:\Foo\Bar'));
64
-		$this->assertEquals($backendAlias, $service->getBackend('identifier_real'));
65
-		$this->assertEquals($backendAlias, $service->getBackend('identifier_alias'));
66
-
67
-		$backends = $service->getBackends();
68
-		$this->assertCount(2, $backends);
69
-		$this->assertArrayHasKey('identifier:\Foo\Bar', $backends);
70
-		$this->assertArrayHasKey('identifier_real', $backends);
71
-		$this->assertArrayNotHasKey('identifier_alias', $backends);
72
-	}
73
-
74
-	public function testBackendProvider(): void {
75
-		$service = new BackendService($this->appConfig);
76
-
77
-		$backend1 = $this->getBackendMock('\Foo\Bar');
78
-		$backend2 = $this->getBackendMock('\Bar\Foo');
79
-
80
-		/** @var IBackendProvider&MockObject $providerMock */
81
-		$providerMock = $this->createMock(IBackendProvider::class);
82
-		$providerMock->expects($this->once())
83
-			->method('getBackends')
84
-			->willReturn([$backend1, $backend2]);
85
-		$service->registerBackendProvider($providerMock);
86
-
87
-		$this->assertEquals($backend1, $service->getBackend('identifier:\Foo\Bar'));
88
-		$this->assertEquals($backend2, $service->getBackend('identifier:\Bar\Foo'));
89
-
90
-		$this->assertCount(2, $service->getBackends());
91
-	}
92
-
93
-	public function testAuthMechanismProvider(): void {
94
-		$service = new BackendService($this->appConfig);
95
-
96
-		$backend1 = $this->getAuthMechanismMock('\Foo\Bar');
97
-		$backend2 = $this->getAuthMechanismMock('\Bar\Foo');
98
-
99
-		/** @var IAuthMechanismProvider&MockObject $providerMock */
100
-		$providerMock = $this->createMock(IAuthMechanismProvider::class);
101
-		$providerMock->expects($this->once())
102
-			->method('getAuthMechanisms')
103
-			->willReturn([$backend1, $backend2]);
104
-		$service->registerAuthMechanismProvider($providerMock);
105
-
106
-		$this->assertEquals($backend1, $service->getAuthMechanism('identifier:\Foo\Bar'));
107
-		$this->assertEquals($backend2, $service->getAuthMechanism('identifier:\Bar\Foo'));
108
-
109
-		$this->assertCount(2, $service->getAuthMechanisms());
110
-	}
111
-
112
-	public function testMultipleBackendProviders(): void {
113
-		$service = new BackendService($this->appConfig);
114
-
115
-		$backend1a = $this->getBackendMock('\Foo\Bar');
116
-		$backend1b = $this->getBackendMock('\Bar\Foo');
117
-
118
-		$backend2 = $this->getBackendMock('\Dead\Beef');
119
-
120
-		/** @var IBackendProvider&MockObject $provider1Mock */
121
-		$provider1Mock = $this->createMock(IBackendProvider::class);
122
-		$provider1Mock->expects($this->once())
123
-			->method('getBackends')
124
-			->willReturn([$backend1a, $backend1b]);
125
-		$service->registerBackendProvider($provider1Mock);
126
-		/** @var IBackendProvider&MockObject $provider2Mock */
127
-		$provider2Mock = $this->createMock(IBackendProvider::class);
128
-		$provider2Mock->expects($this->once())
129
-			->method('getBackends')
130
-			->willReturn([$backend2]);
131
-		$service->registerBackendProvider($provider2Mock);
132
-
133
-		$this->assertEquals($backend1a, $service->getBackend('identifier:\Foo\Bar'));
134
-		$this->assertEquals($backend1b, $service->getBackend('identifier:\Bar\Foo'));
135
-		$this->assertEquals($backend2, $service->getBackend('identifier:\Dead\Beef'));
136
-
137
-		$this->assertCount(3, $service->getBackends());
138
-	}
139
-
140
-	public function testUserMountingBackends(): void {
141
-		$this->appConfig->expects($this->once())
142
-			->method('getValueString')
143
-			->with('files_external', 'user_mounting_backends')
144
-			->willReturn('identifier:\User\Mount\Allowed,identifier_alias');
145
-		$this->appConfig->expects($this->once())
146
-			->method('getValueBool')
147
-			->with('files_external', 'allow_user_mounting')
148
-			->willReturn(true);
149
-
150
-		$service = new BackendService($this->appConfig);
151
-
152
-		$backendAllowed = $this->getBackendMock('\User\Mount\Allowed');
153
-		$backendAllowed->expects($this->never())
154
-			->method('removeVisibility');
155
-		$backendNotAllowed = $this->getBackendMock('\User\Mount\NotAllowed');
156
-		$backendNotAllowed->expects($this->once())
157
-			->method('removeVisibility')
158
-			->with(BackendService::VISIBILITY_PERSONAL);
159
-
160
-		$backendAlias = $this->getMockBuilder(Backend::class)
161
-			->disableOriginalConstructor()
162
-			->getMock();
163
-		$backendAlias->method('getIdentifierAliases')
164
-			->willReturn(['identifier_real', 'identifier_alias']);
165
-		$backendAlias->expects($this->never())
166
-			->method('removeVisibility');
167
-
168
-		$service->registerBackend($backendAllowed);
169
-		$service->registerBackend($backendNotAllowed);
170
-		$service->registerBackend($backendAlias);
171
-	}
172
-
173
-	public function testGetAvailableBackends(): void {
174
-		$service = new BackendService($this->appConfig);
175
-
176
-		$backendAvailable = $this->getBackendMock('\Backend\Available');
177
-		$backendAvailable->expects($this->once())
178
-			->method('checkDependencies')
179
-			->willReturn([]);
180
-		$backendNotAvailable = $this->getBackendMock('\Backend\NotAvailable');
181
-		$backendNotAvailable->expects($this->once())
182
-			->method('checkDependencies')
183
-			->willReturn([
184
-				$this->getMockBuilder('\OCA\Files_External\Lib\MissingDependency')
185
-					->disableOriginalConstructor()
186
-					->getMock()
187
-			]);
188
-
189
-		$service->registerBackend($backendAvailable);
190
-		$service->registerBackend($backendNotAvailable);
191
-
192
-		$availableBackends = $service->getAvailableBackends();
193
-		$this->assertArrayHasKey('identifier:\Backend\Available', $availableBackends);
194
-		$this->assertArrayNotHasKey('identifier:\Backend\NotAvailable', $availableBackends);
195
-	}
196
-
197
-	public static function invalidConfigPlaceholderProvider(): array {
198
-		return [
199
-			[['@user']],
200
-			[['$user']],
201
-			[['hællo']],
202
-			[['spa ce']],
203
-			[['yo\o']],
204
-			[['<script>…</script>']],
205
-			[['xxyoloxx', 'invÆlid']],
206
-			[['tautology', 'tautology']],
207
-			[['tautology2', 'TAUTOLOGY2']],
208
-		];
209
-	}
210
-
211
-	#[\PHPUnit\Framework\Attributes\DataProvider('invalidConfigPlaceholderProvider')]
212
-	public function testRegisterConfigHandlerInvalid(array $placeholders): void {
213
-		$this->expectException(\RuntimeException::class);
214
-
215
-		$service = new BackendService($this->appConfig);
216
-		$mock = $this->createMock(IConfigHandler::class);
217
-		$cb = function () use ($mock) {
218
-			return $mock;
219
-		};
220
-		foreach ($placeholders as $placeholder) {
221
-			$service->registerConfigHandler($placeholder, $cb);
222
-		}
223
-	}
224
-
225
-	public function testConfigHandlers(): void {
226
-		$service = new BackendService($this->appConfig);
227
-		$mock = $this->createMock(IConfigHandler::class);
228
-		$mock->expects($this->exactly(3))
229
-			->method('handle');
230
-		$cb = function () use ($mock) {
231
-			return $mock;
232
-		};
233
-		$service->registerConfigHandler('one', $cb);
234
-		$service->registerConfigHandler('2', $cb);
235
-		$service->registerConfigHandler('Three', $cb);
236
-
237
-		/** @var IConfigHandler[] $handlers */
238
-		$handlers = $service->getConfigHandlers();
239
-
240
-		foreach ($handlers as $handler) {
241
-			$handler->handle('Something');
242
-		}
243
-	}
20
+    protected IAppConfig&MockObject $appConfig;
21
+
22
+    protected function setUp(): void {
23
+        $this->appConfig = $this->createMock(IAppConfig::class);
24
+    }
25
+
26
+    /**
27
+     * @return \OCA\Files_External\Lib\Backend\Backend&MockObject
28
+     */
29
+    protected function getBackendMock(string $class) {
30
+        $backend = $this->createMock(Backend::class);
31
+        $backend->method('getIdentifier')->willReturn('identifier:' . $class);
32
+        $backend->method('getIdentifierAliases')->willReturn(['identifier:' . $class]);
33
+        return $backend;
34
+    }
35
+
36
+    /**
37
+     * @param string $class
38
+     *
39
+     * @return AuthMechanism&MockObject
40
+     */
41
+    protected function getAuthMechanismMock($class) {
42
+        $backend = $this->createMock(AuthMechanism::class);
43
+        $backend->method('getIdentifier')->willReturn('identifier:' . $class);
44
+        $backend->method('getIdentifierAliases')->willReturn(['identifier:' . $class]);
45
+        return $backend;
46
+    }
47
+
48
+    public function testRegisterBackend(): void {
49
+        $service = new BackendService($this->appConfig);
50
+
51
+        $backend = $this->getBackendMock('\Foo\Bar');
52
+
53
+        /** @var \OCA\Files_External\Lib\Backend\Backend&MockObject $backendAlias */
54
+        $backendAlias = $this->createMock(Backend::class);
55
+        $backendAlias->method('getIdentifierAliases')
56
+            ->willReturn(['identifier_real', 'identifier_alias']);
57
+        $backendAlias->method('getIdentifier')
58
+            ->willReturn('identifier_real');
59
+
60
+        $service->registerBackend($backend);
61
+        $service->registerBackend($backendAlias);
62
+
63
+        $this->assertEquals($backend, $service->getBackend('identifier:\Foo\Bar'));
64
+        $this->assertEquals($backendAlias, $service->getBackend('identifier_real'));
65
+        $this->assertEquals($backendAlias, $service->getBackend('identifier_alias'));
66
+
67
+        $backends = $service->getBackends();
68
+        $this->assertCount(2, $backends);
69
+        $this->assertArrayHasKey('identifier:\Foo\Bar', $backends);
70
+        $this->assertArrayHasKey('identifier_real', $backends);
71
+        $this->assertArrayNotHasKey('identifier_alias', $backends);
72
+    }
73
+
74
+    public function testBackendProvider(): void {
75
+        $service = new BackendService($this->appConfig);
76
+
77
+        $backend1 = $this->getBackendMock('\Foo\Bar');
78
+        $backend2 = $this->getBackendMock('\Bar\Foo');
79
+
80
+        /** @var IBackendProvider&MockObject $providerMock */
81
+        $providerMock = $this->createMock(IBackendProvider::class);
82
+        $providerMock->expects($this->once())
83
+            ->method('getBackends')
84
+            ->willReturn([$backend1, $backend2]);
85
+        $service->registerBackendProvider($providerMock);
86
+
87
+        $this->assertEquals($backend1, $service->getBackend('identifier:\Foo\Bar'));
88
+        $this->assertEquals($backend2, $service->getBackend('identifier:\Bar\Foo'));
89
+
90
+        $this->assertCount(2, $service->getBackends());
91
+    }
92
+
93
+    public function testAuthMechanismProvider(): void {
94
+        $service = new BackendService($this->appConfig);
95
+
96
+        $backend1 = $this->getAuthMechanismMock('\Foo\Bar');
97
+        $backend2 = $this->getAuthMechanismMock('\Bar\Foo');
98
+
99
+        /** @var IAuthMechanismProvider&MockObject $providerMock */
100
+        $providerMock = $this->createMock(IAuthMechanismProvider::class);
101
+        $providerMock->expects($this->once())
102
+            ->method('getAuthMechanisms')
103
+            ->willReturn([$backend1, $backend2]);
104
+        $service->registerAuthMechanismProvider($providerMock);
105
+
106
+        $this->assertEquals($backend1, $service->getAuthMechanism('identifier:\Foo\Bar'));
107
+        $this->assertEquals($backend2, $service->getAuthMechanism('identifier:\Bar\Foo'));
108
+
109
+        $this->assertCount(2, $service->getAuthMechanisms());
110
+    }
111
+
112
+    public function testMultipleBackendProviders(): void {
113
+        $service = new BackendService($this->appConfig);
114
+
115
+        $backend1a = $this->getBackendMock('\Foo\Bar');
116
+        $backend1b = $this->getBackendMock('\Bar\Foo');
117
+
118
+        $backend2 = $this->getBackendMock('\Dead\Beef');
119
+
120
+        /** @var IBackendProvider&MockObject $provider1Mock */
121
+        $provider1Mock = $this->createMock(IBackendProvider::class);
122
+        $provider1Mock->expects($this->once())
123
+            ->method('getBackends')
124
+            ->willReturn([$backend1a, $backend1b]);
125
+        $service->registerBackendProvider($provider1Mock);
126
+        /** @var IBackendProvider&MockObject $provider2Mock */
127
+        $provider2Mock = $this->createMock(IBackendProvider::class);
128
+        $provider2Mock->expects($this->once())
129
+            ->method('getBackends')
130
+            ->willReturn([$backend2]);
131
+        $service->registerBackendProvider($provider2Mock);
132
+
133
+        $this->assertEquals($backend1a, $service->getBackend('identifier:\Foo\Bar'));
134
+        $this->assertEquals($backend1b, $service->getBackend('identifier:\Bar\Foo'));
135
+        $this->assertEquals($backend2, $service->getBackend('identifier:\Dead\Beef'));
136
+
137
+        $this->assertCount(3, $service->getBackends());
138
+    }
139
+
140
+    public function testUserMountingBackends(): void {
141
+        $this->appConfig->expects($this->once())
142
+            ->method('getValueString')
143
+            ->with('files_external', 'user_mounting_backends')
144
+            ->willReturn('identifier:\User\Mount\Allowed,identifier_alias');
145
+        $this->appConfig->expects($this->once())
146
+            ->method('getValueBool')
147
+            ->with('files_external', 'allow_user_mounting')
148
+            ->willReturn(true);
149
+
150
+        $service = new BackendService($this->appConfig);
151
+
152
+        $backendAllowed = $this->getBackendMock('\User\Mount\Allowed');
153
+        $backendAllowed->expects($this->never())
154
+            ->method('removeVisibility');
155
+        $backendNotAllowed = $this->getBackendMock('\User\Mount\NotAllowed');
156
+        $backendNotAllowed->expects($this->once())
157
+            ->method('removeVisibility')
158
+            ->with(BackendService::VISIBILITY_PERSONAL);
159
+
160
+        $backendAlias = $this->getMockBuilder(Backend::class)
161
+            ->disableOriginalConstructor()
162
+            ->getMock();
163
+        $backendAlias->method('getIdentifierAliases')
164
+            ->willReturn(['identifier_real', 'identifier_alias']);
165
+        $backendAlias->expects($this->never())
166
+            ->method('removeVisibility');
167
+
168
+        $service->registerBackend($backendAllowed);
169
+        $service->registerBackend($backendNotAllowed);
170
+        $service->registerBackend($backendAlias);
171
+    }
172
+
173
+    public function testGetAvailableBackends(): void {
174
+        $service = new BackendService($this->appConfig);
175
+
176
+        $backendAvailable = $this->getBackendMock('\Backend\Available');
177
+        $backendAvailable->expects($this->once())
178
+            ->method('checkDependencies')
179
+            ->willReturn([]);
180
+        $backendNotAvailable = $this->getBackendMock('\Backend\NotAvailable');
181
+        $backendNotAvailable->expects($this->once())
182
+            ->method('checkDependencies')
183
+            ->willReturn([
184
+                $this->getMockBuilder('\OCA\Files_External\Lib\MissingDependency')
185
+                    ->disableOriginalConstructor()
186
+                    ->getMock()
187
+            ]);
188
+
189
+        $service->registerBackend($backendAvailable);
190
+        $service->registerBackend($backendNotAvailable);
191
+
192
+        $availableBackends = $service->getAvailableBackends();
193
+        $this->assertArrayHasKey('identifier:\Backend\Available', $availableBackends);
194
+        $this->assertArrayNotHasKey('identifier:\Backend\NotAvailable', $availableBackends);
195
+    }
196
+
197
+    public static function invalidConfigPlaceholderProvider(): array {
198
+        return [
199
+            [['@user']],
200
+            [['$user']],
201
+            [['hællo']],
202
+            [['spa ce']],
203
+            [['yo\o']],
204
+            [['<script>…</script>']],
205
+            [['xxyoloxx', 'invÆlid']],
206
+            [['tautology', 'tautology']],
207
+            [['tautology2', 'TAUTOLOGY2']],
208
+        ];
209
+    }
210
+
211
+    #[\PHPUnit\Framework\Attributes\DataProvider('invalidConfigPlaceholderProvider')]
212
+    public function testRegisterConfigHandlerInvalid(array $placeholders): void {
213
+        $this->expectException(\RuntimeException::class);
214
+
215
+        $service = new BackendService($this->appConfig);
216
+        $mock = $this->createMock(IConfigHandler::class);
217
+        $cb = function () use ($mock) {
218
+            return $mock;
219
+        };
220
+        foreach ($placeholders as $placeholder) {
221
+            $service->registerConfigHandler($placeholder, $cb);
222
+        }
223
+    }
224
+
225
+    public function testConfigHandlers(): void {
226
+        $service = new BackendService($this->appConfig);
227
+        $mock = $this->createMock(IConfigHandler::class);
228
+        $mock->expects($this->exactly(3))
229
+            ->method('handle');
230
+        $cb = function () use ($mock) {
231
+            return $mock;
232
+        };
233
+        $service->registerConfigHandler('one', $cb);
234
+        $service->registerConfigHandler('2', $cb);
235
+        $service->registerConfigHandler('Three', $cb);
236
+
237
+        /** @var IConfigHandler[] $handlers */
238
+        $handlers = $service->getConfigHandlers();
239
+
240
+        foreach ($handlers as $handler) {
241
+            $handler->handle('Something');
242
+        }
243
+    }
244 244
 }
Please login to merge, or discard this patch.
apps/files_external/tests/Backend/BackendTest.php 1 patch
Indentation   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -12,62 +12,62 @@
 block discarded – undo
12 12
 use OCA\Files_External\Lib\StorageConfig;
13 13
 
14 14
 class BackendTest extends \Test\TestCase {
15
-	public function testJsonSerialization(): void {
16
-		$backend = $this->getMockBuilder(Backend::class)
17
-			->onlyMethods(['jsonSerializeDefinition'])
18
-			->getMock();
19
-		$backend->expects($this->once())
20
-			->method('jsonSerializeDefinition')
21
-			->willReturn(['foo' => 'bar', 'name' => 'abc']);
15
+    public function testJsonSerialization(): void {
16
+        $backend = $this->getMockBuilder(Backend::class)
17
+            ->onlyMethods(['jsonSerializeDefinition'])
18
+            ->getMock();
19
+        $backend->expects($this->once())
20
+            ->method('jsonSerializeDefinition')
21
+            ->willReturn(['foo' => 'bar', 'name' => 'abc']);
22 22
 
23
-		$backend->setPriority(57);
24
-		$backend->addAuthScheme('foopass');
25
-		$backend->addAuthScheme('barauth');
23
+        $backend->setPriority(57);
24
+        $backend->addAuthScheme('foopass');
25
+        $backend->addAuthScheme('barauth');
26 26
 
27
-		$json = $backend->jsonSerialize();
28
-		$this->assertEquals('bar', $json['foo']);
29
-		$this->assertEquals('abc', $json['name']);
30
-		$this->assertEquals($json['name'], $json['backend']);
31
-		$this->assertEquals(57, $json['priority']);
27
+        $json = $backend->jsonSerialize();
28
+        $this->assertEquals('bar', $json['foo']);
29
+        $this->assertEquals('abc', $json['name']);
30
+        $this->assertEquals($json['name'], $json['backend']);
31
+        $this->assertEquals(57, $json['priority']);
32 32
 
33
-		$this->assertContains('foopass', array_keys($json['authSchemes']));
34
-		$this->assertContains('barauth', array_keys($json['authSchemes']));
35
-	}
33
+        $this->assertContains('foopass', array_keys($json['authSchemes']));
34
+        $this->assertContains('barauth', array_keys($json['authSchemes']));
35
+    }
36 36
 
37
-	public static function validateStorageProvider(): array {
38
-		return [
39
-			[true, true],
40
-			[false, false],
41
-		];
42
-	}
37
+    public static function validateStorageProvider(): array {
38
+        return [
39
+            [true, true],
40
+            [false, false],
41
+        ];
42
+    }
43 43
 
44
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateStorageProvider')]
45
-	public function testValidateStorage(bool $expectedSuccess, bool $definitionSuccess): void {
46
-		$backend = $this->getMockBuilder(Backend::class)
47
-			->onlyMethods(['validateStorageDefinition'])
48
-			->getMock();
49
-		$backend->expects($this->atMost(1))
50
-			->method('validateStorageDefinition')
51
-			->willReturn($definitionSuccess);
44
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateStorageProvider')]
45
+    public function testValidateStorage(bool $expectedSuccess, bool $definitionSuccess): void {
46
+        $backend = $this->getMockBuilder(Backend::class)
47
+            ->onlyMethods(['validateStorageDefinition'])
48
+            ->getMock();
49
+        $backend->expects($this->atMost(1))
50
+            ->method('validateStorageDefinition')
51
+            ->willReturn($definitionSuccess);
52 52
 
53
-		$storageConfig = $this->getMockBuilder(StorageConfig::class)
54
-			->disableOriginalConstructor()
55
-			->getMock();
53
+        $storageConfig = $this->getMockBuilder(StorageConfig::class)
54
+            ->disableOriginalConstructor()
55
+            ->getMock();
56 56
 
57
-		$this->assertEquals($expectedSuccess, $backend->validateStorage($storageConfig));
58
-	}
57
+        $this->assertEquals($expectedSuccess, $backend->validateStorage($storageConfig));
58
+    }
59 59
 
60
-	public function testLegacyAuthMechanismCallback(): void {
61
-		$backend = new Backend();
62
-		$backend->setLegacyAuthMechanismCallback(function (array $params) {
63
-			if (isset($params['ping'])) {
64
-				return 'pong';
65
-			}
66
-			return 'foobar';
67
-		});
60
+    public function testLegacyAuthMechanismCallback(): void {
61
+        $backend = new Backend();
62
+        $backend->setLegacyAuthMechanismCallback(function (array $params) {
63
+            if (isset($params['ping'])) {
64
+                return 'pong';
65
+            }
66
+            return 'foobar';
67
+        });
68 68
 
69
-		$this->assertEquals('pong', $backend->getLegacyAuthMechanism(['ping' => true]));
70
-		$this->assertEquals('foobar', $backend->getLegacyAuthMechanism(['other' => true]));
71
-		$this->assertEquals('foobar', $backend->getLegacyAuthMechanism());
72
-	}
69
+        $this->assertEquals('pong', $backend->getLegacyAuthMechanism(['ping' => true]));
70
+        $this->assertEquals('foobar', $backend->getLegacyAuthMechanism(['other' => true]));
71
+        $this->assertEquals('foobar', $backend->getLegacyAuthMechanism());
72
+    }
73 73
 }
Please login to merge, or discard this patch.
apps/files_external/tests/OwnCloudFunctionsTest.php 1 patch
Indentation   +75 added lines, -75 removed lines patch added patch discarded remove patch
@@ -18,80 +18,80 @@
 block discarded – undo
18 18
  * @package OCA\Files_External\Tests
19 19
  */
20 20
 class OwnCloudFunctionsTest extends \Test\TestCase {
21
-	public static function configUrlProvider(): array {
22
-		return [
23
-			[
24
-				[
25
-					'host' => 'testhost',
26
-					'root' => 'testroot',
27
-					'secure' => false
28
-				],
29
-				'http://testhost/remote.php/webdav/testroot/',
30
-			],
31
-			[
32
-				[
33
-					'host' => 'testhost',
34
-					'root' => 'testroot',
35
-					'secure' => true
36
-				],
37
-				'https://testhost/remote.php/webdav/testroot/',
38
-			],
39
-			[
40
-				[
41
-					'host' => 'http://testhost',
42
-					'root' => 'testroot',
43
-					'secure' => false
44
-				],
45
-				'http://testhost/remote.php/webdav/testroot/',
46
-			],
47
-			[
48
-				[
49
-					'host' => 'https://testhost',
50
-					'root' => 'testroot',
51
-					'secure' => false
52
-				],
53
-				'https://testhost/remote.php/webdav/testroot/',
54
-			],
55
-			[
56
-				[
57
-					'host' => 'https://testhost/testroot',
58
-					'root' => '',
59
-					'secure' => false
60
-				],
61
-				'https://testhost/testroot/remote.php/webdav/',
62
-			],
63
-			[
64
-				[
65
-					'host' => 'https://testhost/testroot',
66
-					'root' => 'subdir',
67
-					'secure' => false
68
-				],
69
-				'https://testhost/testroot/remote.php/webdav/subdir/',
70
-			],
71
-			[
72
-				[
73
-					'host' => 'http://testhost/testroot',
74
-					'root' => 'subdir',
75
-					'secure' => true
76
-				],
77
-				'http://testhost/testroot/remote.php/webdav/subdir/',
78
-			],
79
-			[
80
-				[
81
-					'host' => 'http://testhost/testroot/',
82
-					'root' => '/subdir',
83
-					'secure' => false
84
-				],
85
-				'http://testhost/testroot/remote.php/webdav/subdir/',
86
-			],
87
-		];
88
-	}
21
+    public static function configUrlProvider(): array {
22
+        return [
23
+            [
24
+                [
25
+                    'host' => 'testhost',
26
+                    'root' => 'testroot',
27
+                    'secure' => false
28
+                ],
29
+                'http://testhost/remote.php/webdav/testroot/',
30
+            ],
31
+            [
32
+                [
33
+                    'host' => 'testhost',
34
+                    'root' => 'testroot',
35
+                    'secure' => true
36
+                ],
37
+                'https://testhost/remote.php/webdav/testroot/',
38
+            ],
39
+            [
40
+                [
41
+                    'host' => 'http://testhost',
42
+                    'root' => 'testroot',
43
+                    'secure' => false
44
+                ],
45
+                'http://testhost/remote.php/webdav/testroot/',
46
+            ],
47
+            [
48
+                [
49
+                    'host' => 'https://testhost',
50
+                    'root' => 'testroot',
51
+                    'secure' => false
52
+                ],
53
+                'https://testhost/remote.php/webdav/testroot/',
54
+            ],
55
+            [
56
+                [
57
+                    'host' => 'https://testhost/testroot',
58
+                    'root' => '',
59
+                    'secure' => false
60
+                ],
61
+                'https://testhost/testroot/remote.php/webdav/',
62
+            ],
63
+            [
64
+                [
65
+                    'host' => 'https://testhost/testroot',
66
+                    'root' => 'subdir',
67
+                    'secure' => false
68
+                ],
69
+                'https://testhost/testroot/remote.php/webdav/subdir/',
70
+            ],
71
+            [
72
+                [
73
+                    'host' => 'http://testhost/testroot',
74
+                    'root' => 'subdir',
75
+                    'secure' => true
76
+                ],
77
+                'http://testhost/testroot/remote.php/webdav/subdir/',
78
+            ],
79
+            [
80
+                [
81
+                    'host' => 'http://testhost/testroot/',
82
+                    'root' => '/subdir',
83
+                    'secure' => false
84
+                ],
85
+                'http://testhost/testroot/remote.php/webdav/subdir/',
86
+            ],
87
+        ];
88
+    }
89 89
 
90
-	#[\PHPUnit\Framework\Attributes\DataProvider('configUrlProvider')]
91
-	public function testConfig(array $config, string $expectedUri): void {
92
-		$config['user'] = 'someuser';
93
-		$config['password'] = 'somepassword';
94
-		$instance = new OwnCloud($config);
95
-		$this->assertEquals($expectedUri, $instance->createBaseUri());
96
-	}
90
+    #[\PHPUnit\Framework\Attributes\DataProvider('configUrlProvider')]
91
+    public function testConfig(array $config, string $expectedUri): void {
92
+        $config['user'] = 'someuser';
93
+        $config['password'] = 'somepassword';
94
+        $instance = new OwnCloud($config);
95
+        $this->assertEquals($expectedUri, $instance->createBaseUri());
96
+    }
97 97
 }
Please login to merge, or discard this patch.
apps/files_external/tests/DefinitionParameterTest.php 1 patch
Indentation   +60 added lines, -60 removed lines patch added patch discarded remove patch
@@ -11,72 +11,72 @@
 block discarded – undo
11 11
 use OCA\Files_External\Lib\DefinitionParameter as Param;
12 12
 
13 13
 class DefinitionParameterTest extends \Test\TestCase {
14
-	public function testJsonSerialization(): void {
15
-		$param = new Param('foo', 'bar');
16
-		$this->assertEquals([
17
-			'value' => 'bar',
18
-			'flags' => 0,
19
-			'type' => 0,
20
-			'tooltip' => '',
21
-		], $param->jsonSerialize());
14
+    public function testJsonSerialization(): void {
15
+        $param = new Param('foo', 'bar');
16
+        $this->assertEquals([
17
+            'value' => 'bar',
18
+            'flags' => 0,
19
+            'type' => 0,
20
+            'tooltip' => '',
21
+        ], $param->jsonSerialize());
22 22
 
23
-		$param->setType(Param::VALUE_BOOLEAN);
24
-		$param->setDefaultValue(true);
25
-		$this->assertEquals([
26
-			'value' => 'bar',
27
-			'flags' => 0,
28
-			'type' => Param::VALUE_BOOLEAN,
29
-			'tooltip' => '',
30
-			'defaultValue' => true,
31
-		], $param->jsonSerialize());
23
+        $param->setType(Param::VALUE_BOOLEAN);
24
+        $param->setDefaultValue(true);
25
+        $this->assertEquals([
26
+            'value' => 'bar',
27
+            'flags' => 0,
28
+            'type' => Param::VALUE_BOOLEAN,
29
+            'tooltip' => '',
30
+            'defaultValue' => true,
31
+        ], $param->jsonSerialize());
32 32
 
33
-		$param->setType(Param::VALUE_PASSWORD);
34
-		$param->setFlag(Param::FLAG_OPTIONAL);
35
-		$param->setDefaultValue(null);
36
-		$this->assertEquals([
37
-			'value' => 'bar',
38
-			'flags' => Param::FLAG_OPTIONAL,
39
-			'type' => Param::VALUE_PASSWORD,
40
-			'tooltip' => '',
41
-		], $param->jsonSerialize());
33
+        $param->setType(Param::VALUE_PASSWORD);
34
+        $param->setFlag(Param::FLAG_OPTIONAL);
35
+        $param->setDefaultValue(null);
36
+        $this->assertEquals([
37
+            'value' => 'bar',
38
+            'flags' => Param::FLAG_OPTIONAL,
39
+            'type' => Param::VALUE_PASSWORD,
40
+            'tooltip' => '',
41
+        ], $param->jsonSerialize());
42 42
 
43
-		$param->setType(Param::VALUE_TEXT);
44
-		$param->setFlags(Param::FLAG_HIDDEN);
45
-		$this->assertEquals([
46
-			'value' => 'bar',
47
-			'flags' => Param::FLAG_HIDDEN,
48
-			'type' => Param::VALUE_TEXT,
49
-			'tooltip' => '',
50
-		], $param->jsonSerialize());
51
-	}
43
+        $param->setType(Param::VALUE_TEXT);
44
+        $param->setFlags(Param::FLAG_HIDDEN);
45
+        $this->assertEquals([
46
+            'value' => 'bar',
47
+            'flags' => Param::FLAG_HIDDEN,
48
+            'type' => Param::VALUE_TEXT,
49
+            'tooltip' => '',
50
+        ], $param->jsonSerialize());
51
+    }
52 52
 
53
-	public static function validateValueProvider(): array {
54
-		return [
55
-			[Param::VALUE_TEXT, Param::FLAG_NONE, 'abc', true],
56
-			[Param::VALUE_TEXT, Param::FLAG_NONE, '', false],
57
-			[Param::VALUE_TEXT, Param::FLAG_OPTIONAL, '', true],
58
-			[Param::VALUE_TEXT, Param::FLAG_HIDDEN, '', false],
53
+    public static function validateValueProvider(): array {
54
+        return [
55
+            [Param::VALUE_TEXT, Param::FLAG_NONE, 'abc', true],
56
+            [Param::VALUE_TEXT, Param::FLAG_NONE, '', false],
57
+            [Param::VALUE_TEXT, Param::FLAG_OPTIONAL, '', true],
58
+            [Param::VALUE_TEXT, Param::FLAG_HIDDEN, '', false],
59 59
 
60
-			[Param::VALUE_BOOLEAN, Param::FLAG_NONE, false, true],
61
-			[Param::VALUE_BOOLEAN, Param::FLAG_NONE, 123, false],
62
-			// conversion from string to boolean
63
-			[Param::VALUE_BOOLEAN, Param::FLAG_NONE, 'false', true, false],
64
-			[Param::VALUE_BOOLEAN, Param::FLAG_NONE, 'true', true, true],
60
+            [Param::VALUE_BOOLEAN, Param::FLAG_NONE, false, true],
61
+            [Param::VALUE_BOOLEAN, Param::FLAG_NONE, 123, false],
62
+            // conversion from string to boolean
63
+            [Param::VALUE_BOOLEAN, Param::FLAG_NONE, 'false', true, false],
64
+            [Param::VALUE_BOOLEAN, Param::FLAG_NONE, 'true', true, true],
65 65
 
66
-			[Param::VALUE_PASSWORD, Param::FLAG_NONE, 'foobar', true],
67
-			[Param::VALUE_PASSWORD, Param::FLAG_NONE, '', false],
68
-		];
69
-	}
66
+            [Param::VALUE_PASSWORD, Param::FLAG_NONE, 'foobar', true],
67
+            [Param::VALUE_PASSWORD, Param::FLAG_NONE, '', false],
68
+        ];
69
+    }
70 70
 
71
-	#[\PHPUnit\Framework\Attributes\DataProvider('validateValueProvider')]
72
-	public function testValidateValue($type, $flags, $value, $success, $expectedValue = null): void {
73
-		$param = new Param('foo', 'bar');
74
-		$param->setType($type);
75
-		$param->setFlags($flags);
71
+    #[\PHPUnit\Framework\Attributes\DataProvider('validateValueProvider')]
72
+    public function testValidateValue($type, $flags, $value, $success, $expectedValue = null): void {
73
+        $param = new Param('foo', 'bar');
74
+        $param->setType($type);
75
+        $param->setFlags($flags);
76 76
 
77
-		$this->assertEquals($success, $param->validateValue($value));
78
-		if (isset($expectedValue)) {
79
-			$this->assertEquals($expectedValue, $value);
80
-		}
81
-	}
77
+        $this->assertEquals($success, $param->validateValue($value));
78
+        if (isset($expectedValue)) {
79
+            $this->assertEquals($expectedValue, $value);
80
+        }
81
+    }
82 82
 }
Please login to merge, or discard this patch.
apps/files_external/tests/LegacyDependencyCheckPolyfillTest.php 1 patch
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -13,27 +13,27 @@
 block discarded – undo
13 13
 
14 14
 class LegacyDependencyCheckPolyfillTest extends \Test\TestCase {
15 15
 
16
-	/**
17
-	 * @return MissingDependency[]
18
-	 */
19
-	public static function checkDependencies(): array {
20
-		return [
21
-			(new MissingDependency('dependency'))->setMessage('missing dependency'),
22
-			(new MissingDependency('program'))->setMessage('cannot find program'),
23
-		];
24
-	}
16
+    /**
17
+     * @return MissingDependency[]
18
+     */
19
+    public static function checkDependencies(): array {
20
+        return [
21
+            (new MissingDependency('dependency'))->setMessage('missing dependency'),
22
+            (new MissingDependency('program'))->setMessage('cannot find program'),
23
+        ];
24
+    }
25 25
 
26
-	public function testCheckDependencies(): void {
27
-		$trait = $this->getMockForTrait(LegacyDependencyCheckPolyfill::class);
28
-		$trait->expects($this->once())
29
-			->method('getStorageClass')
30
-			->willReturn(self::class);
26
+    public function testCheckDependencies(): void {
27
+        $trait = $this->getMockForTrait(LegacyDependencyCheckPolyfill::class);
28
+        $trait->expects($this->once())
29
+            ->method('getStorageClass')
30
+            ->willReturn(self::class);
31 31
 
32
-		$dependencies = $trait->checkDependencies();
33
-		$this->assertCount(2, $dependencies);
34
-		$this->assertEquals('dependency', $dependencies[0]->getDependency());
35
-		$this->assertEquals('missing dependency', $dependencies[0]->getMessage());
36
-		$this->assertEquals('program', $dependencies[1]->getDependency());
37
-		$this->assertEquals('cannot find program', $dependencies[1]->getMessage());
38
-	}
32
+        $dependencies = $trait->checkDependencies();
33
+        $this->assertCount(2, $dependencies);
34
+        $this->assertEquals('dependency', $dependencies[0]->getDependency());
35
+        $this->assertEquals('missing dependency', $dependencies[0]->getMessage());
36
+        $this->assertEquals('program', $dependencies[1]->getDependency());
37
+        $this->assertEquals('cannot find program', $dependencies[1]->getMessage());
38
+    }
39 39
 }
Please login to merge, or discard this patch.
apps/oauth2/tests/Controller/OauthApiControllerTest.php 1 patch
Indentation   +572 added lines, -572 removed lines patch added patch discarded remove patch
@@ -29,579 +29,579 @@
 block discarded – undo
29 29
 
30 30
 /* We have to use this to add a property to the mocked request and avoid warnings about dynamic properties on PHP>=8.2 */
31 31
 abstract class RequestMock implements IRequest {
32
-	public array $server = [];
32
+    public array $server = [];
33 33
 }
34 34
 
35 35
 class OauthApiControllerTest extends TestCase {
36
-	/** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */
37
-	private $request;
38
-	/** @var ICrypto|\PHPUnit\Framework\MockObject\MockObject */
39
-	private $crypto;
40
-	/** @var AccessTokenMapper|\PHPUnit\Framework\MockObject\MockObject */
41
-	private $accessTokenMapper;
42
-	/** @var ClientMapper|\PHPUnit\Framework\MockObject\MockObject */
43
-	private $clientMapper;
44
-	/** @var TokenProvider|\PHPUnit\Framework\MockObject\MockObject */
45
-	private $tokenProvider;
46
-	/** @var ISecureRandom|\PHPUnit\Framework\MockObject\MockObject */
47
-	private $secureRandom;
48
-	/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
49
-	private $time;
50
-	/** @var IThrottler|\PHPUnit\Framework\MockObject\MockObject */
51
-	private $throttler;
52
-	/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
53
-	private $logger;
54
-	/** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
55
-	private $timeFactory;
56
-	/** @var OauthApiController */
57
-	private $oauthApiController;
58
-
59
-	protected function setUp(): void {
60
-		parent::setUp();
61
-
62
-		$this->request = $this->createMock(RequestMock::class);
63
-		$this->crypto = $this->createMock(ICrypto::class);
64
-		$this->accessTokenMapper = $this->createMock(AccessTokenMapper::class);
65
-		$this->clientMapper = $this->createMock(ClientMapper::class);
66
-		$this->tokenProvider = $this->createMock(TokenProvider::class);
67
-		$this->secureRandom = $this->createMock(ISecureRandom::class);
68
-		$this->time = $this->createMock(ITimeFactory::class);
69
-		$this->throttler = $this->createMock(IThrottler::class);
70
-		$this->logger = $this->createMock(LoggerInterface::class);
71
-		$this->timeFactory = $this->createMock(ITimeFactory::class);
72
-
73
-		$this->oauthApiController = new OauthApiController(
74
-			'oauth2',
75
-			$this->request,
76
-			$this->crypto,
77
-			$this->accessTokenMapper,
78
-			$this->clientMapper,
79
-			$this->tokenProvider,
80
-			$this->secureRandom,
81
-			$this->time,
82
-			$this->logger,
83
-			$this->throttler,
84
-			$this->timeFactory
85
-		);
86
-	}
87
-
88
-	public function testGetTokenInvalidGrantType(): void {
89
-		$expected = new JSONResponse([
90
-			'error' => 'invalid_grant',
91
-		], Http::STATUS_BAD_REQUEST);
92
-		$expected->throttle(['invalid_grant' => 'foo']);
93
-
94
-		$this->assertEquals($expected, $this->oauthApiController->getToken('foo', null, null, null, null));
95
-	}
96
-
97
-	public function testGetTokenInvalidCode(): void {
98
-		$expected = new JSONResponse([
99
-			'error' => 'invalid_request',
100
-		], Http::STATUS_BAD_REQUEST);
101
-		$expected->throttle(['invalid_request' => 'token not found', 'code' => 'invalidcode']);
102
-
103
-		$this->accessTokenMapper->method('getByCode')
104
-			->with('invalidcode')
105
-			->willThrowException(new AccessTokenNotFoundException());
106
-
107
-		$this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'invalidcode', null, null, null));
108
-	}
109
-
110
-	public function testGetTokenExpiredCode(): void {
111
-		$codeCreatedAt = 100;
112
-		$expiredSince = 123;
113
-
114
-		$expected = new JSONResponse([
115
-			'error' => 'invalid_request',
116
-		], Http::STATUS_BAD_REQUEST);
117
-		$expected->throttle(['invalid_request' => 'authorization_code_expired', 'expired_since' => $expiredSince]);
118
-
119
-		$accessToken = new AccessToken();
120
-		$accessToken->setClientId(42);
121
-		$accessToken->setCodeCreatedAt($codeCreatedAt);
122
-
123
-		$this->accessTokenMapper->method('getByCode')
124
-			->with('validcode')
125
-			->willReturn($accessToken);
126
-
127
-		$tsNow = $codeCreatedAt + OauthApiController::AUTHORIZATION_CODE_EXPIRES_AFTER + $expiredSince;
128
-		$dateNow = (new \DateTimeImmutable())->setTimestamp($tsNow);
129
-		$this->timeFactory->method('now')
130
-			->willReturn($dateNow);
131
-
132
-		$this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'validcode', null, null, null));
133
-	}
134
-
135
-	public function testGetTokenWithCodeForActiveToken(): void {
136
-		// if a token has already delivered oauth tokens,
137
-		// it should not be possible to get a new oauth token from a valid authorization code
138
-		$codeCreatedAt = 100;
139
-
140
-		$expected = new JSONResponse([
141
-			'error' => 'invalid_request',
142
-		], Http::STATUS_BAD_REQUEST);
143
-		$expected->throttle(['invalid_request' => 'authorization_code_received_for_active_token']);
144
-
145
-		$accessToken = new AccessToken();
146
-		$accessToken->setClientId(42);
147
-		$accessToken->setCodeCreatedAt($codeCreatedAt);
148
-		$accessToken->setTokenCount(1);
149
-
150
-		$this->accessTokenMapper->method('getByCode')
151
-			->with('validcode')
152
-			->willReturn($accessToken);
153
-
154
-		$tsNow = $codeCreatedAt + 1;
155
-		$dateNow = (new \DateTimeImmutable())->setTimestamp($tsNow);
156
-		$this->timeFactory->method('now')
157
-			->willReturn($dateNow);
158
-
159
-		$this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'validcode', null, null, null));
160
-	}
161
-
162
-	public function testGetTokenClientDoesNotExist(): void {
163
-		// In this test, the token's authorization code is valid and has not expired
164
-		// and we check what happens when the associated Oauth client does not exist
165
-		$codeCreatedAt = 100;
166
-
167
-		$expected = new JSONResponse([
168
-			'error' => 'invalid_request',
169
-		], Http::STATUS_BAD_REQUEST);
170
-		$expected->throttle(['invalid_request' => 'client not found', 'client_id' => 42]);
171
-
172
-		$accessToken = new AccessToken();
173
-		$accessToken->setClientId(42);
174
-		$accessToken->setCodeCreatedAt($codeCreatedAt);
175
-
176
-		$this->accessTokenMapper->method('getByCode')
177
-			->with('validcode')
178
-			->willReturn($accessToken);
179
-
180
-		// 'now' is before the token's authorization code expiration
181
-		$tsNow = $codeCreatedAt + OauthApiController::AUTHORIZATION_CODE_EXPIRES_AFTER - 1;
182
-		$dateNow = (new \DateTimeImmutable())->setTimestamp($tsNow);
183
-		$this->timeFactory->method('now')
184
-			->willReturn($dateNow);
185
-
186
-		$this->clientMapper->method('getByUid')
187
-			->with(42)
188
-			->willThrowException(new ClientNotFoundException());
189
-
190
-		$this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'validcode', null, null, null));
191
-	}
192
-
193
-	public function testRefreshTokenInvalidRefreshToken(): void {
194
-		$expected = new JSONResponse([
195
-			'error' => 'invalid_request',
196
-		], Http::STATUS_BAD_REQUEST);
197
-		$expected->throttle(['invalid_request' => 'token not found', 'code' => 'invalidrefresh']);
198
-
199
-		$this->accessTokenMapper->method('getByCode')
200
-			->with('invalidrefresh')
201
-			->willThrowException(new AccessTokenNotFoundException());
202
-
203
-		$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'invalidrefresh', null, null));
204
-	}
205
-
206
-	public function testRefreshTokenClientDoesNotExist(): void {
207
-		$expected = new JSONResponse([
208
-			'error' => 'invalid_request',
209
-		], Http::STATUS_BAD_REQUEST);
210
-		$expected->throttle(['invalid_request' => 'client not found', 'client_id' => 42]);
211
-
212
-		$accessToken = new AccessToken();
213
-		$accessToken->setClientId(42);
214
-
215
-		$this->accessTokenMapper->method('getByCode')
216
-			->with('validrefresh')
217
-			->willReturn($accessToken);
218
-
219
-		$this->clientMapper->method('getByUid')
220
-			->with(42)
221
-			->willThrowException(new ClientNotFoundException());
222
-
223
-		$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', null, null));
224
-	}
225
-
226
-	public static function invalidClientProvider() {
227
-		return [
228
-			['invalidClientId', 'invalidClientSecret'],
229
-			['clientId', 'invalidClientSecret'],
230
-			['invalidClientId', 'clientSecret'],
231
-		];
232
-	}
233
-
234
-	/**
235
-	 *
236
-	 * @param string $clientId
237
-	 * @param string $clientSecret
238
-	 */
239
-	#[\PHPUnit\Framework\Attributes\DataProvider('invalidClientProvider')]
240
-	public function testRefreshTokenInvalidClient($clientId, $clientSecret): void {
241
-		$expected = new JSONResponse([
242
-			'error' => 'invalid_client',
243
-		], Http::STATUS_BAD_REQUEST);
244
-		$expected->throttle(['invalid_client' => 'client ID or secret does not match']);
245
-
246
-		$accessToken = new AccessToken();
247
-		$accessToken->setClientId(42);
248
-
249
-		$this->accessTokenMapper->method('getByCode')
250
-			->with('validrefresh')
251
-			->willReturn($accessToken);
252
-
253
-		$this->crypto
254
-			->method('calculateHMAC')
255
-			->with($this->callback(function (string $text) {
256
-				return $text === 'clientSecret' || $text === 'invalidClientSecret';
257
-			}))
258
-			->willReturnCallback(function (string $text) {
259
-				return $text === 'clientSecret'
260
-					? 'hashedClientSecret'
261
-					: 'hashedInvalidClientSecret';
262
-			});
263
-
264
-		$client = new Client();
265
-		$client->setClientIdentifier('clientId');
266
-		$client->setSecret(bin2hex('hashedClientSecret'));
267
-		$this->clientMapper->method('getByUid')
268
-			->with(42)
269
-			->willReturn($client);
270
-
271
-		$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', $clientId, $clientSecret));
272
-	}
273
-
274
-	public function testRefreshTokenInvalidAppToken(): void {
275
-		$expected = new JSONResponse([
276
-			'error' => 'invalid_request',
277
-		], Http::STATUS_BAD_REQUEST);
278
-		$expected->throttle(['invalid_request' => 'token is invalid']);
279
-
280
-		$accessToken = new AccessToken();
281
-		$accessToken->setClientId(42);
282
-		$accessToken->setTokenId(1337);
283
-		$accessToken->setEncryptedToken('encryptedToken');
284
-
285
-		$this->accessTokenMapper->method('getByCode')
286
-			->with('validrefresh')
287
-			->willReturn($accessToken);
288
-
289
-		$client = new Client();
290
-		$client->setClientIdentifier('clientId');
291
-		$client->setSecret(bin2hex('hashedClientSecret'));
292
-		$this->clientMapper->method('getByUid')
293
-			->with(42)
294
-			->willReturn($client);
295
-
296
-		$this->crypto
297
-			->method('decrypt')
298
-			->with('encryptedToken')
299
-			->willReturn('decryptedToken');
300
-
301
-		$this->crypto
302
-			->method('calculateHMAC')
303
-			->with('clientSecret')
304
-			->willReturn('hashedClientSecret');
305
-
306
-		$this->tokenProvider->method('getTokenById')
307
-			->with(1337)
308
-			->willThrowException(new InvalidTokenException());
309
-
310
-		$this->accessTokenMapper->expects($this->once())
311
-			->method('delete')
312
-			->with($accessToken);
313
-
314
-		$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
315
-	}
316
-
317
-	public function testRefreshTokenValidAppToken(): void {
318
-		$accessToken = new AccessToken();
319
-		$accessToken->setClientId(42);
320
-		$accessToken->setTokenId(1337);
321
-		$accessToken->setEncryptedToken('encryptedToken');
322
-
323
-		$this->accessTokenMapper->method('getByCode')
324
-			->with('validrefresh')
325
-			->willReturn($accessToken);
326
-
327
-		$client = new Client();
328
-		$client->setClientIdentifier('clientId');
329
-		$client->setSecret(bin2hex('hashedClientSecret'));
330
-		$this->clientMapper->method('getByUid')
331
-			->with(42)
332
-			->willReturn($client);
333
-
334
-		$this->crypto
335
-			->method('decrypt')
336
-			->with('encryptedToken')
337
-			->willReturn('decryptedToken');
338
-
339
-		$this->crypto
340
-			->method('calculateHMAC')
341
-			->with('clientSecret')
342
-			->willReturn('hashedClientSecret');
343
-
344
-		$appToken = new PublicKeyToken();
345
-		$appToken->setUid('userId');
346
-		$this->tokenProvider->method('getTokenById')
347
-			->with(1337)
348
-			->willThrowException(new ExpiredTokenException($appToken));
349
-
350
-		$this->accessTokenMapper->expects($this->never())
351
-			->method('delete')
352
-			->with($accessToken);
353
-
354
-		$this->secureRandom->method('generate')
355
-			->willReturnCallback(function ($len) {
356
-				return 'random' . $len;
357
-			});
358
-
359
-		$this->tokenProvider->expects($this->once())
360
-			->method('rotate')
361
-			->with(
362
-				$appToken,
363
-				'decryptedToken',
364
-				'random72'
365
-			)->willReturn($appToken);
366
-
367
-		$this->time->method('getTime')
368
-			->willReturn(1000);
369
-
370
-		$this->tokenProvider->expects($this->once())
371
-			->method('updateToken')
372
-			->with(
373
-				$this->callback(function (PublicKeyToken $token) {
374
-					return $token->getExpires() === 4600;
375
-				})
376
-			);
377
-
378
-		$this->crypto->method('encrypt')
379
-			->with('random72', 'random128')
380
-			->willReturn('newEncryptedToken');
381
-
382
-		$this->accessTokenMapper->expects($this->once())
383
-			->method('update')
384
-			->with(
385
-				$this->callback(function (AccessToken $token) {
386
-					return $token->getHashedCode() === hash('sha512', 'random128')
387
-						&& $token->getEncryptedToken() === 'newEncryptedToken';
388
-				})
389
-			);
390
-
391
-		$expected = new JSONResponse([
392
-			'access_token' => 'random72',
393
-			'token_type' => 'Bearer',
394
-			'expires_in' => 3600,
395
-			'refresh_token' => 'random128',
396
-			'user_id' => 'userId',
397
-		]);
398
-
399
-		$this->request->method('getRemoteAddress')
400
-			->willReturn('1.2.3.4');
401
-
402
-		$this->throttler->expects($this->once())
403
-			->method('resetDelay')
404
-			->with(
405
-				'1.2.3.4',
406
-				'login',
407
-				['user' => 'userId']
408
-			);
409
-
410
-		$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
411
-	}
412
-
413
-	public function testRefreshTokenValidAppTokenBasicAuth(): void {
414
-		$accessToken = new AccessToken();
415
-		$accessToken->setClientId(42);
416
-		$accessToken->setTokenId(1337);
417
-		$accessToken->setEncryptedToken('encryptedToken');
418
-
419
-		$this->accessTokenMapper->method('getByCode')
420
-			->with('validrefresh')
421
-			->willReturn($accessToken);
422
-
423
-		$client = new Client();
424
-		$client->setClientIdentifier('clientId');
425
-		$client->setSecret(bin2hex('hashedClientSecret'));
426
-		$this->clientMapper->method('getByUid')
427
-			->with(42)
428
-			->willReturn($client);
429
-
430
-		$this->crypto
431
-			->method('decrypt')
432
-			->with('encryptedToken')
433
-			->willReturn('decryptedToken');
434
-
435
-		$this->crypto
436
-			->method('calculateHMAC')
437
-			->with('clientSecret')
438
-			->willReturn('hashedClientSecret');
439
-
440
-		$appToken = new PublicKeyToken();
441
-		$appToken->setUid('userId');
442
-		$this->tokenProvider->method('getTokenById')
443
-			->with(1337)
444
-			->willThrowException(new ExpiredTokenException($appToken));
445
-
446
-		$this->accessTokenMapper->expects($this->never())
447
-			->method('delete')
448
-			->with($accessToken);
449
-
450
-		$this->secureRandom->method('generate')
451
-			->willReturnCallback(function ($len) {
452
-				return 'random' . $len;
453
-			});
454
-
455
-		$this->tokenProvider->expects($this->once())
456
-			->method('rotate')
457
-			->with(
458
-				$appToken,
459
-				'decryptedToken',
460
-				'random72'
461
-			)->willReturn($appToken);
462
-
463
-		$this->time->method('getTime')
464
-			->willReturn(1000);
465
-
466
-		$this->tokenProvider->expects($this->once())
467
-			->method('updateToken')
468
-			->with(
469
-				$this->callback(function (PublicKeyToken $token) {
470
-					return $token->getExpires() === 4600;
471
-				})
472
-			);
473
-
474
-		$this->crypto->method('encrypt')
475
-			->with('random72', 'random128')
476
-			->willReturn('newEncryptedToken');
477
-
478
-		$this->accessTokenMapper->expects($this->once())
479
-			->method('update')
480
-			->with(
481
-				$this->callback(function (AccessToken $token) {
482
-					return $token->getHashedCode() === hash('sha512', 'random128')
483
-						&& $token->getEncryptedToken() === 'newEncryptedToken';
484
-				})
485
-			);
486
-
487
-		$expected = new JSONResponse([
488
-			'access_token' => 'random72',
489
-			'token_type' => 'Bearer',
490
-			'expires_in' => 3600,
491
-			'refresh_token' => 'random128',
492
-			'user_id' => 'userId',
493
-		]);
494
-
495
-		$this->request->server['PHP_AUTH_USER'] = 'clientId';
496
-		$this->request->server['PHP_AUTH_PW'] = 'clientSecret';
497
-
498
-		$this->request->method('getRemoteAddress')
499
-			->willReturn('1.2.3.4');
500
-
501
-		$this->throttler->expects($this->once())
502
-			->method('resetDelay')
503
-			->with(
504
-				'1.2.3.4',
505
-				'login',
506
-				['user' => 'userId']
507
-			);
508
-
509
-		$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', null, null));
510
-	}
511
-
512
-	public function testRefreshTokenExpiredAppToken(): void {
513
-		$accessToken = new AccessToken();
514
-		$accessToken->setClientId(42);
515
-		$accessToken->setTokenId(1337);
516
-		$accessToken->setEncryptedToken('encryptedToken');
517
-
518
-		$this->accessTokenMapper->method('getByCode')
519
-			->with('validrefresh')
520
-			->willReturn($accessToken);
521
-
522
-		$client = new Client();
523
-		$client->setClientIdentifier('clientId');
524
-		$client->setSecret(bin2hex('hashedClientSecret'));
525
-		$this->clientMapper->method('getByUid')
526
-			->with(42)
527
-			->willReturn($client);
528
-
529
-		$this->crypto
530
-			->method('decrypt')
531
-			->with('encryptedToken')
532
-			->willReturn('decryptedToken');
533
-
534
-		$this->crypto
535
-			->method('calculateHMAC')
536
-			->with('clientSecret')
537
-			->willReturn('hashedClientSecret');
538
-
539
-		$appToken = new PublicKeyToken();
540
-		$appToken->setUid('userId');
541
-		$this->tokenProvider->method('getTokenById')
542
-			->with(1337)
543
-			->willReturn($appToken);
544
-
545
-		$this->accessTokenMapper->expects($this->never())
546
-			->method('delete')
547
-			->with($accessToken);
548
-
549
-		$this->secureRandom->method('generate')
550
-			->willReturnCallback(function ($len) {
551
-				return 'random' . $len;
552
-			});
553
-
554
-		$this->tokenProvider->expects($this->once())
555
-			->method('rotate')
556
-			->with(
557
-				$appToken,
558
-				'decryptedToken',
559
-				'random72'
560
-			)->willReturn($appToken);
561
-
562
-		$this->time->method('getTime')
563
-			->willReturn(1000);
564
-
565
-		$this->tokenProvider->expects($this->once())
566
-			->method('updateToken')
567
-			->with(
568
-				$this->callback(function (PublicKeyToken $token) {
569
-					return $token->getExpires() === 4600;
570
-				})
571
-			);
572
-
573
-		$this->crypto->method('encrypt')
574
-			->with('random72', 'random128')
575
-			->willReturn('newEncryptedToken');
576
-
577
-		$this->accessTokenMapper->expects($this->once())
578
-			->method('update')
579
-			->with(
580
-				$this->callback(function (AccessToken $token) {
581
-					return $token->getHashedCode() === hash('sha512', 'random128')
582
-						&& $token->getEncryptedToken() === 'newEncryptedToken';
583
-				})
584
-			);
585
-
586
-		$expected = new JSONResponse([
587
-			'access_token' => 'random72',
588
-			'token_type' => 'Bearer',
589
-			'expires_in' => 3600,
590
-			'refresh_token' => 'random128',
591
-			'user_id' => 'userId',
592
-		]);
593
-
594
-		$this->request->method('getRemoteAddress')
595
-			->willReturn('1.2.3.4');
596
-
597
-		$this->throttler->expects($this->once())
598
-			->method('resetDelay')
599
-			->with(
600
-				'1.2.3.4',
601
-				'login',
602
-				['user' => 'userId']
603
-			);
604
-
605
-		$this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
606
-	}
36
+    /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */
37
+    private $request;
38
+    /** @var ICrypto|\PHPUnit\Framework\MockObject\MockObject */
39
+    private $crypto;
40
+    /** @var AccessTokenMapper|\PHPUnit\Framework\MockObject\MockObject */
41
+    private $accessTokenMapper;
42
+    /** @var ClientMapper|\PHPUnit\Framework\MockObject\MockObject */
43
+    private $clientMapper;
44
+    /** @var TokenProvider|\PHPUnit\Framework\MockObject\MockObject */
45
+    private $tokenProvider;
46
+    /** @var ISecureRandom|\PHPUnit\Framework\MockObject\MockObject */
47
+    private $secureRandom;
48
+    /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
49
+    private $time;
50
+    /** @var IThrottler|\PHPUnit\Framework\MockObject\MockObject */
51
+    private $throttler;
52
+    /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
53
+    private $logger;
54
+    /** @var ITimeFactory|\PHPUnit\Framework\MockObject\MockObject */
55
+    private $timeFactory;
56
+    /** @var OauthApiController */
57
+    private $oauthApiController;
58
+
59
+    protected function setUp(): void {
60
+        parent::setUp();
61
+
62
+        $this->request = $this->createMock(RequestMock::class);
63
+        $this->crypto = $this->createMock(ICrypto::class);
64
+        $this->accessTokenMapper = $this->createMock(AccessTokenMapper::class);
65
+        $this->clientMapper = $this->createMock(ClientMapper::class);
66
+        $this->tokenProvider = $this->createMock(TokenProvider::class);
67
+        $this->secureRandom = $this->createMock(ISecureRandom::class);
68
+        $this->time = $this->createMock(ITimeFactory::class);
69
+        $this->throttler = $this->createMock(IThrottler::class);
70
+        $this->logger = $this->createMock(LoggerInterface::class);
71
+        $this->timeFactory = $this->createMock(ITimeFactory::class);
72
+
73
+        $this->oauthApiController = new OauthApiController(
74
+            'oauth2',
75
+            $this->request,
76
+            $this->crypto,
77
+            $this->accessTokenMapper,
78
+            $this->clientMapper,
79
+            $this->tokenProvider,
80
+            $this->secureRandom,
81
+            $this->time,
82
+            $this->logger,
83
+            $this->throttler,
84
+            $this->timeFactory
85
+        );
86
+    }
87
+
88
+    public function testGetTokenInvalidGrantType(): void {
89
+        $expected = new JSONResponse([
90
+            'error' => 'invalid_grant',
91
+        ], Http::STATUS_BAD_REQUEST);
92
+        $expected->throttle(['invalid_grant' => 'foo']);
93
+
94
+        $this->assertEquals($expected, $this->oauthApiController->getToken('foo', null, null, null, null));
95
+    }
96
+
97
+    public function testGetTokenInvalidCode(): void {
98
+        $expected = new JSONResponse([
99
+            'error' => 'invalid_request',
100
+        ], Http::STATUS_BAD_REQUEST);
101
+        $expected->throttle(['invalid_request' => 'token not found', 'code' => 'invalidcode']);
102
+
103
+        $this->accessTokenMapper->method('getByCode')
104
+            ->with('invalidcode')
105
+            ->willThrowException(new AccessTokenNotFoundException());
106
+
107
+        $this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'invalidcode', null, null, null));
108
+    }
109
+
110
+    public function testGetTokenExpiredCode(): void {
111
+        $codeCreatedAt = 100;
112
+        $expiredSince = 123;
113
+
114
+        $expected = new JSONResponse([
115
+            'error' => 'invalid_request',
116
+        ], Http::STATUS_BAD_REQUEST);
117
+        $expected->throttle(['invalid_request' => 'authorization_code_expired', 'expired_since' => $expiredSince]);
118
+
119
+        $accessToken = new AccessToken();
120
+        $accessToken->setClientId(42);
121
+        $accessToken->setCodeCreatedAt($codeCreatedAt);
122
+
123
+        $this->accessTokenMapper->method('getByCode')
124
+            ->with('validcode')
125
+            ->willReturn($accessToken);
126
+
127
+        $tsNow = $codeCreatedAt + OauthApiController::AUTHORIZATION_CODE_EXPIRES_AFTER + $expiredSince;
128
+        $dateNow = (new \DateTimeImmutable())->setTimestamp($tsNow);
129
+        $this->timeFactory->method('now')
130
+            ->willReturn($dateNow);
131
+
132
+        $this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'validcode', null, null, null));
133
+    }
134
+
135
+    public function testGetTokenWithCodeForActiveToken(): void {
136
+        // if a token has already delivered oauth tokens,
137
+        // it should not be possible to get a new oauth token from a valid authorization code
138
+        $codeCreatedAt = 100;
139
+
140
+        $expected = new JSONResponse([
141
+            'error' => 'invalid_request',
142
+        ], Http::STATUS_BAD_REQUEST);
143
+        $expected->throttle(['invalid_request' => 'authorization_code_received_for_active_token']);
144
+
145
+        $accessToken = new AccessToken();
146
+        $accessToken->setClientId(42);
147
+        $accessToken->setCodeCreatedAt($codeCreatedAt);
148
+        $accessToken->setTokenCount(1);
149
+
150
+        $this->accessTokenMapper->method('getByCode')
151
+            ->with('validcode')
152
+            ->willReturn($accessToken);
153
+
154
+        $tsNow = $codeCreatedAt + 1;
155
+        $dateNow = (new \DateTimeImmutable())->setTimestamp($tsNow);
156
+        $this->timeFactory->method('now')
157
+            ->willReturn($dateNow);
158
+
159
+        $this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'validcode', null, null, null));
160
+    }
161
+
162
+    public function testGetTokenClientDoesNotExist(): void {
163
+        // In this test, the token's authorization code is valid and has not expired
164
+        // and we check what happens when the associated Oauth client does not exist
165
+        $codeCreatedAt = 100;
166
+
167
+        $expected = new JSONResponse([
168
+            'error' => 'invalid_request',
169
+        ], Http::STATUS_BAD_REQUEST);
170
+        $expected->throttle(['invalid_request' => 'client not found', 'client_id' => 42]);
171
+
172
+        $accessToken = new AccessToken();
173
+        $accessToken->setClientId(42);
174
+        $accessToken->setCodeCreatedAt($codeCreatedAt);
175
+
176
+        $this->accessTokenMapper->method('getByCode')
177
+            ->with('validcode')
178
+            ->willReturn($accessToken);
179
+
180
+        // 'now' is before the token's authorization code expiration
181
+        $tsNow = $codeCreatedAt + OauthApiController::AUTHORIZATION_CODE_EXPIRES_AFTER - 1;
182
+        $dateNow = (new \DateTimeImmutable())->setTimestamp($tsNow);
183
+        $this->timeFactory->method('now')
184
+            ->willReturn($dateNow);
185
+
186
+        $this->clientMapper->method('getByUid')
187
+            ->with(42)
188
+            ->willThrowException(new ClientNotFoundException());
189
+
190
+        $this->assertEquals($expected, $this->oauthApiController->getToken('authorization_code', 'validcode', null, null, null));
191
+    }
192
+
193
+    public function testRefreshTokenInvalidRefreshToken(): void {
194
+        $expected = new JSONResponse([
195
+            'error' => 'invalid_request',
196
+        ], Http::STATUS_BAD_REQUEST);
197
+        $expected->throttle(['invalid_request' => 'token not found', 'code' => 'invalidrefresh']);
198
+
199
+        $this->accessTokenMapper->method('getByCode')
200
+            ->with('invalidrefresh')
201
+            ->willThrowException(new AccessTokenNotFoundException());
202
+
203
+        $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'invalidrefresh', null, null));
204
+    }
205
+
206
+    public function testRefreshTokenClientDoesNotExist(): void {
207
+        $expected = new JSONResponse([
208
+            'error' => 'invalid_request',
209
+        ], Http::STATUS_BAD_REQUEST);
210
+        $expected->throttle(['invalid_request' => 'client not found', 'client_id' => 42]);
211
+
212
+        $accessToken = new AccessToken();
213
+        $accessToken->setClientId(42);
214
+
215
+        $this->accessTokenMapper->method('getByCode')
216
+            ->with('validrefresh')
217
+            ->willReturn($accessToken);
218
+
219
+        $this->clientMapper->method('getByUid')
220
+            ->with(42)
221
+            ->willThrowException(new ClientNotFoundException());
222
+
223
+        $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', null, null));
224
+    }
225
+
226
+    public static function invalidClientProvider() {
227
+        return [
228
+            ['invalidClientId', 'invalidClientSecret'],
229
+            ['clientId', 'invalidClientSecret'],
230
+            ['invalidClientId', 'clientSecret'],
231
+        ];
232
+    }
233
+
234
+    /**
235
+     *
236
+     * @param string $clientId
237
+     * @param string $clientSecret
238
+     */
239
+    #[\PHPUnit\Framework\Attributes\DataProvider('invalidClientProvider')]
240
+    public function testRefreshTokenInvalidClient($clientId, $clientSecret): void {
241
+        $expected = new JSONResponse([
242
+            'error' => 'invalid_client',
243
+        ], Http::STATUS_BAD_REQUEST);
244
+        $expected->throttle(['invalid_client' => 'client ID or secret does not match']);
245
+
246
+        $accessToken = new AccessToken();
247
+        $accessToken->setClientId(42);
248
+
249
+        $this->accessTokenMapper->method('getByCode')
250
+            ->with('validrefresh')
251
+            ->willReturn($accessToken);
252
+
253
+        $this->crypto
254
+            ->method('calculateHMAC')
255
+            ->with($this->callback(function (string $text) {
256
+                return $text === 'clientSecret' || $text === 'invalidClientSecret';
257
+            }))
258
+            ->willReturnCallback(function (string $text) {
259
+                return $text === 'clientSecret'
260
+                    ? 'hashedClientSecret'
261
+                    : 'hashedInvalidClientSecret';
262
+            });
263
+
264
+        $client = new Client();
265
+        $client->setClientIdentifier('clientId');
266
+        $client->setSecret(bin2hex('hashedClientSecret'));
267
+        $this->clientMapper->method('getByUid')
268
+            ->with(42)
269
+            ->willReturn($client);
270
+
271
+        $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', $clientId, $clientSecret));
272
+    }
273
+
274
+    public function testRefreshTokenInvalidAppToken(): void {
275
+        $expected = new JSONResponse([
276
+            'error' => 'invalid_request',
277
+        ], Http::STATUS_BAD_REQUEST);
278
+        $expected->throttle(['invalid_request' => 'token is invalid']);
279
+
280
+        $accessToken = new AccessToken();
281
+        $accessToken->setClientId(42);
282
+        $accessToken->setTokenId(1337);
283
+        $accessToken->setEncryptedToken('encryptedToken');
284
+
285
+        $this->accessTokenMapper->method('getByCode')
286
+            ->with('validrefresh')
287
+            ->willReturn($accessToken);
288
+
289
+        $client = new Client();
290
+        $client->setClientIdentifier('clientId');
291
+        $client->setSecret(bin2hex('hashedClientSecret'));
292
+        $this->clientMapper->method('getByUid')
293
+            ->with(42)
294
+            ->willReturn($client);
295
+
296
+        $this->crypto
297
+            ->method('decrypt')
298
+            ->with('encryptedToken')
299
+            ->willReturn('decryptedToken');
300
+
301
+        $this->crypto
302
+            ->method('calculateHMAC')
303
+            ->with('clientSecret')
304
+            ->willReturn('hashedClientSecret');
305
+
306
+        $this->tokenProvider->method('getTokenById')
307
+            ->with(1337)
308
+            ->willThrowException(new InvalidTokenException());
309
+
310
+        $this->accessTokenMapper->expects($this->once())
311
+            ->method('delete')
312
+            ->with($accessToken);
313
+
314
+        $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
315
+    }
316
+
317
+    public function testRefreshTokenValidAppToken(): void {
318
+        $accessToken = new AccessToken();
319
+        $accessToken->setClientId(42);
320
+        $accessToken->setTokenId(1337);
321
+        $accessToken->setEncryptedToken('encryptedToken');
322
+
323
+        $this->accessTokenMapper->method('getByCode')
324
+            ->with('validrefresh')
325
+            ->willReturn($accessToken);
326
+
327
+        $client = new Client();
328
+        $client->setClientIdentifier('clientId');
329
+        $client->setSecret(bin2hex('hashedClientSecret'));
330
+        $this->clientMapper->method('getByUid')
331
+            ->with(42)
332
+            ->willReturn($client);
333
+
334
+        $this->crypto
335
+            ->method('decrypt')
336
+            ->with('encryptedToken')
337
+            ->willReturn('decryptedToken');
338
+
339
+        $this->crypto
340
+            ->method('calculateHMAC')
341
+            ->with('clientSecret')
342
+            ->willReturn('hashedClientSecret');
343
+
344
+        $appToken = new PublicKeyToken();
345
+        $appToken->setUid('userId');
346
+        $this->tokenProvider->method('getTokenById')
347
+            ->with(1337)
348
+            ->willThrowException(new ExpiredTokenException($appToken));
349
+
350
+        $this->accessTokenMapper->expects($this->never())
351
+            ->method('delete')
352
+            ->with($accessToken);
353
+
354
+        $this->secureRandom->method('generate')
355
+            ->willReturnCallback(function ($len) {
356
+                return 'random' . $len;
357
+            });
358
+
359
+        $this->tokenProvider->expects($this->once())
360
+            ->method('rotate')
361
+            ->with(
362
+                $appToken,
363
+                'decryptedToken',
364
+                'random72'
365
+            )->willReturn($appToken);
366
+
367
+        $this->time->method('getTime')
368
+            ->willReturn(1000);
369
+
370
+        $this->tokenProvider->expects($this->once())
371
+            ->method('updateToken')
372
+            ->with(
373
+                $this->callback(function (PublicKeyToken $token) {
374
+                    return $token->getExpires() === 4600;
375
+                })
376
+            );
377
+
378
+        $this->crypto->method('encrypt')
379
+            ->with('random72', 'random128')
380
+            ->willReturn('newEncryptedToken');
381
+
382
+        $this->accessTokenMapper->expects($this->once())
383
+            ->method('update')
384
+            ->with(
385
+                $this->callback(function (AccessToken $token) {
386
+                    return $token->getHashedCode() === hash('sha512', 'random128')
387
+                        && $token->getEncryptedToken() === 'newEncryptedToken';
388
+                })
389
+            );
390
+
391
+        $expected = new JSONResponse([
392
+            'access_token' => 'random72',
393
+            'token_type' => 'Bearer',
394
+            'expires_in' => 3600,
395
+            'refresh_token' => 'random128',
396
+            'user_id' => 'userId',
397
+        ]);
398
+
399
+        $this->request->method('getRemoteAddress')
400
+            ->willReturn('1.2.3.4');
401
+
402
+        $this->throttler->expects($this->once())
403
+            ->method('resetDelay')
404
+            ->with(
405
+                '1.2.3.4',
406
+                'login',
407
+                ['user' => 'userId']
408
+            );
409
+
410
+        $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
411
+    }
412
+
413
+    public function testRefreshTokenValidAppTokenBasicAuth(): void {
414
+        $accessToken = new AccessToken();
415
+        $accessToken->setClientId(42);
416
+        $accessToken->setTokenId(1337);
417
+        $accessToken->setEncryptedToken('encryptedToken');
418
+
419
+        $this->accessTokenMapper->method('getByCode')
420
+            ->with('validrefresh')
421
+            ->willReturn($accessToken);
422
+
423
+        $client = new Client();
424
+        $client->setClientIdentifier('clientId');
425
+        $client->setSecret(bin2hex('hashedClientSecret'));
426
+        $this->clientMapper->method('getByUid')
427
+            ->with(42)
428
+            ->willReturn($client);
429
+
430
+        $this->crypto
431
+            ->method('decrypt')
432
+            ->with('encryptedToken')
433
+            ->willReturn('decryptedToken');
434
+
435
+        $this->crypto
436
+            ->method('calculateHMAC')
437
+            ->with('clientSecret')
438
+            ->willReturn('hashedClientSecret');
439
+
440
+        $appToken = new PublicKeyToken();
441
+        $appToken->setUid('userId');
442
+        $this->tokenProvider->method('getTokenById')
443
+            ->with(1337)
444
+            ->willThrowException(new ExpiredTokenException($appToken));
445
+
446
+        $this->accessTokenMapper->expects($this->never())
447
+            ->method('delete')
448
+            ->with($accessToken);
449
+
450
+        $this->secureRandom->method('generate')
451
+            ->willReturnCallback(function ($len) {
452
+                return 'random' . $len;
453
+            });
454
+
455
+        $this->tokenProvider->expects($this->once())
456
+            ->method('rotate')
457
+            ->with(
458
+                $appToken,
459
+                'decryptedToken',
460
+                'random72'
461
+            )->willReturn($appToken);
462
+
463
+        $this->time->method('getTime')
464
+            ->willReturn(1000);
465
+
466
+        $this->tokenProvider->expects($this->once())
467
+            ->method('updateToken')
468
+            ->with(
469
+                $this->callback(function (PublicKeyToken $token) {
470
+                    return $token->getExpires() === 4600;
471
+                })
472
+            );
473
+
474
+        $this->crypto->method('encrypt')
475
+            ->with('random72', 'random128')
476
+            ->willReturn('newEncryptedToken');
477
+
478
+        $this->accessTokenMapper->expects($this->once())
479
+            ->method('update')
480
+            ->with(
481
+                $this->callback(function (AccessToken $token) {
482
+                    return $token->getHashedCode() === hash('sha512', 'random128')
483
+                        && $token->getEncryptedToken() === 'newEncryptedToken';
484
+                })
485
+            );
486
+
487
+        $expected = new JSONResponse([
488
+            'access_token' => 'random72',
489
+            'token_type' => 'Bearer',
490
+            'expires_in' => 3600,
491
+            'refresh_token' => 'random128',
492
+            'user_id' => 'userId',
493
+        ]);
494
+
495
+        $this->request->server['PHP_AUTH_USER'] = 'clientId';
496
+        $this->request->server['PHP_AUTH_PW'] = 'clientSecret';
497
+
498
+        $this->request->method('getRemoteAddress')
499
+            ->willReturn('1.2.3.4');
500
+
501
+        $this->throttler->expects($this->once())
502
+            ->method('resetDelay')
503
+            ->with(
504
+                '1.2.3.4',
505
+                'login',
506
+                ['user' => 'userId']
507
+            );
508
+
509
+        $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', null, null));
510
+    }
511
+
512
+    public function testRefreshTokenExpiredAppToken(): void {
513
+        $accessToken = new AccessToken();
514
+        $accessToken->setClientId(42);
515
+        $accessToken->setTokenId(1337);
516
+        $accessToken->setEncryptedToken('encryptedToken');
517
+
518
+        $this->accessTokenMapper->method('getByCode')
519
+            ->with('validrefresh')
520
+            ->willReturn($accessToken);
521
+
522
+        $client = new Client();
523
+        $client->setClientIdentifier('clientId');
524
+        $client->setSecret(bin2hex('hashedClientSecret'));
525
+        $this->clientMapper->method('getByUid')
526
+            ->with(42)
527
+            ->willReturn($client);
528
+
529
+        $this->crypto
530
+            ->method('decrypt')
531
+            ->with('encryptedToken')
532
+            ->willReturn('decryptedToken');
533
+
534
+        $this->crypto
535
+            ->method('calculateHMAC')
536
+            ->with('clientSecret')
537
+            ->willReturn('hashedClientSecret');
538
+
539
+        $appToken = new PublicKeyToken();
540
+        $appToken->setUid('userId');
541
+        $this->tokenProvider->method('getTokenById')
542
+            ->with(1337)
543
+            ->willReturn($appToken);
544
+
545
+        $this->accessTokenMapper->expects($this->never())
546
+            ->method('delete')
547
+            ->with($accessToken);
548
+
549
+        $this->secureRandom->method('generate')
550
+            ->willReturnCallback(function ($len) {
551
+                return 'random' . $len;
552
+            });
553
+
554
+        $this->tokenProvider->expects($this->once())
555
+            ->method('rotate')
556
+            ->with(
557
+                $appToken,
558
+                'decryptedToken',
559
+                'random72'
560
+            )->willReturn($appToken);
561
+
562
+        $this->time->method('getTime')
563
+            ->willReturn(1000);
564
+
565
+        $this->tokenProvider->expects($this->once())
566
+            ->method('updateToken')
567
+            ->with(
568
+                $this->callback(function (PublicKeyToken $token) {
569
+                    return $token->getExpires() === 4600;
570
+                })
571
+            );
572
+
573
+        $this->crypto->method('encrypt')
574
+            ->with('random72', 'random128')
575
+            ->willReturn('newEncryptedToken');
576
+
577
+        $this->accessTokenMapper->expects($this->once())
578
+            ->method('update')
579
+            ->with(
580
+                $this->callback(function (AccessToken $token) {
581
+                    return $token->getHashedCode() === hash('sha512', 'random128')
582
+                        && $token->getEncryptedToken() === 'newEncryptedToken';
583
+                })
584
+            );
585
+
586
+        $expected = new JSONResponse([
587
+            'access_token' => 'random72',
588
+            'token_type' => 'Bearer',
589
+            'expires_in' => 3600,
590
+            'refresh_token' => 'random128',
591
+            'user_id' => 'userId',
592
+        ]);
593
+
594
+        $this->request->method('getRemoteAddress')
595
+            ->willReturn('1.2.3.4');
596
+
597
+        $this->throttler->expects($this->once())
598
+            ->method('resetDelay')
599
+            ->with(
600
+                '1.2.3.4',
601
+                'login',
602
+                ['user' => 'userId']
603
+            );
604
+
605
+        $this->assertEquals($expected, $this->oauthApiController->getToken('refresh_token', null, 'validrefresh', 'clientId', 'clientSecret'));
606
+    }
607 607
 }
Please login to merge, or discard this patch.
apps/theming/tests/Themes/AccessibleThemeTestCase.php 1 patch
Indentation   +150 added lines, -150 removed lines patch added patch discarded remove patch
@@ -12,161 +12,161 @@
 block discarded – undo
12 12
 use Test\TestCase;
13 13
 
14 14
 class AccessibleThemeTestCase extends TestCase {
15
-	protected ITheme $theme;
16
-	protected Util $util;
15
+    protected ITheme $theme;
16
+    protected Util $util;
17 17
 
18
-	/**
19
-	 * Set to true to check for WCAG AAA level accessibility
20
-	 */
21
-	protected static bool $WCAGaaa = false;
18
+    /**
19
+     * Set to true to check for WCAG AAA level accessibility
20
+     */
21
+    protected static bool $WCAGaaa = false;
22 22
 
23
-	public static function dataAccessibilityPairs(): array {
24
-		$textContrast = self::$WCAGaaa ? 7.0 : 4.5;
25
-		$elementContrast = 3.0;
23
+    public static function dataAccessibilityPairs(): array {
24
+        $textContrast = self::$WCAGaaa ? 7.0 : 4.5;
25
+        $elementContrast = 3.0;
26 26
 
27
-		return [
28
-			'primary-element on background' => [
29
-				[
30
-					'--color-primary-element',
31
-					'--color-primary-element-hover',
32
-				],
33
-				[
34
-					'--color-main-background',
35
-					'--color-background-hover',
36
-					'--color-background-dark',
37
-					'--color-background-darker',
38
-					'--color-main-background-blur',
39
-				],
40
-				$elementContrast,
41
-			],
42
-			'status color elements on background' => [
43
-				[
44
-					'--color-error',
45
-					'--color-error-hover',
46
-					'--color-warning',
47
-					'--color-warning-hover',
48
-					'--color-info',
49
-					'--color-info-hover',
50
-					'--color-success',
51
-					'--color-success-hover',
52
-					'--color-favorite',
53
-				],
54
-				[
55
-					'--color-main-background',
56
-					'--color-background-hover',
57
-					'--color-background-dark',
58
-					'--color-background-darker',
59
-					'--color-main-background-blur',
60
-				],
61
-				$elementContrast,
62
-			],
63
-			'border-colors' => [
64
-				[
65
-					'--color-border-maxcontrast',
66
-				],
67
-				[
68
-					'--color-main-background',
69
-					'--color-background-hover',
70
-					'--color-background-dark',
71
-					'--color-main-background-blur',
72
-				],
73
-				$elementContrast,
74
-			],
75
-			// Those two colors are used for borders which will be `color-main-text` on focussed state, thus need 3:1 contrast to it
76
-			'success-error-border-colors' => [
77
-				[
78
-					'--color-error',
79
-					'--color-success',
80
-				],
81
-				[
82
-					'--color-main-text',
83
-				],
84
-				$elementContrast,
85
-			],
86
-			'primary-element-text' => [
87
-				[
88
-					'--color-primary-element-text',
89
-					'--color-primary-element-text-dark',
90
-				],
91
-				[
92
-					'--color-primary-element',
93
-					'--color-primary-element-hover',
94
-				],
95
-				$textContrast,
96
-			],
97
-			'primary-element-light-text' => [
98
-				['--color-primary-element-light-text'],
99
-				[
100
-					'--color-primary-element-light',
101
-					'--color-primary-element-light-hover',
102
-				],
103
-				$textContrast,
104
-			],
105
-			'main-text' => [
106
-				['--color-main-text'],
107
-				[
108
-					'--color-main-background',
109
-					'--color-background-hover',
110
-					'--color-background-dark',
111
-					'--color-background-darker',
112
-					'--color-main-background-blur',
113
-				],
114
-				$textContrast,
115
-			],
116
-			'max-contrast-text' => [
117
-				['--color-text-maxcontrast'],
118
-				[
119
-					'--color-main-background',
120
-					'--color-background-hover',
121
-					'--color-background-dark',
122
-				],
123
-				$textContrast,
124
-			],
125
-			'max-contrast text-on blur' => [
126
-				['--color-text-maxcontrast-background-blur'],
127
-				[
128
-					'--color-main-background-blur',
129
-				],
130
-				$textContrast,
131
-			],
132
-			'status-text' => [
133
-				[
134
-					'--color-error-text',
135
-					'--color-warning-text',
136
-					'--color-success-text',
137
-					'--color-info-text',
138
-				],
139
-				[
140
-					'--color-main-background',
141
-					'--color-background-hover',
142
-					'--color-background-dark',
143
-					'--color-main-background-blur',
144
-				],
145
-				$textContrast,
146
-			],
147
-		];
148
-	}
27
+        return [
28
+            'primary-element on background' => [
29
+                [
30
+                    '--color-primary-element',
31
+                    '--color-primary-element-hover',
32
+                ],
33
+                [
34
+                    '--color-main-background',
35
+                    '--color-background-hover',
36
+                    '--color-background-dark',
37
+                    '--color-background-darker',
38
+                    '--color-main-background-blur',
39
+                ],
40
+                $elementContrast,
41
+            ],
42
+            'status color elements on background' => [
43
+                [
44
+                    '--color-error',
45
+                    '--color-error-hover',
46
+                    '--color-warning',
47
+                    '--color-warning-hover',
48
+                    '--color-info',
49
+                    '--color-info-hover',
50
+                    '--color-success',
51
+                    '--color-success-hover',
52
+                    '--color-favorite',
53
+                ],
54
+                [
55
+                    '--color-main-background',
56
+                    '--color-background-hover',
57
+                    '--color-background-dark',
58
+                    '--color-background-darker',
59
+                    '--color-main-background-blur',
60
+                ],
61
+                $elementContrast,
62
+            ],
63
+            'border-colors' => [
64
+                [
65
+                    '--color-border-maxcontrast',
66
+                ],
67
+                [
68
+                    '--color-main-background',
69
+                    '--color-background-hover',
70
+                    '--color-background-dark',
71
+                    '--color-main-background-blur',
72
+                ],
73
+                $elementContrast,
74
+            ],
75
+            // Those two colors are used for borders which will be `color-main-text` on focussed state, thus need 3:1 contrast to it
76
+            'success-error-border-colors' => [
77
+                [
78
+                    '--color-error',
79
+                    '--color-success',
80
+                ],
81
+                [
82
+                    '--color-main-text',
83
+                ],
84
+                $elementContrast,
85
+            ],
86
+            'primary-element-text' => [
87
+                [
88
+                    '--color-primary-element-text',
89
+                    '--color-primary-element-text-dark',
90
+                ],
91
+                [
92
+                    '--color-primary-element',
93
+                    '--color-primary-element-hover',
94
+                ],
95
+                $textContrast,
96
+            ],
97
+            'primary-element-light-text' => [
98
+                ['--color-primary-element-light-text'],
99
+                [
100
+                    '--color-primary-element-light',
101
+                    '--color-primary-element-light-hover',
102
+                ],
103
+                $textContrast,
104
+            ],
105
+            'main-text' => [
106
+                ['--color-main-text'],
107
+                [
108
+                    '--color-main-background',
109
+                    '--color-background-hover',
110
+                    '--color-background-dark',
111
+                    '--color-background-darker',
112
+                    '--color-main-background-blur',
113
+                ],
114
+                $textContrast,
115
+            ],
116
+            'max-contrast-text' => [
117
+                ['--color-text-maxcontrast'],
118
+                [
119
+                    '--color-main-background',
120
+                    '--color-background-hover',
121
+                    '--color-background-dark',
122
+                ],
123
+                $textContrast,
124
+            ],
125
+            'max-contrast text-on blur' => [
126
+                ['--color-text-maxcontrast-background-blur'],
127
+                [
128
+                    '--color-main-background-blur',
129
+                ],
130
+                $textContrast,
131
+            ],
132
+            'status-text' => [
133
+                [
134
+                    '--color-error-text',
135
+                    '--color-warning-text',
136
+                    '--color-success-text',
137
+                    '--color-info-text',
138
+                ],
139
+                [
140
+                    '--color-main-background',
141
+                    '--color-background-hover',
142
+                    '--color-background-dark',
143
+                    '--color-main-background-blur',
144
+                ],
145
+                $textContrast,
146
+            ],
147
+        ];
148
+    }
149 149
 
150
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataAccessibilityPairs')]
151
-	public function testAccessibilityOfVariables(array $mainColors, array $backgroundColors, float $minContrast): void {
152
-		if (!isset($this->theme)) {
153
-			$this->markTestSkipped('You need to setup $this->theme in your setUp function');
154
-		} elseif (!isset($this->util)) {
155
-			$this->markTestSkipped('You need to setup $this->util in your setUp function');
156
-		}
150
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataAccessibilityPairs')]
151
+    public function testAccessibilityOfVariables(array $mainColors, array $backgroundColors, float $minContrast): void {
152
+        if (!isset($this->theme)) {
153
+            $this->markTestSkipped('You need to setup $this->theme in your setUp function');
154
+        } elseif (!isset($this->util)) {
155
+            $this->markTestSkipped('You need to setup $this->util in your setUp function');
156
+        }
157 157
 
158
-		$variables = $this->theme->getCSSVariables();
158
+        $variables = $this->theme->getCSSVariables();
159 159
 
160
-		// Blur effect does not work so we mockup the color - worst supported case is the default "clouds" background image (on dark themes the clouds with white color are bad on bright themes the primary color as sky is bad)
161
-		$variables['--color-main-background-blur'] = $this->util->mix($variables['--color-main-background'], $this->util->isBrightColor($variables['--color-main-background']) ? '#000000' : '#ffffff', 75);
160
+        // Blur effect does not work so we mockup the color - worst supported case is the default "clouds" background image (on dark themes the clouds with white color are bad on bright themes the primary color as sky is bad)
161
+        $variables['--color-main-background-blur'] = $this->util->mix($variables['--color-main-background'], $this->util->isBrightColor($variables['--color-main-background']) ? '#000000' : '#ffffff', 75);
162 162
 
163
-		foreach ($backgroundColors as $background) {
164
-			$this->assertStringStartsWith('#', $variables[$background], 'Is not a plain color variable - consider to remove or fix this test');
165
-			foreach ($mainColors as $main) {
166
-				$this->assertStringStartsWith('#', $variables[$main], 'Is not a plain color variable - consider to remove or fix this test');
167
-				$realContrast = $this->util->colorContrast($variables[$main], $variables[$background]);
168
-				$this->assertGreaterThanOrEqual($minContrast, $realContrast, "Contrast is not high enough for $main (" . $variables[$main] . ") on $background (" . $variables[$background] . ')');
169
-			}
170
-		}
171
-	}
163
+        foreach ($backgroundColors as $background) {
164
+            $this->assertStringStartsWith('#', $variables[$background], 'Is not a plain color variable - consider to remove or fix this test');
165
+            foreach ($mainColors as $main) {
166
+                $this->assertStringStartsWith('#', $variables[$main], 'Is not a plain color variable - consider to remove or fix this test');
167
+                $realContrast = $this->util->colorContrast($variables[$main], $variables[$background]);
168
+                $this->assertGreaterThanOrEqual($minContrast, $realContrast, "Contrast is not high enough for $main (" . $variables[$main] . ") on $background (" . $variables[$background] . ')');
169
+            }
170
+        }
171
+    }
172 172
 }
Please login to merge, or discard this patch.
apps/theming/tests/Themes/DyslexiaFontTest.php 1 patch
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -27,137 +27,137 @@
 block discarded – undo
27 27
 use Test\TestCase;
28 28
 
29 29
 class DyslexiaFontTest extends TestCase {
30
-	private ThemingDefaults&MockObject $themingDefaults;
31
-	private IUserSession&MockObject $userSession;
32
-	private IURLGenerator $urlGenerator;
33
-	private ImageManager&MockObject $imageManager;
34
-	private IConfig&MockObject $config;
35
-	private IL10N&MockObject $l10n;
36
-	private IAppManager&MockObject $appManager;
37
-
38
-	private DyslexiaFont $dyslexiaFont;
39
-
40
-	protected function setUp(): void {
41
-		$this->themingDefaults = $this->createMock(ThemingDefaults::class);
42
-		$this->userSession = $this->createMock(IUserSession::class);
43
-		$this->imageManager = $this->createMock(ImageManager::class);
44
-		$this->config = $this->createMock(IConfig::class);
45
-		$this->l10n = $this->createMock(IL10N::class);
46
-		$this->appManager = $this->createMock(IAppManager::class);
47
-
48
-		$util = new Util(
49
-			$this->createMock(ServerVersion::class),
50
-			$this->config,
51
-			$this->appManager,
52
-			$this->createMock(IAppData::class),
53
-			$this->imageManager
54
-		);
55
-
56
-		$userSession = $this->createMock(IUserSession::class);
57
-		$cacheFactory = $this->createMock(ICacheFactory::class);
58
-		$request = $this->createMock(IRequest::class);
59
-		$router = $this->createMock(Router::class);
60
-		$this->urlGenerator = new URLGenerator(
61
-			$this->config,
62
-			$userSession,
63
-			$cacheFactory,
64
-			$request,
65
-			$router
66
-		);
67
-
68
-		$this->themingDefaults
69
-			->expects($this->any())
70
-			->method('getColorPrimary')
71
-			->willReturn('#0082c9');
72
-
73
-		$this->themingDefaults
74
-			->expects($this->any())
75
-			->method('getDefaultColorPrimary')
76
-			->willReturn('#0082c9');
77
-
78
-		$this->themingDefaults
79
-			->expects($this->any())
80
-			->method('getColorBackground')
81
-			->willReturn('#0082c9');
82
-
83
-		$this->themingDefaults
84
-			->expects($this->any())
85
-			->method('getDefaultColorBackground')
86
-			->willReturn('#0082c9');
87
-
88
-		$this->l10n
89
-			->expects($this->any())
90
-			->method('t')
91
-			->willReturnCallback(function ($text, $parameters = []) {
92
-				return vsprintf($text, $parameters);
93
-			});
94
-
95
-		$this->dyslexiaFont = new DyslexiaFont(
96
-			$util,
97
-			$this->themingDefaults,
98
-			$this->userSession,
99
-			$this->urlGenerator,
100
-			$this->imageManager,
101
-			$this->config,
102
-			$this->l10n,
103
-			$this->appManager,
104
-			null,
105
-		);
106
-
107
-		parent::setUp();
108
-	}
109
-
110
-
111
-	public function testGetId(): void {
112
-		$this->assertEquals('opendyslexic', $this->dyslexiaFont->getId());
113
-	}
114
-
115
-	public function testGetType(): void {
116
-		$this->assertEquals(ITheme::TYPE_FONT, $this->dyslexiaFont->getType());
117
-	}
118
-
119
-	public function testGetTitle(): void {
120
-		$this->assertNotEmpty($this->dyslexiaFont->getTitle());
121
-	}
122
-
123
-	public function testGetEnableLabel(): void {
124
-		$this->assertNotEmpty($this->dyslexiaFont->getEnableLabel());
125
-	}
126
-
127
-	public function testGetDescription(): void {
128
-		$this->assertNotEmpty($this->dyslexiaFont->getDescription());
129
-	}
130
-
131
-	public function testGetMediaQuery(): void {
132
-		$this->assertEquals('', $this->dyslexiaFont->getMediaQuery());
133
-	}
134
-
135
-	public function testGetCSSVariables(): void {
136
-		$this->assertStringStartsWith('OpenDyslexic', $this->dyslexiaFont->getCSSVariables()['--font-face']);
137
-	}
138
-
139
-	public static function dataTestGetCustomCss(): array {
140
-		return [
141
-			['', true],
142
-			['', false],
143
-			['/subfolder', true],
144
-			['/subfolder', false],
145
-		];
146
-	}
147
-
148
-	/**
149
-	 * Ensure the fonts are always loaded from the web root
150
-	 * despite having url rewriting enabled or not
151
-	 */
152
-	#[\PHPUnit\Framework\Attributes\DataProvider('dataTestGetCustomCss')]
153
-	public function testGetCustomCss(string $webRoot, bool $prettyUrlsEnabled): void {
154
-		\OC::$WEBROOT = $webRoot;
155
-		$this->config->expects($this->any())
156
-			->method('getSystemValue')
157
-			->with('htaccess.IgnoreFrontController', false)
158
-			->willReturn($prettyUrlsEnabled);
159
-
160
-		$this->assertStringContainsString("'$webRoot/apps/theming/fonts/OpenDyslexic-Regular.otf'", $this->dyslexiaFont->getCustomCss());
161
-		$this->assertStringNotContainsString('index.php', $this->dyslexiaFont->getCustomCss());
162
-	}
30
+    private ThemingDefaults&MockObject $themingDefaults;
31
+    private IUserSession&MockObject $userSession;
32
+    private IURLGenerator $urlGenerator;
33
+    private ImageManager&MockObject $imageManager;
34
+    private IConfig&MockObject $config;
35
+    private IL10N&MockObject $l10n;
36
+    private IAppManager&MockObject $appManager;
37
+
38
+    private DyslexiaFont $dyslexiaFont;
39
+
40
+    protected function setUp(): void {
41
+        $this->themingDefaults = $this->createMock(ThemingDefaults::class);
42
+        $this->userSession = $this->createMock(IUserSession::class);
43
+        $this->imageManager = $this->createMock(ImageManager::class);
44
+        $this->config = $this->createMock(IConfig::class);
45
+        $this->l10n = $this->createMock(IL10N::class);
46
+        $this->appManager = $this->createMock(IAppManager::class);
47
+
48
+        $util = new Util(
49
+            $this->createMock(ServerVersion::class),
50
+            $this->config,
51
+            $this->appManager,
52
+            $this->createMock(IAppData::class),
53
+            $this->imageManager
54
+        );
55
+
56
+        $userSession = $this->createMock(IUserSession::class);
57
+        $cacheFactory = $this->createMock(ICacheFactory::class);
58
+        $request = $this->createMock(IRequest::class);
59
+        $router = $this->createMock(Router::class);
60
+        $this->urlGenerator = new URLGenerator(
61
+            $this->config,
62
+            $userSession,
63
+            $cacheFactory,
64
+            $request,
65
+            $router
66
+        );
67
+
68
+        $this->themingDefaults
69
+            ->expects($this->any())
70
+            ->method('getColorPrimary')
71
+            ->willReturn('#0082c9');
72
+
73
+        $this->themingDefaults
74
+            ->expects($this->any())
75
+            ->method('getDefaultColorPrimary')
76
+            ->willReturn('#0082c9');
77
+
78
+        $this->themingDefaults
79
+            ->expects($this->any())
80
+            ->method('getColorBackground')
81
+            ->willReturn('#0082c9');
82
+
83
+        $this->themingDefaults
84
+            ->expects($this->any())
85
+            ->method('getDefaultColorBackground')
86
+            ->willReturn('#0082c9');
87
+
88
+        $this->l10n
89
+            ->expects($this->any())
90
+            ->method('t')
91
+            ->willReturnCallback(function ($text, $parameters = []) {
92
+                return vsprintf($text, $parameters);
93
+            });
94
+
95
+        $this->dyslexiaFont = new DyslexiaFont(
96
+            $util,
97
+            $this->themingDefaults,
98
+            $this->userSession,
99
+            $this->urlGenerator,
100
+            $this->imageManager,
101
+            $this->config,
102
+            $this->l10n,
103
+            $this->appManager,
104
+            null,
105
+        );
106
+
107
+        parent::setUp();
108
+    }
109
+
110
+
111
+    public function testGetId(): void {
112
+        $this->assertEquals('opendyslexic', $this->dyslexiaFont->getId());
113
+    }
114
+
115
+    public function testGetType(): void {
116
+        $this->assertEquals(ITheme::TYPE_FONT, $this->dyslexiaFont->getType());
117
+    }
118
+
119
+    public function testGetTitle(): void {
120
+        $this->assertNotEmpty($this->dyslexiaFont->getTitle());
121
+    }
122
+
123
+    public function testGetEnableLabel(): void {
124
+        $this->assertNotEmpty($this->dyslexiaFont->getEnableLabel());
125
+    }
126
+
127
+    public function testGetDescription(): void {
128
+        $this->assertNotEmpty($this->dyslexiaFont->getDescription());
129
+    }
130
+
131
+    public function testGetMediaQuery(): void {
132
+        $this->assertEquals('', $this->dyslexiaFont->getMediaQuery());
133
+    }
134
+
135
+    public function testGetCSSVariables(): void {
136
+        $this->assertStringStartsWith('OpenDyslexic', $this->dyslexiaFont->getCSSVariables()['--font-face']);
137
+    }
138
+
139
+    public static function dataTestGetCustomCss(): array {
140
+        return [
141
+            ['', true],
142
+            ['', false],
143
+            ['/subfolder', true],
144
+            ['/subfolder', false],
145
+        ];
146
+    }
147
+
148
+    /**
149
+     * Ensure the fonts are always loaded from the web root
150
+     * despite having url rewriting enabled or not
151
+     */
152
+    #[\PHPUnit\Framework\Attributes\DataProvider('dataTestGetCustomCss')]
153
+    public function testGetCustomCss(string $webRoot, bool $prettyUrlsEnabled): void {
154
+        \OC::$WEBROOT = $webRoot;
155
+        $this->config->expects($this->any())
156
+            ->method('getSystemValue')
157
+            ->with('htaccess.IgnoreFrontController', false)
158
+            ->willReturn($prettyUrlsEnabled);
159
+
160
+        $this->assertStringContainsString("'$webRoot/apps/theming/fonts/OpenDyslexic-Regular.otf'", $this->dyslexiaFont->getCustomCss());
161
+        $this->assertStringNotContainsString('index.php', $this->dyslexiaFont->getCustomCss());
162
+    }
163 163
 }
Please login to merge, or discard this patch.