From 9dadc61cae2c4c01a97880e89ca86a0e760fc8d1 Mon Sep 17 00:00:00 2001 From: hukl Date: Wed, 7 Oct 2009 21:03:28 +0200 Subject: implemented complete restful user management interface including functional tests. this enables basic user operation. note that only admins are allowed to create, edit, destroy other users --- app/controllers/users_controller.rb | 30 +++++- app/helpers/users_helper.rb | 7 ++ app/models/user.rb | 2 +- app/views/users/_admin_user_item.html.erb | 12 +++ app/views/users/_user_item.html.erb | 4 + app/views/users/create.html.erb | 2 - app/views/users/destroy.html.erb | 2 - app/views/users/edit.html.erb | 32 ++++++- app/views/users/index.html.erb | 15 +-- app/views/users/new.html.erb | 32 ++++++- app/views/users/show.html.erb | 22 ++++- app/views/users/update.html.erb | 2 - public/stylesheets/admin.css | 4 + test/fixtures/users.yml | 1 + test/functional/nodes_controller_test.rb | 2 - test/functional/users_controller_test.rb | 146 +++++++++++++++++++++++++++++- test/test_helper.rb | 3 + 17 files changed, 292 insertions(+), 26 deletions(-) create mode 100644 app/views/users/_admin_user_item.html.erb create mode 100644 app/views/users/_user_item.html.erb delete mode 100644 app/views/users/create.html.erb delete mode 100644 app/views/users/destroy.html.erb delete mode 100644 app/views/users/update.html.erb diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 19f6b2d..b15f83b 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -3,29 +3,57 @@ class UsersController < ApplicationController # Private before_filter :login_required + before_filter :verify_admin_status, :except => [:index, :show] layout 'admin' def index - @users = User.all + @users = User.all(:order => "login ASC") end def new + @user = User.new( params[:user] ) end def create + @user = User.new params[:user] + + if @user.save + redirect_to user_path(@user) + else + render :new + end end def edit + @user = User.find(params[:id]) end def update + @user = User.find(params[:id]) + + if @user.update_attributes(params[:user]) + redirect_to user_path(@user) + else + render :edit + end end def show + @user = User.find(params[:id]) end def destroy + user = User.find(params[:id]) + user.destroy if user + redirect_to users_path end + private + def verify_admin_status + unless current_user.admin + flash[:notice] = "Sorry, you need to be an admin for this action" + redirect_to users_path + end + end end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 2310a24..ff03138 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -1,2 +1,9 @@ module UsersHelper + def user_list_by_admin_status + if current_user && current_user.admin + render :partial => 'admin_user_item', :collection => @users + else + render :partial => 'user_item', :collection => @users + end + end end diff --git a/app/models/user.rb b/app/models/user.rb index 26ebf45..035a145 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -21,7 +21,7 @@ class User < ActiveRecord::Base validates_format_of :email, :with => Authentication.email_regex, :message => Authentication.bad_email_message - attr_accessible :login, :email, :password, :password_confirmation + attr_accessible :login, :email, :password, :password_confirmation, :admin # Authenticates a user by their login name and unencrypted password. Returns the user or nil. def self.authenticate(login, password) diff --git a/app/views/users/_admin_user_item.html.erb b/app/views/users/_admin_user_item.html.erb new file mode 100644 index 0000000..d882dc4 --- /dev/null +++ b/app/views/users/_admin_user_item.html.erb @@ -0,0 +1,12 @@ + + <%= admin_user_item.login %> + + <%= link_to "Show", user_path(admin_user_item) %> + <%= link_to( + "Destroy", + user_path(admin_user_item), + :method => "delete", + :confirm => "Are you sure to delete user: #{admin_user_item.login}?" + ) %> + + \ No newline at end of file diff --git a/app/views/users/_user_item.html.erb b/app/views/users/_user_item.html.erb new file mode 100644 index 0000000..c3389ba --- /dev/null +++ b/app/views/users/_user_item.html.erb @@ -0,0 +1,4 @@ + + <%= user_item.login %> + + \ No newline at end of file diff --git a/app/views/users/create.html.erb b/app/views/users/create.html.erb deleted file mode 100644 index 48ea02e..0000000 --- a/app/views/users/create.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -

