Creating the Feature File1:09
So I'm not going to show you how to install and how to configure, for example, Behat. I've already done this. This is more of a look over my shoulder type of series. However, if you do want to learn those things, of course, we have dedicated videos on the site. Just go check them out. Now, here you can see I've created a new file called single-purchases.feature. So this is where I can describe and illustrate the needs of the business. For example, this feature will be called Single Purchases. And now I essentially want to illustrate the why.
Defining Feature Purpose1:33
For example, this feature will be called Single Purchases. And now I essentially want to illustrate the why. Why am I doing this? Who? Who is it for? And what? What are we doing? So with that in mind, the why might be in order to avoid subscriptions, because remember, this is really a feature for people who do not like the idea of ever getting a subscription. This is for them.
this is really a feature for people who do not like the idea of ever getting a subscription. This is for them. So they are the benefactor of this feature. So as a visitor, finally, what do we want to be able to do as a visitor? Well, I want to purchase standalone videos. Now in reality, this isn't even required. If you don't want to do this, you don't have to, but I still recommend doing it. It allows you to get in the mindset of who you are building this for. What is the benefit? Why are you doing this?
Writing the First Scenario2:24
What is the benefit? Why are you doing this? All of these things will start to become clear as you write them down. Not to mention the fact that you can come back to this stuff six months later. All right, so now for our first scenario. So the way I like to think of this is, imagine that we are talking to the benefactor. And again, in this case, the benefactor is somebody who doesn't like subscriptions, but may want to buy a video or two now and again. Now you could talk with somebody, or in your mind, just envision having a conversation where you say, all right, given the scenario that you want to purchase videos as a guest,
Now you could talk with somebody, or in your mind, just envision having a conversation where you say, all right, given the scenario that you want to purchase videos as a guest, how exactly do you envision that working? What will happen? Do you visit a lesson page? Do you expect to see some option to purchase the video? What should happen once you do? All of that stuff can be illustrated within our scenario steps here. So I will say the scenario is purchasing a video as a guest. Now this next part where we work on the steps is where a lot of people can falter.
So I will say the scenario is purchasing a video as a guest. Now this next part where we work on the steps is where a lot of people can falter. And I would gladly include myself in this. Strangely enough, when you're thinking from the point of view of your benefactor, and in this case, it's just a visitor to the site, it can sometimes be very difficult to simplify things. And I have trouble with this as well. For example, well, we could say, given I access this URL, and then I click on that button, and then I fill this input with that, and that input with this, and so on and so on. And then I click this button, and then I should be redirected here.
and then I fill this input with that, and that input with this, and so on and so on. And then I click this button, and then I should be redirected here. And then this text within that element should be displayed. And when I click on that, it should download the video. All right, well, that's really super long. And you know what, if you were talking to a regular user, they would never say that, of course. What might they say in reality? Well, they could say something like, okay, maybe I go to your site, and I don't have an account.
Well, they could say something like, okay, maybe I go to your site, and I don't have an account. But if I go to some lesson page, and I try to purchase the video, then I should be able to download it. That's probably more in tune with how a regular person would say it. That's probably way more in tune with how a regular visitor to your site might say it. When I am not logged in, so given we are just a guest, and we expect some lesson to exist. So I can say, and there is a example lesson lesson. Given that lesson exists, when I go to this lesson page, then what?
So I can say, and there is a example lesson lesson. Given that lesson exists, when I go to this lesson page, then what? Well, again, they're not going to say, and I try to fill out this form, and I enter my name and my last name. No, they don't say it. They'll just say, and I try to purchase the video, and I purchase the video. Then what? Then I should be able to download it. And I think that's actually pretty good. Again, this can be weirdly difficult.
Running Behat and Generating Steps5:09
And I think that's actually pretty good. Again, this can be weirdly difficult. We are always in the mindset of the developer. So we end up using things that are more code related or browser related or technical related. You always need to think in terms of the benefactor. And this is probably more or less how the benefactor might verbalize this feature request. Okay, let's now run the test. It's in my features directory, and it's called single purchases. All right, so now at this point, if we scroll all the way to the top, notice that we didn't run anything.
All right, so now at this point, if we scroll all the way to the top, notice that we didn't run anything. And that's because these are not defined methods just yet. Now you'll notice that Behat is nice enough to generate these methods for us. So if you want, you could copy them, or you can run it again, and then add the --append-snippets flag. And that will do the same thing. But this time, all of those methods will automatically be added to your feature context. So now if we run it again, here we can see our first step is to ensure that the user is not logged in.
Implementing Step Definitions6:06
So now if we run it again, here we can see our first step is to ensure that the user is not logged in. So let's open up my feature context. And all the way down here, at the bottom, here are those new methods. Now really, if you think about it, I am not logged in, it's almost like just a little bit of sugar to remind me that we are not dealing with an authenticated user. Now what this means is, at least in my mind right now, I may have to change this later, but I'm thinking I can just get away with returning or not doing anything at all. And like I said though, if that logic should change and there is something special I have to do to assert that a user is not logged in, then I can update this.
And like I said though, if that logic should change and there is something special I have to do to assert that a user is not logged in, then I can update this. Let's run it again. All right, step two. And there is an example lesson lesson. So here we're saying, of course, if we want to purchase a video, then that associated lesson needs to exist in the database. Let's set that up. We will accept the title. So I will use the Laracasts test dummy tool that we covered here on the site to rapidly
We will accept the title. So I will use the Laracasts test dummy tool that we covered here on the site to rapidly create some of these records for the purposes of testing. So let's go ahead and create. And I'll pass in my model here, LaracastsLesson. And I do want to override the title. I will accept whatever is passed in here. And that will automatically be applied as the title for the lesson. Just remember that this was automatically imported. But behind the scenes, this is what we're doing here.
Just remember that this was automatically imported. But behind the scenes, this is what we're doing here. And again, if you'd like to learn more about that, just check it out on github.com/Laracasts/test-dummy. Okay, so let's run the test again and see what our next step is. So far, we're doing a good job, given we aren't logged in, and there is some kind of example lesson. Well, when I go to this lesson page, let's make that work. Now we have a couple choices for this. One, we could take the generated lesson here and store it on the object here.
Now we have a couple choices for this. One, we could take the generated lesson here and store it on the object here. So we could do something like lessonId equals whatever is returned from that, and then get the ID property. Or if this method won't exist elsewhere, then you could maybe depend upon this lesson existing. It just sort of depends. And don't forget, you can always refactor down the line if you need to make it a little more flexible. For now, let's do the easiest choice. So when I go to this lesson page, and I can use this visit because I'm using the mink
For now, let's do the easiest choice. So when I go to this lesson page, and I can use this visit because I'm using the mink context here, and we can browse to lessons/. Now I need to provide a slug here, so I have to be explicit about what that slug is in the lessons table. So let's say slug, and then I will use str_slug, like so. So that means if the title is example lesson, the slug will be example-lesson, okay? And then finally, I can just update this right here. All right, so now when we go to this lesson page, lessons/example-lesson, let's run the test again.
Planning Purchase and Download8:52
All right, so now when we go to this lesson page, lessons/example-lesson, let's run the test again. Now we've finally gotten to the good stuff. These final two methods are where we do most of the work here. So when we say I purchased a video, what form and what shape should that take? And then next, when we should be able to download it, again, what shape should that take? Should there be a download now link, or should we be able to access some kind of downloads page within our settings area? Well, that's all stuff that we will need to think about in the next lesson.
Well, that's all stuff that we will need to think about in the next lesson.
