Initial work on adding a Services layer to PHPCI, for better testability. Starting with Projects
This commit is contained in:
parent
11cce08be3
commit
9a7743e8d3
|
@ -20,6 +20,7 @@ use PHPCI\Helper\Github;
|
||||||
use PHPCI\Helper\SshKey;
|
use PHPCI\Helper\SshKey;
|
||||||
use PHPCI\Model\Build;
|
use PHPCI\Model\Build;
|
||||||
use PHPCI\Model\Project;
|
use PHPCI\Model\Project;
|
||||||
|
use PHPCI\Service\ProjectService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Project Controller - Allows users to create, edit and view projects.
|
* Project Controller - Allows users to create, edit and view projects.
|
||||||
|
@ -39,10 +40,16 @@ class ProjectController extends \PHPCI\Controller
|
||||||
*/
|
*/
|
||||||
protected $projectStore;
|
protected $projectStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \PHPCI\Service\ProjectService
|
||||||
|
*/
|
||||||
|
protected $projectService;
|
||||||
|
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
$this->buildStore = Store\Factory::getStore('Build');
|
$this->buildStore = Store\Factory::getStore('Build');
|
||||||
$this->projectStore = Store\Factory::getStore('Project');
|
$this->projectStore = Store\Factory::getStore('Project');
|
||||||
|
$this->projectService = new ProjectService($this->projectStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,35 +186,23 @@ class ProjectController extends \PHPCI\Controller
|
||||||
|
|
||||||
return $view->render();
|
return $view->render();
|
||||||
} else {
|
} else {
|
||||||
return $this->addProject($form);
|
$title = $this->getParam('title', 'New Project');
|
||||||
|
$reference = $this->getParam('reference', null);
|
||||||
|
$type = $this->getParam('type', null);
|
||||||
|
|
||||||
|
$options = array(
|
||||||
|
'ssh_private_key' => $this->getParam('key', null),
|
||||||
|
'ssh_public_key' => $this->getParam('pubkey', null),
|
||||||
|
'build_config' => $this->getParam('build_config', null),
|
||||||
|
'allow_public_status' => $this->getParam('allow_public_status', 0),
|
||||||
|
);
|
||||||
|
|
||||||
|
$project = $this->projectService->createProject($title, $reference, $type, $options);
|
||||||
|
header('Location: '.PHPCI_URL.'project/view/' . $project->getId());
|
||||||
|
die;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addProject(Form $form)
|
|
||||||
{
|
|
||||||
$values = $form->getValues();
|
|
||||||
|
|
||||||
$matches = array();
|
|
||||||
if ($values['type'] == "gitlab" && preg_match('`^(.*)@(.*):(.*)/(.*)\.git`', $values['reference'], $matches)) {
|
|
||||||
$info = array();
|
|
||||||
$info['user'] = $matches[1];
|
|
||||||
$info['domain'] = $matches[2];
|
|
||||||
$values['access_information'] = serialize($info);
|
|
||||||
$values['reference'] = $matches[3]."/".$matches[4];
|
|
||||||
}
|
|
||||||
|
|
||||||
$values['ssh_private_key'] = $values['key'];
|
|
||||||
$values['ssh_public_key'] = $values['pubkey'];
|
|
||||||
|
|
||||||
$project = new Project();
|
|
||||||
$project->setValues($values);
|
|
||||||
|
|
||||||
$project = $this->projectStore->save($project);
|
|
||||||
|
|
||||||
header('Location: '.PHPCI_URL.'project/view/' . $project->getId());
|
|
||||||
die;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit a project. Handles both the form and processing.
|
* Edit a project. Handles both the form and processing.
|
||||||
*/
|
*/
|
||||||
|
|
105
PHPCI/Service/ProjectService.php
Normal file
105
PHPCI/Service/ProjectService.php
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2014, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link https://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCI\Service;
|
||||||
|
|
||||||
|
use PHPCI\Model\Project;
|
||||||
|
use PHPCI\Store\ProjectStore;
|
||||||
|
|
||||||
|
class ProjectService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \PHPCI\Store\ProjectStore
|
||||||
|
*/
|
||||||
|
protected $projectStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ProjectStore $projectStore
|
||||||
|
*/
|
||||||
|
public function __construct(ProjectStore $projectStore)
|
||||||
|
{
|
||||||
|
$this->projectStore = $projectStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new project model and use the project store to save it.
|
||||||
|
* @param string $title
|
||||||
|
* @param string $type
|
||||||
|
* @param string $reference
|
||||||
|
* @param array $options
|
||||||
|
* @return \PHPCI\Model\Project
|
||||||
|
*/
|
||||||
|
public function createProject($title, $type, $reference, $options = array())
|
||||||
|
{
|
||||||
|
// Create base project and use updateProject() to set its properties:
|
||||||
|
$project = new Project();
|
||||||
|
return $this->updateProject($project, $title, $type, $reference, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the properties of a given project.
|
||||||
|
* @param Project $project
|
||||||
|
* @param string $title
|
||||||
|
* @param string $type
|
||||||
|
* @param string $reference
|
||||||
|
* @param array $options
|
||||||
|
* @return \PHPCI\Model\Project
|
||||||
|
*/
|
||||||
|
public function updateProject(Project $project, $title, $type, $reference, $options = array())
|
||||||
|
{
|
||||||
|
// Set basic properties:
|
||||||
|
$project->setTitle($title);
|
||||||
|
$project->setType($type);
|
||||||
|
$project->setReference($reference);
|
||||||
|
|
||||||
|
// Handle extra project options:
|
||||||
|
if (array_key_exists('ssh_private_key', $options)) {
|
||||||
|
$project->setSshPrivateKey($options['ssh_private_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('ssh_public_key', $options)) {
|
||||||
|
$project->setSshPublicKey($options['ssh_public_key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('build_config', $options)) {
|
||||||
|
$project->setBuildConfig($options['build_config']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('allow_public_status', $options)) {
|
||||||
|
$project->setAllowPublicStatus((int)$options['allow_public_status']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow certain project types to set access information:
|
||||||
|
$this->processAccessInformation($project);
|
||||||
|
|
||||||
|
// Save and return the project:
|
||||||
|
return $this->projectStore->save($project);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In circumstances where it is necessary, populate access information based on other project properties.
|
||||||
|
* @see ProjectService::createProject()
|
||||||
|
* @param Project $project
|
||||||
|
*/
|
||||||
|
protected function processAccessInformation(Project &$project)
|
||||||
|
{
|
||||||
|
$matches = array();
|
||||||
|
$reference = $project->getReference();
|
||||||
|
|
||||||
|
if ($project->getType() == 'gitlab' && preg_match('`^(.*)@(.*):(.*)/(.*)\.git`', $reference, $matches)) {
|
||||||
|
$info = array();
|
||||||
|
$info['user'] = $matches[1];
|
||||||
|
$info['domain'] = $matches[2];
|
||||||
|
|
||||||
|
/** @todo At a later date, we need to find a way to replace this serialized data with JSON */
|
||||||
|
$project->setAccessInformation(serialize($info));
|
||||||
|
$project->setReference($matches[3] . '/' . $matches[4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
Tests/PHPCI/Service/MockProjectStore.php
Normal file
15
Tests/PHPCI/Service/MockProjectStore.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\PHPCI\Service;
|
||||||
|
|
||||||
|
use b8\Model;
|
||||||
|
use PHPCI\Store\ProjectStore;
|
||||||
|
|
||||||
|
class MockProjectStore extends ProjectStore
|
||||||
|
{
|
||||||
|
public function save(Model $project)
|
||||||
|
{
|
||||||
|
$project->setId(1);
|
||||||
|
return $project;
|
||||||
|
}
|
||||||
|
}
|
101
Tests/PHPCI/Service/ProjectServiceTest.php
Normal file
101
Tests/PHPCI/Service/ProjectServiceTest.php
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* PHPCI - Continuous Integration for PHP
|
||||||
|
*
|
||||||
|
* @copyright Copyright 2014, Block 8 Limited.
|
||||||
|
* @license https://github.com/Block8/PHPCI/blob/master/LICENSE.md
|
||||||
|
* @link http://www.phptesting.org/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PHPCI\Service\Tests;
|
||||||
|
|
||||||
|
use PHPCI\Model\Project;
|
||||||
|
use PHPCI\Service\ProjectService;
|
||||||
|
use Tests\PHPCI\Service\MockProjectStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for the ProjectService class.
|
||||||
|
* @author Dan Cryer <dan@block8.co.uk>
|
||||||
|
*/
|
||||||
|
class ProjectServiceTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ProjectService $testedService
|
||||||
|
*/
|
||||||
|
protected $testedService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \ $mockProjectStore
|
||||||
|
*/
|
||||||
|
protected $mockProjectStore;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->mockProjectStore = new MockProjectStore();
|
||||||
|
$this->testedService = new ProjectService($this->mockProjectStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers PHPUnit::execute
|
||||||
|
*/
|
||||||
|
public function testExecute_CreateBasicProject()
|
||||||
|
{
|
||||||
|
$returnValue = $this->testedService->createProject('Test Project', 'github', 'block8/phpci');
|
||||||
|
|
||||||
|
$this->assertEquals('Test Project', $returnValue->getTitle());
|
||||||
|
$this->assertEquals('github', $returnValue->getType());
|
||||||
|
$this->assertEquals('block8/phpci', $returnValue->getReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers PHPUnit::execute
|
||||||
|
*/
|
||||||
|
public function testExecute_CreateProjectWithOptions()
|
||||||
|
{
|
||||||
|
$options = array(
|
||||||
|
'ssh_private_key' => 'private',
|
||||||
|
'ssh_public_key' => 'public',
|
||||||
|
'allow_public_status' => 1,
|
||||||
|
'build_config' => 'config',
|
||||||
|
);
|
||||||
|
|
||||||
|
$returnValue = $this->testedService->createProject('Test Project', 'github', 'block8/phpci', $options);
|
||||||
|
|
||||||
|
$this->assertEquals('private', $returnValue->getSshPrivateKey());
|
||||||
|
$this->assertEquals('public', $returnValue->getSshPublicKey());
|
||||||
|
$this->assertEquals('config', $returnValue->getBuildConfig());
|
||||||
|
$this->assertEquals(1, $returnValue->getAllowPublicStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @link https://github.com/Block8/PHPCI/issues/484
|
||||||
|
* @covers PHPUnit::execute
|
||||||
|
*/
|
||||||
|
public function testExecute_CreateGitlabProjectWithoutPort()
|
||||||
|
{
|
||||||
|
$reference = 'git@gitlab.block8.net:block8/phpci.git';
|
||||||
|
$returnValue = $this->testedService->createProject('Gitlab', 'gitlab', $reference);
|
||||||
|
|
||||||
|
$this->assertEquals('git', $returnValue->getAccessInformation('user'));
|
||||||
|
$this->assertEquals('gitlab.block8.net', $returnValue->getAccessInformation('domain'));
|
||||||
|
$this->assertEquals('block8/phpci', $returnValue->getReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers PHPUnit::execute
|
||||||
|
*/
|
||||||
|
public function testExecute_UpdateExistingProject()
|
||||||
|
{
|
||||||
|
$project = new Project();
|
||||||
|
$project->setTitle('Before Title');
|
||||||
|
$project->setReference('Before Reference');
|
||||||
|
$project->setType('github');
|
||||||
|
|
||||||
|
$returnValue = $this->testedService->updateProject($project, 'After Title', 'bitbucket', 'After Reference');
|
||||||
|
|
||||||
|
$this->assertEquals('After Title', $returnValue->getTitle());
|
||||||
|
$this->assertEquals('After Reference', $returnValue->getReference());
|
||||||
|
$this->assertEquals('bitbucket', $returnValue->getType());
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,5 +20,8 @@
|
||||||
<testsuite name="PHPCI Plugin Test Suite">
|
<testsuite name="PHPCI Plugin Test Suite">
|
||||||
<directory suffix="Test.php">./Tests/PHPCI/Plugin</directory>
|
<directory suffix="Test.php">./Tests/PHPCI/Plugin</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
<testsuite name="PHPCI Service Test Suite">
|
||||||
|
<directory suffix="Test.php">./Tests/PHPCI/Service</directory>
|
||||||
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
Loading…
Reference in a new issue