Skip to content

Commit 07fc1ba

Browse files
CodeRabbit Generated Unit Tests: Add unit tests for PR changes
1 parent 9524f81 commit 07fc1ba

2 files changed

Lines changed: 632 additions & 0 deletions

File tree

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
<?php
2+
3+
namespace SAMSPlugin\Tests\ApiSpecs;
4+
5+
use PHPUnit\Framework\TestCase;
6+
7+
final class ApiSpecValidationTest extends TestCase {
8+
9+
private const API_SPECS_DIR = __DIR__ . '/../../api-specs';
10+
private const EXPECTED_VERSION = '2.1';
11+
12+
private const EXPECTED_SERVERS = [
13+
'flvb.sams-server.de',
14+
'hessen-volley.de',
15+
'nwvv.sams-server.de',
16+
'vvb.sams-server.de',
17+
'vvsa.sams-server.de',
18+
'wvv.sams-server.de',
19+
'www.dvv-ligen.de',
20+
'www.shvv.de',
21+
'www.ssvb.org',
22+
'www.tv-v.de',
23+
'www.vlw-online.de',
24+
'www.volley-saar.de',
25+
'www.volleyball-baden.de',
26+
'www.volleyball-bundesliga.de',
27+
'www.vvrp.de',
28+
];
29+
30+
/**
31+
* Test that all expected API spec files exist
32+
*/
33+
public function testAllExpectedApiSpecFilesExist() {
34+
foreach (self::EXPECTED_SERVERS as $server) {
35+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
36+
$this->assertFileExists(
37+
$filePath,
38+
"API spec file for {$server} version " . self::EXPECTED_VERSION . " should exist"
39+
);
40+
}
41+
}
42+
43+
/**
44+
* Test that all API spec files contain valid JSON
45+
*/
46+
public function testAllApiSpecFilesContainValidJson() {
47+
foreach (self::EXPECTED_SERVERS as $server) {
48+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
49+
$content = file_get_contents($filePath);
50+
51+
$this->assertNotFalse($content, "Should be able to read {$filePath}");
52+
53+
$decoded = json_decode($content, true);
54+
$this->assertNotNull(
55+
$decoded,
56+
"API spec file {$filePath} should contain valid JSON. Error: " . json_last_error_msg()
57+
);
58+
$this->assertIsArray($decoded, "Decoded JSON should be an array/object");
59+
}
60+
}
61+
62+
/**
63+
* Test that all API spec files are valid OpenAPI 3.x specifications
64+
*/
65+
public function testAllApiSpecFilesAreValidOpenApiSpecs() {
66+
foreach (self::EXPECTED_SERVERS as $server) {
67+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
68+
$content = file_get_contents($filePath);
69+
$spec = json_decode($content, true);
70+
71+
// Check required OpenAPI fields
72+
$this->assertArrayHasKey(
73+
'openapi',
74+
$spec,
75+
"{$filePath} should have 'openapi' field"
76+
);
77+
$this->assertArrayHasKey(
78+
'info',
79+
$spec,
80+
"{$filePath} should have 'info' field"
81+
);
82+
$this->assertArrayHasKey(
83+
'paths',
84+
$spec,
85+
"{$filePath} should have 'paths' field"
86+
);
87+
88+
// Verify OpenAPI version is 3.x
89+
$this->assertMatchesRegularExpression(
90+
'/^3\.\d+\.\d+$/',
91+
$spec['openapi'],
92+
"{$filePath} should use OpenAPI version 3.x"
93+
);
94+
}
95+
}
96+
97+
/**
98+
* Test that API version in file content matches filename
99+
*/
100+
public function testApiVersionInFileMatchesFilename() {
101+
foreach (self::EXPECTED_SERVERS as $server) {
102+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
103+
$content = file_get_contents($filePath);
104+
$spec = json_decode($content, true);
105+
106+
$this->assertArrayHasKey(
107+
'info',
108+
$spec,
109+
"{$filePath} should have 'info' field"
110+
);
111+
$this->assertArrayHasKey(
112+
'version',
113+
$spec['info'],
114+
"{$filePath} should have 'info.version' field"
115+
);
116+
$this->assertEquals(
117+
self::EXPECTED_VERSION,
118+
$spec['info']['version'],
119+
"API version in {$filePath} should match filename"
120+
);
121+
}
122+
}
123+
124+
/**
125+
* Test that all API specs have consistent required info fields
126+
*/
127+
public function testAllApiSpecsHaveConsistentInfoFields() {
128+
foreach (self::EXPECTED_SERVERS as $server) {
129+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
130+
$content = file_get_contents($filePath);
131+
$spec = json_decode($content, true);
132+
133+
$this->assertArrayHasKey(
134+
'title',
135+
$spec['info'],
136+
"{$filePath} should have 'info.title' field"
137+
);
138+
$this->assertArrayHasKey(
139+
'version',
140+
$spec['info'],
141+
"{$filePath} should have 'info.version' field"
142+
);
143+
144+
$this->assertIsString($spec['info']['title'], "Title should be a string");
145+
$this->assertNotEmpty($spec['info']['title'], "Title should not be empty");
146+
}
147+
}
148+
149+
/**
150+
* Test that all API specs have paths defined
151+
*/
152+
public function testAllApiSpecsHavePathsDefined() {
153+
foreach (self::EXPECTED_SERVERS as $server) {
154+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
155+
$content = file_get_contents($filePath);
156+
$spec = json_decode($content, true);
157+
158+
$this->assertIsArray(
159+
$spec['paths'],
160+
"{$filePath} paths should be an array/object"
161+
);
162+
$this->assertNotEmpty(
163+
$spec['paths'],
164+
"{$filePath} should have at least one path defined"
165+
);
166+
}
167+
}
168+
169+
/**
170+
* Test that all API specs have servers defined
171+
*/
172+
public function testAllApiSpecsHaveServersDefined() {
173+
foreach (self::EXPECTED_SERVERS as $server) {
174+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
175+
$content = file_get_contents($filePath);
176+
$spec = json_decode($content, true);
177+
178+
$this->assertArrayHasKey(
179+
'servers',
180+
$spec,
181+
"{$filePath} should have 'servers' field"
182+
);
183+
$this->assertIsArray(
184+
$spec['servers'],
185+
"{$filePath} servers should be an array"
186+
);
187+
$this->assertNotEmpty(
188+
$spec['servers'],
189+
"{$filePath} should have at least one server defined"
190+
);
191+
192+
// Check first server has required url field
193+
$this->assertArrayHasKey(
194+
'url',
195+
$spec['servers'][0],
196+
"{$filePath} first server should have 'url' field"
197+
);
198+
}
199+
}
200+
201+
/**
202+
* Test that all API specs have components defined
203+
*/
204+
public function testAllApiSpecsHaveComponentsDefined() {
205+
foreach (self::EXPECTED_SERVERS as $server) {
206+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
207+
$content = file_get_contents($filePath);
208+
$spec = json_decode($content, true);
209+
210+
$this->assertArrayHasKey(
211+
'components',
212+
$spec,
213+
"{$filePath} should have 'components' field"
214+
);
215+
$this->assertIsArray(
216+
$spec['components'],
217+
"{$filePath} components should be an array/object"
218+
);
219+
}
220+
}
221+
222+
/**
223+
* Test that API spec files are not empty
224+
*/
225+
public function testApiSpecFilesAreNotEmpty() {
226+
foreach (self::EXPECTED_SERVERS as $server) {
227+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
228+
$fileSize = filesize($filePath);
229+
230+
$this->assertGreaterThan(
231+
100,
232+
$fileSize,
233+
"{$filePath} should not be empty (should be > 100 bytes)"
234+
);
235+
}
236+
}
237+
238+
/**
239+
* Test that API specs directory structure is correct
240+
*/
241+
public function testApiSpecsDirectoryStructureIsCorrect() {
242+
$this->assertDirectoryExists(
243+
self::API_SPECS_DIR,
244+
"API specs directory should exist"
245+
);
246+
247+
foreach (self::EXPECTED_SERVERS as $server) {
248+
$serverDir = self::API_SPECS_DIR . '/' . $server;
249+
$this->assertDirectoryExists(
250+
$serverDir,
251+
"Server directory {$serverDir} should exist"
252+
);
253+
}
254+
}
255+
256+
/**
257+
* Test that all API specs have SAMS API title
258+
*/
259+
public function testAllApiSpecsHaveSamsApiTitle() {
260+
foreach (self::EXPECTED_SERVERS as $server) {
261+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
262+
$content = file_get_contents($filePath);
263+
$spec = json_decode($content, true);
264+
265+
$title = $spec['info']['title'];
266+
$this->assertStringContainsString(
267+
'SAMS',
268+
$title,
269+
"{$filePath} title should contain 'SAMS'"
270+
);
271+
}
272+
}
273+
274+
/**
275+
* Test that all API specs are readable and parseable in a single pass
276+
*/
277+
public function testAllApiSpecsAreCompletelyParseable() {
278+
foreach (self::EXPECTED_SERVERS as $server) {
279+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
280+
281+
// Test that the entire file can be loaded and parsed without errors
282+
$content = @file_get_contents($filePath);
283+
$this->assertNotFalse($content, "Should be able to read {$filePath}");
284+
285+
json_decode($content, true);
286+
$jsonError = json_last_error();
287+
288+
$this->assertEquals(
289+
JSON_ERROR_NONE,
290+
$jsonError,
291+
"JSON in {$filePath} should be completely valid. Error: " . json_last_error_msg()
292+
);
293+
}
294+
}
295+
296+
/**
297+
* Test boundary case: Non-existent version file should not exist
298+
*/
299+
public function testNonExistentVersionFilesDoNotExist() {
300+
$nonExistentVersion = '999.999';
301+
$server = self::EXPECTED_SERVERS[0];
302+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . $nonExistentVersion . '.json';
303+
304+
$this->assertFileDoesNotExist(
305+
$filePath,
306+
"Non-existent version file should not exist"
307+
);
308+
}
309+
310+
/**
311+
* Test regression: Ensure each spec has at least one GET endpoint
312+
* This ensures the API specs are functional and usable
313+
*/
314+
public function testAllApiSpecsHaveAtLeastOneGetEndpoint() {
315+
foreach (self::EXPECTED_SERVERS as $server) {
316+
$filePath = self::API_SPECS_DIR . '/' . $server . '/' . self::EXPECTED_VERSION . '.json';
317+
$content = file_get_contents($filePath);
318+
$spec = json_decode($content, true);
319+
320+
$hasGetEndpoint = false;
321+
foreach ($spec['paths'] as $path => $methods) {
322+
if (isset($methods['get'])) {
323+
$hasGetEndpoint = true;
324+
break;
325+
}
326+
}
327+
328+
$this->assertTrue(
329+
$hasGetEndpoint,
330+
"{$filePath} should have at least one GET endpoint defined"
331+
);
332+
}
333+
}
334+
}

0 commit comments

Comments
 (0)