Page MenuHomeDevCentral

D531.id1295.diff
No OneTemporary

D531.id1295.diff

diff --git a/app/Jobs/NotifyNewCommitsToDiffusion.php b/app/Jobs/NotifyNewCommitsToDiffusion.php
new file mode 100644
--- /dev/null
+++ b/app/Jobs/NotifyNewCommitsToDiffusion.php
@@ -0,0 +1,194 @@
+<?php
+
+namespace Nasqueron\Notifications\Jobs;
+
+use Nasqueron\Notifications\Actions\ActionError;
+use Nasqueron\Notifications\Actions\NotifyNewCommitsAction;
+use Nasqueron\Notifications\Events\ReportEvent;
+use Nasqueron\Notifications\Phabricator\PhabricatorAPI as API;
+use Nasqueron\Notifications\Phabricator\PhabricatorAPIException;
+
+
+use Event;
+use PhabricatorAPI;
+
+/**
+ * This class allows to notify Phabricator of new commits, so daemons can pull
+ * these new commits and add them into Diffusion.
+ */
+class NotifyNewCommitsToDiffusion extends Job {
+
+ ///
+ /// Private members
+ ///
+
+ /**
+ * The clone URL of the repository
+ *
+ * @var string
+ */
+ private $repository;
+
+ /**
+ * @var \Nasqueron\Notifications\Phabricator\PhabricatorAPI
+ */
+ private $api;
+
+ /**
+ * @var string
+ */
+ private $callSign;
+
+ /**
+ * @var NotifyNewCommitsAction
+ */
+ private $actionToReport;
+
+ /**
+ * @var string
+ */
+ private $sourceProject;
+
+ ///
+ /// Constructor
+ ///
+
+ /**
+ * Initializes a new instance of NotifyNewCommitsToDiffusion.
+ */
+ public function __construct ($sourceProject, $repository) {
+ $this->sourceProject = $sourceProject;
+ $this->repository = $repository;
+ }
+
+ ///
+ /// Helper methods to find correct Phabricator instance and get the API
+ ///
+
+ /**
+ * Gets the relevant Phabricator project for the specified source project.
+ *
+ * @return string The Phabricator project name
+ */
+ private function getPhabricatorProject () {
+ return $this->sourceProject;
+ }
+
+ ///
+ /// Helper methods to populate object members
+ ///
+
+ /**
+ * Fetches API and call sign.
+ *
+ * @return bool true if all requirement have been fetched ; otherwise, false.
+ */
+ private function fetchRequirements () {
+ return $this->fetchAPI() && $this->fetchCallSign();
+ }
+
+ /**
+ * Fetches the Phabricator API to use for the current source project.
+ *
+ * @return bool true if an API instance has been fetch ; otherwise, false.
+ */
+ private function fetchAPI () {
+ $project = $this->getPhabricatorProject();
+ $this->api = PhabricatorAPI::getForProject($project);
+
+ return $this->api !== null;
+ }
+
+ /**
+ * Fetches the call sign matching the repository.
+ *
+ * @return bool true if a call sign have been found ; otherwise, false.
+ */
+ private function fetchCallSign () {
+ $this->callSign = $this->getCallSign();
+
+ return $this->callSign !== "";
+ }
+
+ ///
+ /// Helper methods to query Phabricator API
+ ///
+
+ /**
+ * Gets the call sign matching the repository URL.
+ *
+ * @return string the repository call sign "OPS", or "" if not in Phabricator
+ */
+ private function getCallSign () {
+ $reply = $this->api->call(
+ 'repository.query',
+ [ 'remoteURIs[0]' => $this->repository ]
+ );
+
+ if (!count($reply)) {
+ return "";
+ }
+
+ return API::getFirstResult($reply)->callsign;
+ }
+
+ /**
+ * Calls the diffusion.looksoon API method.
+ *
+ * @throws PhabricatorAPIException
+ */
+ private function callDiffusionLookSoon () {
+ $this->api->call(
+ 'diffusion.looksoon',
+ [ 'callsigns[0]' => $this->callSign ]
+ );
+ }
+
+ ///
+ /// Task
+ ///
+
+ /**
+ * Executes the job.
+ *
+ * @return void
+ */
+ public function handle () {
+ if (!$this->fetchRequirements()) {
+ return;
+ }
+
+ $this->initializeReport();
+ $this->notifyPhabricator();
+ $this->sendReport();
+ }
+
+
+ /**
+ * Initializes the actions report.
+ */
+ private function initializeReport () {
+ $this->actionToReport = new NotifyNewCommitsAction($this->callSign);
+ }
+
+ /**
+ * Notifies Phabricator to pull from the repository.
+ */
+ private function notifyPhabricator () {
+ try {
+ $this->callDiffusionLookSoon();
+ } catch (PhabricatorAPIException $ex) {
+ $actionError = new ActionError($ex);
+ $this->actionToReport->attachError($actionError);
+ }
+ }
+
+ /**
+ * Fires a report event with the actions report.
+ */
+ private function sendReport () {
+ $event = new ReportEvent($this->actionToReport);
+ Event::fire($event);
+ }
+
+}
diff --git a/app/Listeners/PhabricatorListener.php b/app/Listeners/PhabricatorListener.php
--- a/app/Listeners/PhabricatorListener.php
+++ b/app/Listeners/PhabricatorListener.php
@@ -2,22 +2,26 @@
namespace Nasqueron\Notifications\Listeners;
-use Nasqueron\Notifications\Actions\ActionError;
-use Nasqueron\Notifications\Actions\NotifyNewCommitsAction;
+/**
+ * Verified:
+ */
+
use Nasqueron\Notifications\Events\GitHubPayloadEvent;
-use Nasqueron\Notifications\Events\ReportEvent;
-use Nasqueron\Notifications\Phabricator\PhabricatorAPI;
-use Nasqueron\Notifications\Phabricator\PhabricatorAPIException;
+use Nasqueron\Notifications\Jobs\NotifyNewCommitsToDiffusion;
-use Event;
+use Illuminate\Events\Dispatcher;
+/**
+ * Listens to events Phabricator is interested by.
+ */
class PhabricatorListener {
+
///
/// GitHub → Phabricator
///
/**
- * Handles payload events
+ * Handles payload events.
*
* @param GitHubPayloadEvent $event The GitHub payload event
*/
@@ -28,51 +32,16 @@
}
/**
- * @return string the repository call sign "OPS", or "" if not in Phabricator
- */
- private static function getCallSign (PhabricatorAPI $api, $remoteURI) {
- $reply = $api->call(
- 'repository.query',
- [ 'remoteURIs[0]' => $remoteURI ]
- );
-
- if (!count($reply)) {
- return "";
- }
-
- return PhabricatorAPI::getFirstResult($reply)->callsign;
- }
-
- /**
- * Notifies Phabricator there are new commits to pull
+ * Notifies Phabricator there are new commits to pull.
+ *
+ * @param GitHubPayloadEvent $event The GitHub payload event
*/
public function notifyNewCommits (GitHubPayloadEvent $event) {
- $api = PhabricatorAPI::forProject($event->door);
- if (!$api) {
- // We don't have a Phabricator instance for this project.
- return;
- }
-
- $callSign = static::getCallSign(
- $api,
+ $job = new NotifyNewCommitsToDiffusion(
+ $event->door,
$event->payload->repository->clone_url
);
-
- if ($callSign === "") {
- return;
- }
-
- $actionToReport = new NotifyNewCommitsAction($callSign);
- try {
- $api->call(
- 'diffusion.looksoon',
- [ 'callsigns[0]' => $callSign ]
- );
- } catch (PhabricatorAPIException $ex) {
- $actionToReport->attachError(new ActionError($ex));
- }
-
- Event::fire(new ReportEvent($actionToReport));
+ $job->handle();
}
///
@@ -80,14 +49,14 @@
///
/**
- * Register the listeners for the subscriber.
+ * Registers the listeners for the subscriber.
*
- * @param Illuminate\Events\Dispatcher $events
+ * @param Dispatcher $events
*/
- public function subscribe (\Illuminate\Events\Dispatcher $events) {
- $class = 'Nasqueron\Notifications\Listeners\PhabricatorListener';
+ public function subscribe (Dispatcher $events) {
+ $class = PhabricatorListener::class;
$events->listen(
- 'Nasqueron\Notifications\Events\GitHubPayloadEvent',
+ GitHubPayloadEvent::class,
"$class@onGitHubPayload"
);
}
diff --git a/tests/Jobs/NotifyNewCommitsToDiffusionTest.php b/tests/Jobs/NotifyNewCommitsToDiffusionTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Jobs/NotifyNewCommitsToDiffusionTest.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Jobs;
+
+use Nasqueron\Notifications\Jobs\NotifyNewCommitsToDiffusion;
+use Nasqueron\Notifications\Phabricator\PhabricatorAPI;
+use Nasqueron\Notifications\Tests\TestCase;
+
+use Mockery;
+
+class NotifyNewCommitsToDiffusionTest extends TestCase {
+
+ /**
+ * Mock for the Phabricator API factory
+ * @var \Mockery\MockInterface
+ */
+ private $apiFactoryMock;
+
+ /**
+ * The job to test
+ * @var NotifyNewCommitsToDiffusion
+ */
+ private $job;
+
+ public function setUp () {
+ parent::setUp();
+
+ $this->apiFactoryMock = $this->mockPhabricatorAPI();
+ $this->job = $this->mockJob();
+ }
+
+ /**
+ * @return NotifyNewCommitsToDiffusion
+ */
+ protected function mockJob() {
+ return new NotifyNewCommitsToDiffusion("acme", "ssh://acme/k2.git");
+ }
+
+ public function testJobWantsPhabricatorAPI () {
+ $this->apiFactoryMock->shouldReceive('getForProject')->once();
+ $this->job->handle();
+ }
+
+}
\ No newline at end of file

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 7, 04:26 (10 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2179855
Default Alt Text
D531.id1295.diff (9 KB)

Event Timeline