Files
alrahma_sunday_school/tests/app/Config/FinancialRouteIntegrityTest.php
T
root a30c1398a1
Tests / PHPUnit (push) Failing after 1m21s
fix financials
2026-07-18 22:57:40 -04:00

103 lines
3.6 KiB
PHP

<?php
namespace Tests\App\Config;
use CodeIgniter\Test\CIUnitTestCase;
class FinancialRouteIntegrityTest extends CIUnitTestCase
{
private string $routesFile;
protected function setUp(): void
{
parent::setUp();
$this->routesFile = ROOTPATH . 'app/Config/Routes.php';
}
public function testFinancialBrowserWriteRoutesArePostOnlyAndFiltered(): void
{
$routes = file($this->routesFile, FILE_IGNORE_NEW_LINES) ?: [];
$financialWrites = array_values(array_filter($routes, static function (string $line): bool {
return str_contains($line, '$routes->post(')
&& preg_match('/(refunds|expenses|reimbursements|discount|charges|payment|invoice|purchase|inventory)/i', $line);
}));
$this->assertNotEmpty($financialWrites);
foreach ($financialWrites as $line) {
$this->assertStringContainsString("'filter'", $line, $line);
$this->assertStringContainsString('auth:', $line, $line);
}
}
public function testFinancialStateChangingRoutesDoNotUseGet(): void
{
$routes = file($this->routesFile, FILE_IGNORE_NEW_LINES) ?: [];
foreach ($routes as $line) {
if (!str_contains($line, '$routes->get(')) {
continue;
}
if (! preg_match('/\$routes->get\(\s*[\'"]([^\'"]+)/', $line, $matches)) {
continue;
}
$routePath = $matches[1];
if (!preg_match('/(refunds|expenses|reimbursements|discount|charges|payment|invoice|purchase|inventory)/i', $routePath)) {
continue;
}
$this->assertDoesNotMatchRegularExpression('/(update|store|approve|reverse|void|delete|apply|recalculate)/i', $routePath, $line);
}
}
public function testFinancialWritesDoNotUseGetPostMatchRoutes(): void
{
$routes = file($this->routesFile, FILE_IGNORE_NEW_LINES) ?: [];
$checked = 0;
foreach ($routes as $line) {
if (!str_contains($line, '$routes->match(') || !str_contains($line, "'get'") || !str_contains($line, "'post'")) {
continue;
}
if (!preg_match('/(refunds|expenses|reimbursements|discount|charges|payment|invoice|purchase|inventory)/i', $line)) {
continue;
}
$checked++;
$this->fail('Financial routes must split read GET and write POST handlers: ' . $line);
}
$this->assertSame(0, $checked);
}
public function testGenericApiDoesNotExposeFinancialMutations(): void
{
$text = file_get_contents($this->routesFile) ?: '';
$forbidden = [
"post('payments'",
"put('payments/",
"post('payment-transactions'",
"get('payment-transactions'",
"post('payment-notifications/send'",
"post('expenses'",
"put('expenses/",
"post('reimbursements'",
"put('reimbursements/",
"post('refunds'",
"put('refunds/",
"post('discounts/apply'",
"post('extra-charges'",
"put('extra-charges/",
"post('purchase-orders'",
"put('purchase-orders/",
"post('inventory'",
"put('inventory/",
"delete('inventory/",
];
$apiV1Start = strpos($text, "\$routes->group('api/v1'");
$this->assertIsInt($apiV1Start);
$apiV1Text = substr($text, $apiV1Start);
foreach ($forbidden as $needle) {
$this->assertStringNotContainsString($needle, $apiV1Text, $needle);
}
}
}