diff --git a/app/Http/Controllers/Api/ComponentGroupController.php b/app/Http/Controllers/Api/ComponentGroupController.php new file mode 100644 index 000000000..c8d8a7be5 --- /dev/null +++ b/app/Http/Controllers/Api/ComponentGroupController.php @@ -0,0 +1,100 @@ +paginator($groups, $request); + } + + /** + * Get a single group. + * + * @param \CachetHQ\Cachet\Models\ComponentGroup $group + * + * @return \Illuminate\Http\JsonResponse + */ + public function getGroup(ComponentGroup $group) + { + return $this->item($group); + } + + /** + * Create a new component group. + * + * @return \Illuminate\Http\JsonResponse + */ + public function postGroups() + { + $groupData = array_filter(Binput::only(['name', 'order'])); + + try { + $group = ComponentGroup::create($groupData); + } catch (Exception $e) { + throw new BadRequestHttpException(); + } + + return $this->item($group); + } + + /** + * Update an existing group. + * + * @param \CachetHQ\Cachet\Models\ComponentGroup $group + * + * @return \Illuminate\Http\JsonResponse + */ + public function putGroup(ComponentGroup $group) + { + $groupData = array_filter(Binput::only(['name', 'order'])); + + try { + $group->update($groupData); + } catch (Exception $e) { + dd($e->getMessage()); + throw new BadRequestHttpException(); + } + + return $this->item($group); + } + + /** + * Delete an existing group. + * + * @param \CachetHQ\Cachet\Models\ComponentGroup $group + * + * @return \Illuminate\Http\JsonResponse + */ + public function deleteGroup(ComponentGroup $group) + { + $group->delete(); + + return $this->noContent(); + } +} diff --git a/app/Http/Routes/ApiRoutes.php b/app/Http/Routes/ApiRoutes.php index e7c4b7c34..9446785b0 100644 --- a/app/Http/Routes/ApiRoutes.php +++ b/app/Http/Routes/ApiRoutes.php @@ -32,6 +32,8 @@ class ApiRoutes // Components $router->get('components', 'ComponentController@getComponents'); + $router->get('components/groups', 'ComponentGroupController@getGroups'); + $router->get('components/groups/{component_group}', 'ComponentGroupController@getGroup'); $router->get('components/{component}', 'ComponentController@getComponent'); // Incidents @@ -48,16 +50,19 @@ class ApiRoutes $router->get('subscribers', 'SubscriberController@getSubscribers'); $router->post('components', 'ComponentController@postComponents'); + $router->post('components/groups', 'ComponentGroupController@postGroups'); $router->post('incidents', 'IncidentController@postIncidents'); $router->post('metrics', 'MetricController@postMetrics'); $router->post('metrics/{metric}/points', 'MetricPointController@postMetricPoints'); $router->post('subscribers', 'SubscriberController@postSubscribers'); + $router->put('components/groups/{component_group}', 'ComponentGroupController@putGroup'); $router->put('components/{component}', 'ComponentController@putComponent'); $router->put('incidents/{incident}', 'IncidentController@putIncident'); $router->put('metrics/{metric}', 'MetricController@putMetric'); $router->put('metrics/{metric}/points/{metric_point}', 'MetricPointController@putMetricPoint'); + $router->delete('components/groups/{component_group}', 'ComponentGroupController@deleteGroup'); $router->delete('components/{component}', 'ComponentController@deleteComponent'); $router->delete('incidents/{incident}', 'IncidentController@deleteIncident'); $router->delete('metrics/{metric}', 'MetricController@deleteMetric'); diff --git a/app/Models/ComponentGroup.php b/app/Models/ComponentGroup.php index a341c4f23..010750e59 100644 --- a/app/Models/ComponentGroup.php +++ b/app/Models/ComponentGroup.php @@ -19,12 +19,13 @@ class ComponentGroup extends Model use ValidatingTrait; /** - * The validation rules. + * The attributes that should be casted to native types. * * @var string[] */ - public $rules = [ - 'name' => 'required', + protected $casts = [ + 'name' => 'string', + 'order' => 'integer', ]; /** @@ -34,6 +35,16 @@ class ComponentGroup extends Model */ protected $fillable = ['name', 'order']; + /** + * The validation rules. + * + * @var string[] + */ + public $rules = [ + 'name' => 'required', + 'order' => 'integer', + ]; + /** * A group can have many components. * diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index e963a0f9e..1286013ee 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -33,6 +33,13 @@ $factory->define('CachetHQ\Cachet\Models\Component', function ($faker) { ]; }); +$factory->define('CachetHQ\Cachet\Models\ComponentGroup', function ($faker) { + return [ + 'name' => $faker->words(2, true), + 'order' => 0, + ]; +}); + $factory->define('CachetHQ\Cachet\Models\Incident', function ($faker) { return [ 'name' => $faker->sentence(), diff --git a/tests/Api/ComponentGroupTest.php b/tests/Api/ComponentGroupTest.php new file mode 100644 index 000000000..6dafb8528 --- /dev/null +++ b/tests/Api/ComponentGroupTest.php @@ -0,0 +1,94 @@ +create(); + + $this->get('/api/v1/components/groups'); + $this->seeJson(['id' => (string) $groups[0]->id]); + $this->seeJson(['id' => (string) $groups[1]->id]); + $this->seeJson(['id' => (string) $groups[2]->id]); + $this->assertResponseOk(); + } + + public function testGetInvalidGroup() + { + $this->get('/api/v1/components/groups/1'); + $this->assertResponseStatus(404); + } + + public function testPostGroupUnauthorized() + { + $this->post('/api/v1/components/groups'); + + $this->assertResponseStatus(401); + } + + public function testPostGroupNoData() + { + $this->beUser(); + + $this->post('/api/v1/components/groups'); + $this->assertResponseStatus(400); + } + + public function testPostGroup() + { + $this->beUser(); + + $this->post('/api/v1/components/groups', [ + 'name' => 'Foo', + 'order' => 1, + ]); + $this->seeJson(['name' => 'Foo']); + $this->assertResponseOk(); + } + + public function testGetNewGroup() + { + $group = factory('CachetHQ\Cachet\Models\ComponentGroup')->create(); + + $this->get('/api/v1/components/groups/1'); + $this->seeJson(['name' => $group->name]); + $this->assertResponseOk(); + } + + public function testPutGroup() + { + $this->beUser(); + $group = factory('CachetHQ\Cachet\Models\ComponentGroup')->create(); + + $this->put('/api/v1/components/groups/1', [ + 'name' => 'Lorem Ipsum Groupous', + ]); + $this->seeJson(['name' => 'Lorem Ipsum Groupous']); + $this->assertResponseOk(); + } + + public function testDeleteGroup() + { + $this->beUser(); + $group = factory('CachetHQ\Cachet\Models\ComponentGroup')->create(); + + $this->delete('/api/v1/components/groups/1'); + $this->assertResponseStatus(204); + } +}