Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F11724280
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
24 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/app/Services/Service.php b/app/Config/Services/Service.php
similarity index 91%
rename from app/Services/Service.php
rename to app/Config/Services/Service.php
index c43e569..72c2b7f 100644
--- a/app/Services/Service.php
+++ b/app/Config/Services/Service.php
@@ -1,38 +1,38 @@
<?php
-namespace Nasqueron\Notifications\Services;
+namespace Nasqueron\Notifications\Config\Services;
class Service {
/**
* @var string
*/
public $gate;
/**
* @var string
*/
public $door;
/**
* @var string
*/
public $instance;
/**
* @var string
*/
public $secret;
/**
* Gets instance name
*
* @return string The instance name or "ø" if omitted
*/
public function getInstanceName () : string {
if (!isset($this->instance)) {
return "ø";
}
return $this->instance;
}
}
diff --git a/app/Services/Services.php b/app/Config/Services/Services.php
similarity index 98%
rename from app/Services/Services.php
rename to app/Config/Services/Services.php
index f93ad45..47716f0 100644
--- a/app/Services/Services.php
+++ b/app/Config/Services/Services.php
@@ -1,104 +1,104 @@
<?php
-namespace Nasqueron\Notifications\Services;
+namespace Nasqueron\Notifications\Config\Services;
use Storage;
class Services {
///
/// Properties
///
/**
* @var Service[]
*/
public $services = [];
///
/// Constructors
///
/**
* Initializes a new instance of the Services class deserializing a JSON file.
*
* @param string $file The JSON file to deserialize
* @return Services The deserialized instance
*/
public static function loadFromJson (string $file) : Services {
$data = json_decode(Storage::get($file));
$mapper = new \JsonMapper();
return $mapper->map($data, new self());
}
///
/// Methods to get a list of services
///
/**
* Gets the services found in credentials.json configuration file.
*
* @return Service[]
*/
public function get () {
return $this->services;
}
/**
* Gets all the services for a specific gate.
*
* @param string $gate The gate (e.g. GitHub)
* @return Service[]
*/
public function getForGate (string $gate) : array {
$services = [];
foreach ($this->services as $service) {
if ($service->gate === $gate) {
$services[] = $service;
}
}
return $services;
}
///
/// Methods to find a service matching criteria
///
/**
* Gets the service for a specific gate and door
*
* @param string $gate The gate (e.g. GitHub)
* @param string $door The door (e.g. Nasqueron)
* @return Service|null The service information is found; otherwise, null.
*/
public function findServiceByDoor (string $gate, string $door) : ?Service {
foreach ($this->services as $service) {
if ($service->gate === $gate && $service->door === $door) {
return $service;
}
}
return null;
}
/**
* Finds a service for a specific gate, property and value
*
* @param string $gate The gate (e.g. Phabricator)
* @param string $property The property to check (e.g. instance)
* @param mixed $value The property value to find (e.g. 'http://devcentral.nasqueron.org')
* @return Service|null The service information is found; otherwise, null.
*/
public function findServiceByProperty (string $gate, string $property, $value) : ?Service {
foreach ($this->services as $service) {
if ($service->gate === $gate && $service->$property === $value) {
return $service;
}
}
return null;
}
}
diff --git a/app/Console/Commands/ConfigShow.php b/app/Console/Commands/ConfigShow.php
index 626898c..4a2aac7 100644
--- a/app/Console/Commands/ConfigShow.php
+++ b/app/Console/Commands/ConfigShow.php
@@ -1,131 +1,131 @@
<?php
namespace Nasqueron\Notifications\Console\Commands;
use Illuminate\Console\Command;
use Nasqueron\Notifications\Config\Features;
-use Nasqueron\Notifications\Services\Service;
+use Nasqueron\Notifications\Config\Services\Service;
use Config;
use ProjectsMap;
use Services;
class ConfigShow extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'config:show';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Show notifications center configuration';
/**
* Creates a new command instance.
*/
public function __construct () {
parent::__construct();
}
///
/// Prepare information tables
///
/**
* Gets the services (defined in credentials.json) as table rows.
*
- * @return \Nasqueron\Notifications\Services\Service[]
+ * @return \Nasqueron\Notifications\Config\Services\Service[]
*/
protected function getServicesTableRows () : array {
$rows = [];
foreach (Services::get() as $service) {
$rows[] = [
$service->gate,
$service->door,
$service->getInstanceName(),
$this->getServiveStatus($service)
];
}
return $rows;
}
/**
* Gets service status.
*
- * @param \Nasqueron\Notifications\Services\Service $service The service to check
+ * @param \Nasqueron\Notifications\Config\Services\Service $service The service to check
* @return string A description of the issue if something is wrong; otherwise, "✓".
*/
protected function getServiveStatus (Service $service) : string {
if ($service->gate === 'Phabricator') {
// Ensure the projects map is cached
$map = \ProjectsMap::fetch($service->door);
if (!$map->isCached()) {
return "Projects map not cached.";
}
}
return "✓";
}
/**
* Gets features as table rows
*
* @return array
*/
protected function getFeaturesTableRows () : array {
$rows = [];
foreach (Features::getAll() as $key => $value) {
if ($value) {
$checkMark = '✓';
} else {
$checkMark = '';
}
$rows[] = [$key, $checkMark];
}
return $rows;
}
///
/// Handle the command
///
/**
* Executes the console command.
*/
public function handle () : void {
$this->printGates();
$this->printFeatures();
$this->printServices();
}
protected final function printGates () : void {
$this->info("Gates:\n");
foreach (Config::get('gate.controllers') as $gate) {
$this->line('- ' . $gate);
}
}
protected final function printFeatures () : void {
$this->info("\nFeatures:\n");
$this->table(
['Feature', 'Enabled'],
$this->getFeaturesTableRows()
);
}
protected final function printServices () : void {
$this->info("\nServices declared in credentials:\n");
$this->table(
['Gate', 'Door', 'Instance', 'Status'],
$this->getServicesTableRows()
);
}
}
diff --git a/app/Http/Controllers/Gate/GateController.php b/app/Http/Controllers/Gate/GateController.php
index ab8aae7..a25d29d 100644
--- a/app/Http/Controllers/Gate/GateController.php
+++ b/app/Http/Controllers/Gate/GateController.php
@@ -1,120 +1,120 @@
<?php
namespace Nasqueron\Notifications\Http\Controllers\Gate;
use Nasqueron\Notifications\Config\Features;
+use Nasqueron\Notifications\Config\Services\Service;
use Nasqueron\Notifications\Http\Controllers\Controller;
-use Nasqueron\Notifications\Services\Service;
use Symfony\Component\HttpFoundation\Response as BaseResponse;
use Illuminate\View\View;
use App;
use Log;
use Report;
use Response;
use Services;
/**
* Represents a controller handling an entry-point for API payloads
*/
class GateController extends Controller {
///
/// Private members
///
/**
* @var string
*/
protected $door;
///
/// Requests
///
/**
* Handles GET requests
*/
public function onGet () : View {
// Virtually all the push APIs will send they payloads
// using a POST request, so we can provide a sensible
// default GET error message.
return view('gate/ispostonly');
}
/**
* Logs the request
*/
protected function logRequest (array $extraContextualData = []) : void {
Log::info('[Gate] New payload.', [
'service' => static::SERVICE_NAME,
'door' => $this->door,
] + $extraContextualData);
}
///
/// Reports
///
/**
* Initializes the report and registers it
*/
protected function initializeReport () : void {
if (Features::isEnabled('ActionsReport')) {
Report::attachToGate(static::SERVICE_NAME, $this->door);
}
}
/**
* Renders the report
*
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function renderReport () : BaseResponse {
if (!Features::isEnabled('ActionsReport')) {
return response("");
}
$report = App::make('report');
$statusCode = $report->containsError() ? 503 : 200;
return Response::json($report)
->setStatusCode($statusCode);
}
///
/// Credentials
///
/**
* Gets service credentials for this gate and door
*
- * @return Nasqueron\Notifications\Services\Service|null The service information is found; otherwise, null.
+ * @return \Nasqueron\Notifications\Config\Services\Service|null The service information is found; otherwise, null.
*/
public function getService () : ?Service {
return Services::findServiceByDoor(static::SERVICE_NAME, $this->door);
}
/**
* Checks if a registered service exists for this service and door.
*/
protected function doesServiceExist () : bool {
return $this->getService() !== null;
}
/**
* Gets secret for this service and door.
*
* @return string the secret, or if unknown, an empty string
*/
protected function getSecret () : string {
$service= $this->getService();
if ($service !== null) {
return $service->secret;
}
return "";
}
}
diff --git a/app/Providers/ServicesServiceProvider.php b/app/Providers/ServicesServiceProvider.php
index d4d8953..00c911d 100644
--- a/app/Providers/ServicesServiceProvider.php
+++ b/app/Providers/ServicesServiceProvider.php
@@ -1,26 +1,26 @@
<?php
namespace Nasqueron\Notifications\Providers;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\ServiceProvider;
-use Nasqueron\Notifications\Services\Services;
+use Nasqueron\Notifications\Config\Services\Services;
class ServicesServiceProvider extends ServiceProvider {
/**
* Registers the application services.
*
* @return void
*/
public function register() {
$this->app->singleton('services', function (Application $app) {
$path = config('services.gate.credentials');
if (strlen($path) > 0 && $app->make('filesystem')->has($path)) {
return Services::loadFromJson($path);
}
return new Services;
});
}
}
diff --git a/tests/Console/Commands/ConfigShowTest.php b/tests/Console/Commands/ConfigShowTest.php
index 59507dc..6f6291b 100644
--- a/tests/Console/Commands/ConfigShowTest.php
+++ b/tests/Console/Commands/ConfigShowTest.php
@@ -1,97 +1,97 @@
<?php
namespace Nasqueron\Notifications\Tests\Console\Commands;
use Nasqueron\Notifications\Config\Features;
-use Nasqueron\Notifications\Services\Service;
+use Nasqueron\Notifications\Config\Services\Service;
use Mockery;
class ConfigShowTest extends TestCase {
/**
* @var string
*/
protected $class = 'Nasqueron\Notifications\Console\Commands\ConfigShow';
/**
* Nasqueron\Notifications\Services\Services
*/
private $servicesMock;
public function setUp () {
parent::setUp();
$this->servicesMock = $this->mockServices();
}
public function testRegularExecute () {
//Our command calls Services::get()
$this->servicesMock->shouldReceive('get')->once()->andReturn([]);
$this->tester->execute(['command' => $this->command->getName()]);
$this->assertRegexp('/Gates/', $this->tester->getDisplay());
$this->assertRegexp('/Features/', $this->tester->getDisplay());
$this->assertRegexp('/Services declared/', $this->tester->getDisplay());
}
public function testRegularExecuteWithService () {
$service = $this->mockService();
$this->servicesMock
->shouldReceive('get')
->once()
->andReturn([$service]);
$this->tester->execute(['command' => $this->command->getName()]);
$this->assertRegexp('/Storm/', $this->tester->getDisplay());
}
public function testRegularExecuteWithPhabricatorService () {
$this->mockPhabricatorAPIForProjectsMap();
$service = $this->mockService('Phabricator');
$this->servicesMock
->shouldReceive('get')
->once()
->andReturn([$service]);
$this->servicesMock
->shouldReceive('findServiceByProperty');
$this->tester->execute(['command' => $this->command->getName()]);
$this->assertRegexp('/Phabricator.*Projects map not cached./', $this->tester->getDisplay());
}
protected function mockProjectsMap () {
$mock = Mockery::mock('Nasqueron\Notifications\Phabricator\ProjectsMap');
$this->app->instance('phabricator-projectsmap', $mock);
return $mock;
}
public function testRegularExecuteWithPhabricatorServiceWhenTheProjectsMapIsCached () {
// The services list will return only one, for the Phabricator gate.
$service = $this->mockService('Phabricator');
$this->servicesMock
->shouldReceive('get')->once()->andReturn([$service]);
// The project map (built by the factory) will say it's cached.
$this->mockProjectsMap()
->shouldReceive('fetch->isCached')->once()->andReturn(true);
$this->tester->execute(['command' => $this->command->getName()]);
$this->assertRegexp('/Phabricator.*✓/', $this->tester->getDisplay());
}
public function testExecuteWhenSomeFeatureIsDisabled () {
Features::disable('ActionsReport');
$this->servicesMock->shouldReceive('get')->once()->andReturn([]);
$this->tester->execute(['command' => $this->command->getName()]);
$this->assertRegexp('/Gate *\| *✓ *\|/', $this->tester->getDisplay());
$this->assertRegexp('/ActionsReport *\| *\|/', $this->tester->getDisplay());
}
}
diff --git a/tests/Console/Commands/PhabricatorProjectsMapTest.php b/tests/Console/Commands/PhabricatorProjectsMapTest.php
index b3fdefd..018b337 100644
--- a/tests/Console/Commands/PhabricatorProjectsMapTest.php
+++ b/tests/Console/Commands/PhabricatorProjectsMapTest.php
@@ -1,31 +1,31 @@
<?php
namespace Nasqueron\Notifications\Tests\Console\Commands;
-use Nasqueron\Notifications\Services\Service;
+use Nasqueron\Notifications\Config\Services\Service;
class PhabricatorProjectsMapTest extends TestCase {
/**
* @var string
*/
protected $class = 'Nasqueron\Notifications\Console\Commands\PhabricatorProjectsMap';
public function setUp () {
parent::setUp();
$service = $this->mockService('Phabricator');
$this->mockServices()
->shouldReceive('getForGate')
->once()
->andReturn([$service]);
$this->mockPhabricatorAPIForProjectsMap();
}
public function testRegularExecute () {
$this->tester->execute(['command' => $this->command->getName()]);
$this->assertRegexp('/PHID.*Project name/', $this->tester->getDisplay());
$this->assertRegexp('/PHID-PROJ-cztcgpvqr6smnnekotq7.*Agora/', $this->tester->getDisplay());
}
}
diff --git a/tests/Console/Commands/TestCase.php b/tests/Console/Commands/TestCase.php
index 4deb467..54ea728 100644
--- a/tests/Console/Commands/TestCase.php
+++ b/tests/Console/Commands/TestCase.php
@@ -1,82 +1,82 @@
<?php
namespace Nasqueron\Notifications\Tests\Console\Commands;
use Symfony\Component\Console\Tester\CommandTester;
-use Nasqueron\Notifications\Services\Service;
+use Nasqueron\Notifications\Config\Services\Service;
use Nasqueron\Notifications\Tests\TestCase as BaseTestCase;
use Artisan;
use Mockery;
class TestCase extends BaseTestCase {
///
/// Commands test environment
///
/**
* @var Symfony\Component\Console\Command
*/
protected $command;
/**
* @var Symfony\Component\Console\Tester\CommandTester;
*/
protected $tester;
public function setUp () {
parent::setUp();
$this->command = $this->findCommand($this->class);
$this->tester = new CommandTester($this->command);
}
///
/// Helper methods to manipulate command arrays
///
/**
* Finds the first instance of the expected type in the specified array.
*
* @param mixed $expectedType The type to find among the array elements
* @param array $haystack The array where to find
* @return mixed|null If not found, null. Otherwise, the found item.
*/
protected static function findInstanceOf ($expectedType, $haystack) {
foreach ($haystack as $item) {
if ($item instanceof $expectedType) {
return $item;
}
}
return null;
}
protected function findCommand ($expectedType) {
return self::findInstanceOf($expectedType, Artisan::all());
}
///
/// Helper methods to mock services
///
protected function mockServices () {
// Inject into our container a mock of Services
$mock = Mockery::mock('Nasqueron\Notifications\Services\Services');
$this->app->instance('services', $mock);
return $mock;
}
protected function mockService ($gate = 'Storm') {
$service = new Service;
$service->gate = $gate;
$service->door = 'Acme';
$service->instance = "http://www.perdu.com";
return $service;
}
}
diff --git a/tests/Providers/ServicesServiceProviderTest.php b/tests/Providers/ServicesServiceProviderTest.php
index e76d76b..fc93b9b 100644
--- a/tests/Providers/ServicesServiceProviderTest.php
+++ b/tests/Providers/ServicesServiceProviderTest.php
@@ -1,41 +1,41 @@
<?php
namespace Nasqueron\Notifications\Tests\Providers;
use Nasqueron\Notifications\Providers\ServicesServiceProvider;
use Config;
class ServicesServiceProviderTest extends TestCase {
public function testType () {
$this->assertServiceInstanceOf(
- 'Nasqueron\Notifications\Services\Services',
+ "Nasqueron\Notifications\Config\Services\Services",
'services'
);
}
///
/// Tests specific to this service provider
///
public function testWithCredentialsFile () {
$services = $this->app->make('services');
$this->assertGreaterThan(0, count($services->services));
}
public function testWithoutCredentialsFile () {
Config::set('services.gate.credentials', null);
$services = $this->app->make('services');
$this->assertSame(0, count($services->services));
}
public function testWithNontFoundCredentialsFile () {
Config::set('services.gate.credentials', 'notfound.json');
$services = $this->app->make('services');
$this->assertSame(0, count($services->services));
}
}
diff --git a/tests/Services/ServiceTest.php b/tests/Services/ServiceTest.php
index 0d640ea..fdd7c28 100644
--- a/tests/Services/ServiceTest.php
+++ b/tests/Services/ServiceTest.php
@@ -1,45 +1,45 @@
<?php
namespace Nasqueron\Notifications\Tests\Services;
-use Nasqueron\Notifications\Services\Service;
+use Nasqueron\Notifications\Config\Services\Service;
use Nasqueron\Notifications\Tests\TestCase;
class ServiceTest extends TestCase {
/**
* @var \Nasqueron\Notifications\Services\Service
*/
private $serviceWithInstance;
/**
* @var \Nasqueron\Notifications\Services\Service
*/
private $serviceWithoutInstance;
public function setUp () {
$this->serviceWithoutInstance = new Service();
$this->serviceWithInstance = clone $this->serviceWithoutInstance;
$this->serviceWithInstance->instance = "http://www.perdu.com";
}
///
/// Tests for getInstanceName()
///
public function testGetInstanceName () {
$this->assertSame(
"http://www.perdu.com",
$this->serviceWithInstance->getInstanceName()
);
}
public function testGetInstanceNameWhenThereIsNoInstance () {
$this->assertSame(
"ø",
$this->serviceWithoutInstance->getInstanceName()
);
}
}
diff --git a/tests/Services/ServicesTest.php b/tests/Services/ServicesTest.php
index e4d27c4..d996306 100644
--- a/tests/Services/ServicesTest.php
+++ b/tests/Services/ServicesTest.php
@@ -1,90 +1,90 @@
<?php
namespace Nasqueron\Notifications\Tests\Services;
-use Nasqueron\Notifications\Services\Services;
+use Nasqueron\Notifications\Config\Services\Services;
use Nasqueron\Notifications\Tests\TestCase;
class ServicesTest extends TestCase {
private $services;
public function setUp () {
parent::setUp();
$this->services = Services::loadFromJson('credentials.json');
}
public function testGet () {
$actualServices = $this->services->get();
$this->assertGreaterThan(0, $actualServices);
$this->assertSame(
$this->services->services, // This is public, so testable
$actualServices
);
foreach ($actualServices as $service) {
$this->assertInstanceOf(
- 'Nasqueron\Notifications\Services\Service',
+ 'Nasqueron\Notifications\Config\Services\Service',
$service
);
}
}
public function testGetForGate () {
$actualServices = $this->services->getForGate('GitHub');
$this->assertGreaterThan(0, $actualServices);
foreach ($actualServices as $service) {
$this->assertInstanceOf(
- 'Nasqueron\Notifications\Services\Service',
+ 'Nasqueron\Notifications\Config\Services\Service',
$service
);
$this->assertSame('GitHub', $service->gate);
}
}
public function testFindServiceByDoor () {
// Search gives a result
$service = $this->services->findServiceByDoor('GitHub', 'Acme');
$this->assertInstanceOf(
- 'Nasqueron\Notifications\Services\Service',
+ 'Nasqueron\Notifications\Config\Services\Service',
$service
);
$this->assertSame('GitHub', $service->gate);
$this->assertSame('Acme', $service->door);
// Search doesn't give any result
$service = $this->services->findServiceByDoor('GitHub', 'Quux');
$this->assertNull($service);
}
public function testFindServiceByProperty () {
// Search gives a result
$service = $this->services->findServiceByProperty(
'Phabricator',
'instance',
'https://phabricator.acme.tld'
);
$this->assertInstanceOf(
- 'Nasqueron\Notifications\Services\Service',
+ 'Nasqueron\Notifications\Config\Services\Service',
$service
);
$this->assertSame('Phabricator', $service->gate);
$this->assertSame('Acme', $service->door);
// Search doesn't give any result
$service = $this->services->findServiceByProperty(
'Phabricator',
'instance',
'https://notfound.acme.tld'
);
$this->assertNull($service);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Sep 18, 13:53 (19 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2990922
Default Alt Text
(24 KB)
Attached To
Mode
rNOTIF Notifications center
Attached
Detach File
Event Timeline
Log In to Comment