Loading
Current section: Guides 6 exercises
solution

Exercise 02 (Solution)

Transcript

00:00 If you think about it, all the resources that we needed to test authentication, such as the users, verification codes, OTP tokens are already the test data. So my approach to creating a list of nodes for a given user will be no different. I will go to the dbutils file, the same file where we implemented helpers like createuser and createverification, and at the very bottom of it I will declare a new asynchronous function called createNodes. This function will accept an object argument that will consist of owner ID, which is the owner of the nodes that I am about to create, and the array of the nodes to create. Now here I would like to use the same typescript definitions as one would pass to the Prisma client when creating a bunch of notes.

00:43 To do that I can get the Prisma type and access notes create many input as the type. The problem with this type though is that itself, it will contain the owner ID property and it's required because every node must have an owner. But in my utility, I kinda don't wanna repeat myself. I already specifying the owner ID here at the root, and then I want every subsequent node to belong to this owner. So what I'm gonna do is I'm gonna use the emit helper in typescript and emit the owner ID property from my Prisma type.

01:14 So this way, my notes input will be consistent and align with the Prisma client but it won't repeat the owner ID for every individual node. Now to create the actual notes, I will call my prisoner client dot note dot create many and return and provide you the data key that will describe the notes. Here, I will iterate over args dot notes, unfolding every note and adding the owner ID to it through args owner ID. Notice that I used the createMany and return because by default Prisma doesn't return the created records when you use createMany. I will store all the notes in a variable called notes.

01:51 And I will make sure to return them from my utility function. And you probably already know where this is going because I am gonna make this returned object a disposable object so I am able to clear all of these nodes, just delete them once they are no longer needed. To do that, I will declare this symbol as sync dispose as an asynchronous function. And I will once again tap into my Prisma client where I'm gonna delete many nodes where owner ID is ARG's owner ID. Basically, wiping up all the nodes that belong to the user.

02:24 Now it's time to put this utility function to use. And to do that, I will head to my test file, notes list. Test. Ts. You can see that I already have some parts of the task scaffolded such as authentication and going to the user notes.

02:37 But before I do, I need to make sure that those notes actually exist in the database. Here is where this createNotes utility function comes in. So I'm gonna consume it as a disposable object, and here provide the owner ID, which will be my user from the session that's currently authenticated, .id, and for the notes, it'll be an area of objects. So I'll give the first note a title, first note, and content, oh, world. And I will create a second note called second note, very descriptive, with the content, goodbye, cosmos.

03:12 Now once I call this, I will have these notes created and associated with my user. And the only thing remaining is to make sure that they're visible in the UI. I already have the step that navigates to the user notes, so now let's find those notes in the UI by doing page get by role, find a list with accessible name nodes then inside that list find all the list items and inside every list item find elements by role link This will return a list of all the note links on the page. I will store it in a variable called notes and this will not be a promise because we remember that locators are already promises to elements. And now to write the assertion, I will say that I expect these notes to have text content, which is to have text, which will be an array.

04:04 These will be the text of the links of my notes. This will be first note and second note. Now I will run my tests to make sure that everything is alright. So I'll wait for the result here, creating the database and then creating the notes associated with the user and then looking them up in the UI. And it looks like the task is struggling to find something.

04:30 So let's see if it oh, it actually fails. And it fails on my assertion, so in my here, my expect statement to have text. Why is that so? So I can see that I am expecting a second note, but the actual content is second note. That is funny.

04:44 I think I just made a typo here. Yeah. Second note. So once I fix this typo, let's see what the test results will be then. That's much better.

04:58 Now the test is passing as I would expect. Now let's push this test a little further. Let's actually visit every node and make sure that it has the correct content. So after this expectation, I will click on the first note by doing notes dot find by text. So I'll get my text.

05:18 First note and then to click. Now I expect the page to load that note, so I will expect the page element by role heading that has the accessible name of my first note to be visible, and also that the content of this note is visible. I will locate the note area by role, actually by its label, by label text, that will say first note, and then the element by text, which is the note's content. And here, I'll provide hello world also to be visible. And because the user always sees the full list of their notes while viewing a detail of a particular note, all we have to do to test another note is just repeat this process.

06:02 We're gonna go to another link that says second note and has a different content. In this case, goodbye, customers. Again, let's run the tests and make sure that this note checking flow is actually functioning. And it does, which is awesome. So let's recap what we did here.

06:26 In our utilities we prepared a function called create notes that creates a list of notes for the given user by tapping into our Prisma client, basically creating database records, by giving us back those records, returning them for the test purposes, and also disposing of these notes by using the async dispose callback, disposable object API. Then in our tests, we are authenticating as the user persona, using this createNotes function to create the list of notes for the currently authenticated user, then we are going to view all those notes the same way the user would, locating them in the list of all links, the user note links, making sure that the list summary is correct, and then visiting individual notes, the first note and the second note, to make sure that the user is able to view them. Now I'm not gonna lie that being able to tap into Prisma as a part of your test or test utilities is really powerful, but you might not always have that kind of luxury. So if your backend logic is obstructed away from you, there are still other methods how to procure the test data. API mocking being one of the most viable solutions in that case and luckily we're gonna talk about it in more detail in this block.