Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3930791
D617.id1525.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D617.id1525.diff
View Options
diff --git a/app/Console/Commands/NotificationsPayload.php b/app/Console/Commands/NotificationsPayload.php
new file mode 100644
--- /dev/null
+++ b/app/Console/Commands/NotificationsPayload.php
@@ -0,0 +1,205 @@
+<?php
+
+namespace Nasqueron\Notifications\Console\Commands;
+
+use Illuminate\Console\Command;
+
+use InvalidArgumentException;
+use ReflectionClass;
+
+class NotificationsPayload extends Command {
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'notifications:payload {service} {payload} {args*}';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Gets a notification payload from a service payload';
+
+ /**
+ * The service to handle a payload for.
+ *
+ * @var string
+ */
+ private $service;
+
+ /**
+ * The payload.
+ *
+ * @var string
+ */
+ private $payload;
+
+ /**
+ * The parameters to pass to the notifications class constructor.
+ *
+ * An array with arguments' names as keys, arguments' values as values.
+ *
+ * @var array
+ */
+ private $constructor;
+
+ /**
+ * Creates a new command instance.
+ *
+ * @return void
+ */
+ public function __construct() {
+ parent::__construct();
+ }
+
+ /**
+ * Executes the console command.
+ */
+ public function handle() {
+ if ($this->parseArguments()) {
+ $this->printNotification();
+ }
+ }
+
+ /**
+ * Parses arguments passed to the command.
+ *
+ * @return bool true if arguments looks good; otherwise, false.
+ */
+ private function parseArguments () {
+ try {
+ $this->parseService();
+ $this->parsePayload();
+ $this->parseConstructorParameters();
+ } catch (InvalidArgumentException $ex) {
+ $this->error($ex->getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Parses service argument.
+ *
+ * Fills it to the service property.
+ *
+ * @throws InvalidArgumentException when a notification class can't be found for the requested service.
+ */
+ private function parseService () {
+ $this->service = $this->argument('service');
+
+ if (!class_exists($this->getNotificationClass())) {
+ throw new InvalidArgumentException("Unknown service: $this->service");
+ }
+ }
+
+ /**
+ * Parses path to the payload argument.
+ *
+ * Fills the content of the file to the payload property.
+ *
+ * @throws InvalidArgumentException when payload file is not found.
+ */
+ private function parsePayload () {
+ $payloadFile = $this->argument('payload');
+
+ if (!file_exists($payloadFile)) {
+ throw new InvalidArgumentException("File not found: $payloadFile");
+ }
+
+ $this->payload = file_get_contents($payloadFile);
+ }
+
+ /**
+ * Parses all the extra arguments and sets the constructor property
+ * as an array of constructor arguments.
+ *
+ * @throws InvalidArgumentException when too many or too few arguments have been given.
+ */
+ private function parseConstructorParameters () {
+ $keys = $this->getNotificationConstructorParameters();
+
+ $values = $this->argument('args');
+ $values['payload'] = json_decode($this->payload);
+
+ $this->constructor = self::argumentsArrayCombine($keys, $values);
+ }
+
+ /**
+ * Creates an array by using one array for keys and another for its values.
+ *
+ * @param array $keys
+ * @param array $values
+ * @return array
+ *
+ * @throws InvalidArgumentException when keys and values counts don't match
+ */
+ public static function argumentsArrayCombine ($keys, $values) {
+ $countKeys = count($keys);
+ $countValues = count($values);
+
+ if ($countKeys != $countValues) {
+ throw new InvalidArgumentException("Number of arguments mismatch: got $countValues but expected $countKeys.");
+ }
+
+ return array_combine($keys, $values);
+ }
+
+ /**
+ * Initializes a new instance of the relevant notification class,
+ * with the arguments given in the constructor property.
+ *
+ * @return Nasqueron\Notifications\Notification
+ */
+ private function getNotification () {
+ $class = $this->getNotificationClass();
+ $args = array_values($this->constructor);
+ return new $class(...$args);
+ }
+
+ /**
+ * Gets the notification in JSON format.
+ *
+ * @return string
+ */
+ private function formatNotification () {
+ return json_encode($this->getNotification(), JSON_PRETTY_PRINT);
+ }
+
+ /**
+ * Prints the notification for the service, payload and specified arguments.
+ */
+ private function printNotification () {
+ $this->line($this->formatNotification());
+ }
+
+ /**
+ * Gets the notification class for the specified service.
+ *
+ * @return string
+ */
+ private function getNotificationClass () {
+ $namespace = "Nasqueron\Notifications\Notifications\\";
+ return $namespace . $this->service . "Notification";
+ }
+
+ /**
+ * Gets an array with the parameters to pass to the constructor
+ * of the notification class for the specified service.
+ *
+ * @return array
+ */
+ private function getNotificationConstructorParameters () {
+ $parameters = [];
+
+ $class = new ReflectionClass($this->getNotificationClass());
+ foreach ($class->getConstructor()->getParameters() as $parameter) {
+ $parameters[] = $parameter->getName();
+ }
+
+ return $parameters;
+ }
+}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -15,6 +15,7 @@
protected $commands = [
\Nasqueron\Notifications\Console\Commands\ConfigShow::class,
\Nasqueron\Notifications\Console\Commands\Inspire::class,
+ \Nasqueron\Notifications\Console\Commands\NotificationsPayload::class,
\Nasqueron\Notifications\Console\Commands\PhabricatorProjectsMap::class,
];
diff --git a/tests/Console/Commands/NotificationsPayloadTest.php b/tests/Console/Commands/NotificationsPayloadTest.php
new file mode 100644
--- /dev/null
+++ b/tests/Console/Commands/NotificationsPayloadTest.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Nasqueron\Notifications\Tests\Console\Commands;
+
+use Nasqueron\Notifications\Console\Commands\NotificationsPayload;
+
+class NotificationsPayloadTest extends TestCase {
+
+ /**
+ * @var string
+ */
+ protected $class = 'Nasqueron\Notifications\Console\Commands\NotificationsPayload';
+
+ public function testRegularExecute () {
+ $path = __DIR__ . '/../../data/payloads/DockerHubPushPayload.json';
+ $this->tester->execute([
+ 'command' => $this->command->getName(),
+ 'service' => 'DockerHub',
+ 'payload' => $path,
+ 'args' => [
+ 'Acme',
+ 'push'
+ ],
+ ]);
+
+ $this->assertContains('"service": "DockerHub"', $this->tester->getDisplay());
+ $this->assertContains('"project": "Acme"', $this->tester->getDisplay());
+ $this->assertContains('svendowideit\/testhook', $this->tester->getDisplay());
+ }
+
+ /**
+ * @expectedException InvalidArgumentException
+ */
+ public function testArgumentsArrayCombine () {
+ NotificationsPayload::argumentsArrayCombine(['foo'], []);
+ }
+
+ public function testFileNotFound () {
+ $this->tester->execute([
+ 'command' => $this->command->getName(),
+ 'service' => 'DockerHub',
+ 'payload' => "/tmp/not.found",
+ 'args' => [
+ 'Acme',
+ 'push'
+ ],
+ ]);
+
+ $this->assertContains(
+ 'File not found: /tmp/not.found',
+ $this->tester->getDisplay()
+ );
+
+ }
+
+ public function testServiceNotFound () {
+ $path = __DIR__ . '/../../data/payloads/DockerHubPushPayload.json';
+ $this->tester->execute([
+ 'command' => $this->command->getName(),
+ 'service' => 'InterdimensionalTeleport',
+ 'payload' => $path,
+ 'args' => [
+ 'Acme',
+ 'push'
+ ],
+ ]);
+
+ $this->assertContains(
+ 'Unknown service: InterdimensionalTeleport',
+ $this->tester->getDisplay()
+ );
+
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Dec 23, 15:45 (5 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2312728
Default Alt Text
D617.id1525.diff (8 KB)
Attached To
Mode
D617: Add notifications:payload command
Attached
Detach File
Event Timeline
Log In to Comment