29. Sending a friend request


OK. So in this episode, we're going to do a little bit of UI work. We're going to hook up our navigation just
to tidy up some things. And then we're going to get to the point where we can test. And then within our UI, enter an email address of another user and see them in our pending friend request list.
So first things first, let's go over to app.blade.php and head over to the friends link and just hook this up first of all so we can access it. So I can now navigate to that.
Great. And now let's build our form. And before we submit it through, we'll write a test that the endpoint actually
takes the email address, validates it correctly, and of course, adds the friend. So let's go over to friends and index and build out this form just at the top here.
So let's go ahead and steal the header here, pop that in there, add a friend, and then we'll build a form just down here. So the action is going to be probably to friends. The method is going to be post.
And let's build this out. Now, we'll steal this from login because we've already got some form stuff in here. So let's just grab this, paste this in, and pull this in.
Now, for a lot of the stuff that we've been doing, we've not been attaching errors on the UI. We'll clear that up a little bit later. For now, though, we just want to be
able to pass a friend's email address in and click a button. So why don't we just add a class onto here to say space y3 maybe. And then we'll go over to login. And let's just actually grab the markup we have on here
because that makes a little bit more sense. And then let's grab the Login button. And we'll put that in here to send request or whatever we want it to be called.
OK, great. That looks good. So we want to enter an email address. But before we actually submit this through,
we want to write a test for this. So let's go over and say php artisan make test. And we're going to call this friend store test because that's pretty much going to be
the name of our controller. Let's have our pest flag. Let's head to friend store test. And let's think about the three things
that we want to test here. The first one is that it validates the email address to make sure it's actually there. The second one is that we can't add ourself as a friend.
That doesn't make sense. So we need to bear that in mind with our validation rules. And the last is that it actually stores the friend request, e.g. we can see it in the database.
And because we've already created the test over on our friend test here that it can actually see this, as long as we know it's in the database, we then know it's going to appear down here.
So everything sort of links together and starts coming together. So if we head over to our friend test, let's just grab the refresh database trait.
And let's pop this in here, get rid of collection. And let's write our first test that it validates the email. In actual fact, the first test should probably be that we can't do this if we're not authenticated.
And we've already got that over in our feature test just here. So let's just grab this, go over to friend store test, put this in here. And we know that this is now a post request to slash friends.
So let's run this test. So test, tests, feature, and friend store test. Of course, it fails at the moment because we don't have anything to be found.
So let's create this out. So phpArtisan, makeController, friendStoreController. Let's go over to routes and web, create this out as a post request using the friendStoreController.
And over in the friendStoreController, we know to make this test work, we need a constructor with our middleware. That's auth.
And then down here, we need an invoke. And that's going to add the friend. So let's run our test. And we get green.
So that redirects successfully with that. And we can get on with the first test that it validates the email address. So it validates the email address.
Or you could be really specific and say that it's required. Let's create this out. So all we need here is just a user. So let's say user factory create.
And let's just make sure we pull that user model in. And then acting as that user, we want to post through to slash friends. And we don't want to send any data down here.
We just want to assert that the session has errors and email. So let's go ahead and run our test. Of course, this fails because we're not doing any kind of validation whatsoever.
So let's bring our request object in. And let's just do this in the controller. We can always refactor, as we saw earlier, to a form request if we want to.
And let's say that the email here is required. Let's just leave it at that for now. OK, that passes. Now, we also want to check.
So it validates the email address is required. But we also want to test that the email address exists. So we want to make sure that we're actually adding a user that exists.
Now, this is a pretty easy test to write because we can just pass in any email here. Because at this point in our test, we've only created one user in the database.
So we can pass any email that isn't this user, and it should exist, or it should not exist. So let's say mable at and expect that we see an error.
Now, at the moment, of course, that's going to fail because it's just required. There's no exists rule here whatsoever. So let's say that we want to make sure
that it exists in the users table under the email column. We don't need that. It's taken from here implicitly. But let's add that in here anyway.
Run our test. We get green. Great. So we know that the user has to exist before we add them.
Now, let's create a different test. And let's say it can't add self as friend. Pretty important. That would be silly.
So let's go ahead and switch this up to the user who is making the request and their email address. So again, a very similar test here,
but again, just making sure we cover everything. Now, if we run this test, we expect this to fail because, again, we're not checking anything within here that makes this fail.
So let's go to our Friend Store controller. I'm going to switch this over to an array so we can use Laravel's rule object. And we're going to say not in.
And we're going to pass an array in here. Let's just pull that rule in here. We're not in. And we'll just grab the currently authenticated user's
email address. So this cannot match anything in this array, which at the moment is just the requesting user's email address.
Let's run our tests. We get green. Great. There are our validation rules completely done.
OK, so the last test we need to write is that it actually stores the friend request. Let's write this out now. Stores the friend request.
And let's go ahead and create this out. So again, we're going to have a user in here. But we also need another user in here now to be the friend that we're sending the email down as.
So let's go ahead and say friend. And again, acting as, not action, so acting as that user. We want to make a post request to slash friends.
And we want that to be the friend email address. So we know that that should work now in terms of our validation rules. And then we want to expect that this data is in the database.
And therefore, expect that we see it in the UI because we've already written a test for that. So let's say assert database has. And under friends, we want to make sure
that the user ID is the requesting user. The friend ID is the friend that we're adding. And we can say accepted false. So we can cover that part here as well.
Because of course, this test could pass if we just had these two in here if we hadn't used the correct method to add that user and if they would have been accepted
within this controller. So this just adds a little bit more protection. Let's go ahead and run our test. Of course, we get false because the table is empty.
So now over in friend store controller, we just want to go ahead and implement the solution to this. So we already know what we need to do now because we've already written tests for this.
Grab the currently authenticated user and add a friend. We need to look this friend up by their email address. So we can just say user where email and request email. And grab the first user back who matches that email address.
Let's pull the user model in. Let's return back here with this. Let's run our test. And we get agree.
Perfect. So now we can hook our UI up pretty confident that as long as we send the data down properly here, this is going to work.
So let's do that now. OK, so if we just come over to our friends index page, let's take a look at our form. So that posts through to friends with an email address.
As long as we add our cross-site request forgery protection, this should work. Let's try it out. So over in the database, we've got Mabel.
Let's try and add her. And let's hit Send Request. And there we go. We know that we've got pending friend request as Mabel.
Everything works nicely. Now, we know that this shouldn't technically add this user twice because we've already created a test for this.
We're not handling this within our control and showing any kind of error. But we're also not showing any errors on the form at all for any of the validation that we have got.
So what we can do is just very quickly tidy that up. So if we come over to our register controller or register view, we didn't add any errors here either. So probably a good idea to just start on the friends index
page with this. And for this, we just want to go ahead and say error, email, end error. And then in here, just implement some sort
of styled error message. Let's say text small and text red 500, maybe a margin on the top. And just output the message in here.
OK, give that a refresh. Hit this. Email field is required. OK, there we go.
We have hooked up this pretty much by writing our test first and then implementing the UI. Let's head over and look at accepting friend requests from the other side.
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.