2015-10-13 64 views
3

我正在爲Laravel應用程序編寫測試。在我的AuthServiceProvider->boot()中,我根據數據庫中的權限表定義了許多用戶能力$gate->define()在測試Laravel應用程序時,一個加載門是如何定義的?

基本上這樣的:

foreach ($this->getPermissions() as $permission) { 
      $gate->define($permission->name, function ($user) use ($permission) { 
       return $user->hasPermission($permission->name); 
      }); 
     } 

在我的測試,我動態創建的權限,但AuthServiceProvider已經啓動了,這意味着我無法驗證與@canGate等用戶權限

有沒有適當的方法來處理這個問題?

回答

0

你可以做這樣的事情裏面AuthServiceProvider

首先導入必要的軟件包

use Illuminate\Auth\Access\Gate; 
use Illuminate\Contracts\Auth\Access\Gate as GateContract; 
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; 

,然後添加此boot()方法

public function boot(GateContract $gate) 
{ 
    parent::registerPolicies($gate); 

    $gate->define('update-post', function ($user, $post, $isModerator) { 
     // check if user id equals post user id or whatever 
     if ($user->id === $post->user->id) { 
      return true; 
     } 

     // you can define multiple ifs 
     if ($user->id === $category->user_id) { 
      return true; 
     } 

     if ($isModerator) { 
      return true; 
     } 

     return false; 
    }); 

    // you can also define multiple gates 
    $gate->define('update-sub', function($user, $subreddit) { 
     if($user->id === $subreddit->user->id) { 
      return true; 
     } 

     return false; 
    }); 

然後在你的控制器,你可以做些什麼像這樣

if (Gate::denies('update-post', [$post, $isModerator])) { 
    // do something 
} 
2
public function boot(GateContract $gate) 
{ 
    parent::registerPolicies($gate); 

    $gate->before(function($user, $ability) use ($gate){ 
     return $user->hasPermission($ability); 
    }); 
} 

我還沒有廣泛地測試過這個,但它似乎從我的快速測試工作。

+0

如果您想要在插入權限後在testMethod中註冊策略,該怎麼辦? –

1

我知道我對這場比賽有點晚了,但仍然 - 我自己也有同樣的問題,因此這個問題沒有一個全面的答案,這裏是我對同一問題的解決方案(在Laravel 5.3):

我在我的app\Providers\AuthServiceProvider得到這個:

/** 
* Register any authentication/authorization services. 
* 
* @param Gate $gate 
*/ 
public function boot(Gate $gate) 
{ 
    $this->registerPolicies(); 

    if (!app()->runningInConsole()) { 
     $this->definePermissions($gate); 
    } 
} 

/** 
* @param Gate $gate 
*/ 
private function definePermissions(Gate $gate) 
{ 
    $permissions = Permission::with('roles')->get(); 

    foreach($permissions as $permission) { 
     $gate->define($permission->key, function($user) use ($permission) { 
      return $user->hasRole($permission->roles); 
     }); 
    } 
} 

這需要正常的應用程序流的照顧時檢測和禁用過早政策登記測試。

在我tests/TestCase.php文件我已經定義了以下方法(注意:GateIlluminate\Contracts\Auth\Access\Gate):

/** 
* Logs a user in with specified permission(s). 
* 
* @param $permissions 
* @return mixed|null 
*/ 
public function loginWithPermission($permissions) 
{ 
    $user = $this->userWithPermissions($permissions); 

    $this->definePermissions(); 

    $this->actingAs($user); 

    return $user; 
} 

/** 
* Create user with permissions. 
* 
* @param $permissions 
* @param null $user 
* @return mixed|null 
*/ 
private function userWithPermissions($permissions, $user = null) 
{ 
    if(is_string($permissions)) { 
     $permission = factory(Permission::class)->create(['key'=>$permissions, 'label'=>ucwords(str_replace('_', ' ', $permissions))]); 

     if (!$user) { 
      $role = factory(Role::class)->create(['key'=>'role', 'label'=>'Site Role']); 

      $user = factory(User::class)->create(); 
      $user->assignRole($role); 
     } else { 
      $role = $user->roles->first(); 
     } 

     $role->givePermissionTo($permission); 
    } else { 
     foreach($permissions as $permission) { 
      $user = $this->userWithPermissions($permission, $user); 
     } 
    } 

    return $user; 
} 

/** 
* Registers defined permissions. 
*/ 
private function definePermissions() 
{ 
    $gate = $this->app->make(Gate::class); 
    $permissions = Permission::with('roles')->get(); 

    foreach($permissions as $permission) { 
     $gate->define($permission->key, function($user) use ($permission) { 
      return $user->hasRole($permission->roles); 
     }); 
    } 
} 

這使我在以多種方式測試使用此。考慮我的tests/integration/PermissionsTest.php文件中的用例:

/** @test */ 
public function resource_is_only_visible_for_those_with_view_permission() 
{ 
    $this->loginWithPermission('view_users'); 
    $this->visit(route('dashboard'))->seeLink('Users', route('users.index')); 
    $this->visit(route('users.index'))->assertResponseOk(); 

    $this->actingAs(factory(User::class)->create()); 
    $this->visit(route('dashboard'))->dontSeeLink('Users', route('users.index')); 
    $this->get(route('users.index'))->assertResponseStatus(403); 
} 

/** @test */ 
public function resource_action_is_only_visible_for_those_with_relevant_permissions() 
{ 
    $this->loginWithPermission(['view_users', 'edit_users']); 
    $this->visit(route('users.index'))->seeLink('Edit', route('users.edit', User::first()->id)); 

    $this->loginWithPermission('view_users'); 
    $this->visit(route('users.index'))->dontSeeLink('Edit', route('users.edit', User::first()->id)); 
} 

這在我所有的測試中都能正常工作。我希望它有幫助。

相關問題