From e1ddf7f0127e9745f94e5ff9f76ea828e9058720 Mon Sep 17 00:00:00 2001 From: Frédéric Guillot Date: Mon, 15 Sep 2014 22:35:56 +0200 Subject: Run unit tests across different database backends + fix bugs --- app/Core/Loader.php | 33 ++++++++-- app/Model/Project.php | 31 +++++++-- app/Model/Task.php | 38 +++++++++-- app/check_setup.php | 5 -- app/common.php | 179 ++++---------------------------------------------- app/constants.php | 70 ++++++++++++++++++++ app/functions.php | 131 ++++++++++++++++++++++++++++++++++++ app/translator.php | 43 ------------ 8 files changed, 301 insertions(+), 229 deletions(-) create mode 100644 app/constants.php create mode 100644 app/functions.php delete mode 100644 app/translator.php (limited to 'app') diff --git a/app/Core/Loader.php b/app/Core/Loader.php index 7c437654..151081c1 100644 --- a/app/Core/Loader.php +++ b/app/Core/Loader.php @@ -10,18 +10,30 @@ namespace Core; */ class Loader { + /** + * List of paths + * + * @access private + * @var array + */ + private $paths = array(); + /** * Load the missing class * * @access public - * @param string $class Class name + * @param string $class Class name with namespace */ public function load($class) { - $filename = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; + foreach ($this->paths as $path) { + + $filename = $path.DIRECTORY_SEPARATOR.str_replace('\\', DIRECTORY_SEPARATOR, $class).'.php'; - if (file_exists($filename)) { - require $filename; + if (file_exists($filename)) { + require $filename; + break; + } } } @@ -34,4 +46,17 @@ class Loader { spl_autoload_register(array($this, 'load')); } + + /** + * Register a new path + * + * @access public + * @param string $path Path + * @return Core\Loader + */ + public function setPath($path) + { + $this->paths[] = $path; + return $this; + } } diff --git a/app/Model/Project.php b/app/Model/Project.php index 0ba18498..f8df1ae1 100644 --- a/app/Model/Project.php +++ b/app/Model/Project.php @@ -553,7 +553,8 @@ class Project extends Base */ public function update(array $values) { - return $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); + return $this->exists($values['id']) && + $this->db->table(self::TABLE)->eq('id', $values['id'])->save($values); } /** @@ -568,6 +569,18 @@ class Project extends Base return $this->db->table(self::TABLE)->eq('id', $project_id)->remove(); } + /** + * Return true if the project exists + * + * @access public + * @param integer $project_id Project id + * @return boolean + */ + public function exists($project_id) + { + return $this->db->table(self::TABLE)->eq('id', $project_id)->count() === 1; + } + /** * Enable a project * @@ -577,10 +590,11 @@ class Project extends Base */ public function enable($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) - ->save(array('is_active' => 1)); + ->update(array('is_active' => 1)); } /** @@ -592,10 +606,11 @@ class Project extends Base */ public function disable($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) - ->save(array('is_active' => 0)); + ->update(array('is_active' => 0)); } /** @@ -607,7 +622,8 @@ class Project extends Base */ public function enablePublicAccess($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) ->save(array('is_public' => 1, 'token' => Security::generateToken())); @@ -622,7 +638,8 @@ class Project extends Base */ public function disablePublicAccess($project_id) { - return $this->db + return $this->exists($project_id) && + $this->db ->table(self::TABLE) ->eq('id', $project_id) ->save(array('is_public' => 0, 'token' => '')); diff --git a/app/Model/Task.php b/app/Model/Task.php index 6f62c3d2..fcee67f7 100644 --- a/app/Model/Task.php +++ b/app/Model/Task.php @@ -150,16 +150,16 @@ class Task extends Base * Count all tasks for a given project and status * * @access public - * @param integer $project_id Project id - * @param array $status List of status id + * @param integer $project_id Project id + * @param integer $status_id Status id * @return array */ - public function getAll($project_id, array $status = array(self::STATUS_OPEN, self::STATUS_CLOSED)) + public function getAll($project_id, $status_id = self::STATUS_OPEN) { return $this->db ->table(self::TABLE) ->eq('project_id', $project_id) - ->in('is_active', $status) + ->eq('is_active', $status_id) ->findAll(); } @@ -382,6 +382,10 @@ class Task extends Base if (isset($values['score']) && empty($values['score'])) { $values['score'] = 0; } + + if (isset($values['is_active'])) { + $values['is_active'] = (int) $values['is_active']; + } } /** @@ -487,6 +491,18 @@ class Task extends Base } } + /** + * Return true if the project exists + * + * @access public + * @param integer $task_id Task id + * @return boolean + */ + public function exists($task_id) + { + return $this->db->table(self::TABLE)->eq('id', $task_id)->count() === 1; + } + /** * Mark a task closed * @@ -496,6 +512,10 @@ class Task extends Base */ public function close($task_id) { + if (! $this->exists($task_id)) { + return false; + } + $result = $this->db ->table(self::TABLE) ->eq('id', $task_id) @@ -520,12 +540,16 @@ class Task extends Base */ public function open($task_id) { + if (! $this->exists($task_id)) { + return false; + } + $result = $this->db ->table(self::TABLE) ->eq('id', $task_id) ->update(array( 'is_active' => 1, - 'date_completed' => '' + 'date_completed' => 0 )); if ($result) { @@ -544,6 +568,10 @@ class Task extends Base */ public function remove($task_id) { + if (! $this->exists($task_id)) { + return false; + } + $this->file->removeAll($task_id); return $this->db->table(self::TABLE)->eq('id', $task_id)->remove(); diff --git a/app/check_setup.php b/app/check_setup.php index 9ed16967..c4359d7a 100644 --- a/app/check_setup.php +++ b/app/check_setup.php @@ -33,8 +33,3 @@ if (! extension_loaded('mbstring')) { if (! is_writable('data')) { die('The directory "data" must be writeable by your web server user'); } - -// Include password_compat for PHP < 5.5 -if (version_compare(PHP_VERSION, '5.5.0', '<')) { - require __DIR__.'/../vendor/password.php'; -} diff --git a/app/common.php b/app/common.php index f46e3c6b..0ba7df9d 100644 --- a/app/common.php +++ b/app/common.php @@ -1,183 +1,32 @@ setPath('app'); +$loader->setPath('vendor'); $loader->execute(); $registry = new Registry; - -$registry->db = function() use ($registry) { - require __DIR__.'/../vendor/PicoDb/Database.php'; - - switch (DB_DRIVER) { - case 'sqlite': - require __DIR__.'/Schema/Sqlite.php'; - - $params = array( - 'driver' => 'sqlite', - 'filename' => DB_FILENAME - ); - - break; - - case 'mysql': - require __DIR__.'/Schema/Mysql.php'; - - $params = array( - 'driver' => 'mysql', - 'hostname' => DB_HOSTNAME, - 'username' => DB_USERNAME, - 'password' => DB_PASSWORD, - 'database' => DB_NAME, - 'charset' => 'utf8', - ); - - break; - - case 'postgres': - require __DIR__.'/Schema/Postgres.php'; - - $params = array( - 'driver' => 'postgres', - 'hostname' => DB_HOSTNAME, - 'username' => DB_USERNAME, - 'password' => DB_PASSWORD, - 'database' => DB_NAME, - ); - - break; - - default: - die('Database driver not supported'); - } - - $db = new \PicoDb\Database($params); - - if ($db->schema()->check(Schema\VERSION)) { - return $db; - } - else { - $errors = $db->getLogMessages(); - die('Unable to migrate database schema:

'.(isset($errors[0]) ? $errors[0] : 'Unknown error').''); - } -}; - -$registry->event = function() use ($registry) { - return new Event; -}; - -$registry->mailer = function() use ($registry) { - - require_once 'vendor/swiftmailer/swift_required.php'; - - switch (MAIL_TRANSPORT) { - case 'smtp': - $transport = Swift_SmtpTransport::newInstance(MAIL_SMTP_HOSTNAME, MAIL_SMTP_PORT); - $transport->setUsername(MAIL_SMTP_USERNAME); - $transport->setPassword(MAIL_SMTP_PASSWORD); - $transport->setEncryption(MAIL_SMTP_ENCRYPTION); - break; - case 'sendmail': - $transport = Swift_SendmailTransport::newInstance(MAIL_SENDMAIL_COMMAND); - break; - default: - $transport = Swift_MailTransport::newInstance(); - } - - return $transport; -}; +$registry->db = setup_db(); +$registry->event = setup_events(); +$registry->mailer = setup_mailer(); diff --git a/app/constants.php b/app/constants.php new file mode 100644 index 00000000..d52997d7 --- /dev/null +++ b/app/constants.php @@ -0,0 +1,70 @@ +setUsername(MAIL_SMTP_USERNAME); + $transport->setPassword(MAIL_SMTP_PASSWORD); + $transport->setEncryption(MAIL_SMTP_ENCRYPTION); + break; + case 'sendmail': + $transport = Swift_SendmailTransport::newInstance(MAIL_SENDMAIL_COMMAND); + break; + default: + $transport = Swift_MailTransport::newInstance(); + } + + return $transport; +} + +function setup_db() +{ + switch (DB_DRIVER) { + case 'sqlite': + require_once __DIR__.'/Schema/Sqlite.php'; + + $params = array( + 'driver' => 'sqlite', + 'filename' => DB_FILENAME + ); + + break; + + case 'mysql': + require_once __DIR__.'/Schema/Mysql.php'; + + $params = array( + 'driver' => 'mysql', + 'hostname' => DB_HOSTNAME, + 'username' => DB_USERNAME, + 'password' => DB_PASSWORD, + 'database' => DB_NAME, + 'charset' => 'utf8', + ); + + break; + + case 'postgres': + require_once __DIR__.'/Schema/Postgres.php'; + + $params = array( + 'driver' => 'postgres', + 'hostname' => DB_HOSTNAME, + 'username' => DB_USERNAME, + 'password' => DB_PASSWORD, + 'database' => DB_NAME, + ); + + break; + + default: + die('Database driver not supported'); + } + + $db = new Database($params); + + if ($db->schema()->check(Schema\VERSION)) { + return $db; + } + else { + $errors = $db->getLogMessages(); + die('Unable to migrate database schema:

'.(isset($errors[0]) ? $errors[0] : 'Unknown error').''); + } +} + +// Get a translation +function t() +{ + $t = new Translator; + return call_user_func_array(array($t, 'translate'), func_get_args()); +} + +// translate with no html escaping +function e() +{ + $t = new Translator; + return call_user_func_array(array($t, 'translateNoEscaping'), func_get_args()); +} + +// Get a locale currency +function c($value) +{ + $t = new Translator; + return $t->currency($value); +} + +// Get a formatted number +function n($value) +{ + $t = new Translator; + return $t->number($value); +} + +// Get a locale date +function dt($format, $timestamp) +{ + $t = new Translator; + return $t->datetime($format, $timestamp); +} + +// Plurals, return $t2 if $value > 1 +function p($value, $t1, $t2) { + return $value > 1 ? $t2 : $t1; +} diff --git a/app/translator.php b/app/translator.php deleted file mode 100644 index ac4d72e2..00000000 --- a/app/translator.php +++ /dev/null @@ -1,43 +0,0 @@ -currency($value); -} - -// Get a formatted number -function n($value) -{ - $t = new Translator; - return $t->number($value); -} - -// Get a locale date -function dt($format, $timestamp) -{ - $t = new Translator; - return $t->datetime($format, $timestamp); -} - -// Plurals, return $t2 if $value > 1 -function p($value, $t1, $t2) { - return $value > 1 ? $t2 : $t1; -} -- cgit v1.2.3