Skip to content

Commit ce09b2c

Browse files
committed
Make a basic user model (including secure password)
1 parent fdebb5d commit ce09b2c

File tree

7 files changed

+171
-0
lines changed

7 files changed

+171
-0
lines changed

app/models/user.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class User < ActiveRecord::Base
2+
before_save { self.email = email.downcase }
3+
validates :name, presence: true, length: { maximum: 50 }
4+
validates :biography, presence: true
5+
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
6+
validates :email, presence: true,
7+
format: { with: VALID_EMAIL_REGEX },
8+
uniqueness: { case_sensitive: false }
9+
has_secure_password
10+
validates :password, length: { minimum: 6 }
11+
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class CreateUsers < ActiveRecord::Migration
2+
def change
3+
create_table :users do |t|
4+
t.string :name
5+
t.string :email
6+
t.string :biography
7+
8+
t.timestamps
9+
end
10+
end
11+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddIndexToUsersEmail < ActiveRecord::Migration
2+
def change
3+
add_index :users, :email, unique: true
4+
end
5+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddPasswordDigestToUsers < ActiveRecord::Migration
2+
def change
3+
add_column :users, :password_digest, :string
4+
end
5+
end

db/schema.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# encoding: UTF-8
2+
# This file is auto-generated from the current state of the database. Instead
3+
# of editing this file, please use the migrations feature of Active Record to
4+
# incrementally modify your database, and then regenerate this schema definition.
5+
#
6+
# Note that this schema.rb definition is the authoritative source for your
7+
# database schema. If you need to create the application database on another
8+
# system, you should be using db:schema:load, not running all the migrations
9+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
10+
# you'll amass, the slower it'll run and the greater likelihood for issues).
11+
#
12+
# It's strongly recommended that you check this file into your version control system.
13+
14+
ActiveRecord::Schema.define(version: 20140913155807) do
15+
16+
create_table "users", force: true do |t|
17+
t.string "name"
18+
t.string "email"
19+
t.string "biography"
20+
t.datetime "created_at"
21+
t.datetime "updated_at"
22+
t.string "password_digest"
23+
end
24+
25+
add_index "users", ["email"], name: "index_users_on_email", unique: true
26+
27+
end

spec/factories/users.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Read about factories at https://github.com/thoughtbot/factory_girl
2+
3+
FactoryGirl.define do
4+
factory :user do
5+
name "MyString"
6+
email "MyString"
7+
biography "MyString"
8+
end
9+
end

spec/models/user_spec.rb

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
require 'spec_helper'
2+
3+
describe User do
4+
5+
before { @user = User.new(name: "Example User", email: "user@example.com", biography: 'biography example',
6+
password: "foobar", password_confirmation: "foobar") }
7+
8+
subject { @user }
9+
10+
it { should respond_to(:name) }
11+
it { should respond_to(:email) }
12+
it { should respond_to(:biography) }
13+
it { should respond_to(:password_digest) }
14+
it { should respond_to(:password) }
15+
it { should respond_to(:password_confirmation) }
16+
it { should respond_to(:authenticate) }
17+
18+
it { should be_valid }
19+
20+
describe "when name is not present" do
21+
before { @user.name = " " }
22+
it { should_not be_valid }
23+
end
24+
25+
describe "when email is not present" do
26+
before { @user.email = " " }
27+
it { should_not be_valid }
28+
end
29+
30+
describe "when biography is not present" do
31+
before { @user.biography = " " }
32+
it { should_not be_valid }
33+
end
34+
35+
describe "when name is too long" do
36+
before { @user.name = "a" * 51 }
37+
it { should_not be_valid }
38+
end
39+
40+
describe "when email format is invalid" do
41+
it "should be invalid" do
42+
addresses = %w[user@foo,com user_at_foo.org example.user@foo.
43+
foo@bar_baz.com foo@bar+baz.com]
44+
addresses.each do |invalid_address|
45+
@user.email = invalid_address
46+
expect(@user).not_to be_valid
47+
end
48+
end
49+
end
50+
51+
describe "when email format is valid" do
52+
it "should be valid" do
53+
addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
54+
addresses.each do |valid_address|
55+
@user.email = valid_address
56+
expect(@user).to be_valid
57+
end
58+
end
59+
end
60+
61+
describe "when email address is already taken" do
62+
before do
63+
user_with_same_email = @user.dup
64+
user_with_same_email.save
65+
end
66+
67+
it { should_not be_valid }
68+
end
69+
70+
describe "when password is not present" do
71+
before do
72+
@user = User.new(name: "Example User", email: "user@example.com",
73+
password: " ", password_confirmation: " ")
74+
end
75+
it { should_not be_valid }
76+
end
77+
78+
describe "when password doesn't match confirmation" do
79+
before { @user.password_confirmation = "mismatch" }
80+
it { should_not be_valid }
81+
end
82+
83+
describe "with a password that's too short" do
84+
before { @user.password = @user.password_confirmation = "a" * 5 }
85+
it { should be_invalid }
86+
end
87+
88+
describe "return value of authenticate method" do
89+
before { @user.save }
90+
let(:found_user) { User.find_by(email: @user.email) }
91+
92+
describe "with valid password" do
93+
it { should eq found_user.authenticate(@user.password) }
94+
end
95+
96+
describe "with invalid password" do
97+
let(:user_for_invalid_password) { found_user.authenticate("invalid") }
98+
99+
it { should_not eq user_for_invalid_password }
100+
specify { expect(user_for_invalid_password).to be_false }
101+
end
102+
end
103+
end

0 commit comments

Comments
 (0)