From ad0954eb206406acbfa5888585b08e46aeba71dc Mon Sep 17 00:00:00 2001 From: Marius Palade Date: Sun, 2 Oct 2016 15:57:32 +0300 Subject: [PATCH] Add visibility to component groups (#2027) Implement visibility for the components groups. Closes #1892 Add functional test that asserts a guest can only see public items. * Fix tests not running due to hitting the Setup page. The missing `boostrap/cachet/testing.php` file is now generated the first time tests are ran. * Add a functional test that asserts logged in users can see all items. Add constants for possible values for the visible column/field of the ComponentGroup model. Code review changes. * Add API tests for component group visibility feature. * Implement the visibility hidden option for a component group. Fixes #1892. Add migration for the created_by column, in component_groups table. Add methods to the ComponentGroup and User models to be able to work with the created_by column. Hidden component groups are no longer displayed on the index page for loggedin users. Add functional test for the dashboard page. Save owner on create/edit component group. Update the API tests for Component group visibility feature. * Replace auth() usage with app(Guard::class). * Apply StyleCI fixes. * Drop the hidden visibility feature and fix all tests. Some code review fixes too. * Rename public to visible since it's a reserved keyword. Apply StyleCI fixes and correct typo. * Code review changes. * Tidy up component and component groups gathering. * Code review changes and StyleCI fixes. * Code review changes. * Remove extra whitespace * Remove useless method. --- .../AddComponentGroupCommand.php | 12 ++- .../UpdateComponentGroupCommand.php | 12 ++- .../AddComponentGroupCommandHandler.php | 1 + .../UpdateComponentGroupCommandHandler.php | 1 + app/Composers/Modules/ComponentsComposer.php | 44 ++++++++- app/Console/Commands/DemoSeederCommand.php | 2 + .../Api/ComponentGroupController.php | 27 +++++- .../Dashboard/ComponentController.php | 6 +- .../Dashboard/DashboardController.php | 36 +++++++- app/Models/Component.php | 29 ++++++ app/Models/ComponentGroup.php | 49 +++++++++- database/factories/ModelFactory.php | 9 ++ ...erTableComponentGroupsAddVisibleColumn.php | 46 ++++++++++ resources/lang/en/forms.php | 13 ++- .../dashboard/components/groups/add.blade.php | 7 ++ .../components/groups/edit.blade.php | 7 ++ tests/AbstractTestCase.php | 62 +++++++++++++ tests/Api/ComponentGroupTest.php | 66 +++++++++++++- .../AddComponentGroupCommandTest.php | 14 ++- .../UpdateComponentGroupCommandTest.php | 11 ++- .../Dashboard/DashboardControllerTest.php | 84 +++++++++++++++++ .../Controllers/StatusPageControllerTest.php | 91 +++++++++++++++++++ 22 files changed, 602 insertions(+), 27 deletions(-) create mode 100644 database/migrations/2016_07_25_052444_AlterTableComponentGroupsAddVisibleColumn.php create mode 100644 tests/Http/Controllers/Dashboard/DashboardControllerTest.php create mode 100644 tests/Http/Controllers/StatusPageControllerTest.php diff --git a/app/Bus/Commands/ComponentGroup/AddComponentGroupCommand.php b/app/Bus/Commands/ComponentGroup/AddComponentGroupCommand.php index e68f24fd09d8..2982e495c18b 100644 --- a/app/Bus/Commands/ComponentGroup/AddComponentGroupCommand.php +++ b/app/Bus/Commands/ComponentGroup/AddComponentGroupCommand.php @@ -39,6 +39,13 @@ final class AddComponentGroupCommand */ public $collapsed; + /** + * Is the component visible to public? + * + * @var int + */ + public $visible; + /** * The validation rules. * @@ -48,6 +55,7 @@ final class AddComponentGroupCommand 'name' => 'required|string', 'order' => 'int', 'collapsed' => 'int|between:0,3', + 'visible' => 'bool', ]; /** @@ -56,13 +64,15 @@ final class AddComponentGroupCommand * @param string $name * @param int $order * @param int $collapsed + * @param int $visible * * @return void */ - public function __construct($name, $order, $collapsed) + public function __construct($name, $order, $collapsed, $visible) { $this->name = $name; $this->order = (int) $order; $this->collapsed = $collapsed; + $this->visible = (int) $visible; } } diff --git a/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php b/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php index a20c49448557..9f1dbd96fa78 100644 --- a/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php +++ b/app/Bus/Commands/ComponentGroup/UpdateComponentGroupCommand.php @@ -48,6 +48,13 @@ final class UpdateComponentGroupCommand */ public $collapsed; + /** + * Is the component visible to public? + * + * @var int + */ + public $visible; + /** * The validation rules. * @@ -57,6 +64,7 @@ final class UpdateComponentGroupCommand 'name' => 'string', 'order' => 'int', 'collapsed' => 'int|between:0,3', + 'visible' => 'bool', ]; /** @@ -66,14 +74,16 @@ final class UpdateComponentGroupCommand * @param string $name * @param int $order * @param int $collapsed + * @param int $visible * * @return void */ - public function __construct(ComponentGroup $group, $name, $order, $collapsed) + public function __construct(ComponentGroup $group, $name, $order, $collapsed, $visible) { $this->group = $group; $this->name = $name; $this->order = (int) $order; $this->collapsed = $collapsed; + $this->visible = (int) $visible; } } diff --git a/app/Bus/Handlers/Commands/ComponentGroup/AddComponentGroupCommandHandler.php b/app/Bus/Handlers/Commands/ComponentGroup/AddComponentGroupCommandHandler.php index 9066df512436..b2a935a86e97 100644 --- a/app/Bus/Handlers/Commands/ComponentGroup/AddComponentGroupCommandHandler.php +++ b/app/Bus/Handlers/Commands/ComponentGroup/AddComponentGroupCommandHandler.php @@ -30,6 +30,7 @@ public function handle(AddComponentGroupCommand $command) 'name' => $command->name, 'order' => $command->order, 'collapsed' => $command->collapsed, + 'visible' => $command->visible, ]); event(new ComponentGroupWasAddedEvent($group)); diff --git a/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php b/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php index 4ea401869f49..ef0f3a07ef88 100644 --- a/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php +++ b/app/Bus/Handlers/Commands/ComponentGroup/UpdateComponentGroupCommandHandler.php @@ -46,6 +46,7 @@ protected function filter(UpdateComponentGroupCommand $command) 'name' => $command->name, 'order' => $command->order, 'collapsed' => $command->collapsed, + 'visible' => $command->visible, ]; return array_filter($params, function ($val) { diff --git a/app/Composers/Modules/ComponentsComposer.php b/app/Composers/Modules/ComponentsComposer.php index a5df06ba5c11..b581e0457641 100644 --- a/app/Composers/Modules/ComponentsComposer.php +++ b/app/Composers/Modules/ComponentsComposer.php @@ -13,6 +13,7 @@ use CachetHQ\Cachet\Models\Component; use CachetHQ\Cachet\Models\ComponentGroup; +use Illuminate\Contracts\Auth\Guard; use Illuminate\Contracts\View\View; /** @@ -23,6 +24,25 @@ */ class ComponentsComposer { + /** + * The user session object. + * + * @var \Illuminate\Contracts\Auth\Guard + */ + protected $guard; + + /** + * Creates a new components composer instance. + * + * @param \Illuminate\Contracts\Auth\Guard $guard + * + * @return void + */ + public function __construct(Guard $guard) + { + $this->guard = $guard; + } + /** * Index page view composer. * @@ -32,12 +52,28 @@ class ComponentsComposer */ public function compose(View $view) { - // Component & Component Group lists. - $usedComponentGroups = Component::enabled()->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id'); - $componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get(); - $ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get(); + $componentGroups = $this->getVisibleGroupedComponents(); + $ungroupedComponents = Component::ungrouped()->get(); $view->withComponentGroups($componentGroups) ->withUngroupedComponents($ungroupedComponents); } + + /** + * Get visible grouped components. + * + * @return \Illuminate\Support\Collection + */ + protected function getVisibleGroupedComponents() + { + $componentGroupsBuilder = ComponentGroup::query(); + if (!$this->guard->check()) { + $componentGroupsBuilder->visible(); + } + + $usedComponentGroups = Component::grouped()->pluck('group_id'); + + return $componentGroupsBuilder->used($usedComponentGroups) + ->get(); + } } diff --git a/app/Console/Commands/DemoSeederCommand.php b/app/Console/Commands/DemoSeederCommand.php index a682ddd84a96..283f6d6182c1 100644 --- a/app/Console/Commands/DemoSeederCommand.php +++ b/app/Console/Commands/DemoSeederCommand.php @@ -106,10 +106,12 @@ protected function seedComponentGroups() 'name' => 'Websites', 'order' => 1, 'collapsed' => 0, + 'visible' => ComponentGroup::VISIBLE_AUTHENTICATED, ], [ 'name' => 'Alt Three', 'order' => 2, 'collapsed' => 1, + 'visible' => ComponentGroup::VISIBLE_GUEST, ], ]; diff --git a/app/Http/Controllers/Api/ComponentGroupController.php b/app/Http/Controllers/Api/ComponentGroupController.php index 9c424b798233..4804511deb2b 100644 --- a/app/Http/Controllers/Api/ComponentGroupController.php +++ b/app/Http/Controllers/Api/ComponentGroupController.php @@ -16,6 +16,7 @@ use CachetHQ\Cachet\Bus\Commands\ComponentGroup\UpdateComponentGroupCommand; use CachetHQ\Cachet\Models\ComponentGroup; use GrahamCampbell\Binput\Facades\Binput; +use Illuminate\Contracts\Auth\Guard; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Request; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -29,6 +30,23 @@ */ class ComponentGroupController extends AbstractApiController { + /** + * The user session object. + * + * @var \Illuminate\Contracts\Auth\Guard + */ + protected $guard; + + /** + * Creates a new component group controller instance. + * + * @param \Illuminate\Contracts\Auth\Guard $guard + */ + public function __construct(Guard $guard) + { + $this->guard = $guard; + } + /** * Get all groups. * @@ -37,6 +55,9 @@ class ComponentGroupController extends AbstractApiController public function getGroups() { $groups = ComponentGroup::query(); + if (!$this->guard->check()) { + $groups = ComponentGroup::visible(); + } $groups->search(Binput::except(['sort', 'order', 'per_page'])); @@ -74,7 +95,8 @@ public function postGroups() $group = dispatch(new AddComponentGroupCommand( Binput::get('name'), Binput::get('order', 0), - Binput::get('collapsed', 0) + Binput::get('collapsed', 0), + Binput::get('visible', ComponentGroup::VISIBLE_AUTHENTICATED) )); } catch (QueryException $e) { throw new BadRequestHttpException(); @@ -97,7 +119,8 @@ public function putGroup(ComponentGroup $group) $group, Binput::get('name'), Binput::get('order'), - Binput::get('collapsed') + Binput::get('collapsed'), + Binput::get('visible') )); } catch (QueryException $e) { throw new BadRequestHttpException(); diff --git a/app/Http/Controllers/Dashboard/ComponentController.php b/app/Http/Controllers/Dashboard/ComponentController.php index 38a021f453cd..6f0f0f2a5d6e 100644 --- a/app/Http/Controllers/Dashboard/ComponentController.php +++ b/app/Http/Controllers/Dashboard/ComponentController.php @@ -277,7 +277,8 @@ public function postAddComponentGroup() $group = dispatch(new AddComponentGroupCommand( Binput::get('name'), Binput::get('order', 0), - Binput::get('collapsed') + Binput::get('collapsed'), + Binput::get('visible') )); } catch (ValidationException $e) { return Redirect::route('dashboard.components.groups.add') @@ -304,7 +305,8 @@ public function updateComponentGroupAction(ComponentGroup $group) $group, Binput::get('name'), $group->order, - Binput::get('collapsed') + Binput::get('collapsed'), + Binput::get('visible') )); } catch (ValidationException $e) { return Redirect::route('dashboard.components.groups.edit', ['id' => $group->id]) diff --git a/app/Http/Controllers/Dashboard/DashboardController.php b/app/Http/Controllers/Dashboard/DashboardController.php index 9d2d2c1746a2..94d07c476492 100644 --- a/app/Http/Controllers/Dashboard/DashboardController.php +++ b/app/Http/Controllers/Dashboard/DashboardController.php @@ -17,6 +17,7 @@ use CachetHQ\Cachet\Models\ComponentGroup; use CachetHQ\Cachet\Models\Incident; use CachetHQ\Cachet\Models\Subscriber; +use Illuminate\Contracts\Auth\Guard; use Illuminate\Routing\Controller; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Config; @@ -52,16 +53,25 @@ class DashboardController extends Controller */ protected $feed; + /** + * The user session object. + * + * @var \Illuminate\Contracts\Auth\Guard + */ + protected $guard; + /** * Creates a new dashboard controller instance. * * @param \CachetHQ\Cachet\Integrations\Feed $feed + * @param \Illuminate\Contracts\Auth\Guard $guard * * @return void */ - public function __construct(Feed $feed) + public function __construct(Feed $feed, Guard $guard) { $this->feed = $feed; + $this->guard = $guard; $this->startDate = new Date(); $this->dateTimeZone = Config::get('cachet.timezone'); } @@ -86,9 +96,9 @@ public function showDashboard() $components = Component::orderBy('order')->get(); $incidents = $this->getIncidents(); $subscribers = $this->getSubscribers(); - $usedComponentGroups = Component::enabled()->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id'); - $componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get(); - $ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get(); + + $componentGroups = $this->getVisibleGroupedComponents(); + $ungroupedComponents = Component::ungrouped()->get(); $welcomeUser = !Auth::user()->welcomed; if ($welcomeUser) { @@ -174,4 +184,22 @@ protected function getSubscribers() return $allSubscribers; } + + /** + * Get visible grouped components. + * + * @return \Illuminate\Support\Collection + */ + protected function getVisibleGroupedComponents() + { + $componentGroupsBuilder = ComponentGroup::query(); + if (!$this->guard->check()) { + $componentGroupsBuilder = ComponentGroup::visible(); + } + + $usedComponentGroups = Component::grouped()->pluck('group_id'); + + return $componentGroupsBuilder->used($usedComponentGroups) + ->get(); + } } diff --git a/app/Models/Component.php b/app/Models/Component.php index dd87b64639d7..98f5c899c28d 100644 --- a/app/Models/Component.php +++ b/app/Models/Component.php @@ -188,6 +188,35 @@ public function scopeDisabled(Builder $query) return $query->where('enabled', false); } + /** + * Finds all ungrouped components. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeUngrouped(Builder $query) + { + return $query->enabled() + ->where('group_id', 0) + ->orderBy('order') + ->orderBy('created_at'); + } + + /** + * Finds all grouped components. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeGrouped(Builder $query) + { + return $query->enabled() + ->where('group_id', '>', 0) + ->groupBy('group_id'); + } + /** * Returns all of the tags on this component. * diff --git a/app/Models/ComponentGroup.php b/app/Models/ComponentGroup.php index 345f22101be5..5f881dbda338 100644 --- a/app/Models/ComponentGroup.php +++ b/app/Models/ComponentGroup.php @@ -15,13 +15,29 @@ use CachetHQ\Cachet\Models\Traits\SearchableTrait; use CachetHQ\Cachet\Models\Traits\SortableTrait; use CachetHQ\Cachet\Presenters\ComponentGroupPresenter; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Collection; use McCool\LaravelAutoPresenter\HasPresenter; class ComponentGroup extends Model implements HasPresenter { use SearchableTrait, SortableTrait, ValidatingTrait; + /** + * Viewable only authenticated users. + * + * @var int + */ + const VISIBLE_AUTHENTICATED = 0; + + /** + * Viewable by public. + * + * @var int + */ + const VISIBLE_GUEST = 1; + /** * The model's attributes. * @@ -30,6 +46,7 @@ class ComponentGroup extends Model implements HasPresenter protected $attributes = [ 'order' => 0, 'collapsed' => 0, + 'visible' => 0, ]; /** @@ -41,6 +58,7 @@ class ComponentGroup extends Model implements HasPresenter 'name' => 'string', 'order' => 'int', 'collapsed' => 'int', + 'visible' => 'int', ]; /** @@ -48,7 +66,7 @@ class ComponentGroup extends Model implements HasPresenter * * @var string[] */ - protected $fillable = ['name', 'order', 'collapsed']; + protected $fillable = ['name', 'order', 'collapsed', 'visible']; /** * The validation rules. @@ -59,6 +77,7 @@ class ComponentGroup extends Model implements HasPresenter 'name' => 'required|string', 'order' => 'int', 'collapsed' => 'int', + 'visible' => 'bool', ]; /** @@ -71,6 +90,7 @@ class ComponentGroup extends Model implements HasPresenter 'name', 'order', 'collapsed', + 'visible', ]; /** @@ -83,6 +103,7 @@ class ComponentGroup extends Model implements HasPresenter 'name', 'order', 'collapsed', + 'visible', ]; /** @@ -141,4 +162,30 @@ public function getPresenterClass() { return ComponentGroupPresenter::class; } + + /** + * Finds all component groups which are visible to public. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeVisible(Builder $query) + { + return $query->where('visible', self::VISIBLE_GUEST); + } + + /** + * Finds all used component groups. + * + * @param \Illuminate\Database\Eloquent\Builder $query + * @param \Illuminate\Support\Collection $usedComponentGroups + * + * @return \Illuminate\Database\Eloquent\Builder + */ + public function scopeUsed(Builder $query, Collection $usedComponentGroups) + { + return $query->whereIn('id', $usedComponentGroups) + ->orderBy('order'); + } } diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index 3c70bdbeb169..de96e720d384 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -15,6 +15,7 @@ use CachetHQ\Cachet\Models\IncidentTemplate; use CachetHQ\Cachet\Models\Metric; use CachetHQ\Cachet\Models\MetricPoint; +use CachetHQ\Cachet\Models\Setting; use CachetHQ\Cachet\Models\Subscriber; use CachetHQ\Cachet\Models\Subscription; use CachetHQ\Cachet\Models\User; @@ -35,6 +36,7 @@ 'name' => $faker->words(2, true), 'order' => 0, 'collapsed' => random_int(0, 3), + 'visible' => $faker->boolean(), ]; }); @@ -77,6 +79,13 @@ ]; }); +$factory->define(Setting::class, function ($faker) { + return [ + 'name' => 'app_name', + 'value' => 'Cachet Test Demo', + ]; +}); + $factory->define(Subscriber::class, function ($faker) { return [ 'email' => $faker->safeEmail, diff --git a/database/migrations/2016_07_25_052444_AlterTableComponentGroupsAddVisibleColumn.php b/database/migrations/2016_07_25_052444_AlterTableComponentGroupsAddVisibleColumn.php new file mode 100644 index 000000000000..4d933d3ebc23 --- /dev/null +++ b/database/migrations/2016_07_25_052444_AlterTableComponentGroupsAddVisibleColumn.php @@ -0,0 +1,46 @@ +tinyInteger('visible') + ->after('order') + ->unsigned() + ->default(\CachetHQ\Cachet\Models\ComponentGroup::VISIBLE_AUTHENTICATED); + + $table->index('visible'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('component_groups', function (Blueprint $table) { + $table->dropColumn('visible'); + }); + } +} diff --git a/resources/lang/en/forms.php b/resources/lang/en/forms.php index fac80593fe56..f73059ccce5a 100644 --- a/resources/lang/en/forms.php +++ b/resources/lang/en/forms.php @@ -77,11 +77,14 @@ 'enabled' => 'Component enabled?', 'groups' => [ - 'name' => 'Name', - 'collapsing' => 'Choose visibility of the group', - 'visible' => 'Always expanded', - 'collapsed' => 'Collapse the group by default', - 'collapsed_incident' => 'Collapse the group, but expand if there are issues', + 'name' => 'Name', + 'collapsing' => 'Expand/Collapse options', + 'visible' => 'Always expanded', + 'collapsed' => 'Collapse the group by default', + 'collapsed_incident' => 'Collapse the group, but expand if there are issues', + 'visibility' => 'Visibility', + 'visibility_public' => 'Visible to public', + 'visibility_authenticated' => 'Visible only to logged in users', ], ], diff --git a/resources/views/dashboard/components/groups/add.blade.php b/resources/views/dashboard/components/groups/add.blade.php index dc843f9d657e..2b6923a15c52 100644 --- a/resources/views/dashboard/components/groups/add.blade.php +++ b/resources/views/dashboard/components/groups/add.blade.php @@ -29,6 +29,13 @@ +
+ + +
diff --git a/resources/views/dashboard/components/groups/edit.blade.php b/resources/views/dashboard/components/groups/edit.blade.php index 39f0519e7384..e7aacb9f5907 100644 --- a/resources/views/dashboard/components/groups/edit.blade.php +++ b/resources/views/dashboard/components/groups/edit.blade.php @@ -29,6 +29,13 @@
+
+ + +
diff --git a/tests/AbstractTestCase.php b/tests/AbstractTestCase.php index 94e9935b3d35..5901a1e62484 100644 --- a/tests/AbstractTestCase.php +++ b/tests/AbstractTestCase.php @@ -11,6 +11,9 @@ namespace CachetHQ\Tests\Cachet; +use CachetHQ\Cachet\Models\User; +use CachetHQ\Cachet\Settings\Cache; +use CachetHQ\Cachet\Settings\Repository; use Illuminate\Contracts\Console\Kernel; use Illuminate\Foundation\Testing\TestCase; @@ -28,6 +31,13 @@ abstract class AbstractTestCase extends TestCase */ protected $baseUrl = 'http://localhost'; + /** + * Test actor. + * + * @var User + */ + protected $user; + /** * Creates the application. * @@ -41,4 +51,56 @@ public function createApplication() return $app; } + + /** + * Sign in an user if it's the case. + * + * @param User|null $user + * + * @return AbstractTestCase + */ + protected function signIn(User $user = null) + { + $this->user = $user ?: $this->createUser(); + + $this->be($this->user); + + return $this; + } + + /** + * Create and return a new user. + * + * @param array $properties + * + * @return User + */ + protected function createUser($properties = []) + { + return factory(User::class)->create($properties); + } + + /** + * Set up the needed configuration to be able to run the tests. + * + * @return AbstractTestCase + */ + protected function setupConfig() + { + $env = $this->app->environment(); + $repo = $this->app->make(Repository::class); + $cache = $this->app->make(Cache::class); + $loaded = $cache->load($env); + + if ($loaded === false) { + $loaded = $repo->all(); + $cache->store($env, $loaded); + } + + $settings = array_merge($this->app->config->get('setting'), $loaded); + + $this->app->config->set('setting', $settings); + + return $this; + } } diff --git a/tests/Api/ComponentGroupTest.php b/tests/Api/ComponentGroupTest.php index 1da912a9a8ef..2fa40fe62668 100644 --- a/tests/Api/ComponentGroupTest.php +++ b/tests/Api/ComponentGroupTest.php @@ -11,6 +11,9 @@ namespace CachetHQ\Tests\Cachet\Api; +use CachetHQ\Cachet\Models\Component; +use CachetHQ\Cachet\Models\ComponentGroup; + /** * This is the component group test class. * @@ -19,9 +22,13 @@ */ class ComponentGroupTest extends AbstractApiTestCase { + const COMPONENT_GROUP_1_NAME = 'Component Group 1'; + const COMPONENT_GROUP_2_NAME = 'Component Group 2'; + public function testGetGroups() { - $groups = factory('CachetHQ\Cachet\Models\ComponentGroup', 3)->create(); + $groups = factory('CachetHQ\Cachet\Models\ComponentGroup', 3) + ->create(['visible' => ComponentGroup::VISIBLE_GUEST]); $this->get('/api/v1/components/groups'); $this->seeJson(['id' => $groups[0]->id]); @@ -59,8 +66,9 @@ public function testPostGroup() 'name' => 'Foo', 'order' => 1, 'collapsed' => 1, + 'visible' => ComponentGroup::VISIBLE_GUEST, ]); - $this->seeJson(['name' => 'Foo', 'order' => 1, 'collapsed' => 1]); + $this->seeJson(['name' => 'Foo', 'order' => 1, 'collapsed' => 1, 'visible' => ComponentGroup::VISIBLE_GUEST]); $this->assertResponseOk(); } @@ -93,4 +101,58 @@ public function testDeleteGroup() $this->delete('/api/v1/components/groups/1'); $this->assertResponseStatus(204); } + + /** @test */ + public function only_public_component_groups_are_shown_for_a_guest() + { + $this->createComponentGroups(); + + $this->get('/api/v1/components/groups') + ->seeJson(['name' => self::COMPONENT_GROUP_1_NAME]) + ->dontSeeJson(['name' => self::COMPONENT_GROUP_2_NAME]); + $this->assertResponseOk(); + } + + /** @test */ + public function all_component_groups_are_displayed_for_loggedin_users() + { + $this->createComponentGroups() + ->signIn(); + + $this->get('/api/v1/components/groups') + ->seeJson(['name' => self::COMPONENT_GROUP_1_NAME]) + ->seeJson(['name' => self::COMPONENT_GROUP_2_NAME]); + $this->assertResponseOk(); + } + + /** + * Set up the needed data for the tests. + * + * @return TestCase + */ + protected function createComponentGroups() + { + $this->createComponentGroup(self::COMPONENT_GROUP_1_NAME, ComponentGroup::VISIBLE_GUEST) + ->createComponentGroup(self::COMPONENT_GROUP_2_NAME, ComponentGroup::VISIBLE_AUTHENTICATED); + + return $this; + } + + /** + * Create a component group. + * Also attaches a creator if any given as a parameter + * or exists in the test class. + * + * @param string $name + * @param string $visible + * + * @return AbstractApiTestCase + */ + protected function createComponentGroup($name, $visible) + { + factory(ComponentGroup::class) + ->create(['name' => $name, 'visible' => $visible]); + + return $this; + } } diff --git a/tests/Bus/Commands/ComponentGroup/AddComponentGroupCommandTest.php b/tests/Bus/Commands/ComponentGroup/AddComponentGroupCommandTest.php index 8f4253fe81e1..a828cee5ac34 100644 --- a/tests/Bus/Commands/ComponentGroup/AddComponentGroupCommandTest.php +++ b/tests/Bus/Commands/ComponentGroup/AddComponentGroupCommandTest.php @@ -14,6 +14,7 @@ use AltThree\TestBench\CommandTrait; use CachetHQ\Cachet\Bus\Commands\ComponentGroup\AddComponentGroupCommand; use CachetHQ\Cachet\Bus\Handlers\Commands\ComponentGroup\AddComponentGroupCommandHandler; +use CachetHQ\Cachet\Models\ComponentGroup; use CachetHQ\Tests\Cachet\AbstractTestCase; /** @@ -28,9 +29,16 @@ class AddComponentGroupCommandTest extends AbstractTestCase protected function getObjectAndParams() { - $params = ['name' => 'Test', 'order' => 0, 'collapsed' => 1]; - - $object = new AddComponentGroupCommand($params['name'], $params['order'], $params['collapsed']); + $params = [ + 'name' => 'Test', + 'order' => 0, + 'collapsed' => 1, + 'visible' => ComponentGroup::VISIBLE_AUTHENTICATED, + ]; + + $object = new AddComponentGroupCommand( + $params['name'], $params['order'], $params['collapsed'], $params['visible'] + ); return compact('params', 'object'); } diff --git a/tests/Bus/Commands/ComponentGroup/UpdateComponentGroupCommandTest.php b/tests/Bus/Commands/ComponentGroup/UpdateComponentGroupCommandTest.php index 6db036bd3bd9..3ee166a38b43 100644 --- a/tests/Bus/Commands/ComponentGroup/UpdateComponentGroupCommandTest.php +++ b/tests/Bus/Commands/ComponentGroup/UpdateComponentGroupCommandTest.php @@ -29,12 +29,19 @@ class UpdateComponentGroupCommandTest extends AbstractTestCase protected function getObjectAndParams() { - $params = ['group' => new ComponentGroup(), 'name' => 'Foo', 'order' => 1, 'collapsed' => 2]; + $params = [ + 'group' => new ComponentGroup(), + 'name' => 'Foo', + 'order' => 1, + 'collapsed' => 2, + 'visible' => ComponentGroup::VISIBLE_AUTHENTICATED, + ]; $object = new UpdateComponentGroupCommand( $params['group'], $params['name'], $params['order'], - $params['collapsed'] + $params['collapsed'], + $params['visible'] ); return compact('params', 'object'); diff --git a/tests/Http/Controllers/Dashboard/DashboardControllerTest.php b/tests/Http/Controllers/Dashboard/DashboardControllerTest.php new file mode 100644 index 000000000000..d05096c6c34e --- /dev/null +++ b/tests/Http/Controllers/Dashboard/DashboardControllerTest.php @@ -0,0 +1,84 @@ +setupPublicAndNonPublicComponentGroups() + ->setupConfig(); + } + + /** @test */ + public function on_dashboard_all_component_groups_are_displayed() + { + $this->signIn(); + + $this->visit('/dashboard') + ->see(self::COMPONENT_GROUP_1_NAME) + ->see(self::COMPONENT_GROUP_2_NAME); + } + + /** + * Set up the needed data for the components groups tests. + * + * @return TestCase + */ + protected function setupPublicAndNonPublicComponentGroups() + { + $this->createAComponentGroupAndAddAComponent(self::COMPONENT_GROUP_1_NAME, ComponentGroup::VISIBLE_GUEST) + ->createAComponentGroupAndAddAComponent(self::COMPONENT_GROUP_2_NAME, ComponentGroup::VISIBLE_AUTHENTICATED); + + factory(Setting::class)->create(); + + return $this; + } + + /** + * Create a component group and add one component to it. + * + * @param string $name + * @param string $visible + * + * @return TestCase + */ + protected function createAComponentGroupAndAddAComponent($name, $visible) + { + factory(ComponentGroup::class) + ->create(['name' => $name, 'visible' => $visible]) + ->components() + ->save(factory(Component::class)->create()); + + return $this; + } +} diff --git a/tests/Http/Controllers/StatusPageControllerTest.php b/tests/Http/Controllers/StatusPageControllerTest.php new file mode 100644 index 000000000000..6f9a3c68e1f7 --- /dev/null +++ b/tests/Http/Controllers/StatusPageControllerTest.php @@ -0,0 +1,91 @@ +setupPublicAndNonPublicComponentGroups() + ->setupConfig(); + } + + /** @test */ + public function on_index_only_public_component_groups_are_shown_to_a_guest() + { + $this->visit('/') + ->see(self::COMPONENT_GROUP_1_NAME) + ->dontSee(self::COMPONENT_GROUP_2_NAME); + } + + /** @test */ + public function on_index_all_component_groups_are_displayed_to_logged_in_users() + { + $this->signIn(); + + $this->visit('/') + ->see(self::COMPONENT_GROUP_1_NAME) + ->see(self::COMPONENT_GROUP_2_NAME); + } + + /** + * Set up the needed data for the components groups tests. + * + * @return AbstractTestCase + */ + protected function setupPublicAndNonPublicComponentGroups() + { + $this->createAComponentGroupAndAddAComponent(self::COMPONENT_GROUP_1_NAME, ComponentGroup::VISIBLE_GUEST) + ->createAComponentGroupAndAddAComponent(self::COMPONENT_GROUP_2_NAME, ComponentGroup::VISIBLE_AUTHENTICATED); + + factory(Setting::class)->create(); + + return $this; + } + + /** + * Create a component group and add one component to it. + * + * @param string $name + * @param string $visible + * + * @return AbstractTestCase + */ + protected function createAComponentGroupAndAddAComponent($name, $visible) + { + factory(ComponentGroup::class) + ->create(['name' => $name, 'visible' => $visible]) + ->components() + ->save(factory(Component::class)->create()); + + return $this; + } +}