Adding course details response test0:00
Next on our to-do list, we have this to-do where we want to make sure that we see course details. So this will also be a dedicated page where we want to show all the details about one of our courses. And again, with every new feature that belongs to a specific page, I want to start with a new page response test. So let's add a new test here, and the name will be very similar. It gives back successful response for course details page. And then now that this is about a specific course, we need to have a Course already in the database. So let's create one by using our factory again, and let's create one of the Courses. And now what we want to do is we want to make a get request to a new route. So we don't have this route yet, but let's think about how we would want to call this. And I think I want to call this course details.
So we don't have this route yet, but let's think about how we would want to call this. And I think I want to call this courseDetails. And also interesting here, I'm going to provide the course object to the route method. And this is because I already know that I want to use route model binding for this specific route. So we are going to use this course to create the route. And then again, we also want to make sure that we get a successful response back. And then the second part here again, is the part where we act and assert at the same time. All right, let's run this test and let's check the output. We have again, a route not found exception because here courseDetails to route is not defined yet. So again, this is the next step for us because our tests are telling us what to do.
Defining course details route1:32
We have again, a Route not found exception because here course details to route is not defined yet. So again, this is the next step for us because our tests are telling us what to do. And here inside our route file, I want to add now this new route. It will be a GET request that we expect and the URL should build up from the string courses. And then we want to use route model binding by using course and the slug of our course. So this way we define that we want to provide here a model and we don't want to use the ID but the slug field. And we don't have this yet, but we just keep moving on here. And we also want to connect this to a new controller PageCourseDetailsController. And last, let's also add already the name here, which we have already used inside our test course-details. And when we run our test again, we should see now a different error.
Creating course details controller2:20
And last, let's also add already the name here, which we have already used inside our test course-details. And when we run our test again, we should see now a different error. And yeah, we do. Let's take a look in valid route action here because our controller is not given. So let's create one page CourseDetailsController. And again, we want to use a single action controller. Yep. And let's also import this here already. And now if we run the test, let's check the output again. Yeah, it's now a different one because now we get an URL generation exception. Missing required parameter for the route. course-details.
Fixing slug parameter issue3:00
Missing required parameter for the route. Course details. And missing was the parameter course. Since we are providing here a course to our route, I think the issue is about that we don't have yet a slack field on our course. So let's start by trying this now. Let's add a new field here for our slack. And let's also make sure that we add this to our factory. And here we have a slack property which we can use. All right, let's try to run our test again. And now it's working. Yeah, so the issue was about that we have defined here that we want to use the slack field of our course model,
All right, let's try to run our test again. And now it's working. Yeah, so the issue was about that we have defined here that we want to use the slack field of our Course model, but the slack field was not yet given. As always, if we change or add one test in a file, I'm going to run all of the tests now to make sure that we didn't break anything. And yeah, this looks good. So this means we are now ready to create a dedicated test just for the course details page. And we're calling this new feature test. Again, feature test because we're working with the database. PageCourseDetailsTest. And we want to refresh the database and use the past template again.
Building feature tests for details4:19
Page course details test. And we want to refresh the database and use the tests template again. I already know that I want to have at least two tests here. The first one, it shows course details because that's the most important thing for this test here, because it's the course details page. And the second one is it shows course video count. And that's because we want to show how many videos a course has on the details page. So this is information that I already have. Maybe you also get that already from a client. And the reason is that I put this now in a separate test here is that this is a little bit special because for this test,
Maybe you also get that already from a client. And the reason is that I put this now in a separate test here is that this is a little bit special because for this test, we're going to need videos in the Videos model. So that's why I like to have such a test in its separate test. But let's start with our first one here. So what do we need in order to test the course details page? We need, of course, a Course. Let's create a new Course again with the factory. And we want to create it with some data. So in our CourseFactory, we have already defined some fields like for the Slack title and description.
And we want to create it with some data. So in our CourseFactory, we have already defined some fields like for the Slack title and description. We get some faker fields here, some faker values. So I want to still make sure that we see all the fields of the Course on the details page. But there are a few new things. And now I'm going to reference them here directly with some new static text. So first, there will be a tagline for every Course, which is kind of a headline for a Course with some specific marketing text. Then every Course will have its dedicated image. And we want to make sure that we see this on the page as well. And I also already know that I want to show on the Course details page what the User is going to learn when he purchases this Course.
And we want to make sure that we see this on the page as well. And I also already know that I want to show on the course details page what the User is going to learn when he purchases this course. So we're going to have some kind of learnings. And I don't want to make this a text. I want to make this an array and also store those values in the database. So what are the users going to learn for this course? Let's use some dummy text here. Learn level routes, level views, and level comments. OK. Next, we are going to act and assert again.
OK. Next, we are going to act and assert again. We want to make a request to our course details page. And we're going to provide our course as the second argument so that we can build up the route with this lack of our course. Also import this helper method bypassed. And let's assert that everything is OK. And then what do we want to test next? Again, we want to make sure that we see some specific text. So we want to make sure that we see the title and the description again, similar to on the home page. But additionally to this, we also want to show the course tagline and the learnings which we have provided.
So we want to make sure that we see the title and the description again, similar to on the home page. But additionally to this, we also want to show the course tagline and the learnings which we have provided. So let's copy them again and bring them also in here because we want to make sure we see them as well. And then with the image, I'm going to use now the assertC method because the image path is not something that belongs to the text of the response. It will be inside the HTML code. So that's why we need to use the assertC method here. Let's run the test and let's see what the error is saying. First, we have an array to string conversion. And that's because here we are providing to adhere an array to learnings. Learnings is something which is not given yet, but still level fails here because it tries to store this array somehow.
Adding fields and rendering view7:53
And that's because here we are providing to adhere an array to learnings. learnings is something which is not given yet, but still level fails here because it tries to store this array somehow. So we need to tell level and the Course model that this will be an array. We can do this through the public cast property. And here inside an array, we can define what we want our learnings to be. And we want to work with this as an array. And you can see now the error has changed that our table has no column named tagline. Okay, so this means this has already helped, but still we are not there yet. So let's get to our migration file and also add here a string for the tagline. Okay, we're running the test again.
So let's get to our migration file and also add here a string for the tagline. Okay, we're running the test again. What's now? Table courses has no column image. Okay, let's add this as well. Image will be a string as well. Okay, what's next? Has no column learnings. So, yeah, we need to add this as well here. And this will be now a JSON field.
So, yeah, we need to add this as well here. And this will be now a JSON field. And this is how we're going to store an array inside our MySQL database. Okay, the error output has now changed. Field asserting that nothing contains some text which we have defined. Okay, again, we notice already that's because inside our controller, we are not returning anything yet. So we want to return here a few. And we're going to call this courseDetails. Again, I'm using Idea to create this view now directly.
And we're going to call this course details. Again, I'm using Idea to create this view now directly. And let's check the error again. Yeah, it shouldn't have changed now because still is nothing here on this page because we are not showing anything yet. So let's start to bring in here some data. So first we need some headline for our course title. Then also one for our tagline. And here we're also going to need the description of course. Let's run our test again.
And here we're also going to need the description of course. Let's run our test again. What do we have now? Undefined variable course. Yeah, so we are using here a course variable. But inside our controller, we haven't made use of it yet. So since we're using route model binding, I get my course directly here through as an argument. And again, I'm using here the compact method to create an array for our view file. If we run this again, we see now a different error.
And again, I'm using here the compact method to create an array for our view file. If we run this again, we see now a different error. So we are asserting that we see something and that it contains learnLevelRoutes, which it does not. Okay, that's fair enough because we haven't added our learnings here yet. So let's make a list here. And then we're going to loop over all our course learnings as learning. And then we close this. And also for every learning, we want to have a list item with the learning itself. Let's run this again.
And also for every learning, we want to have a list item with the learning itself. Let's run this again. Okay, so far so good. We see the content now here. And the different error is now that we don't see the image yet. So let's also add the image here at the bottom. And the source is for now just the image name. And let's also add an alt text for the image, which is also very important. Let's make it right now already so that we don't forget about it.
which is also very important. Let's make it right now already so that we don't forget about it. And if we run our tests now, they are now green. Perfect. So this means this test is now working. Since the test is passing, we have three options what to do. Do we want to enhance the test? I think for now I'm fine with this. Do we want to refactor? No, we want to wait until our second test is finished.
Do we want to refactor? No, we want to wait until our second test is finished. So this means we can move on here now to our second test.
