Compare commits

..
37 Commits
Author SHA1 Message Date
Jean-Philippe Lang 264274212c Merged r4965 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4967 e93f8b46-1217-0410-a6f0-8f06a7374b81
2011-02-28 20:14:54 +00:00
Jean-Philippe Lang 0949faa787 Merged r4577 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4905 e93f8b46-1217-0410-a6f0-8f06a7374b81
2011-02-21 11:13:37 +00:00
Jean-Philippe Lang aba0dc0371 Updates for 1.0.5 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4569 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-23 10:04:53 +00:00
Jean-Philippe Lang 902d765ab7 Merged r4553 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4565 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-23 10:00:35 +00:00
Jean-Philippe Lang c6852b7af2 Merged r4469 from trunk
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4564 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-23 09:59:36 +00:00
Jean-Philippe Lang 0bff40c1e1 Merged r4467 from trunk
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4563 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-23 09:58:18 +00:00
Jean-Philippe Lang 40ca445071 Merged r4561 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4562 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-23 09:57:02 +00:00
Jean-Philippe Lang f9bd713e3e Removed 1.1 specific translations that were unsafely merged in 1.0 (#7162).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4557 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-22 21:05:13 +00:00
Jean-Philippe Lang ba99936295 Restores non english field_start_date translations (#6629, #7016).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4555 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-22 20:48:23 +00:00
Jean-Philippe Lang 63c4fb5b97 Merged r4541 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4543 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-18 18:42:00 +00:00
Jean-Philippe Lang c02ecdd096 Merged r4539 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4540 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-18 18:14:30 +00:00
Jean-Philippe Lang cb30fa49fc Merged r4468 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4538 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-18 17:22:43 +00:00
Jean-Philippe Lang f4ada319d1 Merged r4535 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4536 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-18 17:13:13 +00:00
Jean-Philippe Lang fdaf587652 Merged r4516 from trunk (i18n 0.4.2 gem is now required: 'gem install -v=0.4.2 i18n', see #7013).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4532 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-18 13:53:34 +00:00
Jean-Philippe Lang 142b837271 Backported r4530 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4531 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-18 13:42:50 +00:00
Jean-Philippe Lang bd8e8bc71b Fixed: error when sending notification on wiki edit for bg, es, zh-TW locales (#7024).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4478 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-12-07 22:05:20 +00:00
Jean-Philippe Lang a67f06910b Merged r4449 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4450 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-29 19:34:56 +00:00
Jean-Philippe Lang ed52753a12 Updates for 1.0.4 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4447 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-28 12:47:36 +00:00
Jean-Philippe Lang bac64c9ab4 Backported r4441 to r4444 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4445 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 16:45:07 +00:00
Jean-Philippe Lang b58382ef2e Merged r4386 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4440 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 15:48:30 +00:00
Jean-Philippe Lang 541a371b41 Backported r4357, r4358, r4360 and r4363 to r4367 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4439 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 15:16:26 +00:00
Jean-Philippe Lang bdb888476d Merged r4437 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4438 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 14:47:31 +00:00
Jean-Philippe Lang f5f55359a8 Translations updates.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4436 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 14:40:51 +00:00
Jean-Philippe Lang eb590ce1eb Merged r4428 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4435 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 14:31:29 +00:00
Jean-Philippe Lang db64675310 Merged r4431 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4434 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 14:30:41 +00:00
Jean-Philippe Lang 92b37c0bea Merged r4426 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4433 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-27 14:28:51 +00:00
Jean-Philippe Lang faa461c66a Merged r4422 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4423 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-21 14:26:01 +00:00
Jean-Philippe Lang b5a409791c Merged r4419 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4420 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-20 14:12:35 +00:00
Jean-Philippe Lang 6c362a5a76 Merged r4417 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4418 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-20 14:06:32 +00:00
Jean-Philippe Lang dbb26b08f8 Merged r4414 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4415 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-20 10:23:13 +00:00
Jean-Philippe Lang 2a7a95d746 Backported r4397 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4401 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-14 11:30:53 +00:00
Jean-Philippe Lang c70ae6c735 Merged r4380 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4400 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-14 11:18:23 +00:00
Jean-Philippe Lang e174c10d6d Merged r4385 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4399 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-14 11:17:20 +00:00
Jean-Philippe Lang 2b9a5bf6e2 Merged r4378 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4398 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-14 11:15:53 +00:00
Jean-Philippe Lang d3b536e9a6 Merged r4389 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4390 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-09 19:56:29 +00:00
Jean-Philippe Lang 9b1eda1b22 Fixed a test broken by r4355 (#6786).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4356 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-01 14:47:23 +00:00
Jean-Philippe Lang f1f0704ef8 Merged r4354 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/1.0-stable@4355 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-11-01 13:14:14 +00:00
95 changed files with 4799 additions and 4554 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ class IssuesController < ApplicationController
before_filter :find_optional_project, :only => [:index] before_filter :find_optional_project, :only => [:index]
before_filter :check_for_default_issue_status, :only => [:new, :create] before_filter :check_for_default_issue_status, :only => [:new, :create]
before_filter :build_new_issue_from_params, :only => [:new, :create] before_filter :build_new_issue_from_params, :only => [:new, :create]
accept_key_auth :index, :show accept_key_auth :index, :show, :create, :update, :destroy
rescue_from Query::StatementInvalid, :with => :query_statement_invalid rescue_from Query::StatementInvalid, :with => :query_statement_invalid
@@ -300,6 +300,7 @@ private
render_error l(:error_no_tracker_in_project) render_error l(:error_no_tracker_in_project)
return false return false
end end
@issue.start_date ||= Date.today
if params[:issue].is_a?(Hash) if params[:issue].is_a?(Hash)
@issue.safe_attributes = params[:issue] @issue.safe_attributes = params[:issue]
if User.current.allowed_to?(:add_issue_watchers, @project) && @issue.new_record? if User.current.allowed_to?(:add_issue_watchers, @project) && @issue.new_record?
@@ -307,7 +308,6 @@ private
end end
end end
@issue.author = User.current @issue.author = User.current
@issue.start_date ||= Date.today
@priorities = IssuePriority.all @priorities = IssuePriority.all
@allowed_statuses = @issue.new_statuses_allowed_to(User.current, true) @allowed_statuses = @issue.new_statuses_allowed_to(User.current, true)
end end
+1
View File
@@ -19,6 +19,7 @@ class JournalsController < ApplicationController
before_filter :find_journal, :only => [:edit] before_filter :find_journal, :only => [:edit]
before_filter :find_issue, :only => [:new] before_filter :find_issue, :only => [:new]
before_filter :find_optional_project, :only => [:index] before_filter :find_optional_project, :only => [:index]
before_filter :authorize, :only => [:new, :edit]
accept_key_auth :index accept_key_auth :index
helper :issues helper :issues
+2 -2
View File
@@ -24,7 +24,7 @@ class ProjectsController < ApplicationController
before_filter :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy] before_filter :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy]
before_filter :authorize_global, :only => [:new, :create] before_filter :authorize_global, :only => [:new, :create]
before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ] before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
accept_key_auth :index accept_key_auth :index, :show, :create, :update, :destroy
after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller| after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller|
if controller.request.post? if controller.request.post?
@@ -93,7 +93,7 @@ class ProjectsController < ApplicationController
flash[:notice] = l(:notice_successful_create) flash[:notice] = l(:notice_successful_create)
redirect_to :controller => 'projects', :action => 'settings', :id => @project redirect_to :controller => 'projects', :action => 'settings', :id => @project
} }
format.xml { head :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) } format.xml { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
end end
else else
respond_to do |format| respond_to do |format|
+4
View File
@@ -109,6 +109,10 @@ class VersionsController < ApplicationController
if @version.update_attributes(attributes) if @version.update_attributes(attributes)
flash[:notice] = l(:notice_successful_update) flash[:notice] = l(:notice_successful_update)
redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
else
respond_to do |format|
format.html { render :action => 'edit' }
end
end end
end end
end end
+1 -1
View File
@@ -18,7 +18,7 @@
class Board < ActiveRecord::Base class Board < ActiveRecord::Base
belongs_to :project belongs_to :project
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC" has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
has_many :messages, :dependent => :delete_all, :order => "#{Message.table_name}.created_on DESC" has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id
acts_as_list :scope => :project_id acts_as_list :scope => :project_id
acts_as_watchable acts_as_watchable
+1
View File
@@ -31,6 +31,7 @@ class Group < Principal
def user_added(user) def user_added(user)
members.each do |member| members.each do |member|
next if member.project.nil?
user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id) user_member = Member.find_by_project_id_and_user_id(member.project_id, user.id) || Member.new(:project_id => member.project_id, :user_id => user.id)
member.member_roles.each do |member_role| member.member_roles.each do |member_role|
user_member.member_roles << MemberRole.new(:role => member_role.role, :inherited_from => member_role.id) user_member.member_roles << MemberRole.new(:role => member_role.role, :inherited_from => member_role.id)
+1 -1
View File
@@ -237,7 +237,7 @@ class Issue < ActiveRecord::Base
if !user.allowed_to?(:manage_subtasks, project) if !user.allowed_to?(:manage_subtasks, project)
attrs.delete('parent_issue_id') attrs.delete('parent_issue_id')
elsif !attrs['parent_issue_id'].blank? elsif !attrs['parent_issue_id'].blank?
attrs.delete('parent_issue_id') unless Issue.visible(user).exists?(attrs['parent_issue_id']) attrs.delete('parent_issue_id') unless Issue.visible(user).exists?(attrs['parent_issue_id'].to_i)
end end
end end
+4 -3
View File
@@ -84,14 +84,15 @@ class IssueRelation < ActiveRecord::Base
def set_issue_to_dates def set_issue_to_dates
soonest_start = self.successor_soonest_start soonest_start = self.successor_soonest_start
if soonest_start if soonest_start && issue_to
issue_to.reschedule_after(soonest_start) issue_to.reschedule_after(soonest_start)
end end
end end
def successor_soonest_start def successor_soonest_start
return nil unless (TYPE_PRECEDES == self.relation_type) && (issue_from.start_date || issue_from.due_date) if (TYPE_PRECEDES == self.relation_type) && delay && issue_from && (issue_from.start_date || issue_from.due_date)
(issue_from.due_date || issue_from.start_date) + 1 + delay (issue_from.due_date || issue_from.start_date) + 1 + delay
end
end end
def <=>(relation) def <=>(relation)
+3 -3
View File
@@ -368,15 +368,15 @@ class Query < ActiveRecord::Base
# Returns true if the query is a grouped query # Returns true if the query is a grouped query
def grouped? def grouped?
!group_by.blank? !group_by_column.nil?
end end
def group_by_column def group_by_column
groupable_columns.detect {|c| c.name.to_s == group_by} groupable_columns.detect {|c| c.groupable && c.name.to_s == group_by}
end end
def group_by_statement def group_by_statement
group_by_column.groupable group_by_column.try(:groupable)
end end
def project_statement def project_statement
+1 -1
View File
@@ -2,5 +2,5 @@
<div class="box"> <div class="box">
<p><%= f.text_field :name, :size => 30, :required => true %></p> <p><%= f.text_field :name, :size => 30, :required => true %></p>
<p><%= f.select :assigned_to_id, @project.users.collect{|u| [u.name, u.id]}, :include_blank => true %></p> <p><%= f.select :assigned_to_id, @project.users.sort.collect{|u| [u.name, u.id]}, :include_blank => true %></p>
</div> </div>
+1 -1
View File
@@ -47,7 +47,7 @@
<hr /> <hr />
<div class="contextual"> <div class="contextual">
<%= link_to_remote_if_authorized(l(:button_quote), { :url => {:action => 'reply', :id => @issue} }, :class => 'icon icon-comment') unless @issue.description.blank? %> <%= link_to_remote_if_authorized(l(:button_quote), { :url => {:controller => 'journals', :action => 'new', :id => @issue} }, :class => 'icon icon-comment') unless @issue.description.blank? %>
</div> </div>
<p><strong><%=l(:field_description)%></strong></p> <p><strong><%=l(:field_description)%></strong></p>
+1 -1
View File
@@ -20,7 +20,7 @@
<!-- page specific tags --> <!-- page specific tags -->
<%= yield :header_tags -%> <%= yield :header_tags -%>
</head> </head>
<body class="<%= body_css_classes %>"> <body class="<%=h body_css_classes %>">
<div id="wrapper"> <div id="wrapper">
<div id="wrapper2"> <div id="wrapper2">
<div id="top-menu"> <div id="top-menu">
+3 -3
View File
@@ -5,9 +5,9 @@ function recreateSortables() {
Sortable.destroy('list-left'); Sortable.destroy('list-left');
Sortable.destroy('list-right'); Sortable.destroy('list-right');
Sortable.create("list-top", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('/my/order_blocks?group=top', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-top")})}, only:'mypage-box', tag:'div'}) Sortable.create("list-top", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('<%= url_for(:controller => 'my', :action => 'order_blocks', :group => 'top') %>', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-top")})}, only:'mypage-box', tag:'div'})
Sortable.create("list-left", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('/my/order_blocks?group=left', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-left")})}, only:'mypage-box', tag:'div'}) Sortable.create("list-left", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('<%= url_for(:controller => 'my', :action => 'order_blocks', :group => 'left') %>', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-left")})}, only:'mypage-box', tag:'div'})
Sortable.create("list-right", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('/my/order_blocks?group=right', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-right")})}, only:'mypage-box', tag:'div'}) Sortable.create("list-right", {constraint:false, containment:['list-top','list-left','list-right'], dropOnEmpty:true, handle:'handle', onUpdate:function(){new Ajax.Request('<%= url_for(:controller => 'my', :action => 'order_blocks', :group => 'right') %>', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("list-right")})}, only:'mypage-box', tag:'div'})
} }
function updateSelect() { function updateSelect() {
+2 -2
View File
@@ -6,7 +6,7 @@
<p><%= setting_text_area :welcome_text, :cols => 60, :rows => 5, :class => 'wiki-edit' %></p> <p><%= setting_text_area :welcome_text, :cols => 60, :rows => 5, :class => 'wiki-edit' %></p>
<%= wikitoolbar_for 'settings_welcome_text' %> <%= wikitoolbar_for 'settings_welcome_text' %>
<p><%= setting_text_field :attachment_max_size, :size => 6 %> KB</p> <p><%= setting_text_field :attachment_max_size, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
<p><%= setting_text_field :per_page_options, :size => 20 %><br /> <p><%= setting_text_field :per_page_options, :size => 20 %><br />
<em><%= l(:text_comma_separated) %></em></p> <em><%= l(:text_comma_separated) %></em></p>
@@ -26,7 +26,7 @@
<p><%= setting_text_field :feeds_limit, :size => 6 %></p> <p><%= setting_text_field :feeds_limit, :size => 6 %></p>
<p><%= setting_text_field :file_max_size_displayed, :size => 6 %> KB</p> <p><%= setting_text_field :file_max_size_displayed, :size => 6 %> <%= l(:"number.human.storage_units.units.kb") %></p>
<p><%= setting_text_field :diff_max_lines_displayed, :size => 6 %></p> <p><%= setting_text_field :diff_max_lines_displayed, :size => 6 %></p>
+2
View File
@@ -5,6 +5,7 @@
<% if @workflow_counts.empty? %> <% if @workflow_counts.empty? %>
<p class="nodata"><%= l(:label_no_data) %></p> <p class="nodata"><%= l(:label_no_data) %></p>
<% else %> <% else %>
<div class="autoscroll">
<table class="list"> <table class="list">
<thead> <thead>
<tr> <tr>
@@ -30,4 +31,5 @@
<% end -%> <% end -%>
</tbody> </tbody>
</table> </table>
</div>
<% end %> <% end %>
+12
View File
@@ -106,5 +106,17 @@ module Rails
end end
end end
# TODO: Workaround for #7013 to be removed for 1.2.0
# Loads i18n 0.4.2 before Rails loads any more recent gem
# 0.5.0 is not compatible with the old interpolation syntax
# Plugins will have to migrate to the new syntax for 1.2.0
require 'rubygems'
begin
gem 'i18n', '0.4.2'
rescue Gem::LoadError => load_error
$stderr.puts %(Missing the i18n 0.4.2 gem. Please `gem install -v=0.4.2 i18n`)
exit 1
end
# All that for this: # All that for this:
Rails.boot! Rails.boot!
+2 -2
View File
@@ -84,9 +84,9 @@ ActionMailer::Base.send :include, AsynchronousMailer
module I18n module I18n
module Backend module Backend
module Base module Base
def warn_syntax_deprecation! def warn_syntax_deprecation!(*args)
return if @skip_syntax_deprecation return if @skip_syntax_deprecation
warn "The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.\nDowngrade your i18n gem to 0.3.7 (everything above must be deinstalled) to remove this warning, see http://www.redmine.org/issues/5608 for more information." warn "The {{key}} interpolation syntax in I18n messages is deprecated and will be removed in Redmine 1.2. Please use %{key} instead, see http://www.redmine.org/issues/7013 for more information."
@skip_syntax_deprecation = true @skip_syntax_deprecation = true
end end
end end
+24 -25
View File
@@ -221,6 +221,7 @@ bg:
field_attr_lastname: Атрибут Фамилия (Lastname) field_attr_lastname: Атрибут Фамилия (Lastname)
field_attr_mail: Атрибут Email field_attr_mail: Атрибут Email
field_onthefly: Динамично създаване на потребител field_onthefly: Динамично създаване на потребител
field_start_date: Начална дата
field_done_ratio: % Прогрес field_done_ratio: % Прогрес
field_auth_source: Начин на оторизация field_auth_source: Начин на оторизация
field_hide_mail: Скрий e-mail адреса ми field_hide_mail: Скрий e-mail адреса ми
@@ -321,7 +322,7 @@ bg:
label_registered_on: Регистрация label_registered_on: Регистрация
label_activity: Дейност label_activity: Дейност
label_new: Нов label_new: Нов
label_logged_as: Влязъл като label_logged_as: Здравейте,
label_environment: Среда label_environment: Среда
label_authentication: Оторизация label_authentication: Оторизация
label_auth_source: Начин на оторозация label_auth_source: Начин на оторозация
@@ -808,12 +809,12 @@ bg:
text_wiki_page_destroy_children: Изтриване на страниците деца и всички техни descendants text_wiki_page_destroy_children: Изтриване на страниците деца и всички техни descendants
setting_password_min_length: Минимална дължина на парола setting_password_min_length: Минимална дължина на парола
field_group_by: Групиране на резултатите по field_group_by: Групиране на резултатите по
mail_subject_wiki_content_updated: "Wiki страницата '{{id}}' не беше обновена" mail_subject_wiki_content_updated: "Wiki страницата '{{page}}' не беше обновена"
label_wiki_content_added: Wiki страница беше добавена label_wiki_content_added: Wiki страница беше добавена
mail_subject_wiki_content_added: "Wiki страницата '{{id}}' беше добавена" mail_subject_wiki_content_added: "Wiki страницата '{{page}}' беше добавена"
mail_body_wiki_content_added: Wiki страницата '{{id}}' беше добавена от {{author}}. mail_body_wiki_content_added: Wiki страницата '{{page}}' беше добавена от {{author}}.
label_wiki_content_updated: Wiki страница беше обновена label_wiki_content_updated: Wiki страница беше обновена
mail_body_wiki_content_updated: Wiki страницата '{{id}}' беше обновена от {{author}}. mail_body_wiki_content_updated: Wiki страницата '{{page}}' беше обновена от {{author}}.
permission_add_project: Създаване на проект permission_add_project: Създаване на проект
setting_new_project_user_role_id: Роля, давана на потребител, създаващ проекти, който не е администратор setting_new_project_user_role_id: Роля, давана на потребител, създаващ проекти, който не е администратор
label_view_all_revisions: Разглеждане на всички ревизии label_view_all_revisions: Разглеждане на всички ревизии
@@ -850,8 +851,8 @@ bg:
button_duplicate: Дублиране button_duplicate: Дублиране
button_copy_and_follow: Копиране и продължаване button_copy_and_follow: Копиране и продължаване
label_copy_source: Източник label_copy_source: Източник
setting_issue_done_ratio: Изчисление на процента на готово задачи с setting_issue_done_ratio: Изчисление на процента на готови задачи с
setting_issue_done_ratio_issue_status: Използване на състояниетона задачите setting_issue_done_ratio_issue_status: Използване на състоянието на задачите
error_issue_done_ratios_not_updated: Процентът на завършените задачи не е обновен. error_issue_done_ratios_not_updated: Процентът на завършените задачи не е обновен.
error_workflow_copy_target: Моля изберете тракер(и) и роля (роли). error_workflow_copy_target: Моля изберете тракер(и) и роля (роли).
setting_issue_done_ratio_issue_field: Използване на поле 'задача' setting_issue_done_ratio_issue_field: Използване на поле 'задача'
@@ -896,28 +897,26 @@ bg:
error_can_not_remove_role: Тази роля се използва и не може да бъде изтрита. error_can_not_remove_role: Тази роля се използва и не може да бъде изтрита.
error_can_not_delete_tracker: Този тракер съдържа задачи и не може да бъде изтрит. error_can_not_delete_tracker: Този тракер съдържа задачи и не може да бъде изтрит.
field_principal: Principal field_principal: Principal
label_my_page_block: My page block label_my_page_block: Блокове в личната страница
notice_failed_to_save_members: "Невъзможност за запис на член(ове): {{errors}}." notice_failed_to_save_members: "Невъзможност за запис на член(ове): {{errors}}."
text_zoom_out: Намаляване text_zoom_out: Намаляване
text_zoom_in: Увеличаване text_zoom_in: Увеличаване
notice_unable_delete_time_entry: Невъзможност за изтриване на запис на time log. notice_unable_delete_time_entry: Невъзможност за изтриване на запис на time log.
label_overall_spent_time: Общо употребено време label_overall_spent_time: Общо употребено време
field_time_entries: Log time field_time_entries: Log time
notice_not_authorized_archived_project: The project you're trying to access has been archived. notice_not_authorized_archived_project: Проектът, който се опитвате да видите е архивиран.
text_tip_issue_end_day: issue ending this day text_tip_issue_end_day: задача, завършваща този ден
field_text: Text field field_text: Текстово поле
label_user_mail_option_only_owner: Only for things I am the owner of field_member_of_group: Член на група
field_member_of_group: Assignee's group project_module_gantt: Мрежов график
project_module_gantt: Gantt text_are_you_sure_with_children: Изтриване на задачата и нейните подзадачи?
text_are_you_sure_with_children: Delete issue and all child issues? text_tip_issue_begin_end_day: задача, започваща и завършваща този ден
text_tip_issue_begin_end_day: issue beginning and ending this day setting_default_notification_option: Подразбиращ се начин за известяване
setting_default_notification_option: Default notification option project_module_calendar: Календар
project_module_calendar: Calendar text_tip_issue_begin_day: задача, започваща този ден
label_user_mail_option_only_my_events: Only for things I watch or I'm involved in button_edit_associated_wikipage: "Редактиране на асоциираната Wiki страница: {{page_title}}"
text_tip_issue_begin_day: issue beginning this day
label_user_mail_option_only_assigned: Only for things I am assigned to
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
field_assigned_to_role: Assignee's role field_assigned_to_role: Assignee's role
field_start_date: Start date label_principal_search: "Търсене на потребител или група:"
label_principal_search: "Search for user or group:" label_user_search: "Търсене на потребител:"
label_user_search: "Search for user:" field_visible: Видим
setting_emails_header: Emails header
+1 -2
View File
@@ -252,6 +252,7 @@ bs:
field_attr_lastname: Atribut za prezime field_attr_lastname: Atribut za prezime
field_attr_mail: Atribut za email field_attr_mail: Atribut za email
field_onthefly: 'Kreiranje korisnika "On-the-fly"' field_onthefly: 'Kreiranje korisnika "On-the-fly"'
field_start_date: Početak
field_done_ratio: % Realizovano field_done_ratio: % Realizovano
field_auth_source: Mod za authentifikaciju field_auth_source: Mod za authentifikaciju
field_hide_mail: Sakrij moju email adresu field_hide_mail: Sakrij moju email adresu
@@ -931,7 +932,5 @@ bs:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -2
View File
@@ -264,6 +264,7 @@ ca:
field_attr_lastname: Atribut del cognom field_attr_lastname: Atribut del cognom
field_attr_mail: Atribut del correu electrònic field_attr_mail: Atribut del correu electrònic
field_onthefly: "Creació de l'usuari «al vol»" field_onthefly: "Creació de l'usuari «al vol»"
field_start_date: Inici
field_done_ratio: % realitzat field_done_ratio: % realitzat
field_auth_source: "Mode d'autenticació" field_auth_source: "Mode d'autenticació"
field_hide_mail: "Oculta l'adreça de correu electrònic" field_hide_mail: "Oculta l'adreça de correu electrònic"
@@ -919,7 +920,5 @@ ca:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -237,6 +237,7 @@ cs:
field_attr_lastname: Příjemní (atribut) field_attr_lastname: Příjemní (atribut)
field_attr_mail: Email (atribut) field_attr_mail: Email (atribut)
field_onthefly: Automatické vytváření uživatelů field_onthefly: Automatické vytváření uživatelů
field_start_date: Začátek
field_done_ratio: % Hotovo field_done_ratio: % Hotovo
field_auth_source: Autentifikační mód field_auth_source: Autentifikační mód
field_hide_mail: Nezobrazovat můj email field_hide_mail: Nezobrazovat můj email
@@ -917,6 +918,5 @@ cs:
button_edit_associated_wikipage: "Upravit přiřazenou Wiki stránku: {{page_title}}" button_edit_associated_wikipage: "Upravit přiřazenou Wiki stránku: {{page_title}}"
text_are_you_sure_with_children: Smazat úkol včetně všech podúkolů? text_are_you_sure_with_children: Smazat úkol včetně všech podúkolů?
field_text: Textové pole field_text: Textové pole
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+25 -26
View File
@@ -250,6 +250,7 @@ da:
field_attr_lastname: Efternavn attribut field_attr_lastname: Efternavn attribut
field_attr_mail: Email attribut field_attr_mail: Email attribut
field_onthefly: løbende brugeroprettelse field_onthefly: løbende brugeroprettelse
field_start_date: Start date
field_done_ratio: % Færdig field_done_ratio: % Færdig
field_auth_source: Sikkerhedsmetode field_auth_source: Sikkerhedsmetode
field_hide_mail: Skjul min email field_hide_mail: Skjul min email
@@ -370,7 +371,7 @@ da:
label_reported_issues: Rapporterede sager label_reported_issues: Rapporterede sager
label_assigned_to_me_issues: Sager tildelt mig label_assigned_to_me_issues: Sager tildelt mig
label_last_login: Sidste login tidspunkt label_last_login: Sidste login tidspunkt
label_registered_on: Registeret den label_registered_on: Registreret den
label_activity: Aktivitet label_activity: Aktivitet
label_new: Ny label_new: Ny
label_logged_as: Registreret som label_logged_as: Registreret som
@@ -441,7 +442,7 @@ da:
label_none: intet label_none: intet
label_nobody: ingen label_nobody: ingen
label_next: Næste label_next: Næste
label_previous: Forrig label_previous: Forrige
label_used_by: Brugt af label_used_by: Brugt af
label_details: Detaljer label_details: Detaljer
label_add_note: Tilføj note label_add_note: Tilføj note
@@ -537,7 +538,7 @@ da:
label_view_diff: Vis forskelle label_view_diff: Vis forskelle
label_diff_inline: inline label_diff_inline: inline
label_diff_side_by_side: side om side label_diff_side_by_side: side om side
label_options: Optioner label_options: Formatering
label_copy_workflow_from: Kopier arbejdsgang fra label_copy_workflow_from: Kopier arbejdsgang fra
label_permissions_report: Godkendelsesrapport label_permissions_report: Godkendelsesrapport
label_watched_issues: Overvågede sager label_watched_issues: Overvågede sager
@@ -547,7 +548,7 @@ da:
label_relation_new: Ny relation label_relation_new: Ny relation
label_relation_delete: Slet relation label_relation_delete: Slet relation
label_relates_to: relaterer til label_relates_to: relaterer til
label_duplicates: kopierer label_duplicates: duplikater
label_blocks: blokerer label_blocks: blokerer
label_blocked_by: blokeret af label_blocked_by: blokeret af
label_precedes: kommer før label_precedes: kommer før
@@ -870,8 +871,8 @@ da:
label_version_sharing_tree: Med projekt træ label_version_sharing_tree: Med projekt træ
label_version_sharing_none: Ikke delt label_version_sharing_none: Ikke delt
error_can_not_archive_project: Dette projekt kan ikke arkiveres error_can_not_archive_project: Dette projekt kan ikke arkiveres
button_duplicate: Kopier button_duplicate: Duplikér
button_copy_and_follow: Kopier og overvåg button_copy_and_follow: Kopiér og overvåg
label_copy_source: Kilde label_copy_source: Kilde
setting_issue_done_ratio: Beregn sagsløsning ratio setting_issue_done_ratio: Beregn sagsløsning ratio
setting_issue_done_ratio_issue_status: Benyt sags status setting_issue_done_ratio_issue_status: Benyt sags status
@@ -896,14 +897,14 @@ da:
label_missing_feeds_access_key: Mangler en RSS nøgle label_missing_feeds_access_key: Mangler en RSS nøgle
button_show: Vis button_show: Vis
text_line_separated: Flere væredier tilladt (en linje for hver værdi). text_line_separated: Flere væredier tilladt (en linje for hver værdi).
setting_mail_handler_body_delimiters: Trunker emails efter en af disse linjer setting_mail_handler_body_delimiters: Trunkér emails efter en af disse linjer
permission_add_subprojects: Lav underprojekter permission_add_subprojects: Lav underprojekter
label_subproject_new: Nyt underprojekt label_subproject_new: Nyt underprojekt
text_own_membership_delete_confirmation: |- text_own_membership_delete_confirmation: |-
Du er ved at fjerne en eller flere af dine rettigheder, og kan muligvis ikke redigere projektet bagefter. Du er ved at fjerne en eller flere af dine rettigheder, og kan muligvis ikke redigere projektet bagefter.
Er du sikker på du ønsker at fortsætte? Er du sikker på du ønsker at fortsætte?
label_close_versions: Luk færdige versioner label_close_versions: Luk færdige versioner
label_board_sticky: Sticky label_board_sticky: Klistret
label_board_locked: Låst label_board_locked: Låst
permission_export_wiki_pages: Eksporter wiki sider permission_export_wiki_pages: Eksporter wiki sider
setting_cache_formatted_text: Cache formatteret tekst setting_cache_formatted_text: Cache formatteret tekst
@@ -914,26 +915,24 @@ da:
field_parent_issue: Hoved opgave field_parent_issue: Hoved opgave
label_subtask_plural: Under opgaver label_subtask_plural: Under opgaver
label_project_copy_notifications: Send email notifikationer, mens projektet kopieres label_project_copy_notifications: Send email notifikationer, mens projektet kopieres
error_can_not_delete_custom_field: Unable to delete custom field error_can_not_delete_custom_field: Kan ikke slette brugerdefineret felt
error_unable_to_connect: Unable to connect ({{value}}) error_unable_to_connect: Kan ikke forbinde ({{value}})
error_can_not_remove_role: This role is in use and can not be deleted. error_can_not_remove_role: Denne rolle er i brug og kan ikke slettes.
error_can_not_delete_tracker: This tracker contains issues and can't be deleted. error_can_not_delete_tracker: Denne type indeholder sager og kan ikke slettes.
field_principal: Principal field_principal: Principal
label_my_page_block: My page block label_my_page_block: blok
notice_failed_to_save_members: "Failed to save member(s): {{errors}}." notice_failed_to_save_members: "Fejl under lagring af medlem(mer): {{errors}}."
text_zoom_out: Zoom out text_zoom_out: Zoom ud
text_zoom_in: Zoom in text_zoom_in: Zoom in
notice_unable_delete_time_entry: Unable to delete time log entry. notice_unable_delete_time_entry: Kan ikke slette tidsregistrering.
label_overall_spent_time: Overall spent time label_overall_spent_time: Overordnet forbrug af tid
field_time_entries: Log time field_time_entries: Log tid
project_module_gantt: Gantt project_module_gantt: Gantt
project_module_calendar: Calendar project_module_calendar: Kalender
field_member_of_group: Member of Group field_member_of_group: Medlem af Gruppe
field_assigned_to_role: Member of Role field_assigned_to_role: Medlem af Rolle
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Redigér tilknyttet Wiki side: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Slet sag og alle undersager?
field_text: Text field field_text: Tekstfelt
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -3
View File
@@ -280,6 +280,7 @@ de:
field_attr_lastname: Name-Attribut field_attr_lastname: Name-Attribut
field_attr_mail: E-Mail-Attribut field_attr_mail: E-Mail-Attribut
field_onthefly: On-the-fly-Benutzererstellung field_onthefly: On-the-fly-Benutzererstellung
field_start_date: Beginn
field_done_ratio: % erledigt field_done_ratio: % erledigt
field_auth_source: Authentifizierungs-Modus field_auth_source: Authentifizierungs-Modus
field_hide_mail: E-Mail-Adresse nicht anzeigen field_hide_mail: E-Mail-Adresse nicht anzeigen
@@ -939,9 +940,6 @@ de:
field_text: Text field field_text: Text field
setting_default_notification_option: Default notification option setting_default_notification_option: Default notification option
notice_not_authorized_archived_project: The project you're trying to access has been archived. notice_not_authorized_archived_project: The project you're trying to access has been archived.
label_user_mail_option_none: "Only for things I watch or I'm involved in"
field_member_of_group: Assignee's group field_member_of_group: Assignee's group
field_assigned_to_role: Assignee's role field_assigned_to_role: Assignee's role
field_start_date: Start date
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
+1 -2
View File
@@ -247,6 +247,7 @@ el:
field_attr_lastname: Ιδιότητα επωνύμου field_attr_lastname: Ιδιότητα επωνύμου
field_attr_mail: Ιδιότητα email field_attr_mail: Ιδιότητα email
field_onthefly: Άμεση δημιουργία χρήστη field_onthefly: Άμεση δημιουργία χρήστη
field_start_date: Εκκίνηση
field_done_ratio: % επιτεύχθη field_done_ratio: % επιτεύχθη
field_auth_source: Τρόπος πιστοποίησης field_auth_source: Τρόπος πιστοποίησης
field_hide_mail: Απόκρυψη διεύθυνσης email field_hide_mail: Απόκρυψη διεύθυνσης email
@@ -917,7 +918,5 @@ el:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+14 -11
View File
@@ -313,6 +313,7 @@ es:
field_role: Perfil field_role: Perfil
field_searchable: Incluir en las búsquedas field_searchable: Incluir en las búsquedas
field_spent_on: Fecha field_spent_on: Fecha
field_start_date: Fecha de inicio
field_start_page: Página principal field_start_page: Página principal
field_status: Estado field_status: Estado
field_subject: Tema field_subject: Tema
@@ -635,8 +636,8 @@ es:
label_user_activity: "Actividad de {{value}}" label_user_activity: "Actividad de {{value}}"
label_user_mail_no_self_notified: "No quiero ser avisado de cambios hechos por mí" label_user_mail_no_self_notified: "No quiero ser avisado de cambios hechos por mí"
label_user_mail_option_all: "Para cualquier evento en todos mis proyectos" label_user_mail_option_all: "Para cualquier evento en todos mis proyectos"
label_user_mail_option_none: "Sólo para elementos monitorizados o relacionados conmigo"
label_user_mail_option_selected: "Para cualquier evento de los proyectos seleccionados..." label_user_mail_option_selected: "Para cualquier evento de los proyectos seleccionados..."
label_user_mail_option_none: "Sólo para elementos monitorizados o relacionados conmigo"
label_user_new: Nuevo usuario label_user_new: Nuevo usuario
label_user_plural: Usuarios label_user_plural: Usuarios
label_version: Versión label_version: Versión
@@ -951,13 +952,15 @@ es:
label_overall_spent_time: Tiempo total dedicado label_overall_spent_time: Tiempo total dedicado
field_time_entries: Log time field_time_entries: Log time
project_module_gantt: Gantt project_module_gantt: Gantt
project_module_calendar: Calendar project_module_calendar: Calendario
field_member_of_group: Member of Group button_edit_associated_wikipage: "Editar paginas Wiki asociadas: {{page_title}}"
field_assigned_to_role: Member of Role text_are_you_sure_with_children: ¿Borrar peticiones y todas sus peticiones hijas?
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" field_text: Campo de texto
text_are_you_sure_with_children: Delete issue and all child issues? setting_default_notification_option: Opcion de notificacion por defecto
field_text: Text field field_member_of_group: Asignado al grupo
field_assigned_to_role: Asignado al perfil
field_start_date: Start date notice_not_authorized_archived_project: El proyecto al que intenta acceder ha sido archivado.
label_principal_search: "Search for user or group:" label_principal_search: "Buscar por usuario o grupo:"
label_user_search: "Search for user:" label_user_search: "Buscar por usuario:"
field_visible: Visible
setting_emails_header: Encabezado de Correos
+926 -926
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -262,6 +262,7 @@ fi:
field_attr_lastname: Sukunimenmääre field_attr_lastname: Sukunimenmääre
field_attr_mail: Sähköpostinmääre field_attr_mail: Sähköpostinmääre
field_onthefly: Automaattinen käyttäjien luonti field_onthefly: Automaattinen käyttäjien luonti
field_start_date: Alku
field_done_ratio: % Tehty field_done_ratio: % Tehty
field_auth_source: Varmennusmuoto field_auth_source: Varmennusmuoto
field_hide_mail: Piiloita sähköpostiosoitteeni field_hide_mail: Piiloita sähköpostiosoitteeni
@@ -942,6 +943,5 @@ fi:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -6
View File
@@ -271,6 +271,7 @@ fr:
field_attr_lastname: Attribut Nom field_attr_lastname: Attribut Nom
field_attr_mail: Attribut Email field_attr_mail: Attribut Email
field_onthefly: Création des utilisateurs à la volée field_onthefly: Création des utilisateurs à la volée
field_start_date: Début
field_done_ratio: % réalisé field_done_ratio: % réalisé
field_auth_source: Mode d'authentification field_auth_source: Mode d'authentification
field_hide_mail: Cacher mon adresse mail field_hide_mail: Cacher mon adresse mail
@@ -937,12 +938,6 @@ fr:
button_edit_associated_wikipage: "Modifier la page wiki associée: {{page_title}}" button_edit_associated_wikipage: "Modifier la page wiki associée: {{page_title}}"
text_are_you_sure_with_children: Supprimer la demande et toutes ses sous-demandes ? text_are_you_sure_with_children: Supprimer la demande et toutes ses sous-demandes ?
field_text: Champ texte field_text: Champ texte
label_user_mail_option_only_owner: Seulement pour ce que j'ai créé
setting_default_notification_option: Option de notification par défaut setting_default_notification_option: Option de notification par défaut
label_user_mail_option_only_my_events: Seulement pour ce que je surveille
label_user_mail_option_only_assigned: Seulement pour ce qui m'est assigné
label_user_mail_option_none: Aucune notification
field_member_of_group: Groupe de l'assigné field_member_of_group: Groupe de l'assigné
field_assigned_to_role: Rôle de l'assigné field_assigned_to_role: Rôle de l'assigné
field_start_date: Start date
+1 -2
View File
@@ -290,6 +290,7 @@ gl:
field_role: Perfil field_role: Perfil
field_searchable: Incluír nas búsquedas field_searchable: Incluír nas búsquedas
field_spent_on: Data field_spent_on: Data
field_start_date: Data de inicio
field_start_page: Páxina principal field_start_page: Páxina principal
field_status: Estado field_status: Estado
field_subject: Tema field_subject: Tema
@@ -933,7 +934,5 @@ gl:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -5
View File
@@ -266,6 +266,7 @@ he:
field_attr_lastname: תכונת שם משפחה field_attr_lastname: תכונת שם משפחה
field_attr_mail: תכונת דוא"ל field_attr_mail: תכונת דוא"ל
field_onthefly: יצירת משתמשים זריזה field_onthefly: יצירת משתמשים זריזה
field_start_date: תאריך התחלה
field_done_ratio: % גמור field_done_ratio: % גמור
field_auth_source: מקור הזדהות field_auth_source: מקור הזדהות
field_hide_mail: החבא את כתובת הדוא"ל שלי field_hide_mail: החבא את כתובת הדוא"ל שלי
@@ -731,9 +732,6 @@ he:
label_user_mail_option_all: "לכל אירוע בכל הפרויקטים שלי" label_user_mail_option_all: "לכל אירוע בכל הפרויקטים שלי"
label_user_mail_option_selected: "לכל אירוע בפרויקטים שבחרתי בלבד..." label_user_mail_option_selected: "לכל אירוע בפרויקטים שבחרתי בלבד..."
label_user_mail_option_none: "רק לנושאים שאני צופה או קשור אליהם" label_user_mail_option_none: "רק לנושאים שאני צופה או קשור אליהם"
label_user_mail_option_only_my_events: עבור דברים שאני צופה או מעורב בהם בלבד
label_user_mail_option_only_assigned: עבור דברים שאני אחראי עליהם בלבד
label_user_mail_option_only_owner: עבור דברים שאני הבעלים שלהם בלבד
label_user_mail_no_self_notified: "אני לא רוצה שיודיעו לי על שינויים שאני מבצע" label_user_mail_no_self_notified: "אני לא רוצה שיודיעו לי על שינויים שאני מבצע"
label_registration_activation_by_email: הפעל חשבון באמצעות דוא"ל label_registration_activation_by_email: הפעל חשבון באמצעות דוא"ל
label_registration_manual_activation: הפעלת חשבון ידנית label_registration_manual_activation: הפעלת חשבון ידנית
@@ -927,9 +925,7 @@ he:
enumeration_doc_categories: קטגוריות מסמכים enumeration_doc_categories: קטגוריות מסמכים
enumeration_activities: פעילויות (מעקב אחר זמנים) enumeration_activities: פעילויות (מעקב אחר זמנים)
enumeration_system_activity: פעילות מערכת enumeration_system_activity: פעילות מערכת
label_user_mail_option_none: No events
field_member_of_group: Assignee's group field_member_of_group: Assignee's group
field_assigned_to_role: Assignee's role field_assigned_to_role: Assignee's role
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -253,6 +253,7 @@ hr:
field_attr_lastname: Atribut prezimena field_attr_lastname: Atribut prezimena
field_attr_mail: Atribut e-pošte field_attr_mail: Atribut e-pošte
field_onthefly: "Izrada korisnika \"u hodu\"" field_onthefly: "Izrada korisnika \"u hodu\""
field_start_date: Pocetak
field_done_ratio: % Učinjeno field_done_ratio: % Učinjeno
field_auth_source: Vrsta prijavljivanja field_auth_source: Vrsta prijavljivanja
field_hide_mail: Sakrij moju adresu e-pošte field_hide_mail: Sakrij moju adresu e-pošte
@@ -924,6 +925,5 @@ hr:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -260,6 +260,7 @@
field_attr_lastname: Vezetéknév field_attr_lastname: Vezetéknév
field_attr_mail: E-mail field_attr_mail: E-mail
field_onthefly: On-the-fly felhasználó létrehozás field_onthefly: On-the-fly felhasználó létrehozás
field_start_date: Kezdés dátuma
field_done_ratio: Elkészült (%) field_done_ratio: Elkészült (%)
field_auth_source: Azonosítási mód field_auth_source: Azonosítási mód
field_hide_mail: Rejtse el az e-mail címem field_hide_mail: Rejtse el az e-mail címem
@@ -940,6 +941,5 @@
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -251,6 +251,7 @@ id:
field_attr_lastname: Atribut nama belakang field_attr_lastname: Atribut nama belakang
field_attr_mail: Atribut email field_attr_mail: Atribut email
field_onthefly: Pembuatan pengguna seketika field_onthefly: Pembuatan pengguna seketika
field_start_date: Mulai
field_done_ratio: % Selesai field_done_ratio: % Selesai
field_auth_source: Mode otentikasi field_auth_source: Mode otentikasi
field_hide_mail: Sembunyikan email saya field_hide_mail: Sembunyikan email saya
@@ -925,6 +926,5 @@ id:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -232,6 +232,7 @@ it:
field_attr_lastname: Attributo cognome field_attr_lastname: Attributo cognome
field_attr_mail: Attributo email field_attr_mail: Attributo email
field_onthefly: Creazione utente "al volo" field_onthefly: Creazione utente "al volo"
field_start_date: Inizio
field_done_ratio: % completato field_done_ratio: % completato
field_auth_source: Modalità di autenticazione field_auth_source: Modalità di autenticazione
field_hide_mail: Nascondi il mio indirizzo email field_hide_mail: Nascondi il mio indirizzo email
@@ -921,6 +922,5 @@ it:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+5 -4
View File
@@ -288,6 +288,7 @@ ja:
field_attr_lastname: 苗字属性 field_attr_lastname: 苗字属性
field_attr_mail: メール属性 field_attr_mail: メール属性
field_onthefly: あわせてユーザを作成 field_onthefly: あわせてユーザを作成
field_start_date: 開始日
field_done_ratio: 進捗 % field_done_ratio: 進捗 %
field_auth_source: 認証方式 field_auth_source: 認証方式
field_hide_mail: メールアドレスを隠す field_hide_mail: メールアドレスを隠す
@@ -322,6 +323,7 @@ ja:
field_member_of_group: 担当者のグループ field_member_of_group: 担当者のグループ
field_assigned_to_role: 担当者のロール field_assigned_to_role: 担当者のロール
field_text: テキスト field_text: テキスト
field_visible: 表示
setting_app_title: アプリケーションのタイトル setting_app_title: アプリケーションのタイトル
setting_app_subtitle: アプリケーションのサブタイトル setting_app_subtitle: アプリケーションのサブタイトル
@@ -351,6 +353,7 @@ ja:
setting_issue_list_default_columns: チケットの一覧で表示する項目 setting_issue_list_default_columns: チケットの一覧で表示する項目
setting_repositories_encodings: リポジトリのエンコーディング setting_repositories_encodings: リポジトリのエンコーディング
setting_commit_logs_encoding: コミットメッセージのエンコーディング setting_commit_logs_encoding: コミットメッセージのエンコーディング
setting_emails_header: メールのヘッダ
setting_emails_footer: メールのフッタ setting_emails_footer: メールのフッタ
setting_protocol: プロトコル setting_protocol: プロトコル
setting_per_page_options: ページ毎の表示件数 setting_per_page_options: ページ毎の表示件数
@@ -754,9 +757,6 @@ ja:
label_user_mail_option_all: "参加しているプロジェクトの全ての通知" label_user_mail_option_all: "参加しているプロジェクトの全ての通知"
label_user_mail_option_selected: "選択したプロジェクトの全ての通知..." label_user_mail_option_selected: "選択したプロジェクトの全ての通知..."
label_user_mail_option_none: "通知しない" label_user_mail_option_none: "通知しない"
label_user_mail_option_only_my_events: "ウォッチまたは関係している事柄のみ"
label_user_mail_option_only_assigned: "自分が担当している事柄のみ"
label_user_mail_option_only_owner: "自分が作成した事柄のみ"
label_user_mail_no_self_notified: 自分自身による変更の通知は不要 label_user_mail_no_self_notified: 自分自身による変更の通知は不要
label_registration_activation_by_email: メールでアカウントを有効化 label_registration_activation_by_email: メールでアカウントを有効化
label_registration_manual_activation: 手動でアカウントを有効化 label_registration_manual_activation: 手動でアカウントを有効化
@@ -806,6 +806,8 @@ ja:
label_api_access_key_created_on: "APIアクセスキーは{{value}}前に作成されました" label_api_access_key_created_on: "APIアクセスキーは{{value}}前に作成されました"
label_subtask_plural: 子チケット label_subtask_plural: 子チケット
label_project_copy_notifications: コピーしたチケットのメール通知を送信する label_project_copy_notifications: コピーしたチケットのメール通知を送信する
label_principal_search: "ユーザまたはグループの検索:"
label_user_search: "ユーザの検索:"
button_login: ログイン button_login: ログイン
button_submit: 変更 button_submit: 変更
@@ -947,6 +949,5 @@ ja:
enumeration_doc_categories: 文書カテゴリ enumeration_doc_categories: 文書カテゴリ
enumeration_activities: 作業分類 (時間トラッキング) enumeration_activities: 作業分類 (時間トラッキング)
enumeration_system_activity: システム作業分類 enumeration_system_activity: システム作業分類
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -299,6 +299,7 @@ ko:
field_attr_lastname: 성 속성 field_attr_lastname: 성 속성
field_attr_mail: 메일 속성 field_attr_mail: 메일 속성
field_onthefly: 동적 사용자 생성 field_onthefly: 동적 사용자 생성
field_start_date: 시작시간
field_done_ratio: 진척도 field_done_ratio: 진척도
field_auth_source: 인증 공급자 field_auth_source: 인증 공급자
field_hide_mail: 메일 주소 숨기기 field_hide_mail: 메일 주소 숨기기
@@ -973,6 +974,5 @@ ko:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -310,6 +310,7 @@ lt:
field_attr_lastname: Pavardės priskiria field_attr_lastname: Pavardės priskiria
field_attr_mail: Elektroninio pašto požymis field_attr_mail: Elektroninio pašto požymis
field_onthefly: Automatinis vartotojų registravimas field_onthefly: Automatinis vartotojų registravimas
field_start_date: Pradėti
field_done_ratio: % atlikta field_done_ratio: % atlikta
field_auth_source: Autentiškumo nustatymo būdas field_auth_source: Autentiškumo nustatymo būdas
field_hide_mail: Paslėpkite mano elektroninio pašto adresą field_hide_mail: Paslėpkite mano elektroninio pašto adresą
@@ -981,6 +982,5 @@ lt:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+917 -917
View File
File diff suppressed because it is too large Load Diff
+922 -922
View File
File diff suppressed because it is too large Load Diff
+923 -923
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -256,6 +256,7 @@ nl:
field_role: Rol field_role: Rol
field_searchable: Doorzoekbaar field_searchable: Doorzoekbaar
field_spent_on: Datum field_spent_on: Datum
field_start_date: Startdatum
field_start_page: Startpagina field_start_page: Startpagina
field_status: Status field_status: Status
field_subject: Onderwerp field_subject: Onderwerp
@@ -899,6 +900,5 @@ nl:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -231,6 +231,7 @@
field_attr_lastname: Etternavnsattributt field_attr_lastname: Etternavnsattributt
field_attr_mail: E-post-attributt field_attr_mail: E-post-attributt
field_onthefly: On-the-fly brukeropprettelse field_onthefly: On-the-fly brukeropprettelse
field_start_date: Start
field_done_ratio: % Ferdig field_done_ratio: % Ferdig
field_auth_source: Autentifikasjonsmodus field_auth_source: Autentifikasjonsmodus
field_hide_mail: Skjul min e-post-adresse field_hide_mail: Skjul min e-post-adresse
@@ -908,6 +909,5 @@
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -277,6 +277,7 @@ pl:
field_role: Rola field_role: Rola
field_searchable: Przeszukiwalne field_searchable: Przeszukiwalne
field_spent_on: Data field_spent_on: Data
field_start_date: Start
field_start_page: Strona startowa field_start_page: Strona startowa
field_status: Status field_status: Status
field_subject: Temat field_subject: Temat
@@ -938,6 +939,5 @@ pl:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -4
View File
@@ -264,6 +264,7 @@ pt-BR:
field_attr_lastname: Atributo para sobrenome field_attr_lastname: Atributo para sobrenome
field_attr_mail: Atributo para e-mail field_attr_mail: Atributo para e-mail
field_onthefly: Criar usuários dinamicamente ("on-the-fly") field_onthefly: Criar usuários dinamicamente ("on-the-fly")
field_start_date: Início
field_done_ratio: % Terminado field_done_ratio: % Terminado
field_auth_source: Modo de autenticação field_auth_source: Modo de autenticação
field_hide_mail: Ocultar meu e-mail field_hide_mail: Ocultar meu e-mail
@@ -941,10 +942,6 @@ pt-BR:
button_edit_associated_wikipage: "Editar página wiki relacionada: {{page_title}}" button_edit_associated_wikipage: "Editar página wiki relacionada: {{page_title}}"
text_are_you_sure_with_children: Excluir a tarefa e suas subtarefas? text_are_you_sure_with_children: Excluir a tarefa e suas subtarefas?
field_text: Campo de texto field_text: Campo de texto
label_user_mail_option_only_owner: Somente para as coisas que eu criei
setting_default_notification_option: Opção padrão de notificação setting_default_notification_option: Opção padrão de notificação
label_user_mail_option_only_my_events: Somente para as coisas que eu esteja observando ou esteja envolvido
label_user_mail_option_only_assigned: Somente para as coisas que estejam atribuídas a mim
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -249,6 +249,7 @@ pt:
field_attr_lastname: Atributo último nome field_attr_lastname: Atributo último nome
field_attr_mail: Atributo e-mail field_attr_mail: Atributo e-mail
field_onthefly: Criação de utilizadores na hora field_onthefly: Criação de utilizadores na hora
field_start_date: Início
field_done_ratio: % Completo field_done_ratio: % Completo
field_auth_source: Modo de autenticação field_auth_source: Modo de autenticação
field_hide_mail: Esconder endereço de e-mail field_hide_mail: Esconder endereço de e-mail
@@ -925,6 +926,5 @@ pt:
button_edit_associated_wikipage: "Editar página Wiki associada: {{page_title}}" button_edit_associated_wikipage: "Editar página Wiki associada: {{page_title}}"
text_are_you_sure_with_children: Apagar tarefa e todas as sub-tarefas? text_are_you_sure_with_children: Apagar tarefa e todas as sub-tarefas?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -232,6 +232,7 @@ ro:
field_attr_lastname: Atribut nume field_attr_lastname: Atribut nume
field_attr_mail: Atribut email field_attr_mail: Atribut email
field_onthefly: Creare utilizator pe loc field_onthefly: Creare utilizator pe loc
field_start_date: Data începerii
field_done_ratio: Realizat (%) field_done_ratio: Realizat (%)
field_auth_source: Mod autentificare field_auth_source: Mod autentificare
field_hide_mail: Nu se afișează adresa de email field_hide_mail: Nu se afișează adresa de email
@@ -910,6 +911,5 @@ ro:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+3 -7
View File
@@ -363,6 +363,7 @@ ru:
field_role: Роль field_role: Роль
field_searchable: Доступно для поиска field_searchable: Доступно для поиска
field_spent_on: Дата field_spent_on: Дата
field_start_date: Начата
field_start_page: Стартовая страница field_start_page: Стартовая страница
field_status: Статус field_status: Статус
field_subject: Тема field_subject: Тема
@@ -381,9 +382,9 @@ ru:
field_version: Версия field_version: Версия
field_watcher: Наблюдатель field_watcher: Наблюдатель
general_csv_decimal_separator: '.' general_csv_decimal_separator: ','
general_csv_encoding: UTF-8 general_csv_encoding: UTF-8
general_csv_separator: ',' general_csv_separator: ';'
general_first_day_of_week: '1' general_first_day_of_week: '1'
general_lang_name: 'Russian (Русский)' general_lang_name: 'Russian (Русский)'
general_pdf_encoding: UTF-8 general_pdf_encoding: UTF-8
@@ -702,9 +703,6 @@ ru:
label_user_mail_option_all: "О всех событиях во всех моих проектах" label_user_mail_option_all: "О всех событиях во всех моих проектах"
label_user_mail_option_none: "Только о тех событиях, которые я отслеживаю или в которых я участвую" label_user_mail_option_none: "Только о тех событиях, которые я отслеживаю или в которых я участвую"
label_user_mail_option_selected: "О всех событиях только в выбранном проекте..." label_user_mail_option_selected: "О всех событиях только в выбранном проекте..."
label_user_mail_option_only_owner: Только для объектов, для которых я являюсь владельцем
label_user_mail_option_only_my_events: Только для объектов, которые я отслеживаю или в которых участвую
label_user_mail_option_only_assigned: Только для объектов, которые назначены мне
label_user_new: Новый пользователь label_user_new: Новый пользователь
label_user_plural: Пользователи label_user_plural: Пользователи
label_version: Версия label_version: Версия
@@ -1035,11 +1033,9 @@ ru:
text_zoom_in: Приблизить text_zoom_in: Приблизить
notice_unable_delete_time_entry: Невозможно удалить запись журнала. notice_unable_delete_time_entry: Невозможно удалить запись журнала.
label_overall_spent_time: Всего затрачено времени label_overall_spent_time: Всего затрачено времени
label_user_mail_option_none: Нет событий
field_member_of_group: Группа назначенного field_member_of_group: Группа назначенного
field_assigned_to_role: Роль назначенного field_assigned_to_role: Роль назначенного
notice_not_authorized_archived_project: Запрашиваемый проект был архивирован. notice_not_authorized_archived_project: Запрашиваемый проект был архивирован.
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
field_start_date: Start Date
+1 -1
View File
@@ -231,6 +231,7 @@ sk:
field_attr_lastname: Priezvisko (atribut) field_attr_lastname: Priezvisko (atribut)
field_attr_mail: Email (atribut) field_attr_mail: Email (atribut)
field_onthefly: Automatické vytváranie užívateľov field_onthefly: Automatické vytváranie užívateľov
field_start_date: Začiatok
field_done_ratio: % hotovo field_done_ratio: % hotovo
field_auth_source: Autentifikačný mód field_auth_source: Autentifikačný mód
field_hide_mail: Nezobrazovať môj email field_hide_mail: Nezobrazovať môj email
@@ -912,6 +913,5 @@ sk:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -236,6 +236,7 @@ sl:
field_attr_lastname: Oznaka za priimek field_attr_lastname: Oznaka za priimek
field_attr_mail: Oznaka za e-naslov field_attr_mail: Oznaka za e-naslov
field_onthefly: Sprotna izdelava uporabnikov field_onthefly: Sprotna izdelava uporabnikov
field_start_date: Začetek
field_done_ratio: % Narejeno field_done_ratio: % Narejeno
field_auth_source: Način overovljanja field_auth_source: Način overovljanja
field_hide_mail: Skrij moj e-naslov field_hide_mail: Skrij moj e-naslov
@@ -913,6 +914,5 @@ sl:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -261,6 +261,7 @@ sr-YU:
field_attr_lastname: Atribut prezimena field_attr_lastname: Atribut prezimena
field_attr_mail: Atribut e-adrese field_attr_mail: Atribut e-adrese
field_onthefly: Kreiranje korisnika u toku rada field_onthefly: Kreiranje korisnika u toku rada
field_start_date: Početak
field_done_ratio: % urađeno field_done_ratio: % urađeno
field_auth_source: Režim potvrde identiteta field_auth_source: Režim potvrde identiteta
field_hide_mail: Sakrij moju e-adresu field_hide_mail: Sakrij moju e-adresu
@@ -917,6 +918,5 @@ sr-YU:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -261,6 +261,7 @@ sr:
field_attr_lastname: Атрибут презимена field_attr_lastname: Атрибут презимена
field_attr_mail: Атрибут е-адресе field_attr_mail: Атрибут е-адресе
field_onthefly: Креирање корисника у току рада field_onthefly: Креирање корисника у току рада
field_start_date: Почетак
field_done_ratio: % урађено field_done_ratio: % урађено
field_auth_source: Режим потврде идентитета field_auth_source: Режим потврде идентитета
field_hide_mail: Сакриј моју е-адресу field_hide_mail: Сакриј моју е-адресу
@@ -918,6 +919,5 @@ sr:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+6 -4
View File
@@ -308,6 +308,7 @@ sv:
field_attr_lastname: Efternamnsattribut field_attr_lastname: Efternamnsattribut
field_attr_mail: Mailattribut field_attr_mail: Mailattribut
field_onthefly: Skapa användare on-the-fly field_onthefly: Skapa användare on-the-fly
field_start_date: Startdatum
field_done_ratio: % Klart field_done_ratio: % Klart
field_auth_source: Autentiseringsläge field_auth_source: Autentiseringsläge
field_hide_mail: Dölj min mailadress field_hide_mail: Dölj min mailadress
@@ -823,6 +824,8 @@ sv:
label_profile: Profil label_profile: Profil
label_subtask_plural: Underaktiviteter label_subtask_plural: Underaktiviteter
label_project_copy_notifications: Skicka mailnotifieringar när projektet kopieras label_project_copy_notifications: Skicka mailnotifieringar när projektet kopieras
label_principal_search: "Sök efter användare eller grupp:"
label_user_search: "Sök efter användare:"
button_login: Logga in button_login: Logga in
button_submit: Skicka button_submit: Skicka
@@ -891,9 +894,9 @@ sv:
text_journal_set_to: "{{label}} satt till {{value}}" text_journal_set_to: "{{label}} satt till {{value}}"
text_journal_deleted: "{{label}} borttagen ({{old}})" text_journal_deleted: "{{label}} borttagen ({{old}})"
text_journal_added: "{{label}} {{value}} tillagd" text_journal_added: "{{label}} {{value}} tillagd"
text_tip_issue_begin_day: arbetsuppgift som börjar denna dag text_tip_issue_begin_day: ärende som börjar denna dag
text_tip_issue_end_day: arbetsuppgift som slutar denna dag text_tip_issue_end_day: ärende som slutar denna dag
text_tip_issue_begin_end_day: arbetsuppgift börjar och slutar denna dag text_tip_issue_begin_end_day: ärende som börjar och slutar denna dag
text_project_identifier_info: 'Små bokstäver (a-z), siffror och streck tillåtna.<br />När den är sparad kan identifieraren inte ändras.' text_project_identifier_info: 'Små bokstäver (a-z), siffror och streck tillåtna.<br />När den är sparad kan identifieraren inte ändras.'
text_caracters_maximum: "max {{count}} tecken." text_caracters_maximum: "max {{count}} tecken."
text_caracters_minimum: "Måste vara minst {{count}} tecken lång." text_caracters_minimum: "Måste vara minst {{count}} tecken lång."
@@ -969,6 +972,5 @@ sv:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -233,6 +233,7 @@ th:
field_attr_lastname: นามสกุล attribute field_attr_lastname: นามสกุล attribute
field_attr_mail: อีเมล์ attribute field_attr_mail: อีเมล์ attribute
field_onthefly: สร้างผู้ใช้ทันที field_onthefly: สร้างผู้ใช้ทันที
field_start_date: เริ่ม
field_done_ratio: % สำเร็จ field_done_ratio: % สำเร็จ
field_auth_source: วิธีการยืนยันตัวตน field_auth_source: วิธีการยืนยันตัวตน
field_hide_mail: ซ่อนอีเมล์ของฉัน field_hide_mail: ซ่อนอีเมล์ของฉัน
@@ -914,6 +915,5 @@ th:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -260,6 +260,7 @@ tr:
field_attr_lastname: Soyad Niteliği field_attr_lastname: Soyad Niteliği
field_attr_mail: E-Posta Niteliği field_attr_mail: E-Posta Niteliği
field_onthefly: Anında kullanıcı oluşturma field_onthefly: Anında kullanıcı oluşturma
field_start_date: Başlangıç
field_done_ratio: % tamamlandı field_done_ratio: % tamamlandı
field_auth_source: Kimlik Denetim Modu field_auth_source: Kimlik Denetim Modu
field_hide_mail: E-posta adresimi gizle field_hide_mail: E-posta adresimi gizle
@@ -940,6 +941,5 @@ tr:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -227,6 +227,7 @@ uk:
field_attr_lastname: Атрибут Прізвище field_attr_lastname: Атрибут Прізвище
field_attr_mail: Атрибут Email field_attr_mail: Атрибут Email
field_onthefly: Створення користувача на льоту field_onthefly: Створення користувача на льоту
field_start_date: Початок
field_done_ratio: % зроблено field_done_ratio: % зроблено
field_auth_source: Режим аутентифікації field_auth_source: Режим аутентифікації
field_hide_mail: Приховувати мій email field_hide_mail: Приховувати мій email
@@ -913,6 +914,5 @@ uk:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+1 -1
View File
@@ -294,6 +294,7 @@ vi:
field_attr_lastname: Lastname attribute field_attr_lastname: Lastname attribute
field_attr_mail: Email attribute field_attr_mail: Email attribute
field_onthefly: On-the-fly user creation field_onthefly: On-the-fly user creation
field_start_date: Bắt đầu
field_done_ratio: Tiến độ field_done_ratio: Tiến độ
field_auth_source: Authentication mode field_auth_source: Authentication mode
field_hide_mail: Không làm lộ email của bạn field_hide_mail: Không làm lộ email của bạn
@@ -972,6 +973,5 @@ vi:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+6 -7
View File
@@ -177,7 +177,7 @@
greater_than_start_date: "必須在開始日期之後" greater_than_start_date: "必須在開始日期之後"
not_same_project: "不屬於同一個專案" not_same_project: "不屬於同一個專案"
circular_dependency: "這個關聯會導致環狀相依" circular_dependency: "這個關聯會導致環狀相依"
cant_link_an_issue_with_a_descendant: "An issue can not be linked to one of its subtasks" cant_link_an_issue_with_a_descendant: "項目無法被連結至自己的子項目"
# You can define own errors for models or model attributes. # You can define own errors for models or model attributes.
# The values :model, :attribute and :value are always available for interpolation. # The values :model, :attribute and :value are always available for interpolation.
@@ -383,6 +383,7 @@
field_member_of_group: "被指派者的群組" field_member_of_group: "被指派者的群組"
field_assigned_to_role: "被指派者的角色" field_assigned_to_role: "被指派者的角色"
field_text: 內容文字 field_text: 內容文字
field_visible: 可被看見
setting_app_title: 標題 setting_app_title: 標題
setting_app_subtitle: 副標題 setting_app_subtitle: 副標題
@@ -411,6 +412,7 @@
setting_issue_list_default_columns: 預設顯示於項目清單的欄位 setting_issue_list_default_columns: 預設顯示於項目清單的欄位
setting_repositories_encodings: 版本庫編碼 setting_repositories_encodings: 版本庫編碼
setting_commit_logs_encoding: 送交訊息編碼 setting_commit_logs_encoding: 送交訊息編碼
setting_emails_header: 電子郵件前頭說明
setting_emails_footer: 電子郵件附帶說明 setting_emails_footer: 電子郵件附帶說明
setting_protocol: 協定 setting_protocol: 協定
setting_per_page_options: 每頁顯示個數選項 setting_per_page_options: 每頁顯示個數選項
@@ -813,10 +815,7 @@
label_search_titles_only: 僅搜尋標題 label_search_titles_only: 僅搜尋標題
label_user_mail_option_all: "提醒與我的專案有關的全部事件" label_user_mail_option_all: "提醒與我的專案有關的全部事件"
label_user_mail_option_selected: "只提醒我所選擇專案中的事件..." label_user_mail_option_selected: "只提醒我所選擇專案中的事件..."
label_user_mail_option_none: "只提醒我觀察中或參與中的事件" label_user_mail_option_none: "取消提醒"
label_user_mail_option_only_my_events: "只提醒我觀察中或參與中的事物"
label_user_mail_option_only_assigned: "只提醒我被指派的事物"
label_user_mail_option_only_owner: "只提醒我作為擁有者的事物"
label_user_mail_no_self_notified: "不提醒我自己所做的變更" label_user_mail_no_self_notified: "不提醒我自己所做的變更"
label_registration_activation_by_email: 透過電子郵件啟用帳戶 label_registration_activation_by_email: 透過電子郵件啟用帳戶
label_registration_manual_activation: 手動啟用帳戶 label_registration_manual_activation: 手動啟用帳戶
@@ -867,6 +866,8 @@
label_profile: 配置概況 label_profile: 配置概況
label_subtask_plural: 子工作項目 label_subtask_plural: 子工作項目
label_project_copy_notifications: 在複製專案的過程中,傳送通知郵件 label_project_copy_notifications: 在複製專案的過程中,傳送通知郵件
label_principal_search: "搜尋用戶或群組:"
label_user_search: "搜尋用戶:"
button_login: 登入 button_login: 登入
button_submit: 送出 button_submit: 送出
@@ -1009,5 +1010,3 @@
enumeration_activities: 活動 (時間追蹤) enumeration_activities: 活動 (時間追蹤)
enumeration_system_activity: 系統活動 enumeration_system_activity: 系統活動
label_principal_search: "Search for user or group:"
label_user_search: "Search for user:"
+1 -1
View File
@@ -272,6 +272,7 @@ zh:
field_attr_lastname: 姓氏属性 field_attr_lastname: 姓氏属性
field_attr_mail: 邮件属性 field_attr_mail: 邮件属性
field_onthefly: 即时用户生成 field_onthefly: 即时用户生成
field_start_date: 开始
field_done_ratio: 完成度 field_done_ratio: 完成度
field_auth_source: 认证模式 field_auth_source: 认证模式
field_hide_mail: 隐藏我的邮件地址 field_hide_mail: 隐藏我的邮件地址
@@ -935,6 +936,5 @@ zh:
button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}" button_edit_associated_wikipage: "Edit associated Wiki page: {{page_title}}"
text_are_you_sure_with_children: Delete issue and all child issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Text field field_text: Text field
field_start_date: Start date
label_principal_search: "Search for user or group:" label_principal_search: "Search for user or group:"
label_user_search: "Search for user:" label_user_search: "Search for user:"
+45 -6
View File
@@ -4,6 +4,45 @@ Redmine - project management software
Copyright (C) 2006-2010 Jean-Philippe Lang Copyright (C) 2006-2010 Jean-Philippe Lang
http://www.redmine.org/ http://www.redmine.org/
== 2010-12-23 v1.0.5
* #6656: Mercurial adapter loses seconds of commit times
* #6996: Migration trac(sqlite3) -> redmine(postgresql) doesnt escape ' char
* #7013: v-1.0.4 trunk - see {{count}} in page display rather than value
* #7016: redundant 'field_start_date' in ja.yml
* #7018: 'undefined method `reschedule_after' for nil:NilClass' on new issues
* #7024: E-mail notifications about Wiki changes.
* #7033: 'class' attribute of <pre> tag shouldn't be truncate
* #7035: CSV value separator in russian
* #7122: Issue-description Quote-button missing
* #7144: custom queries making use of deleted custom fields cause a 500 error
* #7162: Multiply defined label in french translation
== 2010-11-28 v1.0.4
* #5324: Git not working if color.ui is enabled
* #6447: Issues API doesn't allow full key auth for all actions
* #6457: Edit User group problem
* #6575: start date being filled with current date even when blank value is submitted
* #6740: Max attachment size, incorrect usage of 'KB'
* #6760: Select box sorted by ID instead of name in Issue Category
* #6766: Changing target version name can cause an internal error
* #6784: Redmine not working with i18n gem 0.4.2
* #6839: Hardcoded absolute links in my/page_layout
* #6841: Projects API doesn't allow full key auth for all actions
* #6860: svn: Write error: Broken pipe when browsing repository
* #6874: API should return XML description when creating a project
* #6932: submitting wrong parent task input creates a 500 error
* #6966: Records of Forums are remained, deleting project
* #6990: Layout problem in workflow overview
* #5117: mercurial_adapter should ensure the right LANG environment variable
* #6782: Traditional Chinese language file (to r4352)
* #6783: Swedish Translation for r4352
* #6804: Bugfix: spelling fixes
* #6814: Japanese Translation for r4362
* #6948: Bulgarian translation
* #6973: Update es.yml
== 2010-10-31 v1.0.3 == 2010-10-31 v1.0.3
* #4065: Redmine.pm doesn't work with LDAPS and a non-standard port * #4065: Redmine.pm doesn't work with LDAPS and a non-standard port
@@ -1112,7 +1151,7 @@ http://www.redmine.org/
* Search engines now supports pagination. Results are sorted in reverse chronological order * Search engines now supports pagination. Results are sorted in reverse chronological order
* Added "Estimated hours" attribute on issues * Added "Estimated hours" attribute on issues
* A category with assigned issue can now be deleted. 2 options are proposed: remove assignments or reassign issues to another category * A category with assigned issue can now be deleted. 2 options are proposed: remove assignments or reassign issues to another category
* Forum notifications are now also sent to the authors of the thread, even if they don’t watch the board * Forum notifications are now also sent to the authors of the thread, even if they don�t watch the board
* Added an application setting to specify the application protocol (http or https) used to generate urls in emails * Added an application setting to specify the application protocol (http or https) used to generate urls in emails
* Gantt chart: now starts at the current month by default * Gantt chart: now starts at the current month by default
* Gantt chart: month count and zoom factor are automatically saved as user preferences * Gantt chart: month count and zoom factor are automatically saved as user preferences
@@ -1120,7 +1159,7 @@ http://www.redmine.org/
* Added wiki index by date * Added wiki index by date
* Added preview on add/edit issue form * Added preview on add/edit issue form
* Emails footer can now be customized from the admin interface (Admin -> Email notifications) * Emails footer can now be customized from the admin interface (Admin -> Email notifications)
* Default encodings for repository files can now be set in application settings (used to convert files content and diff to UTF-8 so that they’re properly displayed) * Default encodings for repository files can now be set in application settings (used to convert files content and diff to UTF-8 so that they�re properly displayed)
* Calendar: first day of week can now be set in lang files * Calendar: first day of week can now be set in lang files
* Automatic closing of duplicate issues * Automatic closing of duplicate issues
* Added a cross-project issue list * Added a cross-project issue list
@@ -1132,7 +1171,7 @@ http://www.redmine.org/
* Added some accesskeys * Added some accesskeys
* Added "Float" as a custom field format * Added "Float" as a custom field format
* Added basic Theme support * Added basic Theme support
* Added the ability to set the “done ratio” of issues fixed by commit (Nikolay Solakov) * Added the ability to set the �done ratio� of issues fixed by commit (Nikolay Solakov)
* Added custom fields in issue related mail notifications * Added custom fields in issue related mail notifications
* Email notifications are now sent in plain text and html * Email notifications are now sent in plain text and html
* Gantt chart can now be exported to a graphic file (png). This functionality is only available if RMagick is installed. * Gantt chart can now be exported to a graphic file (png). This functionality is only available if RMagick is installed.
@@ -1165,7 +1204,7 @@ http://www.redmine.org/
* Added Korean translation (Choi Jong Yoon) * Added Korean translation (Choi Jong Yoon)
* Fixed: the link to delete issue relations is displayed even if the user is not authorized to delete relations * Fixed: the link to delete issue relations is displayed even if the user is not authorized to delete relations
* Performance improvement on calendar and gantt * Performance improvement on calendar and gantt
* Fixed: wiki preview doesn’t work on long entries * Fixed: wiki preview doesn�t work on long entries
* Fixed: queries with multiple custom fields return no result * Fixed: queries with multiple custom fields return no result
* Fixed: Can not authenticate user against LDAP if its DN contains non-ascii characters * Fixed: Can not authenticate user against LDAP if its DN contains non-ascii characters
* Fixed: URL with ~ broken in wiki formatting * Fixed: URL with ~ broken in wiki formatting
@@ -1176,7 +1215,7 @@ http://www.redmine.org/
* per project forums added * per project forums added
* added the ability to archive projects * added the ability to archive projects
* added “Watch” functionality on issues. It allows users to receive notifications about issue changes * added �Watch� functionality on issues. It allows users to receive notifications about issue changes
* custom fields for issues can now be used as filters on issue list * custom fields for issues can now be used as filters on issue list
* added per user custom queries * added per user custom queries
* commit messages are now scanned for referenced or fixed issue IDs (keywords defined in Admin -> Settings) * commit messages are now scanned for referenced or fixed issue IDs (keywords defined in Admin -> Settings)
@@ -1217,7 +1256,7 @@ http://www.redmine.org/
* added swedish translation (Thomas Habets) * added swedish translation (Thomas Habets)
* italian translation update (Alessio Spadaro) * italian translation update (Alessio Spadaro)
* japanese translation update (Satoru Kurashiki) * japanese translation update (Satoru Kurashiki)
* fixed: error on history atom feed when there’s no notes on an issue change * fixed: error on history atom feed when there�s no notes on an issue change
* fixed: error in journalizing an issue with longtext custom fields (Postgresql) * fixed: error in journalizing an issue with longtext custom fields (Postgresql)
* fixed: creation of Oracle schema * fixed: creation of Oracle schema
* fixed: last day of the month not included in project activity * fixed: last day of the month not included in project activity
+5 -3
View File
@@ -9,14 +9,16 @@ http://www.redmine.org/
* Ruby 1.8.6 or 1.8.7 * Ruby 1.8.6 or 1.8.7
* RubyGems 1.3.1
* Ruby on Rails 2.3.5 (official downloadable Redmine releases are packaged with * Ruby on Rails 2.3.5 (official downloadable Redmine releases are packaged with
the appropriate Rails version) the appropriate Rails version)
* Rack 1.0.1 * Rack 1.0.1 gem
* RubyGems 1.3.1 * Rake 0.8.3 gem
* Rake 0.8.3 * I18n 0.4.2 gem
* A database: * A database:
* MySQL (tested with MySQL 5) * MySQL (tested with MySQL 5)
+1 -1
View File
@@ -1078,7 +1078,7 @@ class RedCloth3 < String
line = "<redpre##{ @pre_list.length }>" line = "<redpre##{ @pre_list.length }>"
first.match(/<#{ OFFTAGS }([^>]*)>/) first.match(/<#{ OFFTAGS }([^>]*)>/)
tag = $1 tag = $1
$2.to_s.match(/(class\=\S+)/i) $2.to_s.match(/(class\=("[^"]+"|'[^']+'))/i)
tag << " #{$1}" if $1 tag << " #{$1}" if $1
@pre_list << "<#{ tag }>#{ aftertag }" @pre_list << "<#{ tag }>#{ aftertag }"
end end
+2 -2
View File
@@ -37,7 +37,7 @@ module Redmine
def format_date(date) def format_date(date)
return nil unless date return nil unless date
Setting.date_format.blank? ? ::I18n.l(date.to_date, :count => date.strftime('%d')) : date.strftime(Setting.date_format) Setting.date_format.blank? ? ::I18n.l(date.to_date) : date.strftime(Setting.date_format)
end end
def format_time(time, include_date = true) def format_time(time, include_date = true)
@@ -45,7 +45,7 @@ module Redmine
time = time.to_time if time.is_a?(String) time = time.to_time if time.is_a?(String)
zone = User.current.time_zone zone = User.current.time_zone
local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time) local = zone ? time.in_time_zone(zone) : (time.utc? ? time.localtime : time)
Setting.time_format.blank? ? ::I18n.l(local, :count => local.strftime('%d'), :format => (include_date ? :default : :time)) : Setting.time_format.blank? ? ::I18n.l(local, :format => (include_date ? :default : :time)) :
((include_date ? "#{format_date(time)} " : "") + "#{local.strftime(Setting.time_format)}") ((include_date ? "#{format_date(time)} " : "") + "#{local.strftime(Setting.time_format)}")
end end
+6 -3
View File
@@ -74,10 +74,10 @@ module Redmine
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
path ||= '' path ||= ''
identifier_from = 'last:1' unless identifier_from and identifier_from.to_i > 0 identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : 'last:1'
identifier_to = 1 unless identifier_to and identifier_to.to_i > 0 identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1
revisions = Revisions.new revisions = Revisions.new
cmd = "#{BZR_BIN} log -v --show-ids -r#{identifier_to.to_i}..#{identifier_from} #{target(path)}" cmd = "#{BZR_BIN} log -v --show-ids -r#{identifier_to}..#{identifier_from} #{target(path)}"
shellout(cmd) do |io| shellout(cmd) do |io|
revision = nil revision = nil
parsing = nil parsing = nil
@@ -140,6 +140,9 @@ module Redmine
else else
identifier_to = identifier_from.to_i - 1 identifier_to = identifier_from.to_i - 1
end end
if identifier_from
identifier_from = identifier_from.to_i
end
cmd = "#{BZR_BIN} diff -r#{identifier_to}..#{identifier_from} #{target(path)}" cmd = "#{BZR_BIN} diff -r#{identifier_to}..#{identifier_from} #{target(path)}"
diff = [] diff = []
shellout(cmd) do |io| shellout(cmd) do |io|
+6 -6
View File
@@ -63,7 +63,7 @@ module Redmine
logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'" logger.debug "<cvs> entries '#{path}' with identifier '#{identifier}'"
path_with_project="#{url}#{with_leading_slash(path)}" path_with_project="#{url}#{with_leading_slash(path)}"
entries = Entries.new entries = Entries.new
cmd = "#{CVS_BIN} -d #{root_url} rls -e" cmd = "#{CVS_BIN} -d #{shell_quote root_url} rls -e"
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
cmd << " #{shell_quote path_with_project}" cmd << " #{shell_quote path_with_project}"
shellout(cmd) do |io| shellout(cmd) do |io|
@@ -108,7 +108,7 @@ module Redmine
logger.debug "<cvs> revisions path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}" logger.debug "<cvs> revisions path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
path_with_project="#{url}#{with_leading_slash(path)}" path_with_project="#{url}#{with_leading_slash(path)}"
cmd = "#{CVS_BIN} -d #{root_url} rlog" cmd = "#{CVS_BIN} -d #{shell_quote root_url} rlog"
cmd << " -d\">#{time_to_cvstime(identifier_from)}\"" if identifier_from cmd << " -d\">#{time_to_cvstime(identifier_from)}\"" if identifier_from
cmd << " #{shell_quote path_with_project}" cmd << " #{shell_quote path_with_project}"
shellout(cmd) do |io| shellout(cmd) do |io|
@@ -229,7 +229,7 @@ module Redmine
def diff(path, identifier_from, identifier_to=nil) def diff(path, identifier_from, identifier_to=nil)
logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}" logger.debug "<cvs> diff path:'#{path}',identifier_from #{identifier_from}, identifier_to #{identifier_to}"
path_with_project="#{url}#{with_leading_slash(path)}" path_with_project="#{url}#{with_leading_slash(path)}"
cmd = "#{CVS_BIN} -d #{root_url} rdiff -u -r#{identifier_to} -r#{identifier_from} #{shell_quote path_with_project}" cmd = "#{CVS_BIN} -d #{shell_quote root_url} rdiff -u -r#{identifier_to} -r#{identifier_from} #{shell_quote path_with_project}"
diff = [] diff = []
shellout(cmd) do |io| shellout(cmd) do |io|
io.each_line do |line| io.each_line do |line|
@@ -244,7 +244,7 @@ module Redmine
identifier = (identifier) ? identifier : "HEAD" identifier = (identifier) ? identifier : "HEAD"
logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}" logger.debug "<cvs> cat path:'#{path}',identifier #{identifier}"
path_with_project="#{url}#{with_leading_slash(path)}" path_with_project="#{url}#{with_leading_slash(path)}"
cmd = "#{CVS_BIN} -d #{root_url} co" cmd = "#{CVS_BIN} -d #{shell_quote root_url} co"
cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier cmd << " -D \"#{time_to_cvstime(identifier)}\"" if identifier
cmd << " -p #{shell_quote path_with_project}" cmd << " -p #{shell_quote path_with_project}"
cat = nil cat = nil
@@ -256,10 +256,10 @@ module Redmine
end end
def annotate(path, identifier=nil) def annotate(path, identifier=nil)
identifier = (identifier) ? identifier : "HEAD" identifier = (identifier) ? identifier.to_i : "HEAD"
logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}" logger.debug "<cvs> annotate path:'#{path}',identifier #{identifier}"
path_with_project="#{url}#{with_leading_slash(path)}" path_with_project="#{url}#{with_leading_slash(path)}"
cmd = "#{CVS_BIN} -d #{root_url} rannotate -r#{identifier} #{shell_quote path_with_project}" cmd = "#{CVS_BIN} -d #{shell_quote root_url} rannotate -r#{identifier} #{shell_quote path_with_project}"
blame = Annotate.new blame = Annotate.new
shellout(cmd) do |io| shellout(cmd) do |io|
io.each_line do |line| io.each_line do |line|
+5 -5
View File
@@ -66,7 +66,7 @@ module Redmine
path_prefix = (path.blank? ? '' : "#{path}/") path_prefix = (path.blank? ? '' : "#{path}/")
path = '.' if path.blank? path = '.' if path.blank?
entries = Entries.new entries = Entries.new
cmd = "#{DARCS_BIN} annotate --repodir #{@url} --xml-output" cmd = "#{DARCS_BIN} annotate --repodir #{shell_quote @url} --xml-output"
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
cmd << " #{shell_quote path}" cmd << " #{shell_quote path}"
shellout(cmd) do |io| shellout(cmd) do |io|
@@ -90,7 +90,7 @@ module Redmine
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
path = '.' if path.blank? path = '.' if path.blank?
revisions = Revisions.new revisions = Revisions.new
cmd = "#{DARCS_BIN} changes --repodir #{@url} --xml-output" cmd = "#{DARCS_BIN} changes --repodir #{shell_quote @url} --xml-output"
cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from cmd << " --from-match #{shell_quote("hash #{identifier_from}")}" if identifier_from
cmd << " --last #{options[:limit].to_i}" if options[:limit] cmd << " --last #{options[:limit].to_i}" if options[:limit]
shellout(cmd) do |io| shellout(cmd) do |io|
@@ -116,7 +116,7 @@ module Redmine
def diff(path, identifier_from, identifier_to=nil) def diff(path, identifier_from, identifier_to=nil)
path = '*' if path.blank? path = '*' if path.blank?
cmd = "#{DARCS_BIN} diff --repodir #{@url}" cmd = "#{DARCS_BIN} diff --repodir #{shell_quote @url}"
if identifier_to.nil? if identifier_to.nil?
cmd << " --match #{shell_quote("hash #{identifier_from}")}" cmd << " --match #{shell_quote("hash #{identifier_from}")}"
else else
@@ -135,7 +135,7 @@ module Redmine
end end
def cat(path, identifier=nil) def cat(path, identifier=nil)
cmd = "#{DARCS_BIN} show content --repodir #{@url}" cmd = "#{DARCS_BIN} show content --repodir #{shell_quote @url}"
cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier cmd << " --match #{shell_quote("hash #{identifier}")}" if identifier
cmd << " #{shell_quote path}" cmd << " #{shell_quote path}"
cat = nil cat = nil
@@ -170,7 +170,7 @@ module Redmine
# Retrieve changed paths for a single patch # Retrieve changed paths for a single patch
def get_paths_for_patch(hash) def get_paths_for_patch(hash)
cmd = "#{DARCS_BIN} annotate --repodir #{@url} --summary --xml-output" cmd = "#{DARCS_BIN} annotate --repodir #{shell_quote @url} --summary --xml-output"
cmd << " --match #{shell_quote("hash #{hash}")} " cmd << " --match #{shell_quote("hash #{hash}")} "
paths = [] paths = []
shellout(cmd) do |io| shellout(cmd) do |io|
+3 -3
View File
@@ -117,7 +117,7 @@ module Redmine
cmd = "#{GIT_BIN} --git-dir #{target('')} log --no-color --raw --date=iso --pretty=fuller " cmd = "#{GIT_BIN} --git-dir #{target('')} log --no-color --raw --date=iso --pretty=fuller "
cmd << " --reverse " if options[:reverse] cmd << " --reverse " if options[:reverse]
cmd << " --all " if options[:all] cmd << " --all " if options[:all]
cmd << " -n #{options[:limit]} " if options[:limit] cmd << " -n #{options[:limit].to_i} " if options[:limit]
cmd << "#{shell_quote(identifier_from + '..')}" if identifier_from cmd << "#{shell_quote(identifier_from + '..')}" if identifier_from
cmd << "#{shell_quote identifier_to}" if identifier_to cmd << "#{shell_quote identifier_to}" if identifier_to
cmd << " --since=#{shell_quote(options[:since].strftime("%Y-%m-%d %H:%M:%S"))}" if options[:since] cmd << " --since=#{shell_quote(options[:since].strftime("%Y-%m-%d %H:%M:%S"))}" if options[:since]
@@ -211,7 +211,7 @@ module Redmine
if identifier_to if identifier_to
cmd = "#{GIT_BIN} --git-dir #{target('')} diff --no-color #{shell_quote identifier_to} #{shell_quote identifier_from}" cmd = "#{GIT_BIN} --git-dir #{target('')} diff --no-color #{shell_quote identifier_to} #{shell_quote identifier_from}"
else else
cmd = "#{GIT_BIN} --git-dir #{target('')} show #{shell_quote identifier_from}" cmd = "#{GIT_BIN} --git-dir #{target('')} show --no-color #{shell_quote identifier_from}"
end end
cmd << " -- #{shell_quote path}" unless path.empty? cmd << " -- #{shell_quote path}" unless path.empty?
@@ -255,7 +255,7 @@ module Redmine
if identifier.nil? if identifier.nil?
identifier = 'HEAD' identifier = 'HEAD'
end end
cmd = "#{GIT_BIN} --git-dir #{target('')} show #{shell_quote(identifier + ':' + path)}" cmd = "#{GIT_BIN} --git-dir #{target('')} show --no-color #{shell_quote(identifier + ':' + path)}"
cat = nil cat = nil
shellout(cmd) do |io| shellout(cmd) do |io|
io.binmode io.binmode
@@ -1,7 +1,7 @@
changeset = 'This template must be used with --debug option\n' changeset = 'This template must be used with --debug option\n'
changeset_quiet = 'This template must be used with --debug option\n' changeset_quiet = 'This template must be used with --debug option\n'
changeset_verbose = 'This template must be used with --debug option\n' changeset_verbose = 'This template must be used with --debug option\n'
changeset_debug = '<logentry revision="{rev}" node="{node|short}">\n<author>{author|escape}</author>\n<date>{date|isodate}</date>\n<paths>\n{file_mods}{file_adds}{file_dels}{file_copies}</paths>\n<msg>{desc|escape}</msg>\n{tags}</logentry>\n\n' changeset_debug = '<logentry revision="{rev}" node="{node|short}">\n<author>{author|escape}</author>\n<date>{date|isodatesec}</date>\n<paths>\n{file_mods}{file_adds}{file_dels}{file_copies}</paths>\n<msg>{desc|escape}</msg>\n{tags}</logentry>\n\n'
file_mod = '<path action="M">{file_mod|escape}</path>\n' file_mod = '<path action="M">{file_mod|escape}</path>\n'
file_add = '<path action="A">{file_add|escape}</path>\n' file_add = '<path action="A">{file_add|escape}</path>\n'
+10 -7
View File
@@ -38,13 +38,13 @@ module Redmine
# release number (eg 0.9.5 or 1.0) or as a revision # release number (eg 0.9.5 or 1.0) or as a revision
# id composed of 12 hexa characters. # id composed of 12 hexa characters.
theversion = hgversion_from_command_line theversion = hgversion_from_command_line
if theversion.match(/^\d+(\.\d+)+/) if m = theversion.match(%r{\A(.*?)((\d+\.)+\d+)})
theversion.split(".").collect(&:to_i) m[2].scan(%r{\d+}).collect(&:to_i)
end end
end end
def hgversion_from_command_line def hgversion_from_command_line
%x{#{HG_BIN} --version}.match(/\(version (.*)\)/)[1] shellout("#{HG_BIN} --version") { |io| io.read }.to_s
end end
def template_path def template_path
@@ -80,7 +80,7 @@ module Redmine
path ||= '' path ||= ''
entries = Entries.new entries = Entries.new
cmd = "#{HG_BIN} -R #{target('')} --cwd #{target('')} locate" cmd = "#{HG_BIN} -R #{target('')} --cwd #{target('')} locate"
cmd << " -r " + (identifier ? identifier.to_s : "tip") cmd << " -r " + shell_quote(identifier ? identifier.to_s : "tip")
cmd << " " + shell_quote("path:#{path}") unless path.empty? cmd << " " + shell_quote("path:#{path}") unless path.empty?
shellout(cmd) do |io| shellout(cmd) do |io|
io.each_line do |line| io.each_line do |line|
@@ -112,7 +112,7 @@ module Redmine
cmd << " -r #{identifier_from.to_i}:" cmd << " -r #{identifier_from.to_i}:"
end end
cmd << " --limit #{options[:limit].to_i}" if options[:limit] cmd << " --limit #{options[:limit].to_i}" if options[:limit]
cmd << " #{path}" if path cmd << " #{shell_quote path}" unless path.blank?
shellout(cmd) do |io| shellout(cmd) do |io|
begin begin
# HG doesn't close the XML Document... # HG doesn't close the XML Document...
@@ -157,6 +157,9 @@ module Redmine
else else
identifier_to = identifier_from.to_i - 1 identifier_to = identifier_from.to_i - 1
end end
if identifier_from
identifier_from = identifier_from.to_i
end
cmd = "#{HG_BIN} -R #{target('')} diff -r #{identifier_to} -r #{identifier_from} --nodates" cmd = "#{HG_BIN} -R #{target('')} diff -r #{identifier_to} -r #{identifier_from} --nodates"
cmd << " -I #{target(path)}" unless path.empty? cmd << " -I #{target(path)}" unless path.empty?
diff = [] diff = []
@@ -171,7 +174,7 @@ module Redmine
def cat(path, identifier=nil) def cat(path, identifier=nil)
cmd = "#{HG_BIN} -R #{target('')} cat" cmd = "#{HG_BIN} -R #{target('')} cat"
cmd << " -r " + (identifier ? identifier.to_s : "tip") cmd << " -r " + shell_quote(identifier ? identifier.to_s : "tip")
cmd << " #{target(path)}" cmd << " #{target(path)}"
cat = nil cat = nil
shellout(cmd) do |io| shellout(cmd) do |io|
@@ -186,7 +189,7 @@ module Redmine
path ||= '' path ||= ''
cmd = "#{HG_BIN} -R #{target('')}" cmd = "#{HG_BIN} -R #{target('')}"
cmd << " annotate -n -u" cmd << " annotate -n -u"
cmd << " -r " + (identifier ? identifier.to_s : "tip") cmd << " -r " + shell_quote(identifier ? identifier.to_s : "tip")
cmd << " -r #{identifier.to_i}" if identifier cmd << " -r #{identifier.to_i}" if identifier
cmd << " #{target(path)}" cmd << " #{target(path)}"
blame = Annotate.new blame = Annotate.new
@@ -36,8 +36,8 @@ module Redmine
version = nil version = nil
shellout(cmd) do |io| shellout(cmd) do |io|
# Read svn version in first returned line # Read svn version in first returned line
if m = io.gets.to_s.match(%r{((\d+\.)+\d+)}) if m = io.read.to_s.match(%r{\A(.*?)((\d+\.)+\d+)})
version = m[0].scan(%r{\d+}).collect(&:to_i) version = m[2].scan(%r{\d+}).collect(&:to_i)
end end
end end
return nil if $? && $?.exitstatus != 0 return nil if $? && $?.exitstatus != 0
@@ -135,8 +135,8 @@ module Redmine
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={}) def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
path ||= '' path ||= ''
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD" identifier_from = (identifier_from && identifier_from.to_i > 0) ? identifier_from.to_i : "HEAD"
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : 1 identifier_to = (identifier_to && identifier_to.to_i > 0) ? identifier_to.to_i : 1
revisions = Revisions.new revisions = Revisions.new
cmd = "#{SVN_BIN} log --xml -r #{identifier_from}:#{identifier_to}" cmd = "#{SVN_BIN} log --xml -r #{identifier_from}:#{identifier_to}"
cmd << credentials_string cmd << credentials_string
+1 -1
View File
@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc: module VERSION #:nodoc:
MAJOR = 1 MAJOR = 1
MINOR = 0 MINOR = 0
TINY = 3 TINY = 5
# Branch values: # Branch values:
# * official release: nil # * official release: nil
+2 -2
View File
@@ -167,7 +167,7 @@ namespace :redmine do
has_many :attachments, :class_name => "TracAttachment", has_many :attachments, :class_name => "TracAttachment",
:finder_sql => "SELECT DISTINCT attachment.* FROM #{TracMigrate::TracAttachment.table_name}" + :finder_sql => "SELECT DISTINCT attachment.* FROM #{TracMigrate::TracAttachment.table_name}" +
" WHERE #{TracMigrate::TracAttachment.table_name}.type = 'ticket'" + " WHERE #{TracMigrate::TracAttachment.table_name}.type = 'ticket'" +
' AND #{TracMigrate::TracAttachment.table_name}.id = \'#{id}\'' ' AND #{TracMigrate::TracAttachment.table_name}.id = \'#{TracMigrate::TracAttachment.connection.quote_string(id.to_s)}\''
has_many :customs, :class_name => "TracTicketCustom", :foreign_key => :ticket has_many :customs, :class_name => "TracTicketCustom", :foreign_key => :ticket
def ticket_type def ticket_type
@@ -207,7 +207,7 @@ namespace :redmine do
has_many :attachments, :class_name => "TracAttachment", has_many :attachments, :class_name => "TracAttachment",
:finder_sql => "SELECT DISTINCT attachment.* FROM #{TracMigrate::TracAttachment.table_name}" + :finder_sql => "SELECT DISTINCT attachment.* FROM #{TracMigrate::TracAttachment.table_name}" +
" WHERE #{TracMigrate::TracAttachment.table_name}.type = 'wiki'" + " WHERE #{TracMigrate::TracAttachment.table_name}.type = 'wiki'" +
' AND #{TracMigrate::TracAttachment.table_name}.id = \'#{id}\'' ' AND #{TracMigrate::TracAttachment.table_name}.id = \'#{TracMigrate::TracAttachment.connection.quote_string(id.to_s)}\''
def self.columns def self.columns
# Hides readonly Trac field to prevent clash with AR readonly? method (Rails 2.0) # Hides readonly Trac field to prevent clash with AR readonly? method (Rails 2.0)
+12
View File
@@ -145,3 +145,15 @@ attachments_012:
filename: version_file.zip filename: version_file.zip
author_id: 2 author_id: 2
content_type: application/octet-stream content_type: application/octet-stream
attachments_013:
created_on: 2006-07-19 21:07:27 +02:00
container_type: Message
container_id: 1
downloads: 0
disk_filename: 060719210727_foo.zip
digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
id: 13
filesize: 452
filename: foo.zip
author_id: 2
content_type: application/octet-stream
+39
View File
@@ -250,6 +250,9 @@ class IssuesControllerTest < ActionController::TestCase
get :show, :id => 1 get :show, :id => 1
assert_response :success assert_response :success
assert_tag :tag => 'a',
:content => /Quote/
assert_tag :tag => 'form', assert_tag :tag => 'form',
:descendant => { :tag => 'fieldset', :descendant => { :tag => 'fieldset',
:child => { :tag => 'legend', :child => { :tag => 'legend',
@@ -382,6 +385,7 @@ class IssuesControllerTest < ActionController::TestCase
:subject => 'This is the test_new issue', :subject => 'This is the test_new issue',
:description => 'This is the description', :description => 'This is the description',
:priority_id => 5, :priority_id => 5,
:start_date => '2010-11-07',
:estimated_hours => '', :estimated_hours => '',
:custom_field_values => {'2' => 'Value for field 2'}} :custom_field_values => {'2' => 'Value for field 2'}}
end end
@@ -392,12 +396,33 @@ class IssuesControllerTest < ActionController::TestCase
assert_equal 2, issue.author_id assert_equal 2, issue.author_id
assert_equal 3, issue.tracker_id assert_equal 3, issue.tracker_id
assert_equal 2, issue.status_id assert_equal 2, issue.status_id
assert_equal Date.parse('2010-11-07'), issue.start_date
assert_nil issue.estimated_hours assert_nil issue.estimated_hours
v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2}) v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
assert_not_nil v assert_not_nil v
assert_equal 'Value for field 2', v.value assert_equal 'Value for field 2', v.value
end end
def test_post_create_without_start_date
@request.session[:user_id] = 2
assert_difference 'Issue.count' do
post :create, :project_id => 1,
:issue => {:tracker_id => 3,
:status_id => 2,
:subject => 'This is the test_new issue',
:description => 'This is the description',
:priority_id => 5,
:start_date => '',
:estimated_hours => '',
:custom_field_values => {'2' => 'Value for field 2'}}
end
assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
issue = Issue.find_by_subject('This is the test_new issue')
assert_not_nil issue
assert_nil issue.start_date
end
def test_post_create_and_continue def test_post_create_and_continue
@request.session[:user_id] = 2 @request.session[:user_id] = 2
post :create, :project_id => 1, post :create, :project_id => 1,
@@ -476,6 +501,20 @@ class IssuesControllerTest < ActionController::TestCase
assert_not_nil issue assert_not_nil issue
assert_equal Issue.find(2), issue.parent assert_equal Issue.find(2), issue.parent
end end
def test_post_create_subissue_with_non_numeric_parent_id
@request.session[:user_id] = 2
assert_difference 'Issue.count' do
post :create, :project_id => 1,
:issue => {:tracker_id => 1,
:subject => 'This is a child issue',
:parent_issue_id => 'ABC'}
end
issue = Issue.find_by_subject('This is a child issue')
assert_not_nil issue
assert_nil issue.parent
end
def test_post_create_should_send_a_notification def test_post_create_should_send_a_notification
ActionMailer::Base.deliveries.clear ActionMailer::Base.deliveries.clear
+8 -2
View File
@@ -40,14 +40,20 @@ class JournalsControllerTest < ActionController::TestCase
def test_reply_to_issue def test_reply_to_issue
@request.session[:user_id] = 2 @request.session[:user_id] = 2
get :new, :id => 1 get :new, :id => 6
assert_response :success assert_response :success
assert_select_rjs :show, "update" assert_select_rjs :show, "update"
end end
def test_reply_to_issue_without_permission
@request.session[:user_id] = 7
get :new, :id => 6
assert_response 403
end
def test_reply_to_note def test_reply_to_note
@request.session[:user_id] = 2 @request.session[:user_id] = 2
get :new, :id => 1, :journal_id => 2 get :new, :id => 6, :journal_id => 4
assert_response :success assert_response :success
assert_select_rjs :show, "update" assert_select_rjs :show, "update"
end end
@@ -22,6 +22,7 @@ require 'repositories_controller'
class RepositoriesController; def rescue_action(e) raise e end; end class RepositoriesController; def rescue_action(e) raise e end; end
class RepositoriesCvsControllerTest < ActionController::TestCase class RepositoriesCvsControllerTest < ActionController::TestCase
fixtures :projects, :users, :roles, :members, :member_roles, :repositories, :enabled_modules
# No '..' in the repository path # No '..' in the repository path
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository' REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository'
@@ -123,6 +123,15 @@ class VersionsControllerTest < ActionController::TestCase
assert_equal 'New version name', version.name assert_equal 'New version name', version.name
assert_equal Date.today, version.effective_date assert_equal Date.today, version.effective_date
end end
def test_post_update_with_validation_failure
@request.session[:user_id] = 2
post :update, :id => 2,
:version => { :name => '',
:effective_date => Date.today.strftime("%Y-%m-%d")}
assert_response :success
assert_template 'edit'
end
def test_destroy def test_destroy
@request.session[:user_id] = 2 @request.session[:user_id] = 2
@@ -1,6 +1,6 @@
require "#{File.dirname(__FILE__)}/../test_helper" require "#{File.dirname(__FILE__)}/../../test_helper"
class DisabledRestApi < ActionController::IntegrationTest class ApiTest::DisabledRestApiTest < ActionController::IntegrationTest
fixtures :all fixtures :all
def setup def setup
@@ -0,0 +1,31 @@
require "#{File.dirname(__FILE__)}/../../test_helper"
class ApiTest::HttpBasicLoginTest < ActionController::IntegrationTest
fixtures :all
def setup
Setting.rest_api_enabled = '1'
Setting.login_required = '1'
end
def teardown
Setting.rest_api_enabled = '0'
Setting.login_required = '0'
end
# Using the NewsController because it's a simple API.
context "get /news" do
setup do
project = Project.find('onlinestore')
EnabledModule.create(:project => project, :name => 'news')
end
context "in :xml format" do
should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.xml")
end
context "in :json format" do
should_allow_http_basic_auth_with_username_and_password(:get, "/projects/onlinestore/news.json")
end
end
end
@@ -0,0 +1,27 @@
require "#{File.dirname(__FILE__)}/../../test_helper"
class ApiTest::HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
fixtures :all
def setup
Setting.rest_api_enabled = '1'
Setting.login_required = '1'
end
def teardown
Setting.rest_api_enabled = '0'
Setting.login_required = '0'
end
# Using the NewsController because it's a simple API.
context "get /news" do
context "in :xml format" do
should_allow_http_basic_auth_with_key(:get, "/news.xml")
end
context "in :json format" do
should_allow_http_basic_auth_with_key(:get, "/news.json")
end
end
end
+336
View File
@@ -0,0 +1,336 @@
# Redmine - project management software
# Copyright (C) 2006-2010 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require "#{File.dirname(__FILE__)}/../../test_helper"
class ApiTest::IssuesTest < ActionController::IntegrationTest
fixtures :projects,
:users,
:roles,
:members,
:member_roles,
:issues,
:issue_statuses,
:versions,
:trackers,
:projects_trackers,
:issue_categories,
:enabled_modules,
:enumerations,
:attachments,
:workflows,
:custom_fields,
:custom_values,
:custom_fields_projects,
:custom_fields_trackers,
:time_entries,
:journals,
:journal_details,
:queries
def setup
Setting.rest_api_enabled = '1'
end
# Use a private project to make sure auth is really working and not just
# only showing public issues.
context "/index.xml" do
should_allow_api_authentication(:get, "/projects/private-child/issues.xml")
end
context "/index.json" do
should_allow_api_authentication(:get, "/projects/private-child/issues.json")
end
context "/index.xml with filter" do
should_allow_api_authentication(:get, "/projects/private-child/issues.xml?status_id=5")
should "show only issues with the status_id" do
get '/issues.xml?status_id=5'
assert_tag :tag => 'issues',
:children => { :count => Issue.visible.count(:conditions => {:status_id => 5}),
:only => { :tag => 'issue' } }
end
end
context "/index.json with filter" do
should_allow_api_authentication(:get, "/projects/private-child/issues.json?status_id=5")
should "show only issues with the status_id" do
get '/issues.json?status_id=5'
json = ActiveSupport::JSON.decode(response.body)
status_ids_used = json.collect {|j| j['status_id'] }
assert_equal 3, status_ids_used.length
assert status_ids_used.all? {|id| id == 5 }
end
end
# Issue 6 is on a private project
context "/issues/6.xml" do
should_allow_api_authentication(:get, "/issues/6.xml")
end
context "/issues/6.json" do
should_allow_api_authentication(:get, "/issues/6.json")
end
context "POST /issues.xml" do
should_allow_api_authentication(:post,
'/issues.xml',
{:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
{:success_code => :created})
should "create an issue with the attributes" do
assert_difference('Issue.count') do
post '/issues.xml', {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, :authorization => credentials('jsmith')
end
issue = Issue.first(:order => 'id DESC')
assert_equal 1, issue.project_id
assert_equal 2, issue.tracker_id
assert_equal 3, issue.status_id
assert_equal 'API test', issue.subject
end
end
context "POST /issues.xml with failure" do
should_allow_api_authentication(:post,
'/issues.xml',
{:issue => {:project_id => 1}},
{:success_code => :unprocessable_entity})
should "have an errors tag" do
assert_no_difference('Issue.count') do
post '/issues.xml', {:issue => {:project_id => 1}}, :authorization => credentials('jsmith')
end
assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
end
end
context "POST /issues.json" do
should_allow_api_authentication(:post,
'/issues.json',
{:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}},
{:success_code => :created})
should "create an issue with the attributes" do
assert_difference('Issue.count') do
post '/issues.json', {:issue => {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}}, :authorization => credentials('jsmith')
end
issue = Issue.first(:order => 'id DESC')
assert_equal 1, issue.project_id
assert_equal 2, issue.tracker_id
assert_equal 3, issue.status_id
assert_equal 'API test', issue.subject
end
end
context "POST /issues.json with failure" do
should_allow_api_authentication(:post,
'/issues.json',
{:issue => {:project_id => 1}},
{:success_code => :unprocessable_entity})
should "have an errors element" do
assert_no_difference('Issue.count') do
post '/issues.json', {:issue => {:project_id => 1}}, :authorization => credentials('jsmith')
end
json = ActiveSupport::JSON.decode(response.body)
assert_equal "can't be blank", json.first['subject']
end
end
# Issue 6 is on a private project
context "PUT /issues/6.xml" do
setup do
@parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
@headers = { :authorization => credentials('jsmith') }
end
should_allow_api_authentication(:put,
'/issues/6.xml',
{:issue => {:subject => 'API update', :notes => 'A new note'}},
{:success_code => :ok})
should "not create a new issue" do
assert_no_difference('Issue.count') do
put '/issues/6.xml', @parameters, @headers
end
end
should "create a new journal" do
assert_difference('Journal.count') do
put '/issues/6.xml', @parameters, @headers
end
end
should "add the note to the journal" do
put '/issues/6.xml', @parameters, @headers
journal = Journal.last
assert_equal "A new note", journal.notes
end
should "update the issue" do
put '/issues/6.xml', @parameters, @headers
issue = Issue.find(6)
assert_equal "API update", issue.subject
end
end
context "PUT /issues/6.xml with failed update" do
setup do
@parameters = {:issue => {:subject => ''}}
@headers = { :authorization => credentials('jsmith') }
end
should_allow_api_authentication(:put,
'/issues/6.xml',
{:issue => {:subject => ''}}, # Missing subject should fail
{:success_code => :unprocessable_entity})
should "not create a new issue" do
assert_no_difference('Issue.count') do
put '/issues/6.xml', @parameters, @headers
end
end
should "not create a new journal" do
assert_no_difference('Journal.count') do
put '/issues/6.xml', @parameters, @headers
end
end
should "have an errors tag" do
put '/issues/6.xml', @parameters, @headers
assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
end
end
context "PUT /issues/6.json" do
setup do
@parameters = {:issue => {:subject => 'API update', :notes => 'A new note'}}
@headers = { :authorization => credentials('jsmith') }
end
should_allow_api_authentication(:put,
'/issues/6.json',
{:issue => {:subject => 'API update', :notes => 'A new note'}},
{:success_code => :ok})
should "not create a new issue" do
assert_no_difference('Issue.count') do
put '/issues/6.json', @parameters, @headers
end
end
should "create a new journal" do
assert_difference('Journal.count') do
put '/issues/6.json', @parameters, @headers
end
end
should "add the note to the journal" do
put '/issues/6.json', @parameters, @headers
journal = Journal.last
assert_equal "A new note", journal.notes
end
should "update the issue" do
put '/issues/6.json', @parameters, @headers
issue = Issue.find(6)
assert_equal "API update", issue.subject
end
end
context "PUT /issues/6.json with failed update" do
setup do
@parameters = {:issue => {:subject => ''}}
@headers = { :authorization => credentials('jsmith') }
end
should_allow_api_authentication(:put,
'/issues/6.json',
{:issue => {:subject => ''}}, # Missing subject should fail
{:success_code => :unprocessable_entity})
should "not create a new issue" do
assert_no_difference('Issue.count') do
put '/issues/6.json', @parameters, @headers
end
end
should "not create a new journal" do
assert_no_difference('Journal.count') do
put '/issues/6.json', @parameters, @headers
end
end
should "have an errors attribute" do
put '/issues/6.json', @parameters, @headers
json = ActiveSupport::JSON.decode(response.body)
assert_equal "can't be blank", json.first['subject']
end
end
context "DELETE /issues/1.xml" do
should_allow_api_authentication(:delete,
'/issues/6.xml',
{},
{:success_code => :ok})
should "delete the issue" do
assert_difference('Issue.count',-1) do
delete '/issues/6.xml', {}, :authorization => credentials('jsmith')
end
assert_nil Issue.find_by_id(6)
end
end
context "DELETE /issues/1.json" do
should_allow_api_authentication(:delete,
'/issues/6.json',
{},
{:success_code => :ok})
should "delete the issue" do
assert_difference('Issue.count',-1) do
delete '/issues/6.json', {}, :authorization => credentials('jsmith')
end
assert_nil Issue.find_by_id(6)
end
end
def credentials(user, password=nil)
ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
end
end
@@ -15,9 +15,9 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require "#{File.dirname(__FILE__)}/../test_helper" require "#{File.dirname(__FILE__)}/../../test_helper"
class ProjectsApiTest < ActionController::IntegrationTest class ApiTest::ProjectsTest < ActionController::IntegrationTest
fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details, fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
:trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
:attachments, :custom_fields, :custom_values, :time_entries :attachments, :custom_fields, :custom_values, :time_entries
@@ -31,23 +31,37 @@ class ProjectsApiTest < ActionController::IntegrationTest
assert_response :success assert_response :success
assert_equal 'application/xml', @response.content_type assert_equal 'application/xml', @response.content_type
end end
context "GET /projects/2.xml" do
# TODO: A private project is needed because should_allow_api_authentication
# actually tests that authentication is *required*, not just allowed
should_allow_api_authentication(:get, "/projects/2.xml")
end
def test_show def test_show
get '/projects/1.xml' get '/projects/1.xml'
assert_response :success assert_response :success
assert_equal 'application/xml', @response.content_type assert_equal 'application/xml', @response.content_type
end end
def test_create context "POST /projects.xml" do
attributes = {:name => 'API test', :identifier => 'api-test'} should_allow_api_authentication(:post,
assert_difference 'Project.count' do '/projects.xml',
post '/projects.xml', {:project => attributes}, :authorization => credentials('admin') {:project => {:name => 'API test', :identifier => 'api-test'}},
end {:success_code => :created})
assert_response :created
assert_equal 'application/xml', @response.content_type should "create a project with the attributes" do
project = Project.first(:order => 'id DESC') assert_difference('Project.count') do
attributes.each do |attribute, value| post '/projects.xml', {:project => {:name => 'API test', :identifier => 'api-test'}}, :authorization => credentials('admin')
assert_equal value, project.send(attribute) end
project = Project.first(:order => 'id DESC')
assert_equal 'API test', project.name
assert_equal 'api-test', project.identifier
assert_response :created
assert_equal 'application/xml', @response.content_type
assert_tag 'project', :child => {:tag => 'id', :content => project.id.to_s}
end end
end end
@@ -61,16 +75,20 @@ class ProjectsApiTest < ActionController::IntegrationTest
assert_tag :errors, :child => {:tag => 'error', :content => "Identifier can't be blank"} assert_tag :errors, :child => {:tag => 'error', :content => "Identifier can't be blank"}
end end
def test_update context "PUT /projects/2.xml" do
attributes = {:name => 'API update'} should_allow_api_authentication(:put,
assert_no_difference 'Project.count' do '/projects/2.xml',
put '/projects/1.xml', {:project => attributes}, :authorization => credentials('jsmith') {:project => {:name => 'API test'}},
end {:success_code => :ok})
assert_response :ok
assert_equal 'application/xml', @response.content_type should "update the project" do
project = Project.find(1) assert_no_difference 'Project.count' do
attributes.each do |attribute, value| put '/projects/2.xml', {:project => {:name => 'API update'}}, :authorization => credentials('jsmith')
assert_equal value, project.send(attribute) end
assert_response :ok
assert_equal 'application/xml', @response.content_type
project = Project.find(2)
assert_equal 'API update', project.name
end end
end end
@@ -83,14 +101,20 @@ class ProjectsApiTest < ActionController::IntegrationTest
assert_equal 'application/xml', @response.content_type assert_equal 'application/xml', @response.content_type
assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"} assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"}
end end
def test_destroy context "DELETE /projects/2.xml" do
assert_difference 'Project.count', -1 do should_allow_api_authentication(:delete,
delete '/projects/2.xml', {}, :authorization => credentials('admin') '/projects/2.xml',
{},
{:success_code => :ok})
should "delete the project" do
assert_difference('Project.count',-1) do
delete '/projects/2.xml', {}, :authorization => credentials('admin')
end
assert_response :ok
assert_nil Project.find_by_id(2)
end end
assert_response :ok
assert_equal 'application/xml', @response.content_type
assert_nil Project.find_by_id(2)
end end
def credentials(user, password=nil) def credentials(user, password=nil)
@@ -0,0 +1,26 @@
require "#{File.dirname(__FILE__)}/../../test_helper"
class ApiTest::TokenAuthenticationTest < ActionController::IntegrationTest
fixtures :all
def setup
Setting.rest_api_enabled = '1'
Setting.login_required = '1'
end
def teardown
Setting.rest_api_enabled = '0'
Setting.login_required = '0'
end
# Using the NewsController because it's a simple API.
context "get /news" do
context "in :xml format" do
should_allow_key_based_auth(:get, "/news.xml")
end
context "in :json format" do
should_allow_key_based_auth(:get, "/news.json")
end
end
end
-80
View File
@@ -1,80 +0,0 @@
require "#{File.dirname(__FILE__)}/../test_helper"
class ApiTokenLoginTest < ActionController::IntegrationTest
fixtures :all
def setup
Setting.rest_api_enabled = '1'
Setting.login_required = '1'
end
def teardown
Setting.rest_api_enabled = '0'
Setting.login_required = '0'
end
# Using the NewsController because it's a simple API.
context "get /news" do
context "in :xml format" do
context "with a valid api token" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'api')
get "/news.xml?key=#{@token.value}"
end
should_respond_with :success
should_respond_with_content_type :xml
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid api token" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'feeds')
get "/news.xml?key=#{@token.value}"
end
should_respond_with :unauthorized
should_respond_with_content_type :xml
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
context "in :json format" do
context "with a valid api token" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'api')
get "/news.json?key=#{@token.value}"
end
should_respond_with :success
should_respond_with_content_type :json
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid api token" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'feeds')
get "/news.json?key=#{@token.value}"
end
should_respond_with :unauthorized
should_respond_with_content_type :json
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
end
end
-103
View File
@@ -1,103 +0,0 @@
require "#{File.dirname(__FILE__)}/../test_helper"
class HttpBasicLoginTest < ActionController::IntegrationTest
fixtures :all
def setup
Setting.rest_api_enabled = '1'
Setting.login_required = '1'
end
def teardown
Setting.rest_api_enabled = '0'
Setting.login_required = '0'
end
# Using the NewsController because it's a simple API.
context "get /news" do
context "in :xml format" do
context "with a valid HTTP authentication" do
setup do
@user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
get "/news.xml", nil, :authorization => @authorization
end
should_respond_with :success
should_respond_with_content_type :xml
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate_with_protected!
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
get "/news.xml", nil, :authorization => @authorization
end
should_respond_with :unauthorized
should_respond_with_content_type :xml
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
context "without credentials" do
setup do
get "/projects/onlinestore/news.xml"
end
should_respond_with :unauthorized
should_respond_with_content_type :xml
should "include_www_authenticate_header" do
assert @controller.response.headers.has_key?('WWW-Authenticate')
end
end
end
context "in :json format" do
context "with a valid HTTP authentication" do
setup do
@user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
get "/news.json", nil, :authorization => @authorization
end
should_respond_with :success
should_respond_with_content_type :json
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate_with_protected!
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
get "/news.json", nil, :authorization => @authorization
end
should_respond_with :unauthorized
should_respond_with_content_type :json
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
context "without credentials" do
setup do
get "/projects/onlinestore/news.json"
end
should_respond_with :unauthorized
should_respond_with_content_type :json
should "include_www_authenticate_header" do
assert @controller.response.headers.has_key?('WWW-Authenticate')
end
end
end
end
@@ -1,84 +0,0 @@
require "#{File.dirname(__FILE__)}/../test_helper"
class HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
fixtures :all
def setup
Setting.rest_api_enabled = '1'
Setting.login_required = '1'
end
def teardown
Setting.rest_api_enabled = '0'
Setting.login_required = '0'
end
# Using the NewsController because it's a simple API.
context "get /news" do
context "in :xml format" do
context "with a valid HTTP authentication using the API token" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'api')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
get "/news.xml", nil, :authorization => @authorization
end
should_respond_with :success
should_respond_with_content_type :xml
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'feeds')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
get "/news.xml", nil, :authorization => @authorization
end
should_respond_with :unauthorized
should_respond_with_content_type :xml
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
context "in :json format" do
context "with a valid HTTP authentication" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'api')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
get "/news.json", nil, :authorization => @authorization
end
should_respond_with :success
should_respond_with_content_type :json
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'feeds')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
get "/news.json", nil, :authorization => @authorization
end
should_respond_with :unauthorized
should_respond_with_content_type :json
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
end
end
-349
View File
@@ -1,349 +0,0 @@
# Redmine - project management software
# Copyright (C) 2006-2010 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require "#{File.dirname(__FILE__)}/../test_helper"
class IssuesApiTest < ActionController::IntegrationTest
fixtures :projects,
:users,
:roles,
:members,
:member_roles,
:issues,
:issue_statuses,
:versions,
:trackers,
:projects_trackers,
:issue_categories,
:enabled_modules,
:enumerations,
:attachments,
:workflows,
:custom_fields,
:custom_values,
:custom_fields_projects,
:custom_fields_trackers,
:time_entries,
:journals,
:journal_details,
:queries
def setup
Setting.rest_api_enabled = '1'
end
context "/index.xml" do
setup do
get '/issues.xml'
end
should_respond_with :success
should_respond_with_content_type 'application/xml'
end
context "/index.json" do
setup do
get '/issues.json'
end
should_respond_with :success
should_respond_with_content_type 'application/json'
should 'return a valid JSON string' do
assert ActiveSupport::JSON.decode(response.body)
end
end
context "/index.xml with filter" do
setup do
get '/issues.xml?status_id=5'
end
should_respond_with :success
should_respond_with_content_type 'application/xml'
should "show only issues with the status_id" do
assert_tag :tag => 'issues',
:children => { :count => Issue.visible.count(:conditions => {:status_id => 5}),
:only => { :tag => 'issue' } }
end
end
context "/index.json with filter" do
setup do
get '/issues.json?status_id=5'
end
should_respond_with :success
should_respond_with_content_type 'application/json'
should 'return a valid JSON string' do
assert ActiveSupport::JSON.decode(response.body)
end
should "show only issues with the status_id" do
json = ActiveSupport::JSON.decode(response.body)
status_ids_used = json.collect {|j| j['status_id'] }
assert_equal 3, status_ids_used.length
assert status_ids_used.all? {|id| id == 5 }
end
end
context "/issues/1.xml" do
setup do
get '/issues/1.xml'
end
should_respond_with :success
should_respond_with_content_type 'application/xml'
end
context "/issues/1.json" do
setup do
get '/issues/1.json'
end
should_respond_with :success
should_respond_with_content_type 'application/json'
should 'return a valid JSON string' do
assert ActiveSupport::JSON.decode(response.body)
end
end
context "POST /issues.xml" do
setup do
@issue_count = Issue.count
@attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :created
should_respond_with_content_type 'application/xml'
should "create an issue with the attributes" do
assert_equal Issue.count, @issue_count + 1
issue = Issue.first(:order => 'id DESC')
@attributes.each do |attribute, value|
assert_equal value, issue.send(attribute)
end
end
end
context "POST /issues.xml with failure" do
setup do
@attributes = {:project_id => 1}
post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :unprocessable_entity
should_respond_with_content_type 'application/xml'
should "have an errors tag" do
assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
end
end
context "POST /issues.json" do
setup do
@issue_count = Issue.count
@attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :created
should_respond_with_content_type 'application/json'
should "create an issue with the attributes" do
assert_equal Issue.count, @issue_count + 1
issue = Issue.first(:order => 'id DESC')
@attributes.each do |attribute, value|
assert_equal value, issue.send(attribute)
end
end
end
context "POST /issues.json with failure" do
setup do
@attributes = {:project_id => 1}
post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :unprocessable_entity
should_respond_with_content_type 'application/json'
should "have an errors element" do
json = ActiveSupport::JSON.decode(response.body)
assert_equal "can't be blank", json.first['subject']
end
end
context "PUT /issues/1.xml" do
setup do
@issue_count = Issue.count
@journal_count = Journal.count
@attributes = {:subject => 'API update', :notes => 'A new note'}
put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :ok
should_respond_with_content_type 'application/xml'
should "not create a new issue" do
assert_equal Issue.count, @issue_count
end
should "create a new journal" do
assert_equal Journal.count, @journal_count + 1
end
should "add the note to the journal" do
journal = Journal.last
assert_equal "A new note", journal.notes
end
should "update the issue" do
issue = Issue.find(1)
@attributes.each do |attribute, value|
assert_equal value, issue.send(attribute) unless attribute == :notes
end
end
end
context "PUT /issues/1.xml with failed update" do
setup do
@attributes = {:subject => ''}
@issue_count = Issue.count
@journal_count = Journal.count
put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :unprocessable_entity
should_respond_with_content_type 'application/xml'
should "not create a new issue" do
assert_equal Issue.count, @issue_count
end
should "not create a new journal" do
assert_equal Journal.count, @journal_count
end
should "have an errors tag" do
assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
end
end
context "PUT /issues/1.json" do
setup do
@issue_count = Issue.count
@journal_count = Journal.count
@attributes = {:subject => 'API update', :notes => 'A new note'}
put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :ok
should_respond_with_content_type 'application/json'
should "not create a new issue" do
assert_equal Issue.count, @issue_count
end
should "create a new journal" do
assert_equal Journal.count, @journal_count + 1
end
should "add the note to the journal" do
journal = Journal.last
assert_equal "A new note", journal.notes
end
should "update the issue" do
issue = Issue.find(1)
@attributes.each do |attribute, value|
assert_equal value, issue.send(attribute) unless attribute == :notes
end
end
end
context "PUT /issues/1.json with failed update" do
setup do
@attributes = {:subject => ''}
@issue_count = Issue.count
@journal_count = Journal.count
put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
end
should_respond_with :unprocessable_entity
should_respond_with_content_type 'application/json'
should "not create a new issue" do
assert_equal Issue.count, @issue_count
end
should "not create a new journal" do
assert_equal Journal.count, @journal_count
end
should "have an errors attribute" do
json = ActiveSupport::JSON.decode(response.body)
assert_equal "can't be blank", json.first['subject']
end
end
context "DELETE /issues/1.xml" do
setup do
@issue_count = Issue.count
delete '/issues/1.xml', {}, :authorization => credentials('jsmith')
end
should_respond_with :ok
should_respond_with_content_type 'application/xml'
should "delete the issue" do
assert_equal Issue.count, @issue_count -1
assert_nil Issue.find_by_id(1)
end
end
context "DELETE /issues/1.json" do
setup do
@issue_count = Issue.count
delete '/issues/1.json', {}, :authorization => credentials('jsmith')
end
should_respond_with :ok
should_respond_with_content_type 'application/json'
should "delete the issue" do
assert_equal Issue.count, @issue_count -1
assert_nil Issue.find_by_id(1)
end
end
def credentials(user, password=nil)
ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
end
end
+232
View File
@@ -181,4 +181,236 @@ class ActiveSupport::TestCase
assert !user.new_record? assert !user.new_record?
end end
end end
# Test that a request allows the three types of API authentication
#
# * HTTP Basic with username and password
# * HTTP Basic with an api key for the username
# * Key based with the key=X parameter
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_api_authentication(http_method, url, parameters={}, options={})
should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters, options)
should_allow_http_basic_auth_with_key(http_method, url, parameters, options)
should_allow_key_based_auth(http_method, url, parameters, options)
end
# Test that a request allows the username and password for HTTP BASIC
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_http_basic_auth_with_username_and_password(http_method, url, parameters={}, options={})
success_code = options[:success_code] || :success
failure_code = options[:failure_code] || :unauthorized
context "should allow http basic auth using a username and password for #{http_method} #{url}" do
context "with a valid HTTP authentication" do
setup do
@user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password', :admin => true) # Admin so they can access the project
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
send(http_method, url, parameters, {:authorization => @authorization})
end
should_respond_with success_code
should_respond_with_content_type_based_on_url(url)
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate_with_protected!
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
send(http_method, url, parameters, {:authorization => @authorization})
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
context "without credentials" do
setup do
send(http_method, url, parameters, {:authorization => ''})
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "include_www_authenticate_header" do
assert @controller.response.headers.has_key?('WWW-Authenticate')
end
end
end
end
# Test that a request allows the API key with HTTP BASIC
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_http_basic_auth_with_key(http_method, url, parameters={}, options={})
success_code = options[:success_code] || :success
failure_code = options[:failure_code] || :unauthorized
context "should allow http basic auth with a key for #{http_method} #{url}" do
context "with a valid HTTP authentication using the API token" do
setup do
@user = User.generate_with_protected!(:admin => true)
@token = Token.generate!(:user => @user, :action => 'api')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
send(http_method, url, parameters, {:authorization => @authorization})
end
should_respond_with success_code
should_respond_with_content_type_based_on_url(url)
should_be_a_valid_response_string_based_on_url(url)
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid HTTP authentication" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'feeds')
@authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
send(http_method, url, parameters, {:authorization => @authorization})
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
end
# Test that a request allows full key authentication
#
# @param [Symbol] http_method the HTTP method for request (:get, :post, :put, :delete)
# @param [String] url the request url, without the key=ZXY parameter
# @param [optional, Hash] parameters additional request parameters
# @param [optional, Hash] options additional options
# @option options [Symbol] :success_code Successful response code (:success)
# @option options [Symbol] :failure_code Failure response code (:unauthorized)
def self.should_allow_key_based_auth(http_method, url, parameters={}, options={})
success_code = options[:success_code] || :success
failure_code = options[:failure_code] || :unauthorized
context "should allow key based auth using key=X for #{http_method} #{url}" do
context "with a valid api token" do
setup do
@user = User.generate_with_protected!(:admin => true)
@token = Token.generate!(:user => @user, :action => 'api')
# Simple url parse to add on ?key= or &key=
request_url = if url.match(/\?/)
url + "&key=#{@token.value}"
else
url + "?key=#{@token.value}"
end
send(http_method, request_url, parameters)
end
should_respond_with success_code
should_respond_with_content_type_based_on_url(url)
should_be_a_valid_response_string_based_on_url(url)
should "login as the user" do
assert_equal @user, User.current
end
end
context "with an invalid api token" do
setup do
@user = User.generate_with_protected!
@token = Token.generate!(:user => @user, :action => 'feeds')
# Simple url parse to add on ?key= or &key=
request_url = if url.match(/\?/)
url + "&key=#{@token.value}"
else
url + "?key=#{@token.value}"
end
send(http_method, request_url, parameters)
end
should_respond_with failure_code
should_respond_with_content_type_based_on_url(url)
should "not login as the user" do
assert_equal User.anonymous, User.current
end
end
end
end
# Uses should_respond_with_content_type based on what's in the url:
#
# '/project/issues.xml' => should_respond_with_content_type :xml
# '/project/issues.json' => should_respond_with_content_type :json
#
# @param [String] url Request
def self.should_respond_with_content_type_based_on_url(url)
case
when url.match(/xml/i)
should_respond_with_content_type :xml
when url.match(/json/i)
should_respond_with_content_type :json
else
raise "Unknown content type for should_respond_with_content_type_based_on_url: #{url}"
end
end
# Uses the url to assert which format the response should be in
#
# '/project/issues.xml' => should_be_a_valid_xml_string
# '/project/issues.json' => should_be_a_valid_json_string
#
# @param [String] url Request
def self.should_be_a_valid_response_string_based_on_url(url)
case
when url.match(/xml/i)
should_be_a_valid_xml_string
when url.match(/json/i)
should_be_a_valid_json_string
else
raise "Unknown content type for should_be_a_valid_response_based_on_url: #{url}"
end
end
# Checks that the response is a valid JSON string
def self.should_be_a_valid_json_string
should "be a valid JSON string (or empty)" do
assert (response.body.blank? || ActiveSupport::JSON.decode(response.body))
end
end
# Checks that the response is a valid XML string
def self.should_be_a_valid_xml_string
should "be a valid XML string" do
assert REXML::Document.new(response.body)
end
end
end
# Simple module to "namespace" all of the API tests
module ApiTest
end end
+8 -3
View File
@@ -1,7 +1,7 @@
require File.dirname(__FILE__) + '/../test_helper' require File.dirname(__FILE__) + '/../test_helper'
class BoardTest < ActiveSupport::TestCase class BoardTest < ActiveSupport::TestCase
fixtures :projects, :boards, :messages fixtures :projects, :boards, :messages, :attachments, :watchers
def setup def setup
@project = Project.find(1) @project = Project.find(1)
@@ -23,8 +23,13 @@ class BoardTest < ActiveSupport::TestCase
def test_destroy def test_destroy
board = Board.find(1) board = Board.find(1)
assert board.destroy assert_difference 'Message.count', -6 do
# make sure that the associated messages are removed assert_difference 'Attachment.count', -1 do
assert_difference 'Watcher.count', -1 do
assert board.destroy
end
end
end
assert_equal 0, Message.count(:conditions => {:board_id => 1}) assert_equal 0, Message.count(:conditions => {:board_id => 1})
end end
end end
@@ -284,6 +284,9 @@ RAW
"<!-- opening comment" => "<p>&lt;!-- opening comment</p>", "<!-- opening comment" => "<p>&lt;!-- opening comment</p>",
# remove attributes except class # remove attributes except class
"<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>", "<pre class='foo'>some text</pre>" => "<pre class='foo'>some text</pre>",
'<pre class="foo">some text</pre>' => '<pre class="foo">some text</pre>',
"<pre class='foo bar'>some text</pre>" => "<pre class='foo bar'>some text</pre>",
'<pre class="foo bar">some text</pre>' => '<pre class="foo bar">some text</pre>',
"<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>", "<pre onmouseover='alert(1)'>some text</pre>" => "<pre>some text</pre>",
} }
to_test.each { |text, result| assert_equal result, textilizable(text) } to_test.each { |text, result| assert_equal result, textilizable(text) }
+10
View File
@@ -63,4 +63,14 @@ class IssueRelationTest < ActiveSupport::TestCase
assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type_for(from) assert_equal IssueRelation::TYPE_PRECEDES, relation.relation_type_for(from)
assert_equal IssueRelation::TYPE_FOLLOWS, relation.relation_type_for(to) assert_equal IssueRelation::TYPE_FOLLOWS, relation.relation_type_for(to)
end end
def test_set_issue_to_dates_without_issue_to
r = IssueRelation.new(:issue_from => Issue.new(:start_date => Date.today), :relation_type => IssueRelation::TYPE_PRECEDES, :delay => 1)
assert_nil r.set_issue_to_dates
end
def test_set_issue_to_dates_without_issues
r = IssueRelation.new(:relation_type => IssueRelation::TYPE_PRECEDES, :delay => 1)
assert_nil r.set_issue_to_dates
end
end end
+4 -4
View File
@@ -29,7 +29,7 @@ class Redmine::I18nTest < ActiveSupport::TestCase
set_language_if_valid 'en' set_language_if_valid 'en'
today = Date.today today = Date.today
Setting.date_format = '' Setting.date_format = ''
assert_equal I18n.l(today, :count => today.strftime('%d')), format_date(today) assert_equal I18n.l(today), format_date(today)
end end
def test_date_format def test_date_format
@@ -47,7 +47,7 @@ class Redmine::I18nTest < ActiveSupport::TestCase
format_date(Date.today) format_date(Date.today)
format_time(Time.now) format_time(Time.now)
format_time(Time.now, false) format_time(Time.now, false)
assert_not_equal 'default', ::I18n.l(Date.today, :count => Date.today.strftime('%d'), :format => :default), "date.formats.default missing in #{lang}" assert_not_equal 'default', ::I18n.l(Date.today, :format => :default), "date.formats.default missing in #{lang}"
assert_not_equal 'time', ::I18n.l(Time.now, :format => :time), "time.formats.time missing in #{lang}" assert_not_equal 'time', ::I18n.l(Time.now, :format => :time), "time.formats.time missing in #{lang}"
end end
assert l('date.day_names').is_a?(Array) assert l('date.day_names').is_a?(Array)
@@ -63,8 +63,8 @@ class Redmine::I18nTest < ActiveSupport::TestCase
now = Time.now now = Time.now
Setting.date_format = '' Setting.date_format = ''
Setting.time_format = '' Setting.time_format = ''
assert_equal I18n.l(now, :count => now.strftime('%d')), format_time(now) assert_equal I18n.l(now), format_time(now)
assert_equal I18n.l(now, :count => now.strftime('%d'), :format => :time), format_time(now, false) assert_equal I18n.l(now, :format => :time), format_time(now, false)
end end
def test_time_format def test_time_format
@@ -11,12 +11,15 @@ begin
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/mercurial_repository' REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/mercurial_repository'
def test_hgversion def test_hgversion
to_test = { "0.9.5" => [0,9,5], to_test = { "Mercurial Distributed SCM (version 0.9.5)\n" => [0,9,5],
"1.0" => [1,0], "Mercurial Distributed SCM (1.0)\n" => [1,0],
"1e4ddc9ac9f7+20080325" => nil, "Mercurial Distributed SCM (1e4ddc9ac9f7+20080325)\n" => nil,
"1.0.1+20080525" => [1,0,1], "Mercurial Distributed SCM (1.0.1+20080525)\n" => [1,0,1],
"1916e629a29d" => nil} "Mercurial Distributed SCM (1916e629a29d)\n" => nil,
"Mercurial SCM Distribuito (versione 0.9.5)\n" => [0,9,5],
"(1.6)\n(1.7)\n(1.8)" => [1,6],
"(1.7.1)\r\n(1.8.1)\r\n(1.9.1)" => [1,7,1]}
to_test.each do |s, v| to_test.each do |s, v|
test_hgversion_for(s, v) test_hgversion_for(s, v)
end end
@@ -26,8 +29,9 @@ begin
to_test = { [0,9,5] => "0.9.5", to_test = { [0,9,5] => "0.9.5",
[1,0] => "1.0", [1,0] => "1.0",
[] => "1.0", [] => "1.0",
[1,0,1] => "1.0"} [1,0,1] => "1.0",
[1,7] => "1.0",
[1,7,1] => "1.0"}
to_test.each do |v, template| to_test.each do |v, template|
test_template_path_for(v, template) test_template_path_for(v, template)
end end
@@ -49,5 +53,8 @@ begin
end end
rescue LoadError rescue LoadError
def test_fake; assert(false, "Requires mocha to run those tests") end class MercurialMochaFake < ActiveSupport::TestCase
def test_fake; assert(false, "Requires mocha to run those tests") end
end
end end
+20
View File
@@ -305,6 +305,26 @@ class MailerTest < ActiveSupport::TestCase
end end
end end
def test_wiki_content_added
content = WikiContent.find(:first)
valid_languages.each do |lang|
Setting.default_language = lang.to_s
assert_difference 'ActionMailer::Base.deliveries.size' do
assert Mailer.deliver_wiki_content_added(content)
end
end
end
def test_wiki_content_updated
content = WikiContent.find(:first)
valid_languages.each do |lang|
Setting.default_language = lang.to_s
assert_difference 'ActionMailer::Base.deliveries.size' do
assert Mailer.deliver_wiki_content_updated(content)
end
end
end
def test_account_information def test_account_information
user = User.find(2) user = User.find(2)
valid_languages.each do |lang| valid_languages.each do |lang|
+16
View File
@@ -225,6 +225,22 @@ class QueryTest < ActiveSupport::TestCase
q = Query.new q = Query.new
assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn} assert q.groupable_columns.detect {|c| c.is_a? QueryCustomFieldColumn}
end end
def test_grouped_with_valid_column
q = Query.new(:group_by => 'status')
assert q.grouped?
assert_not_nil q.group_by_column
assert_equal :status, q.group_by_column.name
assert_not_nil q.group_by_statement
assert_equal 'status', q.group_by_statement
end
def test_grouped_with_invalid_column
q = Query.new(:group_by => 'foo')
assert !q.grouped?
assert_nil q.group_by_column
assert_nil q.group_by_statement
end
def test_default_sort def test_default_sort
q = Query.new q = Query.new
+9 -1
View File
@@ -62,12 +62,20 @@ class RepositoryMercurialTest < ActiveSupport::TestCase
assert_equal 2, @repository.entries("images", 2).size assert_equal 2, @repository.entries("images", 2).size
end end
def test_cat def test_cat
assert @repository.scm.cat("sources/welcome_controller.rb", 2) assert @repository.scm.cat("sources/welcome_controller.rb", 2)
assert_nil @repository.scm.cat("sources/welcome_controller.rb") assert_nil @repository.scm.cat("sources/welcome_controller.rb")
end end
def test_isodatesec
# Template keyword 'isodatesec' supported in Mercurial 1.0 and higher
if @repository.scm.class.client_version_above?([1, 0])
@repository.fetch_changesets
@repository.reload
rev0_committed_on = Time.gm(2007, 12, 14, 9, 22, 52)
assert_equal @repository.changesets.find_by_revision('0').committed_on, rev0_committed_on
end
end
else else
puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!" puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
def test_fake; assert true end def test_fake; assert true end