Creating User

Since this is an new issue and we are using git let us create an new branch

1
$ git checkout -b create-user origin/master

Now let us start working

Setting up our test gem

Since our development will test driven let us setup test frameworks that is:

  • RSpec-rails(this specific rspec meant for usage in rails)

  • cucumber

Kindly note add only the highlighted content in a file when editing an existing file, when file is newly created then add everything

Setting up RSpec-rails

RSpec-rails

On the Gemfile add rspec-rails gem like so:

Gemfile

1
2
3
4
5
6
7
#some contents above this
group :development, :test do
  gem 'rspec-rails'
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
#some contents below this

The bundle to pull it into your project

1
$ bundle install

Generate rspec file by running this command

1
2
3
4
5
$  rails generate rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

Let us ensure rspec will always give friendly result by adding this to .rspec file

.rspec

1
2
3
--require spec_helper
--color
--format documentation

Setting up shoulda matchers and factoryBot

Take tour of shoulda mathcers and FactoryBot Rails

On the Gemfile add shoulda-matchers and factory_bot_rails gems like so:

Gemfile

1
2
3
4
5
6
# some contents above this
group :development, :test do
  gem 'shoulda-matchers'  
  gem 'factory_bot_rails'
end
# some contents below

The bundle to pull them into your project

1
$ bundle

Create spec/support/shoulda_matchers.rb file like so:

1
$ mkdir spec/support &&  touch spec/support/shoulda_matchers.rb

Inside shoulda_matchers.rb file add the following:

spec/support/shoulda_matchers.rb

1
2
3
4
5
6
7
8
9
Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end
RSpec.configure do |config|
  config.include(Shoulda::Matchers::ActiveRecord, type: :model)
end

Inside factory_bot.rb file add the following:

1
$ touch spec/support/factory_bot.rb

spec/support/factory_bot.rb

1
2
3
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

On rails_helper.rb file add the following:

spec/rails_helper.rb

1
2
3
4
5
6
7
# some content above this
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'support/factory_bot.rb'
require 'support/shoulda_matchers.rb'

# truncatated for brevity

setting up cucumber

cucumber-rails

1
2
3
4
5
group :development, :test do
  gem 'cucumber-rails', require: false
  # database_cleaner is not required, but highly recommended
  gem 'database_cleaner'
end
1
$ bundle
1
$ rails generate cucumber:install

We are done with test setup, let us commit this

1
2
$ git add .
$ git commit -m "setup test gems"

Generating User

1
2
3
4
5
6
7
8
$ rails g model User first_name:string last_name:string id_number:string phone_number:string pin:string balance:float password:string
      invoke  active_record
      create    db/migrate/20191230155230_create_users.rb
      create    app/models/user.rb
      invoke    rspec
      create      spec/models/user_spec.rb
      invoke      factory_bot
      create        spec/factories/users.rb
1
2
3
4
5
$  rails db:migrate
== 20191230151728 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.3963s
== 20191230151728 CreateUsers: migrated (0.3963s) =============================

spec/models/user_spec.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
require 'rails_helper'
RSpec.describe User, type: :model 
  describe '#user table column' do
    it { is_expected.to have_db_column :id }
    it { is_expected.to have_db_column :first_name }
    it { is_expected.to have_db_column :last_name }
    it { is_expected.to have_db_column :phone_number }
    it { is_expected.to have_db_column :pin }
    it { is_expected.to have_db_column :id_number }
    it { is_expected.to have_db_column :balance}   
  end
end

User validations

We expect all the attributes not to be null i.e they must be given for user to be created.

Let start by ensuring no attribute is null

spec/models/user_spec.rb

