So let's have a look at our tests, which we haven't looked at in a while, so things probably won't
work as expected, but we can resolve that.
So I've opened a terminal window and I'm in the correct directory because I'm testing my handlers.
So let's run the tests and see what happens.
Go, go test dash the current directory and immediately it says can't find the function human date.
And that makes sense because we've made some changes to our code.
So in our setup test go, which is in Setar Handler's folder, inside her internals folder, there's
a few changes I need to make right away.
So right away, you see that I have this function, this variable functions, which is of template fungimap
and that's empty.
And if you look at our render package where that function is actually defined, we actually have, you
know, some functions now.
So let's copy those.
I'll just copy this whole variable and then modify it as necessary.
So in our setup test, I'm going to replace this one, which doesn't work with this one.
And of course, I need to actually point to the render package.
So I'll put render there and copy and paste it in front of all of these.
And while I'm at it and see that I have ghab register here, but I know I've added more things.
Let's go back to Minogue, go and see what we have in our gub register a bit.
We have all of this, so I'll copy those because I know that's going to have to be there and replace
what's in here with that.
And let's try our tests again and see what happens.
So clear the screen.
Cancel go test Dash V..
All right, so there's some fails there and the fails are all got three 07 wanted 303.
Well, that's kind of strange.
What's going on there?
Well, it turns out and I do this all the time in my handlers, I have often put this status temporary
redirect, which is not the right status for some reason.
I always confuse that with status.
See other if you look at the redirect, it actually says redirect replies to the request with a redirect
to your URL, which may be a path relative, blah, blah, blah.
The provided status code should be in the 300 range and is usually status move permanently, status
not found or status C other.
So I'm going to fix that and I'm going to fix it by doing a global search and replace in my handler's
package.
I will find and replace this which is active status, temporary redirect with HTP status C other.
Let's replace all and see how that's working.
All right, so let's try that.
Go back here, clear the screen and run that test again and see what else is failing.
So everything, everything past except for internal handlers, so where's the fail test repository,
post reservation and return the wrong response code invalid got three or three, one or 200.
So let's see where that is.
That is under handlers test line 238.
So let's go to line 238 of handlers test.
238, and we're saying we should be getting status, OK, and we got what do we get instead?
Got three or three wanted 200 for post reservation handler handlers, test line 238.
So let's find our handlers and find post reservation.
And where is this feeling it after we call post reservation?
And the case here is a test for invalid remedy, start date and date, first date time invalid remedy.
So when I get an invalid remedy in the handlers, that's after a validation and it's returning us to
invalid data status c other.
So it's redirecting us with status.
C other.
It's after the form valid, aha, so first of all, let's get rid of this error message.
I don't need that anymore and this is actually going to render 200, so that should be status, OK?
So here I have the wrong status.
There should be status.
OK.
Because it's actually rendering the page, the status is OK, it's rendering the page with our invalid
form data.
Let's see what happens now.
Go test.
And one more Faile got three or three wanted 303.
That makes no sense, 214, my global search and replace may have not been ideal line 214.
So this is calling for what case now test for invalid remedies if our code is not status, OK, wanted.
This budget that got three or three wanted 303.
This should be status, OK?
Because that's we're checking for here.
Got three or three from post reservation with Invalid Remedy.
So post reservation invalid remedy renders the template, model, template just OK.
So that's OK.
Got three or three, wanted 200, why am I getting three or three handlers, Tesco 214?
This is why we write tests.
Handlers go to 14, post reservation, handwritten Roller's post code for invalid remedy.
And I'm passing an invalid remedy.
And in my handler, when I get an invalid room ID, it is right here.
So that's what I'm passing the remedy is giving me a status, see other OK.
So what it should be giving me for that invalid data in my handler's test is a status of the other status.
The other tried this one more time.
That's good.
All right, so now we've at least got our tests working, but our coverage is really bad, so I'll run
my coverage and have a look at this.
It pops this up, everything here is covered, everything here is covered, we get all the way down
to here.
So let's do the show login page.
That would be a good one to to run a table driven test for.
So let's close this and close this and go back to our tests and write a test for what I'm going to do
is read a test, first of all, for anything that I can with as little effort as possible just by adapting
my my table driven tests.
So we have some routes that we're not actually testing.
Like, for example, we never bothered to test for an invalid route, one that doesn't exist at all.
So I'll just say the name of this test will be non-existent because it's a nonexistent route.
And I'll put in something that I know doesn't exist, green eggs and ham, and that should give me an
HBP status not found.
OK, so what am I missing in there?
It'll be a get request.
Let's run that test, make sure that's going to work as expected, so go test.
Perfect, but we also have a bunch of other routes that don't exist at all in our test file, and those
would be ones like, well, let's see what we have in here in our set up test where we define our routes.
They're here somewhere.
Right here, so we've gone as far as make reservation, get and post and reservation summary in our
routes file, we actually have these ones, user log in, user log.
So copy those and put them in our setup test.
I'm going to copy all the routes that don't currently exist and get rid of the handler's part because
we're in the handler's package.
And all of our admin rates as well, so it's Capito's, even though I'm not going to do them all for
you in this lecture, we are, of course, going to test them all.
So we may as well put them in there.
And they don't need to be wrapped in anything because we're actually just testing the handlers, not
our authentication.
So get rid of that and that.
Given my experience with global search and replace a moment ago, I am not going to do it this time
around.
I'll just do it manually.
OK, so there's all of our roots, let's make sure they still work in our tests, that nothing broke.
Good.
Now, let's go back to our handlers test and see what other routes I can actually do.
So new routes.
I want to test for, say, log in just to see if the page shows up and the path for that.
The route for that is slash user slash log in.
It is a get request and I should see htp dot status OK for that one.
So that's the first one.
We also have a log entry and this gets should be in quotes.
That also is a get request, so I should be able to run that test with no extra effort whatsoever in
the same way the roll call, this log out will call this the dashboard.
And that path for that one is admin dashboard.
And that should just render properly good.
And we also have one for it, new reservations.
So new regs, new reservations, no reservations, new.
And reservations, all OK, so those ones I should be able to check pretty easily and then I also should
be able to show reservation, so let's do that one surance and the path for that or the are for that
is admin reservations new and one.
And since our test repo is actually just returning value and doesn't do any logic, this should all
work.
Let's see if it does.
So clear the screen go test.
And we have one fail, and that is expected 200 got four or four for Dashboard, I must have a path
name wrong in here somehow.
So admin dashboard, admin dashboard get status.
OK, but I spelled out wrong, DHS, HBO, JRD.
Now still going to fall for I must not have copy the route.
Oh, yes, I've got to put it in front of all these because they're not grouped.
I actually have to put them in their.
Oops, look, I had an extra one in all of those.
I do.
So I have to added many here, because in the routes file, the admin is actually added by this group
here where I put admin in mux route and I'm not using that here.
So let's try this one more time.
Go test.
One more fail, 200, but got four or five show reds, 200 or five, so that is show race that is under
the handlers test shows, admin reservations, new one show.
Yeah, I left the show off of there.
OK, one more try.
OK, they passed.
Now let's check our coverage and see what else has been covered already just by adding those to our
table driven test.
This is good.
This is good all the way down.
So show log in is now rendered and that's actually working.
Hoshko log in, though, is not logout is.
So we have a lot more covered just by adding that to our table driven test.
So let's test this one which is post show log in.
I want to test this one because there's a lot of cases I can test there pretty easily.
So let me go over to my code and go to my handlers test.
And right at the bottom, I'll go to the very bottom and I'll create a new test just before this.
Get the context.
Now, I want to create some data.
I want to run this as a table driven test.
I want to check for, say, three situations, one where everything is valid, one where the login credentials
are invalid, and one where I don't actually enter correct information.
Maybe I put a J or just one letter instead of a valid email address.
So what I want to do is create some data for that.
So I'll create a new variable, which I'll call login tests, and that will be a slice of struct.
And let's define it, so I'm going to give my test a name, which will be a string, I'll give my test
an email, which is the username that they're typing in, which is a string I'm not going to bother
with.
Password will say expected status code.
Which will be rent and I'm going to do something we haven't done yet.
I'm also going to say expected HTML, I'm actually going to pull the HTML out of the response and look
for things that I know should be in there and that will be a string.
And finally, I'll have expected location.
What you, Earl, does the user have in his or her browser that will also be a string, OK, and now
I need to populate that with some data, so we'll just do one to start with.
So the first thing we'll put in here, our first test case and we'll just do one to start with will
be called valid credentials.
And for an email address, I'll use me at here, here.
And the corrected the correct status code should be HTP, not status C other, because I'm going to
do a redirect and when you do a redirect, that's the status where we're going to use.
As for the next one, which is expected HTML, I'll leave that empty because I'm not going to examine
that.
In fact, you can't examine the HTML easily from a test when you're doing a redirect.
If you're doing a direct render from the handler, then you get some HTML.
If you're doing a redirect, it's actually sending a redirect to the browser and not HTML.
And finally, what will we what are we going to be redirected to?
Well, when we redirect after successfully logging in and our application, we take them to the homepage
and that's the correct you URL for the homepage.
So I have this set up now.
I need to run the table tests and I'll add more situations in a bit.
So I'll create a new function, which I'll call test log in.
And it's a type or takes a parameter of a pointer to testing the T and we'll run our table tests so
we'll range through all tests.
Right now there's only one, but it'll be more before we're finished.
So four don't care about the indexed.
I'll call my individual test e range login tests.
OK, so what are what's the very first thing we're going to do?
Well, the same as we did in our other tests, we're going to create some posted data.
So posted data is a sign the value of euro values, and I'll make it empty right now and then I'll add
to it one at a time.
So I need to add two things in our login form.
We have our email address and we have our password.
So posted data add and I'm going to add email, which is the key, the same thing we named the form
on that form page and the value will be from our variable email
and I need to have a password in their posted data.
Add password.
I'll just use password as a string.
OK, now we need to create to create the request, so create the request and we'll do it the same way
we did before request and nothing we're ignoring.
The second parameter is assigned HTP the new request.
The method will be post because this is a posted form.
The euro will be user login, which is what the URL is in our form, and then we encode our data string's
new reader.
Posted data dot in code, so that creates a request.
Now we need to get the context for a request and context is a sign the value of get context and we pass
at our request and then we add the request to we add the context to the request.
Request equals request with context and the context.
Now we set the header.
Which you probably don't have to do, but I always do it anyway, because it's good practice request
header set and we're going to set the content type as application at Stasch w w w dash form dash Eurail
encoded.
And again, I don't think you have to do this, but I always do.
So what do I have here to parentheses.
There, so we sent the letter and we create a recorder, a response recorder is assigned the value of
HTP test for HIV test, not new recorder.
And now we call the handler, so call the handler.
Handler is assigned the value of HTP, dog handler func and the handler I want to use is repo.
Post show Longet.
And I don't need parentheses there.
That looks better and actually call the handler handler, not serve http and we want to pass in our
response recorder for the first parameter and a request for the second parameter.
All right.
So this should actually work, but now we need to actually perform some tests.
So that's the first thing we're going to check is our expected status code.
If our code is not equal to IDOT expected status code, then throw an error teda error f.
Failed and I'll put it in the name here, that placeholder expected code, what it is, but got what
we got and that's idot name for the first place holder idot expected status code for the second one
and our code for the third one.
OK, so we should be able to we're only testing one thing right now, but let's just test this and run
this test and see if it works though.
Test should be everything.
Everything passed good, so we've tested that first case in the first one, but what about other tests
where we have HTML or we have an expected location?
Well, for this form, we don't have expected e-mail.
So we'll skip that for a moment and do that next.
But let's try the expected location.
So what we're checking here is when someone logs in successfully, they should be redirected to the
home page.
So we actually want to check to see what the location is, but we only want to do that for a test where
the expected location is not empty.
So we can say if IDOT expected location is not equal to nothing, if it's not an empty string, then
we need to get the euro.
So we need to get the euro from test.
So we want the actual location and I'll ignore the error.
We can get that from our response recorder.
Result location so that stores the location that sent to the browser in this variable, then we just
check to make sure that what we got is what we expected to get.
So we can say if actual location, which is not a string but has a function on it that allows me to
turn it into a string.
If actual location string is not equal to idot expected location and throw an error teda error f.
And we'll say failed and then the name of the test.
Expected location.
String, but got location string, so idot name idot expected location and then actual location and
call the string method.
So let's try that clear air test or clear a screen, run the tests.
Everything passed good.
All right, so the last situation we need to handle is if checking is checking for expected values in
HTML, and again, we'll just use the same logic.
If IDOT expected HTML is not empty, then run this test.
And what we're going to do is to read the response body
into a string and that's pretty easy.
We can say HTML, which is what we're getting from the server, is equal to our response recorder body
string.
So now we have the e-mail that sent back by the browser and we just checked to see if the little fragment
of you are out of e-mail, we expect to be in there.
If it's in there, then we pass the test.
If it's not that we failed the test.
So we can just say, if not string's contains and the string we want to check is HTML.
What we've got back from the browser and what we expect to find in there is in this variable idot expected
HTML.
So if that doesn't exist, throw an error t dot şeref failed percent s for the name and we'll say expected
to find percent s which will be the e-mail we're searching for but did not and do our substitutions
idot name idot expected html.
OK, now this is never going to fire yet because we don't, we don't have a case where it's supposed
to be there, but I'm going to run the tests anyway just to make sure that everything is correct.
And it is.
OK, so let's add another test case and the second test case I'm going to put in here will be one for
invalid credentials.
In other words, people logged in but didn't use the correct username and password.
So we need to pass it a username and I'll pass it to a different email address this time, Jack, at
nimble dot com.
And we need a status which will again be HTP status C other because we're going to do a redirect.
If they don't log in properly and we want to have no HTML, we're checking for what we want to make
sure we're taken to user login.
So what happens when someone logs in with the wrong information.
We do it redirect, which gives the HTP status code of Status C other and we redirect them back to the
user login page.
Now, the only problem we have with this is if we go to our test repo and we look for authenticate,
which is right here, we're always returning a valid login no matter what happens.
But in my handler's test, when I want to check for valid credentials, I use the email address me out
of here NCEA.
When I'm using invalid correct credentials, I use something else so I can just modify my test repo
as follows.
If email is equal to me at here gutsier.
Then say it's a valid slogan, otherwise, if that's not true, then I just need to return something
else.
I'll say return zero, nothing and then some error errors.
Dot knew some error.
And all I want to get there is an error.
So this should actually handle that situation.
So in our tests for the first one, I'm passing the email of me at here Dossie and my repo by test repo
says, Oh that's me at here Dossie.
So it's a valid login.
In my second test I'm passing Jacquette nimble dot com, which is not me at here dossie.
Therefore it will not allow the person to login.
So I'm just faking or mocking what happens at the database level.
So let's try that second test and see if we got that right.
Everything passed good.
Now, what's the third situation that we want to go for?
The third situation is right here.
I'll call it invalid.
Data, in other words, they didn't enter all the information in the correct format in our situation.
The only thing you can't enter in the correct format is an email address.
So I'll just use the letter J for an email address, because that's not an email address.
And in this situation, I want to get a status code of status, OK, because what's being rendered is
the login form all over again.
We're not doing a redirect.
We're actually doing a render.
And in this case, I want to find something that I know is going to be in the login screen.
So what is going to be in the login screen in every situation?
Well, if you think about it, what's always going to be available to us is this action equals user
log in, because that's part of the form.
And the last part, I'm going to ignore the location because I'm actually not getting a location in
this case.
I'm not being told to go somewhere else.
I'm actually getting some HTML.
So in this situation, I have invalid data.
I'm passing in the invalid data of J4, an email address.
I am going to get a status OK, back from the server because the page is rendered OK.
It's just not going where the user wanted to go.
And that HTML that sent back to the user will definitely have action equals user log in because if you
look at your login page under templates.
And find the login screen right here that has this text, and that's the only page in our site that
has this text, therefore that is a valid thing to look for.
So let's test this and see how it looks.
Clear the screen.
And it passes now, if I was to go back and to find that test log in case here, change this from user
log in to user, put an extra R there.
This test should fail now because there is not going to be user or login and it should fail.
And it fails exactly, OK, so that seems to cover most of the cases, let's just check our coverage
here.
And our coverage is green at the top, as it should be all the way down to here.
I'm looking for the login screen social repository.
That's fine.
OK, so this is where am I post login?
So this post so long in here where so this first part is just logging in air and printing it, I don't
care if that ever gets tested.
And I mean, honestly, when I'm writing tests, if I have to jump through really strange hoops just
to catch a situation like this, I'm making my code far more complex than it has to be.
So I'm perfectly OK with that error not being tested.
But everything else in here in the post log in, except for the errors like this, seems to get really
good coverage.
And that's exactly what I'm looking for.
These things I don't worry about at all because I'm not going to make my code far more complex than
it has to be just to get green text everywhere in my coverage report.
So this seems to cover every situation I need to worry about or the majority of the situations I need
to worry about for testing the post login handler.
Now, the rest of these handlers, you should be able to write test for yourself using exactly the same
kind of logic that I did just here.
I am going to post to this lecture all of the completed tests, one that are done to my satisfaction
to this lecture.
So if you get stuck, you can use that code as a reference.
But I think it's time to move on to the last few things we need to handle in order to get our application
into production.