#100DaysOfWeb in Python Transcripts
Chapter: Days 81-84: Unit testing web apps
Lecture: More view model tests

Login or purchase this course to watch this video and the rest of the course contents.
0:00 So you've seen how we can test our view models and that required patching some of our data access code. There's a couple of other tests we could write
0:08 but they're all similar. So I want to just put them in here and let you have them as reference. We'll talk quickly about them.
0:14 But I want to take too much time write a whole bunch of little detailed tests. So let's see what we got here and we'll just talk through them.
0:20 So this tested our index view model. Let's go and test the details one. This one is more complicated. I remember we go, we get a bill
0:27 we get the bill back and then we actually also get the user just like before. And typically there needs to be a proper relationship
0:35 between the user and the bill. So here's the test that we can write. I don't think it's going to run yet but create a request
0:41 when I create a test user and a test bill and importantly we are going to set the user_id to be the bill_id
0:49 and then we're going to need to patch two bits both the repository for getting the user and getting the bill.
0:54 And we're going to return these mock users and next test bill and then we can do our with clause and all of our mocks here
1:01 and create our bills details of view model should be no errors. It should be a user. There should be a bill. Okay, so we'd run that one.
1:09 That would be nice. We also have our tests that there's a possibility of not having a bill. So if I come back here
1:16 if we enter a URL that goes to a bill_id and the bill_id doesn't exist well, we're going to try to do a query for it and we're going to get None.
1:25 We want to make sure that the right error message rather than a crash is handled at the detail view model. So here we're going to come in
1:32 and get all this. It's going to try to get the bill for id 200. Notice we're actually setting the dictionary that it uses off the request
1:39 and it's going to come back and say "No, no, there's an error." And the error is the bill with id 200 was not found.
1:45 Okay. And then we also want to check if there's no user. If we're going to return None for the user a user with an id is not found.
1:52 We saw that error before. And then finally this one is a security test that if we go and try to request a bill as a logged in user
2:01 but it's not our bill, it's another one. We've gone to the URL and we typed in some random number or URL.
2:06 We don't want that still to just show it to us. Just the fact there is a user and there's a bill that's not enough. So we're going to come down here
2:13 and we're going to say the bill that we're looking for does not belong to this user belongs to another one. What should happen then?
2:20 Or we should get an error to say "No, no, no, that bill doesn't belong to you. "You can't see it here." Alright? It does not belong to the user.
2:28 It also should None out empty out the bill here so that there's no accidental case that we accidentally show it to them.
2:36 This will trigger a view to do a 404. Let's run it and see how we're doing. Not so well. Let's expand this out and see what we get here.
2:44 So we have these three tests none of which are passing yet. So we come down here to this line it says we got None here for the error
2:53 and we thought it wouldn't be none. So let's make sure that we're doing this test to say that they're not found. So are we checking to see
3:00 if there's no bill that generate an error message And look at that, we're not. So we need to add more validation to our bill details view model.
3:09 So we'll say this so we don't have a user. We'll say the error, something like this the user with id whatever it is not found.
3:18 And we want something similar. Say elif not bill bill with id such and such was not found. Here we go. All right, so now we're down
3:27 to just one test that doesn't work and that is right there. But we said we would like if somebody tries to request a bill which does not belong to them
3:39 they should be some kind of security leak seen other people's bills and data and so on. That's bad. Well, there was no error
3:45 but it said there should have been an error. So let's go and do one final test here and we'll say if self.user.id is not equal to bill.user_id.
3:58 And what error message are we looking for? The bill is not belong to the user we'll say something like that, okay?
4:03 So our unit tests were able to uncover some security issues that we are now hopefully able to fix. Now the other error right here
4:13 is saying, well, there was an error and probably it says that but you still pass the bill back and if the view's not really careful
4:20 it's going to try to show that bill to the user. So that means we've got to do one more thing back here. So if self.bill equals None, okay.
4:27 If you try to request a bill and there's a security issue, get rid of it. That's it, Tada! All of our test run.
4:33 So there we have all of our view model tests written and working over here. So you can see they all follow this general pattern
4:40 arrange . We typically have to patch out access to things like the database interact with the view model and then assert the right things.
4:49 What's beautiful about this is we didn't have to go and rewrite our views back to default. We've just now made this method more secure
4:58 and have better error reporting without touching it. We only changed their bill details of view model and now it no longer lets users request bills
5:06 that don't belong to them, for example. So I think we're going to put the view models to rest and call them good.
5:12 And we have two more levels of test to write. But there'll be much quicker. We want to call these function as view tests.
5:17 And we also want to send requests entirely through the entire application through the routing through pyramid into these methods and back
5:24 using functional tests.


Talk Python's Mastodon Michael Kennedy's Mastodon