1
2
3
4
5
6
7
8
9
  # truncated for brevity
  describe '#validation of user attributes' do
    it { is_expected.to validate_presence_of(:first_name) }
    it { is_expected.to validate_presence_of(:last_name) }
    it { is_expected.to validate_presence_of(:id_number) }
    it { is_expected.to validate_presence_of(:phone_number) }
    it { is_expected.to validate_presence_of(:password) }
  end
  # truncated for brevity
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ rspec
Failures:

  1) User#validation of user attributes is expected to validate that :first_name cannot be empty/falsy
     Failure/Error: it { is_expected.to validate_presence_of(:first_name) }

       Expected User to validate that :first_name cannot be empty/falsy, but
       this could not be proved.
         After setting :first_name to ‹""›, the matcher expected the User to be
         invalid, but it was valid instead.
     # ./spec/models/user_spec.rb:14:in `block (3 levels) in <top (required)>'

  2) User#validation of user attributes is expected to validate that :last_name cannot be empty/falsy
     Failure/Error: it { is_expected.to validate_presence_of(:last_name) }

       Expected User to validate that :last_name cannot be empty/falsy, but
       this could not be proved.
         After setting :last_name to ‹""›, the matcher expected the User to be
         invalid, but it was valid instead.
     # ./spec/models/user_spec.rb:15:in `block (3 levels) in <top (required)>'

  3) User#validation of user attributes is expected to validate that :pin cannot be empty/falsy
     Failure/Error: it { is_expected.to validate_presence_of(:pin) }

       Expected User to validate that :pin cannot be empty/falsy, but this
       could not be proved.
         After setting :pin to ‹nil›, the matcher expected the User to be
         invalid, but it was valid instead.
     # ./spec/models/user_spec.rb:16:in `block (3 levels) in <top (required)>'

  4) User#validation of user attributes is expected to validate that :pin cannot be empty/falsy
     Failure/Error: it { is_expected.to validate_presence_of(:pin) }

       Expected User to validate that :pin cannot be empty/falsy, but this
       could not be proved.
         After setting :pin to ‹nil›, the matcher expected the User to be
         invalid, but it was valid instead.
     # ./spec/models/user_spec.rb:17:in `block (3 levels) in <top (required)>'

  5) User#validation of user attributes is expected to validate that :password cannot be empty/falsy
     Failure/Error: it { is_expected.to validate_presence_of(:password) }

       Expected User to validate that :password cannot be empty/falsy, but this
       could not be proved.
         After setting :password to ‹""›, the matcher expected the User to be
         invalid, but it was valid instead.
     # ./spec/models/user_spec.rb:18:in `block (3 levels) in <top (required)>'

There are failures means our database will create user even if the field are null.Let us prevent that

model/user.b

1
2
3
4
5
6
7
class User < ApplicationRecord
  validates :first_name, presence: true
  validates :last_name, presence: true
  validates :phone_number, presence: true 
  validates :id_number, presence: true
  validates :password, presence: true
end

Take tour at active record validation for more.

run

1
$ rspec

Everything is green

Exercise

Ensure these expectations are met:

  • We expect pin to be an integer of 4 digits
  • We expect phone_number and id_number to be unique
  • we expect first_name and last name to be at most 30 characters and should not be a digit
  • we expect password to be atleast 8 characters with atleast a special character, capital letter, small letter and a digit
  • we expect id_number to atleast 7 digits and at most 9 digits
  • we expect phone_number atleast 10 characters and most 13 characters
  • we expect phone_number to accept only digit characters for now

Kindly write tests first the call the tutor when you done with tests

shoulda mathcers is your friend here. Kindly put your test in existing '#validation of user attributes' describe block

Database Constraints

Everything is green but we need to ask ourselves is our database safe?, By safety I mean its integrity my personal belief which I believe is universal database is as good as it's integrity. With that in mind what if an indivual directly create user with passing the model, let us say through maybe through sql command.

Let ensure database won't accept user with any of attributes null or empty to be created

spec/models/user_spec.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
describe '#validation of user attributes' do
    # truncatated for brevity
  it "raise database error when user attributes are null" do
      valid_user_attrs = { first_name: "Jane", last_name: "Doe", id_number: 1234567, phone_number: "0700000000", pin: 1234, password: "[email protected]"}
      user_without_first_name_attr =   valid_user_attrs.slice(:last_name,:id_number,:phone_number, :pin, :password)
      user_without_first_name = User.new(user_without_first_name_attr)
      expect { user_without_first_name.save!(validate: false)}.to raise_error(ActiveRecord::NotNullViolation)
      user_without_last_name_attr =   valid_user_attrs.slice(:first_name,:id_number,:phone_number, :pin, :password)
      user_without_last_name = User.new(user_without_last_name_attr)
      expect { user_without_last_name.save!(validate: false)}.to raise_error(ActiveRecord::NotNullViolation)
    end
end

In your create_user migration file i.e 20191222165225_create_users.rb kindly note the digit part of the file may vary depending on time you generated you generated your User model.Add this:

db/migrate/20191222165225_create_users.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :first_name, null: false
      t.string :last_name, null: false
      t.float :balance, null: false, default: 0.0 

      t.timestamps
    end
  end
end

Note the usage of default: 0.0 on balance column, this ensure that when user is created he or she has a balance of 0.0.

To update our schema with changes we to migrate but no new migration have been generation so even we migrate this changes won't be reflected on our schema.

To solve we can rollback and the migrate again:

1
$ rails db:rollback
1
$ rails db:migrate

Now run:

1
$ rspec

It is green again

