Patch #5957 » users_export5.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 | ||
---|---|---|
517 | 517 |
name |
518 | 518 |
end |
519 | 519 | |
520 |
CSS_CLASS_BY_STATUS = {
|
|
520 |
STATUS_NAMES = {
|
|
521 | 521 |
STATUS_ANONYMOUS => 'anon', |
522 | 522 |
STATUS_ACTIVE => 'active', |
523 | 523 |
STATUS_REGISTERED => 'registered', |
524 | 524 |
STATUS_LOCKED => 'locked' |
525 | 525 |
} |
526 | 526 | |
527 |
def status_name |
|
528 |
l(("status_#{STATUS_NAMES[status]}")) |
|
529 |
end |
|
530 | ||
527 | 531 |
def css_classes |
528 |
"user #{CSS_CLASS_BY_STATUS[status]}"
|
|
532 |
"user #{STATUS_NAMES[status]}"
|
|
529 | 533 |
end |
530 | 534 | |
531 | 535 |
# 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/unit/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 |