-
-
Notifications
You must be signed in to change notification settings - Fork 148
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added tasks endpoints; Added more test
- Loading branch information
Showing
33 changed files
with
810 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Http\Controllers\Api\V1; | ||
|
||
use App\Http\Requests\V1\Task\TaskIndexRequest; | ||
use App\Http\Requests\V1\Task\TaskStoreRequest; | ||
use App\Http\Requests\V1\Task\TaskUpdateRequest; | ||
use App\Http\Resources\V1\Task\TaskCollection; | ||
use App\Http\Resources\V1\Task\TaskResource; | ||
use App\Models\Organization; | ||
use App\Models\Task; | ||
use Illuminate\Auth\Access\AuthorizationException; | ||
use Illuminate\Http\JsonResponse; | ||
use Illuminate\Http\Resources\Json\JsonResource; | ||
|
||
class TaskController extends Controller | ||
{ | ||
protected function checkPermission(Organization $organization, string $permission, ?Task $task = null): void | ||
{ | ||
parent::checkPermission($organization, $permission); | ||
if ($task !== null && $task->organization_id !== $organization->id) { | ||
throw new AuthorizationException('Task does not belong to organization'); | ||
} | ||
} | ||
|
||
/** | ||
* Get tasks | ||
* | ||
* @return TaskCollection<TaskResource> | ||
* | ||
* @throws AuthorizationException | ||
* | ||
* @operationId getTasks | ||
*/ | ||
public function index(Organization $organization, TaskIndexRequest $request): TaskCollection | ||
{ | ||
$this->checkPermission($organization, 'tasks:view'); | ||
|
||
$projectId = $request->input('project_id'); | ||
|
||
$query = Task::query() | ||
->whereBelongsTo($organization, 'organization'); | ||
|
||
if ($projectId !== null) { | ||
$query->where('project_id', '=', $projectId); | ||
} | ||
|
||
$tasks = $query->paginate(); | ||
|
||
return new TaskCollection($tasks); | ||
} | ||
|
||
/** | ||
* Create task | ||
* | ||
* @throws AuthorizationException | ||
* | ||
* @operationId createTask | ||
*/ | ||
public function store(Organization $organization, TaskStoreRequest $request): JsonResource | ||
{ | ||
$this->checkPermission($organization, 'tasks:create'); | ||
$task = new Task(); | ||
$task->name = $request->input('name'); | ||
$task->project_id = $request->input('project_id'); | ||
$task->organization()->associate($organization); | ||
$task->save(); | ||
|
||
return new TaskResource($task); | ||
} | ||
|
||
/** | ||
* Update task | ||
* | ||
* @throws AuthorizationException | ||
* | ||
* @operationId updateTask | ||
*/ | ||
public function update(Organization $organization, Task $task, TaskUpdateRequest $request): JsonResource | ||
{ | ||
$this->checkPermission($organization, 'tasks:update', $task); | ||
$task->name = $request->input('name'); | ||
$task->save(); | ||
|
||
return new TaskResource($task); | ||
} | ||
|
||
/** | ||
* Delete task | ||
* | ||
* @throws AuthorizationException | ||
* | ||
* @operationId deleteTask | ||
*/ | ||
public function destroy(Organization $organization, Task $task): JsonResponse | ||
{ | ||
$this->checkPermission($organization, 'tasks:delete', $task); | ||
|
||
$task->delete(); | ||
|
||
return response() | ||
->json(null, 204); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Http\Requests\V1\Task; | ||
|
||
use App\Models\Organization; | ||
use App\Models\Project; | ||
use Illuminate\Contracts\Validation\ValidationRule; | ||
use Illuminate\Database\Eloquent\Builder; | ||
use Illuminate\Foundation\Http\FormRequest; | ||
use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent; | ||
|
||
/** | ||
* @property Organization $organization Organization from model binding | ||
*/ | ||
class TaskIndexRequest extends FormRequest | ||
{ | ||
/** | ||
* Get the validation rules that apply to the request. | ||
* | ||
* @return array<string, array<string|ValidationRule>> | ||
*/ | ||
public function rules(): array | ||
{ | ||
return [ | ||
'project_id' => [ | ||
'uuid', | ||
new ExistsEloquent(Project::class, null, function (Builder $builder): Builder { | ||
/** @var Builder<Project> $builder */ | ||
return $builder->whereBelongsTo($this->organization, 'organization'); | ||
}), | ||
], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Http\Requests\V1\Task; | ||
|
||
use App\Models\Organization; | ||
use App\Models\Project; | ||
use Illuminate\Contracts\Validation\ValidationRule; | ||
use Illuminate\Database\Eloquent\Builder; | ||
use Illuminate\Foundation\Http\FormRequest; | ||
use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent; | ||
|
||
/** | ||
* @property Organization $organization Organization from model binding | ||
*/ | ||
class TaskStoreRequest extends FormRequest | ||
{ | ||
/** | ||
* Get the validation rules that apply to the request. | ||
* | ||
* @return array<string, array<string|ValidationRule>> | ||
*/ | ||
public function rules(): array | ||
{ | ||
return [ | ||
'name' => [ | ||
// TODO: unique | ||
'required', | ||
'string', | ||
'min:1', | ||
'max:255', | ||
], | ||
'project_id' => [ | ||
'required', | ||
new ExistsEloquent(Project::class, null, function (Builder $builder): Builder { | ||
/** @var Builder<Project> $builder */ | ||
return $builder->whereBelongsTo($this->organization, 'organization'); | ||
}), | ||
], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Http\Requests\V1\Task; | ||
|
||
use App\Models\Organization; | ||
use App\Models\Project; | ||
use Illuminate\Contracts\Validation\ValidationRule; | ||
use Illuminate\Database\Eloquent\Builder; | ||
use Illuminate\Foundation\Http\FormRequest; | ||
use Korridor\LaravelModelValidationRules\Rules\ExistsEloquent; | ||
|
||
/** | ||
* @property Organization $organization Organization from model binding | ||
*/ | ||
class TaskUpdateRequest extends FormRequest | ||
{ | ||
/** | ||
* Get the validation rules that apply to the request. | ||
* | ||
* @return array<string, array<string|ValidationRule>> | ||
*/ | ||
public function rules(): array | ||
{ | ||
return [ | ||
'name' => [ | ||
// TODO: unique | ||
'required', | ||
'string', | ||
'min:1', | ||
'max:255', | ||
], | ||
'project_id' => [ | ||
new ExistsEloquent(Project::class, null, function (Builder $builder): Builder { | ||
/** @var Builder<Project> $builder */ | ||
return $builder->whereBelongsTo($this->organization, 'organization'); | ||
}), | ||
], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Http\Resources\V1\Task; | ||
|
||
use App\Http\Resources\PaginatedResourceCollection; | ||
use Illuminate\Http\Resources\Json\ResourceCollection; | ||
|
||
class TaskCollection extends ResourceCollection implements PaginatedResourceCollection | ||
{ | ||
/** | ||
* The resource that this resource collects. | ||
* | ||
* @var string | ||
*/ | ||
public $collects = TaskResource::class; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Http\Resources\V1\Task; | ||
|
||
use App\Http\Resources\V1\BaseResource; | ||
use App\Models\Tag; | ||
use App\Models\Task; | ||
use Illuminate\Http\Request; | ||
|
||
/** | ||
* @property Task $resource | ||
*/ | ||
class TaskResource extends BaseResource | ||
{ | ||
/** | ||
* Transform the resource into an array. | ||
* | ||
* @return array<string, string|bool|int|null> | ||
*/ | ||
public function toArray(Request $request): array | ||
{ | ||
return [ | ||
/** @var string $id ID */ | ||
'id' => $this->resource->id, | ||
/** @var string $name Name */ | ||
'name' => $this->resource->name, | ||
/** @var string $project_id ID of the project */ | ||
'project_id' => $this->resource->project_id, | ||
/** @var string $created_at When the tag was created */ | ||
'created_at' => $this->formatDateTime($this->resource->created_at), | ||
/** @var string $updated_at When the tag was last updated */ | ||
'updated_at' => $this->formatDateTime($this->resource->updated_at), | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.