7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
FREELessons: 17Length: 2.7 hours

Next lesson playing in 5 seconds

  • Overview
  • Transcript

2.1 The Signup Process, Part 1

To start off with the application, we need to provide a mechanism for users to resort to in order to sign themselves up. That way we'll have some meaningful data to work with. So let's start by creating a new folder structure. And for the sake of simplicity, I'm going to type in the bundle jump command and I'll give it a name. I'll call this api because we want this to be the server that should take all incoming requests. So let's go inside and start to think how we should approach this. Let's open the editor really quick and browse the file system. We have a bin directory with a consult and set-up tasks. These are part of the bundler's standard setup don't worry about them just yet. We have the lib directory which is the most important one. It has the version and the api class, per se. Then we have the test directory with a minitest_helper and the first test. You can see that this is a standard minitest class so this is just to string things out in regards to testing. The gemspec is also here it has a Gemfile and a Rakefile these are the most important ones. Let's open the Rakefile really quick and you can see that we don't have any specific task for testing. So let's try and type in bundle exec rake- T to see all of the tasks that have so far. You can see that we only have three and none of them require testing, this is pretty odd. Let's try and type in the rake test command. If I press Enter there, you will that it really doesn't work, nothing shows up. This test should be running, however, it is not. So what we will do is, we're gonna provide our own test task. So we're going to type in require rake/testtask and create our task. There you can see our brand new task task with the following pattern. All of the ruby files that end with underscore test, under the test directory will be tested. We are also going to include the test folder in order to include the mini-test helper. So instead of this, I'm going to change this back to test_helper. I just like it a lot better and this one should be api_test instead of the other way around. Okay, let's see if this works. Let's type in the rake-50 command to see if the test task is there and it is. Now, we can safely run the test command and that test is going to run. There you go, you can see that mini test helper file isn't there. Well of course, we'll need to change this back to a test helper. Let's save and run this again. And there you go we have eight different errors this time. So what is the next step that we should do? Well, in order to have many tests working, we'll need a habit. So we'll type in gem, many tests and we'll type in the required instruction called minitest/autorun. Okay, let's type in the bundled command to have that installed. We should wait a while. [BLANK_AUDIO] Okay, now that minitest is up and running we can run the test suite and there you we have one filled assertion. No message was given. This is part of the api test if we turn this back to true then the tests will pass, there you go. Okay, so our test read is now running. Let's take out the test helper one more time so that we make sure we have nothing missing. And it seems that there is something that we should be doing. We should be typing something in these terms, requiring bundler first and then bundler.require. This way we should be requiring all of the gems inside the gem file, that way we won't miss anything. Let's run the test suite again and there you go, it still works. From here, we should be testing the signup process. The bootstrapping is done. Let's focus on the next step. I'm going to create a services folder and inside I'm going to create a signup test. From here, we should require the test helper and pick it up from here. I'll type in the describe block since I'm going to use mini task spec. So, I'm going to describe a signup class, this signup service will be responsible for turning in some data, namely the user name and the password. And take care of the entire process of signing the user up persisting it in the database. So, I'm going to paste in a snippet of code which already contains some tests. So here we go, I have a service reader here which is going to match this service instance variable which is an instance of signup. By the way, the signup class will belong to api double colon services, a specific module to act as a name space. So before each test we're going to fill in service.all. Finally, we have the set of test. I'm going to assert that service encrypts the password. Meaning that we should have a password that's encrypted then we are not going to allow the password to be sent again so the password should be set to nil so that no one takes a look. [BLANK_AUDIO] We'll have an ID for the user meaning that we will persist it in a database with a timestamp. And finally, we are going to assert that the service returns an okay status, that's the gist of it. There are lots of different things that we should take into consideration as well. Some of them regard bootstrapping and others regard persistence. So I'm gonna go to the gem file and add in an extra couple checks. The first one is active record and the other one is database cleaner. Oh, by the way, let's just take care of adding pri as well. Namely the pri by bug gem this is pretty good for debugging purposes, we'll definitely take advantage of that. With this, we can safely type the bundle command in order to install all of these missing dependencies. So let's wait a little bit until all of those gems are effectively installed. Okay, let's move on. On our exercise, I'm going to clear the gem file for now. And on the other hand, want you go to the test helper and load all of those dependencies and configure them. Namely, the database cleaner so we'll use DatabaseCleaner.strategy equals truncation. After setting up the strategy for DatabaseCleaner, we should create something like this. Extend the MiniTest Spec class in order to include these hooks before running each test, we'd run the start command and at the end of the test we clean the database. By using truncation, we will clean all of the data that was inserted in that specific test. So, let's save now and run the test suite again. We can see that we don't have ORM activated and this comes from database cleaner. It means that we need to create an active record instruction in order to establish a connection with the database. We can do that right away. Let's type in ActiveRecord::Base.establish_connection. Okay, from here we should provide a set of instructions to connect to a test database. We'll use the adapter called sqlite so let's do that. Or either sqlite3 and then the database should be enough. So we'll use db/test.sqlite3. Let's see if this works now. I'm going to run the test of it again and this time you can see that active record is not initialized. Let's take a look at the gem file first and try and require a different thing because active record demands that we require active record likes so. Oh, let me just add in the colon sign. Run the bundle command again, there you go. Now, run the test suite. Okay, this is great news. Now, what we're missing is the actual signup class, the one that belongs to us. So, the bootstrapping phase seems to be over. Let's go ahead to our tests. It requires a signup class which I'll do straight into the lib directory under api, I'll create a folder called services and inside, a signup class so signup.rb. Let's open it in a new tab and define that class so under the api module, double colon services. I'll create the class called signup. Let's see if this works now, I'm going to run the tests and most likely, the class still won't be available. Well, let's take the chance and open the actual api class under the lib directory and require that straightaway. So, api/services/signup, this way when we load the entire test suite, this fill will already be available. Printing the tests now, you will see that all of them will fail. Because we are providing the wrong number of arguments for that signup class. Okay, let's take a look at the tests once again. They are assuming that we need at least one argument but the signup class takes just one. Let me open that really quick. So there you go. Let's open it on the side and you can see that we have no initialized method that takes more than one argument. We want an email and also a password but remember that since we are using this notation we should provide a default value. So I'm going to provide something like me@example.com. And also a password which should be, I don't know, blank password. Remember this is just a placeholder for those two variables so you can change those two however you like. You can even pass the nil if you want to. For the initialized method, we're going to store the email and the password. This looks good, we're following the protocol that we established in the tests, so now the next step is to run the test again. Now the error that we're facing is the call method being at the find. Let's do that, let's create that call method really quick and now we can safely run the test command. And this time we have an error that's different here and also here. So, for most part of the tests, the user method is not defined. In this specific case it's the status. So we'll create attr_reader methods for all of these attributes. So attr_reader forward to email, the user and the status. For obvious reasons, I'm not going to make the password public but I can go ahead and use the call method now and we should have different expectations. Okay, for one thing you can see that this one is expecting ok but we got nil. But the remaining ones are asking for many different methods, the password created at and ID. This is turning quite out of hand with all of these tests. So what I'm gonna do here is I'm going to skip all of the remaining tests and focus on a single one, the one that encrypts the password. So, with this I'm gonna go ahead save and re-run the tests. We should now have only one task that's failing and that is the encrypted password. We don't have that method in because we still need to define that encrypted password variable. And then, we should have something that turns the encrypted password variable into something else. So, encrypted password should be something that we are still yet to determine. If I type in nil like this and run the tests we will get an expectation error. Oh, still we don't have that encrypted password. Well, that's because if you pay close attention to the test you will see that we are requiring the encrypted password from the user not the service. So, I'm going to just delete this It's not necessary at all. So, we are going to use the encrypted password method here and then call something like user.encrypted password is that encrypted password, there you go. And finally, we'll just call user.save and don't forget to type in something like user equals user.new. This new user should take that email first so the email would be the contents of our email instance variable. Then we can actually go ahead and delete this sentence and pass the encrypted password like this. I'm going to finish this off by typing digest SHA1.hexdigest and then a specific password. So we should take our own password as an example and from here we should have a proper encrypted password. Let's do that. Let's run the tests and now you can see that we are missing a user class. Well, that's because we introduced a new dependency, the user class. So let's take care of creating that user class right away. Let's type in the models folder inside the api folder and then the user .rp file. Open it in a new tab and type in class user, inheriting from active record base. Now let's see, let's go ahead and require that from the general api file, so api models and then user. And from here, we are going to have a problem regarding the database. You will see that the user's table isn't there. Well, how do we accomplish this? Learn about how to solve this issue in part two. Jump right into the next lesson.

Back to the top