用測試執行時間可以很容易區分出哪些是 unit test 哪些是 integration test,速度快是 unit test。除此之外,也可以依照測試執行時是否 depend on external resource 來區分,例如 db、cache、third party library or API。
區分出 unit test 跟 integration test 後,把它們分開放。讓 unit test 形成一個綠色安全區域──如果這裡的 test failed,就是 code 有問題而非環境或者設定等等造成的 false alarm。
Gates are most applicable to actions which are not related to any model or resource, such as viewing an administrator dashboard. In contrast, policies should be used when you wish to authorize an action for a particular model or resource.
通常 gates 跟 policies 會混合使用。
Gates
Gates are simply closures that determine if a user is authorized to perform a given action.
classPostControllerextendsController { /** * Update the given post. */ publicfunctionupdate(Request $request, Post $post) { if (! Gate::allows('update-post', $post)) { abort(403); }
classPostPolicy { /** * Determine if the given post can be updated by the user. * * @param \App\Models\User $user * @param \App\Models\Post $post * @return bool */ publicfunctionupdate(User $user, Post $post) { return$user->id === $post->user_id; } }
如果用 --model 生,會生出 CRUD 有關的 function。
使用 Policy
透過 User Model
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class PostController extends Controller { /** * Update the given post. * * @param \Illuminate\Http\Request $request * @param \App\Models\Post $post * @return \Illuminate\Http\Response */ public function update(Request $request, Post $post) { if ($request->user()->cannot('update', $post)) { abort(403); }
// Update the post... } }
沒有 model instance 的 policy:
1 2 3 4 5 6 7 8
public function store(Request $request) { if ($request->user()->cannot('create', Post::class)) { abort(403); }
// Create the post... }
透過 Controller Helpers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class PostController extends Controller { /** * Update the given blog post. * * @param \Illuminate\Http\Request $request * @param \App\Models\Post $post * @return \Illuminate\Http\Response * * @throws \Illuminate\Auth\Access\AuthorizationException */ public function update(Request $request, Post $post) { $this->authorize('update', $post);
// The current user can update the blog post... } }
如果是 resource controller,可以這樣:
1 2 3 4 5 6 7 8 9 10 11 12
class PostController extends Controller { /** * Create the controller instance. * * @return void */ public function __construct() { $this->authorizeResource(Post::class, 'post'); } }
要注意 CRUD 的 function 的 signature 要符合 laravel 需要的 type hint 才能用