From f192185e263de56bb99fec299eb5e4f644de2649 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Tue, 11 Nov 2014 22:58:23 +0100 Subject: [PATCH 01/20] Refactor on mail sending to use Email helper and specific tempalte for successfull build. --- PHPCI/Plugin/Email.php | 111 ++++++++++++++------------------- PHPCI/View/Email/success.phtml | 15 +++++ 2 files changed, 61 insertions(+), 65 deletions(-) create mode 100644 PHPCI/View/Email/success.phtml diff --git a/PHPCI/Plugin/Email.php b/PHPCI/Plugin/Email.php index 7c5171d6..85720d7f 100644 --- a/PHPCI/Plugin/Email.php +++ b/PHPCI/Plugin/Email.php @@ -13,6 +13,7 @@ use b8\View; use PHPCI\Builder; use PHPCI\Helper\Lang; use PHPCI\Model\Build; +use PHPCI\Helper\Email as EmailHelper; /** * Email Plugin - Provides simple email capability to PHPCI. @@ -27,21 +28,16 @@ class Email implements \PHPCI\Plugin */ protected $phpci; + /** + * @var \PHPCI\Model\Build + */ + protected $build; + /** * @var array */ protected $options; - /** - * @var \Swift_Mailer - */ - protected $mailer; - - /** - * @var string - */ - protected $fromAddress; - /** * Set up the plugin, configure options, etc. * @param Builder $phpci @@ -52,25 +48,16 @@ class Email implements \PHPCI\Plugin public function __construct( Builder $phpci, Build $build, - \Swift_Mailer $mailer, array $options = array() ) { $this->phpci = $phpci; $this->build = $build; $this->options = $options; - - $phpCiSettings = $phpci->getSystemConfig('phpci'); - - $this->fromAddress = isset($phpCiSettings['email_settings']['from_address']) - ? $phpCiSettings['email_settings']['from_address'] - : "notifications-ci@phptesting.org"; - - $this->mailer = $mailer; } /** - * Connects to MySQL and runs a specified set of queries. - */ + * Send a notificaiton mail. + */ public function execute() { $addresses = $this->getEmailAddresses(); @@ -81,79 +68,73 @@ class Email implements \PHPCI\Plugin return false; } - $subjectTemplate = "PHPCI - %s - %s"; + $buildStatus = $this->build->isSuccessful() ? "Failing Build" : "Passing Build"; $projectName = $this->phpci->getBuildProjectTitle(); - $logText = $this->build->getLog(); + $mailTemplate = $this->build->isSuccessful() ? 'Email/success' : 'Email/failed'; - if ($this->build->isSuccessful()) { - $sendFailures = $this->sendSeparateEmails( - $addresses, - sprintf($subjectTemplate, $projectName, Lang::get('passing_build')), - sprintf(Lang::get('log_output')."
%s
", $logText) - ); - } else { - $view = new View('Email/failed'); - $view->build = $this->build; - $view->project = $this->build->getProject(); + $view = new View($mailTemplate); + $view->build = $this->build; + $view->project = $this->build->getProject(); + $body = $view->render(); - $emailHtml = $view->render(); - - $sendFailures = $this->sendSeparateEmails( - $addresses, - sprintf($subjectTemplate, $projectName, Lang::get('failing_build')), - $emailHtml - ); - } + $sendFailures = $this->sendSeparateEmails( + $addresses, + sprintf("PHPCI - %s - %s", $projectName, $buildStatus), + $body + ); // This is a success if we've not failed to send anything. + $this->phpci->log(sprintf("%d emails sent", (count($addresses) - $sendFailures))); + $this->phpci->log(sprintf("%d emails failed to send", $sendFailures)); - $this->phpci->log(Lang::get('n_emails_sent', (count($addresses) - count($sendFailures)))); - $this->phpci->log(Lang::get('n_emails_failed', count($sendFailures))); - - return (count($sendFailures) == 0); + return ($sendFailures === 0); } /** - * @param string[]|string $toAddresses Array or single address to send to + * @param string $toAddress Single address to send to * @param string[] $ccList * @param string $subject Email subject * @param string $body Email body * @return array Array of failed addresses */ - public function sendEmail($toAddresses, $ccList, $subject, $body) + public function sendEmail($toAddress, $ccList, $subject, $body) { - $message = \Swift_Message::newInstance($subject) - ->setFrom($this->fromAddress) - ->setTo($toAddresses) - ->setBody($body) - ->setContentType("text/html"); + $email = new EmailHelper(); + + $email->setEmailTo($toAddress, $toAddress); + $email->setSubject($subject); + $email->setBody($body); + $email->setIsHtml(true); if (is_array($ccList) && count($ccList)) { - $message->setCc($ccList); + foreach ($ccList as $address) { + $message->addCc($address, $address); + } } - $failedAddresses = array(); - $this->mailer->send($message, $failedAddresses); - - return $failedAddresses; + return $email->send(); } /** - * Send out build status emails. + * Send an email to a list of specified subjects. + * * @param array $toAddresses - * @param $subject - * @param $body - * @return array + * List of destinatary of message. + * @param string $subject + * Mail subject + * @param string $body + * Mail body + * + * @return int number of failed messages */ public function sendSeparateEmails(array $toAddresses, $subject, $body) { - $failures = array(); + $failures = 0; $ccList = $this->getCcAddresses(); foreach ($toAddresses as $address) { - $newFailures = $this->sendEmail($address, $ccList, $subject, $body); - foreach ($newFailures as $failure) { - $failures[] = $failure; + if (!$this->sendEmail($address, $ccList, $subject, $body)) { + $failures++; } } return $failures; diff --git a/PHPCI/View/Email/success.phtml b/PHPCI/View/Email/success.phtml new file mode 100644 index 00000000..a6dfccea --- /dev/null +++ b/PHPCI/View/Email/success.phtml @@ -0,0 +1,15 @@ +
+
+
+ getTitle(); ?> - Build #getId(); ?> +
+ +
+

Your commit getCommitId(); ?> genrate a successfull build in project getTitle(); ?>.

+ +

getCommitMessage(); ?>

+
getLog(); ?>
+

You can review your commit and the build log.

+
+
+
From 501ca58729e63adcd6f408f1f912f551f5e185af Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Tue, 11 Nov 2014 22:58:57 +0100 Subject: [PATCH 02/20] Remove unrequire parameters on constructur and fixed error on phpdoc. --- Tests/PHPCI/Plugin/EmailTest.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index 0fa2d8f0..b53f4a96 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -30,12 +30,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase protected $mockCiBuilder; /** - * @var \PHPUnit_Framework_MockObject_MockObject $mockMailer - */ - protected $mockMailer; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject $mockMailer + * @var \PHPUnit_Framework_MockObject_MockObject $mockBuild */ protected $mockBuild; @@ -111,7 +106,6 @@ class EmailTest extends \PHPUnit_Framework_TestCase $this->testedEmailPlugin = new EmailPlugin( $this->mockCiBuilder, $this->mockBuild, - $this->mockMailer, $arrOptions ); } @@ -322,4 +316,4 @@ class EmailTest extends \PHPUnit_Framework_TestCase $actualMail->getSubject() ); } -} \ No newline at end of file +} From 33ca150efba7915956ea183950476355ec7e920a Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Tue, 11 Nov 2014 23:05:35 +0100 Subject: [PATCH 03/20] Added project mocking to allow using mail template on successfull build. --- Tests/PHPCI/Plugin/EmailTest.php | 68 ++++++++++---------------------- 1 file changed, 20 insertions(+), 48 deletions(-) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index b53f4a96..855736f2 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -34,11 +34,28 @@ class EmailTest extends \PHPUnit_Framework_TestCase */ protected $mockBuild; + /** + * @var \PHPUnit_Framework_MockObject_MockObject $mockProject + */ + protected $mockProject; + public function setUp() { + $this->mockProject = $this->getMock( + '\PHPCI\Model\Project', + array('getTitle'), + array(), + "mockProject", + false + ); + + $this->mockProject->expects($this->any()) + ->method('getTitle') + ->will($this->returnValue("Test project")); + $this->mockBuild = $this->getMock( '\PHPCI\Model\Build', - array('getLog', 'getStatus'), + array('getLog', 'getStatus', 'getProject'), array(), "mockBuild", false @@ -53,8 +70,8 @@ class EmailTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(\PHPCI\Model\Build::STATUS_SUCCESS)); $this->mockBuild->expects($this->any()) - ->method('getCommitterEmail') - ->will($this->returnValue("committer@test.com")); + ->method('getProject') + ->will($this->returnValue($this->mockProject)); $this->mockCiBuilder = $this->getMock( '\PHPCI\Builder', @@ -149,53 +166,8 @@ class EmailTest extends \PHPUnit_Framework_TestCase ); $this->assertEquals($expectedReturn, $returnValue); - } - /** - * @covers PHPUnit::execute - */ - public function testExecute_UniqueRecipientsFromWithCommitter() - { - $this->loadEmailPluginWithOptions( - array( - 'addresses' => array('test-receiver@example.com', 'test-receiver2@example.com') - ) - ); - $actualMails = []; - $this->catchMailPassedToSend($actualMails); - - $returnValue = $this->testedEmailPlugin->execute(); - $this->assertTrue($returnValue); - - $this->assertCount(2, $actualMails); - - $actualTos = array(key($actualMails[0]->getTo()), key($actualMails[1]->getTo())); - $this->assertContains('test-receiver@example.com', $actualTos); - $this->assertContains('test-receiver2@example.com', $actualTos); - } - - /** - * @covers PHPUnit::execute - */ - public function testExecute_UniqueRecipientsWithCommiter() - { - $this->loadEmailPluginWithOptions( - array( - 'commiter' => true, - 'addresses' => array('test-receiver@example.com', 'committer@test.com') - ) - ); - - $actualMails = []; - $this->catchMailPassedToSend($actualMails); - - $returnValue = $this->testedEmailPlugin->execute(); - $this->assertTrue($returnValue); - - $actualTos = array(key($actualMails[0]->getTo()), key($actualMails[1]->getTo())); - $this->assertContains('test-receiver@example.com', $actualTos); - $this->assertContains('committer@test.com', $actualTos); } /** From f16395e45b12c5f9c015f060fdf86f0579c75606 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Wed, 12 Nov 2014 00:20:17 +0100 Subject: [PATCH 04/20] Use more consistent project name loader to compose mail. --- PHPCI/Plugin/Email.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PHPCI/Plugin/Email.php b/PHPCI/Plugin/Email.php index 85720d7f..406caed6 100644 --- a/PHPCI/Plugin/Email.php +++ b/PHPCI/Plugin/Email.php @@ -68,8 +68,8 @@ class Email implements \PHPCI\Plugin return false; } - $buildStatus = $this->build->isSuccessful() ? "Failing Build" : "Passing Build"; - $projectName = $this->phpci->getBuildProjectTitle(); + $buildStatus = $this->build->isSuccessful() ? "Passing Build" : "Failing Build"; + $projectName = $this->build->getProject()->getTitle(); $mailTemplate = $this->build->isSuccessful() ? 'Email/success' : 'Email/failed'; $view = new View($mailTemplate); From 64bd64e07bb55f28ae4bf63efa400a4a3eea97ff Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Wed, 12 Nov 2014 00:20:55 +0100 Subject: [PATCH 05/20] Added more test case to validate subject, body, status code and mails on messages. --- Tests/PHPCI/Plugin/EmailTest.php | 364 +++++++++++++++++++------------ 1 file changed, 220 insertions(+), 144 deletions(-) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index 855736f2..e311d508 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -10,6 +10,7 @@ namespace PHPCI\Plugin\Tests; use PHPCI\Plugin\Email as EmailPlugin; +use PHPCI\Model\Build; /** @@ -39,8 +40,26 @@ class EmailTest extends \PHPUnit_Framework_TestCase */ protected $mockProject; + /** + * @var int buildStatus + */ + protected $buildStatus; + + /** + * @var array $message; + */ + protected $message; + + /** + * @var bool $mailDelivered + */ + protected $mailDelivered; + public function setUp() { + $this->message = array(); + $this->mailDelivered = true; + $this->mockProject = $this->getMock( '\PHPCI\Model\Project', array('getTitle'), @@ -51,11 +70,11 @@ class EmailTest extends \PHPUnit_Framework_TestCase $this->mockProject->expects($this->any()) ->method('getTitle') - ->will($this->returnValue("Test project")); + ->will($this->returnValue("Test-Project")); $this->mockBuild = $this->getMock( '\PHPCI\Model\Build', - array('getLog', 'getStatus', 'getProject'), + array('getLog', 'getStatus', 'getProject', 'getCommitterEmail'), array(), "mockBuild", false @@ -67,17 +86,22 @@ class EmailTest extends \PHPUnit_Framework_TestCase $this->mockBuild->expects($this->any()) ->method('getStatus') - ->will($this->returnValue(\PHPCI\Model\Build::STATUS_SUCCESS)); + ->will($this->returnCallback(function () { + return $this->buildStatus; + })); $this->mockBuild->expects($this->any()) ->method('getProject') ->will($this->returnValue($this->mockProject)); + $this->mockBuild->expects($this->any()) + ->method('getCommitterEmail') + ->will($this->returnValue('committer-email@example.com')); + $this->mockCiBuilder = $this->getMock( '\PHPCI\Builder', array( 'getSystemConfig', - 'getBuildProjectTitle', 'getBuild', 'log' ), @@ -100,30 +124,41 @@ class EmailTest extends \PHPUnit_Framework_TestCase ) ) ); - $this->mockCiBuilder->expects($this->any()) - ->method('getBuildProjectTitle') - ->will($this->returnValue('Test-Project')); - $this->mockCiBuilder->expects($this->any()) - ->method('getBuild') - ->will($this->returnValue($this->mockBuild)); - - $this->mockMailer = $this->getMock( - '\Swift_Mailer', - array('send'), - array(), - "mockMailer", - false - ); - - $this->loadEmailPluginWithOptions(); } - protected function loadEmailPluginWithOptions($arrOptions = array()) + protected function loadEmailPluginWithOptions($arrOptions = array(), $buildStatus = null, $mailDelivered = true) { - $this->testedEmailPlugin = new EmailPlugin( - $this->mockCiBuilder, - $this->mockBuild, - $arrOptions + $this->mailDelivered = $mailDelivered; + + if (is_null($buildStatus)) { + $this->buildStatus = Build::STATUS_SUCCESS; + } else { + $this->buildStatus = $buildStatus; + } + + // Reset current message. + $this->message = array(); + + $this->testedEmailPlugin = $this->getMock( + '\PHPCI\Plugin\Email', + array('sendEmail'), + array( + $this->mockCiBuilder, + $this->mockBuild, + $arrOptions + ) + ); + + $this->testedEmailPlugin->expects($this->any()) + ->method('sendEmail') + ->will($this->returnCallback(function ($to, $cc, $subject, $body) { + $this->message['to'][] = $to; + $this->message['cc'] = $cc; + $this->message['subject'] = $subject; + $this->message['body'] = $body; + + return $this->mailDelivered; + }) ); } @@ -132,7 +167,10 @@ class EmailTest extends \PHPUnit_Framework_TestCase */ public function testExecute_ReturnsFalseWithoutArgs() { + $this->loadEmailPluginWithOptions(); + $returnValue = $this->testedEmailPlugin->execute(); + // As no addresses will have been mailed as non are configured. $expectedReturn = false; @@ -147,145 +185,183 @@ class EmailTest extends \PHPUnit_Framework_TestCase $this->loadEmailPluginWithOptions( array( 'addresses' => array('test-receiver@example.com') - ) + ), + Build::STATUS_SUCCESS ); - /** @var \Swift_Message $actualMail */ - $actualMail = null; - $this->catchMailPassedToSend($actualMail); - $returnValue = $this->testedEmailPlugin->execute(); - $expectedReturn = true; - $this->assertSystemMail( - 'test-receiver@example.com', - 'test-from-address@example.com', - "Log Output:
Build Log
", - "PHPCI - Test-Project - Passing Build", - $actualMail + $this->assertContains('test-receiver@example.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_BuildsDefaultEmails() + { + $this->loadEmailPluginWithOptions( + array( + 'default_mailto_address' => 'default-mailto-address@example.com' + ), + Build::STATUS_SUCCESS ); - $this->assertEquals($expectedReturn, $returnValue); - + $returnValue = $this->testedEmailPlugin->execute(); + $this->assertContains('default-mailto-address@example.com', $this->message['to']); } /** - * @covers PHPUnit::sendEmail + * @covers PHPUnit::execute */ - public function testSendEmail_CallsMailerSend() + public function testExecute_CcDefaultEmails() { - $this->mockMailer->expects($this->once()) - ->method('send'); - $this->testedEmailPlugin->sendEmail("test@email.com", array(), "hello", "body"); - } - - /** - * @covers PHPUnit::sendEmail - */ - public function testSendEmail_BuildsAMessageObject() - { - $subject = "Test mail"; - $body = "Message Body"; - $toAddress = "test@example.com"; - - $this->mockMailer->expects($this->once()) - ->method('send') - ->with($this->isInstanceOf('\Swift_Message'), $this->anything()); - $this->testedEmailPlugin->sendEmail($toAddress, array(), $subject, $body); - } - - /** - * @covers PHPUnit::sendEmail - */ - public function testSendEmail_BuildsExpectedMessage() - { - $subject = "Test mail"; - $body = "Message Body"; - $toAddress = "test@example.com"; - $expectedMessage = \Swift_Message::newInstance($subject) - ->setFrom('test-from-address@example.com') - ->setTo($toAddress) - ->setBody($body); - - /** @var \Swift_Message $actualMail */ - $actualMail = null; - $this->catchMailPassedToSend($actualMail); - - $this->testedEmailPlugin->sendEmail($toAddress, array(), $subject, $body); - - $this->assertSystemMail( - $toAddress, - 'test-from-address@example.com', - $body, - $subject, - $actualMail + $this->loadEmailPluginWithOptions( + array( + 'default_mailto_address' => 'default-mailto-address@example.com', + 'cc' => array( + 'cc-email-1@example.com', + 'cc-email-2@example.com', + 'cc-email-3@example.com', + ), + ), + Build::STATUS_SUCCESS ); - } - /** - * @param \Swift_Message $actualMail passed by ref and populated with - * the message object the mock mailer - * receives. - */ - protected function catchMailPassedToSend(&$actualMail) - { - $this->mockMailer->expects(is_array($actualMail) ? $this->atLeast(1) : $this->once()) - ->method('send') - ->will( - $this->returnCallback( - function ($passedMail) use (&$actualMail) { - if(is_array($actualMail)) { - $actualMail[] = $passedMail; - } else { - $actualMail = $passedMail; - } - return array(); - } - ) - ); - } - - /** - * Asserts that the actual mail object is populated as expected. - * - * @param string $expectedToAddress - * @param $expectedFromAddress - * @param string $expectedBody - * @param string $expectedSubject - * @param \Swift_Message $actualMail - */ - protected function assertSystemMail( - $expectedToAddress, - $expectedFromAddress, - $expectedBody, - $expectedSubject, - $actualMail - ) { - if (!($actualMail instanceof \Swift_Message)) { - $type = is_object($actualMail) ? get_class($actualMail) : gettype( - $actualMail - ); - throw new \Exception("Expected Swift_Message got " . $type); - } - $this->assertEquals( - array($expectedFromAddress => null), - $actualMail->getFrom() - ); + $this->testedEmailPlugin->execute(); $this->assertEquals( - array($expectedToAddress => null), - $actualMail->getTo() + array( + 'cc-email-1@example.com', + 'cc-email-2@example.com', + 'cc-email-3@example.com', + ), + $this->message['cc'] + ); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_BuildsCommitterEmails() + { + $this->loadEmailPluginWithOptions( + array( + 'committer' => true + ), + Build::STATUS_SUCCESS ); - $this->assertEquals( - $expectedBody, - $actualMail->getBody() + $this->testedEmailPlugin->execute(); + + $this->assertContains('committer-email@example.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_MailSuccessfulBuildHaveProjectName() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_SUCCESS ); - $this->assertEquals( - $expectedSubject, - $actualMail->getSubject() + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertContains('Test-Project', $this->message['subject']); + $this->assertContains('Test-Project', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_MailFailingBuildHaveProjectName() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED ); + + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertContains('Test-Project', $this->message['subject']); + $this->assertContains('Test-Project', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_MailSuccessfulBuildHaveStatus() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_SUCCESS + ); + + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertContains('Passing', $this->message['subject']); + $this->assertContains('successfull', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_MailFailingBuildHaveStatus() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED + ); + + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertContains('Failing', $this->message['subject']); + $this->assertContains('failed', $this->message['body']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_MailDeliverySuccess() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED, + true + ); + + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertEquals(true, $returnValue); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_MailDeliveryFail() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com') + ), + Build::STATUS_FAILED, + false + ); + + $returnValue = $this->testedEmailPlugin->execute(); + + $this->assertEquals(false, $returnValue); } } From 2aff5ab89670bb14fe0a42e2cee99c6fb6894c87 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Wed, 12 Nov 2014 13:37:52 +0100 Subject: [PATCH 06/20] Fixed CS. --- Tests/PHPCI/Plugin/EmailTest.php | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index e311d508..791123e4 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -12,7 +12,6 @@ namespace PHPCI\Plugin\Tests; use PHPCI\Plugin\Email as EmailPlugin; use PHPCI\Model\Build; - /** * Unit test for the PHPUnit plugin. * @author meadsteve @@ -158,14 +157,13 @@ class EmailTest extends \PHPUnit_Framework_TestCase $this->message['body'] = $body; return $this->mailDelivered; - }) - ); + })); } /** * @covers PHPUnit::execute */ - public function testExecute_ReturnsFalseWithoutArgs() + public function testReturnsFalseWithoutArgs() { $this->loadEmailPluginWithOptions(); @@ -180,7 +178,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_BuildsBasicEmails() + public function testBuildsBasicEmails() { $this->loadEmailPluginWithOptions( array( @@ -197,7 +195,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_BuildsDefaultEmails() + public function testBuildsDefaultEmails() { $this->loadEmailPluginWithOptions( array( @@ -214,7 +212,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_CcDefaultEmails() + public function testCcDefaultEmails() { $this->loadEmailPluginWithOptions( array( @@ -243,7 +241,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_BuildsCommitterEmails() + public function testBuildsCommitterEmails() { $this->loadEmailPluginWithOptions( array( @@ -260,7 +258,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_MailSuccessfulBuildHaveProjectName() + public function testMailSuccessfulBuildHaveProjectName() { $this->loadEmailPluginWithOptions( array( @@ -278,7 +276,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_MailFailingBuildHaveProjectName() + public function testMailFailingBuildHaveProjectName() { $this->loadEmailPluginWithOptions( array( @@ -296,7 +294,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_MailSuccessfulBuildHaveStatus() + public function testMailSuccessfulBuildHaveStatus() { $this->loadEmailPluginWithOptions( array( @@ -314,7 +312,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_MailFailingBuildHaveStatus() + public function testMailFailingBuildHaveStatus() { $this->loadEmailPluginWithOptions( array( @@ -332,7 +330,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_MailDeliverySuccess() + public function testMailDeliverySuccess() { $this->loadEmailPluginWithOptions( array( @@ -350,7 +348,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase /** * @covers PHPUnit::execute */ - public function testExecute_MailDeliveryFail() + public function testMailDeliveryFail() { $this->loadEmailPluginWithOptions( array( From 2d194de6d0267e3312407506723fdf033f31a2d2 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Wed, 12 Nov 2014 13:44:56 +0100 Subject: [PATCH 07/20] Fixed code in CC mails. --- PHPCI/Plugin/Email.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Plugin/Email.php b/PHPCI/Plugin/Email.php index 406caed6..fa2a4e85 100644 --- a/PHPCI/Plugin/Email.php +++ b/PHPCI/Plugin/Email.php @@ -108,7 +108,7 @@ class Email implements \PHPCI\Plugin if (is_array($ccList) && count($ccList)) { foreach ($ccList as $address) { - $message->addCc($address, $address); + $email->addCc($address, $address); } } From 74b0513dd5fd88e297dc8d5ea2c687b69c9a4c87 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Wed, 12 Nov 2014 13:51:01 +0100 Subject: [PATCH 08/20] Remove unused code. --- Tests/PHPCI/Plugin/EmailTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index 791123e4..183d17e5 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -187,7 +187,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase Build::STATUS_SUCCESS ); - $returnValue = $this->testedEmailPlugin->execute(); + $this->testedEmailPlugin->execute(); $this->assertContains('test-receiver@example.com', $this->message['to']); } @@ -204,7 +204,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase Build::STATUS_SUCCESS ); - $returnValue = $this->testedEmailPlugin->execute(); + $this->testedEmailPlugin->execute(); $this->assertContains('default-mailto-address@example.com', $this->message['to']); } @@ -267,7 +267,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase Build::STATUS_SUCCESS ); - $returnValue = $this->testedEmailPlugin->execute(); + $this->testedEmailPlugin->execute(); $this->assertContains('Test-Project', $this->message['subject']); $this->assertContains('Test-Project', $this->message['body']); @@ -285,7 +285,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase Build::STATUS_FAILED ); - $returnValue = $this->testedEmailPlugin->execute(); + $this->testedEmailPlugin->execute(); $this->assertContains('Test-Project', $this->message['subject']); $this->assertContains('Test-Project', $this->message['body']); @@ -303,7 +303,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase Build::STATUS_SUCCESS ); - $returnValue = $this->testedEmailPlugin->execute(); + $this->testedEmailPlugin->execute(); $this->assertContains('Passing', $this->message['subject']); $this->assertContains('successfull', $this->message['body']); @@ -321,7 +321,7 @@ class EmailTest extends \PHPUnit_Framework_TestCase Build::STATUS_FAILED ); - $returnValue = $this->testedEmailPlugin->execute(); + $this->testedEmailPlugin->execute(); $this->assertContains('Failing', $this->message['subject']); $this->assertContains('failed', $this->message['body']); From 5b754fe07c757bfeefbfb348b71961f7e56ba20e Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Thu, 25 Dec 2014 21:49:53 +0100 Subject: [PATCH 09/20] Fixed config path for tests. --- Tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index a8b71034..f7cbd630 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -17,7 +17,7 @@ require_once(dirname(__DIR__) . '/vendor/autoload.php'); $conf = array(); $conf['b8']['app']['namespace'] = 'PHPCI'; $conf['b8']['app']['default_controller'] = 'Home'; -$conf['b8']['view']['path'] = dirname(__DIR__) . '/PHPCI/View/'; +$conf['b8']['view']['path'] = dirname(__DIR__) . '/../PHPCI/View/'; // If the PHPCI config file is not where we expect it, try looking in // env for an alternative config path. From 885f947da804b4324b436eb8cf123d54b720e490 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Thu, 25 Dec 2014 22:20:11 +0100 Subject: [PATCH 10/20] Update loader config for test. --- Tests/bootstrap.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index f7cbd630..601c7d7b 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -13,12 +13,6 @@ date_default_timezone_set(@date_default_timezone_get()); // Load Composer autoloader: require_once(dirname(__DIR__) . '/vendor/autoload.php'); -// Load configuration if present: -$conf = array(); -$conf['b8']['app']['namespace'] = 'PHPCI'; -$conf['b8']['app']['default_controller'] = 'Home'; -$conf['b8']['view']['path'] = dirname(__DIR__) . '/../PHPCI/View/'; - // If the PHPCI config file is not where we expect it, try looking in // env for an alternative config path. $configFile = dirname(__FILE__) . '/../PHPCI/config.yml'; @@ -31,6 +25,12 @@ if (!file_exists($configFile)) { } } +// Load configuration if present: +$conf = array(); +$conf['b8']['app']['namespace'] = 'PHPCI'; +$conf['b8']['app']['default_controller'] = 'Home'; +$conf['b8']['view']['path'] = dirname(__DIR__) . '/PHPCI/View/'; + $config = new b8\Config($conf); if (file_exists($configFile)) { From cbd98b6b46a637b48712d2d1f92973b2b013c3b8 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Thu, 5 Feb 2015 14:27:26 +0100 Subject: [PATCH 11/20] Fixed typo. --- PHPCI/Plugin/Email.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Plugin/Email.php b/PHPCI/Plugin/Email.php index fa2a4e85..02987e9b 100644 --- a/PHPCI/Plugin/Email.php +++ b/PHPCI/Plugin/Email.php @@ -56,7 +56,7 @@ class Email implements \PHPCI\Plugin } /** - * Send a notificaiton mail. + * Send a notification mail. */ public function execute() { From 2255767dc1e14b9d5fc3f7f2862a66e721dd95b3 Mon Sep 17 00:00:00 2001 From: Marco Vito Moscaritolo Date: Fri, 6 Feb 2015 19:09:37 +0100 Subject: [PATCH 12/20] Fixed test that use genreated mail to see information. --- Tests/PHPCI/Plugin/EmailTest.php | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Tests/PHPCI/Plugin/EmailTest.php b/Tests/PHPCI/Plugin/EmailTest.php index 183d17e5..965b23c4 100644 --- a/Tests/PHPCI/Plugin/EmailTest.php +++ b/Tests/PHPCI/Plugin/EmailTest.php @@ -209,6 +209,45 @@ class EmailTest extends \PHPUnit_Framework_TestCase $this->assertContains('default-mailto-address@example.com', $this->message['to']); } + /** + * @covers PHPUnit::execute + */ + public function testExecute_UniqueRecipientsFromWithCommitter() + { + $this->loadEmailPluginWithOptions( + array( + 'addresses' => array('test-receiver@example.com', 'test-receiver2@example.com') + ) + ); + + $returnValue = $this->testedEmailPlugin->execute(); + $this->assertTrue($returnValue); + + $this->assertCount(2, $this->message['to']); + + $this->assertContains('test-receiver@example.com', $this->message['to']); + $this->assertContains('test-receiver2@example.com', $this->message['to']); + } + + /** + * @covers PHPUnit::execute + */ + public function testExecute_UniqueRecipientsWithCommiter() + { + $this->loadEmailPluginWithOptions( + array( + 'commiter' => true, + 'addresses' => array('test-receiver@example.com', 'committer@test.com') + ) + ); + + $returnValue = $this->testedEmailPlugin->execute(); + $this->assertTrue($returnValue); + + $this->assertContains('test-receiver@example.com', $this->message['to']); + $this->assertContains('committer@test.com', $this->message['to']); + } + /** * @covers PHPUnit::execute */ From 7c4a9261660598355a34647bd161fe3e4a55cb3a Mon Sep 17 00:00:00 2001 From: Tobias van Beek Date: Mon, 16 Feb 2015 15:00:37 +0100 Subject: [PATCH 13/20] Render the public key on the project edit page. CLose #722 done by @leewillis77 --- PHPCI/Controller/ProjectController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Controller/ProjectController.php b/PHPCI/Controller/ProjectController.php index b263f06e..8457a7bb 100644 --- a/PHPCI/Controller/ProjectController.php +++ b/PHPCI/Controller/ProjectController.php @@ -268,7 +268,7 @@ class ProjectController extends PHPCI\Controller $view->type = 'edit'; $view->project = $project; $view->form = $form; - $view->key = null; + $view->key = $values['pubkey']; return $view->render(); } From 33f2ec172d594da2f49da8802c02dd01a9d3c43a Mon Sep 17 00:00:00 2001 From: Daniel Wolkenhauer Date: Mon, 16 Feb 2015 18:51:05 +0100 Subject: [PATCH 14/20] Fatal error: Call to undefined method PHPCI\Helper\Email::setIsHtml() in ../Email.php on line 107 --- PHPCI/Plugin/Email.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PHPCI/Plugin/Email.php b/PHPCI/Plugin/Email.php index 02987e9b..9e361d91 100644 --- a/PHPCI/Plugin/Email.php +++ b/PHPCI/Plugin/Email.php @@ -104,7 +104,7 @@ class Email implements \PHPCI\Plugin $email->setEmailTo($toAddress, $toAddress); $email->setSubject($subject); $email->setBody($body); - $email->setIsHtml(true); + $email->setHtml(true); if (is_array($ccList) && count($ccList)) { foreach ($ccList as $address) { From 8f5d855193e6b67cd042ac61c8d9553359d6b8d5 Mon Sep 17 00:00:00 2001 From: James Inman Date: Wed, 18 Feb 2015 14:07:26 +0000 Subject: [PATCH 15/20] Adding Technical Debt plugin. --- PHPCI/Languages/lang.en.php | 1 + PHPCI/Plugin/TechnicalDebt.php | 183 ++++++++++++++++++ .../assets/js/build-plugins/technical_debt.js | 79 ++++++++ 3 files changed, 263 insertions(+) create mode 100755 PHPCI/Plugin/TechnicalDebt.php create mode 100755 public/assets/js/build-plugins/technical_debt.js diff --git a/PHPCI/Languages/lang.en.php b/PHPCI/Languages/lang.en.php index 9718e442..5f21d3dc 100644 --- a/PHPCI/Languages/lang.en.php +++ b/PHPCI/Languages/lang.en.php @@ -183,6 +183,7 @@ PHPCI', 'phpmd' => 'PHP Mess Detector', 'phpspec' => 'PHP Spec', 'phpunit' => 'PHP Unit', + 'technical_debt' => 'Technical Debt', 'file' => 'File', 'line' => 'Line', diff --git a/PHPCI/Plugin/TechnicalDebt.php b/PHPCI/Plugin/TechnicalDebt.php new file mode 100755 index 00000000..4d82dd25 --- /dev/null +++ b/PHPCI/Plugin/TechnicalDebt.php @@ -0,0 +1,183 @@ + +* @package PHPCI +* @subpackage Plugins +*/ +class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin +{ + /** + * @var \PHPCI\Builder + */ + protected $phpci; + + /** + * @var array + */ + protected $suffixes; + + /** + * @var string + */ + protected $directory; + + /** + * @var int + */ + protected $allowed_errors; + + /** + * @var int + */ + protected $allowed_warnings; + + /** + * @var string, based on the assumption the root may not hold the code to be + * tested, extends the base path + */ + protected $path; + + /** + * @var array - paths to ignore + */ + protected $ignore; + + /** + * @var array - terms to search for + */ + protected $searches; + + public static function canExecute($stage, Builder $builder, Build $build) + { + if ($stage == 'test') { + return true; + } + + return false; + } + + /** + * @param \PHPCI\Builder $phpci + * @param \PHPCI\Model\Build $build + * @param array $options + */ + public function __construct(Builder $phpci, Build $build, array $options = array()) + { + $this->phpci = $phpci; + $this->build = $build; + $this->suffixes = array('php'); + $this->directory = $phpci->buildPath; + $this->path = ''; + $this->ignore = $this->phpci->ignore; + $this->allowed_warnings = 0; + $this->allowed_errors = 0; + $this->searches = array('TODO', 'FIXME', 'TO DO', 'FIX ME'); + + if (isset($options['searches']) && is_array($options['searches'])) { + $this->searches = $options['searches']; + } + + if (isset($options['zero_config']) && $options['zero_config']) { + $this->allowed_warnings = -1; + $this->allowed_errors = -1; + } + } + + protected function setOptions($options) + { + foreach (array('directory', 'path', 'ignore', 'allowed_warnings', 'allowed_errors') as $key) { + if (array_key_exists($key, $options)) { + $this->{$key} = $options[$key]; + } + } + } + + /** + * Runs in a specified directory, to a specified standard. + */ + public function execute() + { + $this->phpci->logExecOutput(false); + + $ignores = $this->ignore; + $ignores[] = 'phpci.yml'; + + $dirIterator = new \RecursiveDirectoryIterator($this->directory); + $iterator = new \RecursiveIteratorIterator($dirIterator, \RecursiveIteratorIterator::SELF_FIRST); + $files = []; + + foreach ($iterator as $file) { + $filePath = $file->getRealPath(); + $skipFile = false; + foreach ($ignores as $ignore) { + if (stripos($filePath, $ignore) !== false) { + $skipFile = true; + break; + } + } + + // Ignore hidden files, else .git, .sass_cache, etc. all get looped over + if (stripos($filePath, '/.') !== false) { + $skipFile = true; + } + + if ($skipFile == false) { + $files[] = $file->getRealPath(); + } + } + + $files = array_filter(array_unique($files)); + $errorCount = 0; + $data = array(); + + foreach ($files as $file) { + foreach ($this->searches as $search) { + $fileContent = file_get_contents($file); + $allLines = explode(PHP_EOL, $fileContent); + $beforeString = strstr($fileContent, $search, true); + + if (false !== $beforeString) { + $lines = explode(PHP_EOL, $beforeString); + $lineNumber = count($lines); + $content = trim($allLines[$lineNumber - 1]); + + $errorCount++; + $this->phpci->log("Found $search on line $lineNumber of $file:\n$content"); + $data[] = array( + 'file' => str_replace($this->directory, '', $file), + 'line' => $lineNumber, + 'message' => $content + ); + } + } + } + + $this->phpci->log("Found $errorCount instances of " . implode(', ', $this->searches)); + + $this->build->storeMeta('technical_debt-warnings', $errorCount); + $this->build->storeMeta('technical_debt-data', $data); + + if ($this->allowed_errors != -1 && $errorCount > $this->allowed_errors) { + $success = false; + } + + return $success; + } +} + diff --git a/public/assets/js/build-plugins/technical_debt.js b/public/assets/js/build-plugins/technical_debt.js new file mode 100755 index 00000000..a187401d --- /dev/null +++ b/public/assets/js/build-plugins/technical_debt.js @@ -0,0 +1,79 @@ +var TechnicalDebtPlugin = ActiveBuild.UiPlugin.extend({ + id: 'build-technical_debt', + css: 'col-lg-6 col-md-12 col-sm-12 col-xs-12', + title: Lang.get('technical_debt'), + lastData: null, + box: true, + rendered: false, + + register: function() { + var self = this; + var query = ActiveBuild.registerQuery('technical_debt-data', -1, {key: 'technical_debt-data'}) + + $(window).on('technical_debt-data', function(data) { + self.onUpdate(data); + }); + + $(window).on('build-updated', function() { + if (!self.rendered) { + query(); + } + }); + }, + + render: function() { + return $('
' + + '' + + '' + + ' ' + + ' ' + + ' ' + + '' + + '
'+Lang.get('file')+''+Lang.get('line')+''+Lang.get('message')+'
'); + }, + + onUpdate: function(e) { + if (!e.queryData) { + $('#build-technical_debt').hide(); + return; + } + + this.rendered = true; + this.lastData = e.queryData; + + var errors = this.lastData[0].meta_value; + var tbody = $('#technical_debt-data tbody'); + tbody.empty(); + + if (errors.length == 0) { + $('#build-technical_debt').hide(); + return; + } + + for (var i in errors) { + var file = errors[i].file; + + if (ActiveBuild.fileLinkTemplate) { + var fileLink = ActiveBuild.fileLinkTemplate.replace('{FILE}', file); + fileLink = fileLink.replace('{LINE}', errors[i].line); + + file = '' + file + ''; + } + + var row = $('' + + ''+file+'' + + ''+errors[i].line+'' + + ''+errors[i].message+''); + + if (errors[i].type == 'ERROR') { + row.addClass('danger'); + } + + tbody.append(row); + } + + $('#build-technical_debt').show(); + } +}); + +ActiveBuild.registerPlugin(new TechnicalDebtPlugin()); From 2a5ac8ccbcd478de08f036c5ababd4099c5b49e8 Mon Sep 17 00:00:00 2001 From: James Inman Date: Wed, 18 Feb 2015 14:15:59 +0000 Subject: [PATCH 16/20] PHPCS/DocBlock fixes to Technical Debt plugin. --- PHPCI/Plugin/TechnicalDebt.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/PHPCI/Plugin/TechnicalDebt.php b/PHPCI/Plugin/TechnicalDebt.php index 4d82dd25..408f40fb 100755 --- a/PHPCI/Plugin/TechnicalDebt.php +++ b/PHPCI/Plugin/TechnicalDebt.php @@ -63,6 +63,15 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ protected $searches; + + /** + * Check if this plugin can be executed. + * + * @param $stage + * @param Builder $builder + * @param Build $build + * @return bool + */ public static function canExecute($stage, Builder $builder, Build $build) { if ($stage == 'test') { @@ -99,6 +108,10 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } } + /** + * Handle this plugin's options. + * @param $options + */ protected function setOptions($options) { foreach (array('directory', 'path', 'ignore', 'allowed_warnings', 'allowed_errors') as $key) { @@ -123,7 +136,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin $files = []; foreach ($iterator as $file) { - $filePath = $file->getRealPath(); + $filePath = $file->getRealPath(); $skipFile = false; foreach ($ignores as $ignore) { if (stripos($filePath, $ignore) !== false) { @@ -168,7 +181,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } } - $this->phpci->log("Found $errorCount instances of " . implode(', ', $this->searches)); + $this->phpci->log("Found $errorCount instances of " . implode(', ', $this->searches)); $this->build->storeMeta('technical_debt-warnings', $errorCount); $this->build->storeMeta('technical_debt-data', $data); @@ -180,4 +193,3 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin return $success; } } - From d6f72b0b7e66c74ae70db440d379a3000637279d Mon Sep 17 00:00:00 2001 From: James Inman Date: Wed, 18 Feb 2015 14:26:21 +0000 Subject: [PATCH 17/20] PHPCS/PHPMD fixes for Technical Debt plugin. --- PHPCI/Plugin/TechnicalDebt.php | 40 +++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/PHPCI/Plugin/TechnicalDebt.php b/PHPCI/Plugin/TechnicalDebt.php index 408f40fb..71ff0052 100755 --- a/PHPCI/Plugin/TechnicalDebt.php +++ b/PHPCI/Plugin/TechnicalDebt.php @@ -122,21 +122,42 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } /** - * Runs in a specified directory, to a specified standard. + * Runs the plugin */ public function execute() { $this->phpci->logExecOutput(false); - $ignores = $this->ignore; - $ignores[] = 'phpci.yml'; + list($errorCount, $data) = $this->getErrorList(); + $this->phpci->log("Found $errorCount instances of " . implode(', ', $this->searches)); + + $this->build->storeMeta('technical_debt-warnings', $errorCount); + $this->build->storeMeta('technical_debt-data', $data); + + if ($this->allowed_errors != -1 && $errorCount > $this->allowed_errors) { + $success = false; + } + + return $success; + } + + /** + * Gets the number and list of errors returned from the search + * + * @return array + */ + public function getErrorList() + { $dirIterator = new \RecursiveDirectoryIterator($this->directory); $iterator = new \RecursiveIteratorIterator($dirIterator, \RecursiveIteratorIterator::SELF_FIRST); $files = []; + $ignores = $this->ignore; + $ignores[] = 'phpci.yml'; + foreach ($iterator as $file) { - $filePath = $file->getRealPath(); + $filePath = $file->getRealPath(); $skipFile = false; foreach ($ignores as $ignore) { if (stripos($filePath, $ignore) !== false) { @@ -180,16 +201,5 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } } } - - $this->phpci->log("Found $errorCount instances of " . implode(', ', $this->searches)); - - $this->build->storeMeta('technical_debt-warnings', $errorCount); - $this->build->storeMeta('technical_debt-data', $data); - - if ($this->allowed_errors != -1 && $errorCount > $this->allowed_errors) { - $success = false; - } - - return $success; } } From 5bb68507d836bf94be3c7ebd8a87f5411311224f Mon Sep 17 00:00:00 2001 From: James Inman Date: Wed, 18 Feb 2015 14:56:04 +0000 Subject: [PATCH 18/20] Fixing Technical Debt error message. --- PHPCI/Plugin/TechnicalDebt.php | 1 + 1 file changed, 1 insertion(+) diff --git a/PHPCI/Plugin/TechnicalDebt.php b/PHPCI/Plugin/TechnicalDebt.php index 71ff0052..c10e7d29 100755 --- a/PHPCI/Plugin/TechnicalDebt.php +++ b/PHPCI/Plugin/TechnicalDebt.php @@ -126,6 +126,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin */ public function execute() { + $success = true; $this->phpci->logExecOutput(false); list($errorCount, $data) = $this->getErrorList(); From bf6ac530a67e0385032ed653338c34625fec82b8 Mon Sep 17 00:00:00 2001 From: Jon Gotlin Date: Thu, 4 Dec 2014 12:31:21 +0100 Subject: [PATCH 19/20] Create admin command cleanup --- .gitignore | 1 + PHPCI/Command/CreateAdminCommand.php | 129 ++++++------------ PHPCI/Command/InstallCommand.php | 6 +- .../PHPCI/Command/CreateAdminCommandTest.php | 78 +++++++++++ console | 5 +- 5 files changed, 129 insertions(+), 90 deletions(-) create mode 100644 Tests/PHPCI/Command/CreateAdminCommandTest.php diff --git a/.gitignore b/.gitignore index 79784a60..63e81c5b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ PHPCI/Model/Base/MigrationBase.php PHPCI/Store/MigrationStore.php PHPCI/Store/Base/MigrationStoreBase.php local_vars.php +Tests/PHPCI/config.yml diff --git a/PHPCI/Command/CreateAdminCommand.php b/PHPCI/Command/CreateAdminCommand.php index 3b69afd3..265f03b4 100644 --- a/PHPCI/Command/CreateAdminCommand.php +++ b/PHPCI/Command/CreateAdminCommand.php @@ -9,21 +9,36 @@ namespace PHPCI\Command; -use PHPCI\Helper\Lang; use PHPCI\Service\UserService; +use PHPCI\Helper\Lang; +use PHPCI\Store\UserStore; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -use b8\Store\Factory; /** -* Create admin command - creates an admin user -* @author Wogan May (@woganmay) -* @package PHPCI -* @subpackage Console -*/ + * Create admin command - creates an admin user + * @author Wogan May (@woganmay) + * @package PHPCI + * @subpackage Console + */ class CreateAdminCommand extends Command { + /** + * @var UserStore + */ + protected $userStore; + + /** + * @param UserStore $userStore + */ + public function __construct(UserStore $userStore) + { + parent::__construct(); + + $this->userStore = $userStore; + } + protected function configure() { $this @@ -32,92 +47,36 @@ class CreateAdminCommand extends Command } /** - * Creates an admin user in the existing PHPCI database - */ + * Creates an admin user in the existing PHPCI database + * + * {@inheritDoc} + */ protected function execute(InputInterface $input, OutputInterface $output) { - $userStore = Factory::getStore('User'); - $userService = new UserService($userStore); + $userService = new UserService($this->userStore); - require(PHPCI_DIR . 'bootstrap.php'); + /** @var $dialog \Symfony\Component\Console\Helper\DialogHelper */ + $dialog = $this->getHelperSet()->get('dialog'); - // Try to create a user account: - $adminEmail = $this->ask(Lang::get('enter_email'), true, FILTER_VALIDATE_EMAIL); + // Function to validate mail address. + $mailValidator = function ($answer) { + if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) { + throw new \InvalidArgumentException(Lang::get('must_be_valid_email')); + } - if (empty($adminEmail)) { - return; - } + return $answer; + }; - $adminPass = $this->ask(Lang::get('enter_pass')); - $adminName = $this->ask(Lang::get('enter_name')); + $adminEmail = $dialog->askAndValidate($output, Lang::get('enter_email'), $mailValidator, false); + $adminName = $dialog->ask($output, Lang::get('enter_name')); + $adminPass = $dialog->askHiddenResponse($output, Lang::get('enter_password')); try { - $userService->createUser($adminName, $adminEmail, $adminPass, 1); - print Lang::get('user_created') . PHP_EOL; - } catch (\Exception $ex) { - print Lang::get('failed_to_create') . PHP_EOL; - print $ex->getMessage(); - print PHP_EOL; + $userService->createUser($adminName, $adminEmail, $adminPass, true); + $output->writeln(Lang::get('user_created')); + } catch (\Exception $e) { + $output->writeln(sprintf('%s', Lang::get('failed_to_create'))); + $output->writeln(sprintf('%s', $e->getMessage())); } } - - protected function ask($question, $emptyOk = false, $validationFilter = null) - { - print $question . ' '; - - $rtn = ''; - $stdin = fopen('php://stdin', 'r'); - $rtn = fgets($stdin); - fclose($stdin); - - $rtn = trim($rtn); - - if (!$emptyOk && empty($rtn)) { - $rtn = $this->ask($question, $emptyOk, $validationFilter); - } elseif (!is_null($validationFilter) && ! empty($rtn)) { - if (! $this -> controlFormat($rtn, $validationFilter, $statusMessage)) { - print $statusMessage; - $rtn = $this->ask($question, $emptyOk, $validationFilter); - } - } - - return $rtn; - } - protected function controlFormat($valueToInspect, $filter, &$statusMessage) - { - $filters = !(is_array($filter))? array($filter) : $filter; - $statusMessage = ''; - $status = true; - $options = array(); - - foreach ($filters as $filter) { - if (! is_int($filter)) { - $regexp = $filter; - $filter = FILTER_VALIDATE_REGEXP; - $options = array( - 'options' => array( - 'regexp' => $regexp, - ) - ); - } - if (! filter_var($valueToInspect, $filter, $options)) { - $status = false; - - switch ($filter) - { - case FILTER_VALIDATE_URL: - $statusMessage = Lang::get('must_be_valid_url') . PHP_EOL; - break; - case FILTER_VALIDATE_EMAIL: - $statusMessage = Lang::get('must_be_valid_email') . PHP_EOL; - break; - case FILTER_VALIDATE_REGEXP: - $statusMessage = Lang::get('incorrect_format') . PHP_EOL; - break; - } - } - } - - return $status; - } } diff --git a/PHPCI/Command/InstallCommand.php b/PHPCI/Command/InstallCommand.php index d262b9f0..04e0f2dd 100644 --- a/PHPCI/Command/InstallCommand.php +++ b/PHPCI/Command/InstallCommand.php @@ -95,7 +95,7 @@ class InstallCommand extends Command $this->writeConfigFile($conf); $this->setupDatabase($output); - $admin = $this->getAdminInforamtion($input, $output); + $admin = $this->getAdminInformation($input, $output); $this->createAdminUser($admin, $output); } @@ -160,7 +160,7 @@ class InstallCommand extends Command * @param OutputInterface $output * @return array */ - protected function getAdminInforamtion(InputInterface $input, OutputInterface $output) + protected function getAdminInformation(InputInterface $input, OutputInterface $output) { $admin = array(); @@ -172,7 +172,7 @@ class InstallCommand extends Command // Function to validate mail address. $mailValidator = function ($answer) { if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) { - throw new Exception(Lang::get('must_be_valid_email')); + throw new \InvalidArgumentException(Lang::get('must_be_valid_email')); } return $answer; diff --git a/Tests/PHPCI/Command/CreateAdminCommandTest.php b/Tests/PHPCI/Command/CreateAdminCommandTest.php new file mode 100644 index 00000000..738d8f8a --- /dev/null +++ b/Tests/PHPCI/Command/CreateAdminCommandTest.php @@ -0,0 +1,78 @@ +command = $this->getMockBuilder('PHPCI\\Command\\CreateAdminCommand') + ->setConstructorArgs([$this->getMock('PHPCI\\Store\\UserStore')]) + ->setMethods(['reloadConfig']) + ->getMock() + ; + + $this->dialog = $this->getMockBuilder('Symfony\\Component\\Console\\Helper\\DialogHelper') + ->setMethods([ + 'ask', + 'askAndValidate', + 'askHiddenResponse', + ]) + ->getMock() + ; + + $this->application = new Application(); + } + + /** + * @return CommandTester + */ + protected function getCommandTester() + { + $this->application->getHelperSet()->set($this->dialog, 'dialog'); + $this->application->add($this->command); + $command = $this->application->find('phpci:create-admin'); + $commandTester = new CommandTester($command); + + return $commandTester; + } + + public function testExecute() + { + $this->dialog->expects($this->at(0))->method('askAndValidate')->will($this->returnValue('test@example.com')); + $this->dialog->expects($this->at(1))->method('ask')->will($this->returnValue('A name')); + $this->dialog->expects($this->at(2))->method('askHiddenResponse')->will($this->returnValue('foobar123')); + + $commandTester = $this->getCommandTester(); + $commandTester->execute([]); + + $this->assertEquals('User account created!' . PHP_EOL, $commandTester->getDisplay()); + } +} diff --git a/console b/console index 43fc2b8f..782cc2d0 100755 --- a/console +++ b/console @@ -20,6 +20,7 @@ use PHPCI\Command\DaemonCommand; use PHPCI\Command\PollCommand; use PHPCI\Command\CreateAdminCommand; use Symfony\Component\Console\Application; +use b8\Store\Factory; $application = new Application(); @@ -29,6 +30,6 @@ $application->add(new UpdateCommand($loggerConfig->getFor('UpdateCommand'))); $application->add(new GenerateCommand); $application->add(new DaemonCommand($loggerConfig->getFor('DaemonCommand'))); $application->add(new PollCommand($loggerConfig->getFor('PollCommand'))); -$application->add(new CreateAdminCommand); +$application->add(new CreateAdminCommand(Factory::getStore('User'))); -$application->run(); \ No newline at end of file +$application->run(); From 6c8df9a8cee8fe5a5c85cd6a9b937f11cdfd92dc Mon Sep 17 00:00:00 2001 From: James Inman Date: Thu, 19 Feb 2015 13:37:35 +0000 Subject: [PATCH 20/20] Fix missing return statement in Technical Debt. --- PHPCI/Plugin/TechnicalDebt.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PHPCI/Plugin/TechnicalDebt.php b/PHPCI/Plugin/TechnicalDebt.php index c10e7d29..fed76566 100755 --- a/PHPCI/Plugin/TechnicalDebt.php +++ b/PHPCI/Plugin/TechnicalDebt.php @@ -202,5 +202,7 @@ class TechnicalDebt implements PHPCI\Plugin, PHPCI\ZeroConfigPlugin } } } + + return array($errorCount, $data); } }