20. Refactoring authorisation


In the next couple of episodes we're going to do some refactoring but one of the side effects of test-driven development, which is what we've been practicing in this series, is that we've written the test, we know everything works, but we've not actually bothered to hook the UI up.
So we've proved that it works but we don't have the functionality in here to actually do it. So clicking edit a book doesn't work at the moment because we haven't hooked it up, but when we do it'll work. So let's go ahead and make some changes here and we're going to come over to the book's edit page here and just hook this form up to make this
work. So we know that we want to go through to, now that we've written our test, book slash and then the book id. So let's output the book id in here and we've got a post method here but what we're after is a put method. We can use Laravel's helper here method and just say put and that will go ahead and simulate a put request through to this endpoint. Okay let's go over and check it
out, edit book and there we go it's been edited. We can't see anything because we didn't change anything but let's say book one updated. Let's say author one updated and there we go. We can see it works and we can change the status of this. Let's change it to reading and there it is under reading now. Okay so at the moment our tests are all passing but what we're going to do is
refactor the authorization and by that I mean over in the book edit test we checked that it fails if the user doesn't own the book and it should throw a 403. Now if we come over to book edit controller this is what we're doing at the moment but let's change this over to use a policy instead. Remember we're still going to need to access this in the context of a user so we can
get that pivot information but we can clear up this if statement without having to abort manually with a 403. So let's go ahead and create a policy so php artisan make policy and we're going to call this book policy. Let's open that policy up and let's come down here get rid of the constructor because we're not going to need that and let's define out an action here that we can take on a
book and this is going to be update. This will apply to both the view here and the actual process of updating the book as well. So into this we're going to get potentially a user and a book and basically we want to check can this user update this book. Let's pull the namespace in for book first of all and this check is basically just going to be that the user's book relationship contains
this book. So this returns a collection of the books that the user owns and contains we'll just check that this is within it. Now we need to register this policy over in auth service provider so let's come down here we've got an example policy in here we want to hook this book model up to this book policy and then we can just start using this over in our controller. Let's just make
sure that both of these are pulled in and we should be good to refactor. So let's come over to our controller here and we're going to say this authorize we're going to pass in the action which is update that's the method that we defined and we're going to say book. Now the user is implicit here so the user will be passed in to our book policy and of course this check will return
true or false. Now what we can do is get rid of this check here and we can just relook the book up so let's just grab this entire line here put that there and then that just hands this check off to a policy which makes more sense. So let's rerun our tests and there we go it still passes that was a successful refactor. Now we can do the same thing now over in our book put controller
and we can do this right at the top here and we can get rid of this. Now we don't need this book in the context of a user it's not required for this and it's not required for this because we update this pivot in the context of a user anyway so we can actually get rid of this entire chunk of code now to simplify things down. So let's go ahead and run our tests again and sure enough that
passes. Now because we've got a policy here before we validate it really depends on what you want to do. What you could do is always authorize before you validate that kind of makes sense because there's no point throwing back validation errors if the user doesn't own the book. So we can actually simplify our test down now if we come over to our book put test when we look at this test
here we don't actually need to pass this data down now because at the point that we hit this the authorization will kick in before the validation so we can actually get rid of all of that now and if we run our test it's still going to pass. So there we go moving over our authorization and we know that we've got our test to back up whether it works they're still passing.
35 episodes4 hrs 19 mins


Pest is a PHP testing framework that brings beautifully simple syntax to your tests, without sacrificing on features. In this course, we'll get up and running with Pest in a Laravel project and write tests for a real-world application that we'll build along the way.

You'll learn how to set Pest up in a Laravel project, write tests with Pest's built-in assertions, generate code coverage, and more.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.