43 lines
1.5 KiB
PHP
43 lines
1.5 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\EcommerceFinance;
|
|
|
|
use InvalidArgumentException;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class UpstreamReadOnlyQueryTest extends TestCase
|
|
{
|
|
public function test_select_and_read_only_cte_are_allowed(): void
|
|
{
|
|
UpstreamReadOnlyQuery::assertReadOnlySql('SELECT TOP 10 id, name FROM finance_orders');
|
|
UpstreamReadOnlyQuery::assertReadOnlySql(
|
|
'WITH recent AS (SELECT id FROM finance_orders) SELECT id FROM recent'
|
|
);
|
|
|
|
$this->addToAssertionCount(2);
|
|
}
|
|
|
|
#[DataProvider('unsafeSqlProvider')]
|
|
public function test_write_or_high_risk_sql_is_rejected(string $sql): void
|
|
{
|
|
$this->expectException(InvalidArgumentException::class);
|
|
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
}
|
|
|
|
public static function unsafeSqlProvider(): array
|
|
{
|
|
return [
|
|
'insert' => ['INSERT INTO finance_orders (id) VALUES (1)'],
|
|
'cte delete' => ['WITH target AS (SELECT id FROM finance_orders) DELETE FROM target'],
|
|
'select into' => ['SELECT * INTO temp_orders FROM finance_orders'],
|
|
'stored procedure' => ['EXEC refresh_finance_data'],
|
|
'multiple statements' => ['SELECT 1; DELETE FROM finance_orders'],
|
|
'comment' => ['SELECT id FROM finance_orders -- hidden statement'],
|
|
'sequence mutation' => ['SELECT NEXT VALUE FOR finance_sequence'],
|
|
];
|
|
}
|
|
}
|