Files
michaelschiemer/tests/Framework/Database/StoredProcedure/StoredProcedureDefinitionTest.php
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

113 lines
4.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Framework\Database\StoredProcedure;
use App\Framework\Database\StoredProcedure\StoredProcedureDefinition;
test('creates a stored procedure definition with builder pattern', function () {
$procedure = StoredProcedureDefinition::create('get_user_by_id')
->withParameter('user_id', 'INT')
->withBody('SELECT * FROM users WHERE id = user_id')
->returnsType('TABLE');
expect($procedure->getName())->toBe('get_user_by_id');
expect($procedure->getParameters())->toHaveCount(1);
expect($procedure->getParameters()[0]['name'])->toBe('user_id');
expect($procedure->getParameters()[0]['type'])->toBe('INT');
expect($procedure->getBody())->toBe('SELECT * FROM users WHERE id = user_id');
expect($procedure->getReturnType())->toBe('TABLE');
});
test('generates MySQL stored procedure SQL', function () {
$procedure = StoredProcedureDefinition::create('calculate_order_total')
->withParameter('order_id', 'INT')
->withParameter('include_tax', 'BOOLEAN', true)
->withBody('
DECLARE total DECIMAL(10,2);
SELECT SUM(price * quantity) INTO total FROM order_items WHERE order_id = order_id;
IF include_tax THEN
SET total = total * 1.19;
END IF;
RETURN total;
')
->returnsType('DECIMAL(10,2)');
$sql = $procedure->toSql('mysql');
expect($sql)->toContain('CREATE PROCEDURE `calculate_order_total`');
expect($sql)->toContain('IN `order_id` INT');
expect($sql)->toContain('IN `include_tax` BOOLEAN');
expect($sql)->toContain('DECLARE total DECIMAL(10,2)');
expect($sql)->toContain('DELIMITER');
});
test('generates PostgreSQL stored procedure SQL', function () {
$procedure = StoredProcedureDefinition::create('get_active_users')
->withParameter('min_login_count', 'INT')
->withBody('
RETURN QUERY
SELECT * FROM users
WHERE active = true AND login_count >= min_login_count
ORDER BY last_login DESC;
')
->returnsType('SETOF users');
$sql = $procedure->toSql('pgsql');
expect($sql)->toContain('CREATE OR REPLACE FUNCTION get_active_users');
expect($sql)->toContain('min_login_count INT');
expect($sql)->toContain('RETURNS SETOF users');
expect($sql)->toContain('LANGUAGE plpgsql');
});
test('generates SQLite stored procedure SQL as user-defined function', function () {
$procedure = StoredProcedureDefinition::create('calculate_age')
->withParameter('birth_date', 'TEXT')
->withBody('
RETURN (julianday("now") - julianday(birth_date)) / 365.25;
')
->returnsType('REAL');
$sql = $procedure->toSql('sqlite');
expect($sql)->toContain('CREATE FUNCTION calculate_age');
expect($sql)->toContain('(birth_date TEXT)');
expect($sql)->toContain('RETURNS REAL');
});
test('throws exception for unsupported database driver', function () {
$procedure = StoredProcedureDefinition::create('test_procedure')
->withBody('SELECT 1')
->returnsType('INT');
expect(fn () => $procedure->toSql('unsupported_driver'))
->toThrow(\InvalidArgumentException::class, 'Unsupported database driver: unsupported_driver');
});
test('validates procedure name', function () {
expect(fn () => StoredProcedureDefinition::create(''))
->toThrow(\InvalidArgumentException::class, 'Procedure name cannot be empty');
expect(fn () => StoredProcedureDefinition::create('invalid-name'))
->toThrow(\InvalidArgumentException::class, 'Invalid procedure name: invalid-name');
});
test('validates parameter name', function () {
$procedure = StoredProcedureDefinition::create('test_procedure');
expect(fn () => $procedure->withParameter('', 'INT'))
->toThrow(\InvalidArgumentException::class, 'Parameter name cannot be empty');
expect(fn () => $procedure->withParameter('invalid-name', 'INT'))
->toThrow(\InvalidArgumentException::class, 'Invalid parameter name: invalid-name');
});
test('validates body is not empty before generating SQL', function () {
$procedure = StoredProcedureDefinition::create('test_procedure');
expect(fn () => $procedure->toSql('mysql'))
->toThrow(\InvalidArgumentException::class, 'Procedure body cannot be empty');
});