diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index 3077658f..41149d7f 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -374,10 +374,22 @@ class ProjectController extends WebController $values['pubkey'] = $values['ssh_public_key']; $values['environments'] = $project->getEnvironments(); - if (Project::TYPE_GITLAB === $values['type']) { - $accessInfo = $project->getAccessInformation(); - $reference = $accessInfo["user"] . '@' . $accessInfo["domain"] . ':' . $accessInfo["port"] . '/' . ltrim($project->getReference(), '/') . ".git"; - $values['reference'] = $reference; + if (in_array($values['type'], [ + Project::TYPE_GITHUB, + Project::TYPE_GITLAB + ], true)) { + $originReference = $project->getAccessInformation('origin'); + if ($originReference) { + $values['reference'] = $originReference; + } else { + $accessInfo = $project->getAccessInformation(); + $reference = $accessInfo['user'] . '@' . $accessInfo['domain'] . ':' . ltrim($project->getReference(), '/') . '.git'; + if (isset($accessInfo['port']) && $accessInfo['port']) { + $reference = $accessInfo['user'] . '@' . $accessInfo['domain'] . ':' . $accessInfo['port'] . '/' . ltrim($project->getReference(), '/') . '.git'; + } + + $values['reference'] = $reference; + } } if ($method == 'POST') { @@ -535,7 +547,8 @@ class ProjectController extends WebController protected function getReferenceValidator($values) { return function ($val) use ($values) { - $type = $values['type']; + $type = $values['type']; + $gitRegex = '#^((https|http|ssh)://)?((.+)@)?(([^/:]+):?)(:?([0-9]*)/?)(.+)\.git#'; $validators = [ Project::TYPE_HG => [ @@ -543,19 +556,19 @@ class ProjectController extends WebController 'message' => Lang::get('error_hg') ], Project::TYPE_GIT => [ - 'regex' => '/^(git|https?):\/\//', + 'regex' => $gitRegex, 'message' => Lang::get('error_git') ], Project::TYPE_GITLAB => [ - 'regex' => '/^(git|https?):\/\//', + 'regex' => $gitRegex, 'message' => Lang::get('error_gitlab') ], Project::TYPE_GITHUB => [ - 'regex' => '/^(git|https?):\/\//', + 'regex' => $gitRegex, 'message' => Lang::get('error_github') ], Project::TYPE_BITBUCKET => [ - 'regex' => '/^[a-zA-Z0-9_\-]+\/[a-zA-Z0-9_\-\.]+$/', + 'regex' => $gitRegex, 'message' => Lang::get('error_bitbucket') ], Project::TYPE_BITBUCKET_HG => [ diff --git a/src/Model/Build/GitlabBuild.php b/src/Model/Build/GitlabBuild.php index f147102e..2bb8a571 100644 --- a/src/Model/Build/GitlabBuild.php +++ b/src/Model/Build/GitlabBuild.php @@ -49,8 +49,8 @@ class GitlabBuild extends GitBuild $key = trim($this->getProject()->getSshPrivateKey()); if (!empty($key)) { - $user = $this->getProject()->getAccessInformation("user"); - $domain = $this->getProject()->getAccessInformation("domain"); + $user = $this->getProject()->getAccessInformation('user'); + $domain = $this->getProject()->getAccessInformation('domain'); $port = $this->getProject()->getAccessInformation('port'); $url = $user . '@' . $domain . ':'; diff --git a/src/Service/ProjectService.php b/src/Service/ProjectService.php index 37274d11..9e84191b 100644 --- a/src/Service/ProjectService.php +++ b/src/Service/ProjectService.php @@ -143,7 +143,6 @@ class ProjectService */ protected function processAccessInformation(Project $project) { - $matches = []; $reference = $project->getReference(); if (in_array($project->getType(), [ @@ -152,12 +151,30 @@ class ProjectService ], true)) { $info = []; - if (preg_match('`^(.+)@(.+):([0-9]*)\/?(.+)\.git`', $reference, $matches)) { - $info['user'] = $matches[1]; - $info['domain'] = $matches[2]; - $info['port'] = $matches[3]; + if (preg_match( + '#^((https|http|ssh)://)?((.+)@)?(([^/:]+):?)(:?([0-9]*)/?)(.+)\.git#', + $reference, + $matches + )) { + if (isset($matches[4]) && $matches[4]) { + $info['user'] = $matches[4]; + } - $project->setReference($matches[4]); + if (isset($matches[6]) && $matches[6]) { + $info['domain'] = $matches[6]; + } + + if (isset($matches[8]) && $matches[8]) { + $info['port'] = $matches[8]; + } + + if (isset($matches[9]) && $matches[9]) { + $info['reference'] = $matches[9]; + + $project->setReference($matches[9]); + } + + $info['origin'] = $reference; } $project->setAccessInformation($info); diff --git a/tests/src/Service/ProjectServiceTest.php b/tests/src/Service/ProjectServiceTest.php index 4dd31ada..728715e2 100644 --- a/tests/src/Service/ProjectServiceTest.php +++ b/tests/src/Service/ProjectServiceTest.php @@ -25,25 +25,184 @@ class ProjectServiceTest extends \PHPUnit\Framework\TestCase public function setUp() { - $this->mockProjectStore = $this->getMockBuilder('PHPCensor\Store\ProjectStore')->getMock(); - $this->mockProjectStore->expects($this->any()) - ->method('save') - ->will($this->returnArgument(0)); + $this->mockProjectStore = $this + ->getMockBuilder('PHPCensor\Store\ProjectStore') + ->getMock(); + + $this->mockProjectStore + ->expects($this->any()) + ->method('save') + ->will( + $this->returnArgument(0) + ); $this->testedService = new ProjectService($this->mockProjectStore); } - public function testExecute_CreateBasicProject() + public function testExecuteCreateGithubProject() { - $returnValue = $this->testedService->createProject('Test Project', 'github', 'block8/phpci', 0); + $project = $this->testedService->createProject( + 'Test Project', + 'github', + 'php-censor/php-censor1', + 0 + ); - self::assertEquals('Test Project', $returnValue->getTitle()); - self::assertEquals('github', $returnValue->getType()); - self::assertEquals('block8/phpci', $returnValue->getReference()); - self::assertEquals('master', $returnValue->getBranch()); + self::assertEquals('Test Project', $project->getTitle()); + self::assertEquals('github', $project->getType()); + self::assertEquals('php-censor/php-censor1', $project->getReference()); + self::assertEquals('master', $project->getBranch()); + self::assertEquals([], $project->getAccessInformation()); } - public function testExecute_CreateProjectWithOptions() + /** + * @return array + */ + public function getExecuteCreateGithubProjectAccessInformationData() + { + return [ + [ + 'git@github.com:php-censor/php-censor.git', [ + 'user' => 'git', + 'domain' => 'github.com', + 'reference' => 'php-censor/php-censor', + 'origin' => 'git@github.com:php-censor/php-censor.git', + ], + ], [ + 'git@sss.github.com:php-censor/php-censor.git', [ + 'user' => 'git', + 'domain' => 'sss.github.com', + 'reference' => 'php-censor/php-censor', + 'origin' => 'git@sss.github.com:php-censor/php-censor.git', + ], + ], [ + 'ssh://git@github.com/php-censor/php-censor.git', [ + 'user' => 'git', + 'domain' => 'github.com', + 'reference' => 'php-censor/php-censor', + 'origin' => 'ssh://git@github.com/php-censor/php-censor.git', + ], + ], [ + 'https://github.com/php-censor/php-censor.git', [ + 'domain' => 'github.com', + 'reference' => 'php-censor/php-censor', + 'origin' => 'https://github.com/php-censor/php-censor.git', + ], + ], [ + 'http://github.com/php-censor/php-censor.git', [ + 'domain' => 'github.com', + 'reference' => 'php-censor/php-censor', + 'origin' => 'http://github.com/php-censor/php-censor.git', + ], + ], [ + 'git@github.com:443/php-censor/php-censor.git', [ + 'user' => 'git', + 'domain' => 'github.com', + 'port' => '443', + 'reference' => 'php-censor/php-censor', + 'origin' => 'git@github.com:443/php-censor/php-censor.git', + ], + ], [ + 'ssh://git@github.com:443/php-censor/php-censor.git', [ + 'user' => 'git', + 'domain' => 'github.com', + 'port' => '443', + 'reference' => 'php-censor/php-censor', + 'origin' => 'ssh://git@github.com:443/php-censor/php-censor.git', + ], + ], [ + 'https://github.com:443/php-censor/php-censor.git', [ + 'domain' => 'github.com', + 'port' => '443', + 'reference' => 'php-censor/php-censor', + 'origin' => 'https://github.com:443/php-censor/php-censor.git', + ], + ], [ + 'http://github.com:443/php-censor/php-censor.git', [ + 'domain' => 'github.com', + 'port' => '443', + 'reference' => 'php-censor/php-censor', + 'origin' => 'http://github.com:443/php-censor/php-censor.git', + ], + ], [ + 'git@github:php-censor.git', [ + 'user' => 'git', + 'domain' => 'github', + 'reference' => 'php-censor', + 'origin' => 'git@github:php-censor.git', + ], + ], [ + 'ssh://git@github/php-censor.git', [ + 'user' => 'git', + 'domain' => 'github', + 'reference' => 'php-censor', + 'origin' => 'ssh://git@github/php-censor.git', + ], + ], [ + 'https://github/php-censor.git', [ + 'domain' => 'github', + 'reference' => 'php-censor', + 'origin' => 'https://github/php-censor.git', + ], + ], [ + 'http://github/php-censor.git', [ + 'domain' => 'github', + 'reference' => 'php-censor', + 'origin' => 'http://github/php-censor.git', + ], + ], [ + 'git@github:443/php-censor.git', [ + 'user' => 'git', + 'domain' => 'github', + 'port' => '443', + 'reference' => 'php-censor', + 'origin' => 'git@github:443/php-censor.git', + ], + ], [ + 'ssh://git@github:443/php-censor.git', [ + 'user' => 'git', + 'domain' => 'github', + 'port' => '443', + 'reference' => 'php-censor', + 'origin' => 'ssh://git@github:443/php-censor.git', + ], + ], [ + 'https://github:443/php-censor.git', [ + 'domain' => 'github', + 'port' => '443', + 'reference' => 'php-censor', + 'origin' => 'https://github:443/php-censor.git', + ], + ], [ + 'http://github:443/php-censor.git', [ + 'domain' => 'github', + 'port' => '443', + 'reference' => 'php-censor', + 'origin' => 'http://github:443/php-censor.git', + ], + ], + ]; + } + + /** + * @param string $reference + * @param array $accessInformation + * + * @dataProvider getExecuteCreateGithubProjectAccessInformationData + */ + public function testExecuteCreateGithubProjectAccessInformation($reference, array $accessInformation) + { + $project = $this->testedService->createProject( + 'Test Project', + 'github', + $reference, + 0 + ); + + self::assertEquals($accessInformation, $project->getAccessInformation()); + } + + public function testExecuteCreateProjectWithOptions() { $options = [ 'ssh_private_key' => 'private', @@ -53,7 +212,13 @@ class ProjectServiceTest extends \PHPUnit\Framework\TestCase 'branch' => 'testbranch', ]; - $returnValue = $this->testedService->createProject('Test Project', 'github', 'block8/phpci', 0, $options); + $returnValue = $this->testedService->createProject( + 'Test Project', + 'github', + 'block8/phpci', + 0, + $options + ); self::assertEquals('private', $returnValue->getSshPrivateKey()); self::assertEquals('public', $returnValue->getSshPublicKey()); @@ -62,25 +227,7 @@ class ProjectServiceTest extends \PHPUnit\Framework\TestCase self::assertEquals(true, $returnValue->getAllowPublicStatus()); } - /** - * @link https://github.com/Block8/PHPCI/issues/484 - */ - public function testExecute_CreateGitlabProjectWithoutPort() - { - $reference = 'git@gitlab.block8.net:block8/phpci.git'; - $returnValue = $this->testedService->createProject( - 'Gitlab', - Project::TYPE_GITLAB, - $reference, - 0 - ); - - self::assertEquals('git', $returnValue->getAccessInformation('user')); - self::assertEquals('gitlab.block8.net', $returnValue->getAccessInformation('domain')); - self::assertEquals('block8/phpci', $returnValue->getReference()); - } - - public function testExecute_UpdateExistingProject() + public function testExecuteUpdateExistingProject() { $project = new Project(); $project->setTitle('Before Title'); @@ -94,7 +241,7 @@ class ProjectServiceTest extends \PHPUnit\Framework\TestCase self::assertEquals('bitbucket', $returnValue->getType()); } - public function testExecute_EmptyPublicStatus() + public function testExecuteEmptyPublicStatus() { $project = new Project(); $project->setAllowPublicStatus(true); @@ -110,7 +257,7 @@ class ProjectServiceTest extends \PHPUnit\Framework\TestCase self::assertEquals(false, $returnValue->getAllowPublicStatus()); } - public function testExecute_DeleteProject() + public function testExecuteDeleteProject() { $store = $this->getMockBuilder('PHPCensor\Store\ProjectStore')->getMock(); $store->expects($this->once())