Skip to content

Commit

Permalink
Make a basic User model (including secure passwords)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardjortega committed Mar 3, 2012
1 parent b01c900 commit b46d5c4
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 16 deletions.
1 change: 1 addition & 0 deletions Gemfile
@@ -1,6 +1,7 @@
source 'https://rubygems.org'

gem 'rails', '3.2.1'
gem 'bcrypt-ruby', '3.0.1'

group :development, :test do
gem 'sqlite3', '1.3.5'
Expand Down
2 changes: 2 additions & 0 deletions Gemfile.lock
Expand Up @@ -30,6 +30,7 @@ GEM
multi_json (~> 1.0)
annotate (2.4.1.beta1)
arel (3.0.0)
bcrypt-ruby (3.0.1)
builder (3.0.0)
capybara (1.1.2)
mime-types (>= 1.16)
Expand Down Expand Up @@ -151,6 +152,7 @@ PLATFORMS

DEPENDENCIES
annotate (~> 2.4.1.beta)
bcrypt-ruby (= 3.0.1)
capybara (= 1.1.2)
coffee-rails (= 3.2.2)
growl
Expand Down
9 changes: 6 additions & 3 deletions app/models/user.rb
Expand Up @@ -10,8 +10,11 @@
#

class User < ActiveRecord::Base
attr_accessible :name, :email
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password

validates :name, presence: true
validates :email, presence: true
validates :name, presence: true, length: { maximum: 50 }
valid_email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: valid_email_regex }, uniqueness: { case_sensitive: false }
validates :password, length: { minimum: 6 }
end
5 changes: 5 additions & 0 deletions db/migrate/20120303190805_add_index_to_users_email.rb
@@ -0,0 +1,5 @@
class AddIndexToUsersEmail < ActiveRecord::Migration
def change
add_index :users, :email, unique: true
end
end
5 changes: 5 additions & 0 deletions db/migrate/20120303192215_add_password_digest_to_users.rb
@@ -0,0 +1,5 @@
class AddPasswordDigestToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
9 changes: 6 additions & 3 deletions db/schema.rb
Expand Up @@ -11,13 +11,16 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20120302015336) do
ActiveRecord::Schema.define(:version => 20120303192215) do

create_table "users", :force => true do |t|
t.string "name"
t.string "email"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "password_digest"
end

add_index "users", ["email"], :name => "index_users_on_email", :unique => true

end
87 changes: 77 additions & 10 deletions spec/models/user_spec.rb
Expand Up @@ -14,23 +14,90 @@
describe User do

before do
@user = User.new(name: "Example User", email: "user@example.com")
@user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar")
end

subject { @user }

it { should respond_to(:name) }
it { should respond_to(:email) }
it { should respond_to(:password_digest) }
it { should respond_to(:password) }
it { should respond_to(:password_confirmation) }
it { should respond_to(:authenticate) }

it { should be_valid }
it { should be_valid }

describe "when name is not present" do
before { @user.name = " " }
it { should_not be_valid }
end
describe "when name is not present" do
before { @user.name = " " }
it { should_not be_valid }
end

describe "when email is not present" do
before { @user.email = " " }
it { should_not be_valid }
end

describe "when name is too long" do
before { @user.name = "a" * 51 }
it { should_not be_valid }
end

describe "when email format is invalid" do
invalid_addresses = %w[user@foo.com user_at_foo.org example.user@foo.]
invalid_addresses.each do |invalid_address|
before { @user.email = invalid_address }
it { should_not be_valid }
end
end

describe "when email format is valid" do
valid_addresses = %w[user@foo.com A_USER@f.b.org frst.lst@foo.jp a+b@baz.cn]
valid_addresses.each do |valid_address|
before { @user.email = valid_address }
it { should be_valid }
end
end

describe "when email address is already taken" do
before do
user_with_same_email = @user.dup
user_with_same_email.email = @user.email.upcase
user_with_same_email.save
end
it { should_not be_valid }
end

describe "when password is not present" do
before { @user.password = @user.password_confirmation = " " }
it { should_not be_valid }
end

describe "when password doesn't match confirmation" do
before { @user.password_confirmation = "mismatch" }
it { should_not be_valid }
end

describe "return value of authenticate method" do
before { @user.save }
let(:found_user) { User.find_by_email(@user.email) }

describe "with valid password" do
it { should == found_user.authenticate(@user.password) }
end

describe "with invalid password" do
let(:user_for_invalid_password) { found_user.authenticate("invalid") }

it { should_not == user_for_invalid_password }
specify { user_for_invalid_password.should be_false }
end
end

describe "with a password that's too short" do
before { @user.password = @user.password_confirmation = "a" * 5 }
it { should be_invalid }
end


describe "when email is not present" do
before { @user.email = " " }
it { should_not be_valid }
end
end

0 comments on commit b46d5c4

Please sign in to comment.