Kindly note: It is always advice to generate new migration when you add any new changes if database is production or if you working on project with others to avoid collision and data loss

Exercise

  1. Ensure user cannot be created at db level when:

    • id_number is empty
    • phone_number is empty
  2. Make pin to have default value of "1234" at db level

  3. Give the user ability to confirm the password

Testing User Creation

We will test if our user is succefully created if attributes meets our validation requirements(the happy path) and not created if attributes are invalid(sad path)

Let us start with happy path.

With will use factories to do test avoid repeating ourselves Tour factory_bot_rails

Let test that the user we are creating is valid

spec/model/user.rb

1
2
3
4
5
6
7
require 'rails_helper'

RSpec.describe User, type: :model do
  it 'should have valid Factory' do
  expect(FactoryBot.create(:user)).to be_valid
end
# truncated for brevity

On running rspec it fails well the reason might be our user factory.

Let us modify the spec/factories/user.rb to meet our validation requirements as we will use for test

spec/factories/user.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
FactoryBot.define do
  factory :user do
    first_name { "John" }
    last_name { "Doe" }
    id_number { "12345678" }
    phone_number { "070000000000" }
    password { "VeryStrong.123#" }
    password_confirmation{"VeryStrong.123#"}
  end
end

Run rspec again, and there it is green again.

Now let us test that user is created with attributes we passed, and default values of pin and balance are 1234 and 0.0 respectively

spec/model/user.rb

1
2
3
4
5
6
7
8
9
#truncated for brevity
  describe "#creating user" do
    it 'creates user with valid attributes' do
      user = FactoryBot.create(:user) # we create user , insert him on the database
      expect(user.first_name).to eq 'John' # we ensure his name is John since that is what is in the factory
      expect(user.balance).to eq 0.0 # we assert that the user created has a balance of 0.0 remember default value of balance is 0.0
      expect(user.pin).to eq 1234 # we assert that the pin for user created is 1234
    end
  end

Run the test and there we see green

Our is good to go if attributes are valid.What of the sad path i.e what if user has invalid attribute for instance we expect phone_number to be unique, characters of 7 to 9 digits what any of this are not met?. We must ensure that the user is not created in any the above conditions.

These conditions are phone_number given:

  • belong to a user who already exist in our database(unique id number)

  • is not compose of only digits

  • has characters of digits less than 10

  • has characters of digits greater than 13

Let us start by testing already existing phone_number:

spec/model/user.b

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  describe "#creating user" do
    # truncated for brevity
    it "do not allow existing phone number" do
      FactoryBot.create(:user) # we create user
      user = FactoryBot.build(:user, phone_number:  "070000000000", id_number: "0000000") # we build a ?# user factory with existing phone number
      user.save # we save the factory
      expect(user).not_to be_valid # we test that it is not valid
      expect(user.errors.messages[:phone_number]).to eq ["has already been taken"] # we test that error we get from phone number is "["has already been taken"]"
    end
  end

Now let us test that when phone number is not a digit, it not created an it produces and error message

spec/model/user.b

1
2
3
4
5
6
7
8
9
  describe "#creating user" do
    # truncated for brevity
    it "do not allow phone number that is not digit" do
          user = FactoryBot.build(:user, phone_number: "abc12345679") # we build factory for user with non-digit only phone number
          user.save    # save the factory
          expect(user).not_to be_valid # we test that it is not valid
          expect(user.errors.messages[:phone_number]).to eq ["is not a number"] # # we test that error we get from phone number is "["is not a number"]"
    end
  end

Now let us test that when phone number length is less than 10, it not created an it produces and error message

spec/model/user.b

1
2
3
4
5
6
7
8
describe "#creating user" do
    # truncated for brevity
    it "do not allow phone number that are less than 10" do
        user = FactoryBot.build(:user, phone_number: "12345678")
        user.save        
        expect(user.errors.messages[:phone_number]).to eq ["is too short (minimum is 10 characters)"]
    end
end

Now let us test that when phone number length is greater than 13, it not created an it produces and error message

spec/model/user.b

1
2
3
4
5
6
7
8
describe "#creating user" do
  # truncated for brevity
  it "do not allow phone number that is greater than 13" do
        user = FactoryBot.build(:user, phone_number: "12345678910112221")
        user.save
        expect(user.errors.messages[:phone_number]).to eq ["is too long (maximum is 13 characters)"]
  end
end

