Skip to content

Instantly share code, notes, and snippets.

@andrewhl
Created October 29, 2011 04:38
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 andrewhl/1324100 to your computer and use it in GitHub Desktop.
Save andrewhl/1324100 to your computer and use it in GitHub Desktop.
<li>
<%= gravatar_for user, :size => 30 %>
<%= link_to user.name, user %>
<% if current_user.admin? %>
| <%= link_to "delete", user, :method => :delete, :confirm => "You sure?",
:title => "Delete #{user.name}" %>
<% end %>
</li>
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<%= csrf_meta_tag %>
<%= render 'layouts/stylesheets' %>
<%= javascript_include_tag "application" %>
</head>
<body>
<div class="container">
<%= render 'layouts/header' %>
<section class="round">
<% flash.each do |key, value| %>
<%= content_tag(:div, value, :class => "flash #{key}") %>
<% end %>
<%= yield %>
</section>
<%= render 'layouts/footer' %>
<%= debug(params) if Rails.env.development? %>
</div>
</body>
</html>
<h1>All users</h1>
<%= will_paginate %>
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
SampleApp::Application.routes.draw do
get "sessions/new"
resources :users
resources :sessions, :only => [:new, :create, :destroy]
match '/contact', :to => 'pages#contact'
match '/about', :to => 'pages#about'
match '/help', :to => 'pages#help'
match '/signup', :to => 'users#new'
match '/signin', :to => 'sessions#new'
match '/signout', :to => 'sessions#destroy'
root :to => 'pages#home'
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => 'welcome#index'
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
end
# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
RSpec.configure do |config|
# == Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
config.mock_with :rspec
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
def test_sign_in(user)
controller.sign_in(user)
end
def integration_sign_in(user)
visit signin_path
fill_in :email, :with => user.email
fill_in :password, :with => user.password
click_button
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)
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")
30.times do
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
User.paginate(:page => 1).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_confiramtion => "foobar" }
end
it "should create a user" do
lambda do
post :create, :user => @attr
end.should change(User, :count).by(1)
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
it "should sign the user in" do
post :create, :user => @attr
controller.should be_signed_in
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(signin_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
it "should not display delete links" do
get :index
response.should_not have_selector("a", :content => "delete")
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 display delete links" do
get :index
response.should have_selector("a", :content => "delete")
end
it "should destroy the user" do
lambda do
delete :destroy, :id => @user
end.should change(User, :count).by(-1)
end
it "should not destroy self" do
lambda do
delete :destroy, :id => @admin
end.should_not change(User, :count)
response.should redirect_to(users_path)
flash[:error] =~ /You may not delete your own account/i
end
it "should redirect to the users page" do
delete :destroy, :id => @user
response.should redirect_to(users_path)
end
end
end
describe "signed-in user redirect" do
before(:each) do
@user = Factory(:user)
test_sign_in(@user)
end
it "should not be accessible by a signed-in user" do
get :new
response.should redirect_to(root_path)
flash[:info].should =~ /You're already logged in/i
end
it "should display a flash notice on failed access" do
get :create
response.should redirect_to(root_path)
flash[:info].should =~ /You're already logged in/i
end
end
end
class UsersController < ApplicationController
before_filter :authenticate, :only => [:index, :edit, :update, :destroy]
before_filter :correct_user, :only => [:edit, :update]
before_filter :admin_user, :only => :destroy
before_filter :signed_in_user, :only => [:new, :create]
def show
@user = User.find(params[:id])
@title = @user.name
end
def new
@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 = ""
render 'new'
end
end
def edit
@title = "Edit user"
end
def update
if @user.update_attributes(params[:user])
flash[:success] = "Profile updated."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
def index
@title = "All users"
@users = User.paginate(:page => params[:page])
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.admin?
end
def signed_in_user
if signed_in?
flash[:info] = "You're already logged in ..."
redirect_to(root_path)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment