diff --git a/database/factories/CategoryFactory.php b/database/factories/CategoryFactory.php index f5b259b..b23ce16 100644 --- a/database/factories/CategoryFactory.php +++ b/database/factories/CategoryFactory.php @@ -22,6 +22,7 @@ public function definition(): array return [ 'name' => $name, 'slug' => str()->slug($name), + 'is_active' => $this->faker->boolean(80), ]; } } diff --git a/tests/Feature/Admin/Master/CategoryTest.php b/tests/Feature/Admin/Master/CategoryTest.php new file mode 100644 index 0000000..e59d1f2 --- /dev/null +++ b/tests/Feature/Admin/Master/CategoryTest.php @@ -0,0 +1,170 @@ +assertRedirect(route('login')); + }); + + it('returns 403 when user has no permission to view categories', function () { + actingAs(createUnauthorizedUser()) + ->get(route('category.index')) + ->assertStatus(403); + }); +}); + +describe('Category Module - Authorized Actions', function () { + beforeEach(function () { + $user = createAuthorizedUser([ + 'View:Category', + 'Create:Category', + 'Edit:Category', + 'Delete:Category', + 'DeleteAny:Category', + 'ToggleStatus:Category', + ]); + actingAs($user); + }); + + it('can access category index page', function () { + get(route('category.index')) + ->assertOk() + ->assertInertia(fn ($page) => $page + ->component('admin/master/category/index') + ->has('categories') + ); + }); + + it('can create a new category', function () { + $data = ['name' => 'New Category']; + + postJson(route('category.store'), $data) + ->assertRedirect() + ->assertSessionHas('success'); + + assertDatabaseHas('categories', $data); + }); + + it('validates category creation', function () { + // Required + postJson(route('category.store'), []) + ->assertStatus(422) + ->assertJsonValidationErrors(['name']); + + // Max Length (50) + postJson(route('category.store'), ['name' => str_repeat('a', 51)]) + ->assertStatus(422) + ->assertJsonValidationErrors(['name']); + }); + + it('validates category update', function () { + $category = Category::factory()->create(); + + // Required + patchJson(route('category.update', $category), []) + ->assertStatus(422) + ->assertJsonValidationErrors(['name']); + + // Max Length (50) + patchJson(route('category.update', $category), ['name' => str_repeat('a', 51)]) + ->assertStatus(422) + ->assertJsonValidationErrors(['name']); + }); + + it('can update a category', function () { + $category = Category::factory()->create(['name' => 'Old Name']); + $newData = ['name' => 'Updated Name']; + + patchJson(route('category.update', $category), $newData) + ->assertRedirect() + ->assertSessionHas('success'); + + assertDatabaseHas('categories', [ + 'id' => $category->id, + 'name' => 'Updated Name', + ]); + }); + + it('can delete a category', function () { + $category = Category::factory()->create(); + + deleteJson(route('category.destroy', $category)) + ->assertRedirect() + ->assertSessionHas('success'); + + assertSoftDeleted('categories', ['id' => $category->id]); + }); + + it('can delete categories in bulk', function () { + $categories = Category::factory()->count(3)->create(); + $ids = $categories->pluck('id')->toArray(); + + deleteJson(route('category.bulkDestroy'), ['ids' => $ids]) + ->assertRedirect() + ->assertSessionHas('success'); + + foreach ($ids as $id) { + assertSoftDeleted('categories', ['id' => $id]); + } + }); + + it('can toggle category status', function () { + $category = Category::factory()->create(['is_active' => true]); + + patchJson(route('category.toggleStatus', $category)) + ->assertRedirect() + ->assertSessionHas('success'); + + expect($category->fresh()->is_active)->toBeFalse(); + + patchJson(route('category.toggleStatus', $category)) + ->assertRedirect(); + + expect($category->fresh()->is_active)->toBeTrue(); + }); +}); + +describe('Category Module - Unauthorized Actions', function () { + beforeEach(function () { + actingAs(createUnauthorizedUser()); + }); + + it('cannot create a category without permission', function () { + postJson(route('category.store'), ['name' => 'Unauthorized']) + ->assertStatus(403); + }); + + it('cannot update a category without permission', function () { + $category = Category::factory()->create(); + patchJson(route('category.update', $category), ['name' => 'Unauthorized']) + ->assertStatus(403); + }); + + it('cannot delete a category without permission', function () { + $category = Category::factory()->create(); + deleteJson(route('category.destroy', $category)) + ->assertStatus(403); + }); + + it('cannot toggle category status without permission', function () { + $category = Category::factory()->create(); + patchJson(route('category.toggleStatus', $category)) + ->assertStatus(403); + }); +});