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', fn ($page) => $page ->has('data') ->etc() ) ); }); 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); }); });