Page MenuHomeDevCentral

No OneTemporary

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

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)

Event Timeline