diff --git a/.php-censor.yml b/.php-censor.yml index c927f4de..a08ed6fd 100644 --- a/.php-censor.yml +++ b/.php-censor.yml @@ -11,7 +11,7 @@ setup: test: php_unit: config: - - phpunit.pgsql.xml + - phpunit.xml php_mess_detector: allow_failures: true diff --git a/.travis.yml b/.travis.yml index 80bf4f4b..34fc0f3d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,20 +15,16 @@ php: matrix: fast_finish: true -env: - - TYPE=mysql - - TYPE=pgsql - install: - composer selfupdate - composer install before_script: - - if [[ "$TYPE" == "mysql" ]]; then mysql -e "create database IF NOT EXISTS b8_test;" -uroot; fi - - if [[ "$TYPE" == "pgsql" ]]; then psql -c 'create database b8_test;' -U postgres; fi + - mysql -e "create database IF NOT EXISTS b8_test;" -uroot + - psql -c 'create database b8_test;' -U postgres script: - - vendor/bin/phpunit --configuration phpunit.$TYPE.xml --coverage-clover=coverage.xml + - vendor/bin/phpunit --configuration phpunit.xml --coverage-clover=coverage.xml after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/bootstrap.php b/bootstrap.php index a74f2dfd..628eb8de 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,27 +1,27 @@ =5.6.0", - "ext-openssl": "*", - "ext-pdo": "*", - "ext-json": "*", - "ext-xml": "*", - "ext-curl": "*", - - "swiftmailer/swiftmailer": "~5.4.0", - "symfony/yaml": "~3.4.0", - "symfony/console": "~3.4.0", - "symfony/finder": "~3.4.0", - "symfony/dom-crawler": "~3.4.0", - "symfony/css-selector": "~3.4.0", - "symfony/browser-kit": "~3.4.0", - "symfony/process": "~3.4.0", - "symfony/filesystem": "~3.4.0", - "symfony/debug": "~3.4.0", - "symfony/dependency-injection": "~3.4.0", - "symfony/event-dispatcher": "~3.4.0", - "symfony/cache": "~3.4.0", - "psr/log": "~1.0.0", - "monolog/monolog": "~1.22.0", - "pimple/pimple": "~3.0.0", - "robmorgan/phinx": "~0.8.0", - "sensiolabs/ansi-to-html": "~1.1.0", - "pda/pheanstalk": "~3.1.0", - "guzzlehttp/guzzle": "~6.2.0", - "jasongrimes/paginator": "~1.0.0", - - "phpunit/phpunit": "~5.7.0", - "codeception/codeception": "~2.3.0", - "phpmd/phpmd": "~2.6.0", - "sebastian/phpcpd": "~2.0.0", - "squizlabs/php_codesniffer": "~2.8.0", - "block8/php-docblock-checker": "~1.3.0", - "phploc/phploc": "~4.0.0", - "jakub-onderka/php-parallel-lint": "~0.9.0", - "sensiolabs/security-checker": "~4.0.0", - - "doctrine/instantiator": "~1.0.0", - "phpunit/php-token-stream": "~1.4.0", - "phpdocumentor/reflection-docblock": "~2.0.0", - - "oomphinc/composer-installers-extender": "~1.1.0", - - "npm-asset/sprintf-js": "~1.0.0", - "npm-asset/codemirror": "~5.23.0", - "bower-asset/admin-lte": "~2.3.0", - "bower-asset/font-awesome": "~4.7.0", - "bower-asset/ionicons": "~2.0.0", - "bower-asset/raphael": "~2.2.0" - }, - "suggest": { - "maknz/slack": "For SlackNotify plugin", - "hipchat/hipchat-php": "For HipchatNotify plugin", - "mremi/flowdock": "For FlowdockNotify plugin" - }, - "extra": { - "platform": { - "php": "5.6.*" - }, - "installer-types": [ - "bower-asset", - "npm-asset" + "name": "php-censor/php-censor", + "description": "PHP Censor is a open source self-hosted continuous integration server for PHP projects (PHPCI fork).", + "minimum-stability": "stable", + "type": "application", + "keywords": [ + "php", + "php-censor", + "phpci", + "ci-server", + "testing", + "self-hosted", + "open-source", + "ci", + "continuous integration" ], - "installer-paths": { - "public/assets/vendor/{$name}/": ["type:bower-asset", "type:npm-asset"] - } - }, - "repositories": [ - { - "type": "composer", - "url": "https://asset-packagist.org" - } - ] + "homepage": "http://php-censor.info", + "license": "BSD-2-Clause", + "authors": [ + { + "name": "Dmitry Khomutov", + "email": "poisoncorpsee@gmail.com", + "homepage": "http://corpsee.com", + "role": "PHP Censor developer" + }, + { + "name": "Dan Cryer", + "email": "dan.cryer@block8.co.uk", + "homepage": "http://www.block8.co.uk", + "role": "PHPCI developer" + } + ], + "support": { + "issues": "https://github.com/php-censor/php-censor/issues", + "source": "https://github.com/php-censor/php-censor" + }, + "autoload": { + "psr-4": { + "PHPCensor\\": "src/PHPCensor/", + "b8\\": "src/B8Framework/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\PHPCensor\\": "tests/PHPCensor/", + "Tests\\b8\\": "tests/B8Framework/" + } + }, + "require": { + "php": ">=5.6.0", + "ext-openssl": "*", + "ext-pdo": "*", + "ext-json": "*", + "ext-xml": "*", + "ext-curl": "*", + + "swiftmailer/swiftmailer": "~5.4.0", + "symfony/yaml": "~3.4.0", + "symfony/console": "~3.4.0", + "symfony/finder": "~3.4.0", + "symfony/dom-crawler": "~3.4.0", + "symfony/css-selector": "~3.4.0", + "symfony/browser-kit": "~3.4.0", + "symfony/process": "~3.4.0", + "symfony/filesystem": "~3.4.0", + "symfony/debug": "~3.4.0", + "symfony/dependency-injection": "~3.4.0", + "symfony/event-dispatcher": "~3.4.0", + "symfony/cache": "~3.4.0", + "psr/log": "~1.0.0", + "monolog/monolog": "~1.22.0", + "pimple/pimple": "~3.0.0", + "robmorgan/phinx": "~0.8.0", + "sensiolabs/ansi-to-html": "~1.1.0", + "pda/pheanstalk": "~3.1.0", + "guzzlehttp/guzzle": "~6.2.0", + "jasongrimes/paginator": "~1.0.0", + "phpunit/phpunit": "~5.7.0", + "codeception/codeception": "~2.3.0", + "phpmd/phpmd": "~2.6.0", + "sebastian/phpcpd": "~2.0.0", + "squizlabs/php_codesniffer": "~2.8.0", + "block8/php-docblock-checker": "~1.3.0", + "phploc/phploc": "~4.0.0", + "jakub-onderka/php-parallel-lint": "~0.9.0", + "sensiolabs/security-checker": "~4.0.0", + + "doctrine/instantiator": "~1.0.0", + "phpunit/php-token-stream": "~1.4.0", + "phpdocumentor/reflection-docblock": "~2.0.0", + + "oomphinc/composer-installers-extender": "~1.1.0", + + "npm-asset/sprintf-js": "~1.0.0", + "npm-asset/codemirror": "~5.23.0", + "bower-asset/admin-lte": "~2.3.0", + "bower-asset/font-awesome": "~4.7.0", + "bower-asset/ionicons": "~2.0.0", + "bower-asset/raphael": "~2.2.0" + }, + "require-dev": { + "phpunit/dbunit": "~2.0.0" + }, + "suggest": { + "maknz/slack": "For SlackNotify plugin", + "hipchat/hipchat-php": "For HipchatNotify plugin", + "mremi/flowdock": "For FlowdockNotify plugin" + }, + "extra": { + "platform": { + "php": "5.6.*" + }, + "installer-types": [ + "bower-asset", + "npm-asset" + ], + "installer-paths": { + "public/assets/vendor/{$name}/": [ + "type:bower-asset", + "type:npm-asset" + ] + } + }, + "repositories": [ + { + "type": "composer", + "url": "https://asset-packagist.org" + } + ] } diff --git a/composer.lock b/composer.lock index b910c90e..6999424c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "e04dd5f7a7f3a869724c591daf5d8f2e", + "content-hash": "86960b0e8aee816f39921ca1c3e6bfc3", "packages": [ { "name": "behat/gherkin", @@ -220,16 +220,16 @@ }, { "name": "codeception/codeception", - "version": "2.3.8", + "version": "2.3.9", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "43eade17a8cd68e9cde401e8585b09d11d41b12d" + "reference": "104f46fa0bde339f1bcc3a375aac21eb36e65a1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/43eade17a8cd68e9cde401e8585b09d11d41b12d", - "reference": "43eade17a8cd68e9cde401e8585b09d11d41b12d", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/104f46fa0bde339f1bcc3a375aac21eb36e65a1e", + "reference": "104f46fa0bde339f1bcc3a375aac21eb36e65a1e", "shasum": "" }, "require": { @@ -310,7 +310,7 @@ "functional testing", "unit testing" ], - "time": "2018-01-27T22:47:33+00:00" + "time": "2018-02-26T23:29:41+00:00" }, { "name": "codeception/stub", @@ -3945,7 +3945,63 @@ "time": "2017-06-30T11:53:12+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "phpunit/dbunit", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/dbunit.git", + "reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/dbunit/zipball/5c35d74549c21ba55d0ea74ba89d191a51f8cf25", + "reference": "5c35d74549c21ba55d0ea74ba89d191a51f8cf25", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "ext-simplexml": "*", + "php": "^5.4 || ^7.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0", + "symfony/yaml": "^2.1 || ^3.0" + }, + "bin": [ + "dbunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "DbUnit port for PHP/PHPUnit to support database interaction testing.", + "homepage": "https://github.com/sebastianbergmann/dbunit/", + "keywords": [ + "database", + "testing", + "xunit" + ], + "time": "2016-12-02T14:39:14+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/phpunit.pgsql.xml b/phpunit.pgsql.xml deleted file mode 100644 index 3eab7c62..00000000 --- a/phpunit.pgsql.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - ./tests/B8Framework - - - - ./tests/PHPCensor/Helper - - - ./tests/PHPCensor/Controller - - - ./tests/PHPCensor/Logging - - - ./tests/PHPCensor/Model - - - ./tests/PHPCensor/Plugin - - - ./tests/PHPCensor/Service - - - ./tests/PHPCensor/Command - - - ./tests/PHPCensor/ProcessControl - - - ./tests/PHPCensor/Security - - - - - ./src - - ./src/PHPCensor/Migrations - ./src/PHPCensor/Languages - - - - diff --git a/phpunit.mysql.xml b/phpunit.xml similarity index 87% rename from phpunit.mysql.xml rename to phpunit.xml index 74bdde60..bb92ca16 100644 --- a/phpunit.mysql.xml +++ b/phpunit.xml @@ -12,10 +12,12 @@ bootstrap="./tests/bootstrap.php" > - - - - + + + + + + diff --git a/src/B8Framework/Database.php b/src/B8Framework/Database.php index 15cda019..b8a50d8a 100644 --- a/src/B8Framework/Database.php +++ b/src/B8Framework/Database.php @@ -4,11 +4,44 @@ namespace b8; class Database extends \PDO { + const MYSQL_TYPE = 'mysql'; + const POSTGRESQL_TYPE = 'pgsql'; + + /** + * @var string + */ + protected $type = 'read'; + + /** + * @var boolean + */ protected static $initialised = false; - protected static $servers = ['read' => [], 'write' => []]; - protected static $connections = ['read' => null, 'write' => null]; - protected static $details = []; - protected static $lastUsed = ['read' => null, 'write' => null]; + + /** + * @var array + */ + protected static $servers = [ + 'read' => [], + 'write' => [] + ]; + + /** + * @var array + */ + protected static $connections = [ + 'read' => null, + 'write' => null + ]; + + /** + * @var array + */ + protected static $dsn = [ + 'read' => '', + 'write' => '' + ]; + + protected static $details = []; /** * @param string $table @@ -17,7 +50,7 @@ class Database extends \PDO */ public function lastInsertIdExtended($table = null) { - if ($table && $this->getAttribute(self::ATTR_DRIVER_NAME) == 'pgsql') { + if ($table && self::POSTGRESQL_TYPE === $this->getAttribute(self::ATTR_DRIVER_NAME)) { return parent::lastInsertId($table . '_id_seq'); } @@ -31,10 +64,11 @@ class Database extends \PDO self::$servers['read'] = $settings['servers']['read']; self::$servers['write'] = $settings['servers']['write']; - self::$details['type'] = $settings['type']; - self::$details['db'] = $settings['name']; - self::$details['user'] = $settings['username']; - self::$details['pass'] = $settings['password']; + + self::$details['driver'] = $settings['type']; + self::$details['db'] = $settings['name']; + self::$details['user'] = $settings['username']; + self::$details['pass'] = $settings['password']; self::$initialised = true; } @@ -52,11 +86,6 @@ class Database extends \PDO self::init(); } - // If the connection hasn't been used for 5 minutes, force a reconnection: - if (!is_null(self::$lastUsed[$type]) && (time() - self::$lastUsed[$type]) > 300) { - self::$connections[$type] = null; - } - if (is_null(self::$connections[$type])) { // Shuffle, so we pick a random server: $servers = self::$servers[$type]; @@ -69,29 +98,30 @@ class Database extends \PDO // Pull the next server: $server = array_shift($servers); - $dns = self::$details['type'] . ':host=' . $server['host']; + self::$dsn[$type] = self::$details['driver'] . ':host=' . $server['host']; if (isset($server['port'])) { - $dns .= ';port=' . (integer)$server['port']; + self::$dsn[$type] .= ';port=' . (integer)$server['port']; } - $dns .= ';dbname=' . self::$details['db']; + self::$dsn[$type] .= ';dbname=' . self::$details['db']; $pdoOptions = [ - \PDO::ATTR_PERSISTENT => false, - \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, - \PDO::ATTR_TIMEOUT => 2, + \PDO::ATTR_PERSISTENT => false, + \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, + \PDO::ATTR_TIMEOUT => 2, ]; - if ('mysql' === self::$details['type']) { + if (self::MYSQL_TYPE === self::$details['driver']) { $pdoOptions[\PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES 'UTF8'"; } // Try to connect: try { $connection = new self( - $dns, + self::$dsn[$type], self::$details['user'], self::$details['pass'], $pdoOptions ); + $connection->setType($type); } catch (\PDOException $ex) { $connection = false; } @@ -103,41 +133,71 @@ class Database extends \PDO } // No connection? Oh dear. - if (!$connection && $type == 'read') { + if (!$connection && $type === 'read') { throw new \Exception('Could not connect to any ' . $type . ' servers.'); } self::$connections[$type] = $connection; } - self::$lastUsed[$type] = time(); - return self::$connections[$type]; } + /** + * @return array + */ public function getDetails() { return self::$details; } + /** + * @return string + */ + public function getDsn() + { + return self::$dsn[$this->type]; + } + + /** + * @param string $type + */ + public function setType($type) + { + $this->type = $type; + } + public static function reset() { self::$connections = ['read' => null, 'write' => null]; - self::$lastUsed = ['read' => null, 'write' => null]; self::$initialised = false; } - public function prepareCommon($statement, array $driver_options = []) + /** + * @param string $statement + * + * @return string + */ + protected function quoteNames($statement) { $quote = ''; - if ('mysql' === self::$details['type']) { + if (self::MYSQL_TYPE === self::$details['driver']) { $quote = '`'; - } elseif ('pgsql' === self::$details['type']) { + } elseif (self::POSTGRESQL_TYPE === self::$details['driver']) { $quote = '"'; } - $statement = preg_replace('/{{(.*?)}}/', ($quote . '\1' . $quote), $statement); + return preg_replace('/{{(.*?)}}/', ($quote . '\1' . $quote), $statement); + } - return parent::prepare($statement, $driver_options); + /** + * @param string $statement + * @param array $driver_options + * + * @return \PDOStatement + */ + public function prepareCommon($statement, array $driver_options = []) + { + return parent::prepare($this->quoteNames($statement), $driver_options); } } diff --git a/src/B8Framework/Model.php b/src/B8Framework/Model.php index a269c346..7c0784ca 100644 --- a/src/B8Framework/Model.php +++ b/src/B8Framework/Model.php @@ -7,7 +7,6 @@ use Symfony\Component\Cache\Simple\ArrayCache; class Model { - public static $sleepable = []; protected $getters = []; protected $setters = []; protected $data = []; @@ -35,82 +34,6 @@ class Model return $this->tableName; } - /** - * @param integer $depth - * @param integer $currentDepth - * - * @return array - */ - public function toArray($depth = 2, $currentDepth = 0) - { - if (isset(static::$sleepable) && is_array(static::$sleepable) && count(static::$sleepable)) { - $sleepable = static::$sleepable; - } else { - $sleepable = array_keys($this->getters); - } - - $rtn = []; - foreach ($sleepable as $property) { - $rtn[$property] = $this->propertyToArray($property, $currentDepth, $depth); - } - - return $rtn; - } - - /** - * @param string $property - * @param integer $currentDepth - * @param integer $depth - * - * @return mixed - */ - protected function propertyToArray($property, $currentDepth, $depth) - { - $rtn = null; - - if (array_key_exists($property, $this->getters)) { - $method = $this->getters[$property]; - $rtn = $this->{$method}(); - - if (is_object($rtn) || is_array($rtn)) { - $rtn = ($depth > $currentDepth) ? $this->valueToArray($rtn, $currentDepth, $depth) : null; - } - } - - return $rtn; - } - - /** - * @param mixed $value - * @param integer $currentDepth - * @param integer $depth - * - * @return mixed - */ - protected function valueToArray($value, $currentDepth, $depth) - { - $rtn = null; - if (!is_null($value)) { - if (is_object($value) && method_exists($value, 'toArray')) { - $rtn = $value->toArray($depth, $currentDepth + 1); - } elseif (is_array($value)) { - $childArray = []; - - foreach ($value as $k => $v) { - $childArray[$k] = $this->valueToArray($v, $currentDepth + 1, $depth); - } - - $rtn = $childArray; - } else { - $rtn = (is_string($value) && !mb_check_encoding($value, 'UTF-8')) - ? mb_convert_encoding($value, 'UTF-8') - : $value; - } - } - - return $rtn; - } - /** * @return array */ diff --git a/src/PHPCensor/BuildFactory.php b/src/PHPCensor/BuildFactory.php index 95690732..a2ef1af3 100644 --- a/src/PHPCensor/BuildFactory.php +++ b/src/PHPCensor/BuildFactory.php @@ -7,7 +7,7 @@ use PHPCensor\Model\Build; /** * BuildFactory - Takes in a generic "Build" and returns a type-specific build model. - * + * * @author Dan Cryer */ class BuildFactory @@ -43,33 +43,33 @@ class BuildFactory if (!empty($project)) { switch ($project->getType()) { - case 'remote': - $type = 'RemoteGitBuild'; - break; case 'local': $type = 'LocalBuild'; break; + case 'git': + $type = 'GitBuild'; + break; case 'github': $type = 'GithubBuild'; break; case 'bitbucket': $type = 'BitbucketBuild'; break; - case 'bitbuckethg': - $type = 'BitbucketHgBuild'; - break; case 'gitlab': $type = 'GitlabBuild'; break; - case 'hg': - $type = 'MercurialBuild'; - break; - case 'svn': - $type = 'SubversionBuild'; - break; case 'gogs': $type = 'GogsBuild'; break; + case 'hg': + $type = 'HgBuild'; + break; + case 'bitbucket-hg': + $type = 'BitbucketHgBuild'; + break; + case 'svn': + $type = 'SvnBuild'; + break; default: return $build; } diff --git a/src/PHPCensor/Controller/BuildController.php b/src/PHPCensor/Controller/BuildController.php index 29382310..936c13dc 100644 --- a/src/PHPCensor/Controller/BuildController.php +++ b/src/PHPCensor/Controller/BuildController.php @@ -300,18 +300,14 @@ class BuildController extends Controller */ protected function formatBuilds($builds) { - Project::$sleepable = ['id', 'title', 'reference', 'type']; - $rtn = ['count' => $builds['count'], 'items' => []]; + /** @var Build $build */ foreach ($builds['items'] as $build) { - $item = $build->toArray(1); - - $header = new View('Build/header-row'); + $header = new View('Build/header-row'); $header->build = $build; - $item['header_row'] = $header->render(); - $rtn['items'][$item['id']] = $item; + $rtn['items'][$build->getId()]['header_row'] = $header->render(); } ksort($rtn['items']); diff --git a/src/PHPCensor/Migrations/20180228024622_renamed_build_types.php b/src/PHPCensor/Migrations/20180228024622_renamed_build_types.php new file mode 100644 index 00000000..4cd2255f --- /dev/null +++ b/src/PHPCensor/Migrations/20180228024622_renamed_build_types.php @@ -0,0 +1,18 @@ +execute("UPDATE project SET type = 'git' WHERE type = 'remote'"); + $this->execute("UPDATE project SET type = 'bitbucket-hg' WHERE type = 'bitbuckethg'"); + } + + public function down() + { + $this->execute("UPDATE project SET type = 'remote' WHERE type = 'git'"); + $this->execute("UPDATE project SET type = 'bitbuckethg' WHERE type = 'bitbucket-hg'"); + } +} diff --git a/src/PHPCensor/Model/Build.php b/src/PHPCensor/Model/Build.php index bcdf56fc..2a40d684 100644 --- a/src/PHPCensor/Model/Build.php +++ b/src/PHPCensor/Model/Build.php @@ -34,21 +34,11 @@ class Build extends Model const SOURCE_WEBHOOK = 4; const SOURCE_WEBHOOK_PULL_REQUEST = 5; - /** - * @var array - */ - public static $sleepable = []; - /** * @var string */ protected $tableName = 'build'; - /** - * @var string - */ - protected $modelName = 'Build'; - /** * @var integer */ diff --git a/src/PHPCensor/Model/Build/BitbucketBuild.php b/src/PHPCensor/Model/Build/BitbucketBuild.php index 2e84802f..3b29d38d 100644 --- a/src/PHPCensor/Model/Build/BitbucketBuild.php +++ b/src/PHPCensor/Model/Build/BitbucketBuild.php @@ -15,7 +15,7 @@ use PHPCensor\Model\BuildError; * * @author Dan Cryer */ -class BitbucketBuild extends RemoteGitBuild +class BitbucketBuild extends GitBuild { /** * Get link to commit from another source (i.e. BitBucket) diff --git a/src/PHPCensor/Model/Build/BitbucketHgBuild.php b/src/PHPCensor/Model/Build/BitbucketHgBuild.php index 6be40937..574abf61 100644 --- a/src/PHPCensor/Model/Build/BitbucketHgBuild.php +++ b/src/PHPCensor/Model/Build/BitbucketHgBuild.php @@ -9,7 +9,7 @@ use PHPCensor\Model\Build; * * @author Artem Bochkov */ -class BitbucketHgBuild extends MercurialBuild +class BitbucketHgBuild extends HgBuild { /** * Get link to commit from another source (i.e. BitBucket) diff --git a/src/PHPCensor/Model/Build/RemoteGitBuild.php b/src/PHPCensor/Model/Build/GitBuild.php similarity index 99% rename from src/PHPCensor/Model/Build/RemoteGitBuild.php rename to src/PHPCensor/Model/Build/GitBuild.php index 49753393..40ecf59c 100644 --- a/src/PHPCensor/Model/Build/RemoteGitBuild.php +++ b/src/PHPCensor/Model/Build/GitBuild.php @@ -11,7 +11,7 @@ use Psr\Log\LogLevel; * * @author Dan Cryer */ -class RemoteGitBuild extends Build +class GitBuild extends Build { /** * Get the URL to be used to clone this remote repository. diff --git a/src/PHPCensor/Model/Build/GithubBuild.php b/src/PHPCensor/Model/Build/GithubBuild.php index be2b5d31..b3968b93 100644 --- a/src/PHPCensor/Model/Build/GithubBuild.php +++ b/src/PHPCensor/Model/Build/GithubBuild.php @@ -15,7 +15,7 @@ use PHPCensor\Model\BuildError; * * @author Dan Cryer */ -class GithubBuild extends RemoteGitBuild +class GithubBuild extends GitBuild { /** * Get link to commit from another source (i.e. Github) diff --git a/src/PHPCensor/Model/Build/GitlabBuild.php b/src/PHPCensor/Model/Build/GitlabBuild.php index 35525b37..ad5a30b9 100644 --- a/src/PHPCensor/Model/Build/GitlabBuild.php +++ b/src/PHPCensor/Model/Build/GitlabBuild.php @@ -4,10 +4,10 @@ namespace PHPCensor\Model\Build; /** * Gitlab Build Model - * + * * @author André Cianfarani */ -class GitlabBuild extends RemoteGitBuild +class GitlabBuild extends GitBuild { /** diff --git a/src/PHPCensor/Model/Build/GogsBuild.php b/src/PHPCensor/Model/Build/GogsBuild.php index cab9ad54..9f5d95e6 100644 --- a/src/PHPCensor/Model/Build/GogsBuild.php +++ b/src/PHPCensor/Model/Build/GogsBuild.php @@ -5,7 +5,7 @@ namespace PHPCensor\Model\Build; /** * GogsBuild Build Model */ -class GogsBuild extends RemoteGitBuild +class GogsBuild extends GitBuild { /** * Get link to commit from Gogs repository diff --git a/src/PHPCensor/Model/Build/MercurialBuild.php b/src/PHPCensor/Model/Build/HgBuild.php similarity index 98% rename from src/PHPCensor/Model/Build/MercurialBuild.php rename to src/PHPCensor/Model/Build/HgBuild.php index 4711fbe3..7073144e 100644 --- a/src/PHPCensor/Model/Build/MercurialBuild.php +++ b/src/PHPCensor/Model/Build/HgBuild.php @@ -10,7 +10,7 @@ use PHPCensor\Builder; * * @author Pavel Gopanenko */ -class MercurialBuild extends Build +class HgBuild extends Build { /** * Get the URL to be used to clone this remote repository. diff --git a/src/PHPCensor/Model/Build/SubversionBuild.php b/src/PHPCensor/Model/Build/SvnBuild.php similarity index 98% rename from src/PHPCensor/Model/Build/SubversionBuild.php rename to src/PHPCensor/Model/Build/SvnBuild.php index 68a2ff7d..12fb57a2 100644 --- a/src/PHPCensor/Model/Build/SubversionBuild.php +++ b/src/PHPCensor/Model/Build/SvnBuild.php @@ -7,10 +7,10 @@ use PHPCensor\Builder; /** * Remote Subversion Build Model - * + * * @author Nadir Dzhilkibaev */ -class SubversionBuild extends Build +class SvnBuild extends Build { protected $svnCommand = 'svn export -q --non-interactive '; @@ -21,7 +21,7 @@ class SubversionBuild extends Build { $url = rtrim($this->getProject()->getReference(), '/') . '/'; $branch = ltrim($this->getBranch(), '/'); - + // For empty default branch or default branch name like "/trunk" or "trunk" (-> "trunk") if (empty($branch) || $branch == 'trunk') { $url .= 'trunk'; diff --git a/src/PHPCensor/Model/BuildError.php b/src/PHPCensor/Model/BuildError.php index 5b7bbf1c..a031b395 100644 --- a/src/PHPCensor/Model/BuildError.php +++ b/src/PHPCensor/Model/BuildError.php @@ -12,21 +12,11 @@ class BuildError extends Model const SEVERITY_NORMAL = 2; const SEVERITY_LOW = 3; - /** - * @var array - */ - public static $sleepable = []; - /** * @var string */ protected $tableName = 'build_error'; - /** - * @var string - */ - protected $modelName = 'BuildError'; - /** * @var array */ diff --git a/src/PHPCensor/Model/BuildMeta.php b/src/PHPCensor/Model/BuildMeta.php index 1c2881a2..f1bd45c4 100644 --- a/src/PHPCensor/Model/BuildMeta.php +++ b/src/PHPCensor/Model/BuildMeta.php @@ -7,21 +7,11 @@ use b8\Store\Factory; class BuildMeta extends Model { - /** - * @var array - */ - public static $sleepable = []; - /** * @var string */ protected $tableName = 'build_meta'; - /** - * @var string - */ - protected $modelName = 'BuildMeta'; - /** * @var array */ diff --git a/src/PHPCensor/Model/Environment.php b/src/PHPCensor/Model/Environment.php index e70da4ee..427a9be8 100644 --- a/src/PHPCensor/Model/Environment.php +++ b/src/PHPCensor/Model/Environment.php @@ -6,21 +6,11 @@ use PHPCensor\Model; class Environment extends Model { - /** - * @var array - */ - public static $sleepable = []; - /** * @var string */ protected $tableName = 'environment'; - /** - * @var string - */ - protected $modelName = 'Environment'; - /** * @var array */ diff --git a/src/PHPCensor/Model/Project.php b/src/PHPCensor/Model/Project.php index c6ad79be..4c581fcf 100644 --- a/src/PHPCensor/Model/Project.php +++ b/src/PHPCensor/Model/Project.php @@ -14,21 +14,11 @@ use Symfony\Component\Yaml\Dumper as YamlDumper; */ class Project extends Model { - /** - * @var array - */ - public static $sleepable = []; - /** * @var string */ protected $tableName = 'project'; - /** - * @var string - */ - protected $modelName = 'Project'; - /** * @var array */ diff --git a/src/PHPCensor/Model/ProjectGroup.php b/src/PHPCensor/Model/ProjectGroup.php index 68824381..2847c8a6 100644 --- a/src/PHPCensor/Model/ProjectGroup.php +++ b/src/PHPCensor/Model/ProjectGroup.php @@ -7,21 +7,11 @@ use b8\Store\Factory; class ProjectGroup extends Model { - /** - * @var array - */ - public static $sleepable = []; - /** * @var string */ protected $tableName = 'project_group'; - /** - * @var string - */ - protected $modelName = 'ProjectGroup'; - /** * @var array */ diff --git a/src/PHPCensor/Model/User.php b/src/PHPCensor/Model/User.php index d49c7472..dd1dceb6 100644 --- a/src/PHPCensor/Model/User.php +++ b/src/PHPCensor/Model/User.php @@ -10,21 +10,11 @@ use PHPCensor\Model; */ class User extends Model { - /** - * @var array - */ - public static $sleepable = []; - /** * @var string */ protected $tableName = 'user'; - /** - * @var string - */ - protected $modelName = 'User'; - /** * @var array */ diff --git a/src/PHPCensor/Store/EnvironmentStore.php b/src/PHPCensor/Store/EnvironmentStore.php index bb9d1d9c..8bee7f08 100644 --- a/src/PHPCensor/Store/EnvironmentStore.php +++ b/src/PHPCensor/Store/EnvironmentStore.php @@ -12,17 +12,17 @@ class EnvironmentStore extends Store /** * @var string */ - protected $tableName = 'environment'; + protected $tableName = 'environment'; /** * @var string */ - protected $modelName = '\PHPCensor\Model\Environment'; + protected $modelName = '\PHPCensor\Model\Environment'; /** * @var string */ - protected $primaryKey = 'id'; + protected $primaryKey = 'id'; /** * Get a Environment by primary key (Id) diff --git a/src/PHPCensor/View/WidgetLastBuilds/update.phtml b/src/PHPCensor/View/WidgetLastBuilds/update.phtml index b07bdb80..772a2039 100644 --- a/src/PHPCensor/View/WidgetLastBuilds/update.phtml +++ b/src/PHPCensor/View/WidgetLastBuilds/update.phtml @@ -87,6 +87,7 @@ use PHPCensor\Model\Build; diff --git a/tests/B8Framework/DatabaseMysqlTest.php b/tests/B8Framework/DatabaseMysqlTest.php new file mode 100755 index 00000000..139f4d81 --- /dev/null +++ b/tests/B8Framework/DatabaseMysqlTest.php @@ -0,0 +1,231 @@ +connection) { + try { + $pdo = new \PDO( + 'mysql:host=localhost;dbname=' . MYSQL_DBNAME, + MYSQL_USER, + MYSQL_PASSWORD + ); + + $this->connection = $this->createDefaultDBConnection($pdo, MYSQL_DBNAME); + + $this->connection->getConnection()->query(' + CREATE TABLE IF NOT EXISTS `database_mysql_test` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `projectId` int(11) NOT NULL, + `branch` varchar(250) NOT NULL DEFAULT \'master\', + `createDate` datetime, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + '); + } catch (\PDOException $ex) { + $this->connection = null; + } + } + } else { + $this->connection = null; + } + } + + /** + * @return \PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected function getConnection() + { + if (null === $this->connection) { + $this->markTestSkipped('Test skipped because MySQL database/user/extension doesn`t exist.'); + } + + return $this->connection; + } + + /** + * @return \PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected function getDataSet() + { + return $this->createArrayDataSet([ + 'database_mysql_test' => [[ + 'id' => 1, + 'projectId' => 1, + 'branch' => 'master', + 'createDate' => null, + ], [ + 'id' => 2, + 'projectId' => 2, + 'branch' => 'dev', + 'createDate' => '2018-02-20 01:01:01', + ], [ + 'id' => 3, + 'projectId' => 2, + 'branch' => 'master', + 'createDate' => '2018-02-21 02:02:02', + ]], + ]); + } + + protected function setUp() + { + parent::setUp(); + + new Config([ + 'b8' => [ + 'database' => [ + 'servers' => [ + 'read' => [ + ['host' => 'localhost'], + ], + 'write' => [ + ['host' => 'localhost'], + ], + ], + 'type' => Database::MYSQL_TYPE, + 'name' => MYSQL_DBNAME, + 'username' => MYSQL_USER, + 'password' => MYSQL_PASSWORD, + ], + ], + ]); + Database::reset(); + } + + public function testGetConnection() + { + $writeConnection = Database::getConnection('write'); + $readConnection = Database::getConnection('read'); + + self::assertInstanceOf('\b8\Database', $writeConnection); + self::assertInstanceOf('\b8\Database', $readConnection); + + $writeDetails = $writeConnection->getDetails(); + + self::assertTrue(is_array($writeDetails)); + self::assertEquals(MYSQL_DBNAME, $writeDetails['db']); + self::assertEquals(MYSQL_USER, $writeDetails['user']); + self::assertEquals(MYSQL_PASSWORD, $writeDetails['pass']); + + $readDetails = $readConnection->getDetails(); + + self::assertTrue(is_array($readDetails)); + self::assertEquals(MYSQL_DBNAME, $readDetails['db']); + self::assertEquals(MYSQL_USER, $readDetails['user']); + self::assertEquals(MYSQL_PASSWORD, $readDetails['pass']); + + self::assertEquals('mysql:host=localhost;dbname=b8_test', $readConnection->getDsn()); + } + + public function testGetWriteConnectionWithPort() + { + new Config([ + 'b8' => [ + 'database' => [ + 'servers' => [ + 'read' => [ + [ + 'host' => 'localhost', + 'port' => 3306, + ], + ], + 'write' => [ + [ + 'host' => 'localhost', + 'port' => 3306, + ], + ], + ], + 'type' => Database::MYSQL_TYPE, + 'name' => MYSQL_DBNAME, + 'username' => MYSQL_USER, + 'password' => MYSQL_PASSWORD, + ], + ], + ]); + Database::reset(); + + $writeConnection = Database::getConnection('write'); + $readConnection = Database::getConnection('read'); + + self::assertInstanceOf('\b8\Database', $writeConnection); + self::assertInstanceOf('\b8\Database', $readConnection); + + self::assertEquals('mysql:host=localhost;port=3306;dbname=b8_test', $readConnection->getDsn()); + } + + /** + * @expectedException \Exception + */ + public function testConnectionFailure() + { + new Config([ + 'b8' => [ + 'database' => [ + 'servers' => [ + 'read' => [ + ['host' => 'localhost'], + ], + 'write' => [ + ['host' => 'localhost'], + ], + ], + 'type' => Database::MYSQL_TYPE, + 'name' => 'b8_test_2', + 'username' => '', + 'password' => '', + ], + ], + ]); + Database::reset(); + + Database::getConnection('read'); + } + + public function testPrepareCommon() + { + $readConnection = Database::getConnection('read'); + + $sql = 'SELECT * FROM {{database_mysql_test}} WHERE {{projectId}} = :projectId'; + $query = $readConnection->prepareCommon($sql); + + $query->bindValue(':projectId', 2); + $query->execute(); + + $data = $query->fetchAll(\PDO::FETCH_ASSOC); + + self::assertEquals(2, count($data)); + } + + public function testLastInsertIdExtended() + { + $writeConnection = Database::getConnection('write'); + + $sql = 'INSERT INTO {{database_mysql_test}} ({{projectId}}) VALUES (3)'; + $query = $writeConnection->prepareCommon($sql); + + $query->execute(); + + self::assertEquals(4, $writeConnection->lastInsertIdExtended()); + } +} diff --git a/tests/B8Framework/DatabasePostgresqlTest.php b/tests/B8Framework/DatabasePostgresqlTest.php new file mode 100755 index 00000000..c571d6e4 --- /dev/null +++ b/tests/B8Framework/DatabasePostgresqlTest.php @@ -0,0 +1,235 @@ +connection) { + try { + $pdo = new \PDO( + 'pgsql:host=localhost;dbname=' . POSTGRESQL_DBNAME, + POSTGRESQL_USER, + POSTGRESQL_PASSWORD + ); + + $this->connection = $this->createDefaultDBConnection($pdo, POSTGRESQL_DBNAME); + + $this->connection->getConnection()->query(' + CREATE TABLE IF NOT EXISTS "database_mysql_test" ( + "id" SERIAL, + "projectId" integer NOT NULL, + "branch" character varying(250) NOT NULL DEFAULT \'master\', + "createDate" timestamp without time zone, + PRIMARY KEY ("id") + ); + '); + } catch (\PDOException $ex) { + $this->connection = null; + } + } + } else { + $this->connection = null; + } + } + + /** + * @return \PHPUnit_Extensions_Database_DB_IDatabaseConnection + */ + protected function getConnection() + { + if (null === $this->connection) { + $this->markTestSkipped('Test skipped because PostgreSQL database/user/extension doesn`t exist.'); + } + + return $this->connection; + } + + /** + * @return \PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected function getDataSet() + { + return $this->createArrayDataSet([ + 'database_mysql_test' => [[ + 'id' => 1, + 'projectId' => 1, + 'branch' => 'master', + 'createDate' => null, + ], [ + 'id' => 2, + 'projectId' => 2, + 'branch' => 'dev', + 'createDate' => '2018-02-20 01:01:01', + ], [ + 'id' => 3, + 'projectId' => 2, + 'branch' => 'master', + 'createDate' => '2018-02-21 02:02:02', + ]], + ]); + } + + protected function setUp() + { + parent::setUp(); + + new Config([ + 'b8' => [ + 'database' => [ + 'servers' => [ + 'read' => [ + ['host' => 'localhost'], + ], + 'write' => [ + ['host' => 'localhost'], + ], + ], + 'type' => Database::POSTGRESQL_TYPE, + 'name' => POSTGRESQL_DBNAME, + 'username' => POSTGRESQL_USER, + 'password' => POSTGRESQL_PASSWORD, + ], + ], + ]); + Database::reset(); + } + + public function testGetConnection() + { + $writeConnection = Database::getConnection('write'); + $readConnection = Database::getConnection('read'); + + self::assertInstanceOf('\b8\Database', $writeConnection); + self::assertInstanceOf('\b8\Database', $readConnection); + + $writeDetails = $writeConnection->getDetails(); + + self::assertTrue(is_array($writeDetails)); + self::assertEquals(POSTGRESQL_DBNAME, $writeDetails['db']); + self::assertEquals(POSTGRESQL_USER, $writeDetails['user']); + self::assertEquals(POSTGRESQL_PASSWORD, $writeDetails['pass']); + + $readDetails = $readConnection->getDetails(); + + self::assertTrue(is_array($readDetails)); + self::assertEquals(POSTGRESQL_DBNAME, $readDetails['db']); + self::assertEquals(POSTGRESQL_USER, $readDetails['user']); + self::assertEquals(POSTGRESQL_PASSWORD, $readDetails['pass']); + + self::assertEquals('pgsql:host=localhost;dbname=b8_test', $readConnection->getDsn()); + } + + public function testGetWriteConnectionWithPort() + { + new Config([ + 'b8' => [ + 'database' => [ + 'servers' => [ + 'read' => [ + [ + 'host' => 'localhost', + 'port' => 5432, + ], + ], + 'write' => [ + [ + 'host' => 'localhost', + 'port' => 5432, + ], + ], + ], + 'type' => Database::POSTGRESQL_TYPE, + 'name' => POSTGRESQL_DBNAME, + 'username' => POSTGRESQL_USER, + 'password' => POSTGRESQL_PASSWORD, + ], + ], + ]); + Database::reset(); + + $writeConnection = Database::getConnection('write'); + $readConnection = Database::getConnection('read'); + + self::assertInstanceOf('\b8\Database', $writeConnection); + self::assertInstanceOf('\b8\Database', $readConnection); + + self::assertEquals('pgsql:host=localhost;port=5432;dbname=b8_test', $readConnection->getDsn()); + } + + /** + * @expectedException \Exception + */ + public function testConnectionFailure() + { + new Config([ + 'b8' => [ + 'database' => [ + 'servers' => [ + 'read' => [ + ['host' => 'localhost'], + ], + 'write' => [ + ['host' => 'localhost'], + ], + ], + 'type' => Database::POSTGRESQL_TYPE, + 'name' => 'b8_test_2', + 'username' => '', + 'password' => '', + ], + ], + ]); + Database::reset(); + + Database::getConnection('read'); + } + + public function testPrepareCommon() + { + $readConnection = Database::getConnection('read'); + + $sql = 'SELECT * FROM {{database_mysql_test}} WHERE {{projectId}} = :projectId'; + $query = $readConnection->prepareCommon($sql); + + $query->bindValue(':projectId', 2); + $query->execute(); + + $data = $query->fetchAll(\PDO::FETCH_ASSOC); + + self::assertEquals(2, count($data)); + } + + public function testLastInsertIdExtended() + { + $this->connection->getConnection()->query(' + ALTER SEQUENCE "database_mysql_test_id_seq" RESTART WITH 4; + '); + + $writeConnection = Database::getConnection('write'); + + $sql = 'INSERT INTO {{database_mysql_test}} ({{projectId}}) VALUES (3)'; + $query = $writeConnection->prepareCommon($sql); + + $query->execute(); + + self::assertEquals(4, $writeConnection->lastInsertIdExtended('database_mysql_test')); + } +} diff --git a/tests/B8Framework/DatabaseTest.php b/tests/B8Framework/DatabaseTest.php deleted file mode 100755 index 7a353e8d..00000000 --- a/tests/B8Framework/DatabaseTest.php +++ /dev/null @@ -1,94 +0,0 @@ - [ - 'database' => [ - 'servers' => [ - 'read' => [ - ['host' => 'localhost'], - ], - 'write' => [ - ['host' => 'localhost'], - ], - ], - 'type' => DB_TYPE, - 'name' => DB_NAME, - 'username' => DB_USER, - 'password' => DB_PASS, - ], - ], - ]); - } - - protected function checkDatabaseConnection() - { - try { - $connection = Database::getConnection('read'); - } catch (\Exception $e) { - if ('Could not connect to any read servers.' === $e->getMessage()) { - $this->markTestSkipped('Test skipped because test database doesn`t exist.'); - } else { - throw $e; - } - } - } - - public function testGetWriteConnection() - { - $this->checkDatabaseConnection(); - - $connection = Database::getConnection('write'); - self::assertInstanceOf('\b8\Database', $connection); - } - - public function testGetDetails() - { - $this->checkDatabaseConnection(); - - $details = Database::getConnection('read')->getDetails(); - self::assertTrue(is_array($details)); - self::assertTrue(($details['db'] == DB_NAME)); - self::assertTrue(($details['user'] == DB_USER)); - self::assertTrue(($details['pass'] == DB_PASS)); - } - - /** - * @expectedException \Exception - */ - public function testConnectionFailure() - { - $this->checkDatabaseConnection(); - - Database::reset(); - - $config = new Config([ - 'b8' => [ - 'database' => [ - 'servers' => [ - 'read' => [ - ['host' => 'localhost'], - ], - 'write' => [ - ['host' => 'localhost'], - ], - ], - 'type' => DB_TYPE, - 'name' => 'b8_test_2', - 'username' => '', - 'password' => '', - ], - ], - ]); - - Database::getConnection('read'); - } -} diff --git a/tests/PHPCensor/Plugin/Util/PhpUnitResultTest.php b/tests/PHPCensor/Plugin/Util/PhpUnitResultTest.php index 58d119b8..9eeaa50a 100644 --- a/tests/PHPCensor/Plugin/Util/PhpUnitResultTest.php +++ b/tests/PHPCensor/Plugin/Util/PhpUnitResultTest.php @@ -83,7 +83,7 @@ class PhpUnitResultTest extends \PHPUnit\Framework\TestCase public static function getTestData() { return [ - 'json' => [PhpUnitResultJson::class, 'tests/PHPCensor/Plugin/SampleFiles/phpunit_money.txt'], + 'json' => [PhpUnitResultJson::class, 'tests/PHPCensor/Plugin/SampleFiles/phpunit_money.txt'], 'junit' => [PhpUnitResultJunit::class, 'tests/PHPCensor/Plugin/SampleFiles/phpunit_money_junit.xml'], ]; } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index f308bdc6..113bf8bf 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,51 +1,42 @@ loadYaml($configFile); -} - if (!defined('APP_URL') && !empty($config)) { define('APP_URL', $config->get('php-censor.url', '') . '/'); } -\PHPCensor\Helper\Lang::init($config, 'en'); - -define('DB_NAME', getenv('DB_NAME')); -define('DB_USER', getenv('DB_USER')); -define('DB_TYPE', getenv('DB_TYPE')); -define('DB_PASS', getenv('DB_PASS')); +\PHPCensor\Helper\Lang::init($config);