Around creating a reservation.
I'll create a new spec called Reservations dot end to end dot spec dot ts.
And let's go ahead and actually rename our health check file.
We can remove the dot app here.
So we'll open up a new describe block and describe the reservations and then open up a function where
we'll test reservations.
Our first test will be to create.
So we'll call this create and open up a function where we'll now we'll create a new reservation.
So of course, before we actually create the reservation, we will need to authenticate with our authentication
service.
So let's set up a new before all block, which will contain an async function.
And inside of here we're going to do the setup work for our test where we'll create a new user and get
an authorization header for that user.
After some refactoring to our auth service.
First, we will call, await, Fetch and reach out to our auth service.
Listening on Port 3001, we will provide an options object to fetch where we'll specify the method and
make sure this is a post request and we'll specify a body where we'll call json.stringify, provide
a new object and here we can provide our email, call it sleep or Nest app at gmail.com.
And the password?
I will give it a strong password as usual.
Let's go ahead and actually take this object out and declare it in a new variable that we'll call user
and paste it here.
So now let's json.stringify the user.
And now I want to call our auth service with our credentials to log in.
And instead of using a set cookie to set a JWT cookie, I want to get the JWT sent back directly from
the login call and then we can provide it as a header to our authentication service.
So to accomplish this, let's firstly go to our auth service where we'll firstly go into our auth controller
and instead of sending the user back in our login response, we'll actually get the JWT back directly
from this login call and then we will respond with that JWT.
So let's go to the auth service dot login.
And in addition to setting the response cookie, we will now return the token back to the controller.
So now that we returned the token back to the controller, we need to make sure that we actually end
up using it in our JWT strategy.
So here we'll also expand our JWT from request to accept a request dot headers dot authentication header
so that we can pass a request header.
But this will be useful if we operate our microservices on different domains because the cookies will
not carry over in that case.
So one more change we're going to have to make is to our JWT auth guard in our common folder where we
actually send the request to the auth service to authenticate the JWT.
You can see right now we're pulling the JWT directly off of the cookies only.
Let's go ahead and add a new section to this variable that will be if we don't find the beat on the
cookies.
We'll also switch to HTTP, get the request, and this time we'll look for the dot headers dot authentication
so that we pass the cookies or the headers here.
Only make sure we change the headers authentication to a lowercase a here as all of our headers will
start with a lowercase letter.
Now we want our changes to be pushed up and built by Codebuild so that we can correctly test out our
new end to end tests.
So I'll go ahead and make sure that we go ahead and commit all this code and then push them up so that
the code build will start a new build.
So go ahead and push them up.
So now back in our test, let's declare a new const here called Response and we'll call it Await Fetch.
We'll call it HTTP auth service again and we will pass in the same method of post.
Now make sure in our first fetch we're calling slash users root to actually create the user.
And then in the second call we will call slash auth slash login.
Now we'll provide the same body, which is our user and our credentials that we know exists at this
point and we get the JWT back.
So to actually parse the JWT, we'll call await response dot text because we returned JWT as plain text
so we can simply console dot log the JWT out for now and in our first test block.
Let's just expect true to be truthy so we can test this out.
Let's proceed back in the terminal.
By rerunning our test suite by running Docker compose up and end.
So lastly, in order for this request to be sent properly, we also need to pass a header section where
we're going to supply a content type of application slash JSON.
So we'll copy this headers and also apply it to our request to log in to the system.
Now we'll go ahead and rerun our tests by running Docker.
Compose up end to end.
Now we can see our test has passed and our console log statement, we can see the JWT access token supplied
here in our test.
So let's set a new variable in the top section of our test called JWT, which will be a string.
And then we will set JWT down here so that the JWT is defined.
So our setup work will be a test in of itself to show that the auth service is working properly.
But now we'll actually test the creation of a new reservation.
And to do this we'll create a new variable called response and set it equal to await Fetch.
And now we'll call it HTTP reservations at Port 3000 and make sure this is an async function and I will
supply our options object where we have the method of post, we will have a headers section that we
can copy from a previous request and then the body which will be json.stringify.
And now we need to provide the body of the reservations request.
Now to do this we can actually just copy one of the requests we already have inside of Postman and paste
this in.
Just make sure to remove the outer object.
Of course.
Make sure we provide the authentication header which we will set equal to the JWT.
And now at this point we can make a just assertion that we expect the response dot okay to be truthy
and then we can parse the reservation response by calling await response dot JSON and let's log out
the reservation that we get back from this request.
Now of course, make sure we add a slash reservations in our URL here so that we actually post to the
right spot.
So after our changes to our app have been completed and cloud build, we'll go ahead and tell Docker
compose to pull our images by running Docker, compose pull.
Now we can rerun our tests by running Docker, compose up end to end.
So you can see this reservation test has passed and we are getting this reservation back.
Okay, so I'll get rid of our console log and now we can actually test out our get functionality as
well to get the newly created reservation to make sure that the get functionality is working and that
the reservation was actually persisted.
So firstly, I'll rename our first response to response, create and update all of our variables to
use, response, create, and then we'll create a new variable called response Get and call await Fetch
HTTP reservations at Port 3000, slash reservations and change this to a template literal because if
we recall in our reservations controller we can get a reservation by its underscore ID, which is exactly
what we'll do here.
We will actually use the newly created reservation response dot underscore ID to get the reservation
by ID and then we'll rename reservation created reservation because now I want to create a new const
called Reservation and set it equal to zero eight response, get dot JSON and now we can actually make
an assertion that the created reservation from our CREATE request actually will to equal our reservation
from our get request.
Make sure we change the reservation variable here to created reservation dot underscore ID and then
don't forget we need to provide an options object so that we can supply headers and set authentication
to JWT.
So after rerunning our test, you can see that our reservation test passed and our assertion is exactly
correct in this test because the created reservation now equals the reservation from get.
So this is great.
Let's update the name of the test here to create and get because that's what we're testing.
And I'll pull this functionality to create the reservation out into a.
New function out here just to make it a bit cleaner.
So I'll call this crate reservation, which will be an async function and it'll go ahead and just return
the created reservation.
And now inside of here we can call const created reservation is equal to await create reservation.
And now this is just a bit cleaner and easier to read.
Okay, so now we have a basic suite of end to end tests that will give us confidence that our production
images one all start up because of our health check and also that our basic reservation functionality
is functioning end to end.
We're able to create a reservation and get that reservation and both of the responses match.
Exactly.
Okay.
So back in our root Package.json, I want to update our test end to end command here to reflect our
new end to end tests.
So we'll change this command to Docker compose and then we'll specify a new argument called project
directory, which essentially just allows us to choose where to run these commands from.
In our case, we know that's the end to end folder and then we just call up end to end.
So now all we have to do to execute our tests is go to the root of our project and run yarn test end
to end and it'll kick off our end to end test.