##// END OF EJS Templates
Added an active field track if an Enumeration is active on the frontend view....
Eric Davis -
r2832:e76d4c5c4c3f
parent child
Show More
@@ -0,0 +1,9
1 class AddActiveFieldToEnumerations < ActiveRecord::Migration
2 def self.up
3 add_column :enumerations, :active, :boolean, :default => true, :null => false
4 end
5
6 def self.down
7 remove_column :enumerations, :active
8 end
9 end
@@ -1,164 +1,171
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module TimelogHelper
19 19 include ApplicationHelper
20 20
21 21 def render_timelog_breadcrumb
22 22 links = []
23 23 links << link_to(l(:label_project_all), {:project_id => nil, :issue_id => nil})
24 24 links << link_to(h(@project), {:project_id => @project, :issue_id => nil}) if @project
25 25 links << link_to_issue(@issue) if @issue
26 26 breadcrumb links
27 27 end
28
29 def activity_collection_for_select_options
30 activities = TimeEntryActivity.all
28
29 # Returns a collection of activities for a select field. time_entry
30 # is optional and will be used to check if the selected TimeEntryActivity
31 # is active.
32 def activity_collection_for_select_options(time_entry=nil)
33 activities = TimeEntryActivity.active
31 34 collection = []
32 collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
35 if time_entry && !time_entry.activity.active?
36 collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ]
37 else
38 collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default)
39 end
33 40 activities.each { |a| collection << [a.name, a.id] }
34 41 collection
35 42 end
36 43
37 44 def select_hours(data, criteria, value)
38 45 if value.to_s.empty?
39 46 data.select {|row| row[criteria].blank? }
40 47 else
41 48 data.select {|row| row[criteria] == value}
42 49 end
43 50 end
44 51
45 52 def sum_hours(data)
46 53 sum = 0
47 54 data.each do |row|
48 55 sum += row['hours'].to_f
49 56 end
50 57 sum
51 58 end
52 59
53 60 def options_for_period_select(value)
54 61 options_for_select([[l(:label_all_time), 'all'],
55 62 [l(:label_today), 'today'],
56 63 [l(:label_yesterday), 'yesterday'],
57 64 [l(:label_this_week), 'current_week'],
58 65 [l(:label_last_week), 'last_week'],
59 66 [l(:label_last_n_days, 7), '7_days'],
60 67 [l(:label_this_month), 'current_month'],
61 68 [l(:label_last_month), 'last_month'],
62 69 [l(:label_last_n_days, 30), '30_days'],
63 70 [l(:label_this_year), 'current_year']],
64 71 value)
65 72 end
66 73
67 74 def entries_to_csv(entries)
68 75 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
69 76 decimal_separator = l(:general_csv_decimal_separator)
70 77 custom_fields = TimeEntryCustomField.find(:all)
71 78 export = StringIO.new
72 79 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
73 80 # csv header fields
74 81 headers = [l(:field_spent_on),
75 82 l(:field_user),
76 83 l(:field_activity),
77 84 l(:field_project),
78 85 l(:field_issue),
79 86 l(:field_tracker),
80 87 l(:field_subject),
81 88 l(:field_hours),
82 89 l(:field_comments)
83 90 ]
84 91 # Export custom fields
85 92 headers += custom_fields.collect(&:name)
86 93
87 94 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
88 95 # csv lines
89 96 entries.each do |entry|
90 97 fields = [format_date(entry.spent_on),
91 98 entry.user,
92 99 entry.activity,
93 100 entry.project,
94 101 (entry.issue ? entry.issue.id : nil),
95 102 (entry.issue ? entry.issue.tracker : nil),
96 103 (entry.issue ? entry.issue.subject : nil),
97 104 entry.hours.to_s.gsub('.', decimal_separator),
98 105 entry.comments
99 106 ]
100 107 fields += custom_fields.collect {|f| show_value(entry.custom_value_for(f)) }
101 108
102 109 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
103 110 end
104 111 end
105 112 export.rewind
106 113 export
107 114 end
108 115
109 116 def format_criteria_value(criteria, value)
110 117 value.blank? ? l(:label_none) : ((k = @available_criterias[criteria][:klass]) ? k.find_by_id(value.to_i) : format_value(value, @available_criterias[criteria][:format]))
111 118 end
112 119
113 120 def report_to_csv(criterias, periods, hours)
114 121 export = StringIO.new
115 122 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
116 123 # Column headers
117 124 headers = criterias.collect {|criteria| l(@available_criterias[criteria][:label]) }
118 125 headers += periods
119 126 headers << l(:label_total)
120 127 csv << headers.collect {|c| to_utf8(c) }
121 128 # Content
122 129 report_criteria_to_csv(csv, criterias, periods, hours)
123 130 # Total row
124 131 row = [ l(:label_total) ] + [''] * (criterias.size - 1)
125 132 total = 0
126 133 periods.each do |period|
127 134 sum = sum_hours(select_hours(hours, @columns, period.to_s))
128 135 total += sum
129 136 row << (sum > 0 ? "%.2f" % sum : '')
130 137 end
131 138 row << "%.2f" %total
132 139 csv << row
133 140 end
134 141 export.rewind
135 142 export
136 143 end
137 144
138 145 def report_criteria_to_csv(csv, criterias, periods, hours, level=0)
139 146 hours.collect {|h| h[criterias[level]].to_s}.uniq.each do |value|
140 147 hours_for_value = select_hours(hours, criterias[level], value)
141 148 next if hours_for_value.empty?
142 149 row = [''] * level
143 150 row << to_utf8(format_criteria_value(criterias[level], value))
144 151 row += [''] * (criterias.length - level - 1)
145 152 total = 0
146 153 periods.each do |period|
147 154 sum = sum_hours(select_hours(hours_for_value, @columns, period.to_s))
148 155 total += sum
149 156 row << (sum > 0 ? "%.2f" % sum : '')
150 157 end
151 158 row << "%.2f" %total
152 159 csv << row
153 160
154 161 if criterias.length > level + 1
155 162 report_criteria_to_csv(csv, criterias, periods, hours_for_value, level + 1)
156 163 end
157 164 end
158 165 end
159 166
160 167 def to_utf8(s)
161 168 @ic ||= Iconv.new(l(:general_csv_encoding), 'UTF-8')
162 169 begin; @ic.iconv(s.to_s); rescue; s.to_s; end
163 170 end
164 171 end
@@ -1,132 +1,140
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Enumeration < ActiveRecord::Base
19 19 acts_as_list :scope => 'type = \'#{type}\''
20 20 acts_as_customizable
21 21
22 22 before_destroy :check_integrity
23 23
24 24 validates_presence_of :name
25 25 validates_uniqueness_of :name, :scope => [:type]
26 26 validates_length_of :name, :maximum => 30
27 27
28 28 # Backwards compatiblity named_scopes.
29 29 # Can be removed post-0.9
30 30 named_scope :priorities, :conditions => { :type => "IssuePriority" }, :order => 'position' do
31 31 ActiveSupport::Deprecation.warn("Enumeration#priorities is deprecated, use the IssuePriority class. (#{Redmine::Info.issue(3007)})")
32 32 def default
33 33 find(:first, :conditions => { :is_default => true })
34 34 end
35 35 end
36 36
37 37 named_scope :document_categories, :conditions => { :type => "DocumentCategory" }, :order => 'position' do
38 38 ActiveSupport::Deprecation.warn("Enumeration#document_categories is deprecated, use the DocumentCategories class. (#{Redmine::Info.issue(3007)})")
39 39 def default
40 40 find(:first, :conditions => { :is_default => true })
41 41 end
42 42 end
43 43
44 44 named_scope :activities, :conditions => { :type => "TimeEntryActivity" }, :order => 'position' do
45 45 ActiveSupport::Deprecation.warn("Enumeration#activities is deprecated, use the TimeEntryActivity class. (#{Redmine::Info.issue(3007)})")
46 46 def default
47 47 find(:first, :conditions => { :is_default => true })
48 48 end
49 49 end
50 50
51 51 named_scope :values, lambda {|type| { :conditions => { :type => type }, :order => 'position' } } do
52 52 def default
53 53 find(:first, :conditions => { :is_default => true })
54 54 end
55 55 end
56 # End backwards compatiblity named_scopes
56 57
57 58 named_scope :all, :order => 'position'
58 59
60 named_scope :active, lambda {
61 {
62 :conditions => {:active => true},
63 :order => 'position'
64 }
65 }
66
59 67 def self.default
60 68 # Creates a fake default scope so Enumeration.default will check
61 69 # it's type. STI subclasses will automatically add their own
62 70 # types to the finder.
63 71 if self.descends_from_active_record?
64 72 find(:first, :conditions => { :is_default => true, :type => 'Enumeration' })
65 73 else
66 74 # STI classes are
67 75 find(:first, :conditions => { :is_default => true })
68 76 end
69 77 end
70 78
71 79 # Overloaded on concrete classes
72 80 def option_name
73 81 nil
74 82 end
75 83
76 84 # Backwards compatiblity. Can be removed post-0.9
77 85 def opt
78 86 ActiveSupport::Deprecation.warn("Enumeration#opt is deprecated, use the STI classes now. (#{Redmine::Info.issue(3007)})")
79 87 return OptName
80 88 end
81 89
82 90 def before_save
83 91 if is_default? && is_default_changed?
84 92 Enumeration.update_all("is_default = #{connection.quoted_false}", {:type => type})
85 93 end
86 94 end
87 95
88 96 # Overloaded on concrete classes
89 97 def objects_count
90 98 0
91 99 end
92 100
93 101 def in_use?
94 102 self.objects_count != 0
95 103 end
96 104
97 105 alias :destroy_without_reassign :destroy
98 106
99 107 # Destroy the enumeration
100 108 # If a enumeration is specified, objects are reassigned
101 109 def destroy(reassign_to = nil)
102 110 if reassign_to && reassign_to.is_a?(Enumeration)
103 111 self.transfer_relations(reassign_to)
104 112 end
105 113 destroy_without_reassign
106 114 end
107 115
108 116 def <=>(enumeration)
109 117 position <=> enumeration.position
110 118 end
111 119
112 120 def to_s; name end
113 121
114 122 # Returns the Subclasses of Enumeration. Each Subclass needs to be
115 123 # required in development mode.
116 124 #
117 125 # Note: subclasses is protected in ActiveRecord
118 126 def self.get_subclasses
119 127 @@subclasses[Enumeration]
120 128 end
121 129
122 130 private
123 131 def check_integrity
124 132 raise "Can't delete enumeration" if self.in_use?
125 133 end
126 134
127 135 end
128 136
129 137 # Force load the subclasses in development mode
130 138 require_dependency 'time_entry_activity'
131 139 require_dependency 'document_category'
132 140 require_dependency 'issue_priority'
@@ -1,16 +1,19
1 1 <%= error_messages_for 'enumeration' %>
2 2 <div class="box">
3 3 <!--[form:optvalue]-->
4 4 <%= hidden_field 'enumeration', 'type' %>
5 5
6 6 <p><label for="enumeration_name"><%=l(:field_name)%></label>
7 7 <%= text_field 'enumeration', 'name' %></p>
8 8
9 <p><label for="enumeration_active"><%=l(:field_active)%></label>
10 <%= check_box 'enumeration', 'active' %></p>
11
9 12 <p><label for="enumeration_is_default"><%=l(:field_is_default)%></label>
10 13 <%= check_box 'enumeration', 'is_default' %></p>
11 14 <!--[eoform:optvalue]-->
12 15
13 16 <% @enumeration.custom_field_values.each do |value| %>
14 17 <p><%= custom_field_tag_with_label :enumeration, value %></p>
15 18 <% end %>
16 </div> No newline at end of file
19 </div>
@@ -1,29 +1,37
1 1 <h2><%=l(:label_enumerations)%></h2>
2 2
3 3 <% Enumeration.get_subclasses.each do |klass| %>
4 4 <h3><%= l(klass::OptionName) %></h3>
5 5
6 6 <% enumerations = klass.all %>
7 7 <% if enumerations.any? %>
8 8 <table class="list">
9 <tr>
10 <th><%= l(:field_name) %></th>
11 <th style="width:15%;"><%= l(:field_is_default) %></th>
12 <th style="width:15%;"><%= l(:field_active) %></th>
13 <th style="width:15%;"></th>
14 <th align="center" style="width:10%;"> </th>
15 </tr>
9 16 <% enumerations.each do |enumeration| %>
10 17 <tr class="<%= cycle('odd', 'even') %>">
11 18 <td><%= link_to h(enumeration), :action => 'edit', :id => enumeration %></td>
12 19 <td style="width:15%;"><%= image_tag('true.png') if enumeration.is_default? %></td>
20 <td style="width:15%;"><%= image_tag('true.png') if enumeration.active? %></td>
13 21 <td style="width:15%;"><%= reorder_links('enumeration', {:action => 'update', :id => enumeration}) %></td>
14 22 <td class="buttons">
15 23 <%= link_to l(:button_delete), { :action => 'destroy', :id => enumeration },
16 24 :method => :post,
17 25 :confirm => l(:text_are_you_sure),
18 26 :class => 'icon icon-del' %>
19 27 </td>
20 28 </tr>
21 29 <% end %>
22 30 </table>
23 31 <% reset_cycle %>
24 32 <% end %>
25 33
26 34 <p><%= link_to l(:label_enumeration_new), { :action => 'new', :type => klass.name } %></p>
27 35 <% end %>
28 36
29 37 <% html_title(l(:label_enumerations)) -%>
@@ -1,21 +1,21
1 1 <h2><%= l(:label_spent_time) %></h2>
2 2
3 3 <% labelled_tabular_form_for :time_entry, @time_entry, :url => {:action => 'edit', :id => @time_entry, :project_id => @time_entry.project} do |f| %>
4 4 <%= error_messages_for 'time_entry' %>
5 5 <%= back_url_hidden_field_tag %>
6 6
7 7 <div class="box">
8 8 <p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
9 9 <p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
10 10 <p><%= f.text_field :hours, :size => 6, :required => true %></p>
11 11 <p><%= f.text_field :comments, :size => 100 %></p>
12 <p><%= f.select :activity_id, activity_collection_for_select_options, :required => true %></p>
12 <p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p>
13 13 <% @time_entry.custom_field_values.each do |value| %>
14 14 <p><%= custom_field_tag_with_label :time_entry, value %></p>
15 15 <% end %>
16 16 <%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
17 17 </div>
18 18
19 19 <%= submit_tag l(:button_save) %>
20 20
21 21 <% end %>
@@ -1,830 +1,832
1 1 en:
2 2 date:
3 3 formats:
4 4 # Use the strftime parameters for formats.
5 5 # When no format has been given, it uses default.
6 6 # You can provide other formats here if you like!
7 7 default: "%m/%d/%Y"
8 8 short: "%b %d"
9 9 long: "%B %d, %Y"
10 10
11 11 day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
12 12 abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
13 13
14 14 # Don't forget the nil at the beginning; there's no such thing as a 0th month
15 15 month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
16 16 abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
17 17 # Used in date_select and datime_select.
18 18 order: [ :year, :month, :day ]
19 19
20 20 time:
21 21 formats:
22 22 default: "%m/%d/%Y %I:%M %p"
23 23 time: "%I:%M %p"
24 24 short: "%d %b %H:%M"
25 25 long: "%B %d, %Y %H:%M"
26 26 am: "am"
27 27 pm: "pm"
28 28
29 29 datetime:
30 30 distance_in_words:
31 31 half_a_minute: "half a minute"
32 32 less_than_x_seconds:
33 33 one: "less than 1 second"
34 34 other: "less than {{count}} seconds"
35 35 x_seconds:
36 36 one: "1 second"
37 37 other: "{{count}} seconds"
38 38 less_than_x_minutes:
39 39 one: "less than a minute"
40 40 other: "less than {{count}} minutes"
41 41 x_minutes:
42 42 one: "1 minute"
43 43 other: "{{count}} minutes"
44 44 about_x_hours:
45 45 one: "about 1 hour"
46 46 other: "about {{count}} hours"
47 47 x_days:
48 48 one: "1 day"
49 49 other: "{{count}} days"
50 50 about_x_months:
51 51 one: "about 1 month"
52 52 other: "about {{count}} months"
53 53 x_months:
54 54 one: "1 month"
55 55 other: "{{count}} months"
56 56 about_x_years:
57 57 one: "about 1 year"
58 58 other: "about {{count}} years"
59 59 over_x_years:
60 60 one: "over 1 year"
61 61 other: "over {{count}} years"
62 62
63 63 number:
64 64 human:
65 65 format:
66 66 delimiter: ""
67 67 precision: 1
68 68 storage_units:
69 69 format: "%n %u"
70 70 units:
71 71 byte:
72 72 one: "Byte"
73 73 other: "Bytes"
74 74 kb: "KB"
75 75 mb: "MB"
76 76 gb: "GB"
77 77 tb: "TB"
78 78
79 79
80 80 # Used in array.to_sentence.
81 81 support:
82 82 array:
83 83 sentence_connector: "and"
84 84 skip_last_comma: false
85 85
86 86 activerecord:
87 87 errors:
88 88 messages:
89 89 inclusion: "is not included in the list"
90 90 exclusion: "is reserved"
91 91 invalid: "is invalid"
92 92 confirmation: "doesn't match confirmation"
93 93 accepted: "must be accepted"
94 94 empty: "can't be empty"
95 95 blank: "can't be blank"
96 96 too_long: "is too long (maximum is {{count}} characters)"
97 97 too_short: "is too short (minimum is {{count}} characters)"
98 98 wrong_length: "is the wrong length (should be {{count}} characters)"
99 99 taken: "has already been taken"
100 100 not_a_number: "is not a number"
101 101 not_a_date: "is not a valid date"
102 102 greater_than: "must be greater than {{count}}"
103 103 greater_than_or_equal_to: "must be greater than or equal to {{count}}"
104 104 equal_to: "must be equal to {{count}}"
105 105 less_than: "must be less than {{count}}"
106 106 less_than_or_equal_to: "must be less than or equal to {{count}}"
107 107 odd: "must be odd"
108 108 even: "must be even"
109 109 greater_than_start_date: "must be greater than start date"
110 110 not_same_project: "doesn't belong to the same project"
111 111 circular_dependency: "This relation would create a circular dependency"
112 112
113 113 actionview_instancetag_blank_option: Please select
114 114
115 115 general_text_No: 'No'
116 116 general_text_Yes: 'Yes'
117 117 general_text_no: 'no'
118 118 general_text_yes: 'yes'
119 119 general_lang_name: 'English'
120 120 general_csv_separator: ','
121 121 general_csv_decimal_separator: '.'
122 122 general_csv_encoding: ISO-8859-1
123 123 general_pdf_encoding: ISO-8859-1
124 124 general_first_day_of_week: '7'
125 125
126 126 notice_account_updated: Account was successfully updated.
127 127 notice_account_invalid_creditentials: Invalid user or password
128 128 notice_account_password_updated: Password was successfully updated.
129 129 notice_account_wrong_password: Wrong password
130 130 notice_account_register_done: Account was successfully created. To activate your account, click on the link that was emailed to you.
131 131 notice_account_unknown_email: Unknown user.
132 132 notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
133 133 notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
134 134 notice_account_activated: Your account has been activated. You can now log in.
135 135 notice_successful_create: Successful creation.
136 136 notice_successful_update: Successful update.
137 137 notice_successful_delete: Successful deletion.
138 138 notice_successful_connection: Successful connection.
139 139 notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
140 140 notice_locking_conflict: Data has been updated by another user.
141 141 notice_not_authorized: You are not authorized to access this page.
142 142 notice_email_sent: "An email was sent to {{value}}"
143 143 notice_email_error: "An error occurred while sending mail ({{value}})"
144 144 notice_feeds_access_key_reseted: Your RSS access key was reset.
145 145 notice_failed_to_save_issues: "Failed to save {{count}} issue(s) on {{total}} selected: {{ids}}."
146 146 notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
147 147 notice_account_pending: "Your account was created and is now pending administrator approval."
148 148 notice_default_data_loaded: Default configuration successfully loaded.
149 149 notice_unable_delete_version: Unable to delete version.
150 150
151 151 error_can_t_load_default_data: "Default configuration could not be loaded: {{value}}"
152 152 error_scm_not_found: "The entry or revision was not found in the repository."
153 153 error_scm_command_failed: "An error occurred when trying to access the repository: {{value}}"
154 154 error_scm_annotate: "The entry does not exist or can not be annotated."
155 155 error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
156 156 error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
157 157 error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
158 158
159 159 warning_attachments_not_saved: "{{count}} file(s) could not be saved."
160 160
161 161 mail_subject_lost_password: "Your {{value}} password"
162 162 mail_body_lost_password: 'To change your password, click on the following link:'
163 163 mail_subject_register: "Your {{value}} account activation"
164 164 mail_body_register: 'To activate your account, click on the following link:'
165 165 mail_body_account_information_external: "You can use your {{value}} account to log in."
166 166 mail_body_account_information: Your account information
167 167 mail_subject_account_activation_request: "{{value}} account activation request"
168 168 mail_body_account_activation_request: "A new user ({{value}}) has registered. The account is pending your approval:"
169 169 mail_subject_reminder: "{{count}} issue(s) due in the next days"
170 170 mail_body_reminder: "{{count}} issue(s) that are assigned to you are due in the next {{days}} days:"
171 171 mail_subject_wiki_content_added: "'{{page}}' wiki page has been added"
172 172 mail_body_wiki_content_added: "The '{{page}}' wiki page has been added by {{author}}."
173 173 mail_subject_wiki_content_updated: "'{{page}}' wiki page has been updated"
174 174 mail_body_wiki_content_updated: "The '{{page}}' wiki page has been updated by {{author}}."
175 175
176 176 gui_validation_error: 1 error
177 177 gui_validation_error_plural: "{{count}} errors"
178 178
179 179 field_name: Name
180 180 field_description: Description
181 181 field_summary: Summary
182 182 field_is_required: Required
183 183 field_firstname: Firstname
184 184 field_lastname: Lastname
185 185 field_mail: Email
186 186 field_filename: File
187 187 field_filesize: Size
188 188 field_downloads: Downloads
189 189 field_author: Author
190 190 field_created_on: Created
191 191 field_updated_on: Updated
192 192 field_field_format: Format
193 193 field_is_for_all: For all projects
194 194 field_possible_values: Possible values
195 195 field_regexp: Regular expression
196 196 field_min_length: Minimum length
197 197 field_max_length: Maximum length
198 198 field_value: Value
199 199 field_category: Category
200 200 field_title: Title
201 201 field_project: Project
202 202 field_issue: Issue
203 203 field_status: Status
204 204 field_notes: Notes
205 205 field_is_closed: Issue closed
206 206 field_is_default: Default value
207 207 field_tracker: Tracker
208 208 field_subject: Subject
209 209 field_due_date: Due date
210 210 field_assigned_to: Assigned to
211 211 field_priority: Priority
212 212 field_fixed_version: Target version
213 213 field_user: User
214 214 field_role: Role
215 215 field_homepage: Homepage
216 216 field_is_public: Public
217 217 field_parent: Subproject of
218 218 field_is_in_chlog: Issues displayed in changelog
219 219 field_is_in_roadmap: Issues displayed in roadmap
220 220 field_login: Login
221 221 field_mail_notification: Email notifications
222 222 field_admin: Administrator
223 223 field_last_login_on: Last connection
224 224 field_language: Language
225 225 field_effective_date: Date
226 226 field_password: Password
227 227 field_new_password: New password
228 228 field_password_confirmation: Confirmation
229 229 field_version: Version
230 230 field_type: Type
231 231 field_host: Host
232 232 field_port: Port
233 233 field_account: Account
234 234 field_base_dn: Base DN
235 235 field_attr_login: Login attribute
236 236 field_attr_firstname: Firstname attribute
237 237 field_attr_lastname: Lastname attribute
238 238 field_attr_mail: Email attribute
239 239 field_onthefly: On-the-fly user creation
240 240 field_start_date: Start
241 241 field_done_ratio: % Done
242 242 field_auth_source: Authentication mode
243 243 field_hide_mail: Hide my email address
244 244 field_comments: Comment
245 245 field_url: URL
246 246 field_start_page: Start page
247 247 field_subproject: Subproject
248 248 field_hours: Hours
249 249 field_activity: Activity
250 250 field_spent_on: Date
251 251 field_identifier: Identifier
252 252 field_is_filter: Used as a filter
253 253 field_issue_to: Related issue
254 254 field_delay: Delay
255 255 field_assignable: Issues can be assigned to this role
256 256 field_redirect_existing_links: Redirect existing links
257 257 field_estimated_hours: Estimated time
258 258 field_column_names: Columns
259 259 field_time_zone: Time zone
260 260 field_searchable: Searchable
261 261 field_default_value: Default value
262 262 field_comments_sorting: Display comments
263 263 field_parent_title: Parent page
264 264 field_editable: Editable
265 265 field_watcher: Watcher
266 266 field_identity_url: OpenID URL
267 267 field_content: Content
268 268 field_group_by: Group results by
269 269
270 270 setting_app_title: Application title
271 271 setting_app_subtitle: Application subtitle
272 272 setting_welcome_text: Welcome text
273 273 setting_default_language: Default language
274 274 setting_login_required: Authentication required
275 275 setting_self_registration: Self-registration
276 276 setting_attachment_max_size: Attachment max. size
277 277 setting_issues_export_limit: Issues export limit
278 278 setting_mail_from: Emission email address
279 279 setting_bcc_recipients: Blind carbon copy recipients (bcc)
280 280 setting_plain_text_mail: Plain text mail (no HTML)
281 281 setting_host_name: Host name and path
282 282 setting_text_formatting: Text formatting
283 283 setting_wiki_compression: Wiki history compression
284 284 setting_feeds_limit: Feed content limit
285 285 setting_default_projects_public: New projects are public by default
286 286 setting_autofetch_changesets: Autofetch commits
287 287 setting_sys_api_enabled: Enable WS for repository management
288 288 setting_commit_ref_keywords: Referencing keywords
289 289 setting_commit_fix_keywords: Fixing keywords
290 290 setting_autologin: Autologin
291 291 setting_date_format: Date format
292 292 setting_time_format: Time format
293 293 setting_cross_project_issue_relations: Allow cross-project issue relations
294 294 setting_issue_list_default_columns: Default columns displayed on the issue list
295 295 setting_repositories_encodings: Repositories encodings
296 296 setting_commit_logs_encoding: Commit messages encoding
297 297 setting_emails_footer: Emails footer
298 298 setting_protocol: Protocol
299 299 setting_per_page_options: Objects per page options
300 300 setting_user_format: Users display format
301 301 setting_activity_days_default: Days displayed on project activity
302 302 setting_display_subprojects_issues: Display subprojects issues on main projects by default
303 303 setting_enabled_scm: Enabled SCM
304 304 setting_mail_handler_api_enabled: Enable WS for incoming emails
305 305 setting_mail_handler_api_key: API key
306 306 setting_sequential_project_identifiers: Generate sequential project identifiers
307 307 setting_gravatar_enabled: Use Gravatar user icons
308 308 setting_diff_max_lines_displayed: Max number of diff lines displayed
309 309 setting_file_max_size_displayed: Max size of text files displayed inline
310 310 setting_repository_log_display_limit: Maximum number of revisions displayed on file log
311 311 setting_openid: Allow OpenID login and registration
312 312 setting_password_min_length: Minimum password length
313 313 setting_new_project_user_role_id: Role given to a non-admin user who creates a project
314 314
315 315 permission_add_project: Create project
316 316 permission_edit_project: Edit project
317 317 permission_select_project_modules: Select project modules
318 318 permission_manage_members: Manage members
319 319 permission_manage_versions: Manage versions
320 320 permission_manage_categories: Manage issue categories
321 321 permission_add_issues: Add issues
322 322 permission_edit_issues: Edit issues
323 323 permission_manage_issue_relations: Manage issue relations
324 324 permission_add_issue_notes: Add notes
325 325 permission_edit_issue_notes: Edit notes
326 326 permission_edit_own_issue_notes: Edit own notes
327 327 permission_move_issues: Move issues
328 328 permission_delete_issues: Delete issues
329 329 permission_manage_public_queries: Manage public queries
330 330 permission_save_queries: Save queries
331 331 permission_view_gantt: View gantt chart
332 332 permission_view_calendar: View calender
333 333 permission_view_issue_watchers: View watchers list
334 334 permission_add_issue_watchers: Add watchers
335 335 permission_log_time: Log spent time
336 336 permission_view_time_entries: View spent time
337 337 permission_edit_time_entries: Edit time logs
338 338 permission_edit_own_time_entries: Edit own time logs
339 339 permission_manage_news: Manage news
340 340 permission_comment_news: Comment news
341 341 permission_manage_documents: Manage documents
342 342 permission_view_documents: View documents
343 343 permission_manage_files: Manage files
344 344 permission_view_files: View files
345 345 permission_manage_wiki: Manage wiki
346 346 permission_rename_wiki_pages: Rename wiki pages
347 347 permission_delete_wiki_pages: Delete wiki pages
348 348 permission_view_wiki_pages: View wiki
349 349 permission_view_wiki_edits: View wiki history
350 350 permission_edit_wiki_pages: Edit wiki pages
351 351 permission_delete_wiki_pages_attachments: Delete attachments
352 352 permission_protect_wiki_pages: Protect wiki pages
353 353 permission_manage_repository: Manage repository
354 354 permission_browse_repository: Browse repository
355 355 permission_view_changesets: View changesets
356 356 permission_commit_access: Commit access
357 357 permission_manage_boards: Manage boards
358 358 permission_view_messages: View messages
359 359 permission_add_messages: Post messages
360 360 permission_edit_messages: Edit messages
361 361 permission_edit_own_messages: Edit own messages
362 362 permission_delete_messages: Delete messages
363 363 permission_delete_own_messages: Delete own messages
364 364
365 365 project_module_issue_tracking: Issue tracking
366 366 project_module_time_tracking: Time tracking
367 367 project_module_news: News
368 368 project_module_documents: Documents
369 369 project_module_files: Files
370 370 project_module_wiki: Wiki
371 371 project_module_repository: Repository
372 372 project_module_boards: Boards
373 373
374 374 label_user: User
375 375 label_user_plural: Users
376 376 label_user_new: New user
377 377 label_project: Project
378 378 label_project_new: New project
379 379 label_project_plural: Projects
380 380 label_x_projects:
381 381 zero: no projects
382 382 one: 1 project
383 383 other: "{{count}} projects"
384 384 label_project_all: All Projects
385 385 label_project_latest: Latest projects
386 386 label_issue: Issue
387 387 label_issue_new: New issue
388 388 label_issue_plural: Issues
389 389 label_issue_view_all: View all issues
390 390 label_issues_by: "Issues by {{value}}"
391 391 label_issue_added: Issue added
392 392 label_issue_updated: Issue updated
393 393 label_document: Document
394 394 label_document_new: New document
395 395 label_document_plural: Documents
396 396 label_document_added: Document added
397 397 label_role: Role
398 398 label_role_plural: Roles
399 399 label_role_new: New role
400 400 label_role_and_permissions: Roles and permissions
401 401 label_member: Member
402 402 label_member_new: New member
403 403 label_member_plural: Members
404 404 label_tracker: Tracker
405 405 label_tracker_plural: Trackers
406 406 label_tracker_new: New tracker
407 407 label_workflow: Workflow
408 408 label_issue_status: Issue status
409 409 label_issue_status_plural: Issue statuses
410 410 label_issue_status_new: New status
411 411 label_issue_category: Issue category
412 412 label_issue_category_plural: Issue categories
413 413 label_issue_category_new: New category
414 414 label_custom_field: Custom field
415 415 label_custom_field_plural: Custom fields
416 416 label_custom_field_new: New custom field
417 417 label_enumerations: Enumerations
418 418 label_enumeration_new: New value
419 419 label_information: Information
420 420 label_information_plural: Information
421 421 label_please_login: Please log in
422 422 label_register: Register
423 423 label_login_with_open_id_option: or login with OpenID
424 424 label_password_lost: Lost password
425 425 label_home: Home
426 426 label_my_page: My page
427 427 label_my_account: My account
428 428 label_my_projects: My projects
429 429 label_administration: Administration
430 430 label_login: Sign in
431 431 label_logout: Sign out
432 432 label_help: Help
433 433 label_reported_issues: Reported issues
434 434 label_assigned_to_me_issues: Issues assigned to me
435 435 label_last_login: Last connection
436 436 label_registered_on: Registered on
437 437 label_activity: Activity
438 438 label_overall_activity: Overall activity
439 439 label_user_activity: "{{value}}'s activity"
440 440 label_new: New
441 441 label_logged_as: Logged in as
442 442 label_environment: Environment
443 443 label_authentication: Authentication
444 444 label_auth_source: Authentication mode
445 445 label_auth_source_new: New authentication mode
446 446 label_auth_source_plural: Authentication modes
447 447 label_subproject_plural: Subprojects
448 448 label_and_its_subprojects: "{{value}} and its subprojects"
449 449 label_min_max_length: Min - Max length
450 450 label_list: List
451 451 label_date: Date
452 452 label_integer: Integer
453 453 label_float: Float
454 454 label_boolean: Boolean
455 455 label_string: Text
456 456 label_text: Long text
457 457 label_attribute: Attribute
458 458 label_attribute_plural: Attributes
459 459 label_download: "{{count}} Download"
460 460 label_download_plural: "{{count}} Downloads"
461 461 label_no_data: No data to display
462 462 label_change_status: Change status
463 463 label_history: History
464 464 label_attachment: File
465 465 label_attachment_new: New file
466 466 label_attachment_delete: Delete file
467 467 label_attachment_plural: Files
468 468 label_file_added: File added
469 469 label_report: Report
470 470 label_report_plural: Reports
471 471 label_news: News
472 472 label_news_new: Add news
473 473 label_news_plural: News
474 474 label_news_latest: Latest news
475 475 label_news_view_all: View all news
476 476 label_news_added: News added
477 477 label_change_log: Change log
478 478 label_settings: Settings
479 479 label_overview: Overview
480 480 label_version: Version
481 481 label_version_new: New version
482 482 label_version_plural: Versions
483 483 label_confirmation: Confirmation
484 484 label_export_to: 'Also available in:'
485 485 label_read: Read...
486 486 label_public_projects: Public projects
487 487 label_open_issues: open
488 488 label_open_issues_plural: open
489 489 label_closed_issues: closed
490 490 label_closed_issues_plural: closed
491 491 label_x_open_issues_abbr_on_total:
492 492 zero: 0 open / {{total}}
493 493 one: 1 open / {{total}}
494 494 other: "{{count}} open / {{total}}"
495 495 label_x_open_issues_abbr:
496 496 zero: 0 open
497 497 one: 1 open
498 498 other: "{{count}} open"
499 499 label_x_closed_issues_abbr:
500 500 zero: 0 closed
501 501 one: 1 closed
502 502 other: "{{count}} closed"
503 503 label_total: Total
504 504 label_permissions: Permissions
505 505 label_current_status: Current status
506 506 label_new_statuses_allowed: New statuses allowed
507 507 label_all: all
508 508 label_none: none
509 509 label_nobody: nobody
510 510 label_next: Next
511 511 label_previous: Previous
512 512 label_used_by: Used by
513 513 label_details: Details
514 514 label_add_note: Add a note
515 515 label_per_page: Per page
516 516 label_calendar: Calendar
517 517 label_months_from: months from
518 518 label_gantt: Gantt
519 519 label_internal: Internal
520 520 label_last_changes: "last {{count}} changes"
521 521 label_change_view_all: View all changes
522 522 label_personalize_page: Personalize this page
523 523 label_comment: Comment
524 524 label_comment_plural: Comments
525 525 label_x_comments:
526 526 zero: no comments
527 527 one: 1 comment
528 528 other: "{{count}} comments"
529 529 label_comment_add: Add a comment
530 530 label_comment_added: Comment added
531 531 label_comment_delete: Delete comments
532 532 label_query: Custom query
533 533 label_query_plural: Custom queries
534 534 label_query_new: New query
535 535 label_filter_add: Add filter
536 536 label_filter_plural: Filters
537 537 label_equals: is
538 538 label_not_equals: is not
539 539 label_in_less_than: in less than
540 540 label_in_more_than: in more than
541 541 label_greater_or_equal: '>='
542 542 label_less_or_equal: '<='
543 543 label_in: in
544 544 label_today: today
545 545 label_all_time: all time
546 546 label_yesterday: yesterday
547 547 label_this_week: this week
548 548 label_last_week: last week
549 549 label_last_n_days: "last {{count}} days"
550 550 label_this_month: this month
551 551 label_last_month: last month
552 552 label_this_year: this year
553 553 label_date_range: Date range
554 554 label_less_than_ago: less than days ago
555 555 label_more_than_ago: more than days ago
556 556 label_ago: days ago
557 557 label_contains: contains
558 558 label_not_contains: doesn't contain
559 559 label_day_plural: days
560 560 label_repository: Repository
561 561 label_repository_plural: Repositories
562 562 label_browse: Browse
563 563 label_modification: "{{count}} change"
564 564 label_modification_plural: "{{count}} changes"
565 565 label_branch: Branch
566 566 label_tag: Tag
567 567 label_revision: Revision
568 568 label_revision_plural: Revisions
569 569 label_associated_revisions: Associated revisions
570 570 label_added: added
571 571 label_modified: modified
572 572 label_copied: copied
573 573 label_renamed: renamed
574 574 label_deleted: deleted
575 575 label_latest_revision: Latest revision
576 576 label_latest_revision_plural: Latest revisions
577 577 label_view_revisions: View revisions
578 578 label_view_all_revisions: View all revisions
579 579 label_max_size: Maximum size
580 580 label_sort_highest: Move to top
581 581 label_sort_higher: Move up
582 582 label_sort_lower: Move down
583 583 label_sort_lowest: Move to bottom
584 584 label_roadmap: Roadmap
585 585 label_roadmap_due_in: "Due in {{value}}"
586 586 label_roadmap_overdue: "{{value}} late"
587 587 label_roadmap_no_issues: No issues for this version
588 588 label_search: Search
589 589 label_result_plural: Results
590 590 label_all_words: All words
591 591 label_wiki: Wiki
592 592 label_wiki_edit: Wiki edit
593 593 label_wiki_edit_plural: Wiki edits
594 594 label_wiki_page: Wiki page
595 595 label_wiki_page_plural: Wiki pages
596 596 label_index_by_title: Index by title
597 597 label_index_by_date: Index by date
598 598 label_current_version: Current version
599 599 label_preview: Preview
600 600 label_feed_plural: Feeds
601 601 label_changes_details: Details of all changes
602 602 label_issue_tracking: Issue tracking
603 603 label_spent_time: Spent time
604 604 label_f_hour: "{{value}} hour"
605 605 label_f_hour_plural: "{{value}} hours"
606 606 label_time_tracking: Time tracking
607 607 label_change_plural: Changes
608 608 label_statistics: Statistics
609 609 label_commits_per_month: Commits per month
610 610 label_commits_per_author: Commits per author
611 611 label_view_diff: View differences
612 612 label_diff_inline: inline
613 613 label_diff_side_by_side: side by side
614 614 label_options: Options
615 615 label_copy_workflow_from: Copy workflow from
616 616 label_permissions_report: Permissions report
617 617 label_watched_issues: Watched issues
618 618 label_related_issues: Related issues
619 619 label_applied_status: Applied status
620 620 label_loading: Loading...
621 621 label_relation_new: New relation
622 622 label_relation_delete: Delete relation
623 623 label_relates_to: related to
624 624 label_duplicates: duplicates
625 625 label_duplicated_by: duplicated by
626 626 label_blocks: blocks
627 627 label_blocked_by: blocked by
628 628 label_precedes: precedes
629 629 label_follows: follows
630 630 label_end_to_start: end to start
631 631 label_end_to_end: end to end
632 632 label_start_to_start: start to start
633 633 label_start_to_end: start to end
634 634 label_stay_logged_in: Stay logged in
635 635 label_disabled: disabled
636 636 label_show_completed_versions: Show completed versions
637 637 label_me: me
638 638 label_board: Forum
639 639 label_board_new: New forum
640 640 label_board_plural: Forums
641 641 label_topic_plural: Topics
642 642 label_message_plural: Messages
643 643 label_message_last: Last message
644 644 label_message_new: New message
645 645 label_message_posted: Message added
646 646 label_reply_plural: Replies
647 647 label_send_information: Send account information to the user
648 648 label_year: Year
649 649 label_month: Month
650 650 label_week: Week
651 651 label_date_from: From
652 652 label_date_to: To
653 653 label_language_based: Based on user's language
654 654 label_sort_by: "Sort by {{value}}"
655 655 label_send_test_email: Send a test email
656 656 label_feeds_access_key_created_on: "RSS access key created {{value}} ago"
657 657 label_module_plural: Modules
658 658 label_added_time_by: "Added by {{author}} {{age}} ago"
659 659 label_updated_time_by: "Updated by {{author}} {{age}} ago"
660 660 label_updated_time: "Updated {{value}} ago"
661 661 label_jump_to_a_project: Jump to a project...
662 662 label_file_plural: Files
663 663 label_changeset_plural: Changesets
664 664 label_default_columns: Default columns
665 665 label_no_change_option: (No change)
666 666 label_bulk_edit_selected_issues: Bulk edit selected issues
667 667 label_theme: Theme
668 668 label_default: Default
669 669 label_search_titles_only: Search titles only
670 670 label_user_mail_option_all: "For any event on all my projects"
671 671 label_user_mail_option_selected: "For any event on the selected projects only..."
672 672 label_user_mail_option_none: "Only for things I watch or I'm involved in"
673 673 label_user_mail_no_self_notified: "I don't want to be notified of changes that I make myself"
674 674 label_registration_activation_by_email: account activation by email
675 675 label_registration_manual_activation: manual account activation
676 676 label_registration_automatic_activation: automatic account activation
677 677 label_display_per_page: "Per page: {{value}}"
678 678 label_age: Age
679 679 label_change_properties: Change properties
680 680 label_general: General
681 681 label_more: More
682 682 label_scm: SCM
683 683 label_plugins: Plugins
684 684 label_ldap_authentication: LDAP authentication
685 685 label_downloads_abbr: D/L
686 686 label_optional_description: Optional description
687 687 label_add_another_file: Add another file
688 688 label_preferences: Preferences
689 689 label_chronological_order: In chronological order
690 690 label_reverse_chronological_order: In reverse chronological order
691 691 label_planning: Planning
692 692 label_incoming_emails: Incoming emails
693 693 label_generate_key: Generate a key
694 694 label_issue_watchers: Watchers
695 695 label_example: Example
696 696 label_display: Display
697 697 label_sort: Sort
698 698 label_ascending: Ascending
699 699 label_descending: Descending
700 700 label_date_from_to: From {{start}} to {{end}}
701 701 label_wiki_content_added: Wiki page added
702 702 label_wiki_content_updated: Wiki page updated
703 703 label_group: Group
704 704 label_group_plural: Groups
705 705 label_group_new: New group
706 706 label_time_entry_plural: Spent time
707 707
708 708 button_login: Login
709 709 button_submit: Submit
710 710 button_save: Save
711 711 button_check_all: Check all
712 712 button_uncheck_all: Uncheck all
713 713 button_delete: Delete
714 714 button_create: Create
715 715 button_create_and_continue: Create and continue
716 716 button_test: Test
717 717 button_edit: Edit
718 718 button_add: Add
719 719 button_change: Change
720 720 button_apply: Apply
721 721 button_clear: Clear
722 722 button_lock: Lock
723 723 button_unlock: Unlock
724 724 button_download: Download
725 725 button_list: List
726 726 button_view: View
727 727 button_move: Move
728 728 button_back: Back
729 729 button_cancel: Cancel
730 730 button_activate: Activate
731 731 button_sort: Sort
732 732 button_log_time: Log time
733 733 button_rollback: Rollback to this version
734 734 button_watch: Watch
735 735 button_unwatch: Unwatch
736 736 button_reply: Reply
737 737 button_archive: Archive
738 738 button_unarchive: Unarchive
739 739 button_reset: Reset
740 740 button_rename: Rename
741 741 button_change_password: Change password
742 742 button_copy: Copy
743 743 button_annotate: Annotate
744 744 button_update: Update
745 745 button_configure: Configure
746 746 button_quote: Quote
747 747
748 748 status_active: active
749 749 status_registered: registered
750 750 status_locked: locked
751
752 field_active: Active
751 753
752 754 text_select_mail_notifications: Select actions for which email notifications should be sent.
753 755 text_regexp_info: eg. ^[A-Z0-9]+$
754 756 text_min_max_length_info: 0 means no restriction
755 757 text_project_destroy_confirmation: Are you sure you want to delete this project and related data ?
756 758 text_subprojects_destroy_warning: "Its subproject(s): {{value}} will be also deleted."
757 759 text_workflow_edit: Select a role and a tracker to edit the workflow
758 760 text_are_you_sure: Are you sure ?
759 761 text_journal_changed: "{{label}} changed from {{old}} to {{new}}"
760 762 text_journal_set_to: "{{label}} set to {{value}}"
761 763 text_journal_deleted: "{{label}} deleted ({{old}})"
762 764 text_journal_added: "{{label}} {{value}} added"
763 765 text_tip_task_begin_day: task beginning this day
764 766 text_tip_task_end_day: task ending this day
765 767 text_tip_task_begin_end_day: task beginning and ending this day
766 768 text_project_identifier_info: 'Only lower case letters (a-z), numbers and dashes are allowed.<br />Once saved, the identifier can not be changed.'
767 769 text_caracters_maximum: "{{count}} characters maximum."
768 770 text_caracters_minimum: "Must be at least {{count}} characters long."
769 771 text_length_between: "Length between {{min}} and {{max}} characters."
770 772 text_tracker_no_workflow: No workflow defined for this tracker
771 773 text_unallowed_characters: Unallowed characters
772 774 text_comma_separated: Multiple values allowed (comma separated).
773 775 text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
774 776 text_issue_added: "Issue {{id}} has been reported by {{author}}."
775 777 text_issue_updated: "Issue {{id}} has been updated by {{author}}."
776 778 text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content ?
777 779 text_issue_category_destroy_question: "Some issues ({{count}}) are assigned to this category. What do you want to do ?"
778 780 text_issue_category_destroy_assignments: Remove category assignments
779 781 text_issue_category_reassign_to: Reassign issues to this category
780 782 text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
781 783 text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
782 784 text_load_default_configuration: Load the default configuration
783 785 text_status_changed_by_changeset: "Applied in changeset {{value}}."
784 786 text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s) ?'
785 787 text_select_project_modules: 'Select modules to enable for this project:'
786 788 text_default_administrator_account_changed: Default administrator account changed
787 789 text_file_repository_writable: Attachments directory writable
788 790 text_plugin_assets_writable: Plugin assets directory writable
789 791 text_rmagick_available: RMagick available (optional)
790 792 text_destroy_time_entries_question: "{{hours}} hours were reported on the issues you are about to delete. What do you want to do ?"
791 793 text_destroy_time_entries: Delete reported hours
792 794 text_assign_time_entries_to_project: Assign reported hours to the project
793 795 text_reassign_time_entries: 'Reassign reported hours to this issue:'
794 796 text_user_wrote: "{{value}} wrote:"
795 797 text_enumeration_destroy_question: "{{count}} objects are assigned to this value."
796 798 text_enumeration_category_reassign_to: 'Reassign them to this value:'
797 799 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/email.yml and restart the application to enable them."
798 800 text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
799 801 text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
800 802 text_custom_field_possible_values_info: 'One line for each value'
801 803 text_wiki_page_destroy_question: "This page has {{descendants}} child page(s) and descendant(s). What do you want to do?"
802 804 text_wiki_page_nullify_children: "Keep child pages as root pages"
803 805 text_wiki_page_destroy_children: "Delete child pages and all their descendants"
804 806 text_wiki_page_reassign_children: "Reassign child pages to this parent page"
805 807
806 808 default_role_manager: Manager
807 809 default_role_developper: Developer
808 810 default_role_reporter: Reporter
809 811 default_tracker_bug: Bug
810 812 default_tracker_feature: Feature
811 813 default_tracker_support: Support
812 814 default_issue_status_new: New
813 815 default_issue_status_in_progress: In Progress
814 816 default_issue_status_resolved: Resolved
815 817 default_issue_status_feedback: Feedback
816 818 default_issue_status_closed: Closed
817 819 default_issue_status_rejected: Rejected
818 820 default_doc_category_user: User documentation
819 821 default_doc_category_tech: Technical documentation
820 822 default_priority_low: Low
821 823 default_priority_normal: Normal
822 824 default_priority_high: High
823 825 default_priority_urgent: Urgent
824 826 default_priority_immediate: Immediate
825 827 default_activity_design: Design
826 828 default_activity_development: Development
827 829
828 830 enumeration_issue_priorities: Issue priorities
829 831 enumeration_doc_categories: Document categories
830 832 enumeration_activities: Activities (time tracking)
@@ -1,69 +1,88
1 1 ---
2 2 enumerations_001:
3 3 name: Uncategorized
4 4 id: 1
5 5 opt: DCAT
6 6 type: DocumentCategory
7 active: true
7 8 enumerations_002:
8 9 name: User documentation
9 10 id: 2
10 11 opt: DCAT
11 12 type: DocumentCategory
13 active: true
12 14 enumerations_003:
13 15 name: Technical documentation
14 16 id: 3
15 17 opt: DCAT
16 18 type: DocumentCategory
19 active: true
17 20 enumerations_004:
18 21 name: Low
19 22 id: 4
20 23 opt: IPRI
21 24 type: IssuePriority
25 active: true
22 26 enumerations_005:
23 27 name: Normal
24 28 id: 5
25 29 opt: IPRI
26 30 type: IssuePriority
27 31 is_default: true
32 active: true
28 33 enumerations_006:
29 34 name: High
30 35 id: 6
31 36 opt: IPRI
32 37 type: IssuePriority
38 active: true
33 39 enumerations_007:
34 40 name: Urgent
35 41 id: 7
36 42 opt: IPRI
37 43 type: IssuePriority
44 active: true
38 45 enumerations_008:
39 46 name: Immediate
40 47 id: 8
41 48 opt: IPRI
42 49 type: IssuePriority
50 active: true
43 51 enumerations_009:
44 52 name: Design
45 53 id: 9
46 54 opt: ACTI
47 55 type: TimeEntryActivity
56 active: true
48 57 enumerations_010:
49 58 name: Development
50 59 id: 10
51 60 opt: ACTI
52 61 type: TimeEntryActivity
53 62 is_default: true
63 active: true
54 64 enumerations_011:
55 65 name: QA
56 66 id: 11
57 67 opt: ACTI
58 68 type: TimeEntryActivity
69 active: true
59 70 enumerations_012:
60 71 name: Default Enumeration
61 72 id: 12
62 73 opt: ''
63 74 type: Enumeration
64 75 is_default: true
76 active: true
65 77 enumerations_013:
66 78 name: Another Enumeration
67 79 id: 13
68 80 opt: ''
69 81 type: Enumeration
82 active: true
83 enumerations_014:
84 name: Inactive Activity
85 id: 14
86 opt: ACTI
87 type: TimeEntryActivity
88 active: false
@@ -1,404 +1,427
1 # -*- coding: utf-8 -*-
1 2 # redMine - project management software
2 3 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 4 #
4 5 # This program is free software; you can redistribute it and/or
5 6 # modify it under the terms of the GNU General Public License
6 7 # as published by the Free Software Foundation; either version 2
7 8 # of the License, or (at your option) any later version.
8 9 #
9 10 # This program is distributed in the hope that it will be useful,
10 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 13 # GNU General Public License for more details.
13 14 #
14 15 # You should have received a copy of the GNU General Public License
15 16 # along with this program; if not, write to the Free Software
16 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 18
18 19 require File.dirname(__FILE__) + '/../test_helper'
19 20 require 'timelog_controller'
20 21
21 22 # Re-raise errors caught by the controller.
22 23 class TimelogController; def rescue_action(e) raise e end; end
23 24
24 25 class TimelogControllerTest < ActionController::TestCase
25 26 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
26 27
27 28 def setup
28 29 @controller = TimelogController.new
29 30 @request = ActionController::TestRequest.new
30 31 @response = ActionController::TestResponse.new
31 32 end
32 33
33 34 def test_edit_routing
34 35 assert_routing(
35 36 {:method => :get, :path => '/issues/567/time_entries/new'},
36 37 :controller => 'timelog', :action => 'edit', :issue_id => '567'
37 38 )
38 39 assert_routing(
39 40 {:method => :get, :path => '/projects/ecookbook/time_entries/new'},
40 41 :controller => 'timelog', :action => 'edit', :project_id => 'ecookbook'
41 42 )
42 43 assert_routing(
43 44 {:method => :get, :path => '/projects/ecookbook/issues/567/time_entries/new'},
44 45 :controller => 'timelog', :action => 'edit', :project_id => 'ecookbook', :issue_id => '567'
45 46 )
46 47
47 48 #TODO: change new form to POST to issue_time_entries_path instead of to edit action
48 49 #TODO: change edit form to PUT to time_entry_path
49 50 assert_routing(
50 51 {:method => :get, :path => '/time_entries/22/edit'},
51 52 :controller => 'timelog', :action => 'edit', :id => '22'
52 53 )
53 54 end
54 55
55 56 def test_get_edit
56 57 @request.session[:user_id] = 3
57 58 get :edit, :project_id => 1
58 59 assert_response :success
59 60 assert_template 'edit'
60 61 # Default activity selected
61 62 assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
62 63 :content => 'Development'
63 64 end
64 65
65 66 def test_get_edit_existing_time
66 67 @request.session[:user_id] = 2
67 68 get :edit, :id => 2, :project_id => nil
68 69 assert_response :success
69 70 assert_template 'edit'
70 71 # Default activity selected
71 72 assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/timelog/edit/2' }
72 73 end
73 74
75 def test_get_edit_should_only_show_active_time_entry_activities
76 @request.session[:user_id] = 3
77 get :edit, :project_id => 1
78 assert_response :success
79 assert_template 'edit'
80 assert_no_tag :tag => 'option', :content => 'Inactive Activity'
81
82 end
83
84 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
85 te = TimeEntry.find(1)
86 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
87 te.save!
88
89 @request.session[:user_id] = 1
90 get :edit, :project_id => 1, :id => 1
91 assert_response :success
92 assert_template 'edit'
93 # Blank option since nothing is pre-selected
94 assert_tag :tag => 'option', :content => '--- Please select ---'
95 end
96
74 97 def test_post_edit
75 98 # TODO: should POST to issues’ time log instead of project. change form
76 99 # and routing
77 100 @request.session[:user_id] = 3
78 101 post :edit, :project_id => 1,
79 102 :time_entry => {:comments => 'Some work on TimelogControllerTest',
80 103 # Not the default activity
81 104 :activity_id => '11',
82 105 :spent_on => '2008-03-14',
83 106 :issue_id => '1',
84 107 :hours => '7.3'}
85 108 assert_redirected_to :action => 'details', :project_id => 'ecookbook'
86 109
87 110 i = Issue.find(1)
88 111 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
89 112 assert_not_nil t
90 113 assert_equal 11, t.activity_id
91 114 assert_equal 7.3, t.hours
92 115 assert_equal 3, t.user_id
93 116 assert_equal i, t.issue
94 117 assert_equal i.project, t.project
95 118 end
96 119
97 120 def test_update
98 121 entry = TimeEntry.find(1)
99 122 assert_equal 1, entry.issue_id
100 123 assert_equal 2, entry.user_id
101 124
102 125 @request.session[:user_id] = 1
103 126 post :edit, :id => 1,
104 127 :time_entry => {:issue_id => '2',
105 128 :hours => '8'}
106 129 assert_redirected_to :action => 'details', :project_id => 'ecookbook'
107 130 entry.reload
108 131
109 132 assert_equal 8, entry.hours
110 133 assert_equal 2, entry.issue_id
111 134 assert_equal 2, entry.user_id
112 135 end
113 136
114 137 def test_destroy_routing
115 138 #TODO: use DELETE to time_entry_path
116 139 assert_routing(
117 140 {:method => :post, :path => '/time_entries/55/destroy'},
118 141 :controller => 'timelog', :action => 'destroy', :id => '55'
119 142 )
120 143 end
121 144
122 145 def test_destroy
123 146 @request.session[:user_id] = 2
124 147 post :destroy, :id => 1
125 148 assert_redirected_to :action => 'details', :project_id => 'ecookbook'
126 149 assert_nil TimeEntry.find_by_id(1)
127 150 end
128 151
129 152 def test_report_routing
130 153 assert_routing(
131 154 {:method => :get, :path => '/projects/567/time_entries/report'},
132 155 :controller => 'timelog', :action => 'report', :project_id => '567'
133 156 )
134 157 assert_routing(
135 158 {:method => :get, :path => '/projects/567/time_entries/report.csv'},
136 159 :controller => 'timelog', :action => 'report', :project_id => '567', :format => 'csv'
137 160 )
138 161 end
139 162
140 163 def test_report_no_criteria
141 164 get :report, :project_id => 1
142 165 assert_response :success
143 166 assert_template 'report'
144 167 end
145 168
146 169 def test_report_routing_for_all_projects
147 170 assert_routing(
148 171 {:method => :get, :path => '/time_entries/report'},
149 172 :controller => 'timelog', :action => 'report'
150 173 )
151 174 end
152 175
153 176 def test_report_all_projects
154 177 get :report
155 178 assert_response :success
156 179 assert_template 'report'
157 180 end
158 181
159 182 def test_report_all_projects_denied
160 183 r = Role.anonymous
161 184 r.permissions.delete(:view_time_entries)
162 185 r.permissions_will_change!
163 186 r.save
164 187 get :report
165 188 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftime_entries%2Freport'
166 189 end
167 190
168 191 def test_report_all_projects_one_criteria
169 192 get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
170 193 assert_response :success
171 194 assert_template 'report'
172 195 assert_not_nil assigns(:total_hours)
173 196 assert_equal "8.65", "%.2f" % assigns(:total_hours)
174 197 end
175 198
176 199 def test_report_all_time
177 200 get :report, :project_id => 1, :criterias => ['project', 'issue']
178 201 assert_response :success
179 202 assert_template 'report'
180 203 assert_not_nil assigns(:total_hours)
181 204 assert_equal "162.90", "%.2f" % assigns(:total_hours)
182 205 end
183 206
184 207 def test_report_all_time_by_day
185 208 get :report, :project_id => 1, :criterias => ['project', 'issue'], :columns => 'day'
186 209 assert_response :success
187 210 assert_template 'report'
188 211 assert_not_nil assigns(:total_hours)
189 212 assert_equal "162.90", "%.2f" % assigns(:total_hours)
190 213 assert_tag :tag => 'th', :content => '2007-03-12'
191 214 end
192 215
193 216 def test_report_one_criteria
194 217 get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
195 218 assert_response :success
196 219 assert_template 'report'
197 220 assert_not_nil assigns(:total_hours)
198 221 assert_equal "8.65", "%.2f" % assigns(:total_hours)
199 222 end
200 223
201 224 def test_report_two_criterias
202 225 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
203 226 assert_response :success
204 227 assert_template 'report'
205 228 assert_not_nil assigns(:total_hours)
206 229 assert_equal "162.90", "%.2f" % assigns(:total_hours)
207 230 end
208 231
209 232 def test_report_at_issue_level
210 233 get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
211 234 assert_response :success
212 235 assert_template 'report'
213 236 assert_not_nil assigns(:total_hours)
214 237 assert_equal "154.25", "%.2f" % assigns(:total_hours)
215 238 end
216 239
217 240 def test_report_custom_field_criteria
218 241 get :report, :project_id => 1, :criterias => ['project', 'cf_1']
219 242 assert_response :success
220 243 assert_template 'report'
221 244 assert_not_nil assigns(:total_hours)
222 245 assert_not_nil assigns(:criterias)
223 246 assert_equal 2, assigns(:criterias).size
224 247 assert_equal "162.90", "%.2f" % assigns(:total_hours)
225 248 # Custom field column
226 249 assert_tag :tag => 'th', :content => 'Database'
227 250 # Custom field row
228 251 assert_tag :tag => 'td', :content => 'MySQL',
229 252 :sibling => { :tag => 'td', :attributes => { :class => 'hours' },
230 253 :child => { :tag => 'span', :attributes => { :class => 'hours hours-int' },
231 254 :content => '1' }}
232 255 end
233 256
234 257 def test_report_one_criteria_no_result
235 258 get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project']
236 259 assert_response :success
237 260 assert_template 'report'
238 261 assert_not_nil assigns(:total_hours)
239 262 assert_equal "0.00", "%.2f" % assigns(:total_hours)
240 263 end
241 264
242 265 def test_report_all_projects_csv_export
243 266 get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
244 267 assert_response :success
245 268 assert_equal 'text/csv', @response.content_type
246 269 lines = @response.body.chomp.split("\n")
247 270 # Headers
248 271 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
249 272 # Total row
250 273 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
251 274 end
252 275
253 276 def test_report_csv_export
254 277 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
255 278 assert_response :success
256 279 assert_equal 'text/csv', @response.content_type
257 280 lines = @response.body.chomp.split("\n")
258 281 # Headers
259 282 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
260 283 # Total row
261 284 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
262 285 end
263 286
264 287 def test_details_all_projects
265 288 get :details
266 289 assert_response :success
267 290 assert_template 'details'
268 291 assert_not_nil assigns(:total_hours)
269 292 assert_equal "162.90", "%.2f" % assigns(:total_hours)
270 293 end
271 294
272 295 def test_project_details_routing
273 296 assert_routing(
274 297 {:method => :get, :path => '/projects/567/time_entries'},
275 298 :controller => 'timelog', :action => 'details', :project_id => '567'
276 299 )
277 300 end
278 301
279 302 def test_details_at_project_level
280 303 get :details, :project_id => 1
281 304 assert_response :success
282 305 assert_template 'details'
283 306 assert_not_nil assigns(:entries)
284 307 assert_equal 4, assigns(:entries).size
285 308 # project and subproject
286 309 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
287 310 assert_not_nil assigns(:total_hours)
288 311 assert_equal "162.90", "%.2f" % assigns(:total_hours)
289 312 # display all time by default
290 313 assert_equal '2007-03-11'.to_date, assigns(:from)
291 314 assert_equal '2007-04-22'.to_date, assigns(:to)
292 315 end
293 316
294 317 def test_details_at_project_level_with_date_range
295 318 get :details, :project_id => 1, :from => '2007-03-20', :to => '2007-04-30'
296 319 assert_response :success
297 320 assert_template 'details'
298 321 assert_not_nil assigns(:entries)
299 322 assert_equal 3, assigns(:entries).size
300 323 assert_not_nil assigns(:total_hours)
301 324 assert_equal "12.90", "%.2f" % assigns(:total_hours)
302 325 assert_equal '2007-03-20'.to_date, assigns(:from)
303 326 assert_equal '2007-04-30'.to_date, assigns(:to)
304 327 end
305 328
306 329 def test_details_at_project_level_with_period
307 330 get :details, :project_id => 1, :period => '7_days'
308 331 assert_response :success
309 332 assert_template 'details'
310 333 assert_not_nil assigns(:entries)
311 334 assert_not_nil assigns(:total_hours)
312 335 assert_equal Date.today - 7, assigns(:from)
313 336 assert_equal Date.today, assigns(:to)
314 337 end
315 338
316 339 def test_issue_details_routing
317 340 assert_routing(
318 341 {:method => :get, :path => 'time_entries'},
319 342 :controller => 'timelog', :action => 'details'
320 343 )
321 344 assert_routing(
322 345 {:method => :get, :path => '/issues/234/time_entries'},
323 346 :controller => 'timelog', :action => 'details', :issue_id => '234'
324 347 )
325 348 # TODO: issue detail page shouldnt link to project_issue_time_entries_path but to normal issues one
326 349 # doesnt seem to have effect on resulting page so controller can be left untouched
327 350 assert_routing(
328 351 {:method => :get, :path => '/projects/ecookbook/issues/123/time_entries'},
329 352 :controller => 'timelog', :action => 'details', :project_id => 'ecookbook', :issue_id => '123'
330 353 )
331 354 end
332 355
333 356 def test_details_at_issue_level
334 357 get :details, :issue_id => 1
335 358 assert_response :success
336 359 assert_template 'details'
337 360 assert_not_nil assigns(:entries)
338 361 assert_equal 2, assigns(:entries).size
339 362 assert_not_nil assigns(:total_hours)
340 363 assert_equal 154.25, assigns(:total_hours)
341 364 # display all time by default
342 365 assert_equal '2007-03-11'.to_date, assigns(:from)
343 366 assert_equal '2007-04-22'.to_date, assigns(:to)
344 367 end
345 368
346 369 def test_details_formatted_routing
347 370 assert_routing(
348 371 {:method => :get, :path => 'time_entries.atom'},
349 372 :controller => 'timelog', :action => 'details', :format => 'atom'
350 373 )
351 374 assert_routing(
352 375 {:method => :get, :path => 'time_entries.csv'},
353 376 :controller => 'timelog', :action => 'details', :format => 'csv'
354 377 )
355 378 end
356 379
357 380 def test_details_for_project_formatted_routing
358 381 assert_routing(
359 382 {:method => :get, :path => '/projects/567/time_entries.atom'},
360 383 :controller => 'timelog', :action => 'details', :format => 'atom', :project_id => '567'
361 384 )
362 385 assert_routing(
363 386 {:method => :get, :path => '/projects/567/time_entries.csv'},
364 387 :controller => 'timelog', :action => 'details', :format => 'csv', :project_id => '567'
365 388 )
366 389 end
367 390
368 391 def test_details_for_issue_formatted_routing
369 392 assert_routing(
370 393 {:method => :get, :path => '/projects/ecookbook/issues/123/time_entries.atom'},
371 394 :controller => 'timelog', :action => 'details', :project_id => 'ecookbook', :issue_id => '123', :format => 'atom'
372 395 )
373 396 assert_routing(
374 397 {:method => :get, :path => '/projects/ecookbook/issues/123/time_entries.csv'},
375 398 :controller => 'timelog', :action => 'details', :project_id => 'ecookbook', :issue_id => '123', :format => 'csv'
376 399 )
377 400 end
378 401
379 402 def test_details_atom_feed
380 403 get :details, :project_id => 1, :format => 'atom'
381 404 assert_response :success
382 405 assert_equal 'application/atom+xml', @response.content_type
383 406 assert_not_nil assigns(:items)
384 407 assert assigns(:items).first.is_a?(TimeEntry)
385 408 end
386 409
387 410 def test_details_all_projects_csv_export
388 411 Setting.date_format = '%m/%d/%Y'
389 412 get :details, :format => 'csv'
390 413 assert_response :success
391 414 assert_equal 'text/csv', @response.content_type
392 415 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
393 416 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
394 417 end
395 418
396 419 def test_details_csv_export
397 420 Setting.date_format = '%m/%d/%Y'
398 421 get :details, :project_id => 1, :format => 'csv'
399 422 assert_response :success
400 423 assert_equal 'text/csv', @response.content_type
401 424 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
402 425 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
403 426 end
404 427 end
General Comments 0
You need to be logged in to leave comments. Login now