Users#create

-

Find me in app/views/users/create.html.erb

diff --git a/app/views/users/destroy.html.erb b/app/views/users/destroy.html.erb deleted file mode 100644 index de4bd26..0000000 --- a/app/views/users/destroy.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -

Users#destroy

-

Find me in app/views/users/destroy.html.erb

diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 1881fbd..5b73242 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -1,2 +1,30 @@ -

Users#edit

-

Find me in app/views/users/edit.html.erb

+

Edit existing user

+ +<% form_for @user do |f| %> + + + + + + + + + + + + + + + + + + + + + + + + + +
Login<%= f.text_field :login %>
E-Mail<%= f.text_field :email %>
Password<%= f.text_field :password %>
Confirm<%= f.text_field :password_confirmation %>
Admin?<%= f.check_box :admin %>
<%= f.submit "Create" %>
+<% end %> \ No newline at end of file diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index f0b5b28..8526d84 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -1,12 +1,13 @@

Users

- +
- <% @users.each do |user| %> - - - - <% end %> -
login
<%= user.login %>
\ No newline at end of file + <%= user_list_by_admin_status %> + + + +<% content_for :subnavigation do %> + <%= link_to "create", new_user_path %> +<% end %> \ No newline at end of file diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index c21a1ad..0629641 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -1,2 +1,30 @@ -

Users#new

-

Find me in app/views/users/new.html.erb

+

Create new user

+ +<% form_for @user do |f| %> + + + + + + + + + + + + + + + + + + + + + + + + + +
Login<%= f.text_field :login %>
E-Mail<%= f.text_field :email %>
Password<%= f.text_field :password %>
Confirm<%= f.text_field :password_confirmation %>
Admin?<%= f.check_box :admin %>
<%= f.submit "Create" %>
+<% end %> \ No newline at end of file diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index e5fa3ad..3055d24 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -1,2 +1,20 @@ -

Users#show

-

Find me in app/views/users/show.html.erb

+

User: <%= @user.login %>

+ + + + + + + + + + + + + + +
Login<%= @user.login %>
E-Mail<%= @user.email %>
Admin?<%= @user.admin ? "yes" : "no" %>
+ +<% content_for :subnavigation do %> + <%= link_to 'Edit', edit_user_path(@user) %> +<% end %> diff --git a/app/views/users/update.html.erb b/app/views/users/update.html.erb deleted file mode 100644 index cabbde1..0000000 --- a/app/views/users/update.html.erb +++ /dev/null @@ -1,2 +0,0 @@ -

Users#update

-

Find me in app/views/users/update.html.erb

diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index d74632b..1822ed1 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css @@ -439,3 +439,7 @@ input#move_to_search_term, input#node_staged_slug { width: 680px; } +table#user_list td { + padding-right: 30px; +} + diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 5b32afc..a62b350 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -13,4 +13,5 @@ aaron: salt: 5be6f9cdd04fd7ab3c91cd32a5334ba2339b8005 crypted_password: 740a48caf7dd5ff11318d812d57c0a0928cfbc12 # 'monkey' created_at: <%= 1.days.ago.to_s :db %> + admin: true diff --git a/test/functional/nodes_controller_test.rb b/test/functional/nodes_controller_test.rb index 3293f42..3dae9db 100644 --- a/test/functional/nodes_controller_test.rb +++ b/test/functional/nodes_controller_test.rb @@ -2,8 +2,6 @@ require 'test_helper' class NodesControllerTest < ActionController::TestCase - include AuthenticatedTestHelper - def test_get_index Node.root.descendants.delete_all test_node = Node.create :slug => "foo" diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb index c3db123..a8333fe 100644 --- a/test/functional/users_controller_test.rb +++ b/test/functional/users_controller_test.rb @@ -1,8 +1,148 @@ require 'test_helper' class UsersControllerTest < ActionController::TestCase - # Replace this with your real tests. - test "the truth" do - assert true + + test "get index as regular user renders stripped partial" do + login_as :quentin + get :index + assert_response :success + assert_select "a", { :count => 0, :text => "Destroy" } end + + test "get index as admin user renders admin partial" do + login_as :aaron + get :index + assert_response :success + assert_select "a", "Destroy" + assert_select "a", "Show", "Edit Link is missing" + end + + test "get new when logged in as admin" do + login_as :aaron + get :new + assert_response :success + end + + test "get new without being logged in as admin redirects back to index" do + login_as :quentin + get :new + assert_response :redirect + assert_redirected_to users_path + assert_equal( + "Sorry, you need to be an admin for this action", + @response.flash[:notice] + ) + end + + test "creating new users being logged in as admin" do + login_as :aaron + assert_difference "User.count", +1 do + post :create, :user => { + :login => "peter", + :email => "foo@bar.com", + :password => "xxxzzz", + :password_confirmation => "xxxzzz" + } + end + + assert_redirected_to user_path(User.last) + assert !User.last.admin + end + + test "creating new admin users being logged in as admin" do + login_as :aaron + assert_difference "User.count", +1 do + post :create, :user => { + :login => "peter", + :email => "foo@bar.com", + :password => "xxxzzz", + :password_confirmation => "xxxzzz", + :admin => true + } + end + + assert_redirected_to user_path(User.last) + assert User.last.admin + end + + test "creating new users not being logged as regular user wont work" do + login_as :quentin + assert_no_difference "User.count" do + post :create, :user => { + :login => "peter", + :email => "foo@bar.com", + :password => "xxxzzz", + :password_confirmation => "xxxzzz" + } + end + + assert_redirected_to users_path + assert_equal( + "Sorry, you need to be an admin for this action", + @response.flash[:notice] + ) + end + + test "get edit of another user being logged in as regular user wont work" do + login_as :quentin + get :edit, :id => User.find_by_login("aaron").id + assert_redirected_to users_path + assert_equal( + "Sorry, you need to be an admin for this action", + @response.flash[:notice] + ) + end + + test "get edit of another user being logged in as admin user" do + login_as :aaron + get :edit, :id => User.find_by_login("quentin").id + assert_response :success + end + + test "updating an user when being logged in as regular user wont work" do + user = User.find_by_login("aaron") + login_as :quentin + put :update, :id => user.id, :user => {:login => "random"} + assert_redirected_to users_path + assert_equal( + "Sorry, you need to be an admin for this action", + @response.flash[:notice] + ) + end + + test "updating an user when being login in as admin user" do + user = User.find_by_login("quentin") + login_as :aaron + put :update, :id => user.id, :user => {:login => "random"} + assert_redirected_to user_path(user) + assert_equal "random", user.reload.login + end + + test "showing a user" do + login_as :quentin + get :show, :id => User.find_by_login("aaron").id + assert_response :success + end + + test "destroying an user being logged in as regular user wont work" do + login_as :quentin + assert_no_difference "User.count" do + delete :destroy, :id => User.find_by_login("aaron").id + end + assert_redirected_to users_path + assert_equal( + "Sorry, you need to be an admin for this action", + @response.flash[:notice] + ) + end + + test "destroying an user being logged in as admin user" do + login_as :aaron + assert_difference "User.count", -1 do + delete :destroy, :id => User.find_by_login("quentin").id + end + assert_redirected_to users_path + end + + end diff --git a/test/test_helper.rb b/test/test_helper.rb index b9fe251..21d4604 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -3,6 +3,9 @@ require File.expand_path(File.dirname(__FILE__) + "/../config/environment") require 'test_help' class ActiveSupport::TestCase + + include AuthenticatedTestHelper + # Transactional fixtures accelerate your tests by wrapping each test method # in a transaction that's rolled back on completion. This ensures that the # test database remains unchanged so your fixtures don't have to be reloaded -- cgit v1.3