Exercise

  • Test that when user is created with id_number which is less than 7 digits it will fail and produce an error,also test this error message
  • Test that when user is created with id_number which more than 9 digits it will fail and produce an error, also test this error message
  • Test that when user is created with id_number which is not digits it will fail and produce an error, also test this error message

  • Test that when user is created with id_number which already exists it will fail and produce an error, also test this error message

  • Test that when user is created with password which is less than 8 characters it will and produce an error, also test this error message
  • Test that when user is created with password which is 8 or more characters but has no digit it will and produce an error, also test this error message
  • Test that when user is created with password which is 8 or more characters but has no uppercase letter it will fail and produce an error, also test this error message
  • Test that when user is created with password which is 8 or more characters but has no lowercase it will fail and produce an error, also test this error message
  • Test that when user is created with password which is 8 or more characters but has no special character it will fail and produce an error, also test this error message
  • Test that when user is created with password_confirmation do not match password it will fail and produce an error, also test this error message

User's Perspective

The user the primary concern when build an application therefore his or her input is necessary.Let us build our application from their(Users) perspective.

We are going to use to cucumber which uses gherkin to achieve behavior driven development(bdd)

Our Feature is user sign up

When user is signup page or creating an account he or should something i.e a form with fields first name, last name e.t.c, Upon sucessfully signup will direct created user to a show page have their details. Let us test starting with happy path that is succesful signup

Create a file features/user/signup.feature add the following content to it

features/user/signup.feature

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Feature: User Sign Up
As a User
I want  so sign up
So that can have an account

Scenario: User successfully signup
Given I am on the signup page
Then I should see "First Name"
And I should see "Last Name"
And I should see "ID number"
And I should see "Phone Number"
And I should see "Password"
And I should see "Create Account" button
When I fill in "First Name" with "Jane"
And I fill in "Last Name" with "Doe"
And I fill in "ID Number" with "12345678"
And I fill in "Phone Number" with "070000000000"
And I fill in "Password" with "Stronger*than123Usual"
And I click Create Account
Then I shoud be redirect to show page
And I should see "First Name: Jane"
And I should see "Last Name: Doe"
And I should see "ID Number: 12345678"
And I should see "Phone Number: 070000000000"
And I should see "Pin: 1234"
And I should see "Balance: 0.0"
1
$ cucumber

On running cucumber you see undefined step failure.Let us reticfity that just below the failures there is suggestion on you can define your step.

cucumber steps

Copypaste the highlighted part into features/step_definitions/user.rb file

When run cucumber again, the first step (Given I am on the Sigup page) is pending

1
$ cucumber

Let us writing our steps definitions for sucessful user signup, we will use capybara (which comes shipped with cucumber) syntax On features/step_definitions/user.rb add these:

features/step_definitions/user.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Given("I am on the signup page") do
  visit 'users/new'
end

Then("I should see {string}") do |string|
  expect(page).to_have_content string
end

Then("I should see {string} button") do |string|
 expect(page).to have_button string
end

When("I fill in {string} with {string}") do |string, string2|
  fill_in string, with: string2
end

When("I click Create Account") do
  click_button('Create Account')
end

Then("I shoud be redirect to show page") do
  user = User.find_by(id_number: '12345678')
  user_id = user.id
  visit "/users/#{user_id}"
end

The first step visit route users/new which the sign up page.On that page we expect to see a form with neccessary e.g first_name,last_name e.t.c that's what second step is doing.On same page there is Create User button(step four) then fill the form with the neccessary data(step 5) and click the Create User button step(6).Last on step seven we are directed to the route users/:id which is the user show page. We use User.find_by(id_number: '12345678') because id_ number is unique and we specifically created user with that id_number in our scenario. find_by in this case returns a single user(our created user).We the user's id from the user object and use it to show this specific user.For more on find_by and other methods tour active_record

Let us run cuccumber again. We get No route matches [GET] "/users/new" (ActionController::RoutingError).This is because how step is visit an not exist route users/new with the get method.

Let us give our test what it want

We create this route.So on the file config/routes.rb.

config/routes.rb

1
2
3
4
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  get 'users/new', to: 'users#new', as: 'new_user'
end

We have created with pointing to UsersController and new action in the UserController

We run cucumber and again but error Change to uninitialized constant UsersController

Let us define our UsersController inside app/controller/users_controller.rb file

app/controller/users_controller.rb

1
2
3
class  UsersController < ApplicationController

end

On running the cucumber we get an error The action 'new' could not be found for UsersController (AbstractController::ActionNotFound).

Let us go ahead and do that, define the new action on UsersController like:

app/controller/users_controller.rb

1
2
3
4
class  UsersController < ApplicationController
  def new
  end
end

We try running cucumber again we get UsersController#new is missing a template for request formats: text/html (ActionController::MissingExactTemplate).

There is no template, create file app/views/users/new.html.erb

Run cucumber now our first step has the user is able visit signup page by now.

