refactor: consolidate file path validation patterns and support scoped packages

- Extract file path validation regex into ValidationPatterns::FILE_PATH_PATTERN constant
- Add filePathRules() and filePathMessages() helper methods for reusable validation
- Extend allowed characters from [a-zA-Z0-9._\-/] to [a-zA-Z0-9._\-/~@+] to support:
  - Scoped npm packages (@org/package)
  - Language-specific directories (c++, rust+)
  - Version markers (v1~, build~)
- Replace duplicate inline regex patterns across multiple files
- Add tests for paths with @ symbol and tilde/plus characters
This commit is contained in:
Andras Bacsai committed 2026-03-12 13:09:13 +01:00
1 parent 709e5e882e
commit 01031fc5f3
8 files changed
+74 -16

No files matched your search

+35 -1
View File
@@ -91,6 +91,28 @@ describe('deployment job path field validation', function () {
->toBe('/docker/Dockerfile.prod');
});
test('allows path with @ symbol for scoped packages', function () {
$job = new ReflectionClass(ApplicationDeploymentJob::class);
$method = $job->getMethod('validatePathField');
$method->setAccessible(true);
$instance = $job->newInstanceWithoutConstructor();
expect($method->invoke($instance, '/packages/@intlayer/mcp/Dockerfile', 'dockerfile_location'))
->toBe('/packages/@intlayer/mcp/Dockerfile');
});
test('allows path with tilde and plus characters', function () {
$job = new ReflectionClass(ApplicationDeploymentJob::class);
$method = $job->getMethod('validatePathField');
$method->setAccessible(true);
$instance = $job->newInstanceWithoutConstructor();
expect($method->invoke($instance, '/build~v1/c++/Dockerfile', 'dockerfile_location'))
->toBe('/build~v1/c++/Dockerfile');
});
test('allows valid compose file path', function () {
$job = new ReflectionClass(ApplicationDeploymentJob::class);
$method = $job->getMethod('validatePathField');
@@ -149,6 +171,18 @@ describe('API validation rules for path fields', function () {
});
});
test('dockerfile_location validation allows paths with @ for scoped packages', function () {
$rules = sharedDataApplications();
$validator = validator(
['dockerfile_location' => '/packages/@intlayer/mcp/Dockerfile'],
['dockerfile_location' => $rules['dockerfile_location']]
);
expect($validator->fails())->toBeFalse();
});
});
describe('sharedDataApplications rules survive array_merge in controller', function () {
test('docker_compose_location safe regex is not overridden by local rules', function () {
$sharedRules = sharedDataApplications();
@@ -164,7 +198,7 @@ describe('sharedDataApplications rules survive array_merge in controller', funct
// The merged rules for docker_compose_location should be the safe regex, not just 'string'
expect($merged['docker_compose_location'])->toBeArray();
expect($merged['docker_compose_location'])->toContain('regex:/^\/[a-zA-Z0-9._\-\/]+$/');
expect($merged['docker_compose_location'])->toContain('regex:'.\App\Support\ValidationPatterns::FILE_PATH_PATTERN);
});
});