تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Define Feature and Test0:00

Today, I'm working on the LaraCast codebase itself. I need to find all Users who have cancelled or been deactivated, and once it has been two months after that date, we're going to send them sort of a marketing, please come back email. You know, same dirt stuff. Okay, so let's get started. I'm going to begin with a test. php artisan make:test, and we'll call this PleaseComeBackTest. Okay, so if we switch over to that, let's clear this out, and I'm going to use my own stub instead.

Create Cancelled Users1:05

users to come back, I expect the first User to receive an email. Yeah, I'm going to delete all of this, but I like to do this up front just to kind of gather my thoughts. So something like this, given we have a User who cancelled two months ago, okay, well, let's build up a factory for the User. However, by default, this assumes a subscribed User. So I'm going to use model factory states, and I have one called cancelled. So this will put the User in a cancelled state. But that being said, it needs to be a specific cancellation date. So let's say right here, subscription_ends_at is the column, and I'm going to override

But that being said, it needs to be a specific cancellation date. So let's say right here, subscription ends at is the column, and I'm going to override that to be exactly two months ago. So I'll say Carbon::today(), subMonths(2). Okay, so now we have a User who cancelled their account exactly two months ago from the running of this test. Next we need another cancelled User. So let's do this, but we don't have to override that. Okay, so we have user number one and user number two. Let's continue.

Okay, so we have User number one and User number two. Let's continue. When we dispatch a job to email cancelled users to come back. Yeah, so if I do something like this, I know it's going to be a job class. So I'll say, what should we call this? How about ContactCancelledUsers? And that's fine. That's fine for now. So let's new that up. Now remember, this class doesn't even exist yet.

Assert Emails with Mail Fake2:25

So let's new that up. Now remember, this class doesn't even exist yet. We're just writing the code that ideally we would use. So when we dispatch a job that should email all cancelled users from two months ago, I expect the first user to receive an email. Okay, so let's use the mail fakes for this. So I'll say Mail::fake(). And basically what that does is it swaps the underlying class for the mail facade out with a fake version that never actually sends the email. It just stores it in memory.

a fake version that never actually sends the email. It just stores it in memory. And then we can perform assertions against that. So because we now have a fake, I can say things like, I expect this Mailable to be sent. And we'll do something like, PleaseComeBack will be the name of the Mailable. But specifically, I want it to be sent to this person and not to this person. So why don't we say cancelled two months ago, I'm just going to be very specific here. And cancelled today. Okay, so now I can pass a closure here that will accept the Mailable. And I could say, okay, I expect a mail to be sent to the person that has the email address.

Okay, so now I can pass a closure here that will accept the Mailable. And I could say, okay, I expect a mail to be sent to the person that has the email address of this guy here. Like so. And let's use that. And then we'll do another one here. So maybe I'll say, I expect a mail to be sent to this person, but not to this person. So I could say assertNotSent, and then we'll say cancelledToday. All right, I think I think that should get us started. So let's run it.

Generate Job and Mailable3:49

All right, I think I think that should get us started. So let's run it. And we'll take it step by step. All right, contactCancelledUsers. Yeah, that job doesn't even exist. So let's do that now. php artisan make:job ContactCancelledUsers. I'm going to import that now and run the test again. All right.

I'm going to import that now and run the test again. All right. So I expected this mailable to be sent, but it wasn't. It doesn't even exist at this point. So that'll be our next step. I'll say php artisan make:mail me a mailable. And then I'm going to use a markdown template here. And that will be the view emails.please_come_back. Okay, so now if we go to that please_come_back view, this will be the email that we sent and there'll be something like $user $user->name, please come back something cheesy like.

Okay, so now if we go to that pleaseComeBackView, this will be the email that we sent and there'll be something like $userName, please come back something cheesy like this. I'll try to make it funny. But I'll do that on my own. So this will be the body of the email. Maybe it lists new content that has been released since they cancelled stuff like that. But yeah, I'll need to take some time on my own to populate that. Okay, so now we have this Mailable here, right?

