| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- <?php
- /*
- * Copyright 2026 Alessandro Chiapparini <sprint_planer_web@chiapparini.org>
- * SPDX-License-Identifier: Apache-2.0
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * See the LICENSE file in the project root for the full license text.
- */
- declare(strict_types=1);
- namespace App\Tests\Repositories;
- use App\Repositories\AuditRepository;
- use App\Services\AuditLogger;
- use App\Tests\TestCase;
- use InvalidArgumentException;
- /**
- * R01-N11: AuditRepository::distinctColumn interpolates its argument into
- * SQL. The method is private and both internal callers pass literals, but
- * the runtime whitelist guard makes the contract explicit so a future
- * refactor can't open an injection vector.
- */
- final class AuditRepositoryTest extends TestCase
- {
- public function testDistinctActionsReturnsSortedUniqueValues(): void
- {
- $pdo = $this->makeDb();
- $logger = new AuditLogger($pdo);
- $logger->record('UPDATE', 'worker', 1, ['n' => 1], ['n' => 2]);
- $logger->record('CREATE', 'worker', 2, null, ['n' => 1]);
- $logger->record('UPDATE', 'sprint', 3, ['n' => 1], ['n' => 2]);
- $repo = new AuditRepository($pdo);
- $this->assertSame(['CREATE', 'UPDATE'], $repo->distinctActions());
- }
- public function testDistinctEntityTypesReturnsSortedUniqueValues(): void
- {
- $pdo = $this->makeDb();
- $logger = new AuditLogger($pdo);
- $logger->record('UPDATE', 'worker', 1, ['n' => 1], ['n' => 2]);
- $logger->record('UPDATE', 'sprint', 2, ['n' => 1], ['n' => 2]);
- $logger->record('UPDATE', 'worker', 3, ['n' => 1], ['n' => 2]);
- $repo = new AuditRepository($pdo);
- $this->assertSame(['sprint', 'worker'], $repo->distinctEntityTypes());
- }
- public function testDistinctColumnRejectsUnknownColumnViaReflection(): void
- {
- $pdo = $this->makeDb();
- $repo = new AuditRepository($pdo);
- $rm = new \ReflectionMethod($repo, 'distinctColumn');
- $rm->setAccessible(true);
- $this->expectException(InvalidArgumentException::class);
- $rm->invoke($repo, 'user_email');
- }
- public function testDistinctColumnRejectsInjectionAttemptViaReflection(): void
- {
- $pdo = $this->makeDb();
- $repo = new AuditRepository($pdo);
- $rm = new \ReflectionMethod($repo, 'distinctColumn');
- $rm->setAccessible(true);
- $this->expectException(InvalidArgumentException::class);
- $rm->invoke($repo, 'action; DROP TABLE audit_log; --');
- }
- }
|