Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
797f777900 | ||
|
|
04a8a72491 | ||
|
|
a1a6dcffca | ||
|
|
d31402734b | ||
|
|
5180ca0cdd | ||
|
|
e5802895ce | ||
|
|
da1a3449ce | ||
|
|
2b2f721ef4 | ||
|
|
62114336cf | ||
|
|
4f48d1b4dd | ||
|
|
d6d064f875 | ||
|
|
6d8649b9d3 | ||
|
|
39deb03855 | ||
|
|
70036a7ad0 | ||
|
|
68d421b978 | ||
|
|
268a9db47e | ||
|
|
a35b81b9fa | ||
|
|
fd450fd2da | ||
|
|
2c0ba78f70 | ||
|
|
f0f01d370e | ||
|
|
4c330a1241 | ||
|
|
baa4ebd05f | ||
|
|
59f14478ed | ||
|
|
8fefb7c05b | ||
|
|
1feb373c89 | ||
|
|
32fd503cbb | ||
|
|
cf31aeaf81 | ||
|
|
83ea66fd2c | ||
|
|
ef2c5cab2d | ||
|
|
dee6f6b138 | ||
|
|
a4c0c18e3d | ||
|
|
4c82fbb6f8 | ||
|
|
68ded50edc | ||
|
|
72ecb80dc7 | ||
|
|
86ee285eb4 | ||
|
|
c229ea6386 | ||
|
|
687fca170e | ||
|
|
26564b06f7 | ||
|
|
34016c38bd | ||
|
|
15ff361894 | ||
|
|
b45b5f4322 | ||
|
|
8addbc537a | ||
|
|
87eeacba80 | ||
|
|
a7250c41e2 | ||
|
|
7c45396d92 | ||
|
|
c1f98c835c |
24
Gemfile
24
Gemfile
@@ -2,7 +2,7 @@ source :rubygems
|
||||
|
||||
gem "rails", "2.3.14"
|
||||
gem "i18n", "~> 0.4.2"
|
||||
gem "coderay", "~> 1.0.0"
|
||||
gem "coderay", "~> 1.0.6"
|
||||
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
|
||||
gem "tzinfo", "~> 0.3.31"
|
||||
|
||||
@@ -16,18 +16,20 @@ group :openid do
|
||||
gem "ruby-openid", "~> 2.1.4", :require => "openid"
|
||||
end
|
||||
|
||||
# Optional gem for exporting the gantt to a PNG file
|
||||
group :rmagick do
|
||||
# RMagick 2 supports ruby 1.9
|
||||
# RMagick 1 would be fine for ruby 1.8 but Bundler does not support
|
||||
# different requirements for the same gem on different platforms
|
||||
gem "rmagick", ">= 2.0.0"
|
||||
# Optional gem for exporting the gantt to a PNG file, not supported with jruby
|
||||
platforms :mri, :mingw do
|
||||
group :rmagick do
|
||||
# RMagick 2 supports ruby 1.9
|
||||
# RMagick 1 would be fine for ruby 1.8 but Bundler does not support
|
||||
# different requirements for the same gem on different platforms
|
||||
gem "rmagick", ">= 2.0.0"
|
||||
end
|
||||
end
|
||||
|
||||
# Database gems
|
||||
platforms :mri, :mingw do
|
||||
group :postgresql do
|
||||
gem "pg", "~> 0.9.0"
|
||||
gem "pg", ">= 0.11.0"
|
||||
end
|
||||
|
||||
group :sqlite do
|
||||
@@ -73,6 +75,12 @@ group :test do
|
||||
gem "mocha"
|
||||
end
|
||||
|
||||
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
|
||||
if File.exists?(local_gemfile)
|
||||
puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v`
|
||||
instance_eval File.read(local_gemfile)
|
||||
end
|
||||
|
||||
# Load plugins' Gemfiles
|
||||
Dir.glob File.expand_path("../vendor/plugins/*/Gemfile", __FILE__) do |file|
|
||||
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
|
||||
|
||||
@@ -131,14 +131,6 @@ class AccountController < ApplicationController
|
||||
|
||||
private
|
||||
|
||||
def logout_user
|
||||
if User.current.logged?
|
||||
cookies.delete :autologin
|
||||
Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
|
||||
self.logged_user = nil
|
||||
end
|
||||
end
|
||||
|
||||
def authenticate_user
|
||||
if Setting.openid? && using_open_id?
|
||||
open_id_authenticate(params[:openid_url])
|
||||
|
||||
@@ -75,9 +75,7 @@ class AdminController < ApplicationController
|
||||
def info
|
||||
@db_adapter_name = ActiveRecord::Base.connection.adapter_name
|
||||
@checklist = [
|
||||
[:text_default_administrator_account_changed,
|
||||
User.find(:first,
|
||||
:conditions => ["login=? and hashed_password=?", 'admin', User.hash_password('admin')]).nil?],
|
||||
[:text_default_administrator_account_changed, User.default_admin_account_changed?],
|
||||
[:text_file_repository_writable, File.writable?(Attachment.storage_path)],
|
||||
[:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)],
|
||||
[:text_rmagick_available, Object.const_defined?(:Magick)]
|
||||
|
||||
@@ -126,6 +126,15 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
# Logs out current user
|
||||
def logout_user
|
||||
if User.current.logged?
|
||||
cookies.delete :autologin
|
||||
Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
|
||||
self.logged_user = nil
|
||||
end
|
||||
end
|
||||
|
||||
# check if login is globally required to access the application
|
||||
def check_if_login_required
|
||||
# no check needed if user is already logged in
|
||||
@@ -364,18 +373,6 @@ class ApplicationController < ActionController::Base
|
||||
:content_type => 'application/atom+xml'
|
||||
end
|
||||
|
||||
# TODO: remove in Redmine 1.4
|
||||
def self.accept_key_auth(*actions)
|
||||
ActiveSupport::Deprecation.warn "ApplicationController.accept_key_auth is deprecated and will be removed in Redmine 1.4. Use accept_rss_auth (or accept_api_auth) instead."
|
||||
accept_rss_auth(*actions)
|
||||
end
|
||||
|
||||
# TODO: remove in Redmine 1.4
|
||||
def accept_key_auth_actions
|
||||
ActiveSupport::Deprecation.warn "ApplicationController.accept_key_auth_actions is deprecated and will be removed in Redmine 1.4. Use accept_rss_auth (or accept_api_auth) instead."
|
||||
self.class.accept_rss_auth
|
||||
end
|
||||
|
||||
def self.accept_rss_auth(*actions)
|
||||
if actions.any?
|
||||
write_inheritable_attribute('accept_rss_auth_actions', actions)
|
||||
|
||||
@@ -47,7 +47,7 @@ class BoardsController < ApplicationController
|
||||
:include => [:author, {:last_reply => :author}],
|
||||
:limit => @topic_pages.items_per_page,
|
||||
:offset => @topic_pages.current.offset
|
||||
@message = Message.new
|
||||
@message = Message.new(:board => @board)
|
||||
render :action => 'show', :layout => !request.xhr?
|
||||
}
|
||||
format.atom {
|
||||
|
||||
@@ -42,7 +42,7 @@ class IssueRelationsController < ApplicationController
|
||||
def create
|
||||
@relation = IssueRelation.new(params[:relation])
|
||||
@relation.issue_from = @issue
|
||||
if params[:relation] && m = params[:relation][:issue_to_id].to_s.match(/^#?(\d+)$/)
|
||||
if params[:relation] && m = params[:relation][:issue_to_id].to_s.strip.match(/^#?(\d+)$/)
|
||||
@relation.issue_to = Issue.visible.find_by_id(m[1].to_i)
|
||||
end
|
||||
saved = @relation.save
|
||||
|
||||
@@ -225,12 +225,19 @@ class IssuesController < ApplicationController
|
||||
end
|
||||
target_projects ||= @projects
|
||||
|
||||
@available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
|
||||
if @copy
|
||||
@available_statuses = [IssueStatus.default]
|
||||
else
|
||||
@available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
|
||||
end
|
||||
@custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&)
|
||||
@assignables = target_projects.map(&:assignable_users).reduce(:&)
|
||||
@trackers = target_projects.map(&:trackers).reduce(:&)
|
||||
@versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&)
|
||||
@categories = target_projects.map {|p| p.issue_categories}.reduce(:&)
|
||||
if @copy
|
||||
@attachments_present = @issues.detect {|i| i.attachments.any?}.present?
|
||||
end
|
||||
|
||||
@safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
|
||||
render :layout => false if request.xhr?
|
||||
@@ -246,7 +253,7 @@ class IssuesController < ApplicationController
|
||||
@issues.each do |issue|
|
||||
issue.reload
|
||||
if @copy
|
||||
issue = issue.copy
|
||||
issue = issue.copy({}, :attachments => params[:copy_attachments].present?)
|
||||
end
|
||||
journal = issue.init_journal(User.current, params[:notes])
|
||||
issue.safe_attributes = attributes
|
||||
@@ -348,8 +355,6 @@ private
|
||||
# from the params
|
||||
# TODO: Refactor, not everything in here is needed by #edit
|
||||
def update_issue_from_params
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
@priorities = IssuePriority.active
|
||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||
@time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
|
||||
@time_entry.attributes = params[:time_entry]
|
||||
@@ -371,6 +376,8 @@ private
|
||||
end
|
||||
end
|
||||
@issue.safe_attributes = issue_attributes
|
||||
@priorities = IssuePriority.active
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
true
|
||||
end
|
||||
|
||||
@@ -420,7 +427,16 @@ private
|
||||
def parse_params_for_bulk_issue_attributes(params)
|
||||
attributes = (params[:issue] || {}).reject {|k,v| v.blank?}
|
||||
attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
|
||||
attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values]
|
||||
if custom = attributes[:custom_field_values]
|
||||
custom.reject! {|k,v| v.blank?}
|
||||
custom.keys.each do |k|
|
||||
if custom[k].is_a?(Array)
|
||||
custom[k] << '' if custom[k].delete('__none__')
|
||||
else
|
||||
custom[k] = '' if custom[k] == '__none__'
|
||||
end
|
||||
end
|
||||
end
|
||||
attributes
|
||||
end
|
||||
end
|
||||
|
||||
@@ -65,6 +65,24 @@ class MyController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
# Destroys user's account
|
||||
def destroy
|
||||
@user = User.current
|
||||
unless @user.own_account_deletable?
|
||||
redirect_to :action => 'account'
|
||||
return
|
||||
end
|
||||
|
||||
if request.post? && params[:confirm]
|
||||
@user.destroy
|
||||
if @user.destroyed?
|
||||
logout_user
|
||||
flash[:notice] = l(:notice_account_deleted)
|
||||
end
|
||||
redirect_to home_path
|
||||
end
|
||||
end
|
||||
|
||||
# Manage user's password
|
||||
def password
|
||||
@user = User.current
|
||||
|
||||
@@ -100,6 +100,7 @@ module CustomFieldsHelper
|
||||
when "list"
|
||||
options = []
|
||||
options << [l(:label_no_change_option), ''] unless custom_field.multiple?
|
||||
options << [l(:label_none), '__none__'] unless custom_field.is_required?
|
||||
options += custom_field.possible_values_options(projects)
|
||||
select_tag(field_name, options_for_select(options),
|
||||
:id => field_id, :multiple => custom_field.multiple?)
|
||||
|
||||
@@ -332,7 +332,7 @@ module IssuesHelper
|
||||
cv = issue.custom_field_values.detect {|v| v.custom_field_id == column.custom_field.id}
|
||||
show_value(cv)
|
||||
else
|
||||
value = issue.send(column.name)
|
||||
value = column.value(issue)
|
||||
if value.is_a?(Date)
|
||||
format_date(value)
|
||||
elsif value.is_a?(Time)
|
||||
|
||||
@@ -145,8 +145,8 @@ class Issue < ActiveRecord::Base
|
||||
end
|
||||
|
||||
# Returns an unsaved copy of the issue
|
||||
def copy(attributes=nil)
|
||||
copy = self.class.new.copy_from(self)
|
||||
def copy(attributes=nil, copy_options={})
|
||||
copy = self.class.new.copy_from(self, copy_options)
|
||||
copy.attributes = attributes if attributes
|
||||
copy
|
||||
end
|
||||
@@ -509,18 +509,30 @@ class Issue < ActiveRecord::Base
|
||||
!relations_to.detect {|ir| ir.relation_type == 'blocks' && !ir.issue_from.closed?}.nil?
|
||||
end
|
||||
|
||||
# Returns an array of status that user is able to apply
|
||||
# Returns an array of statuses that user is able to apply
|
||||
def new_statuses_allowed_to(user=User.current, include_default=false)
|
||||
statuses = status.find_new_statuses_allowed_to(
|
||||
user.admin ? Role.all : user.roles_for_project(project),
|
||||
tracker,
|
||||
author == user,
|
||||
assigned_to_id_changed? ? assigned_to_id_was == user.id : assigned_to_id == user.id
|
||||
)
|
||||
statuses << status unless statuses.empty?
|
||||
statuses << IssueStatus.default if include_default
|
||||
statuses = statuses.uniq.sort
|
||||
blocked? ? statuses.reject {|s| s.is_closed?} : statuses
|
||||
if new_record? && @copied_from
|
||||
[IssueStatus.default, @copied_from.status].compact.uniq.sort
|
||||
else
|
||||
initial_status = nil
|
||||
if new_record?
|
||||
initial_status = IssueStatus.default
|
||||
elsif status_id_was
|
||||
initial_status = IssueStatus.find_by_id(status_id_was)
|
||||
end
|
||||
initial_status ||= status
|
||||
|
||||
statuses = initial_status.find_new_statuses_allowed_to(
|
||||
user.admin ? Role.all : user.roles_for_project(project),
|
||||
tracker,
|
||||
author == user,
|
||||
assigned_to_id_changed? ? assigned_to_id_was == user.id : assigned_to_id == user.id
|
||||
)
|
||||
statuses << initial_status unless statuses.empty?
|
||||
statuses << IssueStatus.default if include_default
|
||||
statuses = statuses.compact.uniq.sort
|
||||
blocked? ? statuses.reject {|s| s.is_closed?} : statuses
|
||||
end
|
||||
end
|
||||
|
||||
def assigned_to_was
|
||||
|
||||
@@ -42,6 +42,12 @@ class MailHandler < ActionMailer::Base
|
||||
super email
|
||||
end
|
||||
|
||||
cattr_accessor :ignored_emails_headers
|
||||
@@ignored_emails_headers = {
|
||||
'X-Auto-Response-Suppress' => 'OOF',
|
||||
'Auto-Submitted' => 'auto-replied'
|
||||
}
|
||||
|
||||
# Processes incoming emails
|
||||
# Returns the created object (eg. an issue, a message) or false
|
||||
def receive(email)
|
||||
@@ -54,6 +60,16 @@ class MailHandler < ActionMailer::Base
|
||||
end
|
||||
return false
|
||||
end
|
||||
# Ignore auto generated emails
|
||||
self.class.ignored_emails_headers.each do |key, ignored_value|
|
||||
value = email.header_string(key)
|
||||
if value && value.to_s.downcase == ignored_value.downcase
|
||||
if logger && logger.info
|
||||
logger.info "MailHandler: ignoring email with #{key}:#{value} header"
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
@user = User.find_by_mail(sender_email) if sender_email.present?
|
||||
if @user && !@user.active?
|
||||
if logger && logger.info
|
||||
|
||||
@@ -359,7 +359,7 @@ class Mailer < ActionMailer::Base
|
||||
|
||||
issues_by_assignee = scope.all(:include => [:status, :assigned_to, :project, :tracker]).group_by(&:assigned_to)
|
||||
issues_by_assignee.each do |assignee, issues|
|
||||
deliver_reminder(assignee, issues, days) if assignee && assignee.active?
|
||||
deliver_reminder(assignee, issues, days) if assignee.is_a?(User) && assignee.active?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -372,6 +372,17 @@ class Mailer < ActionMailer::Base
|
||||
ActionMailer::Base.perform_deliveries = was_enabled
|
||||
end
|
||||
|
||||
# Sends emails synchronously in the given block
|
||||
def self.with_synched_deliveries(&block)
|
||||
saved_method = ActionMailer::Base.delivery_method
|
||||
if m = saved_method.to_s.match(%r{^async_(.+)$})
|
||||
ActionMailer::Base.delivery_method = m[1].to_sym
|
||||
end
|
||||
yield
|
||||
ensure
|
||||
ActionMailer::Base.delivery_method = saved_method
|
||||
end
|
||||
|
||||
private
|
||||
def initialize_defaults(method_name)
|
||||
super
|
||||
|
||||
@@ -37,7 +37,6 @@ class Message < ActiveRecord::Base
|
||||
:author_key => :author_id
|
||||
acts_as_watchable
|
||||
|
||||
attr_protected :locked, :sticky
|
||||
validates_presence_of :board, :subject, :content
|
||||
validates_length_of :subject, :maximum => 255
|
||||
validate :cannot_reply_to_locked_topic, :on => :create
|
||||
@@ -50,7 +49,7 @@ class Message < ActiveRecord::Base
|
||||
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
|
||||
|
||||
safe_attributes 'subject', 'content'
|
||||
safe_attributes 'locked', 'sticky',
|
||||
safe_attributes 'locked', 'sticky', 'board_id',
|
||||
:if => lambda {|message, user|
|
||||
user.allowed_to?(:edit_messages, message.project)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class Token < ActiveRecord::Base
|
||||
|
||||
# Delete all expired tokens
|
||||
def self.destroy_expired
|
||||
Token.delete_all ["action <> 'feeds' AND created_on < ?", Time.now - @@validity_time]
|
||||
Token.delete_all ["action NOT IN (?) AND created_on < ?", ['feeds', 'api'], Time.now - @@validity_time]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -68,7 +68,7 @@ class User < Principal
|
||||
MAIL_LENGTH_LIMIT = 60
|
||||
|
||||
validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
|
||||
validates_uniqueness_of :login, :if => Proc.new { |user| !user.login.blank? }, :case_sensitive => false
|
||||
validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, :case_sensitive => false
|
||||
validates_uniqueness_of :mail, :if => Proc.new { |user| !user.mail.blank? }, :case_sensitive => false
|
||||
# Login must contain lettres, numbers, underscores only
|
||||
validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
|
||||
@@ -284,14 +284,18 @@ class User < Principal
|
||||
|
||||
# Return user's RSS key (a 40 chars long string), used to access feeds
|
||||
def rss_key
|
||||
token = self.rss_token || Token.create(:user => self, :action => 'feeds')
|
||||
token.value
|
||||
if rss_token.nil?
|
||||
create_rss_token(:action => 'feeds')
|
||||
end
|
||||
rss_token.value
|
||||
end
|
||||
|
||||
# Return user's API key (a 40 chars long string), used to access the API
|
||||
def api_key
|
||||
token = self.api_token || self.create_api_token(:action => 'api')
|
||||
token.value
|
||||
if api_token.nil?
|
||||
create_api_token(:action => 'api')
|
||||
end
|
||||
api_token.value
|
||||
end
|
||||
|
||||
# Return an array of project ids for which the user has explicitly turned mail notifications on
|
||||
@@ -348,6 +352,11 @@ class User < Principal
|
||||
find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
|
||||
end
|
||||
|
||||
# Returns true if the default admin account can no longer be used
|
||||
def self.default_admin_account_changed?
|
||||
!User.active.find_by_login("admin").try(:check_password?, "admin")
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
@@ -477,6 +486,12 @@ class User < Principal
|
||||
allowed_to?(action, nil, options.reverse_merge(:global => true), &block)
|
||||
end
|
||||
|
||||
# Returns true if the user is allowed to delete his own account
|
||||
def own_account_deletable?
|
||||
Setting.unsubscribe? &&
|
||||
(!admin? || User.active.first(:conditions => ["admin = ? AND id <> ?", true, id]).present?)
|
||||
end
|
||||
|
||||
safe_attributes 'login',
|
||||
'firstname',
|
||||
'lastname',
|
||||
|
||||
@@ -60,6 +60,13 @@
|
||||
<p><label><%= h(custom_field.name) %></label> <%= custom_field_tag_for_bulk_edit('issue', custom_field, @projects) %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @copy && @attachments_present %>
|
||||
<p>
|
||||
<label for='copy_attachments'><%= l(:label_copy_attachments) %></label>
|
||||
<%= check_box_tag 'copy_attachments', '1', true %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= call_hook(:view_issues_bulk_edit_details_bottom, { :issues => @issues }) %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<title><%=h html_title %></title>
|
||||
<meta name="description" content="<%= Redmine::Info.app_name %>" />
|
||||
<meta name="keywords" content="issue,bug,tracker" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE" />
|
||||
<%= csrf_meta_tag %>
|
||||
<%= favicon %>
|
||||
<%= stylesheet_link_tag 'application', :media => 'all' %>
|
||||
|
||||
@@ -6,13 +6,17 @@
|
||||
<p><label for="message_subject"><%= l(:field_subject) %></label><br />
|
||||
<%= f.text_field :subject, :size => 120, :id => "message_subject" %>
|
||||
|
||||
<% if !replying && User.current.allowed_to?(:edit_messages, @project) %>
|
||||
<% unless replying %>
|
||||
<% if @message.safe_attribute? 'sticky' %>
|
||||
<label><%= f.check_box :sticky %><%= l(:label_board_sticky) %></label>
|
||||
<% end %>
|
||||
<% if @message.safe_attribute? 'locked' %>
|
||||
<label><%= f.check_box :locked %><%= l(:label_board_locked) %></label>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<% if !replying && !@message.new_record? && User.current.allowed_to?(:edit_messages, @project) %>
|
||||
<% if !replying && !@message.new_record? && @message.safe_attribute?('board_id') %>
|
||||
<p><label><%= l(:label_board) %></label><br />
|
||||
<%= f.select :board_id, @project.boards.collect {|b| [b.name, b.id]} %></p>
|
||||
<% end %>
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
<p><%=l(:field_login)%>: <strong><%= link_to_user(@user, :format => :username) %></strong><br />
|
||||
<%=l(:field_created_on)%>: <%= format_time(@user.created_on) %></p>
|
||||
|
||||
<% if @user.own_account_deletable? %>
|
||||
<p><%= link_to(l(:button_delete_my_account), {:action => 'destroy'}, :class => 'icon icon-del') %></p>
|
||||
<% end %>
|
||||
|
||||
<h4><%= l(:label_feeds_access_key) %></h4>
|
||||
|
||||
|
||||
11
app/views/my/destroy.html.erb
Normal file
11
app/views/my/destroy.html.erb
Normal file
@@ -0,0 +1,11 @@
|
||||
<h2><%=l(:label_confirmation)%></h2>
|
||||
<div class="warning">
|
||||
<p><%= simple_format l(:text_account_destroy_confirmation)%></p>
|
||||
<p>
|
||||
<% form_tag({}) do %>
|
||||
<label><%= check_box_tag 'confirm', 1 %> <%= l(:general_text_Yes) %></label>
|
||||
<%= submit_tag l(:button_delete_my_account) %> |
|
||||
<%= link_to l(:button_cancel), :action => 'account' %>
|
||||
<% end %>
|
||||
</p>
|
||||
</div>
|
||||
@@ -10,6 +10,8 @@
|
||||
[l(:label_registration_manual_activation), "2"],
|
||||
[l(:label_registration_automatic_activation), "3"]] %></p>
|
||||
|
||||
<p><%= setting_check_box :unsubscribe %></p>
|
||||
|
||||
<p><%= setting_text_field :password_min_length, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_check_box :lost_password, :label => :label_password_lost %></p>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<p>
|
||||
<%= label_tag "period_type_interval", l(:description_date_range_interval), :class => "hidden-for-sighted" %>
|
||||
<%= radio_button_tag 'period_type', '2', @free_period, :onclick => 'Form.Element.enable("from");Form.Element.enable("to");Form.Element.disable("period");', :id => "period_type_interval" %>
|
||||
<span onclick="$('period_type_2').checked = true;">
|
||||
<span onclick="$('period_type_interval').checked = true;Form.Element.enable('from');Form.Element.enable('to');Form.Element.disable('period');">
|
||||
<%= l(:label_date_from_to,
|
||||
:start => ((label_tag "from", l(:description_date_from), :class => "hidden-for-sighted") +
|
||||
text_field_tag('from', @from, :size => 10, :disabled => !@free_period) + calendar_for('from')),
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# MySQL (default setup).
|
||||
# Default setup is given for MySQL with ruby1.8. If you're running Redmine
|
||||
# with MySQL and ruby1.9, replace the adapter name with `mysql2`.
|
||||
# Examples for PostgreSQL and SQLite3 can be found at the end.
|
||||
|
||||
production:
|
||||
adapter: mysql
|
||||
|
||||
@@ -1025,3 +1025,9 @@ ar:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -174,6 +174,7 @@ bg:
|
||||
notice_gantt_chart_truncated: Мрежовият график е съкратен, понеже броят на обектите, които могат да бъдат показани е твърде голям (%{max})
|
||||
notice_issue_successful_create: Задача %{id} е създадена.
|
||||
notice_issue_update_conflict: Задачата е била променена от друг потребител, докато вие сте я редактирали.
|
||||
notice_account_deleted: Вашият профил беше премахнат без възможност за възстановяване.
|
||||
|
||||
error_can_t_load_default_data: "Грешка при зареждане на примерната информация: %{value}"
|
||||
error_scm_not_found: Несъществуващ обект в хранилището.
|
||||
@@ -384,6 +385,7 @@ bg:
|
||||
setting_issue_group_assignment: Разрешено назначаването на задачи на групи
|
||||
setting_default_issue_start_date_to_creation_date: Начална дата на новите задачи по подразбиране да бъде днешната дата
|
||||
setting_commit_cross_project_ref: Отбелязване и приключване на задачи от други проекти, несвързани с конкретното хранилище
|
||||
setting_unsubscribe: Потребителите могат да премахват профилите си
|
||||
|
||||
permission_add_project: Създаване на проект
|
||||
permission_add_subprojects: Създаване на подпроекти
|
||||
@@ -895,6 +897,7 @@ bg:
|
||||
button_show: Показване
|
||||
button_edit_section: Редактиране на тази секция
|
||||
button_export: Експорт
|
||||
button_delete_my_account: Премахване на моя профил
|
||||
|
||||
status_active: активен
|
||||
status_registered: регистриран
|
||||
@@ -979,6 +982,7 @@ bg:
|
||||
text_issue_conflict_resolution_overwrite: Прилагане на моите промени (предишните коментари ще бъдат запазени, но някои други промени може да бъдат презаписани)
|
||||
text_issue_conflict_resolution_add_notes: Добавяне на моите коментари и отхвърляне на другите мои промени
|
||||
text_issue_conflict_resolution_cancel: Отхвърляне на всички мои промени и презареждане на %{link}
|
||||
text_account_destroy_confirmation: "Сигурен/на ли сте, че желаете да продължите?\nВашият профил ще бъде премахнат без възможност за възстановяване."
|
||||
|
||||
default_role_manager: Мениджър
|
||||
default_role_developer: Разработчик
|
||||
|
||||
@@ -1039,3 +1039,9 @@ bs:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1027,3 +1027,9 @@ ca:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1028,3 +1028,9 @@ cs:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1042,3 +1042,9 @@ da:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -210,7 +210,7 @@ de:
|
||||
mail_body_lost_password: 'Benutzen Sie den folgenden Link, um Ihr Kennwort zu ändern:'
|
||||
mail_subject_register: "%{value} Kontoaktivierung"
|
||||
mail_body_register: 'Um Ihr Konto zu aktivieren, benutzen Sie folgenden Link:'
|
||||
mail_body_account_information_external: "Sie können sich mit Ihrem Konto %{value} an anmelden."
|
||||
mail_body_account_information_external: "Sie können sich mit Ihrem Konto %{value} anmelden."
|
||||
mail_body_account_information: Ihre Konto-Informationen
|
||||
mail_subject_account_activation_request: "Antrag auf %{value} Kontoaktivierung"
|
||||
mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
|
||||
@@ -503,7 +503,7 @@ de:
|
||||
label_last_login: Letzte Anmeldung
|
||||
label_registered_on: Angemeldet am
|
||||
label_activity: Aktivität
|
||||
label_overall_activity: Aktivität aller Projekte anzeigen
|
||||
label_overall_activity: Aktivitäten aller Projekte anzeigen
|
||||
label_user_activity: "Aktivität von %{value}"
|
||||
label_new: Neu
|
||||
label_logged_as: Angemeldet als
|
||||
@@ -717,7 +717,7 @@ de:
|
||||
label_message_new: Neues Thema
|
||||
label_message_posted: Forenbeitrag hinzugefügt
|
||||
label_reply_plural: Antworten
|
||||
label_send_information: Sende Kontoinformationen zum Benutzer
|
||||
label_send_information: Sende Kontoinformationen an Benutzer
|
||||
label_year: Jahr
|
||||
label_month: Monat
|
||||
label_week: Woche
|
||||
@@ -992,11 +992,11 @@ de:
|
||||
text_scm_config: Die SCM-Kommandos können in der in config/configuration.yml konfiguriert werden. Redmine muss anschließend neu gestartet werden.
|
||||
text_scm_command_not_available: Scm Kommando ist nicht verfügbar. Bitte prüfen Sie die Einstellungen im Administrationspanel.
|
||||
|
||||
notice_issue_successful_create: Issue %{id} created.
|
||||
label_between: between
|
||||
setting_issue_group_assignment: Allow issue assignment to groups
|
||||
notice_issue_successful_create: Ticket %{id} erstellt.
|
||||
label_between: zwischen
|
||||
setting_issue_group_assignment: Erlaubt die Ticket-Zuweisung an Gruppen
|
||||
label_diff: diff
|
||||
text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
|
||||
text_git_repository_note: Repository steht für sich alleine (bare) und liegt lokal (z.B. /gitrepo, c:\gitrepo)
|
||||
|
||||
description_filter: Filter
|
||||
description_search: Suchfeld
|
||||
@@ -1045,3 +1045,7 @@ de:
|
||||
permission_manage_related_issues: Zugehörige Tickets verwalten
|
||||
field_ldap_filter: LDAP Filter
|
||||
label_search_for_watchers: Nach hinzufügbaren Beobachtern suchen
|
||||
notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelöscht.
|
||||
setting_unsubscribe: Erlaubt Benutzern das eigene Benutzerkonto zu löschen
|
||||
button_delete_my_account: Mein Benutzerkonto löschen
|
||||
text_account_destroy_confirmation: Möchten Sie wirklich fortfahren?\nIhr Benutzerkonto wird für immer gelöscht und kann nicht wiederhergestellt werden.
|
||||
|
||||
@@ -1025,3 +1025,9 @@ el:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1027,3 +1027,9 @@ en-GB:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -173,6 +173,7 @@ en:
|
||||
notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
|
||||
notice_issue_successful_create: "Issue %{id} created."
|
||||
notice_issue_update_conflict: "The issue has been updated by an other user while you were editing it."
|
||||
notice_account_deleted: "Your account has been permanently deleted."
|
||||
|
||||
error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
|
||||
error_scm_not_found: "The entry or revision was not found in the repository."
|
||||
@@ -383,6 +384,7 @@ en:
|
||||
setting_issue_group_assignment: Allow issue assignment to groups
|
||||
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
|
||||
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
|
||||
permission_add_project: Create project
|
||||
permission_add_subprojects: Create subprojects
|
||||
@@ -894,6 +896,7 @@ en:
|
||||
button_show: Show
|
||||
button_edit_section: Edit this section
|
||||
button_export: Export
|
||||
button_delete_my_account: Delete my account
|
||||
|
||||
status_active: active
|
||||
status_registered: registered
|
||||
@@ -978,6 +981,7 @@ en:
|
||||
text_issue_conflict_resolution_overwrite: "Apply my changes anyway (previous notes will be kept but some changes may be overwritten)"
|
||||
text_issue_conflict_resolution_add_notes: "Add my notes and discard my other changes"
|
||||
text_issue_conflict_resolution_cancel: "Discard all my changes and redisplay %{link}"
|
||||
text_account_destroy_confirmation: "Are you sure you want to proceed?\nYour account will be permanently deleted, with no way to reactivate it."
|
||||
|
||||
default_role_manager: Manager
|
||||
default_role_developer: Developer
|
||||
|
||||
@@ -1062,3 +1062,9 @@ es:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1041,3 +1041,9 @@ et:
|
||||
error_attachment_too_big: "Seda faili ei saa üles laadida, kuna ületab maksimumsuurust (%{max_size})"
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1028,3 +1028,9 @@ eu:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1027,3 +1027,9 @@ fa:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1046,3 +1046,9 @@ fi:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -188,6 +188,7 @@ fr:
|
||||
notice_gantt_chart_truncated: "Le diagramme a été tronqué car il excède le nombre maximal d'éléments pouvant être affichés (%{max})"
|
||||
notice_issue_successful_create: "La demande %{id} a été créée."
|
||||
notice_issue_update_conflict: "La demande a été mise à jour par un autre utilisateur pendant que vous la modifiez."
|
||||
notice_account_deleted: "Votre compte a été définitivement supprimé."
|
||||
|
||||
error_can_t_load_default_data: "Une erreur s'est produite lors du chargement du paramétrage : %{value}"
|
||||
error_scm_not_found: "L'entrée et/ou la révision demandée n'existe pas dans le dépôt."
|
||||
@@ -379,6 +380,7 @@ fr:
|
||||
setting_issue_group_assignment: Permettre l'assignement des demandes aux groupes
|
||||
setting_default_issue_start_date_to_creation_date: Donner à la date de début d'une nouvelle demande la valeur de la date du jour
|
||||
setting_commit_cross_project_ref: Permettre le référencement et la résolution des demandes de tous les autres projets
|
||||
setting_unsubscribe: Permettre aux utilisateurs de se désinscrire
|
||||
|
||||
permission_add_project: Créer un projet
|
||||
permission_add_subprojects: Créer des sous-projets
|
||||
@@ -868,6 +870,7 @@ fr:
|
||||
button_show: Afficher
|
||||
button_edit_section: Modifier cette section
|
||||
button_export: Exporter
|
||||
button_delete_my_account: Supprimer mon compte
|
||||
|
||||
status_active: actif
|
||||
status_registered: enregistré
|
||||
@@ -934,6 +937,7 @@ fr:
|
||||
text_issue_conflict_resolution_overwrite: "Appliquer quand même ma mise à jour (les notes précédentes seront conservées mais des changements pourront être écrasés)"
|
||||
text_issue_conflict_resolution_add_notes: "Ajouter mes notes et ignorer mes autres changements"
|
||||
text_issue_conflict_resolution_cancel: "Annuler ma mise à jour et réafficher %{link}"
|
||||
text_account_destroy_confirmation: "Êtes-vous sûr de vouloir continuer ?\nVotre compte sera définitivement supprimé, sans aucune possibilité de le réactiver."
|
||||
|
||||
default_role_manager: "Manager "
|
||||
default_role_developer: "Développeur "
|
||||
@@ -1039,4 +1043,4 @@ fr:
|
||||
label_child_revision: Enfant
|
||||
error_scm_annotate_big_text_file: Cette entrée ne peut pas être annotée car elle excède la taille maximale.
|
||||
setting_repositories_encodings: Encodages des fichiers et des dépôts
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
label_search_for_watchers: Rechercher des observateurs
|
||||
|
||||
@@ -1036,3 +1036,9 @@ gl:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1030,3 +1030,9 @@ he:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1031,3 +1031,9 @@ hr:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1044,3 +1044,9 @@
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1031,3 +1031,9 @@ id:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1026,3 +1026,9 @@ it:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1055,3 +1055,9 @@ ja:
|
||||
permission_manage_related_issues: 関連するチケットの管理
|
||||
field_ldap_filter: LDAPフィルタ
|
||||
label_search_for_watchers: ウォッチャーを検索して追加
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1075,3 +1075,9 @@ ko:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1085,3 +1085,9 @@ lt:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1019,3 +1019,9 @@ lv:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1025,3 +1025,9 @@ mk:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1025,3 +1025,9 @@ mn:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1007,3 +1007,9 @@ nl:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1015,3 +1015,9 @@
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1042,3 +1042,9 @@ pl:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1048,3 +1048,9 @@ pt-BR:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1030,3 +1030,9 @@ pt:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1022,3 +1022,9 @@ ro:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1140,3 +1140,7 @@ ru:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: "Ваша учетная запись полностью удалена"
|
||||
setting_unsubscribe: "Разрешить пользователям удалять свои учетные записи"
|
||||
button_delete_my_account: "Удалить мою учетную запись"
|
||||
text_account_destroy_confirmation: "Ваша учетная запись будет полностью удалена без возможности восстановления.\nВы уверены, что хотите продолжить?"
|
||||
|
||||
@@ -1025,3 +1025,9 @@ sk:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1025,3 +1025,9 @@ sl:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1025,3 +1025,9 @@ sr-YU:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1026,3 +1026,9 @@ sr:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1066,3 +1066,9 @@ sv:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1022,3 +1022,9 @@ th:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1044,3 +1044,9 @@ tr:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1022,3 +1022,7 @@ uk:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: "Ваш обліковій запис повністю видалений"
|
||||
setting_unsubscribe: "Дозволити користувачам видаляти свої облікові записи"
|
||||
button_delete_my_account: "Видалити мій обліковий запис"
|
||||
text_account_destroy_confirmation: "Ваш обліковий запис буде повністю видалений без можливості відновлення.\nВи певні, что бажаете продовжити?"
|
||||
|
||||
@@ -1076,3 +1076,9 @@ vi:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1105,3 +1105,9 @@
|
||||
description_date_from: 輸入起始日期
|
||||
description_date_to: 輸入結束日期
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -1001,12 +1001,12 @@ zh:
|
||||
label_child_revision: 子修订
|
||||
error_scm_annotate_big_text_file: 输入文本内容超长,无法输入。
|
||||
setting_default_issue_start_date_to_creation_date: 使用当前日期作为新问题的开始日期
|
||||
button_edit_section: Edit this section
|
||||
setting_repositories_encodings: Attachments and repositories encodings
|
||||
description_all_columns: All Columns
|
||||
button_export: Export
|
||||
label_export_options: "%{export_format} export options"
|
||||
error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
|
||||
button_edit_section: 编辑此区域
|
||||
setting_repositories_encodings: 附件和版本库编码
|
||||
description_all_columns: 所有列
|
||||
button_export: 导出
|
||||
label_export_options: "%{export_format} 导出选项"
|
||||
error_attachment_too_big: 该文件无法上传。超过文件大小限制 (%{max_size})
|
||||
notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
|
||||
label_x_issues:
|
||||
zero: 0 问题
|
||||
@@ -1027,3 +1027,9 @@ zh:
|
||||
permission_manage_related_issues: Manage related issues
|
||||
field_ldap_filter: LDAP filter
|
||||
label_search_for_watchers: Search for watchers to add
|
||||
notice_account_deleted: Your account has been permanently deleted.
|
||||
setting_unsubscribe: Allow users to unsubscribe
|
||||
button_delete_my_account: Delete my account
|
||||
text_account_destroy_confirmation: |-
|
||||
Are you sure you want to proceed?
|
||||
Your account will be permanently deleted, with no way to reactivate it.
|
||||
|
||||
@@ -78,6 +78,8 @@ ActionController::Routing::Routes.draw do |map|
|
||||
|
||||
map.connect 'my/account', :controller => 'my', :action => 'account',
|
||||
:conditions => {:method => [:get, :post]}
|
||||
map.connect 'my/account/destroy', :controller => 'my', :action => 'destroy',
|
||||
:conditions => {:method => [:get, :post]}
|
||||
map.connect 'my/page', :controller => 'my', :action => 'page',
|
||||
:conditions => {:method => :get}
|
||||
# Redirects to my/page
|
||||
@@ -339,6 +341,7 @@ ActionController::Routing::Routes.draw do |map|
|
||||
map.resources :roles, :except => :show, :collection => {:permissions => [:get, :post]}
|
||||
map.resources :enumerations, :except => :show
|
||||
|
||||
map.connect 'projects/:id/search', :controller => 'search', :action => 'index', :conditions => {:method => :get}
|
||||
map.connect 'search', :controller => 'search', :action => 'index', :conditions => {:method => :get}
|
||||
|
||||
map.connect 'mail_handler', :controller => 'mail_handler',
|
||||
|
||||
@@ -31,6 +31,8 @@ self_registration:
|
||||
default: '2'
|
||||
lost_password:
|
||||
default: 1
|
||||
unsubscribe:
|
||||
default: 1
|
||||
password_min_length:
|
||||
format: int
|
||||
default: 4
|
||||
|
||||
@@ -4,13 +4,26 @@ Redmine - project management software
|
||||
Copyright (C) 2006-2012 Jean-Philippe Lang
|
||||
http://www.redmine.org/
|
||||
|
||||
== TBD v1.4.0
|
||||
== 2012-04-20 v1.4.1
|
||||
|
||||
* Defect #8574: Time report: date range fields not enabled when using the calendar popup
|
||||
* Defect #10642: Nested textile ol/ul lists generate invalid HTML
|
||||
* Defect #10668: RSS key is generated twice when user is not reloaded
|
||||
* Defect #10669: Token.destroy_expired should not delete API tokens
|
||||
* Defect #10675: "Submit and continue" is broken
|
||||
* Defect #10711: User cannot change account details with "Login has already been taken" error
|
||||
* Feature #10664: Unsubscribe Own User Account
|
||||
* Patch #10693: German Translation Update
|
||||
|
||||
== 2012-04-14 v1.4.0
|
||||
|
||||
* Defect #2719: Increase username length limit from 30 to 60
|
||||
* Defect #3087: Revision referring to issues across all projects
|
||||
* Defect #4824: Unable to connect (can't convert Net::LDAP::LdapError into String)
|
||||
* Defect #5058: reminder mails are not sent when delivery_method is :async_smtp
|
||||
* Defect #6859: Moving issues to a tracker with different custom fields should let fill these fields
|
||||
* Defect #7398: Error when trying to quick create a version with required custom field
|
||||
* Defect #7495: Python multiline comments highlighting problem in Repository browser
|
||||
* Defect #7826: bigdecimal-segfault-fix.rb must be removed for Oracle
|
||||
* Defect #7920: Attempted to update a stale object when copying a project
|
||||
* Defect #8857: Git: Too long in fetching repositories after upgrade from 1.1 or new branch at first time
|
||||
@@ -20,6 +33,7 @@ http://www.redmine.org/
|
||||
* Defect #9978: Japanese "permission_add_issue_watchers" is wrong
|
||||
* Defect #10006: Email reminders are sent for closed issues
|
||||
* Defect #10150: CSV export and spent time: rounding issue
|
||||
* Defect #10168: CSV export breaks custom columns
|
||||
* Defect #10181: Issue context menu and bulk edit form show irrelevant statuses
|
||||
* Defect #10198: message_id regex in pop3.rb only recognizes Message-ID header (not Message-Id)
|
||||
* Defect #10251: Description diff link in note details is relative when received by email
|
||||
@@ -29,14 +43,12 @@ http://www.redmine.org/
|
||||
* Defect #10410: [Localization] Grammar issue of Simplified Chinese in zh.yml
|
||||
* Defect #10442: Ruby 1.9.3 Time Zone setting Internal error.
|
||||
* Defect #10467: Confusing behavior while moving issue to a project with disabled Issues module
|
||||
* Defect #10505: Error when exporting to PDF with NoMethodError (undefined method `downcase' for nil:NilClass)
|
||||
* Defect #10554: Defect symbols when exporting tasks in pdf
|
||||
* Defect #10575: Uploading of attachments which filename contains non-ASCII chars fails with Ruby 1.9
|
||||
* Defect #10590: WikiContent::Version#text return string with #<Encoding:ASCII-8BIT> when uncompressed
|
||||
* Defect #10591: Dutch "label_file_added" translation is wrong
|
||||
* Defect #10593: Error: 'incompatible character encodings: UTF-8 and ASCII-8BIT' (old annoing issue) on ruby-1.9.3
|
||||
* Defect #10600: Watchers search generates an Internal error
|
||||
* Defect #10602: Attachment link has get parameter :class
|
||||
* Defect #10605: Bulk edit selected issues does not allow selection of blank values for custom fields
|
||||
* Defect #10619: When changing status before tracker, it shows improper status
|
||||
* Feature #779: Multiple SCM per project
|
||||
* Feature #971: Add "Spent time" column to query
|
||||
* Feature #1060: Add a LDAP-filter using external auth sources
|
||||
@@ -63,6 +75,7 @@ http://www.redmine.org/
|
||||
* Feature #6296: Bulk-edit custom fields through context menu
|
||||
* Feature #6386: Issue mail should render the HTML version of the issue details
|
||||
* Feature #6449: Edit a wiki page's parent on the edit page
|
||||
* Feature #6555: Double-click on "Submit" and "Save" buttons should not send two requests to server
|
||||
* Feature #7361: Highlight active query in the side bar
|
||||
* Feature #7420: Rest API for projects members
|
||||
* Feature #7603: Please make editing issues more obvious than "Change properties (More)"
|
||||
@@ -74,20 +87,32 @@ http://www.redmine.org/
|
||||
* Feature #9995: Time entries insertion, "Create and continue" button
|
||||
* Feature #10020: Enable global time logging at /time_entries/new
|
||||
* Feature #10042: Bulk change private flag
|
||||
* Feature #10046: Update installation doc on release
|
||||
* Feature #10126: Add members of subprojects in the assignee and author filters
|
||||
* Feature #10131: Include custom fiels in time entries API responses
|
||||
* Feature #10207: Git: use default branch from HEAD
|
||||
* Feature #10208: Estonian translation
|
||||
* Feature #10253: Better handling of attachments when validation fails
|
||||
* Feature #10350: Bulk copy should allow for changing the target version
|
||||
* Feature #10607: Ignore out-of-office incoming emails
|
||||
* Feature #10635: Adding time like "123 Min" is invalid
|
||||
* Patch #9998: Make attachement "Optional Description" less wide
|
||||
* Patch #10066: i18n not working with russian gem
|
||||
* Patch #10128: Disable IE 8 compatibility mode to fix wrong div.autoscroll scroll bar behaviour
|
||||
* Patch #10155: Russian translation changed
|
||||
* Patch #10464: Enhanced PDF output for Issues list
|
||||
* Patch #10470: Efficiently process new git revisions in a single batch
|
||||
* Patch #10513: Dutch translation improvement
|
||||
|
||||
== 2012-04-14 v1.3.3
|
||||
|
||||
* Defect #10505: Error when exporting to PDF with NoMethodError (undefined method `downcase' for nil:NilClass)
|
||||
* Defect #10554: Defect symbols when exporting tasks in pdf
|
||||
* Defect #10564: Unable to change locked, sticky flags and board when editing a message
|
||||
* Defect #10591: Dutch "label_file_added" translation is wrong
|
||||
* Defect #10622: "Default administrator account changed" is always true
|
||||
* Patch #10555: rake redmine:send_reminders aborted if issue assigned to group
|
||||
* Patch #10611: Simplified Chinese translations for 1.3-stable
|
||||
|
||||
== 2012-03-11 v1.3.2
|
||||
|
||||
* Defect #8194: {{toc}} uses identical anchors for subsections with the same name
|
||||
|
||||
@@ -31,6 +31,10 @@ Optional:
|
||||
of the rmagick gem using:
|
||||
bundle install --without development test rmagick
|
||||
|
||||
If you need to load some gems that are not required by Redmine core (eg. fcgi),
|
||||
you can create a file named Gemfile.local at the root of your redmine directory.
|
||||
It will be loaded automatically when running `bundle install`.
|
||||
|
||||
3. Create an empty utf8 encoded database: "redmine" for example
|
||||
|
||||
4. Configure the database parameters in config/database.yml
|
||||
|
||||
@@ -585,7 +585,7 @@ class RedCloth3 < String
|
||||
last_line = line_id
|
||||
end
|
||||
if line_id - last_line > 1 or line_id == lines.length - 1
|
||||
depth.delete_if do |v|
|
||||
while v = depth.pop
|
||||
lines[last_line] << "</li>\n\t</#{ lT( v ) }l>"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ module Redmine #:nodoc:
|
||||
# 2:30 => 2.5
|
||||
s.gsub!(%r{^(\d+):(\d+)$}) { $1.to_i + $2.to_i / 60.0 }
|
||||
# 2h30, 2h, 30m => 2.5, 2, 0.5
|
||||
s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
|
||||
s.gsub!(%r{^((\d+)\s*(h|hours?))?\s*((\d+)\s*(m|min)?)?$}i) { |m| ($1 || $4) ? ($2.to_i + $5.to_i / 60.0) : m[0] }
|
||||
end
|
||||
# 2,5 => 2.5
|
||||
s.gsub!(',', '.')
|
||||
|
||||
@@ -40,7 +40,7 @@ module Redmine
|
||||
# Should not return line numbers nor outer pre tag
|
||||
def highlight_by_filename(text, filename)
|
||||
language = ::CodeRay::FileType[filename]
|
||||
language ? ::CodeRay.scan(text, language).html : ERB::Util.h(text)
|
||||
language ? ::CodeRay.scan(text, language).html(:break_lines => true) : ERB::Util.h(text)
|
||||
end
|
||||
|
||||
# Highlights +text+ using +language+ syntax
|
||||
|
||||
@@ -4,13 +4,13 @@ module Redmine
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 1
|
||||
MINOR = 4
|
||||
TINY = 0
|
||||
TINY = 1
|
||||
|
||||
# Branch values:
|
||||
# * official release: nil
|
||||
# * stable branch: stable
|
||||
# * trunk: devel
|
||||
BRANCH = 'devel'
|
||||
BRANCH = 'stable'
|
||||
|
||||
def self.revision
|
||||
revision = nil
|
||||
|
||||
@@ -23,7 +23,7 @@ module Redmine
|
||||
end
|
||||
|
||||
def link_to(name, options={})
|
||||
url = { :format => name.to_s.downcase }.merge(options.delete(:url) || {})
|
||||
url = { :format => name.to_s.downcase }.merge(options.delete(:url) || {}).except('page')
|
||||
caption = options.delete(:caption) || name
|
||||
html_options = { :class => name.to_s.downcase, :rel => 'nofollow' }.merge(options)
|
||||
@view.content_tag('span', @view.link_to(caption, url, html_options))
|
||||
|
||||
@@ -48,8 +48,8 @@ namespace :ci do
|
||||
test_conf = { 'adapter' => (RUBY_VERSION >= '1.9' ? 'mysql2' : 'mysql'), 'database' => test_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins', 'encoding' => 'utf8' }
|
||||
when 'postgresql'
|
||||
raise "Error creating databases" unless
|
||||
system(%|psql -U jenkins -d postgres -c "create database #{dev_db_name} owner jenkins encoding 'UTF8';|) &&
|
||||
system(%|psql -U jenkins -d postgres -c "create database #{test_db_name} owner jenkins encoding 'UTF8';|)
|
||||
system(%|psql -U jenkins -d postgres -c "create database #{dev_db_name} owner jenkins encoding 'UTF8';"|) &&
|
||||
system(%|psql -U jenkins -d postgres -c "create database #{test_db_name} owner jenkins encoding 'UTF8';"|)
|
||||
dev_conf = { 'adapter' => 'postgresql', 'database' => dev_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins' }
|
||||
test_conf = { 'adapter' => 'postgresql', 'database' => test_db_name, 'host' => 'localhost', 'username' => 'jenkins', 'password' => 'jenkins' }
|
||||
when 'sqlite3'
|
||||
|
||||
@@ -35,7 +35,9 @@ namespace :redmine do
|
||||
options[:project] = ENV['project'] if ENV['project']
|
||||
options[:tracker] = ENV['tracker'].to_i if ENV['tracker']
|
||||
options[:users] = (ENV['users'] || '').split(',').each(&:strip!)
|
||||
|
||||
Mailer.reminders(options)
|
||||
|
||||
Mailer.with_synched_deliveries do
|
||||
Mailer.reminders(options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -520,4 +520,19 @@ function hideOnLoad() {
|
||||
});
|
||||
}
|
||||
|
||||
function addFormObserversForDoubleSubmit() {
|
||||
$$('form[method=post]').each(function(form) {
|
||||
if (!form.hasClassName('multiple-submit')) {
|
||||
form.on('submit', function(form_submission) {
|
||||
if (form.getStorage().get('submitted')) {
|
||||
form_submission.stop();
|
||||
} else {
|
||||
form.getStorage().set('submitted', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Event.observe(window, 'load', hideOnLoad);
|
||||
Event.observe(window, 'load', addFormObserversForDoubleSubmit);
|
||||
|
||||
@@ -348,7 +348,7 @@ div#issue-changesets div.changeset { padding: 4px;}
|
||||
div#issue-changesets div.changeset { border-bottom: 1px solid #ddd; }
|
||||
div#issue-changesets p { margin-top: 0; margin-bottom: 1em;}
|
||||
|
||||
.journal ul.details img {margin:0 0 -3px 4px; vertical-middle:base;}
|
||||
.journal ul.details img {margin:0 0 -3px 4px;}
|
||||
|
||||
div#activity dl, #search-results { margin-left: 2em; }
|
||||
div#activity dd, #search-results dd { margin-bottom: 1em; padding-left: 18px; font-size: 0.9em; }
|
||||
|
||||
@@ -110,92 +110,89 @@ div.action_A { background: #bfb }
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
.syntaxhl .code pre { overflow: auto }
|
||||
.syntaxhl .debug { color:white ! important; background:blue ! important; }
|
||||
.syntaxhl .debug { color: white !important; background: blue !important; }
|
||||
|
||||
.syntaxhl .attribute-name { color:#b48 }
|
||||
.syntaxhl .annotation { color:#007 }
|
||||
.syntaxhl .attribute-name { color:#b48 }
|
||||
.syntaxhl .attribute-value { color:#700 }
|
||||
.syntaxhl .binary { color:#509 }
|
||||
|
||||
.syntaxhl .char .content { color:#D20 }
|
||||
.syntaxhl .char .delimiter { color:#710 }
|
||||
.syntaxhl .char { color:#D20 }
|
||||
.syntaxhl .class { color:#B06; font-weight:bold }
|
||||
.syntaxhl .class-variable { color:#369 }
|
||||
.syntaxhl .color { color:#0A0 }
|
||||
.syntaxhl .comment { color:#777 }
|
||||
.syntaxhl .comment .char { color:#444 }
|
||||
.syntaxhl .comment .delimiter { color:#444 }
|
||||
|
||||
.syntaxhl .char { color:#D20 }
|
||||
.syntaxhl .char .content { color:#D20 }
|
||||
.syntaxhl .char .delimiter { color:#710 }
|
||||
|
||||
.syntaxhl .class { color:#B06; font-weight:bold }
|
||||
.syntaxhl .complex { color:#A08 }
|
||||
.syntaxhl .constant { color:#036; font-weight:bold }
|
||||
.syntaxhl .color { color:#0A0 }
|
||||
.syntaxhl .class-variable { color:#369 }
|
||||
.syntaxhl .decorator { color:#B0B }
|
||||
.syntaxhl .definition { color:#099; font-weight:bold }
|
||||
.syntaxhl .directive { color:#088; font-weight:bold }
|
||||
.syntaxhl .delimiter { color:black }
|
||||
.syntaxhl .directive { color:#088; font-weight:bold }
|
||||
.syntaxhl .doc { color:#970 }
|
||||
.syntaxhl .doctype { color:#34b }
|
||||
.syntaxhl .doc-string { color:#D42; font-weight:bold }
|
||||
.syntaxhl .escape { color:#666 }
|
||||
.syntaxhl .doctype { color:#34b }
|
||||
.syntaxhl .entity { color:#800; font-weight:bold }
|
||||
.syntaxhl .error { color:#F00; background-color:#FAA }
|
||||
.syntaxhl .escape { color:#666 }
|
||||
.syntaxhl .exception { color:#C00; font-weight:bold }
|
||||
.syntaxhl .float { color:#60E }
|
||||
.syntaxhl .function { color:#06B; font-weight:bold }
|
||||
.syntaxhl .global-variable { color:#d70 }
|
||||
.syntaxhl .hex { color:#02b }
|
||||
.syntaxhl .integer { color:#00D }
|
||||
.syntaxhl .include { color:#B44; font-weight:bold }
|
||||
.syntaxhl .imaginary { color:#f00 }
|
||||
|
||||
.syntaxhl .include { color:#B44; font-weight:bold }
|
||||
.syntaxhl .inline { background-color: hsla(0,0%,0%,0.07); color: black }
|
||||
.syntaxhl .inline-delimiter { font-weight: bold; color: #666 }
|
||||
|
||||
.syntaxhl .instance-variable { color:#33B }
|
||||
.syntaxhl .integer { color:#00D }
|
||||
.syntaxhl .key .char { color: #60f }
|
||||
.syntaxhl .key .delimiter { color: #404 }
|
||||
.syntaxhl .key { color: #606 }
|
||||
.syntaxhl .keyword { color:#080; font-weight:bold }
|
||||
.syntaxhl .label { color:#970; font-weight:bold }
|
||||
.syntaxhl .local-variable { color:#963 }
|
||||
.syntaxhl .namespace { color:#707; font-weight:bold }
|
||||
.syntaxhl .octal { color:#40E }
|
||||
.syntaxhl .operator { }
|
||||
.syntaxhl .predefined-constant { color:#069 }
|
||||
.syntaxhl .predefined { color:#369; font-weight:bold }
|
||||
.syntaxhl .predefined-constant { color:#069 }
|
||||
.syntaxhl .predefined-type { color:#0a5; font-weight:bold }
|
||||
.syntaxhl .preprocessor { color:#579 }
|
||||
.syntaxhl .pseudo-class { color:#00C; font-weight:bold }
|
||||
.syntaxhl .reserved { color:#080; font-weight:bold }
|
||||
|
||||
.syntaxhl .key .char { color: #60f }
|
||||
.syntaxhl .key .delimiter { color: #404 }
|
||||
.syntaxhl .key { color: #606 }
|
||||
.syntaxhl .keyword { color:#080; font-weight:bold }
|
||||
|
||||
.syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
|
||||
.syntaxhl .regexp .content { color:#808 }
|
||||
.syntaxhl .regexp .delimiter { color:#404 }
|
||||
.syntaxhl .regexp .modifier { color:#C2C }
|
||||
|
||||
.syntaxhl .string { background-color:hsla(0,100%,50%,0.05); }
|
||||
.syntaxhl .string .content { color: #D20 }
|
||||
.syntaxhl .string .char { color: #b0b }
|
||||
.syntaxhl .string .delimiter { color: #710 }
|
||||
.syntaxhl .string .modifier { color: #E40 }
|
||||
|
||||
.syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
|
||||
.syntaxhl .regexp { background-color:hsla(300,100%,50%,0.06); }
|
||||
.syntaxhl .reserved { color:#080; font-weight:bold }
|
||||
.syntaxhl .shell .content { color:#2B2 }
|
||||
.syntaxhl .shell .delimiter { color:#161 }
|
||||
|
||||
.syntaxhl .symbol { color:#A60 }
|
||||
.syntaxhl .shell { background-color:hsla(120,100%,50%,0.06); }
|
||||
.syntaxhl .string .char { color: #b0b }
|
||||
.syntaxhl .string .content { color: #D20 }
|
||||
.syntaxhl .string .delimiter { color: #710 }
|
||||
.syntaxhl .string .modifier { color: #E40 }
|
||||
.syntaxhl .string { background-color:hsla(0,100%,50%,0.05); }
|
||||
.syntaxhl .symbol .content { color:#A60 }
|
||||
.syntaxhl .symbol .delimiter { color:#630 }
|
||||
|
||||
.syntaxhl .symbol { color:#A60 }
|
||||
.syntaxhl .tag { color:#070 }
|
||||
.syntaxhl .type { color:#339; font-weight:bold }
|
||||
.syntaxhl .value { color: #088; }
|
||||
.syntaxhl .variable { color:#037 }
|
||||
|
||||
|
||||
.syntaxhl .insert { background: hsla(120,100%,50%,0.12) }
|
||||
.syntaxhl .delete { background: hsla(0,100%,50%,0.12) }
|
||||
.syntaxhl .change { color: #bbf; background: #007; }
|
||||
.syntaxhl .head { color: #f8f; background: #505 }
|
||||
.syntaxhl .head .filename { color: white; }
|
||||
|
||||
.syntaxhl .delete .eyecatcher { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
|
||||
.syntaxhl .insert .eyecatcher { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
|
||||
|
||||
.syntaxhl .insert .insert { color: #0c0; background:transparent; font-weight:bold }
|
||||
.syntaxhl .delete .delete { color: #c00; background:transparent; font-weight:bold }
|
||||
.syntaxhl .change .change { color: #88f }
|
||||
.syntaxhl .head .head { color: #f4f }
|
||||
|
||||
@@ -48,6 +48,10 @@ class IssueRelationsControllerTest < ActionController::TestCase
|
||||
post :create, :issue_id => 1,
|
||||
:relation => {:issue_to_id => '2', :relation_type => 'relates', :delay => ''}
|
||||
end
|
||||
relation = IssueRelation.first(:order => 'id DESC')
|
||||
assert_equal 1, relation.issue_from_id
|
||||
assert_equal 2, relation.issue_to_id
|
||||
assert_equal 'relates', relation.relation_type
|
||||
end
|
||||
|
||||
def test_create_xhr
|
||||
@@ -61,6 +65,9 @@ class IssueRelationsControllerTest < ActionController::TestCase
|
||||
assert_select 'tr', 2 # relations
|
||||
end
|
||||
end
|
||||
relation = IssueRelation.first(:order => 'id DESC')
|
||||
assert_equal 3, relation.issue_from_id
|
||||
assert_equal 1, relation.issue_to_id
|
||||
end
|
||||
|
||||
def test_create_should_accept_id_with_hash
|
||||
@@ -69,6 +76,18 @@ class IssueRelationsControllerTest < ActionController::TestCase
|
||||
post :create, :issue_id => 1,
|
||||
:relation => {:issue_to_id => '#2', :relation_type => 'relates', :delay => ''}
|
||||
end
|
||||
relation = IssueRelation.first(:order => 'id DESC')
|
||||
assert_equal 2, relation.issue_to_id
|
||||
end
|
||||
|
||||
def test_create_should_strip_id
|
||||
assert_difference 'IssueRelation.count' do
|
||||
@request.session[:user_id] = 3
|
||||
post :create, :issue_id => 1,
|
||||
:relation => {:issue_to_id => ' 2 ', :relation_type => 'relates', :delay => ''}
|
||||
end
|
||||
relation = IssueRelation.first(:order => 'id DESC')
|
||||
assert_equal 2, relation.issue_to_id
|
||||
end
|
||||
|
||||
def test_create_should_not_break_with_non_numerical_id
|
||||
|
||||
@@ -305,6 +305,15 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_index_should_omit_page_param_in_export_links
|
||||
get :index, :page => 2
|
||||
assert_response :success
|
||||
assert_select 'a.atom[href=/issues.atom]'
|
||||
assert_select 'a.csv[href=/issues.csv]'
|
||||
assert_select 'a.pdf[href=/issues.pdf]'
|
||||
assert_select 'form#csv-export-form[action=/issues.csv]'
|
||||
end
|
||||
|
||||
def test_index_csv
|
||||
get :index, :format => 'csv'
|
||||
assert_response :success
|
||||
@@ -1363,6 +1372,22 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_equal 'This is the test_new issue', issue.subject
|
||||
end
|
||||
|
||||
def test_update_new_form_should_propose_transitions_based_on_initial_status
|
||||
@request.session[:user_id] = 2
|
||||
Workflow.delete_all
|
||||
Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 2)
|
||||
Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 1, :new_status_id => 5)
|
||||
Workflow.create!(:role_id => 1, :tracker_id => 1, :old_status_id => 5, :new_status_id => 4)
|
||||
|
||||
xhr :post, :new, :project_id => 1,
|
||||
:issue => {:tracker_id => 1,
|
||||
:status_id => 5,
|
||||
:subject => 'This is an issue'}
|
||||
|
||||
assert_equal 5, assigns(:issue).status_id
|
||||
assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
|
||||
end
|
||||
|
||||
def test_post_create
|
||||
@request.session[:user_id] = 2
|
||||
assert_difference 'Issue.count' do
|
||||
@@ -2171,6 +2196,23 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_equal 'This is the test_new issue', issue.subject
|
||||
end
|
||||
|
||||
def test_update_edit_form_should_propose_transitions_based_on_initial_status
|
||||
@request.session[:user_id] = 2
|
||||
Workflow.delete_all
|
||||
Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 1)
|
||||
Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 2, :new_status_id => 5)
|
||||
Workflow.create!(:role_id => 1, :tracker_id => 2, :old_status_id => 5, :new_status_id => 4)
|
||||
|
||||
xhr :put, :new, :project_id => 1,
|
||||
:id => 2,
|
||||
:issue => {:tracker_id => 2,
|
||||
:status_id => 5,
|
||||
:subject => 'This is an issue'}
|
||||
|
||||
assert_equal 5, assigns(:issue).status_id
|
||||
assert_equal [1,2,5], assigns(:allowed_statuses).map(&:id).sort
|
||||
end
|
||||
|
||||
def test_update_edit_form_with_project_change
|
||||
@request.session[:user_id] = 2
|
||||
xhr :put, :new, :project_id => 1,
|
||||
@@ -2665,7 +2707,7 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
:attributes => {:name => "issue[custom_field_values][#{field.id}]"},
|
||||
:children => {
|
||||
:only => {:tag => 'option'},
|
||||
:count => Project.find(1).users.count + 1
|
||||
:count => Project.find(1).users.count + 2 # "no change" + "none" options
|
||||
}
|
||||
end
|
||||
|
||||
@@ -2681,7 +2723,7 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
:attributes => {:name => "issue[custom_field_values][#{field.id}]"},
|
||||
:children => {
|
||||
:only => {:tag => 'option'},
|
||||
:count => Project.find(1).shared_versions.count + 1
|
||||
:count => Project.find(1).shared_versions.count + 2 # "no change" + "none" options
|
||||
}
|
||||
end
|
||||
|
||||
@@ -2698,7 +2740,7 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
:attributes => {:name => "issue[custom_field_values][1][]"},
|
||||
:children => {
|
||||
:only => {:tag => 'option'},
|
||||
:count => 3
|
||||
:count => field.possible_values.size + 1 # "none" options
|
||||
}
|
||||
end
|
||||
|
||||
@@ -2924,6 +2966,17 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_equal '777', journal.details.first.value
|
||||
end
|
||||
|
||||
def test_bulk_update_custom_field_to_blank
|
||||
@request.session[:user_id] = 2
|
||||
post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing custom field',
|
||||
:issue => {:priority_id => '',
|
||||
:assigned_to_id => '',
|
||||
:custom_field_values => {'1' => '__none__'}}
|
||||
assert_response 302
|
||||
assert_equal '', Issue.find(1).custom_field_value(1)
|
||||
assert_equal '', Issue.find(3).custom_field_value(1)
|
||||
end
|
||||
|
||||
def test_bulk_update_multi_custom_field
|
||||
field = CustomField.find(1)
|
||||
field.update_attribute :multiple, true
|
||||
@@ -2942,6 +2995,20 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_nil Issue.find(2).custom_field_value(1)
|
||||
end
|
||||
|
||||
def test_bulk_update_multi_custom_field_to_blank
|
||||
field = CustomField.find(1)
|
||||
field.update_attribute :multiple, true
|
||||
|
||||
@request.session[:user_id] = 2
|
||||
post :bulk_update, :ids => [1, 3], :notes => 'Bulk editing multi custom field',
|
||||
:issue => {:priority_id => '',
|
||||
:assigned_to_id => '',
|
||||
:custom_field_values => {'1' => ['__none__']}}
|
||||
assert_response 302
|
||||
assert_equal [''], Issue.find(1).custom_field_value(1)
|
||||
assert_equal [''], Issue.find(3).custom_field_value(1)
|
||||
end
|
||||
|
||||
def test_bulk_update_unassign
|
||||
assert_not_nil Issue.find(2).assigned_to
|
||||
@request.session[:user_id] = 2
|
||||
@@ -2990,6 +3057,19 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_equal 'Failed to save 1 issue(s) on 2 selected: #2.', flash[:error]
|
||||
end
|
||||
|
||||
def test_get_bulk_copy
|
||||
@request.session[:user_id] = 2
|
||||
get :bulk_edit, :ids => [1, 2, 3], :copy => '1'
|
||||
assert_response :success
|
||||
assert_template 'bulk_edit'
|
||||
|
||||
issues = assigns(:issues)
|
||||
assert_not_nil issues
|
||||
assert_equal [1, 2, 3], issues.map(&:id).sort
|
||||
|
||||
assert_select 'input[name=copy_attachments]'
|
||||
end
|
||||
|
||||
def test_bulk_copy_to_another_project
|
||||
@request.session[:user_id] = 2
|
||||
assert_difference 'Issue.count', 2 do
|
||||
@@ -2998,27 +3078,41 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
end
|
||||
end
|
||||
assert_redirected_to '/projects/ecookbook/issues'
|
||||
|
||||
copies = Issue.all(:order => 'id DESC', :limit => issues.size)
|
||||
copies.each do |copy|
|
||||
assert_equal 2, copy.project_id
|
||||
end
|
||||
end
|
||||
|
||||
def test_bulk_copy_should_allow_not_changing_the_issue_attributes
|
||||
@request.session[:user_id] = 2
|
||||
issue_before_move = Issue.find(1)
|
||||
assert_difference 'Issue.count', 1 do
|
||||
assert_no_difference 'Project.find(1).issues.count' do
|
||||
post :bulk_update, :ids => [1], :copy => '1',
|
||||
:issue => {
|
||||
:project_id => '2', :tracker_id => '', :assigned_to_id => '',
|
||||
:status_id => '', :start_date => '', :due_date => ''
|
||||
}
|
||||
end
|
||||
issues = [
|
||||
Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, :priority_id => 2, :subject => 'issue 1', :author_id => 1, :assigned_to_id => nil),
|
||||
Issue.create!(:project_id => 2, :tracker_id => 3, :status_id => 2, :priority_id => 1, :subject => 'issue 2', :author_id => 2, :assigned_to_id => 3)
|
||||
]
|
||||
|
||||
assert_difference 'Issue.count', issues.size do
|
||||
post :bulk_update, :ids => issues.map(&:id), :copy => '1',
|
||||
:issue => {
|
||||
:project_id => '', :tracker_id => '', :assigned_to_id => '',
|
||||
:status_id => '', :start_date => '', :due_date => ''
|
||||
}
|
||||
end
|
||||
|
||||
copies = Issue.all(:order => 'id DESC', :limit => issues.size)
|
||||
issues.each do |orig|
|
||||
copy = copies.detect {|c| c.subject == orig.subject}
|
||||
assert_not_nil copy
|
||||
assert_equal orig.project_id, copy.project_id
|
||||
assert_equal orig.tracker_id, copy.tracker_id
|
||||
assert_equal orig.status_id, copy.status_id
|
||||
assert_equal orig.assigned_to_id, copy.assigned_to_id
|
||||
assert_equal orig.priority_id, copy.priority_id
|
||||
end
|
||||
issue_after_move = Issue.first(:order => 'id desc', :conditions => {:project_id => 2})
|
||||
assert_equal issue_before_move.tracker_id, issue_after_move.tracker_id
|
||||
assert_equal issue_before_move.status_id, issue_after_move.status_id
|
||||
assert_equal issue_before_move.assigned_to_id, issue_after_move.assigned_to_id
|
||||
end
|
||||
|
||||
def test_bulk_copy_should_allow_changing_the_issue_attributes
|
||||
def test_bulk_copy_should_allow_changing_the_issue_attributes
|
||||
# Fixes random test failure with Mysql
|
||||
# where Issue.all(:limit => 2, :order => 'id desc', :conditions => {:project_id => 2})
|
||||
# doesn't return the expected results
|
||||
@@ -3030,7 +3124,7 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
post :bulk_update, :ids => [1, 2], :copy => '1',
|
||||
:issue => {
|
||||
:project_id => '2', :tracker_id => '', :assigned_to_id => '4',
|
||||
:status_id => '3', :start_date => '2009-12-01', :due_date => '2009-12-31'
|
||||
:status_id => '1', :start_date => '2009-12-01', :due_date => '2009-12-31'
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -3040,7 +3134,7 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
copied_issues.each do |issue|
|
||||
assert_equal 2, issue.project_id, "Project is incorrect"
|
||||
assert_equal 4, issue.assigned_to_id, "Assigned to is incorrect"
|
||||
assert_equal 3, issue.status_id, "Status is incorrect"
|
||||
assert_equal 1, issue.status_id, "Status is incorrect"
|
||||
assert_equal '2009-12-01', issue.start_date.to_s, "Start date is incorrect"
|
||||
assert_equal '2009-12-31', issue.due_date.to_s, "Due date is incorrect"
|
||||
end
|
||||
@@ -3064,6 +3158,36 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
assert_equal 'Copying one issue', journal.notes
|
||||
end
|
||||
|
||||
def test_bulk_copy_should_allow_not_copying_the_attachments
|
||||
attachment_count = Issue.find(3).attachments.size
|
||||
assert attachment_count > 0
|
||||
@request.session[:user_id] = 2
|
||||
|
||||
assert_difference 'Issue.count', 1 do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
post :bulk_update, :ids => [3], :copy => '1',
|
||||
:issue => {
|
||||
:project_id => ''
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_bulk_copy_should_allow_copying_the_attachments
|
||||
attachment_count = Issue.find(3).attachments.size
|
||||
assert attachment_count > 0
|
||||
@request.session[:user_id] = 2
|
||||
|
||||
assert_difference 'Issue.count', 1 do
|
||||
assert_difference 'Attachment.count', attachment_count do
|
||||
post :bulk_update, :ids => [3], :copy => '1', :copy_attachments => '1',
|
||||
:issue => {
|
||||
:project_id => ''
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_bulk_copy_to_another_project_should_follow_when_needed
|
||||
@request.session[:user_id] = 2
|
||||
post :bulk_update, :ids => [1], :copy => '1', :issue => {:project_id => 2}, :follow => '1'
|
||||
|
||||
@@ -131,6 +131,30 @@ class MessagesControllerTest < ActionController::TestCase
|
||||
assert_equal 'New body', message.content
|
||||
end
|
||||
|
||||
def test_post_edit_sticky_and_locked
|
||||
@request.session[:user_id] = 2
|
||||
post :edit, :board_id => 1, :id => 1,
|
||||
:message => { :subject => 'New subject',
|
||||
:content => 'New body',
|
||||
:locked => '1',
|
||||
:sticky => '1'}
|
||||
assert_redirected_to '/boards/1/topics/1'
|
||||
message = Message.find(1)
|
||||
assert_equal true, message.sticky?
|
||||
assert_equal true, message.locked?
|
||||
end
|
||||
|
||||
def test_post_edit_should_allow_to_change_board
|
||||
@request.session[:user_id] = 2
|
||||
post :edit, :board_id => 1, :id => 1,
|
||||
:message => { :subject => 'New subject',
|
||||
:content => 'New body',
|
||||
:board_id => 2}
|
||||
assert_redirected_to '/boards/2/topics/1'
|
||||
message = Message.find(1)
|
||||
assert_equal Board.find(2), message.board
|
||||
end
|
||||
|
||||
def test_reply
|
||||
@request.session[:user_id] = 2
|
||||
post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' }
|
||||
|
||||
@@ -84,6 +84,45 @@ class MyControllerTest < ActionController::TestCase
|
||||
assert user.groups.empty?
|
||||
end
|
||||
|
||||
def test_my_account_should_show_destroy_link
|
||||
get :account
|
||||
assert_select 'a[href=/my/account/destroy]'
|
||||
end
|
||||
|
||||
def test_get_destroy_should_display_the_destroy_confirmation
|
||||
get :destroy
|
||||
assert_response :success
|
||||
assert_template 'destroy'
|
||||
assert_select 'form[action=/my/account/destroy]' do
|
||||
assert_select 'input[name=confirm]'
|
||||
end
|
||||
end
|
||||
|
||||
def test_post_destroy_without_confirmation_should_not_destroy_account
|
||||
assert_no_difference 'User.count' do
|
||||
post :destroy
|
||||
end
|
||||
assert_response :success
|
||||
assert_template 'destroy'
|
||||
end
|
||||
|
||||
def test_post_destroy_without_confirmation_should_destroy_account
|
||||
assert_difference 'User.count', -1 do
|
||||
post :destroy, :confirm => '1'
|
||||
end
|
||||
assert_redirected_to '/'
|
||||
assert_match /deleted/i, flash[:notice]
|
||||
end
|
||||
|
||||
def test_post_destroy_with_unsubscribe_not_allowed_should_not_destroy_account
|
||||
User.any_instance.stubs(:own_account_deletable?).returns(false)
|
||||
|
||||
assert_no_difference 'User.count' do
|
||||
post :destroy, :confirm => '1'
|
||||
end
|
||||
assert_redirected_to '/my/account'
|
||||
end
|
||||
|
||||
def test_change_password
|
||||
get :password
|
||||
assert_response :success
|
||||
|
||||
@@ -53,4 +53,14 @@ class LayoutTest < ActionController::IntegrationTest
|
||||
:attributes => {:src => %r{^/javascripts/jstoolbar/textile.js}},
|
||||
:parent => {:tag => 'head'}
|
||||
end
|
||||
|
||||
def test_search_field_outside_project_should_link_to_global_search
|
||||
get '/'
|
||||
assert_select 'div#quick-search form[action=/search]'
|
||||
end
|
||||
|
||||
def test_search_field_inside_project_should_link_to_project_search
|
||||
get '/projects/ecookbook'
|
||||
assert_select 'div#quick-search form[action=/projects/ecookbook/search]'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -25,6 +25,12 @@ class RoutingMyTest < ActionController::IntegrationTest
|
||||
{ :controller => 'my', :action => 'account' }
|
||||
)
|
||||
end
|
||||
["get", "post"].each do |method|
|
||||
assert_routing(
|
||||
{ :method => method, :path => "/my/account/destroy" },
|
||||
{ :controller => 'my', :action => 'destroy' }
|
||||
)
|
||||
end
|
||||
assert_routing(
|
||||
{ :method => 'get', :path => "/my/page" },
|
||||
{ :controller => 'my', :action => 'page' }
|
||||
|
||||
@@ -23,5 +23,9 @@ class RoutingSearchTest < ActionController::IntegrationTest
|
||||
{ :method => 'get', :path => "/search" },
|
||||
{ :controller => 'search', :action => 'index' }
|
||||
)
|
||||
assert_routing(
|
||||
{ :method => 'get', :path => "/projects/foo/search" },
|
||||
{ :controller => 'search', :action => 'index', :id => 'foo' }
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -395,6 +395,14 @@ class IssueTest < ActiveSupport::TestCase
|
||||
assert_equal expected_statuses, issue.new_statuses_allowed_to(admin)
|
||||
end
|
||||
|
||||
def test_new_statuses_allowed_to_should_return_default_and_current_status_when_copying
|
||||
issue = Issue.find(1).copy
|
||||
assert_equal [1], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
|
||||
|
||||
issue = Issue.find(2).copy
|
||||
assert_equal [1, 2], issue.new_statuses_allowed_to(User.find(2)).map(&:id)
|
||||
end
|
||||
|
||||
def test_copy
|
||||
issue = Issue.new.copy_from(1)
|
||||
assert issue.copy?
|
||||
|
||||
@@ -110,6 +110,36 @@ class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase
|
||||
)
|
||||
end
|
||||
|
||||
def test_nested_lists
|
||||
raw = <<-RAW
|
||||
# Item 1
|
||||
# Item 2
|
||||
** Item 2a
|
||||
** Item 2b
|
||||
# Item 3
|
||||
** Item 3a
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<ol>
|
||||
<li>Item 1</li>
|
||||
<li>Item 2
|
||||
<ul>
|
||||
<li>Item 2a</li>
|
||||
<li>Item 2b</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Item 3
|
||||
<ul>
|
||||
<li>Item 3a</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_escaping
|
||||
assert_html_output(
|
||||
'this is a <script>' => 'this is a <script>'
|
||||
|
||||
@@ -359,6 +359,21 @@ class MailHandlerTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_ignore_auto_replied_emails
|
||||
[
|
||||
"X-Auto-Response-Suppress: OOF",
|
||||
"Auto-Submitted: auto-replied",
|
||||
"Auto-Submitted: Auto-Replied"
|
||||
].each do |header|
|
||||
raw = IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
|
||||
raw = header + "\n" + raw
|
||||
|
||||
assert_no_difference 'Issue.count' do
|
||||
assert_equal false, MailHandler.receive(raw), "email with #{header} header was not ignored"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_add_issue_should_send_email_notification
|
||||
Setting.notified_events = ['issue_added']
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
@@ -45,6 +45,7 @@ class TimeEntryTest < ActiveSupport::TestCase
|
||||
"3 h 15 m" => 3.25,
|
||||
"3 hours" => 3.0,
|
||||
"12min" => 0.2,
|
||||
"12 Min" => 0.2,
|
||||
}
|
||||
|
||||
assertions.each do |k, v|
|
||||
|
||||
@@ -35,4 +35,27 @@ class TokenTest < ActiveSupport::TestCase
|
||||
assert !Token.exists?(t1.id)
|
||||
assert Token.exists?(t2.id)
|
||||
end
|
||||
|
||||
def test_destroy_expired_should_not_destroy_feeds_and_api_tokens
|
||||
Token.delete_all
|
||||
|
||||
Token.create!(:user_id => 1, :action => 'api', :created_on => 7.days.ago)
|
||||
Token.create!(:user_id => 1, :action => 'feeds', :created_on => 7.days.ago)
|
||||
|
||||
assert_no_difference 'Token.count' do
|
||||
assert_equal 0, Token.destroy_expired
|
||||
end
|
||||
end
|
||||
|
||||
def test_destroy_expired_should_destroy_expired_tokens
|
||||
Token.delete_all
|
||||
|
||||
Token.create!(:user_id => 1, :action => 'autologin', :created_on => 7.days.ago)
|
||||
Token.create!(:user_id => 2, :action => 'autologin', :created_on => 3.days.ago)
|
||||
Token.create!(:user_id => 3, :action => 'autologin', :created_on => 1.hour.ago)
|
||||
|
||||
assert_difference 'Token.count', -2 do
|
||||
assert_equal 2, Token.destroy_expired
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -134,6 +134,20 @@ class UserTest < ActiveSupport::TestCase
|
||||
assert_equal "john", @admin.login
|
||||
end
|
||||
|
||||
def test_update_should_not_fail_for_legacy_user_with_different_case_logins
|
||||
u1 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser1@somenet.foo")
|
||||
u1.login = 'newuser1'
|
||||
assert u1.save
|
||||
|
||||
u2 = User.new(:firstname => "new", :lastname => "user", :mail => "newuser2@somenet.foo")
|
||||
u2.login = 'newuser1'
|
||||
assert u2.save(false)
|
||||
|
||||
user = User.find(u2.id)
|
||||
user.firstname = "firstname"
|
||||
assert user.save, "Save failed"
|
||||
end
|
||||
|
||||
def test_destroy_should_delete_members_and_roles
|
||||
members = Member.find_all_by_user_id(2)
|
||||
ms = members.size
|
||||
@@ -585,6 +599,22 @@ class UserTest < ActiveSupport::TestCase
|
||||
assert_equal key, @jsmith.rss_key
|
||||
end
|
||||
|
||||
def test_rss_key_should_not_be_generated_twice
|
||||
assert_difference 'Token.count', 1 do
|
||||
key1 = @jsmith.rss_key
|
||||
key2 = @jsmith.rss_key
|
||||
assert_equal key1, key2
|
||||
end
|
||||
end
|
||||
|
||||
def test_api_key_should_not_be_generated_twice
|
||||
assert_difference 'Token.count', 1 do
|
||||
key1 = @jsmith.api_key
|
||||
key2 = @jsmith.api_key
|
||||
assert_equal key1, key2
|
||||
end
|
||||
end
|
||||
|
||||
context "User#api_key" do
|
||||
should "generate a new one if the user doesn't have one" do
|
||||
user = User.generate_with_protected!(:api_token => nil)
|
||||
@@ -630,6 +660,38 @@ class UserTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
|
||||
user = User.find_by_login("admin")
|
||||
user.password = "admin"
|
||||
user.save!
|
||||
|
||||
assert_equal false, User.default_admin_account_changed?
|
||||
end
|
||||
|
||||
def test_default_admin_account_changed_should_return_true_if_password_was_changed
|
||||
user = User.find_by_login("admin")
|
||||
user.password = "newpassword"
|
||||
user.save!
|
||||
|
||||
assert_equal true, User.default_admin_account_changed?
|
||||
end
|
||||
|
||||
def test_default_admin_account_changed_should_return_true_if_account_is_disabled
|
||||
user = User.find_by_login("admin")
|
||||
user.password = "admin"
|
||||
user.status = User::STATUS_LOCKED
|
||||
user.save!
|
||||
|
||||
assert_equal true, User.default_admin_account_changed?
|
||||
end
|
||||
|
||||
def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
|
||||
user = User.find_by_login("admin")
|
||||
user.destroy
|
||||
|
||||
assert_equal true, User.default_admin_account_changed?
|
||||
end
|
||||
|
||||
def test_roles_for_project
|
||||
# user with a role
|
||||
roles = @jsmith.roles_for_project(Project.find(1))
|
||||
@@ -738,7 +800,34 @@ class UserTest < ActiveSupport::TestCase
|
||||
user.auth_source = denied_auth_source
|
||||
assert !user.change_password_allowed?, "User allowed to change password, though auth source does not"
|
||||
end
|
||||
end
|
||||
|
||||
def test_own_account_deletable_should_be_true_with_unsubscrive_enabled
|
||||
with_settings :unsubscribe => '1' do
|
||||
assert_equal true, User.find(2).own_account_deletable?
|
||||
end
|
||||
end
|
||||
|
||||
def test_own_account_deletable_should_be_false_with_unsubscrive_disabled
|
||||
with_settings :unsubscribe => '0' do
|
||||
assert_equal false, User.find(2).own_account_deletable?
|
||||
end
|
||||
end
|
||||
|
||||
def test_own_account_deletable_should_be_false_for_a_single_admin
|
||||
User.delete_all(["admin = ? AND id <> ?", true, 1])
|
||||
|
||||
with_settings :unsubscribe => '1' do
|
||||
assert_equal false, User.find(1).own_account_deletable?
|
||||
end
|
||||
end
|
||||
|
||||
def test_own_account_deletable_should_be_true_for_an_admin_if_other_admin_exists
|
||||
User.generate_with_protected(:admin => true)
|
||||
|
||||
with_settings :unsubscribe => '1' do
|
||||
assert_equal true, User.find(1).own_account_deletable?
|
||||
end
|
||||
end
|
||||
|
||||
context "#allowed_to?" do
|
||||
|
||||
Reference in New Issue
Block a user