From 847fca7d4462394f67db76ff44fd1fd1b6d22501 Mon Sep 17 00:00:00 2001 From: Amon De Shir Date: Sun, 8 Dec 2024 16:18:40 +0100 Subject: [PATCH 01/14] add is_disabled tu schools table --- app/Models/School.php | 1 + database/factories/SchoolFactory.php | 8 ++++++++ .../migrations/2024_08_08_113859_create_schools_table.php | 1 + 3 files changed, 10 insertions(+) diff --git a/app/Models/School.php b/app/Models/School.php index 7c357a54..1be45d05 100644 --- a/app/Models/School.php +++ b/app/Models/School.php @@ -19,6 +19,7 @@ * @property string $building_number * @property string $apartment_number * @property string $zip_code + * @property boolean $is_disabled * @property Carbon $created_at * @property Carbon $updated_at * @property Collection $users diff --git a/database/factories/SchoolFactory.php b/database/factories/SchoolFactory.php index 0d121b9c..eac7014f 100644 --- a/database/factories/SchoolFactory.php +++ b/database/factories/SchoolFactory.php @@ -28,9 +28,17 @@ public function definition(): array "building_number" => fake()->buildingNumber(), "apartment_number" => fake()->buildingNumber(), "zip_code" => fake()->randomNumber(2) . "-" . fake()->randomNumber(3), + "is_disabled" => false, ]; } + public function disabled() + { + return $this->state(fn(array $attributes): array => [ + "is_disabled" => true, + ]); + } + public function withoutApartment(): static { return $this->state(fn(array $attributes): array => [ diff --git a/database/migrations/2024_08_08_113859_create_schools_table.php b/database/migrations/2024_08_08_113859_create_schools_table.php index 67d89e7f..794845a7 100644 --- a/database/migrations/2024_08_08_113859_create_schools_table.php +++ b/database/migrations/2024_08_08_113859_create_schools_table.php @@ -18,6 +18,7 @@ public function up(): void $table->string("building_number"); $table->string("apartment_number")->nullable(); $table->string("zip_code"); + $table->boolean("is_disabled")->default(false); $table->timestamps(); }); } From 4985e25fb92e0a79cb75ad5ce6347590023c71ad Mon Sep 17 00:00:00 2001 From: Amon De Shir Date: Sun, 8 Dec 2024 16:18:46 +0100 Subject: [PATCH 02/14] fix code style --- database/migrations/0001_01_01_000000_create_users_table.php | 1 + 1 file changed, 1 insertion(+) diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 5f34af2f..b85055e1 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -25,6 +25,7 @@ public function up(): void $table->string("token"); $table->timestamp("created_at")->nullable(); }); + Schema::create("sessions", function (Blueprint $table): void { $table->string("id")->primary(); $table->foreignId("user_id")->nullable()->index(); From 9a0d83555261ed37003eff193e1fabaafc1eb5aa Mon Sep 17 00:00:00 2001 From: Amon De Shir Date: Sun, 8 Dec 2024 21:08:08 +0100 Subject: [PATCH 03/14] remove unused routes --- resources/js/Pages/Admin/CreateAdmin.vue | 3 -- resources/js/Pages/Admin/EditAdmin.vue | 3 -- resources/js/Pages/Admin/EditUser.vue | 3 -- resources/js/Pages/User/Edit.vue | 53 ------------------- routes/web.php | 8 ++- tests/Feature/AdminTest.php | 65 ------------------------ tests/Feature/UserTest.php | 52 ------------------- 7 files changed, 3 insertions(+), 184 deletions(-) delete mode 100644 resources/js/Pages/Admin/CreateAdmin.vue delete mode 100644 resources/js/Pages/Admin/EditAdmin.vue delete mode 100644 resources/js/Pages/Admin/EditUser.vue delete mode 100644 resources/js/Pages/User/Edit.vue diff --git a/resources/js/Pages/Admin/CreateAdmin.vue b/resources/js/Pages/Admin/CreateAdmin.vue deleted file mode 100644 index 0ad8c3d0..00000000 --- a/resources/js/Pages/Admin/CreateAdmin.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/resources/js/Pages/Admin/EditAdmin.vue b/resources/js/Pages/Admin/EditAdmin.vue deleted file mode 100644 index ddee353f..00000000 --- a/resources/js/Pages/Admin/EditAdmin.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/resources/js/Pages/Admin/EditUser.vue b/resources/js/Pages/Admin/EditUser.vue deleted file mode 100644 index 22ca2d90..00000000 --- a/resources/js/Pages/Admin/EditUser.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/resources/js/Pages/User/Edit.vue b/resources/js/Pages/User/Edit.vue deleted file mode 100644 index 0fc65abd..00000000 --- a/resources/js/Pages/User/Edit.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/routes/web.php b/routes/web.php index e0bf2ade..1c0b8735 100644 --- a/routes/web.php +++ b/routes/web.php @@ -72,20 +72,18 @@ Route::get("/schools", [SchoolsController::class, "index"])->name("admin.schools.index"); Route::post("/schools", [SchoolsController::class, "store"])->name("admin.schools.store"); - Route::patch("/schools/{school}", [SchoolsController::class, "update"])->name("admin.schools.update"); - Route::delete("/schools/{school}", [SchoolsController::class, "destroy"])->name("admin.schools.destroy"); + Route::patch("/schools/{school}", [SchoolsController::class, "update"])->name("admin.schools.update")->can("update,school"); + Route::delete("/schools/{school}", [SchoolsController::class, "destroy"])->name("admin.schools.destroy")->can("delete,school"); + Route::post("/schools/{school}/disable", [SchoolsController::class, "disable"])->name("admin.schools.disable")->can("disable,school"); Route::post("/schools/fetch", [SchoolsController::class, "fetch"])->name("admin.schools.fetch"); Route::get("/schools/status", [SchoolsController::class, "status"])->name("admin.schools.status"); Route::get("/users", [UserController::class, "index"])->name("admin.users.index"); - Route::get("/users/{user}/edit", [UserController::class, "edit"])->name("admin.users.edit"); Route::patch("/users/{user}", [UserController::class, "update"])->name("admin.users.update"); Route::middleware(["role:super_admin"])->group(function (): void { Route::get("/admins", [AdminController::class, "index"])->name("admin.admins.index"); - Route::get("/admins/create", [AdminController::class, "create"])->name("admin.admins.create"); - Route::get("/admins/{user}/edit", [AdminController::class, "edit"])->name("admin.admins.edit"); Route::post("/admins", [AdminController::class, "store"])->name("admin.admins.store"); Route::patch("/admins/{user}", [AdminController::class, "update"])->name("admin.admins.update"); Route::delete("/admins/{user}", [AdminController::class, "destroy"])->name("admin.admins.destroy"); diff --git a/tests/Feature/AdminTest.php b/tests/Feature/AdminTest.php index 3db08b97..d4c30e0f 100644 --- a/tests/Feature/AdminTest.php +++ b/tests/Feature/AdminTest.php @@ -49,29 +49,6 @@ public function testAdminCannotViewAdmins(): void ->assertStatus(403); } - public function testSuperAdminCanViewAddAdminPanel(): void - { - User::factory()->count(10)->create(); - $this->assertDatabaseCount("users", 12); - - $this->actingAs($this->superAdmin) - ->get("/admin/admins/create") - ->assertInertia( - fn(Assert $page) => $page - ->component("Admin/CreateAdmin"), - ); - } - - public function testAdminCannotViewAddAdminPanel(): void - { - User::factory()->count(10)->create(); - $this->assertDatabaseCount("users", 12); - - $this->actingAs($this->admin) - ->get("/admin/admins/create") - ->assertStatus(403); - } - public function testSuperAdminCanAddAdmin(): void { $school = School::factory()->create(); @@ -112,30 +89,6 @@ public function testAdminCannotAddAdmin(): void ]); } - public function testSuperAdminCanViewEditAdmin(): void - { - $admin = User::factory()->admin()->create(); - - $this->actingAs($this->superAdmin) - ->from("/admin/admins") - ->get("/admin/admins/{$admin->id}/edit") - ->assertInertia( - fn(Assert $page) => $page - ->component("Admin/EditAdmin") - ->where("user.id", $admin->id), - ); - } - - public function testAdminCannotViewEditAdmin(): void - { - $admin = User::factory()->admin()->create(); - - $this->actingAs($this->admin) - ->from("/admin/admins") - ->get("/admin/admins/{$admin->id}/edit") - ->assertStatus(403); - } - public function testSuperAdminCanEditAdmin(): void { $school = School::factory()->create(); @@ -247,16 +200,6 @@ public function testUserCannotAccessAdminCrud(): void ->get("/admin/admins") ->assertStatus(403); - $this->actingAs($user) - ->from("/dashboard") - ->get("/admin/admins/create") - ->assertStatus(403); - - $this->actingAs($user) - ->from("/dashboard") - ->get("/admin/admins/{$this->admin->id}/edit") - ->assertStatus(403); - $this->actingAs($user) ->from("/dashboard") ->post("/admin/admins", ["name" => "new Name"]) @@ -281,14 +224,6 @@ public function guestCannotAccessAdminCrud(): void ->get("/admin/admins") ->assertStatus(403); - $this->from("/dashboard") - ->get("/admin/admins/create") - ->assertStatus(403); - - $this->from("/dashboard") - ->get("/admin/admins/{$this->admin->id}/edit") - ->assertStatus(403); - $this->from("/dashboard") ->post("/admin/admins", ["name" => "new Name"]) ->assertForbidden(); diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php index 28b94216..7bcc985b 100644 --- a/tests/Feature/UserTest.php +++ b/tests/Feature/UserTest.php @@ -53,48 +53,6 @@ public function testSuperAdminCanViewUsers(): void ); } - public function testAdminCanViewEditUser(): void - { - $user = User::factory()->create(); - - $this->actingAs($this->admin) - ->from("/admin/users") - ->get("/admin/users/{$user->id}/edit") - ->assertInertia( - fn(Assert $page) => $page - ->component("Admin/EditUser") - ->where("user.id", $user->id), - ); - } - - public function testSuperAdminCanViewEditUser(): void - { - $user = User::factory()->create(); - - $this->actingAs($this->superAdmin) - ->from("/admin/users") - ->get("/admin/users/{$user->id}/edit") - ->assertInertia( - fn(Assert $page) => $page - ->component("Admin/EditUser") - ->where("user.id", $user->id), - ); - } - - public function testAdminCannotViewEditUserThatDoesNotExist(): void - { - $this->actingAs($this->admin) - ->get("/admin/users/999/edit") - ->assertStatus(404); - } - - public function testSuperAdminCannotViewEditUserThatDoesNotExist(): void - { - $this->actingAs($this->superAdmin) - ->get("/admin/users/999/edit") - ->assertStatus(404); - } - public function testAdminCanEditUser(): void { $school = School::factory()->create(); @@ -355,11 +313,6 @@ public function testUserCannotAccessCrud(): void ->get("/admin/users/") ->assertStatus(403); - $this->actingAs($user) - ->from("/dashboard") - ->get("/admin/users/{$user->id}/edit") - ->assertStatus(403); - $this->actingAs($user) ->from("/dashboard") ->patch("/admin/users/{$user->id}", ["name" => "New Name"]) @@ -385,11 +338,6 @@ public function guestCannotAccessCrud(): void ->assertStatus(403) ->assertRedirect("/"); - $this->from("/") - ->get("/admin/users/{$user->id}/edit") - ->assertStatus(403) - ->assertRedirect("/"); - $this->from("/") ->patch("/admin/users/{$user->id}", ["name" => "New Name"]) ->assertStatus(403) From bb349bf741281c1a02fac10ae28b309cbab05c80 Mon Sep 17 00:00:00 2001 From: Amon De Shir Date: Sun, 8 Dec 2024 21:08:51 +0100 Subject: [PATCH 04/14] add disable school route --- app/Http/Controllers/SchoolsController.php | 28 ++++++++- app/Policies/SchoolPolicy.php | 26 +++++++++ tests/Feature/SchoolTest.php | 68 +++++++++++++++++++++- 3 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 app/Policies/SchoolPolicy.php diff --git a/app/Http/Controllers/SchoolsController.php b/app/Http/Controllers/SchoolsController.php index 999bd1cb..a7d11ebc 100644 --- a/app/Http/Controllers/SchoolsController.php +++ b/app/Http/Controllers/SchoolsController.php @@ -14,6 +14,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Bus; use Illuminate\Support\Facades\Cache; use Inertia\Inertia; @@ -26,11 +27,12 @@ class SchoolsController extends Controller { - public function index(SortHelper $sorter): Response + public function index(SortHelper $sorter, Request $request): Response { $query = $sorter->sort(School::query(), ["id", "name", "regon", "updated_at", "created_at"], ["students", "address"]); $query = $this->sortByStudents($query, $sorter); $query = $this->sortByAddress($query, $sorter); + $query = $this->filterDisabledSchools($query, $request); $query = $sorter->search($query, "name"); $schools = $sorter->paginate($query); @@ -59,7 +61,18 @@ public function destroy(School $school): RedirectResponse $school->delete(); return redirect() - ->back(); + ->back() + ->with("status", "Szkoła została usunięta."); + } + + public function disable(School $school): RedirectResponse + { + $school->is_disabled = true; + $school->save(); + + return redirect() + ->back() + ->with("status", "Szkoła została zablokowa."); } /** @@ -131,4 +144,15 @@ private function sortByAddress(Builder $query, SortHelper $sorter): Builder return $query; } + + private function filterDisabledSchools(Builder $query, Request $request): Builder + { + $showDisabled = $request->query("disabled", "false") === "true"; + + if (!$showDisabled) { + return $query->where("is_disabled", false); + } + + return $query; + } } diff --git a/app/Policies/SchoolPolicy.php b/app/Policies/SchoolPolicy.php new file mode 100644 index 00000000..18d38dbf --- /dev/null +++ b/app/Policies/SchoolPolicy.php @@ -0,0 +1,26 @@ +is_disabled; + } + + public function delete(User $user, School $school): bool + { + return $school->users()->count() === 0; + } + + public function disable(User $user, School $school): bool + { + return !$school->is_disabled; + } +} diff --git a/tests/Feature/SchoolTest.php b/tests/Feature/SchoolTest.php index 7aba0345..4c54e065 100644 --- a/tests/Feature/SchoolTest.php +++ b/tests/Feature/SchoolTest.php @@ -38,6 +38,41 @@ public function testAdminCanViewSchools(): void ); } + public function testFilteringAndSortingSchools(): void + { + School::factory()->count(8)->create(); + School::factory()->disabled()->create(["name" => "AAAAAA"]); + School::factory()->disabled()->create(["name" => "ZZZZZZ"]); + + $this->actingAs($this->admin) + ->get("/admin/schools?sort=name&order=asc&disabled=true") + ->assertInertia(fn(Assert $page) => $page + ->component("Admin/SchoolsPanel") + ->has("schools.data", 11) + ->where("schools.data.0.name", "AAAAAA") + ->where("schools.data.10.name", "ZZZZZZ")); + + $this->actingAs($this->admin) + ->get("/admin/schools?sort=name&order=desc&disabled=true") + ->assertInertia(fn(Assert $page) => $page + ->component("Admin/SchoolsPanel") + ->has("schools.data", 11) + ->where("schools.data.0.name", "ZZZZZZ") + ->where("schools.data.10.name", "AAAAAA")); + + $this->actingAs($this->admin) + ->get("/admin/schools?sort=name&order=asc&disabled=false") + ->assertInertia(fn(Assert $page) => $page + ->component("Admin/SchoolsPanel") + ->has("schools.data", 9)); + + $this->actingAs($this->admin) + ->get("/admin/schools?search=AAAAAA&order=asc&disabled=true") + ->assertInertia(fn(Assert $page) => $page + ->component("Admin/SchoolsPanel") + ->has("schools.data", 1)); + } + public function testAdminCanCreateSchool(): void { $data = [ @@ -102,7 +137,7 @@ public function testAdminCannotEditSchoolThatNotExisted(): void ->assertStatus(404); } - public function testAdminCanDeleteSchool(): void + public function testAdminCanDeleteEmptySchool(): void { $school = School::factory()->create(); @@ -116,6 +151,37 @@ public function testAdminCanDeleteSchool(): void ]); } + public function testAdminCannotDeleteSchoolWithStudents(): void + { + $school = School::factory()->create(); + $user = User::factory()->create(); + $user->school()->associate($school)->save(); + + $this->actingAs($this->admin) + ->from("/") + ->delete("/admin/schools/{$school->id}") + ->assertStatus(403); + + $this->assertDatabaseHas("schools", [ + "id" => $school->id, + ]); + } + + public function testAdminCanDisableSchool(): void + { + $school = School::factory()->create(); + + $this->actingAs($this->admin) + ->from("/") + ->post("/admin/schools/{$school->id}/disable") + ->assertRedirect("/"); + + $this->assertDatabaseHas("schools", [ + "id" => $school->id, + "is_disabled" => true, + ]); + } + public function testAdminCannotDeleteSchoolThatNotExisted(): void { $this->actingAs($this->admin) From 7011d45271a77084e9ba54854f174df4295f64a5 Mon Sep 17 00:00:00 2001 From: Amon De Shir Date: Sun, 8 Dec 2024 21:09:51 +0100 Subject: [PATCH 05/14] update school resource --- app/Http/Resources/SchoolResource.php | 1 + resources/js/Types/School.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/app/Http/Resources/SchoolResource.php b/app/Http/Resources/SchoolResource.php index eee4b506..d255f0e1 100644 --- a/app/Http/Resources/SchoolResource.php +++ b/app/Http/Resources/SchoolResource.php @@ -20,6 +20,7 @@ public function toArray(Request $request): array "regon" => $this->regon, "city" => $this->city, "street" => $this->street, + "isDisabled" => $this->is_disabled, "buildingNumber" => $this->building_number, "apartmentNumber" => $this->apartment_number, "zipCode" => $this->zip_code, diff --git a/resources/js/Types/School.d.ts b/resources/js/Types/School.d.ts index c02d4f47..5f6d8c34 100644 --- a/resources/js/Types/School.d.ts +++ b/resources/js/Types/School.d.ts @@ -7,6 +7,7 @@ interface School { street: string buildingNumber: string apartmentNumber?: string + isDisabled: boolean zipCode: string createdAt: string updatedAt: string From 6ff70b2c8f90dbe29ba808db261283a332d94000 Mon Sep 17 00:00:00 2001 From: Amon De Shir Date: Sun, 8 Dec 2024 21:12:39 +0100 Subject: [PATCH 06/14] fix code style --- resources/js/components/Home/RegisterForm.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/js/components/Home/RegisterForm.vue b/resources/js/components/Home/RegisterForm.vue index 076998db..24a28329 100644 --- a/resources/js/components/Home/RegisterForm.vue +++ b/resources/js/components/Home/RegisterForm.vue @@ -44,7 +44,6 @@ function submit() { /> - `