تكرار السؤال: …
الإجابة المختصرة
تُحاكي المستخدم الحالي بـ actingAs وتتحقق من أكواد الاستجابة (401 لغير المسجل، 403 لغير المصرّح، 200 للمالك)، وتختبر الـ Policies مباشرة عبر Gate::forUser أو $user->can.
الشرح
اختبر ثلاث حالات على الأقل لكل مورد محمي: زائر غير مسجل (401)، مستخدم مسجل لا يملك الصلاحية (403)، والمستخدم صاحب الصلاحية (نجاح). استخدم الـ factories لإنشاء المستخدمين والأدوار، ولا تعتمد على بيانات ثابتة. لاختبار منطق الـ Policy عزله في اختبار وحدة يستدعي الدالة مباشرة، بينما تتحقق اختبارات الـ Feature من ربط الـ Policy فعليًا بالمسار عبر authorize أو middleware can. ولا تتحقق من إخفاء الأزرار في الواجهة بدل التحقق من رفض الخادم.
مثال بالكود
public function test_only_the_owner_can_update_a_post(): void
{
$owner = User::factory()->create();
$other = User::factory()->create();
$post = Post::factory()->for($owner)->create();
$this->putJson("/api/posts/{$post->id}", ['title' => 'New'])
->assertUnauthorized(); // guest → 401
$this->actingAs($other)->putJson("/api/posts/{$post->id}", ['title' => 'New'])
->assertForbidden(); // authenticated but not allowed → 403
$this->actingAs($owner)->putJson("/api/posts/{$post->id}", ['title' => 'New'])
->assertOk();
}
public function test_post_policy_update_rule(): void
{
$owner = User::factory()->create();
$post = Post::factory()->for($owner)->create();
$this->assertTrue(Gate::forUser($owner)->allows('update', $post));
$this->assertFalse(Gate::forUser(User::factory()->create())->allows('update', $post));
}أخطاء شائعة
- اختبار حالة المستخدم المصرّح فقط وإهمال حالات الزائر والمستخدم غير المخوّل، فلا تُكتشف ثغرات التفويض.
- الخلط بين 401 (غير مصادَق) و 403 (مصادَق لكن ممنوع) في التوقعات.