Page MenuHomeDevCentral

D317.diff
No OneTemporary

D317.diff

diff --git a/app/Facades/PhabricatorAPI.php b/app/Facades/PhabricatorAPI.php
new file mode 100644
--- /dev/null
+++ b/app/Facades/PhabricatorAPI.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Nasqueron\Notifications\Facades;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * @see \Nasqueron\Notifications\Phabricator\PhabricatorAPIFactory
+ */
+class PhabricatorAPI extends Facade {
+
+ /**
+ * Gets the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor() {
+ return 'phabricator-api';
+ }
+
+}
diff --git a/app/Facades/ProjectsMap.php b/app/Facades/ProjectsMap.php
new file mode 100644
--- /dev/null
+++ b/app/Facades/ProjectsMap.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Nasqueron\Notifications\Facades;
+
+use Illuminate\Support\Facades\Facade;
+
+/**
+ * @see \Nasqueron\Notifications\Phabricator\PhabricatorAPIFactory
+ */
+class ProjectsMap extends Facade {
+
+ /**
+ * Gets the registered name of the component.
+ *
+ * @return string
+ */
+ protected static function getFacadeAccessor() {
+ return 'phabricator-projectsmap';
+ }
+
+}
diff --git a/app/Phabricator/PhabricatorAPIFactory.php b/app/Phabricator/PhabricatorAPIFactory.php
new file mode 100644
--- /dev/null
+++ b/app/Phabricator/PhabricatorAPIFactory.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Nasqueron\Notifications\Phabricator;
+
+class PhabricatorAPIFactory {
+
+ /**
+ * Gets an instance of the Phabricator API client class
+ *
+ * @param string $instance The Phabricator instance
+ * @return Nasqueron\Notifications\Phabricator\PhabricatorAPI
+ */
+ public function get ($instance) {
+ return PhabricatorAPI::forInstance($instance);
+ }
+
+ /**
+ * Gets an instance of the Phabricator API client class for a project
+ *
+ * @param string $project The Phabricator project name
+ * @return Nasqueron\Notifications\Phabricator\PhabricatorAPI
+ */
+ public function getForProject ($project) {
+ return PhabricatorAPI::forProject($project);
+ }
+}
diff --git a/app/Phabricator/ProjectsMap.php b/app/Phabricator/ProjectsMap.php
--- a/app/Phabricator/ProjectsMap.php
+++ b/app/Phabricator/ProjectsMap.php
@@ -11,29 +11,29 @@
///
/**
- * The maximum number of projects to fetch
- */
+ * The maximum number of projects to fetch
+ */
const LIMIT = 1000;
/**
- * The projects as an array with phid as keys, project names as $value
- *
- * @var string[]
- */
+ * The projects as an array with phid as keys, project names as $value
+ *
+ * @var string[]
+ */
private $map = [];
/**
- * The Phabricator instance for this projects map
- *
- * @var string
- */
+ * The Phabricator instance for this projects map
+ *
+ * @var string
+ */
private $instance;
/**
- * The source of the map
- *
- * @var string
- */
+ * The source of the map
+ *
+ * @var string
+ */
private $source = 'unloaded';
///
@@ -41,10 +41,10 @@
///
/**
- * Initializes a new instance of ProjectsMap
- *
- * @param string $instance The Phabricator root URL without trailing slash
- */
+ * Initializes a new instance of ProjectsMap
+ *
+ * @param string $instance The Phabricator root URL without trailing slash
+ */
public function __construct ($instance) {
$this->instance = $instance;
}
@@ -54,10 +54,10 @@
///
/**
- * Gets iterator
- *
- * @return Traversable
- */
+ * Gets iterator
+ *
+ * @return Traversable
+ */
public function getIterator ( ) {
return new \ArrayIterator($this->map);
}
@@ -67,39 +67,39 @@
///
/**
- * Determines whether an offset exists
- *
- * @param mixed $offset The offset
- */
+ * Determines whether an offset exists
+ *
+ * @param mixed $offset The offset
+ */
public function offsetExists ($offset) {
return array_key_exists($offset, $this->map);
}
/**
- * Gets an offset
- *
- * @param mixed $offset The offset
- * @return mixed The value
- */
+ * Gets an offset
+ *
+ * @param mixed $offset The offset
+ * @return mixed The value
+ */
public function offsetGet ($offset) {
return $this->map[$offset];
}
/**
- * Assigns a value to the specified offset
- *
- * @param mixed $offset The offset
- * @param mixed $value The value to assign
- */
+ * Assigns a value to the specified offset
+ *
+ * @param mixed $offset The offset
+ * @param mixed $value The value to assign
+ */
public function offsetSet ($offset, $value) {
$this->map[$offset] = $value;
}
/**
- * Unset an offset
- *
- * @param mixed $offset The offset
- */
+ * Unset an offset
+ *
+ * @param mixed $offset The offset
+ */
public function offsetUnset ($offset) {
unset($this->map[$offset]);
}
@@ -109,33 +109,33 @@
///
/**
- * Gets a new ProjectsMap instance from cache or API when not cached
- *
- * @param string $phabricatorURL The Phabricator URL (e.g. http://secure.phabricator.com)
- * @return ProjectsMap
- */
+ * Gets a new ProjectsMap instance from cache or API when not cached
+ *
+ * @param string $phabricatorURL The Phabricator URL (e.g. http://secure.phabricator.com)
+ * @return ProjectsMap
+ */
public static function load ($phabricatorURL) {
- $instance = new self($phabricatorURL);
+ $instance = new self($phabricatorURL);
- if ($instance->isCached()) {
- $instance->loadFromCache();
- } else {
- $instance->fetchFromAPI();
- }
+ if ($instance->isCached()) {
+ $instance->loadFromCache();
+ } else {
+ $instance->fetchFromAPI();
+ }
- return $instance;
+ return $instance;
}
/**
- * Gets a new ProjectsMap instance and queries Phabricator API to fill it
- *
- * @param string $phabricatorURL The Phabricator URL (e.g. http://secure.phabricator.com)
- * @return ProjectsMap
- */
+ * Gets a new ProjectsMap instance and queries Phabricator API to fill it
+ *
+ * @param string $phabricatorURL The Phabricator URL (e.g. http://secure.phabricator.com)
+ * @return ProjectsMap
+ */
public static function fetch ($phabricatorURL) {
- $instance = new self($phabricatorURL);
- $instance->fetchFromAPI();
- return $instance;
+ $instance = new self($phabricatorURL);
+ $instance->fetchFromAPI();
+ return $instance;
}
///
@@ -143,27 +143,27 @@
///
/**
- * Fetches the projects' map from the Phabricator API
- */
+ * Fetches the projects' map from the Phabricator API
+ */
private function fetchFromAPI () {
- $reply = PhabricatorAPI::forInstance($this->instance)->call(
- 'project.query',
- [ 'limit' => self::LIMIT ]
+ $reply = \PhabricatorAPI::get($this->instance)->call(
+ 'project.query',
+ [ 'limit' => self::LIMIT ]
);
- if (!$reply) {
- throw new \Exception("Empty reply calling project.query at $this->instance API.");
- }
+ if (!$reply) {
+ throw new \Exception("Empty reply calling project.query at $this->instance API.");
+ }
- if (!property_exists($reply, 'data')) {
- throw new \Exception("Invalid reply calling project.query at $this->instance API.");
- }
+ if (!property_exists($reply, 'data')) {
+ throw new \Exception("Invalid reply calling project.query at $this->instance API.");
+ }
- foreach ($reply->data as $phid => $projectInfo) {
- $this->offsetSet($phid, $projectInfo->name);
- }
+ foreach ($reply->data as $phid => $projectInfo) {
+ $this->offsetSet($phid, $projectInfo->name);
+ }
- $this->source = 'api';
+ $this->source = 'api';
}
///
@@ -171,35 +171,35 @@
///
/**
- * Gets cache key
- *
- * @return string The cache key for the current projects map
- */
+ * Gets cache key
+ *
+ * @return string The cache key for the current projects map
+ */
private function getCacheKey () {
return class_basename(get_class($this)) . '-' . md5($this->instance);
}
/**
- * Determines if the instance is cached
- *
- * @return bool true if cached; otherwise, false.
- */
+ * Determines if the instance is cached
+ *
+ * @return bool true if cached; otherwise, false.
+ */
public function isCached () {
return Cache::has($this->getCacheKey());
}
/**
- * Saves data to cache
- */
+ * Saves data to cache
+ */
public function saveToCache () {
Cache::forever($this->getCacheKey(), $this->map);
}
/**
- * Loads data from cache
- *
- * Populates 'map' and 'source' properties
- */
+ * Loads data from cache
+ *
+ * Populates 'map' and 'source' properties
+ */
public function loadFromCache () {
$this->map = Cache::get($this->getCacheKey());
$this->source = 'cache';
@@ -210,11 +210,11 @@
///
/**
- * Gets project name, refreshing the cache if needed
- *
- * @param string $projectPHID the PHID of the project to query the name
- * @return string
- */
+ * Gets project name, refreshing the cache if needed
+ *
+ * @param string $projectPHID the PHID of the project to query the name
+ * @return string
+ */
public function getProjectName ($projectPHID) {
if ($this->offsetExists($projectPHID)) {
return $this->offsetGet($projectPHID);
@@ -229,10 +229,10 @@
}
/**
- * Returns the projects map as an array, each row ['PHID', 'project name']
- *
- * @return array
- */
+ * Returns the projects map as an array, each row ['PHID', 'project name']
+ *
+ * @return array
+ */
public function toArray () {
$array = [];
foreach ($this->map as $phid => $projectName) {
diff --git a/app/Phabricator/ProjectsMapFactory.php b/app/Phabricator/ProjectsMapFactory.php
new file mode 100644
--- /dev/null
+++ b/app/Phabricator/ProjectsMapFactory.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Nasqueron\Notifications\Phabricator;
+
+class ProjectsMapFactory {
+
+ /**
+ * Loads projects map from cache or fetches it from API if not cached
+ *
+ * @param string $instance The Phabricator instance
+ * @return Nasqueron\Notifications\Phabricator\ProjectsMap
+ */
+ public function load ($instance) {
+ return ProjectsMap::load($instance);
+ }
+
+ /**
+ * Fetches projects map from API
+ *
+ * @param string $instance The Phabricator instance
+ * @return Nasqueron\Notifications\Phabricator\ProjectsMap
+ */
+ public function fetch ($instance) {
+ return ProjectsMap::fetch($instance);
+ }
+
+}
diff --git a/app/Providers/PhabricatorAPIServiceProvider.php b/app/Providers/PhabricatorAPIServiceProvider.php
new file mode 100644
--- /dev/null
+++ b/app/Providers/PhabricatorAPIServiceProvider.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Nasqueron\Notifications\Providers;
+
+use Illuminate\Contracts\Foundation\Application;
+use Illuminate\Support\ServiceProvider;
+
+use Nasqueron\Notifications\Phabricator\PhabricatorAPIFactory;
+
+class PhabricatorAPIServiceProvider extends ServiceProvider
+{
+ /**
+ * Bootstraps the application services.
+ *
+ * @return void
+ */
+ public function boot() {
+ }
+
+ /**
+ * Registers the application services.
+ *
+ * @return void
+ */
+ public function register() {
+ $this->app->singleton('phabricator-api', function () {
+ return new PhabricatorAPIFactory;
+ });
+ }
+}
diff --git a/app/Providers/PhabricatorProjectsMapServiceProvider.php b/app/Providers/PhabricatorProjectsMapServiceProvider.php
new file mode 100644
--- /dev/null
+++ b/app/Providers/PhabricatorProjectsMapServiceProvider.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Nasqueron\Notifications\Providers;
+
+use Illuminate\Contracts\Foundation\Application;
+use Illuminate\Support\ServiceProvider;
+
+use Nasqueron\Notifications\Phabricator\ProjectsMapFactory;
+
+class PhabricatorProjectsMapServiceProvider extends ServiceProvider
+{
+ /**
+ * Bootstraps the application services.
+ *
+ * @return void
+ */
+ public function boot() {
+ }
+
+ /**
+ * Registers the application services.
+ *
+ * @return void
+ */
+ public function register() {
+ $this->app->singleton('phabricator-projectsmap', function () {
+ return new ProjectsMapFactory;
+ });
+ }
+}
diff --git a/config/app.php b/config/app.php
--- a/config/app.php
+++ b/config/app.php
@@ -172,6 +172,8 @@
Nasqueron\Notifications\Providers\AppServiceProvider::class,
Nasqueron\Notifications\Providers\BrokerServiceProvider::class,
Nasqueron\Notifications\Providers\EventServiceProvider::class,
+ Nasqueron\Notifications\Providers\PhabricatorAPIServiceProvider::class,
+ Nasqueron\Notifications\Providers\PhabricatorProjectsMapServiceProvider::class,
Nasqueron\Notifications\Providers\ReportServiceProvider::class,
Nasqueron\Notifications\Providers\RouteServiceProvider::class,
Nasqueron\Notifications\Providers\SentryServiceProvider::class,
@@ -249,6 +251,8 @@
* App aliases...
*/
'Broker' => Nasqueron\Notifications\Facades\Broker::class,
+ 'PhabricatorAPI' => Nasqueron\Notifications\Facades\PhabricatorAPI::class,
+ 'ProjectsMap' => Nasqueron\Notifications\Facades\ProjectsMap::class,
'Raven' => Nasqueron\Notifications\Facades\Raven::class,
'Report' => Nasqueron\Notifications\Facades\Report::class,
'Services' => Nasqueron\Notifications\Facades\Services::class,
diff --git a/tests/Facades/PhabricatorAPITest.php b/tests/Facades/PhabricatorAPITest.php
new file mode 100644
--- /dev/null
+++ b/tests/Facades/PhabricatorAPITest.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Facades;
+
+use Nasqueron\Notifications\Facades\PhabricatorAPI;
+use Nasqueron\Notifications\Tests\TestCase;
+
+class PhabricatorAPITest extends TestCase {
+
+ public function testIfFacadeAccessorCouldBeResolvedInAppContainer () {
+ $this->assertInstanceOf(
+ 'Nasqueron\Notifications\Phabricator\PhabricatorAPIFactory',
+ PhabricatorAPI::getFacadeRoot()
+ );
+ }
+}
diff --git a/tests/Facades/ProjectsMapTest.php b/tests/Facades/ProjectsMapTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Facades/ProjectsMapTest.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Facades;
+
+use Nasqueron\Notifications\Facades\ProjectsMap;
+use Nasqueron\Notifications\Tests\TestCase;
+
+class ProjectsMapTest extends TestCase {
+
+ public function testIfFacadeAccessorCouldBeResolvedInAppContainer () {
+ $this->assertInstanceOf(
+ 'Nasqueron\Notifications\Phabricator\ProjectsMapFactory',
+ ProjectsMap::getFacadeRoot()
+ );
+ }
+}
diff --git a/tests/Phabricator/PhabricatorAPIFactoryTest.php b/tests/Phabricator/PhabricatorAPIFactoryTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Phabricator/PhabricatorAPIFactoryTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Phabricator;
+
+use Nasqueron\Notifications\Tests\TestCase;
+
+class PhabricatorAPIFactoryTest extends TestCase {
+
+ /**
+ * @var \Nasqueron\Notifications\Phabricator\ProjectsMapFactory
+ */
+ private $factory;
+
+ public function setUp () {
+ parent::setUp();
+ $this->factory = $this->app->make('phabricator-api');
+ }
+
+ public function testGetAPI () {
+ $this->assertInstanceOf(
+ '\Nasqueron\Notifications\Phabricator\PhabricatorAPI',
+ $this->factory->get("https://phabricator.acme.tld")
+ );
+ }
+
+ public function testGetAPIForProject () {
+ $this->assertInstanceOf(
+ '\Nasqueron\Notifications\Phabricator\PhabricatorAPI',
+ $this->factory->getForProject("Acme")
+ );
+ }
+}
diff --git a/tests/Phabricator/ProjectsMapFactoryTest.php b/tests/Phabricator/ProjectsMapFactoryTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Phabricator/ProjectsMapFactoryTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Phabricator;
+
+use Nasqueron\Notifications\Tests\TestCase;
+
+class ProjectsMapFactoryTest extends TestCase {
+
+ /**
+ * @var \Nasqueron\Notifications\Phabricator\ProjectsMapFactory
+ */
+ private $factory;
+
+ public function setUp () {
+ parent::setUp();
+ $this->factory = $this->app->make('phabricator-projectsmap');
+
+ $mock = $this->mockPhabricatorAPIForProjectsMap();
+ }
+
+ public function testLoadProjectsMap () {
+ $this->assertInstanceOf(
+ '\Nasqueron\Notifications\Phabricator\ProjectsMap',
+ $this->factory->load("https://phabricator.acme.tld")
+ );
+ }
+
+ public function testFetchProjectsMap () {
+ $this->assertInstanceOf(
+ '\Nasqueron\Notifications\Phabricator\ProjectsMap',
+ $this->factory->fetch("https://phabricator.acme.tld")
+ );
+ }
+
+}
diff --git a/tests/Providers/PhabricatorAPIServiceProviderTest.php b/tests/Providers/PhabricatorAPIServiceProviderTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Providers/PhabricatorAPIServiceProviderTest.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Providers;
+
+class PhabricatorAPIServiceProviderTest extends TestCase {
+
+ public function testType () {
+ $this->assertServiceInstanceOf(
+ 'Nasqueron\Notifications\Phabricator\PhabricatorAPIFactory',
+ 'phabricator-api'
+ );
+ }
+
+}
diff --git a/tests/Providers/PhabricatorProjectsMapServiceProviderTest.php b/tests/Providers/PhabricatorProjectsMapServiceProviderTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Providers/PhabricatorProjectsMapServiceProviderTest.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Providers;
+
+class PhabricatorProjectsMapServiceProviderTest extends TestCase {
+
+ public function testType () {
+ $this->assertServiceInstanceOf(
+ 'Nasqueron\Notifications\Phabricator\ProjectsMapFactory',
+ 'phabricator-projectsmap'
+ );
+ }
+
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -70,6 +70,34 @@
$this->app->instance('broker', $mock);
}
+ /**
+ * Mocks the Phabricator API
+ *
+ * @return Nasqueron\Notifications\Phabricator\PhabricatorAPIFactory The mock
+ */
+ protected function mockPhabricatorAPI () {
+ // Inject into our container a mock of PhabricatorAPI
+ $mock = Mockery::mock('Nasqueron\Notifications\Phabricator\PhabricatorAPIFactory');
+ $this->app->instance('phabricator-api', $mock);
+
+ return $mock;
+ }
+
+ private function mockPhabricatorAPIProjectsQueryReply () {
+ $json = file_get_contents('tests/data/PhabricatorProjetsQueryReply.json');
+ return json_decode($json);
+ }
+
+ /**
+ * Mocks the Phabricator API
+ */
+ protected function mockPhabricatorAPIForProjectsMap () {
+ $mock = $this->mockPhabricatorAPI();
+
+ $reply = $this->mockPhabricatorAPIProjectsQueryReply();
+ $mock->shouldReceive('get->call')->andReturn($reply);
+ }
+
///
/// Helpers to post data to gates
///
diff --git a/tests/data/PhabricatorProjetsQueryReply.json b/tests/data/PhabricatorProjetsQueryReply.json
new file mode 100644
--- /dev/null
+++ b/tests/data/PhabricatorProjetsQueryReply.json
@@ -0,0 +1,61 @@
+{
+ "data": {
+ "PHID-PROJ-6dg6ogx5pjmk24ur4tp4": {
+ "id": "60",
+ "phid": "PHID-PROJ-6dg6ogx5pjmk24ur4tp4",
+ "name": "Accounts",
+ "profileImagePHID": "PHID-FILE-fgoutnn6wzccr6w2nldv",
+ "icon": "tag",
+ "color": "orange",
+ "members": [
+ "PHID-USER-fnetlprx7zdotfm2hdrz"
+ ],
+ "slugs": [
+ "accounts"
+ ],
+ "dateCreated": "1453142137",
+ "dateModified": "1453142157"
+ },
+ "PHID-PROJ-cztcgpvqr6smnnekotq7": {
+ "id": "17",
+ "phid": "PHID-PROJ-cztcgpvqr6smnnekotq7",
+ "name": "Agora",
+ "profileImagePHID": "PHID-FILE-2lbihkjdnretjk52wmoi",
+ "icon": "folder",
+ "color": "blue",
+ "members": [
+ "PHID-USER-fnetlprx7zdotfm2hdrz"
+ ],
+ "slugs": [
+ "agora",
+ "wiki"
+ ],
+ "dateCreated": "1417065185",
+ "dateModified": "1417076656"
+ },
+ "PHID-PROJ-3iew3cqf3htpazfyzb5a": {
+ "id": "29",
+ "phid": "PHID-PROJ-3iew3cqf3htpazfyzb5a",
+ "name": "architecture",
+ "profileImagePHID": "PHID-FILE-bljt7kpva2cwkx6omh2j",
+ "icon": "tag",
+ "color": "orange",
+ "members": [
+ "PHID-USER-fnetlprx7zdotfm2hdrz"
+ ],
+ "slugs": [
+ "architecture",
+ "architect",
+ "archi"
+ ],
+ "dateCreated": "1427725535",
+ "dateModified": "1427725949"
+ }
+ },
+ "slugMap": [],
+ "cursor": {
+ "limit": "3",
+ "after": "29",
+ "before": null
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 21, 14:30 (19 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2309583
Default Alt Text
D317.diff (21 KB)

Event Timeline