Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RailsConf: Concerns #9

Open
wants to merge 2 commits into
base: railsconf-start
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions app/models/concerns/emailable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Emailable
extend ActiveSupport::Concern

included do
before_save { self.email = email.downcase }

VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }

# downcase the searched for email
scope :by_email_wildcard, ->(q) { where("email like ?", "#{q.downcase}%") }
end

def email_domain
regex = /\A[\w+\-.]+@([a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z)/i
email[regex, 1]
end

module ClassMethods
def by_email(email)
where(email: email.downcase).first
end
end
end
19 changes: 3 additions & 16 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@
#

class User < ActiveRecord::Base
include Emailable
has_many :microposts, dependent: :destroy
has_many :relationships, foreign_key: "follower_id", dependent: :destroy
has_many :followed_users, through: :relationships, source: :followed
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships, source: :follower
before_save { self.email = email.downcase }

before_create :create_remember_token
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }

has_secure_password
validates :password, length: { minimum: 6 }

Expand Down Expand Up @@ -55,18 +54,6 @@ def unfollow!(other_user)
relationships.find_by(followed_id: other_user.id).destroy
end

def email_domain
regex = /\A[\w+\-.]+@([a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z)/i
email[regex, 1]
end

# downcase the searched for email
scope :by_email_wildcard, ->(q) { where("email like ?", "#{q.downcase}%") }

def self.by_email(email)
where(email: email.downcase).first
end

private

def create_remember_token
Expand Down
105 changes: 105 additions & 0 deletions spec/models/concerns/emailable_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
require 'spec_helper'


describe User do

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

subject { @user }

describe "#email_domain" do
it "should equal example.com" do
expect(@user.email_domain).to eq("example.com")
end
end

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

describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user@foo,com user_at_foo.org example.user@foo.
foo@bar_baz.com foo@bar+baz.com foo@bar..com]
addresses.each do |invalid_address|
@user.email = invalid_address
expect(@user).not_to be_valid
end
end
end

describe "when email format is valid" do
it "should be valid" do
addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
addresses.each do |valid_address|
@user.email = valid_address
expect(@user).to be_valid
end
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
end
end

describe "User email queries" do
before do
@u1 = FactoryGirl.create(:user, email: "foobar@baz.com")
@u2 = FactoryGirl.create(:user, email: "foobaz@bar.com")
@u3 = FactoryGirl.create(:user, email: "abcdef@ghi.com")
end

describe ".by_email" do
context "Using lower case" do
it "finds the correct user" do
expect(User.by_email(@u2.email).id).to eq(@u2.id)
end
end

context "Using wrong case" do
it "finds the correct user" do
expect(User.by_email(@u1.email.upcase).id).to eq(@u1.id)
end
end

context "Using no user" do
it "finds no user" do
expect(User.by_email("junk")).to be_nil
end
end
end

describe ".by_email_wildcard" do
context "Using lower case" do
it "finds the correct user" do
expect(User.by_email_wildcard("foo").pluck(:id)).to match_array([@u1.id, @u2.id])
end
end

context "Using wrong case" do
it "finds the correct user" do
expect(User.by_email_wildcard("FoO").pluck(:id)).to match_array([@u1.id, @u2.id])
end
end

context "Using no match" do
it "finds the correct user" do
expect(User.by_email_wildcard("junk")).to be_empty
end
end
end
end

91 changes: 0 additions & 91 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,50 +65,6 @@
it { should_not be_valid }
end

describe "#email_domain" do
it "should equal example.com" do
expect(@user.email_domain).to eq("example.com")
end
end

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

describe "when email format is invalid" do
it "should be invalid" do
addresses = %w[user@foo,com user_at_foo.org example.user@foo.
foo@bar_baz.com foo@bar+baz.com foo@bar..com]
addresses.each do |invalid_address|
@user.email = invalid_address
expect(@user).not_to be_valid
end
end
end

describe "when email format is valid" do
it "should be valid" do
addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
addresses.each do |valid_address|
@user.email = valid_address
expect(@user).to be_valid
end
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
end

describe "when password is not present" do
before do
@user = User.new(name: "Example User", email: "user@example.com",
Expand Down Expand Up @@ -217,50 +173,3 @@
end
end

describe "User email queries" do
before do
@u1 = FactoryGirl.create(:user, email: "foobar@baz.com")
@u2 = FactoryGirl.create(:user, email: "foobaz@bar.com")
@u3 = FactoryGirl.create(:user, email: "abcdef@ghi.com")
end

describe ".by_email" do
context "Using lower case" do
it "finds the correct user" do
expect(User.by_email(@u2.email).id).to eq(@u2.id)
end
end

context "Using wrong case" do
it "finds the correct user" do
expect(User.by_email(@u1.email.upcase).id).to eq(@u1.id)
end
end

context "Using no user" do
it "finds no user" do
expect(User.by_email("junk")).to be_nil
end
end
end

describe ".by_email_wildcard" do
context "Using lower case" do
it "finds the correct user" do
expect(User.by_email_wildcard("foo").pluck(:id)).to match_array([@u1.id, @u2.id])
end
end

context "Using wrong case" do
it "finds the correct user" do
expect(User.by_email_wildcard("FoO").pluck(:id)).to match_array([@u1.id, @u2.id])
end
end

context "Using no match" do
it "finds the correct user" do
expect(User.by_email_wildcard("junk")).to be_empty
end
end
end
end