But the second step fails the page empty yet we expect to see a form with some attributes.Let us create this form.

app/views/users/new.html.erb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  <%= form_with scope: :user, url: new_user_path, local: true do |form| %>
  <p>
    <%= form.label :first_name %><br>
    <%= form.text_field :first_name %>
  </p>
  <p>
    <%= form.label :last_name %><br>
    <%= form.text_field :last_name %>
  </p>
  <p>
    <%= form.label :id_number %><br>
    <%= form.text_field :id_number %>
  </p>
  <p>
    <%= form.label :phone_number %><br>
    <%= form.text_field :phone_number %>
  </p>
  <p>
    <%= form.label :password %><br>
    <%= form.password_field :password %>
  </p>
  <p>
    <%= form.label :password_confirmation%><br>
    <%= form.password_field :password_confirmation %>
  </p>
  <p>
    <%= form.submit "Create Account" %>
  </p>
<% end %>

If your run cucumber again it fails but this time the error is No route matches [POST] "/users/new" (ActionController::RoutingError).

For more on routing check Rails Routing from the Outside In

So let create this route.Since it post method it will use create on the controller will create this as well.

config/routes.rb

1
2
3
4
5
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
 get '/users/new', to: 'users#new'
 post 'users/', to: 'users#create'
end

app/controllers/users_controller.rb

1
2
3
4
5
6
class  UsersController < ApplicationController
  def new
  end
  def create
  end
end

Edit the form_with line inside app/views/users/new.html.erb to look like this:

<%= form_with scope: :user, url: users_path, local: true do |form| %>

Run cucumber you an error which suggest that user was not created, undefined method 'id' for nil:NilClass (NoMethodError) therefore let us create it

app/controllers/users_controller.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class  UsersController < ApplicationController
  def new
  end
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to user_path(@user)
    else
      render 'new'
    end
  end

  private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :password, :password_confirmation, :phone_number, :id_number)
  end
end

Run the test again.

No route matches [GET] "/users/339" (ActionController::RoutingError)

Let us create the route and its corresponding controller action.

config/routes.rb

1
2
3
4
5
6
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
 get '/users/new', to: 'users#new'
 post 'users/', to: 'users#create'
 get 'users/:id', to: 'users#show', as: 'user'
end

app/controllers/users_controller.rb

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class  UsersController < ApplicationController
  def new
  end
  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to user_path(@user)
    else
      render 'new'
    end
  end
  def show
    @user = User.find(params[:id])
  end

  private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :password, :password_confirmation, :phone_number, :id_number)
  end
end

Run cucumber, the template is missing as suggest by the error UsersController#show is missing a template for request formats: text/html (ActionController::MissingExactTemplate)

Create file app/views/users/show.html.erb

Then run test.

The failure suggest template lacks the content we expect let us fill it with our expected content

app/views/users/show.html.erb*

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<p>
  <strong>First Name:</strong>
  <%= @user.first_name %>
</p>

<p>
  <strong>Last Name:</strong>
  <%= @user.last_name %>
</p>

<p>
  <strong>ID Number:</strong>
  <%= @user.id_number %>
</p>
<p>
  <strong>Phone Number:</strong>
  <%= @user.phone_number %>
</p>
<p>
  <strong>ID Number:</strong>
  <%= @user.id_number %>
</p>
<p>
  <strong>Pin:</strong>
  <%= @user.pin %>
</p>
<p>
  <strong>Balance:</strong>
  <%= @user.balance %>
</p>

Now run the test and every is green

Run your server

$ rails server

Now visit localhost:3000/users/new and try creating a new user.

Exercise

Using BDD test that, make sure you test that errors will be displays

To display errors refer to Displaying Validation Errors in Views

  1. User without first name won't be created

  2. User whose first name is alphabets but greater than 30 characters won't be created

  3. User whose first name contains non-alphabets characters won't be created

  4. User without last name won't be created

  5. User whose last name contains only aphalbet characters but greater than 30 characters won't be created

  6. User whose first name contains non-alphabet characters won't be created

  7. User without phone number won't be created

  8. User with phone number that already exist won't be created

  9. User whose phone number contains non-digit characters won't be created

  10. User whose phone number contains only digits but less than 10 characters won't be created

  11. User whose phone number contains only digits but more than 13 characters won't be created

  12. User with id number that already exist won't be created

  13. User whose id number contains non-digit characters won't be created

  14. User whose id number contains only digits but less than 7 characters won't be created

  15. User whose id number contains only digits but more than 9 characters won't be created

  16. User with invalid password won't be created

  17. User whose password and password confirmation do not match won't be created