KeyCloakTest::testConstructorWithPublicClient()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 3
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 5
rs 10
1
<?php
2
3
/*
4
 * SPDX-License-Identifier: AGPL-3.0-only
5
 * SPDX-FileCopyrightText: Copyright 2025 grommunio GmbH
6
 *
7
 * Unit tests for KeyCloak class
8
 */
9
10
use PHPUnit\Framework\TestCase;
0 ignored issues
show
Bug introduced by
The type PHPUnit\Framework\TestCase was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
12
/**
13
 * @internal
14
 *
15
 * @coversNothing
16
 */
17
class KeyCloakTest extends TestCase {
18
	private function createTestConfig(): array {
19
		return [
20
			'realm' => 'test-realm',
21
			'resource' => 'test-client',
22
			'auth-server-url' => 'https://keycloak.example.com/',
23
			'credentials' => [
24
				'secret' => 'test-secret-12345',
25
			],
26
		];
27
	}
28
29
	private function createPublicClientConfig(): array {
30
		return [
31
			'realm' => 'test-realm',
32
			'resource' => 'test-client',
33
			'auth-server-url' => 'https://keycloak.example.com/',
34
			'public-client' => true,
35
			'realm-public-key' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA',
36
		];
37
	}
38
39
	protected function setUp(): void {
40
		// Set up required server variables for URL construction
41
		$_SERVER['HTTP_HOST'] = 'example.com';
42
		$_SERVER['REQUEST_URI'] = '/test';
43
	}
44
45
	// Constructor tests
46
	public function testConstructorWithArrayConfig(): void {
47
		$config = $this->createTestConfig();
48
		$keycloak = new KeyCloak($config);
49
50
		$this->assertInstanceOf(KeyCloak::class, $keycloak);
51
	}
52
53
	public function testConstructorWithJsonStringConfig(): void {
54
		$config = $this->createTestConfig();
55
		$keycloak = new KeyCloak(json_encode($config));
56
57
		$this->assertInstanceOf(KeyCloak::class, $keycloak);
58
	}
59
60
	public function testConstructorSetsRedirectUrl(): void {
61
		$config = $this->createTestConfig();
62
		$keycloak = new KeyCloak($config);
63
64
		$this->assertEquals('https://example.com/test', $keycloak->redirect_url);
65
	}
66
67
	public function testConstructorHandlesTrailingSlashInUrl(): void {
68
		$_SERVER['REQUEST_URI'] = '/test/';
69
		$config = $this->createTestConfig();
70
		$keycloak = new KeyCloak($config);
71
72
		$this->assertEquals('https://example.com/test', $keycloak->redirect_url);
73
	}
74
75
	public function testConstructorUsesDefaultRealm(): void {
76
		$config = [
77
			'auth-server-url' => 'https://keycloak.example.com/',
78
			'credentials' => ['secret' => 'test'],
79
		];
80
		$keycloak = new KeyCloak($config);
81
82
		$this->assertInstanceOf(KeyCloak::class, $keycloak);
83
	}
84
85
	public function testConstructorUsesDefaultClientId(): void {
86
		$config = [
87
			'realm' => 'test',
88
			'auth-server-url' => 'https://keycloak.example.com/',
89
			'credentials' => ['secret' => 'test'],
90
		];
91
		$keycloak = new KeyCloak($config);
92
93
		$this->assertInstanceOf(KeyCloak::class, $keycloak);
94
	}
95
96
	public function testConstructorWithPublicClient(): void {
97
		$config = $this->createPublicClientConfig();
98
		$keycloak = new KeyCloak($config);
99
100
		$this->assertInstanceOf(KeyCloak::class, $keycloak);
101
	}
102
103
	// Public property tests
104
	public function testAccessTokenPropertyExists(): void {
105
		$config = $this->createTestConfig();
106
		$keycloak = new KeyCloak($config);
107
108
		$this->assertObjectHasProperty('access_token', $keycloak);
109
	}
110
111
	public function testRefreshTokenPropertyExists(): void {
112
		$config = $this->createTestConfig();
113
		$keycloak = new KeyCloak($config);
114
115
		$this->assertObjectHasProperty('refresh_token', $keycloak);
116
	}
117
118
	public function testIdTokenPropertyExists(): void {
119
		$config = $this->createTestConfig();
120
		$keycloak = new KeyCloak($config);
121
122
		$this->assertObjectHasProperty('id_token', $keycloak);
123
	}
124
125
	public function testGrantPropertyExists(): void {
126
		$config = $this->createTestConfig();
127
		$keycloak = new KeyCloak($config);
128
129
		$this->assertObjectHasProperty('grant', $keycloak);
130
	}
131
132
	public function testErrorPropertyExists(): void {
133
		$config = $this->createTestConfig();
134
		$keycloak = new KeyCloak($config);
135
136
		$this->assertObjectHasProperty('error', $keycloak);
137
	}
138
139
	// login_url tests
140
	public function testLoginUrlReturnsString(): void {
141
		$config = $this->createTestConfig();
142
		$keycloak = new KeyCloak($config);
143
144
		$url = $keycloak->login_url('https://example.com/callback');
145
146
		$this->assertIsString($url);
147
	}
148
149
	public function testLoginUrlContainsRealm(): void {
150
		$config = $this->createTestConfig();
151
		$keycloak = new KeyCloak($config);
152
153
		$url = $keycloak->login_url('https://example.com/callback');
154
155
		$this->assertStringContainsString('test-realm', $url);
156
	}
157
158
	public function testLoginUrlContainsClientId(): void {
159
		$config = $this->createTestConfig();
160
		$keycloak = new KeyCloak($config);
161
162
		$url = $keycloak->login_url('https://example.com/callback');
163
164
		$this->assertStringContainsString('test-client', $url);
165
	}
166
167
	public function testLoginUrlContainsRedirectUri(): void {
168
		$config = $this->createTestConfig();
169
		$keycloak = new KeyCloak($config);
170
171
		$url = $keycloak->login_url('https://example.com/callback');
172
173
		$this->assertStringContainsString('redirect_uri', $url);
174
		$this->assertStringContainsString(urlencode('https://example.com/callback'), $url);
175
	}
176
177
	public function testLoginUrlContainsScope(): void {
178
		$config = $this->createTestConfig();
179
		$keycloak = new KeyCloak($config);
180
181
		$url = $keycloak->login_url('https://example.com/callback');
182
183
		$this->assertStringContainsString('scope=openid', $url);
184
	}
185
186
	public function testLoginUrlContainsResponseType(): void {
187
		$config = $this->createTestConfig();
188
		$keycloak = new KeyCloak($config);
189
190
		$url = $keycloak->login_url('https://example.com/callback');
191
192
		$this->assertStringContainsString('response_type=code', $url);
193
	}
194
195
	public function testLoginUrlContainsState(): void {
196
		$config = $this->createTestConfig();
197
		$keycloak = new KeyCloak($config);
198
199
		$url = $keycloak->login_url('https://example.com/callback');
200
201
		$this->assertStringContainsString('state=', $url);
202
	}
203
204
	public function testLoginUrlStateIsRandom(): void {
205
		$config = $this->createTestConfig();
206
		$keycloak = new KeyCloak($config);
207
208
		$url1 = $keycloak->login_url('https://example.com/callback');
209
		$url2 = $keycloak->login_url('https://example.com/callback');
210
211
		$this->assertNotEquals($url1, $url2);
212
	}
213
214
	// is_expired tests
215
	public function testIsExpiredReturnsTrueWithoutAccessToken(): void {
216
		$config = $this->createTestConfig();
217
		$keycloak = new KeyCloak($config);
218
219
		$this->assertTrue($keycloak->is_expired());
220
	}
221
222
	// Last refresh time tests
223
	public function testGetLastRefreshTimeReturnsNull(): void {
224
		$config = $this->createTestConfig();
225
		$keycloak = new KeyCloak($config);
226
227
		$this->assertNull($keycloak->get_last_refresh_time());
228
	}
229
230
	public function testSetLastRefreshTime(): void {
231
		$config = $this->createTestConfig();
232
		$keycloak = new KeyCloak($config);
233
234
		$time = time();
235
		$keycloak->set_last_refresh_time($time);
236
237
		$this->assertEquals($time, $keycloak->get_last_refresh_time());
238
	}
239
240
	public function testSetAndGetLastRefreshTimeRoundTrip(): void {
241
		$config = $this->createTestConfig();
242
		$keycloak = new KeyCloak($config);
243
244
		$time = 1234567890;
245
		$keycloak->set_last_refresh_time($time);
246
247
		$this->assertEquals($time, $keycloak->get_last_refresh_time());
248
	}
249
250
	// Refresh grant request tests
251
	public function testRefreshGrantReqReturnsFalseWithoutGrant(): void {
252
		$config = $this->createTestConfig();
253
		$keycloak = new KeyCloak($config);
254
255
		$this->assertFalse($keycloak->refresh_grant_req());
256
	}
257
258
	public function testRefreshGrantReqReturnsFalseWithoutRefreshToken(): void {
259
		$config = $this->createTestConfig();
260
		$keycloak = new KeyCloak($config);
261
		$keycloak->grant = ['access_token' => 'test'];
262
263
		$this->assertFalse($keycloak->refresh_grant_req());
264
	}
265
266
	// URL encoding tests
267
	public function testLoginUrlEncodesSpecialCharacters(): void {
268
		$config = $this->createTestConfig();
269
		$keycloak = new KeyCloak($config);
270
271
		$url = $keycloak->login_url('https://example.com/callback?param=value&other=test');
272
273
		$this->assertStringContainsString(urlencode('https://example.com/callback?param=value&other=test'), $url);
274
	}
275
276
	public function testLoginUrlHandlesComplexRedirectUrl(): void {
277
		$config = $this->createTestConfig();
278
		$keycloak = new KeyCloak($config);
279
280
		$complexUrl = 'https://example.com/path/to/callback?existing=param';
281
		$url = $keycloak->login_url($complexUrl);
282
283
		$this->assertStringContainsString(urlencode($complexUrl), $url);
284
	}
285
286
	// Class structure tests
287
	public function testKeysCloakClassExists(): void {
288
		$this->assertTrue(class_exists('KeyCloak'));
289
	}
290
291
	public function testGetInstanceReturnsNullWithoutConfig(): void {
292
		// This test assumes the config file doesn't exist
293
		if (!file_exists('/etc/gromox/keycloak.json')) {
294
			$instance = KeyCloak::getInstance();
295
			$this->assertNull($instance);
296
		}
297
		else {
298
			$this->assertTrue(true); // Skip if config exists
299
		}
300
	}
301
}
302