Patch #5957 » users_export6.patch
| app/controllers/users_controller.rb | ||
|---|---|---|
| 28 | 28 |
include SortHelper |
| 29 | 29 |
helper :custom_fields |
| 30 | 30 |
include CustomFieldsHelper |
| 31 |
include UsersHelper |
|
| 31 | 32 |
helper :principal_memberships |
| 32 | 33 | |
| 33 | 34 |
require_sudo_mode :create, :update, :destroy |
| ... | ... | |
| 59 | 60 |
@groups = Group.givable.sort |
| 60 | 61 |
render :layout => !request.xhr? |
| 61 | 62 |
} |
| 63 |
format.csv {
|
|
| 64 |
send_data(users_to_csv(scope.order(sort_clause)), :type => 'text/csv; header=present', :filename => 'users.csv') |
|
| 65 |
} |
|
| 62 | 66 |
format.api |
| 63 | 67 |
end |
| 64 | 68 |
end |
| app/helpers/users_helper.rb | ||
|---|---|---|
| 18 | 18 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 19 | 19 | |
| 20 | 20 |
module UsersHelper |
| 21 |
include ApplicationHelper |
|
| 22 | ||
| 21 | 23 |
def users_status_options_for_select(selected) |
| 22 | 24 |
user_count_by_status = User.group('status').count.to_hash
|
| 23 |
options_for_select([[l(:label_all), ''], |
|
| 24 |
["#{l(:status_active)} (#{user_count_by_status[1].to_i})", '1'],
|
|
| 25 |
["#{l(:status_registered)} (#{user_count_by_status[2].to_i})", '2'],
|
|
| 26 |
["#{l(:status_locked)} (#{user_count_by_status[3].to_i})", '3']], selected.to_s)
|
|
| 25 |
options_for_select([[l(:label_all), '']] + (User.valid_statuses.map {|c| ["#{l('status_' + User::STATUS_NAMES[c])} (#{user_count_by_status[c].to_i})", c]}), selected.to_s)
|
|
| 27 | 26 |
end |
| 28 | 27 | |
| 29 | 28 |
def user_mail_notification_options(user) |
| ... | ... | |
| 61 | 60 |
end |
| 62 | 61 |
tabs |
| 63 | 62 |
end |
| 63 | ||
| 64 |
def users_to_csv(users) |
|
| 65 |
Redmine::Export::CSV.generate do |csv| |
|
| 66 |
columns = [ |
|
| 67 |
'login', |
|
| 68 |
'firstname', |
|
| 69 |
'lastname', |
|
| 70 |
'mail', |
|
| 71 |
'admin', |
|
| 72 |
'created_on', |
|
| 73 |
'last_login_on', |
|
| 74 |
'status' |
|
| 75 |
] |
|
| 76 | ||
| 77 |
# csv header fields |
|
| 78 |
csv << columns.map{|column| l('field_' + column)}
|
|
| 79 |
# csv lines |
|
| 80 |
columns[columns.index('status')]= 'status_name'
|
|
| 81 |
users.each do |user| |
|
| 82 |
csv << columns.map{|column| format_object(user.send(column), false)}
|
|
| 83 |
end |
|
| 84 |
end |
|
| 85 |
end |
|
| 64 | 86 |
end |
| app/models/user.rb | ||
|---|---|---|
| 514 | 514 |
name |
| 515 | 515 |
end |
| 516 | 516 | |
| 517 |
CSS_CLASS_BY_STATUS = {
|
|
| 517 |
STATUS_NAMES = {
|
|
| 518 | 518 |
STATUS_ANONYMOUS => 'anon', |
| 519 | 519 |
STATUS_ACTIVE => 'active', |
| 520 | 520 |
STATUS_REGISTERED => 'registered', |
| 521 | 521 |
STATUS_LOCKED => 'locked' |
| 522 | 522 |
} |
| 523 | 523 | |
| 524 |
def status_name |
|
| 525 |
l(("status_#{STATUS_NAMES[status]}"))
|
|
| 526 |
end |
|
| 527 | ||
| 524 | 528 |
def css_classes |
| 525 |
"user #{CSS_CLASS_BY_STATUS[status]}"
|
|
| 529 |
"user #{STATUS_NAMES[status]}"
|
|
| 526 | 530 |
end |
| 527 | 531 | |
| 528 | 532 |
# Returns the current day according to user's time zone |
| app/views/users/index.html.erb | ||
|---|---|---|
| 55 | 55 |
</table> |
| 56 | 56 |
</div> |
| 57 | 57 |
<span class="pagination"><%= pagination_links_full @user_pages, @user_count %></span> |
| 58 |
<% other_formats_links do |f| %> |
|
| 59 |
<%= f.link_to_with_query_parameters 'CSV' %> |
|
| 60 |
<% end %> |
|
| 58 | 61 |
<% else %> |
| 59 | 62 |
<p class="nodata"><%= l(:label_no_data) %></p> |
| 60 | 63 |
<% end %> |
| test/functional/users_controller_test.rb | ||
|---|---|---|
| 64 | 64 |
end |
| 65 | 65 |
end |
| 66 | 66 | |
| 67 |
def test_index_csv |
|
| 68 |
with_settings :default_language => 'en' do |
|
| 69 |
get :index, :params => { :format => 'csv' }
|
|
| 70 |
assert_response :success |
|
| 71 | ||
| 72 |
assert_equal User.logged.status(1).count, response.body.chomp.split("\n").size - 1
|
|
| 73 |
assert_include 'active', response.body |
|
| 74 |
assert_not_include 'locked', response.body |
|
| 75 |
assert_equal 'text/csv; header=present', @response.content_type |
|
| 76 |
end |
|
| 77 |
end |
|
| 78 | ||
| 79 |
def test_index_csv_with_status_filter |
|
| 80 |
with_settings :default_language => 'en' do |
|
| 81 |
get :index, :params => { :status => 3, :format => 'csv' }
|
|
| 82 |
assert_response :success |
|
| 83 | ||
| 84 |
assert_equal User.logged.status(3).count, response.body.chomp.split("\n").size - 1
|
|
| 85 |
assert_include 'locked', response.body |
|
| 86 |
assert_not_include 'active', response.body |
|
| 87 |
assert_equal 'text/csv; header=present', @response.content_type |
|
| 88 |
end |
|
| 89 |
end |
|
| 90 | ||
| 91 |
def test_index_csv_with_name_filter |
|
| 92 |
get :index, :params => {:name => 'John', :format => 'csv'}
|
|
| 93 |
assert_response :success |
|
| 94 | ||
| 95 |
assert_equal User.logged.like('John').count, response.body.chomp.split("\n").size - 1
|
|
| 96 |
assert_include 'John', response.body |
|
| 97 |
assert_equal 'text/csv; header=present', @response.content_type |
|
| 98 |
end |
|
| 99 | ||
| 100 |
def test_index_csv_with_group_filter |
|
| 101 |
get :index, :params => {:group_id => '10', :format => 'csv'}
|
|
| 102 |
assert_response :success |
|
| 103 | ||
| 104 |
assert_equal Group.find(10).users.count, response.body.chomp.split("\n").size - 1
|
|
| 105 |
assert_equal 'text/csv; header=present', @response.content_type |
|
| 106 |
end |
|
| 107 | ||
| 67 | 108 |
def test_show |
| 68 | 109 |
@request.session[:user_id] = nil |
| 69 | 110 |
get :show, :params => {:id => 2}
|
| test/helpers/users_helper_test.rb | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2016 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 | ||
| 18 |
require File.expand_path('../../test_helper', __FILE__)
|
|
| 19 | ||
| 20 |
class UserHelperTest < Redmine::HelperTest |
|
| 21 |
include UsersHelper |
|
| 22 |
include ERB::Util |
|
| 23 | ||
| 24 |
def test_users_status_options_for_select_should_have_selected_options |
|
| 25 |
selected = 1 |
|
| 26 |
with_locale 'en' do |
|
| 27 |
options = users_status_options_for_select(selected) |
|
| 28 |
user_count_by_status = User.group('status').count.to_hash
|
|
| 29 |
assert_select_in options, "option[value='']", :text => 'all' |
|
| 30 |
assert_select_in options, "option[selected='selected'][value='1']", :text => "active (#{user_count_by_status[1].to_i})"
|
|
| 31 |
assert_select_in options, "option[value='2']", :text => "registered (#{user_count_by_status[2].to_i})"
|
|
| 32 |
assert_select_in options, "option[value='3']", :text => "locked (#{user_count_by_status[3].to_i})"
|
|
| 33 |
end |
|
| 34 |
end |
|
| 35 | ||
| 36 |
def test_users_to_csv_header_should_be_column_name |
|
| 37 |
with_locale 'en' do |
|
| 38 |
column_names = [ |
|
| 39 |
'Login', |
|
| 40 |
'First name', |
|
| 41 |
'Last name', |
|
| 42 |
'Email', |
|
| 43 |
'Administrator', |
|
| 44 |
'Created', |
|
| 45 |
'Last connection', |
|
| 46 |
'Status' |
|
| 47 |
] |
|
| 48 |
csv = users_to_csv(User.logged) |
|
| 49 |
column_names.each do |column_name| |
|
| 50 |
assert_include column_name, csv |
|
| 51 |
end |
|
| 52 |
end |
|
| 53 |
end |
|
| 54 | ||
| 55 |
def test_users_to_csv_should_status_convert_to_status_name |
|
| 56 |
with_locale 'en' do |
|
| 57 |
csv = users_to_csv(User.status(1)) |
|
| 58 |
assert_include 'active', csv |
|
| 59 |
end |
|
| 60 |
end |
|
| 61 |
end |
|
| test/unit/user_test.rb | ||
|---|---|---|
| 838 | 838 |
assert_equal true, User.default_admin_account_changed? |
| 839 | 839 |
end |
| 840 | 840 | |
| 841 |
def test_status_name_should_return_status_name |
|
| 842 |
user = User.new |
|
| 843 |
user.status = User::STATUS_ACTIVE |
|
| 844 | ||
| 845 |
assert_equal l("status_#{User::STATUS_NAMES[user.status]}"), user.status_name
|
|
| 846 |
end |
|
| 847 | ||
| 848 |
def test_css_classes_should_return_class_name |
|
| 849 |
user = User.new |
|
| 850 |
user.status = User::STATUS_ACTIVE |
|
| 851 | ||
| 852 |
assert_equal "user " + User::STATUS_NAMES[user.status], user.css_classes |
|
| 853 |
end |
|
| 854 | ||
| 841 | 855 |
def test_membership_with_project_should_return_membership |
| 842 | 856 |
project = Project.find(1) |
| 843 | 857 | |