But yeah, I'll need to take some time on my own to populate that. Okay, so now we have this Mailable here, right? Please come back. And you can see that when we build the template, it is deferring to that view. But it does need the User. So it's going to need something like this. And we'll make this public so that we can access it from the template. Okay, so now within here, we do have access to that user variable. All right, great. So let's come back to our test.

All right, great. So let's come back to our test. And I'm going to run it again. It's still saying the mailable wasn't sent for a couple reasons. One, we haven't imported this class. So I will do that now at the very top. But yeah, if we run it again, it's still not going to be sent. But at least we're looking for the correct mailable. Okay, so let's go into our new Job. And yeah, here, this is where we're basically going to say, give me, and I'll import that,

Implement Job Query and Send5:42

Okay, so let's go into our new job. And yeah, here, this is where we're basically going to say, give me, and I'll import that, give me all of the users where their subscription ends at. So this is the column within my users table that lists when the user no longer has access to the content. And I will cast that to a date. So rather than the specific time of the day, I just want the date itself. And we'll say, find me all users who canceled exactly two months ago from today. So subMonths(2). Give me all of them.

So sub months two. Give me all of them. All right, so these should be the users we want. Then I could say, how do we do this? I could say foreach $user, maybe, then fire off a Mailable. So I could say Mail, import that to the $user. And we'll send a new, please come back. Yeah, is that the way to do this? You can do things like where you say Mail::to, and then you pass a collection of users. But that will send the single email to all of those users.

You can do things like where you say mail to, and then you pass a collection of users. But that will send the single email to all of those users. And that's not what we want in this case. We want a unique email to each person. So let's run this, but oh, it's still failing. That's interesting. I wouldn't expect that. Are we getting the right users? And yeah, we got exactly the one user. That's what we expected.

And yeah, we got exactly the one User. That's what we expected. Yeah, because if we had said, give me all the users, it should return two. But we limited that to only the User who canceled exactly two months ago. And then we filter through and fire off the mailable. So what's the deal here? Mail::fake(). Oh yeah, we forgot to return this, because basically, this callback will be passed to an array_filter, basically. So we need to make sure that we return that to specify that we're returning true.

an array_filter, basically. So we need to make sure that we return that to specify that we're returning true. Otherwise, it'll default to false or null. So if we run that now, yeah, we do get green. So I don't think we need anything up here. We're just doing some cleanup at this point. I don't need dispatchable here. We're not going to be interacting with the queue. So reformat. And then we could even say, rather than using the variable, we'll inline it.

Schedule and Manually Test7:52

So reformat. And then we could even say, rather than using the variable, we'll inline it. Yeah. So give me all the users who canceled two months ago. For each one, fire off a pleaseComeBackAlert. So now at this point, our test tells us everything works. So the only remaining step would be to visit my Kernel here. And if we scroll down, you can see I have a couple of other things where I accumulate daily statistics. I delete some old archived records.

daily statistics. I delete some old archived records. But yeah, I could also say, every single day, we're going to dispatch that job exactly once. So now why don't we try it out together and we'll test the email. And here is the job that we will run. So let's grab the full path here. And now we can test it out in the terminal. So yeah, let's dispatch a new ContactCanceledUsersJob. And yeah, that's just going to find all User who canceled exactly two months ago and fire off that email.

And yeah, that's just going to find all Users who canceled exactly two months ago and fire off that email. And for the purposes of this video, in my local database, I set exactly two Users who did cancel two months ago from today. So if we give that a run, I'm using MailTrap locally. So if we switch over to Safari, yep, there we go. We have these two demo accounts, and we can see Ali testing it. That's my wife. I create stupid usernames when I'm testing things out. And then here's another one, brand new tester.

I create stupid usernames when I'm testing things out. And then here's another one, brand new tester. But yeah, at this point, I'm not going to do it in the video. But at this point, I'd start fleshing out the email, maybe find recent series that might interest them, things of that nature. So I will get started on that. And yeah, of course, usually, once I write my test, I will delete the comments like so. And we'll give it one last run. It passes. We're at green.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