Compare commits
1 Commits
2.0-stable
...
2.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b83ed5a040 |
8
Gemfile
8
Gemfile
@@ -1,11 +1,11 @@
|
||||
source 'http://rubygems.org'
|
||||
|
||||
gem 'rails', '3.2.6'
|
||||
gem 'rails', '3.2.5'
|
||||
gem 'prototype-rails', '3.2.1'
|
||||
gem "i18n", "~> 0.6.0"
|
||||
gem "coderay", "~> 1.0.6"
|
||||
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
|
||||
gem "builder", "3.0.0"
|
||||
gem "builder"
|
||||
|
||||
# Optional gem for LDAP authentication
|
||||
group :ldap do
|
||||
@@ -74,9 +74,7 @@ end
|
||||
|
||||
group :test do
|
||||
gem "shoulda", "~> 2.11"
|
||||
# Shoulda does not work nice on Ruby 1.9.3 and seems to need test-unit explicitely.
|
||||
gem "test-unit", :platforms => [:mri_19]
|
||||
gem "mocha", "0.12.3"
|
||||
gem "mocha"
|
||||
end
|
||||
|
||||
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
|
||||
|
||||
@@ -445,9 +445,9 @@ class ApplicationController < ActionController::Base
|
||||
# Returns the API key present in the request
|
||||
def api_key_from_request
|
||||
if params[:key].present?
|
||||
params[:key].to_s
|
||||
params[:key]
|
||||
elsif request.headers["X-Redmine-API-Key"].present?
|
||||
request.headers["X-Redmine-API-Key"].to_s
|
||||
request.headers["X-Redmine-API-Key"]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ class BoardsController < ApplicationController
|
||||
|
||||
@topic_count = @board.topics.count
|
||||
@topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
|
||||
@topics = @board.topics.reorder("#{Message.table_name}.sticky DESC").order(sort_clause).all(
|
||||
@topics = @board.topics.find :all, :order => ["#{Message.table_name}.sticky DESC", sort_clause].compact.join(', '),
|
||||
:include => [:author, {:last_reply => :author}],
|
||||
:limit => @topic_pages.items_per_page,
|
||||
:offset => @topic_pages.current.offset)
|
||||
:offset => @topic_pages.current.offset
|
||||
@message = Message.new(:board => @board)
|
||||
render :action => 'show', :layout => !request.xhr?
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class TimelogController < ApplicationController
|
||||
|
||||
def index
|
||||
sort_init 'spent_on', 'desc'
|
||||
sort_update 'spent_on' => ['spent_on', "#{TimeEntry.table_name}.created_on"],
|
||||
sort_update 'spent_on' => 'spent_on',
|
||||
'user' => 'user_id',
|
||||
'activity' => 'activity_id',
|
||||
'project' => "#{Project.table_name}.name",
|
||||
|
||||
@@ -253,7 +253,7 @@ module ApplicationHelper
|
||||
def project_tree_options_for_select(projects, options = {})
|
||||
s = ''
|
||||
project_tree(projects) do |project, level|
|
||||
name_prefix = (level > 0 ? (' ' * 2 * level + '» ') : '').html_safe
|
||||
name_prefix = (level > 0 ? (' ' * 2 * level + '» ').html_safe : '')
|
||||
tag_options = {:value => project.id}
|
||||
if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project))
|
||||
tag_options[:selected] = 'selected'
|
||||
@@ -812,7 +812,7 @@ module ApplicationHelper
|
||||
end
|
||||
end
|
||||
|
||||
HEADING_RE = /(<h(\d)( [^>]+)?>(.+?)<\/h(\d)>)/i unless const_defined?(:HEADING_RE)
|
||||
HEADING_RE = /(<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>)/i unless const_defined?(:HEADING_RE)
|
||||
|
||||
def parse_sections(text, project, obj, attr, only_path, options)
|
||||
return unless options[:edit_section_links]
|
||||
@@ -883,8 +883,6 @@ module ApplicationHelper
|
||||
# Renders the TOC with given headings
|
||||
def replace_toc(text, headings)
|
||||
text.gsub!(TOC_RE) do
|
||||
# Keep only the 4 first levels
|
||||
headings = headings.select{|level, anchor, item| level <= 4}
|
||||
if headings.empty?
|
||||
''
|
||||
else
|
||||
|
||||
@@ -24,7 +24,6 @@ class Attachment < ActiveRecord::Base
|
||||
validates_presence_of :filename, :author
|
||||
validates_length_of :filename, :maximum => 255
|
||||
validates_length_of :disk_filename, :maximum => 255
|
||||
validates_length_of :description, :maximum => 255
|
||||
validate :validate_max_file_size
|
||||
|
||||
acts_as_event :title => :filename,
|
||||
|
||||
@@ -124,28 +124,6 @@ class Issue < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
# AR#Persistence#destroy would raise and RecordNotFound exception
|
||||
# if the issue was already deleted or updated (non matching lock_version).
|
||||
# This is a problem when bulk deleting issues or deleting a project
|
||||
# (because an issue may already be deleted if its parent was deleted
|
||||
# first).
|
||||
# The issue is reloaded by the nested_set before being deleted so
|
||||
# the lock_version condition should not be an issue but we handle it.
|
||||
def destroy
|
||||
super
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
# Stale or already deleted
|
||||
begin
|
||||
reload
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
# The issue was actually already deleted
|
||||
@destroyed = true
|
||||
return freeze
|
||||
end
|
||||
# The issue was stale, retry to destroy
|
||||
super
|
||||
end
|
||||
|
||||
# Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
|
||||
def available_custom_fields
|
||||
(project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : []
|
||||
|
||||
@@ -50,8 +50,8 @@ class MailHandler < ActionMailer::Base
|
||||
|
||||
cattr_accessor :ignored_emails_headers
|
||||
@@ignored_emails_headers = {
|
||||
'X-Auto-Response-Suppress' => 'oof',
|
||||
'Auto-Submitted' => /^auto-/
|
||||
'X-Auto-Response-Suppress' => 'OOF',
|
||||
'Auto-Submitted' => 'auto-replied'
|
||||
}
|
||||
|
||||
# Processes incoming emails
|
||||
@@ -69,14 +69,11 @@ class MailHandler < ActionMailer::Base
|
||||
# Ignore auto generated emails
|
||||
self.class.ignored_emails_headers.each do |key, ignored_value|
|
||||
value = email.header[key]
|
||||
if value
|
||||
value = value.to_s.downcase
|
||||
if (ignored_value.is_a?(Regexp) && value.match(ignored_value)) || value == ignored_value
|
||||
if logger && logger.info
|
||||
logger.info "MailHandler: ignoring email with #{key}:#{value} header"
|
||||
end
|
||||
return false
|
||||
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?
|
||||
@@ -166,7 +163,7 @@ class MailHandler < ActionMailer::Base
|
||||
issue = Issue.new(:author => user, :project => project)
|
||||
issue.safe_attributes = issue_attributes_from_keywords(issue)
|
||||
issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
|
||||
issue.subject = cleaned_up_subject
|
||||
issue.subject = email.subject.to_s.chomp[0,255]
|
||||
if issue.subject.blank?
|
||||
issue.subject = '(no subject)'
|
||||
end
|
||||
@@ -226,7 +223,7 @@ class MailHandler < ActionMailer::Base
|
||||
end
|
||||
|
||||
if !message.locked?
|
||||
reply = Message.new(:subject => cleaned_up_subject.gsub(%r{^.*msg\d+\]}, '').strip,
|
||||
reply = Message.new(:subject => email.subject.gsub(%r{^.*msg\d+\]}, '').strip,
|
||||
:content => cleaned_up_text_body)
|
||||
reply.author = user
|
||||
reply.board = message.board
|
||||
@@ -367,23 +364,6 @@ class MailHandler < ActionMailer::Base
|
||||
cleanup_body(plain_text_body)
|
||||
end
|
||||
|
||||
def cleaned_up_subject
|
||||
subject = email.subject.to_s
|
||||
unless subject.respond_to?(:encoding)
|
||||
# try to reencode to utf8 manually with ruby1.8
|
||||
begin
|
||||
if h = email.header[:subject]
|
||||
if m = h.value.match(/^=\?([^\?]+)\?/)
|
||||
subject = Redmine::CodesetUtil.to_utf8(subject, m[1])
|
||||
end
|
||||
end
|
||||
rescue
|
||||
# nop
|
||||
end
|
||||
end
|
||||
subject.strip[0,255]
|
||||
end
|
||||
|
||||
def self.full_sanitizer
|
||||
@full_sanitizer ||= HTML::FullSanitizer.new
|
||||
end
|
||||
|
||||
@@ -361,9 +361,7 @@ class Mailer < ActionMailer::Base
|
||||
def self.with_synched_deliveries(&block)
|
||||
saved_method = ActionMailer::Base.delivery_method
|
||||
if m = saved_method.to_s.match(%r{^async_(.+)$})
|
||||
synched_method = m[1]
|
||||
ActionMailer::Base.delivery_method = synched_method.to_sym
|
||||
ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
|
||||
ActionMailer::Base.delivery_method = m[1].to_sym
|
||||
end
|
||||
yield
|
||||
ensure
|
||||
|
||||
@@ -174,9 +174,9 @@ class Query < ActiveRecord::Base
|
||||
if values_for(field)
|
||||
case type_for(field)
|
||||
when :integer
|
||||
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+$/) }
|
||||
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+$/) }
|
||||
when :float
|
||||
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+(\.\d*)?$/) }
|
||||
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+(\.\d*)?$/) }
|
||||
when :date, :date_past
|
||||
case operator_for(field)
|
||||
when "=", ">=", "<=", "><"
|
||||
|
||||
@@ -37,8 +37,8 @@ class Repository < ActiveRecord::Base
|
||||
validates_presence_of :identifier, :unless => Proc.new { |r| r.is_default? || r.set_as_default? }
|
||||
validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true
|
||||
validates_exclusion_of :identifier, :in => %w(show entry raw changes annotate diff show stats graph)
|
||||
# donwcase letters, digits, dashes, underscores but not digits only
|
||||
validates_format_of :identifier, :with => /^(?!\d+$)[a-z0-9\-_]*$/, :allow_blank => true
|
||||
# donwcase letters, digits, dashes but not digits only
|
||||
validates_format_of :identifier, :with => /^(?!\d+$)[a-z0-9\-]*$/, :allow_blank => true
|
||||
# Checks if the SCM is enabled when creating a repository
|
||||
validate :repo_create_validation, :on => :create
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ class TimeEntry < ActiveRecord::Base
|
||||
end
|
||||
}
|
||||
|
||||
safe_attributes 'hours', 'comments', 'issue_id', 'activity_id', 'spent_on', 'custom_field_values', 'custom_fields'
|
||||
safe_attributes 'hours', 'comments', 'issue_id', 'activity_id', 'spent_on', 'custom_field_values'
|
||||
|
||||
def initialize(attributes=nil, *args)
|
||||
super
|
||||
|
||||
@@ -130,11 +130,8 @@ class User < Principal
|
||||
|
||||
# Returns the user that matches provided login and password, or nil
|
||||
def self.try_to_login(login, password)
|
||||
login = login.to_s
|
||||
password = password.to_s
|
||||
|
||||
# Make sure no one can sign in with an empty password
|
||||
return nil if password.empty?
|
||||
return nil if password.to_s.empty?
|
||||
user = find_by_login(login)
|
||||
if user
|
||||
# user is already in local database
|
||||
@@ -167,7 +164,7 @@ class User < Principal
|
||||
|
||||
# Returns the user who matches the given autologin +key+ or nil
|
||||
def self.try_to_autologin(key)
|
||||
tokens = Token.find_all_by_action_and_value('autologin', key.to_s)
|
||||
tokens = Token.find_all_by_action_and_value('autologin', key)
|
||||
# Make sure there's only 1 token that matches the key
|
||||
if tokens.size == 1
|
||||
token = tokens.first
|
||||
@@ -341,12 +338,12 @@ class User < Principal
|
||||
end
|
||||
|
||||
def self.find_by_rss_key(key)
|
||||
token = Token.find_by_action_and_value('feeds', key.to_s)
|
||||
token = Token.find_by_value(key)
|
||||
token && token.user.active? ? token.user : nil
|
||||
end
|
||||
|
||||
def self.find_by_api_key(key)
|
||||
token = Token.find_by_action_and_value('api', key.to_s)
|
||||
token = Token.find_by_action_and_value('api', key)
|
||||
token && token.user.active? ? token.user : nil
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)).html_safe %></h2>
|
||||
<h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)) %></h2>
|
||||
<p class="subtitle"><%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %></p>
|
||||
|
||||
<div id="activity">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<span>
|
||||
<%= file_field_tag 'attachments[1][file]', :size => 30, :id => nil, :class => 'file',
|
||||
:onchange => "checkFileSize(this, #{Setting.attachment_max_size.to_i.kilobytes}, '#{escape_javascript(l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)))}');" -%>
|
||||
<%= text_field_tag 'attachments[1][description]', '', :id => nil, :class => 'description', :maxlength => 255, :placeholder => l(:label_optional_description) %>
|
||||
<%= text_field_tag 'attachments[1][description]', '', :id => nil, :class => 'description', :placeholder => l(:label_optional_description) %>
|
||||
<%= link_to_function(image_tag('delete.png'), 'removeFileField(this)', :title => (l(:button_delete))) %>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
<% if @notes.present? %>
|
||||
<label><%= radio_button_tag 'conflict_resolution', 'add_notes' %> <%= l(:text_issue_conflict_resolution_add_notes) %></label><br />
|
||||
<% end %>
|
||||
<label><%= radio_button_tag 'conflict_resolution', 'cancel' %> <%= l(:text_issue_conflict_resolution_cancel, :link => link_to_issue(@issue, :subject => false)).html_safe %></label>
|
||||
<label><%= radio_button_tag 'conflict_resolution', 'cancel' %> <%= l(:text_issue_conflict_resolution_cancel, :link => link_to_issue(@issue, :subject => false)) %></label>
|
||||
</p>
|
||||
<p><%= submit_tag l(:button_submit) %></p>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<p><%= l(:mail_body_wiki_content_added, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url),
|
||||
:author => h(@wiki_content.author)).html_safe %><br />
|
||||
:author => h(@wiki_content.author)) %><br />
|
||||
<em><%=h @wiki_content.comments %></em></p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<p><%= l(:mail_body_wiki_content_updated, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url),
|
||||
:author => h(@wiki_content.author)).html_safe %><br />
|
||||
:author => h(@wiki_content.author)) %><br />
|
||||
<em><%=h @wiki_content.comments %></em></p>
|
||||
|
||||
<p><%= l(:label_view_diff) %>:<br />
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
<%=l(:text_project_destroy_confirmation)%>
|
||||
|
||||
<% if @project_to_destroy.descendants.any? %>
|
||||
<br /><%= l(:text_subprojects_destroy_warning,
|
||||
content_tag('strong', h(@project_to_destroy.descendants.collect{|p| p.to_s}.join(', ')))).html_safe %>
|
||||
<br /><%= l(:text_subprojects_destroy_warning, content_tag('strong', h(@project_to_destroy.descendants.collect{|p| p.to_s}.join(', ')))) %>
|
||||
<% end %>
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -76,14 +76,14 @@ ar:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "Byte"
|
||||
other: "Bytes"
|
||||
kb: "KB"
|
||||
kb: "kB"
|
||||
mb: "MB"
|
||||
gb: "GB"
|
||||
tb: "TB"
|
||||
|
||||
@@ -78,7 +78,7 @@ bg:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -89,7 +89,7 @@ bs:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -80,7 +80,7 @@ ca:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -81,14 +81,14 @@ cs:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "Bajt"
|
||||
other: "Bajtů"
|
||||
kb: "KB"
|
||||
kb: "kB"
|
||||
mb: "MB"
|
||||
gb: "GB"
|
||||
tb: "TB"
|
||||
|
||||
@@ -91,7 +91,7 @@ da:
|
||||
format:
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -93,7 +93,7 @@ de:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
@@ -1036,7 +1036,7 @@ de:
|
||||
label_copy_attachments: Anhänge Kopieren
|
||||
label_item_position: "%{position}/%{count}"
|
||||
label_completed_versions: Abgeschlossene Versionen
|
||||
field_multiple: Mehrere Werte
|
||||
field_multiple: Mehrer Werte
|
||||
setting_commit_cross_project_ref: Erlauben auf Tickets aller anderen Projekte zu referenzieren
|
||||
text_issue_conflict_resolution_add_notes: Meine Änderungen übernehmen und alle anderen Änderungen verwerfen
|
||||
text_issue_conflict_resolution_overwrite: Meine Änderungen trotzdem übernehmen (vorherige Notizen bleiben erhalten aber manche können überschrieben werden)
|
||||
|
||||
@@ -77,7 +77,7 @@ el:
|
||||
precision: 3
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ""
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -81,14 +81,14 @@ en-GB:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "Byte"
|
||||
other: "Bytes"
|
||||
kb: "KB"
|
||||
kb: "kB"
|
||||
mb: "MB"
|
||||
gb: "GB"
|
||||
tb: "TB"
|
||||
|
||||
@@ -77,14 +77,14 @@ en:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "Byte"
|
||||
other: "Bytes"
|
||||
kb: "KB"
|
||||
kb: "kB"
|
||||
mb: "MB"
|
||||
gb: "GB"
|
||||
tb: "TB"
|
||||
|
||||
@@ -48,7 +48,7 @@ es:
|
||||
# These three are to override number.format and are optional
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -94,7 +94,7 @@ et:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -79,7 +79,7 @@ eu:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -77,7 +77,7 @@ fa:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -64,7 +64,7 @@ fi:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -91,7 +91,7 @@ fr:
|
||||
format: '%n %u'
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 2
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -32,7 +32,7 @@ gl:
|
||||
format:
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -72,7 +72,7 @@ hr:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -78,7 +78,7 @@ id:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -96,7 +96,7 @@ ja:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
@@ -758,7 +758,7 @@ ja:
|
||||
label_week: 週
|
||||
label_date_from: "日付指定: "
|
||||
label_date_to: から
|
||||
label_language_based: ユーザの言語の設定に従う
|
||||
label_language_based: 既定の言語の設定に従う
|
||||
label_sort_by: "並び替え %{value}"
|
||||
label_send_test_email: テストメールを送信
|
||||
label_feeds_access_key: RSSアクセスキー
|
||||
|
||||
@@ -119,7 +119,7 @@ ko:
|
||||
# These three are to override number.format and are optional
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -109,7 +109,7 @@ lt:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
# Storage units output formatting.
|
||||
# %u is the storage unit, %n is the number (default: 2 MB)
|
||||
|
||||
@@ -72,7 +72,7 @@ lv:
|
||||
human:
|
||||
format:
|
||||
delimiter: " "
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -77,7 +77,7 @@ mk:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -75,7 +75,7 @@ mn:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -74,7 +74,7 @@ nl:
|
||||
precision: 3
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ""
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
other: "nesten %{count} år"
|
||||
number:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 2
|
||||
separator: "."
|
||||
delimiter: ","
|
||||
currency:
|
||||
|
||||
@@ -21,7 +21,7 @@ pl:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -18,10 +18,10 @@ pt-BR:
|
||||
|
||||
time:
|
||||
formats:
|
||||
default: "%A, %d de %B de %Y, %H:%M h"
|
||||
time: "%H:%M h"
|
||||
short: "%d/%m, %H:%M h"
|
||||
long: "%A, %d de %B de %Y, %H:%M h"
|
||||
default: "%A, %d de %B de %Y, %H:%M hs"
|
||||
time: "%H:%M hs"
|
||||
short: "%d/%m, %H:%M hs"
|
||||
long: "%A, %d de %B de %Y, %H:%M hs"
|
||||
only_second: "%S"
|
||||
datetime:
|
||||
formats:
|
||||
@@ -97,7 +97,7 @@ pt-BR:
|
||||
delimiter: '.'
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: '.'
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -89,7 +89,7 @@ pt:
|
||||
delimiter: ''
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ''
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -73,7 +73,7 @@ ro:
|
||||
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ""
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -68,7 +68,7 @@ ru:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 2
|
||||
# Rails 2.2
|
||||
# storage_units: [байт, КБ, МБ, ГБ, ТБ]
|
||||
|
||||
@@ -1089,11 +1089,11 @@ ru:
|
||||
notice_issue_successful_create: Задача %{id} создана.
|
||||
label_between: между
|
||||
setting_issue_group_assignment: Разрешить назначение задач группам пользователей
|
||||
label_diff: Разница(diff)
|
||||
label_diff: diff
|
||||
text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
|
||||
description_query_sort_criteria_direction: Порядок сортировки
|
||||
description_query_sort_criteria_direction: Sort direction
|
||||
description_project_scope: Search scope
|
||||
description_filter: Фильтр
|
||||
description_filter: Filter
|
||||
description_user_mail_notification: Mail notification settings
|
||||
description_date_from: Enter start date
|
||||
description_message_content: Message content
|
||||
@@ -1101,23 +1101,23 @@ ru:
|
||||
description_date_range_interval: Choose range by selecting start and end date
|
||||
description_issue_category_reassign: Choose issue category
|
||||
description_search: Searchfield
|
||||
description_notes: Примечания
|
||||
description_date_range_list: Выберите диапазон из списка
|
||||
description_choose_project: Проекты
|
||||
description_date_to: Введите дату выполнения
|
||||
description_query_sort_criteria_attribute: Критерий сортировки
|
||||
description_wiki_subpages_reassign: Выбрать новую родительскую страницу
|
||||
description_selected_columns: Выбранные столбцы
|
||||
label_parent_revision: Родительский
|
||||
label_child_revision: Дочерний
|
||||
error_scm_annotate_big_text_file: Комментарий невозможен из-за превышения максимального размера текстового файла.
|
||||
setting_default_issue_start_date_to_creation_date: Использовать текущую дату в качестве даты начала для новых задач
|
||||
button_edit_section: Редактировать эту секцию
|
||||
setting_repositories_encodings: Кодировка вложений и хранилищ
|
||||
description_all_columns: Все столбцы
|
||||
button_export: Экспорт
|
||||
label_export_options: "%{export_format} параметры экспорта"
|
||||
error_attachment_too_big: Этот файл нельзя загрузить из-за превышения максимального размера файла (%{max_size})
|
||||
description_notes: Notes
|
||||
description_date_range_list: Choose range from list
|
||||
description_choose_project: Projects
|
||||
description_date_to: Enter end date
|
||||
description_query_sort_criteria_attribute: Sort attribute
|
||||
description_wiki_subpages_reassign: Choose new parent page
|
||||
description_selected_columns: Selected Columns
|
||||
label_parent_revision: Parent
|
||||
label_child_revision: Child
|
||||
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
|
||||
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
|
||||
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})
|
||||
notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
|
||||
label_x_issues:
|
||||
zero: 0 Задач
|
||||
@@ -1125,21 +1125,21 @@ ru:
|
||||
few: "%{count} Задач"
|
||||
many: "%{count} Задач"
|
||||
other: "%{count} Задач"
|
||||
label_repository_new: Новое хранилище
|
||||
field_repository_is_default: Хранилище по умолчанию
|
||||
label_copy_attachments: Копировать вложения
|
||||
label_repository_new: New repository
|
||||
field_repository_is_default: Main repository
|
||||
label_copy_attachments: Copy attachments
|
||||
label_item_position: "%{position}/%{count}"
|
||||
label_completed_versions: Завершенные версии
|
||||
text_project_identifier_info: Допускаются только строчные латинские буквы (a-z), цифры, тире и подчеркивания.<br />После сохранения идентификатор изменить нельзя.
|
||||
field_multiple: Множественные значения
|
||||
setting_commit_cross_project_ref: Разрешить ссылаться и исправлять задачи во всех остальных проектах
|
||||
text_issue_conflict_resolution_add_notes: Добавить мои примечания и отказаться от моих изменений
|
||||
text_issue_conflict_resolution_overwrite: Применить мои изменения (все предыдущие замечания будут сохранены, но некоторые изменения могут быть перезаписаны)
|
||||
notice_issue_update_conflict: Кто-то изменил задачу, пока вы ее редактировали.
|
||||
text_issue_conflict_resolution_cancel: Отменить мои изменения и показать задачу заново %{link}
|
||||
permission_manage_related_issues: Управление связанными задачами
|
||||
field_ldap_filter: Фильтр LDAP
|
||||
label_search_for_watchers: Найти наблюдателей
|
||||
label_completed_versions: Completed versions
|
||||
text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.
|
||||
field_multiple: Multiple values
|
||||
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
|
||||
text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
|
||||
text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
|
||||
notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
|
||||
text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
|
||||
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: "Удалить мою учетную запись"
|
||||
|
||||
@@ -75,7 +75,7 @@ sk:
|
||||
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ""
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -75,7 +75,7 @@ sl:
|
||||
precision: 3
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ""
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -77,14 +77,14 @@ sq:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "Byte"
|
||||
other: "Bytes"
|
||||
kb: "KB"
|
||||
kb: "kB"
|
||||
mb: "MB"
|
||||
gb: "GB"
|
||||
tb: "TB"
|
||||
|
||||
@@ -77,7 +77,7 @@ sr-YU:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -77,7 +77,7 @@ sr:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -47,14 +47,14 @@ sv:
|
||||
# These three are to override number.format and are optional
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
# precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "Byte"
|
||||
other: "Bytes"
|
||||
kb: "KB"
|
||||
kb: "kB"
|
||||
mb: "MB"
|
||||
gb: "GB"
|
||||
tb: "TB"
|
||||
|
||||
@@ -74,7 +74,7 @@ th:
|
||||
precision: 3
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ""
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -99,7 +99,7 @@ tr:
|
||||
format:
|
||||
delimiter: '.'
|
||||
separator: ','
|
||||
precision: 3
|
||||
precision: 2
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -74,7 +74,7 @@ uk:
|
||||
precision: 3
|
||||
human:
|
||||
format:
|
||||
precision: 3
|
||||
precision: 1
|
||||
delimiter: ""
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
|
||||
@@ -48,7 +48,7 @@ vi:
|
||||
# These three are to override number.format and are optional
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
# 下列三個選項設定, 若有設定值將會取代 number.format 成為預設值
|
||||
# separator:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
# 儲存單位輸出格式.
|
||||
# %u 是儲存單位, %n 是數值 (預設值: 2 MB)
|
||||
storage_units:
|
||||
|
||||
@@ -79,14 +79,14 @@ zh:
|
||||
human:
|
||||
format:
|
||||
delimiter: ""
|
||||
precision: 3
|
||||
precision: 1
|
||||
storage_units:
|
||||
format: "%n %u"
|
||||
units:
|
||||
byte:
|
||||
one: "Byte"
|
||||
other: "Bytes"
|
||||
kb: "KB"
|
||||
kb: "kB"
|
||||
mb: "MB"
|
||||
gb: "GB"
|
||||
tb: "TB"
|
||||
|
||||
@@ -224,7 +224,6 @@ RedmineApp::Application.routes.draw do
|
||||
get 'projects/:id/repository/:repository_id/revisions', :to => 'repositories#revisions'
|
||||
get 'projects/:id/repository/:repository_id/revisions/:rev/:action(/*path(.:ext))',
|
||||
:controller => 'repositories',
|
||||
:format => false,
|
||||
:constraints => {
|
||||
:action => /(browse|show|entry|raw|annotate|diff)/,
|
||||
:rev => /[a-z0-9\.\-_]+/
|
||||
@@ -243,7 +242,6 @@ RedmineApp::Application.routes.draw do
|
||||
delete 'projects/:id/repository/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
|
||||
get 'projects/:id/repository/revisions/:rev/:action(/*path(.:ext))',
|
||||
:controller => 'repositories',
|
||||
:format => false,
|
||||
:constraints => {
|
||||
:action => /(browse|show|entry|raw|annotate|diff)/,
|
||||
:rev => /[a-z0-9\.\-_]+/
|
||||
|
||||
@@ -4,46 +4,6 @@ Redmine - project management software
|
||||
Copyright (C) 2006-2012 Jean-Philippe Lang
|
||||
http://www.redmine.org/
|
||||
|
||||
== 2012-09-16 v2.0.4
|
||||
|
||||
* Defect #10818: Running rake in test environment causes exception
|
||||
* Defect #11209: Wiki diff may generate broken HTML
|
||||
* Defect #11217: Project names in drop-down are escaped twice
|
||||
* Defect #11262: Link is escaped in wiki added/updated notification email
|
||||
* Defect #11307: Can't filter for negative numeric custom fields
|
||||
* Defect #11325: Unified diff link broken on specific file/revision diff view
|
||||
* Defect #11341: Escaped link in conflict resolution form
|
||||
* Defect #11365: Attachment description length is not validated
|
||||
* Defect #11511: Confirmation page has broken HTML when a project folding sub project is deleted
|
||||
* Defect #11533: rake redmine:plugins:test doesn't run tests in subdirectories
|
||||
* Defect #11541: Version sharing is missing in the REST API
|
||||
* Defect #11550: Issue reminder doesn't work when using asynchronous delivery
|
||||
* Defect #11776: Can't override mailer views inside redmine plugin.
|
||||
* Defect #11789: Edit section links broken with h5/h6 headings
|
||||
* Feature #11338: Exclude emails with auto-submitted => auto-generated
|
||||
* Patch #11299: redmine:plugins:migrate should update db/schema.rb
|
||||
* Patch #11328: Fix Japanese mistranslation for 'label_language_based'
|
||||
* Patch #11448: Russian translation for 1.4-stable and 2.0-stable
|
||||
* Patch #11600: Fix plural form of the abbreviation for hours in Brazilian Portuguese
|
||||
|
||||
== 2012-06-18 v2.0.3
|
||||
|
||||
* Defect #10688: PDF export from Wiki - Problems with tables
|
||||
* Defect #11061: Cannot choose commit versions to view differences in Git/Mercurial repository view
|
||||
* Defect #11065: E-Mail submitted tickets: German umlauts in 'Subject' get malformed (ruby 1.8)
|
||||
* Defect #11098: Default priorities have the same position and can't be reordered
|
||||
* Defect #11105: <% content_for :header_tags do %> doesn't work inside hook
|
||||
* Defect #11112: REST API - custom fields in POST/PUT ignored for time_entries
|
||||
* Defect #11118: "Maximum file size" displayed on upload forms is incorrect
|
||||
* Defect #11124: Link to user is escaped in activity title
|
||||
* Defect #11133: Wiki-page section edit link can point to incorrect section
|
||||
* Defect #11160: SQL Error on time report if a custom field has multiple values for an entry
|
||||
* Defect #11170: Topics sort order is broken in Redmine 2.x
|
||||
* Defect #11178: Spent time sorted by date-descending order lists same-date entries in physical order (not-reverse)
|
||||
* Defect #11185: Redmine fails to delete a project with parent/child task
|
||||
* Feature #11162: Upgrade to Rails 3.2.6
|
||||
* Patch #11113: Small glitch in German localization
|
||||
|
||||
== 2012-06-05 v2.0.2
|
||||
|
||||
* Defect #11032: Project list is not shown when "For any event on the selected projects only..." is selected on user edit panel
|
||||
|
||||
@@ -13,7 +13,7 @@ http://www.redmine.org/
|
||||
|
||||
* A database:
|
||||
* MySQL (tested with MySQL 5.1)
|
||||
* PostgreSQL (tested with PostgreSQL 9.1)
|
||||
* PostgreSQL (tested with PostgreSQL 8.4)
|
||||
* SQLite3 (tested with SQLite 3.6)
|
||||
|
||||
Optional:
|
||||
@@ -38,10 +38,7 @@ Optional:
|
||||
3. Create an empty utf8 encoded database: "redmine" for example
|
||||
|
||||
4. Configure the database parameters in config/database.yml
|
||||
for the "production" environment (default database is MySQL and ruby1.8)
|
||||
|
||||
If you're running Redmine with MySQL and ruby1.9, replace the adapter name
|
||||
with `mysql2`
|
||||
for the "production" environment (default database is MySQL)
|
||||
|
||||
5. Generate a session store secret
|
||||
|
||||
|
||||
@@ -2,23 +2,7 @@ Description:
|
||||
The plugin generator creates stubs for a new Redmine plugin.
|
||||
|
||||
Example:
|
||||
./script/rails generate redmine_plugin meetings
|
||||
create plugins/meetings/app
|
||||
create plugins/meetings/app/controllers
|
||||
create plugins/meetings/app/helpers
|
||||
create plugins/meetings/app/models
|
||||
create plugins/meetings/app/views
|
||||
create plugins/meetings/db/migrate
|
||||
create plugins/meetings/lib/tasks
|
||||
create plugins/meetings/assets/images
|
||||
create plugins/meetings/assets/javascripts
|
||||
create plugins/meetings/assets/stylesheets
|
||||
create plugins/meetings/config/locales
|
||||
create plugins/meetings/test
|
||||
create plugins/meetings/test/fixtures
|
||||
create plugins/meetings/test/unit
|
||||
create plugins/meetings/test/functional
|
||||
create plugins/meetings/test/integration
|
||||
./script/generate redmine_plugin meetings
|
||||
create plugins/meetings/README.rdoc
|
||||
create plugins/meetings/init.rb
|
||||
create plugins/meetings/config/routes.rb
|
||||
|
||||
@@ -2,4 +2,4 @@ Description:
|
||||
Generates a plugin controller.
|
||||
|
||||
Example:
|
||||
./script/rails generate redmine_plugin_controller meetings pools index show vote
|
||||
./script/generate redmine_plugin_controller meetings pools index show vote
|
||||
|
||||
@@ -2,4 +2,4 @@ Description:
|
||||
Generates a plugin model.
|
||||
|
||||
Examples:
|
||||
./script/rails generate redmine_plugin_model meetings pool
|
||||
./script/generate redmine_plugin_model meetings pool
|
||||
|
||||
@@ -131,15 +131,6 @@ module ActiveRecord
|
||||
when 'lowest'
|
||||
move_to_bottom
|
||||
end
|
||||
reset_positions_in_list
|
||||
end
|
||||
|
||||
def reset_positions_in_list
|
||||
acts_as_list_class.where(scope_condition).reorder("#{position_column} ASC, id ASC").each_with_index do |item, i|
|
||||
unless item.send(position_column) == (i + 1)
|
||||
acts_as_list_class.update_all({position_column => (i + 1)}, {:id => item.id})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Removes the item from the list.
|
||||
@@ -218,7 +209,7 @@ module ActiveRecord
|
||||
def bottom_item(except = nil)
|
||||
conditions = scope_condition
|
||||
conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except
|
||||
acts_as_list_class.where(conditions).reorder("#{position_column} DESC").first
|
||||
acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC")
|
||||
end
|
||||
|
||||
# Forces item to assume the bottom position in the list.
|
||||
|
||||
@@ -283,7 +283,6 @@ class TCPDF
|
||||
@state ||= 0
|
||||
@tableborder ||= 0
|
||||
@tdbegin ||= false
|
||||
@tdtext ||= ''
|
||||
@tdwidth ||= 0
|
||||
@tdheight ||= 0
|
||||
@tdalign ||= "L"
|
||||
@@ -3511,12 +3510,28 @@ class TCPDF
|
||||
|
||||
else
|
||||
#Text
|
||||
if (@tdbegin)
|
||||
element.gsub!(/[\t\r\n\f]/, "");
|
||||
@tdtext << element.gsub(/ /, " ");
|
||||
elsif (@href)
|
||||
if (@href)
|
||||
element.gsub!(/[\t\r\n\f]/, "");
|
||||
addHtmlLink(@href, element, fill);
|
||||
elsif (@tdbegin)
|
||||
element.gsub!(/[\t\r\n\f]/, "");
|
||||
element.gsub!(/ /, " ");
|
||||
base_page = @page;
|
||||
base_x = @x;
|
||||
base_y = @y;
|
||||
|
||||
MultiCell(@tdwidth, @tdheight, unhtmlentities(element.strip), @tableborder, @tdalign, @tdfill, 1);
|
||||
tr_end = @t_cells[@table_id][@tr_id][@td_id]['j1'] + 1;
|
||||
if @max_td_page[tr_end].nil? or (@max_td_page[tr_end] < @page)
|
||||
@max_td_page[tr_end] = @page
|
||||
@max_td_y[tr_end] = @y
|
||||
elsif (@max_td_page[tr_end] == @page)
|
||||
@max_td_y[tr_end] = @y if @max_td_y[tr_end].nil? or (@max_td_y[tr_end] < @y)
|
||||
end
|
||||
|
||||
@page = base_page;
|
||||
@x = base_x + @tdwidth;
|
||||
@y = base_y;
|
||||
elsif (@pre_state == true and element.length > 0)
|
||||
Write(@lasth, unhtmlentities(element), '', fill);
|
||||
elsif (element.strip.length > 0)
|
||||
@@ -3810,7 +3825,6 @@ class TCPDF
|
||||
@x += 5;
|
||||
|
||||
when 'table'
|
||||
Ln();
|
||||
if @default_table_columns < @max_table_columns[@table_id]
|
||||
@table_columns = @max_table_columns[@table_id];
|
||||
else
|
||||
@@ -3907,11 +3921,6 @@ class TCPDF
|
||||
|
||||
when 'img'
|
||||
if (!attrs['src'].nil?)
|
||||
# Don't generates image inside table tag
|
||||
if (@tdbegin)
|
||||
@tdtext << attrs['src'];
|
||||
return
|
||||
end
|
||||
# Only generates image include a pdf if RMagick is avalaible
|
||||
unless Object.const_defined?(:Magick)
|
||||
Write(@lasth, attrs['src'], '', fill);
|
||||
@@ -4070,23 +4079,6 @@ class TCPDF
|
||||
Ln();
|
||||
|
||||
when 'td','th'
|
||||
base_page = @page;
|
||||
base_x = @x;
|
||||
base_y = @y;
|
||||
|
||||
MultiCell(@tdwidth, @tdheight, unhtmlentities(@tdtext.strip), @tableborder, @tdalign, @tdfill, 1);
|
||||
tr_end = @t_cells[@table_id][@tr_id][@td_id]['j1'] + 1;
|
||||
if @max_td_page[tr_end].nil? or (@max_td_page[tr_end] < @page)
|
||||
@max_td_page[tr_end] = @page
|
||||
@max_td_y[tr_end] = @y
|
||||
elsif (@max_td_page[tr_end] == @page)
|
||||
@max_td_y[tr_end] = @y if @max_td_y[tr_end].nil? or (@max_td_y[tr_end] < @y)
|
||||
end
|
||||
|
||||
@page = base_page;
|
||||
@x = base_x + @tdwidth;
|
||||
@y = base_y;
|
||||
@tdtext = '';
|
||||
@tdbegin = false;
|
||||
@tdwidth = 0;
|
||||
@tdheight = 0;
|
||||
@@ -4134,6 +4126,7 @@ class TCPDF
|
||||
@l_margin -= 5;
|
||||
@r_margin -= 5;
|
||||
@tableborder=0;
|
||||
Ln();
|
||||
@table_id += 1;
|
||||
|
||||
when 'strong'
|
||||
|
||||
@@ -50,17 +50,16 @@ module Redmine
|
||||
words_add += 1
|
||||
else
|
||||
del_at = pos unless del_at
|
||||
deleted << ' ' unless deleted.empty?
|
||||
deleted << h(change[2])
|
||||
deleted << ' ' + h(change[2])
|
||||
words_del += 1
|
||||
end
|
||||
end
|
||||
if add_at
|
||||
words[add_at] = '<span class="diff_in">'.html_safe + words[add_at]
|
||||
words[add_to] = words[add_to] + '</span>'.html_safe
|
||||
words[add_at] = '<span class="diff_in">' + words[add_at]
|
||||
words[add_to] = words[add_to] + '</span>'
|
||||
end
|
||||
if del_at
|
||||
words.insert del_at - del_off + dels + words_add, '<span class="diff_out">'.html_safe + deleted + '</span>'.html_safe
|
||||
words.insert del_at - del_off + dels + words_add, '<span class="diff_out">' + deleted + '</span>'
|
||||
dels += 1
|
||||
del_off += words_del
|
||||
words_del = 0
|
||||
|
||||
@@ -138,21 +138,21 @@ module Redmine
|
||||
# Add list and boolean custom fields as available criteria
|
||||
custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
|
||||
custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
||||
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id ORDER BY c.value LIMIT 1)",
|
||||
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)",
|
||||
:format => cf.field_format,
|
||||
:label => cf.name}
|
||||
end if @project
|
||||
|
||||
# Add list and boolean time entry custom fields
|
||||
TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
||||
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id ORDER BY c.value LIMIT 1)",
|
||||
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)",
|
||||
:format => cf.field_format,
|
||||
:label => cf.name}
|
||||
end
|
||||
|
||||
# Add list and boolean time entry activity custom fields
|
||||
TimeEntryActivityCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
|
||||
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id ORDER BY c.value LIMIT 1)",
|
||||
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id)",
|
||||
:format => cf.field_format,
|
||||
:label => cf.name}
|
||||
end
|
||||
|
||||
@@ -107,13 +107,7 @@ module Redmine
|
||||
#
|
||||
def self.render_on(hook, options={})
|
||||
define_method hook do |context|
|
||||
if context[:hook_caller].respond_to?(:render)
|
||||
context[:hook_caller].send(:render, {:locals => context}.merge(options))
|
||||
elsif context[:controller].is_a?(ActionController::Base)
|
||||
context[:controller].send(:render_to_string, {:locals => context}.merge(options))
|
||||
else
|
||||
raise "Cannot render #{self.name} hook from #{context[:hook_caller].class.name}"
|
||||
end
|
||||
context[:controller].send(:render_to_string, {:locals => context}.merge(options))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -144,15 +138,14 @@ module Redmine
|
||||
# * project => current project
|
||||
# * request => Request instance
|
||||
# * controller => current Controller instance
|
||||
# * hook_caller => object that called the hook
|
||||
#
|
||||
module Helper
|
||||
def call_hook(hook, context={})
|
||||
if is_a?(ActionController::Base)
|
||||
default_context = {:controller => self, :project => @project, :request => request, :hook_caller => self}
|
||||
default_context = {:controller => self, :project => @project, :request => request}
|
||||
Redmine::Hook.call_hook(hook, default_context.merge(context))
|
||||
else
|
||||
default_context = { :project => @project, :hook_caller => self }
|
||||
default_context = { :project => @project }
|
||||
default_context[:controller] = controller if respond_to?(:controller)
|
||||
default_context[:request] = request if respond_to?(:request)
|
||||
Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe
|
||||
|
||||
@@ -82,7 +82,6 @@ module Redmine #:nodoc:
|
||||
view_path = File.join(p.directory, 'app', 'views')
|
||||
if File.directory?(view_path)
|
||||
ActionController::Base.prepend_view_path(view_path)
|
||||
ActionMailer::Base.prepend_view_path(view_path)
|
||||
end
|
||||
|
||||
# Adds the app/{controllers,helpers,models} directories of the plugin to the autoload path
|
||||
|
||||
@@ -4,7 +4,7 @@ module Redmine
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 0
|
||||
TINY = 4
|
||||
TINY = 2
|
||||
|
||||
# Branch values:
|
||||
# * official release: nil
|
||||
|
||||
@@ -69,7 +69,7 @@ module Redmine
|
||||
l = 1
|
||||
started = false
|
||||
ended = false
|
||||
text.scan(/(((?:.*?)(\A|\r?\n\s*\r?\n))(h(\d+)(#{A}#{C})\.(?::(\S+))? (.*?)$)|.*)/m).each do |all, content, lf, heading, level|
|
||||
text.scan(/(((?:.*?)(\A|\r?\n\r?\n))(h(\d+)(#{A}#{C})\.(?::(\S+))? (.*?)$)|.*)/m).each do |all, content, lf, heading, level|
|
||||
if heading.nil?
|
||||
if ended
|
||||
after << all
|
||||
|
||||
@@ -70,8 +70,6 @@ namespace :redmine do
|
||||
rescue Redmine::PluginNotFound
|
||||
abort "Plugin #{name} was not found."
|
||||
end
|
||||
|
||||
Rake::Task["db:schema:dump"].invoke
|
||||
end
|
||||
|
||||
desc 'Copies plugins assets into the public directory.'
|
||||
@@ -84,36 +82,6 @@ namespace :redmine do
|
||||
abort "Plugin #{name} was not found."
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Runs the plugins tests.'
|
||||
task :test do
|
||||
Rake::Task["redmine:plugins:test:units"].invoke
|
||||
Rake::Task["redmine:plugins:test:functionals"].invoke
|
||||
Rake::Task["redmine:plugins:test:integration"].invoke
|
||||
end
|
||||
|
||||
namespace :test do
|
||||
desc 'Runs the plugins unit tests.'
|
||||
Rake::TestTask.new :units => "db:test:prepare" do |t|
|
||||
t.libs << "test"
|
||||
t.verbose = true
|
||||
t.test_files = FileList["plugins/#{ENV['NAME'] || '*'}/test/unit/**/*_test.rb"]
|
||||
end
|
||||
|
||||
desc 'Runs the plugins functional tests.'
|
||||
Rake::TestTask.new :functionals => "db:test:prepare" do |t|
|
||||
t.libs << "test"
|
||||
t.verbose = true
|
||||
t.test_files = FileList["plugins/#{ENV['NAME'] || '*'}/test/functional/**/*_test.rb"]
|
||||
end
|
||||
|
||||
desc 'Runs the plugins integration tests.'
|
||||
Rake::TestTask.new :integration => "db:test:prepare" do |t|
|
||||
t.libs << "test"
|
||||
t.verbose = true
|
||||
t.test_files = FileList["plugins/#{ENV['NAME'] || '*'}/test/integration/**/*_test.rb"]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ table.revision-info td {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div.revision-graph { position: absolute; min-width: 1px; }
|
||||
div.revision-graph { position: absolute; }
|
||||
|
||||
div.changeset-changes ul { margin: 0; padding: 0; }
|
||||
div.changeset-changes ul > ul { margin-left: 18px; padding: 0; }
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
Content-Type: application/ms-tnef; name="winmail.dat"
|
||||
Content-Transfer-Encoding: binary
|
||||
From: John Smith <JSmith@somenet.foo>
|
||||
To: "redmine@somenet.foo" <redmine@somenet.foo>
|
||||
Subject: =?iso-8859-1?Q?Testmail_from_Webmail:_=E4_=F6_=FC...?=
|
||||
Date: Fri, 1 Jun 2012 14:39:38 +0200
|
||||
Message-ID: <87C31D42249DD0489D1A1444E3232DD7019D6183@foo.bar>
|
||||
Accept-Language: de-CH, en-US
|
||||
Content-Language: de-CH
|
||||
|
||||
Fixture
|
||||
@@ -55,16 +55,13 @@ class ActivitiesControllerTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
def test_global_index
|
||||
@request.session[:user_id] = 1
|
||||
get :index
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
assert_not_nil assigns(:events_by_day)
|
||||
|
||||
i5 = Issue.find(5)
|
||||
d5 = User.find(1).time_to_date(i5.created_on)
|
||||
assert_tag :tag => "h3",
|
||||
:content => /#{d5.day}/,
|
||||
:content => /#{5.day.ago.to_date.day}/,
|
||||
:sibling => { :tag => "dl",
|
||||
:child => { :tag => "dt",
|
||||
:attributes => { :class => /issue/ },
|
||||
@@ -76,19 +73,13 @@ class ActivitiesControllerTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
def test_user_index
|
||||
@request.session[:user_id] = 1
|
||||
get :index, :user_id => 2
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
assert_not_nil assigns(:events_by_day)
|
||||
|
||||
assert_select 'h2 a[href=/users/2]', :text => 'John Smith'
|
||||
|
||||
i1 = Issue.find(1)
|
||||
d1 = User.find(1).time_to_date(i1.created_on)
|
||||
|
||||
assert_tag :tag => "h3",
|
||||
:content => /#{d1.day}/,
|
||||
:content => /#{3.day.ago.to_date.day}/,
|
||||
:sibling => { :tag => "dl",
|
||||
:child => { :tag => "dt",
|
||||
:attributes => { :class => /issue/ },
|
||||
|
||||
@@ -55,20 +55,6 @@ class BoardsControllerTest < ActionController::TestCase
|
||||
assert_not_nil assigns(:topics)
|
||||
end
|
||||
|
||||
def test_show_should_display_sticky_messages_first
|
||||
Message.update_all(:sticky => 0)
|
||||
Message.update_all({:sticky => 1}, {:id => 1})
|
||||
|
||||
get :show, :project_id => 1, :id => 1
|
||||
assert_response :success
|
||||
|
||||
topics = assigns(:topics)
|
||||
assert_not_nil topics
|
||||
assert topics.size > 1, "topics size was #{topics.size}"
|
||||
assert topics.first.sticky?
|
||||
assert topics.first.updated_on < topics.second.updated_on
|
||||
end
|
||||
|
||||
def test_show_with_permission_should_display_the_new_message_form
|
||||
@request.session[:user_id] = 2
|
||||
get :show, :project_id => 1, :id => 1
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class DocumentsControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
:enabled_modules, :documents, :enumerations,
|
||||
:groups_users, :attachments
|
||||
fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules, :documents, :enumerations
|
||||
|
||||
def setup
|
||||
User.current = nil
|
||||
@@ -97,16 +95,16 @@ LOREM
|
||||
|
||||
def test_create_with_one_attachment
|
||||
ActionMailer::Base.deliveries.clear
|
||||
Setting.notified_events << 'document_added'
|
||||
@request.session[:user_id] = 2
|
||||
set_tmp_attachments_directory
|
||||
|
||||
with_settings :notified_events => %w(document_added) do
|
||||
post :create, :project_id => 'ecookbook',
|
||||
post :create, :project_id => 'ecookbook',
|
||||
:document => { :title => 'DocumentsControllerTest#test_post_new',
|
||||
:description => 'This is a new document',
|
||||
:category_id => 2},
|
||||
:attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
|
||||
end
|
||||
|
||||
assert_redirected_to '/projects/ecookbook/documents'
|
||||
|
||||
document = Document.find_by_title('DocumentsControllerTest#test_post_new')
|
||||
@@ -126,23 +124,6 @@ LOREM
|
||||
assert_template 'new'
|
||||
end
|
||||
|
||||
def test_create_non_default_category
|
||||
@request.session[:user_id] = 2
|
||||
category2 = Enumeration.find_by_name('User documentation')
|
||||
category2.update_attributes(:is_default => true)
|
||||
category1 = Enumeration.find_by_name('Uncategorized')
|
||||
post :create,
|
||||
:project_id => 'ecookbook',
|
||||
:document => { :title => 'no default',
|
||||
:description => 'This is a new document',
|
||||
:category_id => category1.id }
|
||||
assert_redirected_to '/projects/ecookbook/documents'
|
||||
doc = Document.find_by_title('no default')
|
||||
assert_not_nil doc
|
||||
assert_equal category1.id, doc.category_id
|
||||
assert_equal category1, doc.category
|
||||
end
|
||||
|
||||
def test_edit
|
||||
@request.session[:user_id] = 2
|
||||
get :edit, :id => 1
|
||||
|
||||
@@ -58,14 +58,13 @@ class FilesControllerTest < ActionController::TestCase
|
||||
def test_create_file
|
||||
set_tmp_attachments_directory
|
||||
@request.session[:user_id] = 2
|
||||
Setting.notified_events = ['file_added']
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
with_settings :notified_events => %w(file_added) do
|
||||
assert_difference 'Attachment.count' do
|
||||
post :create, :project_id => 1, :version_id => '',
|
||||
:attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
|
||||
assert_response :redirect
|
||||
end
|
||||
assert_difference 'Attachment.count' do
|
||||
post :create, :project_id => 1, :version_id => '',
|
||||
:attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}
|
||||
assert_response :redirect
|
||||
end
|
||||
assert_redirected_to '/projects/ecookbook/files'
|
||||
a = Attachment.find(:first, :order => 'created_on DESC')
|
||||
@@ -81,6 +80,7 @@ class FilesControllerTest < ActionController::TestCase
|
||||
def test_create_version_file
|
||||
set_tmp_attachments_directory
|
||||
@request.session[:user_id] = 2
|
||||
Setting.notified_events = ['file_added']
|
||||
|
||||
assert_difference 'Attachment.count' do
|
||||
post :create, :project_id => 1, :version_id => '2',
|
||||
|
||||
@@ -1371,7 +1371,6 @@ class IssuesControllerTest < ActionController::TestCase
|
||||
:tag => 'input',
|
||||
:attributes => {:type => 'file', :name => 'attachments[1][file]'}
|
||||
}
|
||||
assert_select 'input[name=?][maxlength=255]', 'attachments[1][description]'
|
||||
end
|
||||
|
||||
def test_get_new_should_prefill_the_form_from_params
|
||||
|
||||
@@ -71,14 +71,10 @@ class IssuesControllerTransactionTest < ActionController::TestCase
|
||||
|
||||
assert_response :success
|
||||
assert_template 'edit'
|
||||
|
||||
assert_select 'div.conflict'
|
||||
assert_select 'input[name=?][value=?]', 'conflict_resolution', 'overwrite'
|
||||
assert_select 'input[name=?][value=?]', 'conflict_resolution', 'add_notes'
|
||||
assert_select 'label' do
|
||||
assert_select 'input[name=?][value=?]', 'conflict_resolution', 'cancel'
|
||||
assert_select 'a[href=/issues/2]'
|
||||
end
|
||||
assert_tag 'div', :attributes => {:class => 'conflict'}
|
||||
assert_tag 'input', :attributes => {:name => 'conflict_resolution', :value => 'overwrite'}
|
||||
assert_tag 'input', :attributes => {:name => 'conflict_resolution', :value => 'add_notes'}
|
||||
assert_tag 'input', :attributes => {:name => 'conflict_resolution', :value => 'cancel'}
|
||||
end
|
||||
|
||||
def test_update_stale_issue_should_save_attachments
|
||||
|
||||
@@ -91,12 +91,11 @@ class MessagesControllerTest < ActionController::TestCase
|
||||
def test_post_new
|
||||
@request.session[:user_id] = 2
|
||||
ActionMailer::Base.deliveries.clear
|
||||
Setting.notified_events = ['message_posted']
|
||||
|
||||
with_settings :notified_events => %w(message_posted) do
|
||||
post :new, :board_id => 1,
|
||||
post :new, :board_id => 1,
|
||||
:message => { :subject => 'Test created message',
|
||||
:content => 'Message body'}
|
||||
end
|
||||
message = Message.find_by_subject('Test created message')
|
||||
assert_not_nil message
|
||||
assert_redirected_to "/boards/1/topics/#{message.to_param}"
|
||||
|
||||
@@ -82,13 +82,12 @@ class NewsControllerTest < ActionController::TestCase
|
||||
|
||||
def test_post_create
|
||||
ActionMailer::Base.deliveries.clear
|
||||
@request.session[:user_id] = 2
|
||||
Setting.notified_events << 'news_added'
|
||||
|
||||
with_settings :notified_events => %w(news_added) do
|
||||
post :create, :project_id => 1, :news => { :title => 'NewsControllerTest',
|
||||
@request.session[:user_id] = 2
|
||||
post :create, :project_id => 1, :news => { :title => 'NewsControllerTest',
|
||||
:description => 'This is the description',
|
||||
:summary => '' }
|
||||
end
|
||||
assert_redirected_to '/projects/ecookbook/news'
|
||||
|
||||
news = News.find_by_title('NewsControllerTest')
|
||||
|
||||
@@ -412,10 +412,6 @@ class ProjectsControllerTest < ActionController::TestCase
|
||||
assert_response :success
|
||||
assert_template 'destroy'
|
||||
assert_not_nil Project.find_by_id(1)
|
||||
assert_tag :tag => 'strong',
|
||||
:content => ['Private child of eCookbook',
|
||||
'Child of private child, eCookbook Subproject 1',
|
||||
'eCookbook Subproject 2'].join(', ')
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
|
||||
@@ -87,16 +87,6 @@ class RepositoriesGitControllerTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
## Ruby uses ANSI api to fork a process on Windows.
|
||||
## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
|
||||
## and these are incompatible with ASCII.
|
||||
## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10
|
||||
## http://code.google.com/p/msysgit/issues/detail?id=80
|
||||
## So, Latin-1 path tests fail on Japanese Windows
|
||||
WINDOWS_PASS = (Redmine::Platform.mswin? &&
|
||||
Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10]))
|
||||
WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10"
|
||||
|
||||
def test_get_new
|
||||
@request.session[:user_id] = 1
|
||||
@project.repository.destroy
|
||||
@@ -224,8 +214,6 @@ class RepositoriesGitControllerTest < ActionController::TestCase
|
||||
def test_entry_show_latin_1
|
||||
if @ruby19_non_utf8_pass
|
||||
puts_ruby19_non_utf8_pass()
|
||||
elsif WINDOWS_PASS
|
||||
puts WINDOWS_SKIP_STR
|
||||
elsif JRUBY_SKIP
|
||||
puts JRUBY_SKIP_STR
|
||||
else
|
||||
@@ -287,53 +275,26 @@ class RepositoriesGitControllerTest < ActionController::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
def test_diff_with_rev_and_path
|
||||
assert_equal 0, @repository.changesets.count
|
||||
@repository.fetch_changesets
|
||||
@project.reload
|
||||
assert_equal NUM_REV, @repository.changesets.count
|
||||
with_settings :diff_max_lines_displayed => 1000 do
|
||||
# Full diff of changeset 2f9c0091
|
||||
['inline', 'sbs'].each do |dt|
|
||||
get :diff,
|
||||
:id => PRJ_ID,
|
||||
:rev => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7',
|
||||
:path => repository_path_hash(['sources', 'watchers_controller.rb'])[:param],
|
||||
:type => dt
|
||||
assert_response :success
|
||||
assert_template 'diff'
|
||||
# Line 22 removed
|
||||
assert_tag :tag => 'th',
|
||||
:content => '22',
|
||||
:sibling => { :tag => 'td',
|
||||
:attributes => { :class => /diff_out/ },
|
||||
:content => /def remove/ }
|
||||
assert_tag :tag => 'h2', :content => /2f9c0091/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_diff_truncated
|
||||
assert_equal 0, @repository.changesets.count
|
||||
@repository.fetch_changesets
|
||||
@project.reload
|
||||
assert_equal NUM_REV, @repository.changesets.count
|
||||
Setting.diff_max_lines_displayed = 5
|
||||
|
||||
with_settings :diff_max_lines_displayed => 5 do
|
||||
# Truncated diff of changeset 2f9c0091
|
||||
with_cache do
|
||||
get :diff, :id => PRJ_ID, :type => 'inline',
|
||||
:rev => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
|
||||
assert_response :success
|
||||
assert @response.body.include?("... This diff was truncated")
|
||||
with_settings :default_language => 'fr' do
|
||||
get :diff, :id => PRJ_ID, :type => 'inline',
|
||||
:rev => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
|
||||
assert_response :success
|
||||
assert ! @response.body.include?("... This diff was truncated")
|
||||
assert @response.body.include?("... Ce diff")
|
||||
end
|
||||
end
|
||||
# Truncated diff of changeset 2f9c0091
|
||||
with_cache do
|
||||
get :diff, :id => PRJ_ID, :type => 'inline',
|
||||
:rev => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
|
||||
assert_response :success
|
||||
assert @response.body.include?("... This diff was truncated")
|
||||
|
||||
Setting.default_language = 'fr'
|
||||
get :diff, :id => PRJ_ID, :type => 'inline',
|
||||
:rev => '2f9c0091c754a91af7a9c478e36556b4bde8dcf7'
|
||||
assert_response :success
|
||||
assert ! @response.body.include?("... This diff was truncated")
|
||||
assert @response.body.include?("... Ce diff")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -474,8 +435,6 @@ class RepositoriesGitControllerTest < ActionController::TestCase
|
||||
def test_annotate_latin_1
|
||||
if @ruby19_non_utf8_pass
|
||||
puts_ruby19_non_utf8_pass()
|
||||
elsif WINDOWS_PASS
|
||||
puts WINDOWS_SKIP_STR
|
||||
elsif JRUBY_SKIP
|
||||
puts JRUBY_SKIP_STR
|
||||
else
|
||||
|
||||
@@ -57,7 +57,6 @@ class SettingsControllerTest < ActionController::TestCase
|
||||
assert !Setting.bcc_recipients?
|
||||
assert_equal %w(issue_added issue_updated news_added), Setting.notified_events
|
||||
assert_equal 'Test footer', Setting.emails_footer
|
||||
Setting.clear_cache
|
||||
end
|
||||
|
||||
def test_get_plugin_settings
|
||||
|
||||
@@ -33,10 +33,6 @@ class SysControllerTest < ActionController::TestCase
|
||||
Setting.enabled_scm = %w(Subversion Git)
|
||||
end
|
||||
|
||||
def teardown
|
||||
Setting.clear_cache
|
||||
end
|
||||
|
||||
def test_projects_with_repository_enabled
|
||||
get :projects
|
||||
assert_response :success
|
||||
|
||||
@@ -80,16 +80,6 @@ class TimeEntryReportsControllerTest < ActionController::TestCase
|
||||
assert_equal "162.90", "%.2f" % assigns(:report).total_hours
|
||||
end
|
||||
|
||||
def test_report_custom_field_criteria_with_multiple_values
|
||||
field = TimeEntryCustomField.create!(:name => 'multi', :field_format => 'list', :possible_values => ['value1', 'value2'])
|
||||
entry = TimeEntry.create!(:project => Project.find(1), :hours => 1, :activity_id => 10, :user => User.find(2), :spent_on => Date.today)
|
||||
CustomValue.create!(:customized => entry, :custom_field => field, :value => 'value1')
|
||||
CustomValue.create!(:customized => entry, :custom_field => field, :value => 'value2')
|
||||
|
||||
get :report, :project_id => 1, :columns => 'day', :criteria => ["cf_#{field.id}"]
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_report_one_day
|
||||
get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criteria => ["member", "activity"]
|
||||
assert_response :success
|
||||
|
||||
@@ -568,20 +568,6 @@ class TimelogControllerTest < ActionController::TestCase
|
||||
:attributes => {:action => "/projects/ecookbook/issues/1/time_entries", :id => 'query_form'}
|
||||
end
|
||||
|
||||
def test_index_should_sort_by_spent_on_and_created_on
|
||||
t1 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:00:00', :activity_id => 10)
|
||||
t2 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-16', :created_on => '2012-06-16 20:05:00', :activity_id => 10)
|
||||
t3 = TimeEntry.create!(:user => User.find(1), :project => Project.find(1), :hours => 1, :spent_on => '2012-06-15', :created_on => '2012-06-16 20:10:00', :activity_id => 10)
|
||||
|
||||
get :index, :project_id => 1, :from => '2012-06-15', :to => '2012-06-16'
|
||||
assert_response :success
|
||||
assert_equal [t2, t1, t3], assigns(:entries)
|
||||
|
||||
get :index, :project_id => 1, :from => '2012-06-15', :to => '2012-06-16', :sort => 'spent_on'
|
||||
assert_response :success
|
||||
assert_equal [t3, t1, t2], assigns(:entries)
|
||||
end
|
||||
|
||||
def test_index_atom_feed
|
||||
get :index, :project_id => 1, :format => 'atom'
|
||||
assert_response :success
|
||||
|
||||
@@ -96,16 +96,6 @@ class WelcomeControllerTest < ActionController::TestCase
|
||||
assert @controller.respond_to?(:call_hook)
|
||||
end
|
||||
|
||||
def test_project_jump_box_should_escape_names_once
|
||||
Project.find(1).update_attribute :name, 'Foo & Bar'
|
||||
@request.session[:user_id] = 2
|
||||
|
||||
get :index
|
||||
assert_select "#header select" do
|
||||
assert_select "option", :text => 'Foo & Bar'
|
||||
end
|
||||
end
|
||||
|
||||
context "test_api_offset_and_limit" do
|
||||
context "without params" do
|
||||
should "return 0, 25" do
|
||||
|
||||
@@ -495,19 +495,11 @@ class WikiControllerTest < ActionController::TestCase
|
||||
end
|
||||
|
||||
def test_diff
|
||||
content = WikiPage.find(1).content
|
||||
assert_difference 'WikiContent::Version.count', 2 do
|
||||
content.text = "Line removed\nThis is a sample text for testing diffs"
|
||||
content.save!
|
||||
content.text = "This is a sample text for testing diffs\nLine added"
|
||||
content.save!
|
||||
end
|
||||
|
||||
get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => content.version, :version_from => (content.version - 1)
|
||||
get :diff, :project_id => 1, :id => 'CookBook_documentation', :version => 2, :version_from => 1
|
||||
assert_response :success
|
||||
assert_template 'diff'
|
||||
assert_select 'span.diff_out', :text => 'Line removed'
|
||||
assert_select 'span.diff_in', :text => 'Line added'
|
||||
assert_tag :tag => 'span', :attributes => { :class => 'diff_in'},
|
||||
:content => /updated/
|
||||
end
|
||||
|
||||
def test_annotate
|
||||
|
||||
@@ -66,6 +66,8 @@ class AccountTest < ActionController::IntegrationTest
|
||||
assert_template 'my/page'
|
||||
assert_equal user.id, session[:user_id]
|
||||
assert_not_nil user.reload.last_login_on
|
||||
seconds_ago = 10.second.ago.utc
|
||||
assert user.last_login_on.utc > 10.second.ago.utc, "#{user.last_login_on.utc} was not > #{seconds_ago}"
|
||||
end
|
||||
|
||||
def test_lost_password
|
||||
|
||||
@@ -79,21 +79,6 @@ class ApiTest::TimeEntriesTest < ActionController::IntegrationTest
|
||||
assert_equal 3.5, entry.hours
|
||||
assert_equal TimeEntryActivity.find(11), entry.activity
|
||||
end
|
||||
|
||||
should "accept custom fields" do
|
||||
field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'string')
|
||||
|
||||
assert_difference 'TimeEntry.count' do
|
||||
post '/time_entries.xml', {:time_entry => {
|
||||
:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11', :custom_fields => [{:id => field.id.to_s, :value => 'accepted'}]
|
||||
}}, credentials('jsmith')
|
||||
end
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
entry = TimeEntry.first(:order => 'id DESC')
|
||||
assert_equal 'accepted', entry.custom_field_value(field)
|
||||
end
|
||||
end
|
||||
|
||||
context "with project_id" do
|
||||
|
||||
@@ -35,17 +35,6 @@ class MenuManagerTest < ActionController::IntegrationTest
|
||||
end
|
||||
end
|
||||
|
||||
class ContentForInsideHook < Redmine::Hook::ViewListener
|
||||
render_on :view_welcome_index_left, :inline => <<-VIEW
|
||||
<% content_for :header_tags do %>
|
||||
<%= javascript_include_tag 'test_plugin.js', :plugin => 'test_plugin' %>
|
||||
<%= stylesheet_link_tag 'test_plugin.css', :plugin => 'test_plugin' %>
|
||||
<% end %>
|
||||
|
||||
<p>ContentForInsideHook content</p>
|
||||
VIEW
|
||||
end
|
||||
|
||||
def setup
|
||||
Redmine::Hook.clear_listeners
|
||||
end
|
||||
@@ -75,16 +64,4 @@ VIEW
|
||||
assert_select 'div#main'
|
||||
assert_select 'div#main.nosidebar', 0
|
||||
end
|
||||
|
||||
def test_hook_with_content_for_should_append_content
|
||||
Redmine::Hook.add_listener(ContentForInsideHook)
|
||||
|
||||
get '/'
|
||||
assert_response :success
|
||||
assert_select 'p', :text => 'ContentForInsideHook content'
|
||||
assert_select 'head' do
|
||||
assert_select 'script[src=/plugin_assets/test_plugin/javascripts/test_plugin.js]'
|
||||
assert_select 'link[href=/plugin_assets/test_plugin/stylesheets/test_plugin.css]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user