In this lesson we're going to focus on setting up our test suite to allow us to test our tasks as well.
Now you might say what is there to set up everything's already configured.
We could just add another test case right here for a task specific endpoint and you'd be right.
The only problem with the current approach is that this is the user test suite.
We want to create a separate test suite for tasks.
We don't want all of the test cases for our entire project to live in the exact same file and as we
do a bit of refactoring with our test suites.
We'll also take some time to pull other code out of this user test suite such as the code up above.
Responsible for resetting the database to a nice starting point.
Now the reason we're doing that is right now this code is only running for the user test suite and we're
going to want to run this code for our task tests as well.
So let's go ahead and kick things off by first deleting math dot J.S. and math dot test dot J s two
files we're no longer going to need all remove math dot J.S. from the source directory.
Let's start there and then down below from the tests folder.
We're going to remove math dot test dot J S and once both of those are gone our test suite should be
back to its expected working state.
And right here it is we have ten passing tests and they all exist in this one test suite user dot test
dot J S now from here we're going to create a second test suite.
That means we'll be adding a new file to our tests directory.
Right here we're gonna call this one task dot test dot J S and we're actually going to kick things off
by creating a test case that makes sure tasks can be created as we would expect.
Now down below we can see our new test suite is failing and that's because there is no test cases inside
of here.
Once we actually create that first test things will start to work once again.
Now to kick things off what we're gonna do is load in some stuff we'll need.
I'll start by creating the concert request so I can load in Super Test by requiring it and once we have
that in place I'm also going to load in the task model something we'll be using in this file.
So right here const.
Now we want to grab the task model defined over in source models.
Task dot J S and down below it is our export.
That means right here we can create a constant called task and require it.
That is dot dot to get out of the tests directory forward slash source then forward slash models forward
slash task.
Now with this in place let's go ahead and create our very first test case for this one right here.
We'll go ahead and call test.
I'll provide a name for this one should create task for user and then we'll go ahead and set up the
actual function down below.
This is where we're gonna go through the process of authenticating as a given user and actually firing
off the correct request to create that task.
Now what's the problem here.
The problem is that we don't have access to our test user that is created and manipulated in our other
test suite.
We want to make sure that both of these files can get access to that test data for the moment.
We just have that one test user.
But in order to test other task related endpoints we'll have to create some tasks in that database initially
as well so we can test that things like deleting a task or fetching your tasks actually work as expected.
So for the moment that means we can actually fill out this test case.
We're gonna do a bit of refactoring related to how we set up that test data to get started I'm going
to save this test suite.
I'm gonna close down index an app dot J S and we're going to create a brand new file for setting up
the database that's going to live in the fixtures directory in our tests folder.
So inside of here I'll create a new file called DB dot J S and this is gonna contain all of the code
necessary to set that database up.
Now to kick things off what we want to do is make sure we create the same user data that we're currently
creating over in the user test suite over in user dot test dot J S I'm gonna grab this code right here
which is responsible for generating that user.
I'm going to take it.
Cut it out of its current location and bring it over to D.B. dot J S pasting it in.
Now we do need some stuff that we don't have in this file.
For example I need JWT and I also need a mongoose.
So right here I'll go ahead and load both of those in.
First stop all require Mongoose storing it on a mongoose variable then down below I'll load in the JWT
library by using require with Jason Webb token now we can go ahead and move back to user test dot J
S and remove both of those modules because they're no longer used inside of this file.
All we need is request app and user.
Now down below this makes some problems for what we already have right here.
We are trying to create that user and then down below we use the two variables defined over here quite
a bit.
So how are we going to remedy this situation.
Well what we're gonna do is first create a function and this function will get called to set up our
data.
So this will eventually be used with before each.
Right here.
Let's go ahead and start with that.
I'm going to create a constant and I'll call this something like setup database or configure database
or populate database or whatever name you want to choose.
Now we're gonna set this up as an async function and for the moment the contents of this function is
gonna be exactly the same as the contents of before each.
Over here.
That means I can just take these two lines I can cut them out of their current location and bring them
over to D.B. J S and we're ready to go.
Now the next thing we need to do is export some key values from this file so our test suites can actually
use them right here module dot exports is gonna get set equal to an object and I'll be adding these
three variables on as properties.
I'll start with user 1 I.D. though the order isn't important then.
User 1 followed by last but not least set up database.
So at this point we have this new file and it's exporting these stuff that user dot test dot J.S. needs.
So all we have to do to get the test suite back to its former working glory is to load those things
in right over here.
What does that mean for us.
It means we're gonna grab a few things using some object D structuring I'm going to grab user 1 I.D.
user 1 and setup database.
And we're gonna grab those from the file we just created.
So all require dot forward slash of fixtures forward slash D.B..
Now the two things user 1 I.D. and user 1 those are already being used by all of the code down below.
There's no need to make any changes to any of that.
All we have to do to get before each working once again is to remove the function we're currently passing
in and pass in a setup database instead.
Now once again the advantage of doing this is that I can simply use this one line in it.
Task dot test dot J S to get access to all of these same features over there.
Now the only other change we need to make is over in D.B. J S we just added that new code which uses
the User model that's sitting right here.
So we need to make sure we load that in as well.
Right here const user equals will use require with the following path that is dot dot to get out of
the fixtures directory but word slash dot dot to get out of tests than it is source models.
User.
Now if we go ahead and save D.B. dot J s and our user test suite I would expect us to be back to that
working test suite.
Right here it looks like everything is working as expected.
We have all of our test cases passing which is great.
Now we can actually take these same two lines exactly as they currently are.
Copy them to the clipboard bring them over to task dot test dot J S.
Paste them in.
And now this file has access to all of that same test data now from a user dot test done J.S..
We also want to grab this line right here that imports the app.
We could manually type that out again or we could just copy and paste it over to the new test suite.
And with this in place our test suite is now good to go.
It's currently not doing much testing but everything is set up to at least work in the long term.
Now when we have multiple test suites each interacting with the database there's a chance for conflict
because of how just runs things just will try to run our tests in separate test suites at the same time.
And since we're depending on certain changes to the database we can get into situations where tests
fail incorrectly for example this sign up test might fail because in between it creating the user and
it finding the user a test in a different file messes up the user may be doing something like resetting
the database.
So it's important to write real test cases but it's also important to recognize that our test cases
can interfere with each other if we let them.
We can fix this with a simple change in package Dot.
Jason All we need to do is add a new option onto the just command along side of the watch option.
This is hyphen hyphen run in band that is capital I capital B.
This is going to run your tests in series making sure that there's no overlap or chance of conflict.
Now when we change the command we will need to use control C to manually shut down just then we can
start it up once again using up and enter and we're good to go.
Now at this point we can actually write a test case ensuring that a given user can indeed create a task
and that is exactly what we're going to do right now.
Down below I can see the test suite did restart and we still have eleven passing tests which is excellent.
Right here we'll kick things off what they call to request.
Let's start by creating a constant called response and I'm gonna go ahead and use a wait with my call
to request will pass in our Express application and in this case I'm trying to make an H TTP a post
request to the following endpoint that is a forward slash tasks.
Now from here we'll start by going ahead and setting up the authentication header so that is dot set
to call the set method right here.
Authorization providing the value as well.
Bearer followed by that token.
Now we still have access to this because of how we set up the DB fixtures file.
We have user 1 I.D. and user 1.
And right here like we've done before it is user 1.
Dot tokens grabbing the first one and getting the JWT off of that object.
Now with this in place the next thing we're going to do is use send to send the necessary data.
So I'll call send providing an object.
Now we know for tasks the only thing we need to provide is a description.
So right here I'll do just that description equals I can use whatever I'd like.
I'll use something like from my test and then down below we can go ahead and use expect to expect the
following status code a 2 0 1.
Now we'll go ahead and add more to this test case in just a moment before we run it though let's make
sure to mark this as an async function since we are using a weight right inside.
Now let's run the test case and make sure it's at least working in its current state.
If this is at least working we'll expand on it adding other assertions and down below it is indeed functional.
Now what we're gonna do is usually task a model to find that new task by its I.D. and make sure it was
actually saved to the database and that it looks correct.
So we have the I.D. on the response down below.
I'll create a new constant lower case t task I'll use a weight with the following task dot find by I.D.
like we had done plenty of times for user and we have response dot body dot underscore I.D..
Now with this in place let's go ahead and assert that we actually got something back.
I'll use expect for that.
And like we had done before with users.
I'll expect that the task is not null.
I'll start with not then the assertion to be no.
Excellent.
Now we can go ahead and run things in its current state although we could expand on our assertions even
further.
Now that we have their response and we have the task.
For example I could check that the descriptions line up I could check that this user is the owner.
I could check if the completed value was correctly set to false.
I could check all sorts of things depending on what I'm worried about failing right here.
Let's go ahead and just make sure that these completed property on this new task is indeed false.
So right here what I'll do is expect something about the task we found in the database.
I'm going to expect.
Task dot completed to be false.
So right here I can use to be or to equal and I can pass false in.
Now once again if I save things the test should still be passing as that is the default value set up
for that specific field and that is exactly what we end up getting down below.
That's where I'd like to stop for this one in the next lesson we'll actually set up our setup database
function and to wipe existing tasks and create some test ones as well so we can write more interesting
test cases.
I'm excited to get to that.
Let's jump right in.