| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- <?php
- declare(strict_types=1);
- namespace App\Tests\Unit\App;
- use App\App\Config;
- use PHPUnit\Framework\TestCase;
- /**
- * SEC_REVIEW F35 — `INTERNAL_JOB_TOKEN` startup validation.
- */
- final class ConfigTest extends TestCase
- {
- public function testEmptyTokenIsRejected(): void
- {
- $errors = Config::collectErrors(['internal_job_token' => '']);
- self::assertNotEmpty($errors);
- self::assertStringContainsString('INTERNAL_JOB_TOKEN', $errors[0]);
- }
- public function testMissingKeyIsRejected(): void
- {
- $errors = Config::collectErrors([]);
- self::assertNotEmpty($errors);
- self::assertStringContainsString('INTERNAL_JOB_TOKEN', $errors[0]);
- }
- public function testShortHexIsRejected(): void
- {
- $errors = Config::collectErrors(['internal_job_token' => str_repeat('a', 31)]);
- self::assertNotEmpty($errors);
- }
- public function testNonHexIsRejected(): void
- {
- // 32+ chars but contains non-hex — caught by the charset rule.
- $errors = Config::collectErrors([
- 'internal_job_token' => 'this-token-is-32-plus-chars-but-not-hex-at-all',
- ]);
- self::assertNotEmpty($errors);
- }
- public function testWeakLiteralFooIsRejected(): void
- {
- // The exact case the SEC_REVIEW called out.
- $errors = Config::collectErrors(['internal_job_token' => 'foo']);
- self::assertNotEmpty($errors);
- }
- public function testThirtyTwoHexCharsAccepted(): void
- {
- $errors = Config::collectErrors([
- 'internal_job_token' => str_repeat('a', 32),
- ]);
- self::assertSame([], $errors);
- }
- public function testSixtyFourHexCharsAcceptedDocumentedForm(): void
- {
- // openssl rand -hex 32 → 64 hex chars; the documented form.
- $errors = Config::collectErrors([
- 'internal_job_token' => bin2hex(random_bytes(32)),
- ]);
- self::assertSame([], $errors);
- }
- public function testUppercaseHexAccepted(): void
- {
- $errors = Config::collectErrors([
- 'internal_job_token' => str_repeat('A', 32),
- ]);
- self::assertSame([], $errors);
- }
- public function testValidateOrExitWritesToStderrAndExits(): void
- {
- // Run the failing branch in a subprocess so we can observe both
- // the non-zero exit and the STDERR text without taking down PHPUnit.
- $script = <<<'PHP'
- <?php
- declare(strict_types=1);
- require %s;
- App\App\Config::validateOrExit(['internal_job_token' => 'too-short']);
- PHP;
- $autoload = var_export(__DIR__ . '/../../../vendor/autoload.php', true);
- $script = sprintf($script, $autoload);
- $tmp = tempnam(sys_get_temp_dir(), 'cfg');
- self::assertIsString($tmp);
- file_put_contents($tmp, $script);
- $stderr = '';
- $process = proc_open(
- [PHP_BINARY, $tmp],
- [1 => ['pipe', 'w'], 2 => ['pipe', 'w']],
- $pipes,
- );
- self::assertIsResource($process);
- fclose($pipes[1]);
- $stderr = (string) stream_get_contents($pipes[2]);
- fclose($pipes[2]);
- $exitCode = proc_close($process);
- @unlink($tmp);
- self::assertSame(1, $exitCode);
- self::assertStringContainsString('INTERNAL_JOB_TOKEN', $stderr);
- }
- }
|