Skip to content

Instantly share code, notes, and snippets.

@behrangsa
Created February 5, 2012 10:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save behrangsa/1744655 to your computer and use it in GitHub Desktop.
Save behrangsa/1744655 to your computer and use it in GitHub Desktop.
SO Question
class UsersController < ApplicationController
before_filter :authenticate, :only => [:index, :edit, :update]
before_filter :correct_user, :only => [:edit, :update]
before_filter :admin_user, :only => :destroy
def index
@title = "All users"
@users = User.paginate(:page => params[:page])
end
def show
@user = User.find(params[:id])
@title = @user.name
end
def new
redirect_to(root_path) unless current_user?(nil)
@user = User.new
@title = "Sign up"
end
def create
@user = User.new(params[:user])
if @user.save
sign_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
@title = "Sign up"
@user.password = nil
@user.password_confirmation = nil
render 'new'
end
end
def edit
@title = "Edit user"
end
def update
@user = User.find(params[:id])
if @user.update_attributes(params[:user])
flash[:success] = "Profile updated."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User destroyed."
redirect_to users_path
end
private
def authenticate
deny_access unless signed_in?
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_path) unless current_user?(@user)
end
def admin_user
redirect_to(root_path) unless (current_user && current_user.admin?)
end
end
require 'spec_helper'
describe UsersController do
render_views
describe "GET 'index'" do
describe "for non-signed-in users" do
it "should deny access" do
get :index
response.should redirect_to(signin_path)
flash[:notice].should =~ /sign in/i
end
end
describe "for signed-in users" do
before(:each) do
@user = test_sign_in(Factory(:user))
second = Factory(:user, :name => "Bob", :email => "another@example.com")
third = Factory(:user, :name => "Ben", :email => "another@example.net")
@users = [@user, second, third]
30.times do
@users << Factory(:user, :name => Factory.next(:name),
:email => Factory.next(:email))
end
end
it "should be successful" do
get :index
response.should be_success
end
it "should have the right title" do
get :index
response.should have_selector("title", :content => "All users")
end
it "should have an element for each user" do
get :index
@users[0..2].each do |user|
response.should have_selector("li", :content => user.name)
end
end
it "should paginate users" do
get :index
response.should have_selector("div.pagination")
response.should have_selector("span.disabled", :content => "Previous")
response.should have_selector("a", :href => "/users?page=2",
:content => "2")
response.should have_selector("a", :href => "/users?page=2",
:content => "Next")
end
end
end
describe "GET 'show'" do
before(:each) do
@user = Factory(:user)
end
it "should be successful" do
get :show, :id => @user
response.should be_success
end
it "should find the right user" do
get :show, :id => @user
assigns(:user).should == @user
end
it "should have the right title" do
get :show, :id => @user
response.should have_selector("title", :content => @user.name)
end
it "should include the user's name" do
get :show, :id => @user
response.should have_selector("h1", :content => @user.name)
end
it "should have a profile image" do
get :show, :id => @user
response.should have_selector("h1>img", :class => "gravatar")
end
end
describe "GET 'new'" do
it "should be successful" do
get 'new'
response.should be_success
end
it "should have the right title" do
get 'new'
response.should have_selector("title", :content => "Sign up")
end
it "should have a name field" do
get :new
response.should have_selector("input[name='user[name]'][type='text']")
end
it "should have an email field" do
get :new
response.should have_selector("input[name='user[email]'][type='text']")
end
it "should have a password field" do
get :new
response.should have_selector("input[name='user[password]'][type='password']")
end
it "should have a password confirmation field" do
get :new
response.should have_selector("input[name='user[password_confirmation]'][type='password']")
end
end
describe "POST 'create'" do
describe "failure" do
before(:each) do
@attr = {:name => "", :email => "", :password => "",
:password_confirmation => ""}
end
it "should not create a user" do
lambda do
post :create, :user => @attr
end.should_not change(User, :count)
end
it "should have the right title" do
post :create, :user => @attr
response.should have_selector("title", :content => "Sign up")
end
it "should render the 'new' page" do
post :create, :user => @attr
response.should render_template('new')
end
end
describe "success" do
before(:each) do
@attr = {:name => "New User", :email => "user@example.com",
:password => "foobar", :password_confirmation => "foobar"}
end
it "should create a user" do
lambda do
post :create, :user => @attr
end.should change(User, :count).by(1)
end
it "should sign the user in" do
post :create, :user => @attr
controller.should be_signed_in
end
it "should redirect to the user show page" do
post :create, :user => @attr
response.should redirect_to(user_path(assigns(:user)))
end
it "should have a welcome message" do
post :create, :user => @attr
flash[:success].should =~ /welcome to the sample app/i
end
end
end
describe "GET 'edit'" do
before(:each) do
@user = Factory(:user)
test_sign_in(@user)
end
it "should be successful" do
get :edit, :id => @user
response.should be_success
end
it "should have the right title" do
get :edit, :id => @user
response.should have_selector("title", :content => "Edit user")
end
it "should have a link to change the Gravatar" do
get :edit, :id => @user
gravatar_url = "http://gravatar.com/emails"
response.should have_selector("a", :href => gravatar_url,
:content => "change")
end
end
describe "PUT 'update'" do
before(:each) do
@user = Factory(:user)
test_sign_in(@user)
end
describe "failure" do
before(:each) do
@attr = {:email => "", :name => "", :password => "",
:password_confirmation => ""}
end
it "should render the 'edit' page" do
put :update, :id => @user, :user => @attr
response.should render_template('edit')
end
it "should have the right title" do
put :update, :id => @user, :user => @attr
response.should have_selector("title", :content => "Edit user")
end
end
describe "success" do
before(:each) do
@attr = {:name => "New Name", :email => "user@example.org",
:password => "barbaz", :password_confirmation => "barbaz"}
end
it "should change the user's attributes" do
put :update, :id => @user, :user => @attr
@user.reload
@user.name.should == @attr[:name]
@user.email.should == @attr[:email]
end
it "should redirect to the user show page" do
put :update, :id => @user, :user => @attr
response.should redirect_to(user_path(@user))
end
it "should have a flash message" do
put :update, :id => @user, :user => @attr
flash[:success].should =~ /updated/
end
end
end
describe "authentication of edit/update pages" do
before(:each) do
@user = Factory(:user)
end
describe "for non-signed-in users" do
it "should deny access to 'edit'" do
get :edit, :id => @user
response.should redirect_to(signin_path)
end
it "should deny access to 'update'" do
put :update, :id => @user, :user => {}
response.should redirect_to(signin_path)
end
end
describe "for signed-in users" do
before(:each) do
wrong_user = Factory(:user, :email => "user@example.net")
test_sign_in(wrong_user)
end
it "should require matching users for 'edit'" do
get :edit, :id => @user
response.should redirect_to(root_path)
end
it "should require matching users for 'update'" do
put :update, :id => @user, :user => {}
response.should redirect_to(root_path)
end
end
end
describe "DELETE 'destroy'" do
before(:each) do
@user = Factory(:user)
end
describe "as a non-signed-in user" do
it "should deny access" do
delete :destroy, :id => @user
response.should redirect_to(root_path)
end
end
describe "as a non-admin user" do
it "should protect the page" do
test_sign_in(@user)
delete :destroy, :id => @user
response.should redirect_to(root_path)
end
end
describe "as an admin user" do
before(:each) do
admin = Factory(:user, :email => "admin@example.com", :admin => true)
test_sign_in(admin)
end
it "should destroy the user" do
lambda do
delete :destroy, :id => @user
end.should change(User, :count).by(-1)
end
it "should redirect to the users page" do
delete :destroy, :id => @user
response.should redirect_to(users_path)
end
end
end
end
# == Schema Information
#
# Table name: users
#
# id :integer not null, primary key
# name :string(255)
# email :string(255)
# created_at :datetime
# updated_at :datetime
#
require 'spec_helper'
describe User do
before(:each) do
@attr = {
:name => "Example User",
:email => "user@example.com",
:password => "foobar",
:password_confirmation => "foobar"
}
end
it "should create a new instance given valid attributes" do
User.create!(@attr)
end
# Don't understand the code bellow. The merge is throwing me off
it "should require a name" do
no_name_user = User.new(@attr.merge(:name => ""))
no_name_user.should_not be_valid
end
it "should require an email address" do
no_email_user = User.new(@attr.merge(:email => ""))
no_email_user.should_not be_valid
end
it "should reject names that are too long" do
long_name = "a" * 51
long_name_user = User.new(@attr.merge(:name => long_name))
long_name_user.should_not be_valid
end
it "should accept valid email addresses" do
addresses = %w[user@foo.com THE_USER@foo.bar.org first.last@foo.jp]
addresses.each do |address|
valid_email_user = User.new(@attr.merge(:email => address))
valid_email_user.should be_valid
end
end
it "should reject invalid email addresses" do
addresses = %w[user@foo,com user_at_foo.org example.user@foo.]
addresses.each do |address|
invalid_email_user = User.new(@attr.merge(:email => address))
invalid_email_user.should_not be_valid
end
end
it "should reject duplicate email addresses" do
# Put a user with given email address into the database.
User.create!(@attr)
user_with_duplicate_email = User.new(@attr)
user_with_duplicate_email.should_not be_valid
end
it "should reject email addresses identical up to case" do
upcased_email = @attr[:email].upcase
User.create!(@attr.merge(:email => upcased_email))
user_with_duplicate_email = User.new(@attr)
user_with_duplicate_email.should_not be_valid
end
describe "password validations" do
it "should require a password" do
User.new(@attr.merge(:password => "", :password_confirmation => "")).
should_not be_valid
end
it "should require a matching password confirmation" do
User.new(@attr.merge(:password_confirmation => "invalid")).
should_not be_valid
end
it "should reject short passwords" do
short = "a" * 5
hash = @attr.merge(:password => short, :password_confirmation => short)
User.new(hash).should_not be_valid
end
it "should reject long passwords" do
long = "a" * 41
hash = @attr.merge(:password => long, :password_confirmation => long)
User.new(hash).should_not be_valid
end
end
describe "password encryption" do
before(:each) do
@user = User.create!(@attr)
end
it "should set the encrypted password" do
@user.encrypted_password.should_not be_blank
end
describe "has_password? method" do
it "should be true if the passwords match" do
@user.has_password?(@attr[:password]).should be_true
end
it "should be false if the passwords don't match" do
@user.has_password?("invalid").should be_false
end
end
describe "authenticate method" do
it "should return nil on email/password mismatch" do
wrong_password_user = User.authenticate(@attr[:email], "wrongpass")
wrong_password_user.should be_nil
end
it "should return nil for an email address with no user" do
nonexistent_user = User.authenticate("bar@foo.com", @attr[:password])
nonexistent_user.should be_nil
end
it "should return the user on email/password match" do
matching_user = User.authenticate(@attr[:email], @attr[:password])
matching_user.should == @user
end
end
end
describe "admin attribute" do
before(:each) do
@user = User.create!(@attr)
end
it "should respond to admin" do
@user.should respond_to(:admin)
end
it "should not be an admin by default" do
@user.should_not be_admin
end
it "should be convertible to an admin" do
@user.toggle!(:admin)
@user.should be_admin
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment