From 778664b20a62593ffc9ab0e9f66e7b06df122a0c Mon Sep 17 00:00:00 2001 From: James Brooks Date: Wed, 3 Aug 2016 17:44:21 +0100 Subject: [PATCH 1/6] Added new Beacon handling code --- .env.example | 2 + .../Jobs/System/SendBeaconJobHandler.php | 64 ++++++++++ app/Bus/Jobs/System/SendBeaconJob.php | 24 ++++ app/Console/Commands/BeaconCommand.php | 47 +++++++ app/Console/Kernel.php | 4 + .../Providers/IntegrationServiceProvider.php | 17 +++ app/Integrations/Contracts/Beacon.php | 34 ++++++ app/Integrations/Core/Beacon.php | 115 ++++++++++++++++++ app/Models/User.php | 25 ++++ app/Settings/Repository.php | 17 +++ config/cachet.php | 13 ++ tests/Bus/Jobs/JobExistenceTest.php | 30 +++++ tests/Bus/Jobs/System/SendBeaconJobTest.php | 48 ++++++++ .../IntegrationServiceProviderTest.php | 6 + 14 files changed, 446 insertions(+) create mode 100644 app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php create mode 100644 app/Bus/Jobs/System/SendBeaconJob.php create mode 100644 app/Console/Commands/BeaconCommand.php create mode 100644 app/Integrations/Contracts/Beacon.php create mode 100644 app/Integrations/Core/Beacon.php create mode 100644 tests/Bus/Jobs/JobExistenceTest.php create mode 100644 tests/Bus/Jobs/System/SendBeaconJobTest.php diff --git a/.env.example b/.env.example index 7dfca241..c68962a3 100644 --- a/.env.example +++ b/.env.example @@ -14,6 +14,8 @@ DB_PREFIX=null CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync + +CACHET_BEACON=true CACHET_EMOJI=false MAIL_DRIVER=smtp diff --git a/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php b/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php new file mode 100644 index 00000000..05733540 --- /dev/null +++ b/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php @@ -0,0 +1,64 @@ + + */ +class SendBeaconJobHandler +{ + /** + * The beacon instance. + * + * @var \CachetHQ\Cachet\Integrations\Contracts\Beacon + */ + protected $beacon; + + /** + * Create a new send beacon job handler instance. + * + * @param \CachetHQ\Cachet\Integrations\Contracts\Beacon $beacon + * + * @return void + */ + public function __construct(Beacon $beacon) + { + $this->beacon = $beacon; + } + + /** + * Handle the send beacon job. + * + * @param \CachetHQ\Cachet\Bus\Jobs\SendBeaconJob $job + * + * @return void + */ + public function handle(SendBeaconJob $job) + { + // Don't send anything if the installation explicitly prevents us. + if (!$this->beacon->enabled()) { + return; + } + + try { + $this->beacon->send(); + } catch (Exception $e) { + // + } + } +} diff --git a/app/Bus/Jobs/System/SendBeaconJob.php b/app/Bus/Jobs/System/SendBeaconJob.php new file mode 100644 index 00000000..577aa810 --- /dev/null +++ b/app/Bus/Jobs/System/SendBeaconJob.php @@ -0,0 +1,24 @@ + + */ +final class SendBeaconJob implements ShouldQueue +{ + // +} diff --git a/app/Console/Commands/BeaconCommand.php b/app/Console/Commands/BeaconCommand.php new file mode 100644 index 00000000..03391eb4 --- /dev/null +++ b/app/Console/Commands/BeaconCommand.php @@ -0,0 +1,47 @@ + + */ +class BeaconCommand extends Command +{ + /** + * The console command name. + * + * @var string + */ + protected $name = 'cachet:beacon'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Send a beacon to the Cachet server.'; + + /** + * Execute the console command. + * + * @return void + */ + public function fire() + { + dispatch(new SendBeaconJob()); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index d1c9686b..d1acd666 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -11,6 +11,7 @@ namespace CachetHQ\Cachet\Console; +use CachetHQ\Cachet\Console\Commands\BeaconCommand; use CachetHQ\Cachet\Console\Commands\DemoMetricPointSeederCommand; use CachetHQ\Cachet\Console\Commands\DemoSeederCommand; use Illuminate\Console\Scheduling\Schedule; @@ -24,6 +25,7 @@ class Kernel extends ConsoleKernel * @var array */ protected $commands = [ + BeaconCommand::class, DemoMetricPointSeederCommand::class, DemoSeederCommand::class, ]; @@ -38,5 +40,7 @@ class Kernel extends ConsoleKernel protected function schedule(Schedule $schedule) { $schedule->command('queue:work --sleep=3 --tries=3')->everyMinute(); + + $schedule->command('cachet:beacon')->twiceDaily('00:00', '12:00'); } } diff --git a/app/Foundation/Providers/IntegrationServiceProvider.php b/app/Foundation/Providers/IntegrationServiceProvider.php index aa2c9f95..4f4ba9e0 100644 --- a/app/Foundation/Providers/IntegrationServiceProvider.php +++ b/app/Foundation/Providers/IntegrationServiceProvider.php @@ -11,10 +11,12 @@ namespace CachetHQ\Cachet\Foundation\Providers; +use CachetHQ\Cachet\Integrations\Contracts\Beacon as BeaconContract; use CachetHQ\Cachet\Integrations\Contracts\Credits as CreditsContract; use CachetHQ\Cachet\Integrations\Contracts\Feed as FeedContract; use CachetHQ\Cachet\Integrations\Contracts\Releases as ReleasesContract; use CachetHQ\Cachet\Integrations\Contracts\System as SystemContract; +use CachetHQ\Cachet\Integrations\Core\Beacon; use CachetHQ\Cachet\Integrations\Core\Credits; use CachetHQ\Cachet\Integrations\Core\Feed; use CachetHQ\Cachet\Integrations\Core\System; @@ -36,6 +38,7 @@ class IntegrationServiceProvider extends ServiceProvider */ public function register() { + $this->registerBeacon(); $this->registerCredits(); $this->registerFeed(); $this->registerSystem(); @@ -43,6 +46,20 @@ class IntegrationServiceProvider extends ServiceProvider $this->registerReleases(); } + /** + * Register the beacon class. + * + * @return void + */ + protected function registerBeacon() + { + $this->app->singleton(BeaconContract::class, function ($app) { + $config = $app['config']; + + return new Beacon($config); + }); + } + /** * Register the credits class. * diff --git a/app/Integrations/Contracts/Beacon.php b/app/Integrations/Contracts/Beacon.php new file mode 100644 index 00000000..61571403 --- /dev/null +++ b/app/Integrations/Contracts/Beacon.php @@ -0,0 +1,34 @@ + + */ +interface Beacon +{ + /** + * Has the install enabled Cachet beacon? + * + * @return bool + */ + public function enabled(); + + /** + * Send a beacon to our server. + * + * @return void + */ + public function send(); +} diff --git a/app/Integrations/Core/Beacon.php b/app/Integrations/Core/Beacon.php new file mode 100644 index 00000000..4ce40696 --- /dev/null +++ b/app/Integrations/Core/Beacon.php @@ -0,0 +1,115 @@ + + */ +class Beacon implements BeaconContract +{ + /** + * The beacon url. + * + * @var string + */ + const URL = 'https://cachethq.io/beacon'; + + /** + * The illuminate config instance. + * + * @var \Illuminate\Contracts\Config\Repository + */ + protected $config; + + /** + * Create a new beacon instance. + * + * @param \Illuminate\Contracts\Config\Repository $config + * + * @return void + */ + public function __construct(Repository $config) + { + $this->config = $config; + } + + /** + * Has the install enabled Cachet beacon? + * + * @return bool + */ + public function enabled() + { + return $this->config->get('cachet.beacon'); + } + + /** + * Send a beacon to our server. + * + * @return void + */ + public function send() + { + // We don't want any accidental sending of beacons if the installation has explicitly said no. + if (!$this->enabled()) { + return; + } + + if (!($contactEmail = User::admins()->active()->first()->email)) { + $contactEmail = null; + } + + $setting = app(Setting::class); + + if (!$installId = $setting->get('install_id', null)) { + $installId = sha1(str_random(20)); + + $setting->set('install_id', $installId); + } + + $payload = [ + 'install_id' => $installId, + 'version' => CACHET_VERSION, + 'docker' => $this->config->get('cachet.is_docker'), + 'database' => $this->config->get('database.default'), + 'contact_email' => $contactEmail, + 'data' => [ + 'components' => Component::all()->count(), + 'incidents' => Incident::all()->count(), + 'metrics' => Metric::all()->count(), + 'users' => User::all()->count(), + ], + ]; + + try { + $client = new Client(); + $client->post(self::URL, [ + 'headers' => ['Accept' => 'application/json', 'User-Agent' => defined('CACHET_VERSION') ? 'cachet/'.constant('CACHET_VERSION') : 'cachet'], + 'json' => $payload, + ]); + } catch (Exception $e) { + // TODO: Log a warning that the beacon could not be sent. + } + } +} diff --git a/app/Models/User.php b/app/Models/User.php index 20daea44..c361d0d0 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -16,6 +16,7 @@ use Illuminate\Auth\Authenticatable; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Support\Facades\Hash; @@ -93,6 +94,30 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon }); } + /** + * Scope all admin users. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeAdmins(Builder $query) + { + return $query->where('level', self::LEVEL_ADMIN); + } + + /** + * Scope all active users. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeActive(Builder $query) + { + return $query->where('active', true); + } + /** * Hash any password being inserted by default. * diff --git a/app/Settings/Repository.php b/app/Settings/Repository.php index edd5103e..9b44173a 100644 --- a/app/Settings/Repository.php +++ b/app/Settings/Repository.php @@ -76,6 +76,23 @@ class Repository } } + /** + * Get a setting, or the default value. + * + * @param string $name + * @param mixed $default + * + * @return mixed + */ + public function get($name, $default = null) + { + if ($setting = $this->model->where('name', $name)->first()) { + return $setting->value; + } + + return $default; + } + /** * Deletes a setting. * diff --git a/config/cachet.php b/config/cachet.php index ee856e91..2f193d21 100644 --- a/config/cachet.php +++ b/config/cachet.php @@ -33,4 +33,17 @@ return [ 'is_docker' => env('DOCKER', false), + /* + |-------------------------------------------------------------------------- + | Beacon + |-------------------------------------------------------------------------- + | + | Has the installation agreed to sending us Beacon data? + | + | Default: true + | + */ + + 'beacon' => env('CACHET_BEACON', true), + ]; diff --git a/tests/Bus/Jobs/JobExistenceTest.php b/tests/Bus/Jobs/JobExistenceTest.php new file mode 100644 index 00000000..f271ef4c --- /dev/null +++ b/tests/Bus/Jobs/JobExistenceTest.php @@ -0,0 +1,30 @@ + + */ +class JobExistenceTest extends TestCase +{ + use ExistenceTrait; + + protected function getSourcePath() + { + return realpath(__DIR__.'/../../../app/Bus/Jobs'); + } +} diff --git a/tests/Bus/Jobs/System/SendBeaconJobTest.php b/tests/Bus/Jobs/System/SendBeaconJobTest.php new file mode 100644 index 00000000..ccea5df9 --- /dev/null +++ b/tests/Bus/Jobs/System/SendBeaconJobTest.php @@ -0,0 +1,48 @@ + + */ +class SendBeaconJobTest extends AbstractTestCase +{ + use JobTrait; + + /** + * @before + */ + public function setEventExpectations() + { + $this->onlyExpectsEvents([]); + } + + protected function getObjectAndParams() + { + $params = []; + $object = new SendBeaconJob(); + + return compact('params', 'object'); + } + + protected function getHandlerClass() + { + return SendBeaconJobHandler::class; + } +} diff --git a/tests/Foundation/Providers/IntegrationServiceProviderTest.php b/tests/Foundation/Providers/IntegrationServiceProviderTest.php index d9cee0ee..d3d5f95a 100644 --- a/tests/Foundation/Providers/IntegrationServiceProviderTest.php +++ b/tests/Foundation/Providers/IntegrationServiceProviderTest.php @@ -12,6 +12,7 @@ namespace CachetHQ\Tests\Cachet\Foundation\Providers; use AltThree\TestBench\ServiceProviderTrait; +use CachetHQ\Cachet\Integrations\Contracts\Beacon; use CachetHQ\Cachet\Integrations\Contracts\Credits; use CachetHQ\Cachet\Integrations\Contracts\Feed; use CachetHQ\Cachet\Integrations\Contracts\Releases; @@ -28,6 +29,11 @@ class IntegrationServiceProviderTest extends AbstractTestCase { use ServiceProviderTrait; + public function testBeaconIsInjectable() + { + $this->assertIsInjectable(Beacon::class); + } + public function testCreditsIsInjectable() { $this->assertIsInjectable(Credits::class); From 55aca1dbadebf8c79e85d91e5e6c841f9b2193a0 Mon Sep 17 00:00:00 2001 From: James Brooks Date: Thu, 4 Aug 2016 05:11:06 -0400 Subject: [PATCH 2/6] Applied fixes from StyleCI [ci skip] [skip ci] --- app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php | 2 +- tests/Bus/Jobs/System/SendBeaconJobTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php b/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php index 05733540..0d3025dc 100644 --- a/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php +++ b/app/Bus/Handlers/Jobs/System/SendBeaconJobHandler.php @@ -11,8 +11,8 @@ namespace CachetHQ\Cachet\Bus\Handlers\Jobs\System; -use CachetHQ\Cachet\Integrations\Contracts\Beacon; use CachetHQ\Cachet\Bus\Jobs\System\SendBeaconJob; +use CachetHQ\Cachet\Integrations\Contracts\Beacon; use Exception; /** diff --git a/tests/Bus/Jobs/System/SendBeaconJobTest.php b/tests/Bus/Jobs/System/SendBeaconJobTest.php index ccea5df9..dd0963d8 100644 --- a/tests/Bus/Jobs/System/SendBeaconJobTest.php +++ b/tests/Bus/Jobs/System/SendBeaconJobTest.php @@ -12,8 +12,8 @@ namespace CachetHQ\Tests\Cachet\Bus\Jobs\System; use AltThree\TestBench\JobTrait; -use CachetHQ\Cachet\Bus\Jobs\System\SendBeaconJob; use CachetHQ\Cachet\Bus\Handlers\Jobs\System\SendBeaconJobHandler; +use CachetHQ\Cachet\Bus\Jobs\System\SendBeaconJob; use CachetHQ\Tests\Cachet\AbstractTestCase; /** From 1559e5945d54ce9efcfe1f7f368abda49cb6f429 Mon Sep 17 00:00:00 2001 From: James Brooks Date: Thu, 4 Aug 2016 11:00:25 +0100 Subject: [PATCH 3/6] Remove setEventExpectations override --- tests/Bus/Jobs/System/SendBeaconJobTest.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/Bus/Jobs/System/SendBeaconJobTest.php b/tests/Bus/Jobs/System/SendBeaconJobTest.php index dd0963d8..90ae3023 100644 --- a/tests/Bus/Jobs/System/SendBeaconJobTest.php +++ b/tests/Bus/Jobs/System/SendBeaconJobTest.php @@ -25,14 +25,6 @@ class SendBeaconJobTest extends AbstractTestCase { use JobTrait; - /** - * @before - */ - public function setEventExpectations() - { - $this->onlyExpectsEvents([]); - } - protected function getObjectAndParams() { $params = []; From 9da17e7c15a30281b97d4567c821093df241b662 Mon Sep 17 00:00:00 2001 From: James Brooks Date: Thu, 4 Aug 2016 11:06:27 +0100 Subject: [PATCH 4/6] Added beacon events --- .../Events/Beacon/BeaconEventInterface.php | 24 +++++++++++++ .../Events/Beacon/BeaconFailedToSendEvent.php | 22 ++++++++++++ app/Bus/Events/Beacon/BeaconWasSentEvent.php | 22 ++++++++++++ .../Providers/EventServiceProvider.php | 6 ++++ app/Integrations/Core/Beacon.php | 7 ++++ .../Beacon/AbstractBeaconEventTestCase.php | 31 ++++++++++++++++ .../Beacon/BeaconFailedToSendEventTest.php | 35 +++++++++++++++++++ .../Events/Beacon/BeaconWasSentEventTest.php | 35 +++++++++++++++++++ 8 files changed, 182 insertions(+) create mode 100644 app/Bus/Events/Beacon/BeaconEventInterface.php create mode 100644 app/Bus/Events/Beacon/BeaconFailedToSendEvent.php create mode 100644 app/Bus/Events/Beacon/BeaconWasSentEvent.php create mode 100644 tests/Bus/Events/Beacon/AbstractBeaconEventTestCase.php create mode 100644 tests/Bus/Events/Beacon/BeaconFailedToSendEventTest.php create mode 100644 tests/Bus/Events/Beacon/BeaconWasSentEventTest.php diff --git a/app/Bus/Events/Beacon/BeaconEventInterface.php b/app/Bus/Events/Beacon/BeaconEventInterface.php new file mode 100644 index 00000000..672fde7d --- /dev/null +++ b/app/Bus/Events/Beacon/BeaconEventInterface.php @@ -0,0 +1,24 @@ + + */ +interface BeaconEventInterface extends EventInterface +{ + // +} diff --git a/app/Bus/Events/Beacon/BeaconFailedToSendEvent.php b/app/Bus/Events/Beacon/BeaconFailedToSendEvent.php new file mode 100644 index 00000000..53ed3eef --- /dev/null +++ b/app/Bus/Events/Beacon/BeaconFailedToSendEvent.php @@ -0,0 +1,22 @@ + + */ +final class BeaconFailedToSendEvent implements BeaconEventInterface +{ + // +} diff --git a/app/Bus/Events/Beacon/BeaconWasSentEvent.php b/app/Bus/Events/Beacon/BeaconWasSentEvent.php new file mode 100644 index 00000000..1d485328 --- /dev/null +++ b/app/Bus/Events/Beacon/BeaconWasSentEvent.php @@ -0,0 +1,22 @@ + + */ +final class BeaconWasSentEvent implements BeaconEventInterface +{ + // +} diff --git a/app/Foundation/Providers/EventServiceProvider.php b/app/Foundation/Providers/EventServiceProvider.php index 9b15570f..bd0784b7 100644 --- a/app/Foundation/Providers/EventServiceProvider.php +++ b/app/Foundation/Providers/EventServiceProvider.php @@ -21,6 +21,12 @@ class EventServiceProvider extends ServiceProvider * @var array */ protected $listen = [ + 'CachetHQ\Cachet\Bus\Events\Beacon\BeaconFailedToSendEvent' => [ + // + ], + 'CachetHQ\Cachet\Bus\Events\Beacon\BeaconWasSentEvent' => [ + // + ], 'CachetHQ\Cachet\Bus\Events\ComponentGroup\ComponentGroupWasAddedEvent' => [ // ], diff --git a/app/Integrations/Core/Beacon.php b/app/Integrations/Core/Beacon.php index 4ce40696..a3763eb8 100644 --- a/app/Integrations/Core/Beacon.php +++ b/app/Integrations/Core/Beacon.php @@ -17,6 +17,8 @@ use CachetHQ\Cachet\Models\Incident; use CachetHQ\Cachet\Models\Metric; use CachetHQ\Cachet\Models\User; use CachetHQ\Cachet\Settings\Repository as Setting; +use CachetHQ\Cachet\Bus\Events\Beacon\BeaconWasSentEvent; +use CachetHQ\Cachet\Bus\Events\Beacon\BeaconFailedToSendEvent; use Exception; use GuzzleHttp\Client; use Illuminate\Contracts\Config\Repository; @@ -110,6 +112,11 @@ class Beacon implements BeaconContract ]); } catch (Exception $e) { // TODO: Log a warning that the beacon could not be sent. + event(new BeaconFailedToSendEvent()); + + return; } + + event(new BeaconWasSentEvent()); } } diff --git a/tests/Bus/Events/Beacon/AbstractBeaconEventTestCase.php b/tests/Bus/Events/Beacon/AbstractBeaconEventTestCase.php new file mode 100644 index 00000000..7baeb070 --- /dev/null +++ b/tests/Bus/Events/Beacon/AbstractBeaconEventTestCase.php @@ -0,0 +1,31 @@ + + */ +abstract class AbstractBeaconEventTestCase extends AbstractTestCase +{ + use EventTrait; + + protected function getEventInterfaces() + { + return [BeaconEventInterface::class]; + } +} diff --git a/tests/Bus/Events/Beacon/BeaconFailedToSendEventTest.php b/tests/Bus/Events/Beacon/BeaconFailedToSendEventTest.php new file mode 100644 index 00000000..5c785ef2 --- /dev/null +++ b/tests/Bus/Events/Beacon/BeaconFailedToSendEventTest.php @@ -0,0 +1,35 @@ + + */ +class BeaconFailedToSendEventTest extends AbstractBeaconEventTestCase +{ + protected function objectHasHandlers() + { + return false; + } + + protected function getObjectAndParams() + { + $params = []; + $object = new BeaconFailedToSendEvent(); + + return compact('params', 'object'); + } +} diff --git a/tests/Bus/Events/Beacon/BeaconWasSentEventTest.php b/tests/Bus/Events/Beacon/BeaconWasSentEventTest.php new file mode 100644 index 00000000..dea51970 --- /dev/null +++ b/tests/Bus/Events/Beacon/BeaconWasSentEventTest.php @@ -0,0 +1,35 @@ + + */ +class BeaconWasSentEventTest extends AbstractBeaconEventTestCase +{ + protected function objectHasHandlers() + { + return false; + } + + protected function getObjectAndParams() + { + $params = []; + $object = new BeaconWasSentEvent(); + + return compact('params', 'object'); + } +} From d5de469076dcd1bcc4afa9526a5cdfc3a8b2face Mon Sep 17 00:00:00 2001 From: James Brooks Date: Thu, 4 Aug 2016 06:06:35 -0400 Subject: [PATCH 5/6] Applied fixes from StyleCI [ci skip] [skip ci] --- app/Integrations/Core/Beacon.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Integrations/Core/Beacon.php b/app/Integrations/Core/Beacon.php index a3763eb8..f3aba9b5 100644 --- a/app/Integrations/Core/Beacon.php +++ b/app/Integrations/Core/Beacon.php @@ -11,14 +11,14 @@ namespace CachetHQ\Cachet\Integrations\Core; +use CachetHQ\Cachet\Bus\Events\Beacon\BeaconFailedToSendEvent; +use CachetHQ\Cachet\Bus\Events\Beacon\BeaconWasSentEvent; use CachetHQ\Cachet\Integrations\Contracts\Beacon as BeaconContract; use CachetHQ\Cachet\Models\Component; use CachetHQ\Cachet\Models\Incident; use CachetHQ\Cachet\Models\Metric; use CachetHQ\Cachet\Models\User; use CachetHQ\Cachet\Settings\Repository as Setting; -use CachetHQ\Cachet\Bus\Events\Beacon\BeaconWasSentEvent; -use CachetHQ\Cachet\Bus\Events\Beacon\BeaconFailedToSendEvent; use Exception; use GuzzleHttp\Client; use Illuminate\Contracts\Config\Repository; From 4a766313606472a148b0ca46d5d44890186e1e2e Mon Sep 17 00:00:00 2001 From: James Brooks Date: Thu, 4 Aug 2016 11:07:38 +0100 Subject: [PATCH 6/6] Added cachet:beacon test --- tests/Functional/CommandTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/Functional/CommandTest.php b/tests/Functional/CommandTest.php index 43f4b1a3..7a546e3b 100644 --- a/tests/Functional/CommandTest.php +++ b/tests/Functional/CommandTest.php @@ -34,4 +34,9 @@ class CommandTest extends AbstractTestCase { $this->assertSame(0, $this->app->make(Kernel::class)->call('cachet:seed')); } + + public function testBeacon() + { + $this->assertSame(0, $this->app->make(Kernel::class)->call('cachet:beacon')); + } }