Skip to content

Commit db103e9

Browse files
committed
Fix tests and implement schedule updates API
1 parent 3669b41 commit db103e9

18 files changed

+398
-61
lines changed

database/factories/UpdateFactory.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
namespace Cachet\Database\Factories;
44

5+
use Cachet\Enums\ComponentStatusEnum;
56
use Cachet\Enums\IncidentStatusEnum;
7+
use Cachet\Models\Component;
68
use Cachet\Models\Incident;
9+
use Cachet\Models\Schedule;
710
use Cachet\Models\Update;
811
use Illuminate\Database\Eloquent\Factories\Factory;
12+
use Illuminate\Database\Eloquent\Relations\Relation;
913

1014
/**
1115
* @extends Factory<Update>
@@ -23,10 +27,28 @@ public function definition(): array
2327
{
2428
return [
2529
'updateable_id' => Incident::factory(),
26-
'updateable_type' => 'incident',
30+
'updateable_type' => Relation::getMorphAlias(Incident::class),
2731
'status' => IncidentStatusEnum::identified->value,
2832
'message' => fake()->paragraph,
2933
'user_id' => 1, // @todo decide how to handle storing of users... nullable?
3034
];
3135
}
36+
37+
public function forIncident(?Incident $incident = null): self
38+
{
39+
return $this->state([
40+
'updateable_id' => $component->id ?? Incident::factory(),
41+
'updateable_type' => Relation::getMorphAlias(Incident::class),
42+
'status' => IncidentStatusEnum::identified->value,
43+
]);
44+
}
45+
46+
public function forSchedule(?Schedule $schedule = null): self
47+
{
48+
return $this->state([
49+
'updateable_id' => $schedule->id ?? Schedule::factory(),
50+
'updateable_type' => Relation::getMorphAlias(Schedule::class),
51+
'status' => null,
52+
]);
53+
}
3254
}

database/migrations/2024_10_11_150422_add_morphable_columns_to_incident_updates.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public function up(): void
1313
{
1414
Schema::table('incident_updates', function (Blueprint $table) {
1515
$table->morphs('updateable');
16+
$table->unsignedTinyInteger('status')->nullable()->change();
1617
});
1718
}
1819
};

routes/api.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Cachet\Http\Controllers\Api\MetricController;
1010
use Cachet\Http\Controllers\Api\MetricPointController;
1111
use Cachet\Http\Controllers\Api\ScheduleController;
12+
use Cachet\Http\Controllers\Api\ScheduleUpdateController;
1213
use Cachet\Http\Controllers\Api\StatusController;
1314
use Illuminate\Support\Facades\Route;
1415

@@ -22,8 +23,10 @@
2223
]);
2324

2425
Route::apiResource('incidents.updates', IncidentUpdateController::class)
25-
->parameter('updates', 'incidentUpdate')
26-
->scoped();
26+
->scoped(['updateable_id']);
27+
28+
Route::apiResource('schedules.updates', ScheduleUpdateController::class)
29+
->scoped(['updateable_id']);
2730

2831
Route::apiResource('metrics.points', MetricPointController::class)
2932
->parameter('points', 'metricPoint')

src/Actions/Update/CreateUpdate.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,23 @@
44

55
use Cachet\Actions\Incident\UpdateIncident;
66
use Cachet\Models\Incident;
7+
use Cachet\Models\Schedule;
78
use Cachet\Models\Update;
89

910
class CreateUpdate
1011
{
1112
/**
1213
* Handle the action.
1314
*/
14-
public function handle(Incident $incident, array $data): Update
15+
public function handle(Incident|Schedule $resource, array $data): Update
1516
{
1617
$update = new Update(array_merge(['user_id' => auth()->id()], $data));
1718

18-
$incident->updates()->save($update);
19+
$resource->updates()->save($update);
1920

2021
// Update the incident with the new status.
21-
if ($incident->status !== $data['status']) {
22-
app(UpdateIncident::class)->handle($incident, [
22+
if ($resource instanceof Incident && $resource->status !== $data['status']) {
23+
app(UpdateIncident::class)->handle($resource, [
2324
'status' => $data['status'],
2425
]);
2526
}

src/Actions/Update/EditUpdate.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ class EditUpdate
1111
*/
1212
public function handle(Update $update, array $data): Update
1313
{
14-
$update->update($data);
15-
16-
return $update->fresh();
14+
return tap($update, function (Update $update) use ($data) {
15+
$update->update($data);
16+
});
1717
}
1818
}

src/Http/Controllers/Api/IncidentUpdateController.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Cachet\Actions\Update\EditUpdate;
88
use Cachet\Http\Requests\CreateIncidentUpdateRequest;
99
use Cachet\Http\Requests\UpdateIncidentUpdateRequest;
10-
use Cachet\Http\Resources\Update as IncidentUpdateResource;
10+
use Cachet\Http\Resources\Update as UpdateResource;
1111
use Cachet\Models\Incident;
1212
use Cachet\Models\Update;
1313
use Illuminate\Http\Response;
@@ -40,7 +40,7 @@ public function index(Incident $incident)
4040
->allowedSorts(['status', 'created_at'])
4141
->simplePaginate(request('per_page', 15));
4242

43-
return IncidentUpdateResource::collection($updates);
43+
return UpdateResource::collection($updates);
4444
}
4545

4646
/**
@@ -56,7 +56,7 @@ public function store(CreateIncidentUpdateRequest $request, Incident $incident,
5656
{
5757
$update = $createUpdateAction->handle($incident, $request->validated());
5858

59-
return IncidentUpdateResource::make($update);
59+
return UpdateResource::make($update);
6060
}
6161

6262
/**
@@ -68,7 +68,7 @@ public function store(CreateIncidentUpdateRequest $request, Incident $incident,
6868
*/
6969
public function show(Incident $incident, Update $update)
7070
{
71-
return IncidentUpdateResource::make($update)
71+
return UpdateResource::make($update)
7272
->response()
7373
->setStatusCode(Response::HTTP_OK);
7474
}
@@ -86,7 +86,7 @@ public function update(UpdateIncidentUpdateRequest $request, Incident $incident,
8686
{
8787
$editUpdateAction->handle($update, $request->validated());
8888

89-
return IncidentUpdateResource::make($update->fresh());
89+
return UpdateResource::make($update->fresh());
9090
}
9191

9292
/**

src/Http/Controllers/Api/ScheduleController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ class ScheduleController extends Controller
2828
* @queryParam per_page int How many items to show per page. Example: 20
2929
* @queryParam page int Which page to show. Example: 2
3030
* @queryParam sort string Field to sort by. Enum: name, id, scheduled_at, completed_at, enabled Example: name
31-
* @queryParam include string Include related resources. Enum: components Example: components
31+
* @queryParam include string Include related resources. Enum: components, updates Example: components
3232
* @queryParam filters string[] Filter the resources. Example: name=api
3333
*/
3434
public function index()
3535
{
3636
$schedules = QueryBuilder::for(Schedule::class)
37-
->allowedIncludes(['components'])
37+
->allowedIncludes(['components', 'updates'])
3838
->allowedFilters(['name'])
3939
->allowedSorts(['name', 'id', 'scheduled_at', 'completed_at'])
4040
->simplePaginate(request('per_page', 15));
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
namespace Cachet\Http\Controllers\Api;
4+
5+
use Cachet\Actions\Update\CreateUpdate;
6+
use Cachet\Actions\Update\DeleteUpdate;
7+
use Cachet\Actions\Update\EditUpdate;
8+
use Cachet\Http\Requests\CreateScheduleUpdateRequest;
9+
use Cachet\Http\Requests\UpdateScheduleUpdateRequest;
10+
use Cachet\Http\Resources\Update as UpdateResource;
11+
use Cachet\Models\Incident;
12+
use Cachet\Models\Schedule;
13+
use Cachet\Models\Update;
14+
use Illuminate\Database\Eloquent\Relations\Relation;
15+
use Illuminate\Http\Response;
16+
use Illuminate\Routing\Controller;
17+
use Spatie\QueryBuilder\QueryBuilder;
18+
19+
/**
20+
* @group Schedule Updates
21+
*/
22+
class ScheduleUpdateController extends Controller
23+
{
24+
/**
25+
* List Incident Updates
26+
*
27+
* @apiResourceCollection \Cachet\Http\Resources\Update
28+
*
29+
* @apiResourceModel \Cachet\Models\Update
30+
*
31+
* @queryParam per_page int How many items to show per page. Example: 20
32+
* @queryParam page int Which page to show. Example: 2
33+
* @queryParam sort string Field to sort by. Enum: name, created_at Example: name
34+
* @queryParam filters string[] Filter the resources.
35+
*/
36+
public function index(Schedule $schedule)
37+
{
38+
$updates = QueryBuilder::for(Update::class)
39+
->where('updateable_id', $schedule->id)
40+
->where('updateable_type', Relation::getMorphAlias(Schedule::class))
41+
->allowedSorts(['created_at'])
42+
->simplePaginate(request('per_page', 15));
43+
44+
return UpdateResource::collection($updates);
45+
}
46+
47+
/**
48+
* Create Schedule Update
49+
*
50+
* @apiResource \Cachet\Http\Resources\Update
51+
*
52+
* @apiResourceModel \Cachet\Models\Update
53+
*
54+
* @authenticated
55+
*/
56+
public function store(CreateScheduleUpdateRequest $request, Schedule $schedule, CreateUpdate $createUpdateAction)
57+
{
58+
$update = $createUpdateAction->handle($schedule, $request->validated());
59+
60+
return UpdateResource::make($update);
61+
}
62+
63+
/**
64+
* Get Schedule Update
65+
*
66+
* @apiResource \Cachet\Http\Resources\Update
67+
*
68+
* @apiResourceModel \Cachet\Models\Update
69+
*/
70+
public function show(Incident $incident, Schedule $schedule)
71+
{
72+
return UpdateResource::make($schedule)
73+
->response()
74+
->setStatusCode(Response::HTTP_OK);
75+
}
76+
77+
/**
78+
* Update Schedule Update
79+
*
80+
* @apiResource \Cachet\Http\Resources\Update
81+
*
82+
* @apiResourceModel \Cachet\Models\Update
83+
*
84+
* @authenticated
85+
*/
86+
public function update(UpdateScheduleUpdateRequest $request, Schedule $schedule, Update $update, EditUpdate $editUpdateAction)
87+
{
88+
$editUpdateAction->handle($update, $request->validated());
89+
90+
return UpdateResource::make($update->fresh());
91+
}
92+
93+
/**
94+
* Delete Schedule Update
95+
*
96+
* @response 204
97+
*
98+
* @authenticated
99+
*/
100+
public function destroy(Schedule $schedule, Update $update, DeleteUpdate $deleteUpdateAction)
101+
{
102+
$deleteUpdateAction->handle($update);
103+
104+
return response()->noContent();
105+
}
106+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Cachet\Http\Requests;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class CreateScheduleUpdateRequest extends FormRequest
8+
{
9+
/**
10+
* Determine if the user is authorized to make this request.
11+
*/
12+
public function authorize(): bool
13+
{
14+
return true;
15+
}
16+
17+
/**
18+
* Get the validation rules that apply to the request.
19+
*
20+
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
21+
*/
22+
public function rules(): array
23+
{
24+
return [
25+
'message' => ['required', 'string'],
26+
];
27+
}
28+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Cachet\Http\Requests;
4+
5+
use Illuminate\Foundation\Http\FormRequest;
6+
7+
class UpdateScheduleUpdateRequest extends FormRequest
8+
{
9+
/**
10+
* Determine if the user is authorized to make this request.
11+
*/
12+
public function authorize(): bool
13+
{
14+
return true;
15+
}
16+
17+
/**
18+
* Get the validation rules that apply to the request.
19+
*
20+
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array|string>
21+
*/
22+
public function rules(): array
23+
{
24+
return [
25+
'message' => ['string'],
26+
];
27+
}
28+
}

0 commit comments

Comments
 (0)