Compare commits

..
1 Commits
Author SHA1 Message Date
Jean-Philippe Lang c2a6e1eeb7 tagged version 2.1.2
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/tags/2.1.2@10537 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-30 10:43:39 +00:00
54 changed files with 208 additions and 691 deletions
-1
View File
@@ -19,7 +19,6 @@
/public/plugin_assets /public/plugin_assets
/tmp/* /tmp/*
/tmp/cache/* /tmp/cache/*
/tmp/pdf/*
/tmp/sessions/* /tmp/sessions/*
/tmp/sockets/* /tmp/sockets/*
/tmp/test/* /tmp/test/*
-1
View File
@@ -21,7 +21,6 @@ public/dispatch.*
public/plugin_assets public/plugin_assets
tmp/* tmp/*
tmp/cache/* tmp/cache/*
tmp/pdf/*
tmp/sessions/* tmp/sessions/*
tmp/sockets/* tmp/sockets/*
tmp/test/* tmp/test/*
+1 -1
View File
@@ -41,7 +41,7 @@ end
platforms :mri_18, :mingw_18 do platforms :mri_18, :mingw_18 do
group :mysql do group :mysql do
gem "mysql", "~> 2.8.1" gem "mysql"
end end
end end
+1 -2
View File
@@ -26,8 +26,7 @@ class PreviewsController < ApplicationController
if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n") if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n")
@description = nil @description = nil
end end
# params[:notes] is useful for preview of notes in issue history @notes = params[:notes]
@notes = params[:notes] || (params[:issue] ? params[:issue][:notes] : nil)
else else
@description = (params[:issue] ? params[:issue][:description] : nil) @description = (params[:issue] ? params[:issue][:description] : nil)
end end
+1 -1
View File
@@ -239,7 +239,7 @@ class WikiController < ApplicationController
# Export wiki to a single pdf or html file # Export wiki to a single pdf or html file
def export def export
@pages = @wiki.pages.all(:order => 'title', :include => [:content, :attachments]) @pages = @wiki.pages.all(:order => 'title', :include => [:content, :attachments], :limit => 75)
respond_to do |format| respond_to do |format|
format.html { format.html {
export = render_to_string :action => 'export_multiple', :layout => false export = render_to_string :action => 'export_multiple', :layout => false
+3 -2
View File
@@ -795,10 +795,11 @@ module ApplicationHelper
if repository && User.current.allowed_to?(:browse_repository, project) if repository && User.current.allowed_to?(:browse_repository, project)
name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$} name =~ %r{^[/\\]*(.*?)(@([0-9a-f]+))?(#(L\d+))?$}
path, rev, anchor = $1, $3, $5 path, rev, anchor = $1, $3, $5
link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param, link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => 'entry', :id => project, :repository_id => repository.identifier_param,
:path => to_path_param(path), :path => to_path_param(path),
:rev => rev, :rev => rev,
:anchor => anchor}, :anchor => anchor,
:format => (prefix == 'export' ? 'raw' : nil)},
:class => (prefix == 'export' ? 'source download' : 'source') :class => (prefix == 'export' ? 'source download' : 'source')
end end
end end
+2 -2
View File
@@ -26,8 +26,8 @@ module ContextMenusHelper
end end
if options.delete(:disabled) if options.delete(:disabled)
options.delete(:method) options.delete(:method)
options.delete(:data) options.delete(:confirm)
options[:onclick] = 'return false;' options.delete(:onclick)
options[:class] << ' disabled' options[:class] << ' disabled'
url = '#' url = '#'
end end
+1 -7
View File
@@ -130,13 +130,7 @@ class CustomField < ActiveRecord::Base
possible_values_options = possible_values_options(customized) possible_values_options = possible_values_options(customized)
if possible_values_options.present? if possible_values_options.present?
keyword = keyword.to_s.downcase keyword = keyword.to_s.downcase
if v = possible_values_options.detect {|text, id| text.downcase == keyword} possible_values_options.detect {|text, id| text.downcase == keyword}.try(:last)
if v.is_a?(Array)
v.last
else
v
end
end
else else
keyword keyword
end end
+4 -23
View File
@@ -124,7 +124,6 @@ class MailHandler < ActionMailer::Base
def dispatch def dispatch
headers = [email.in_reply_to, email.references].flatten.compact headers = [email.in_reply_to, email.references].flatten.compact
subject = email.subject.to_s
if headers.detect {|h| h.to_s =~ MESSAGE_ID_RE} if headers.detect {|h| h.to_s =~ MESSAGE_ID_RE}
klass, object_id = $1, $2.to_i klass, object_id = $1, $2.to_i
method_name = "receive_#{klass}_reply" method_name = "receive_#{klass}_reply"
@@ -133,9 +132,9 @@ class MailHandler < ActionMailer::Base
else else
# ignoring it # ignoring it
end end
elsif m = subject.match(ISSUE_REPLY_SUBJECT_RE) elsif m = email.subject.match(ISSUE_REPLY_SUBJECT_RE)
receive_issue_reply(m[1].to_i) receive_issue_reply(m[1].to_i)
elsif m = subject.match(MESSAGE_REPLY_SUBJECT_RE) elsif m = email.subject.match(MESSAGE_REPLY_SUBJECT_RE)
receive_message_reply(m[1].to_i) receive_message_reply(m[1].to_i)
else else
dispatch_to_default dispatch_to_default
@@ -245,26 +244,9 @@ class MailHandler < ActionMailer::Base
def add_attachments(obj) def add_attachments(obj)
if email.attachments && email.attachments.any? if email.attachments && email.attachments.any?
email.attachments.each do |attachment| email.attachments.each do |attachment|
filename = attachment.filename
unless filename.respond_to?(:encoding)
# try to reencode to utf8 manually with ruby1.8
h = attachment.header['Content-Disposition']
unless h.nil?
begin
if m = h.value.match(/filename\*[0-9\*]*=([^=']+)'/)
filename = Redmine::CodesetUtil.to_utf8(filename, m[1])
elsif m = h.value.match(/filename=.*=\?([^\?]+)\?[BbQq]\?/)
# http://tools.ietf.org/html/rfc2047#section-4
filename = Redmine::CodesetUtil.to_utf8(filename, m[1])
end
rescue
# nop
end
end
end
obj.attachments << Attachment.create(:container => obj, obj.attachments << Attachment.create(:container => obj,
:file => attachment.decoded, :file => attachment.decoded,
:filename => filename, :filename => attachment.filename,
:author => user, :author => user,
:content_type => attachment.mime_type) :content_type => attachment.mime_type)
end end
@@ -391,8 +373,7 @@ class MailHandler < ActionMailer::Base
# try to reencode to utf8 manually with ruby1.8 # try to reencode to utf8 manually with ruby1.8
begin begin
if h = email.header[:subject] if h = email.header[:subject]
# http://tools.ietf.org/html/rfc2047#section-4 if m = h.value.match(/^=\?([^\?]+)\?/)
if m = h.value.match(/=\?([^\?]+)\?[BbQq]\?/)
subject = Redmine::CodesetUtil.to_utf8(subject, m[1]) subject = Redmine::CodesetUtil.to_utf8(subject, m[1])
end end
end end
+3 -3
View File
@@ -30,13 +30,13 @@ class Principal < ActiveRecord::Base
if q.blank? if q.blank?
{} {}
else else
q = q.to_s q = q.to_s.downcase
pattern = "%#{q}%" pattern = "%#{q}%"
sql = "LOWER(login) LIKE LOWER(:p) OR LOWER(firstname) LIKE LOWER(:p) OR LOWER(lastname) LIKE LOWER(:p) OR LOWER(mail) LIKE LOWER(:p)" sql = "LOWER(login) LIKE :p OR LOWER(firstname) LIKE :p OR LOWER(lastname) LIKE :p OR LOWER(mail) LIKE :p"
params = {:p => pattern} params = {:p => pattern}
if q =~ /^(.+)\s+(.+)$/ if q =~ /^(.+)\s+(.+)$/
a, b = "#{$1}%", "#{$2}%" a, b = "#{$1}%", "#{$2}%"
sql << " OR (LOWER(firstname) LIKE LOWER(:a) AND LOWER(lastname) LIKE LOWER(:b)) OR (LOWER(firstname) LIKE LOWER(:b) AND LOWER(lastname) LIKE LOWER(:a))" sql << " OR (LOWER(firstname) LIKE :a AND LOWER(lastname) LIKE :b) OR (LOWER(firstname) LIKE :b AND LOWER(lastname) LIKE :a)"
params.merge!(:a => a, :b => b) params.merge!(:a => a, :b => b)
end end
{:conditions => [sql, params]} {:conditions => [sql, params]}
-4
View File
@@ -427,9 +427,5 @@ class Repository < ActiveRecord::Base
connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})") connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}") connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
clear_extra_info_of_changesets
end
def clear_extra_info_of_changesets
end end
end end
-11
View File
@@ -255,15 +255,4 @@ class Repository::Git < Repository
:order => 'committed_on DESC' :order => 'committed_on DESC'
) )
end end
def clear_extra_info_of_changesets
return if extra_info.nil?
v = extra_info["extra_report_last_commit"]
write_attribute(:extra_info, nil)
h = {}
h["extra_report_last_commit"] = v
merge_extra_info(h)
self.save
end
private :clear_extra_info_of_changesets
end end
-7
View File
@@ -33,7 +33,6 @@ class Version < ActiveRecord::Base
validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :not_a_date, :allow_nil => true validates_format_of :effective_date, :with => /^\d{4}-\d{2}-\d{2}$/, :message => :not_a_date, :allow_nil => true
validates_inclusion_of :status, :in => VERSION_STATUSES validates_inclusion_of :status, :in => VERSION_STATUSES
validates_inclusion_of :sharing, :in => VERSION_SHARINGS validates_inclusion_of :sharing, :in => VERSION_SHARINGS
validate :validate_version
scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}} scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}}
scope :open, :conditions => {:status => 'open'} scope :open, :conditions => {:status => 'open'}
@@ -276,10 +275,4 @@ class Version < ActiveRecord::Base
progress progress
end end
end end
def validate_version
if effective_date.nil? && @attributes['effective_date'].present?
errors.add :effective_date, :not_a_date
end
end
end end
+1 -1
View File
@@ -3,6 +3,6 @@
<% if @message.present? %> <% if @message.present? %>
<p id="errorExplanation"><%=h @message %></p> <p id="errorExplanation"><%=h @message %></p>
<% end %> <% end %>
<p><a href="javascript:history.back()"><%= l(:button_back) %></a></p> <p><a href="javascript:history.back()">Back</a></p>
<% html_title @status %> <% html_title @status %>
+1 -1
View File
@@ -19,7 +19,7 @@
<tr class="group open"> <tr class="group open">
<td colspan="<%= query.columns.size + 2 %>"> <td colspan="<%= query.columns.size + 2 %>">
<span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span> <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
<%= group.blank? ? l(:label_none) : column_content(@query.group_by_column, issue) %> <span class="count">(<%= @issue_count_by_group[group] %>)</span> <%= group.blank? ? 'None' : column_content(@query.group_by_column, issue) %> <span class="count">(<%= @issue_count_by_group[group] %>)</span>
<%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}", "toggleAllRowGroups(this)", :class => 'toggle-all') %> <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}", "toggleAllRowGroups(this)", :class => 'toggle-all') %>
</td> </td>
</tr> </tr>
+1 -7
View File
@@ -1,8 +1,2 @@
$("#journal-<%= @journal.id %>-notes").hide(); $("#journal-<%= @journal.id %>-notes").hide();
$("#journal-<%= @journal.id %>-notes").after('<%= escape_javascript(render :partial => 'notes_form') %>');
if ($("form#journal-<%= @journal.id %>-form").length > 0) {
// journal edit form already loaded
$("#journal-<%= @journal.id %>-form").show();
} else {
$("#journal-<%= @journal.id %>-notes").after('<%= escape_javascript(render :partial => 'notes_form') %>');
}
@@ -14,7 +14,7 @@
<tr class="<%= cycle 'odd', 'even' %>"> <tr class="<%= cycle 'odd', 'even' %>">
<td> <td>
<%= link_to repository.identifier, <%= link_to repository.identifier,
{:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier.present? %> {:controller => 'repositories', :action => 'show',:id => @project, :repository_id => repository.identifier_param} if repository.identifier_param.present? %>
</td> </td>
<td align="center"><%= checked_image repository.is_default? %></td> <td align="center"><%= checked_image repository.is_default? %></td>
<td><%=h repository.scm_name %></td> <td><%=h repository.scm_name %></td>
+1 -2
View File
@@ -1,8 +1,7 @@
<div class="contextual"> <div class="contextual">
<%= form_tag( <%= form_tag(
{:controller => 'repositories', :action => 'revision', :id => @project, {:controller => 'repositories', :action => 'revision', :id => @project,
:repository_id => @repository.identifier_param}, :repository_id => @repository.identifier_param}
:method => :get
) do %> ) do %>
<%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 8 %> <%= l(:label_revision) %>: <%= text_field_tag 'rev', @rev, :size => 8 %>
<%= submit_tag 'OK' %> <%= submit_tag 'OK' %>
+11 -11
View File
@@ -844,7 +844,7 @@ de:
button_show: Anzeigen button_show: Anzeigen
status_active: aktiv status_active: aktiv
status_registered: nicht aktivierte status_registered: angemeldet
status_locked: gesperrt status_locked: gesperrt
version_status_open: offen version_status_open: offen
@@ -1017,8 +1017,8 @@ de:
description_date_from: Startdatum eintragen description_date_from: Startdatum eintragen
description_date_to: Enddatum eintragen description_date_to: Enddatum eintragen
label_parent_revision: Vorgänger label_parent_revision: Parent
label_child_revision: Nachfolger label_child_revision: Child
error_scm_annotate_big_text_file: Der Eintrag kann nicht umgesetzt werden, da er die maximale Textlänge überschreitet. error_scm_annotate_big_text_file: Der Eintrag kann nicht umgesetzt werden, da er die maximale Textlänge überschreitet.
setting_default_issue_start_date_to_creation_date: Aktuelles Datum als Beginn für neue Tickets verwenden setting_default_issue_start_date_to_creation_date: Aktuelles Datum als Beginn für neue Tickets verwenden
button_edit_section: Diesen Bereich bearbeiten button_edit_section: Diesen Bereich bearbeiten
@@ -1068,14 +1068,14 @@ de:
field_timeout: Auszeit (in Sekunden) field_timeout: Auszeit (in Sekunden)
setting_thumbnails_enabled: Vorschaubilder von Dateianhängen anzeigen setting_thumbnails_enabled: Vorschaubilder von Dateianhängen anzeigen
setting_thumbnails_size: Größe der Vorschaubilder (in Pixel) setting_thumbnails_size: Größe der Vorschaubilder (in Pixel)
label_status_transitions: Statusänderungen label_status_transitions: Status transitions
label_fields_permissions: Feldberechtigungen label_fields_permissions: Fields permissions
label_readonly: Nur-Lese-Zugriff label_readonly: Nur-Lese-Zugriff
label_required: Erforderlich label_required: Erforderlich
text_repository_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt.<br />Einmal gespeichert, kann die Kennung nicht mehr geändert werden.' text_repository_identifier_info: 'Kleinbuchstaben (a-z), Ziffern, Binde- und Unterstriche erlaubt.<br />Einmal gespeichert, kann die Kennung nicht mehr geändert werden.'
field_board_parent: Übergeordnetes Forum field_board_parent: Parent forum
label_attribute_of_project: "%{name} des Projekts" label_attribute_of_project: Project's %{name}
label_attribute_of_author: "%{name} des Autors" label_attribute_of_author: Author's %{name}
label_attribute_of_assigned_to: "%{name} des Bearbeiters" label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: "%{name} der Zielversion" label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: Unteraufgaben kopieren label_copy_subtasks: Copy subtasks
+50 -50
View File
@@ -49,7 +49,7 @@ nl:
one: "ongeveer 1 uur" one: "ongeveer 1 uur"
other: "ongeveer %{count} uren" other: "ongeveer %{count} uren"
x_hours: x_hours:
one: "1 uur" one: "1 hour"
other: "%{count} hours" other: "%{count} hours"
x_days: x_days:
one: "1 dag" one: "1 dag"
@@ -990,58 +990,58 @@ nl:
description_all_columns: Alle kolommen description_all_columns: Alle kolommen
button_export: Exporteren button_export: Exporteren
label_export_options: "%{export_format} export opties" label_export_options: "%{export_format} export opties"
error_attachment_too_big: Dit bestand kan niet worden geupload omdat het de maximaal toegestane grootte overschrijd (%{max_size}) 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: "Opslaan gefaald voor %{count} tijdsnotatie(s) van %{total} geselecteerde: %{ids}." notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
label_x_issues: label_x_issues:
zero: 0 incidenten zero: 0 issue
one: 1 incidenten one: 1 issue
other: "%{count} incidenten" other: "%{count} issues"
label_repository_new: Nieuw repository label_repository_new: New repository
field_repository_is_default: Hoofd repository field_repository_is_default: Main repository
label_copy_attachments: Copieer bijlage(n) label_copy_attachments: Copy attachments
label_item_position: "%{position}/%{count}" label_item_position: "%{position}/%{count}"
label_completed_versions: Versies compleet label_completed_versions: Completed versions
field_multiple: Meerdere waardes field_multiple: Multiple values
setting_commit_cross_project_ref: Sta toe om incidenten van alle projecten te refereren en oplossen setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
text_issue_conflict_resolution_add_notes: Voeg mijn notities toe en annuleer andere wijzigingen text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes
text_issue_conflict_resolution_overwrite: Voeg mijn wijzigingen alsnog toe (voorgaande notities worden bewaard, maar sommige kunnen overschreden worden) text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
notice_issue_update_conflict: Dit incident is reeds geupdate door een andere gebruiker terwijl jij bezig was notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
text_issue_conflict_resolution_cancel: Annuleer mijn wijzigingen en geef pagina opnieuw weer %{link} text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
permission_manage_related_issues: Beheer gerelateerde incidenten permission_manage_related_issues: Manage related issues
field_auth_source_ldap_filter: LDAP filter field_auth_source_ldap_filter: LDAP filter
label_search_for_watchers: Zoek om monitoorders toe te voegen label_search_for_watchers: Search for watchers to add
notice_account_deleted: Uw account is permanent verwijderd notice_account_deleted: Your account has been permanently deleted.
setting_unsubscribe: Sta gebruikers toe hun eigen account te verwijderen setting_unsubscribe: Allow users to delete their own account
button_delete_my_account: Verwijder mijn account button_delete_my_account: Delete my account
text_account_destroy_confirmation: |- text_account_destroy_confirmation: |-
Weet u zeker dat u door wilt gaan? Are you sure you want to proceed?
Uw account wordt permanent verwijderd zonder mogelijkheid deze te heractiveren. Your account will be permanently deleted, with no way to reactivate it.
error_session_expired: Uw sessie is verlopen. U dient opnieuw in te loggen. error_session_expired: Your session has expired. Please login again.
text_session_expiration_settings: "Waarschuwing: door deze instelling te wijzigen kan sessies laten verlopen inclusief de uwe" text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
setting_session_lifetime: Maximale sessieduur setting_session_lifetime: Session maximum lifetime
setting_session_timeout: Sessie inactiviteit timeout setting_session_timeout: Session inactivity timeout
label_session_expiration: Sessie verlopen label_session_expiration: Session expiration
permission_close_project: Sluit / heropen project permission_close_project: Close / reopen the project
label_show_closed_projects: Gesloten projecten weergeven label_show_closed_projects: View closed projects
button_close: Sluiten button_close: Close
button_reopen: Heropen button_reopen: Reopen
project_status_active: actief project_status_active: active
project_status_closed: gesloten project_status_closed: closed
project_status_archived: gearchiveerd project_status_archived: archived
text_project_closed: Dit project is gesloten en op alleen-lezen text_project_closed: This project is closed and read-only.
notice_user_successful_create: Gebruiker %{id} aangemaakt. notice_user_successful_create: User %{id} created.
field_core_fields: Standaard verleden field_core_fields: Standard fields
field_timeout: Timeout (in seconds) field_timeout: Timeout (in seconds)
setting_thumbnails_enabled: Geef bijlage miniaturen weer setting_thumbnails_enabled: Display attachment thumbnails
setting_thumbnails_size: Grootte miniaturen (in pixels) setting_thumbnails_size: Thumbnails size (in pixels)
label_status_transitions: Status transitie label_status_transitions: Status transitions
label_fields_permissions: Permissie velden label_fields_permissions: Fields permissions
label_readonly: Alleen-lezen label_readonly: Read-only
label_required: Verplicht label_required: Required
text_repository_identifier_info: 'Alleen kleine letter (a-z), cijfers, streepjes en liggende streepjes zijn toegestaan.<br />Eenmaal opgeslagen kan de identifier niet worden gewijzigd.' text_repository_identifier_info: 'Alleen kleine letter (a-z), cijfers, streepjes en liggende streepjes zijn toegestaan.<br />Eenmaal opgeslagen kan de identifier niet worden gewijzigd.'
field_board_parent: Hoofd forum field_board_parent: Parent forum
label_attribute_of_project: Project %{name} label_attribute_of_project: Project's %{name}
label_attribute_of_author: Auteur(s) %{name} label_attribute_of_author: Author's %{name}
label_attribute_of_assigned_to: Toegewezen %{name} label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: Target versions %{name} label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: Kopieer subtaken label_copy_subtasks: Copy subtasks
+35 -35
View File
@@ -971,64 +971,64 @@
setting_issue_group_assignment: Tillat tildeling av saker til grupper setting_issue_group_assignment: Tillat tildeling av saker til grupper
label_diff: diff label_diff: diff
description_query_sort_criteria_direction: Sorteringsretning description_query_sort_criteria_direction: Sort direction
description_project_scope: Search scope description_project_scope: Search scope
description_filter: Filter description_filter: Filter
description_user_mail_notification: Mail notification settings description_user_mail_notification: Mail notification settings
description_date_from: Oppgi startdato description_date_from: Enter start date
description_message_content: Meldingsinnhold description_message_content: Message content
description_available_columns: Tilgjengelige kolonner description_available_columns: Available Columns
description_date_range_interval: Velg datointervall ved å spesifisere start- og sluttdato description_date_range_interval: Choose range by selecting start and end date
description_issue_category_reassign: Choose issue category description_issue_category_reassign: Choose issue category
description_search: Søkefelt description_search: Searchfield
description_notes: Notes description_notes: Notes
description_date_range_list: Choose range from list description_date_range_list: Choose range from list
description_choose_project: Prosjekter description_choose_project: Projects
description_date_to: Oppgi sluttdato description_date_to: Enter end date
description_query_sort_criteria_attribute: Sort attribute description_query_sort_criteria_attribute: Sort attribute
description_wiki_subpages_reassign: Velg ny overordnet side description_wiki_subpages_reassign: Choose new parent page
description_selected_columns: Valgte kolonner description_selected_columns: Selected Columns
label_parent_revision: Overordnet label_parent_revision: Parent
label_child_revision: Underordnet label_child_revision: Child
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size. 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: Bruk dagens dato som startdato for nye saker setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
button_edit_section: Rediger denne seksjonen button_edit_section: Edit this section
setting_repositories_encodings: Attachments and repositories encodings setting_repositories_encodings: Attachments and repositories encodings
description_all_columns: Alle kolonnene description_all_columns: All Columns
button_export: Eksporter button_export: Export
label_export_options: "%{export_format} eksportvalg" label_export_options: "%{export_format} export options"
error_attachment_too_big: Filen overstiger maksimum filstørrelse (%{max_size}) og kan derfor ikke lastes opp 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}." notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
label_x_issues: label_x_issues:
zero: 0 sak zero: 0 sak
one: 1 sak one: 1 sak
other: "%{count} saker" other: "%{count} saker"
label_repository_new: Nytt depot label_repository_new: New repository
field_repository_is_default: Hoveddepot field_repository_is_default: Main repository
label_copy_attachments: Kopier vedlegg label_copy_attachments: Copy attachments
label_item_position: "%{position}/%{count}" label_item_position: "%{position}/%{count}"
label_completed_versions: Completed versions label_completed_versions: Completed versions
text_project_identifier_info: Kun små bokstaver (a-z), tall, bindestrek (-) og "underscore" (_) er tillatt.<br />Etter lagring er det ikke mulig å gjøre endringer. 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: Flere verdier field_multiple: Multiple values
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed 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_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) text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
notice_issue_update_conflict: Saken ble oppdatert av en annen bruker mens du redigerte den. notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
text_issue_conflict_resolution_cancel: Forkast alle endringen mine og vis %{link} på nytt text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
permission_manage_related_issues: Manage related issues permission_manage_related_issues: Manage related issues
field_auth_source_ldap_filter: LDAP filter field_auth_source_ldap_filter: LDAP filter
label_search_for_watchers: Search for watchers to add label_search_for_watchers: Search for watchers to add
notice_account_deleted: Din konto er ugjenkallelig slettet. notice_account_deleted: Your account has been permanently deleted.
setting_unsubscribe: Tillat brukere å slette sin egen konto setting_unsubscribe: Allow users to delete their own account
button_delete_my_account: Slett kontoen min button_delete_my_account: Delete my account
text_account_destroy_confirmation: |- text_account_destroy_confirmation: |-
Er du sikker på at du ønsker å fortsette? Are you sure you want to proceed?
Kontoen din vil bli ugjenkallelig slettet uten mulighet for å reaktiveres igjen. Your account will be permanently deleted, with no way to reactivate it.
error_session_expired: Økten har gått ut på tid. Vennligst logg på igjen. error_session_expired: Your session has expired. Please login again.
text_session_expiration_settings: "Advarsel: ved å endre disse innstillingene kan aktive økter gå ut på tid, inkludert din egen." text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
setting_session_lifetime: Øktenes makslengde setting_session_lifetime: Session maximum lifetime
setting_session_timeout: Økten er avsluttet på grunn av inaktivitet setting_session_timeout: Session inactivity timeout
label_session_expiration: Økten er avsluttet label_session_expiration: Session expiration
permission_close_project: Close / reopen the project permission_close_project: Close / reopen the project
label_show_closed_projects: View closed projects label_show_closed_projects: View closed projects
button_close: Close button_close: Close
+28 -28
View File
@@ -1121,7 +1121,7 @@ ru:
button_export: Экспорт button_export: Экспорт
label_export_options: "%{export_format} параметры экспорта" label_export_options: "%{export_format} параметры экспорта"
error_attachment_too_big: Этот файл нельзя загрузить из-за превышения максимального размера файла (%{max_size}) error_attachment_too_big: Этот файл нельзя загрузить из-за превышения максимального размера файла (%{max_size})
notice_failed_to_save_time_entries: "Невозможно сохранить %{count} затраченное время для %{total} выбранных: %{ids}." notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
label_x_issues: label_x_issues:
zero: 0 Задач zero: 0 Задач
one: 1 Задача one: 1 Задача
@@ -1147,32 +1147,32 @@ ru:
setting_unsubscribe: "Разрешить пользователям удалять свои учетные записи" setting_unsubscribe: "Разрешить пользователям удалять свои учетные записи"
button_delete_my_account: "Удалить мою учетную запись" button_delete_my_account: "Удалить мою учетную запись"
text_account_destroy_confirmation: "Ваша учетная запись будет полностью удалена без возможности восстановления.\nВы уверены, что хотите продолжить?" text_account_destroy_confirmation: "Ваша учетная запись будет полностью удалена без возможности восстановления.\nВы уверены, что хотите продолжить?"
error_session_expired: Срок вашей сессии истек. Пожалуйста войдите еще раз error_session_expired: Your session has expired. Please login again.
text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours." text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
setting_session_lifetime: Максимальная продолжительность сессии setting_session_lifetime: Session maximum lifetime
setting_session_timeout: Таймут сессии setting_session_timeout: Session inactivity timeout
label_session_expiration: Срок истечения сессии label_session_expiration: Session expiration
permission_close_project: Закрывать / открывать проекты permission_close_project: Close / reopen the project
label_show_closed_projects: Просматривать закрытые проекты label_show_closed_projects: View closed projects
button_close: Сделать закрытым button_close: Close
button_reopen: Сделать открытым button_reopen: Reopen
project_status_active: открытые project_status_active: active
project_status_closed: закрытые project_status_closed: closed
project_status_archived: архивированные project_status_archived: archived
text_project_closed: Проект закрыт и находиться в режиме только для чтения. text_project_closed: This project is closed and read-only.
notice_user_successful_create: Пользователь %{id} создан. notice_user_successful_create: User %{id} created.
field_core_fields: Стандартные поля field_core_fields: Standard fields
field_timeout: Таймаут (в секундах) field_timeout: Timeout (in seconds)
setting_thumbnails_enabled: Отображать превью для приложений setting_thumbnails_enabled: Display attachment thumbnails
setting_thumbnails_size: Размер первью (в пикселях) setting_thumbnails_size: Thumbnails size (in pixels)
label_status_transitions: Статус-переходы label_status_transitions: Status transitions
label_fields_permissions: Права на изменения полей label_fields_permissions: Fields permissions
label_readonly: Не изменяется label_readonly: Read-only
label_required: Обязательное label_required: Required
text_repository_identifier_info: Допускаются только строчные латинские буквы (a-z), цифры, тире и подчеркивания.<br />После сохранения идентификатор изменить нельзя. text_repository_identifier_info: Допускаются только строчные латинские буквы (a-z), цифры, тире и подчеркивания.<br />После сохранения идентификатор изменить нельзя.
field_board_parent: Родительский форум field_board_parent: Parent forum
label_attribute_of_project: Проект %{name} label_attribute_of_project: Project's %{name}
label_attribute_of_author: Имя автора %{name} label_attribute_of_author: Author's %{name}
label_attribute_of_assigned_to: Назначена %{name} label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: Версия %{name} label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: Копировать подзадачи label_copy_subtasks: Copy subtasks
+6 -6
View File
@@ -1061,9 +1061,9 @@ zh:
label_readonly: 只读 label_readonly: 只读
label_required: 必填 label_required: 必填
text_repository_identifier_info: 仅小写字母(a-z)、数字、破折号(-)和下划线(_)可以使用。<br />一旦保存,标识无法修改。 text_repository_identifier_info: 仅小写字母(a-z)、数字、破折号(-)和下划线(_)可以使用。<br />一旦保存,标识无法修改。
field_board_parent: 父论坛 field_board_parent: Parent forum
label_attribute_of_project: 项目 %{name} label_attribute_of_project: Project's %{name}
label_attribute_of_author: 作者 %{name} label_attribute_of_author: Author's %{name}
label_attribute_of_assigned_to: 分配给 %{name} label_attribute_of_assigned_to: Assignee's %{name}
label_attribute_of_fixed_version: 目标版本 %{name} label_attribute_of_fixed_version: Target version's %{name}
label_copy_subtasks: 复制子任务 label_copy_subtasks: Copy subtasks
-40
View File
@@ -4,46 +4,6 @@ Redmine - project management software
Copyright (C) 2006-2012 Jean-Philippe Lang Copyright (C) 2006-2012 Jean-Philippe Lang
http://www.redmine.org/ http://www.redmine.org/
== 2012-12-18 v2.1.5
* Defect #12400: Validation fails when receiving an email with list custom fields
* Defect #12451: Macros.rb extract_macro_options should use lazy search
* Defect #12513: Grouping of issues by custom fields not correct in PDF export
* Defect #12566: Issue history notes previews are broken
* Defect #12568: Clicking "edit" on a journal multiple times shows multiple forms
* Patch #12605: Norwegian translation for 1.4-stable update
* Patch #12614: Dutch translation
* Patch #12615: Russian translation
== 2012-11-24 v2.1.4
* Defect #12274: Wiki export from Index by title is truncated
* Defect #12298: Right-click context menu unable to batch/bulk update (IE8)
* Defect #12332: Repository identifier does not display on Project/Settings/Repositories
* Defect #12396: Error when receiving an email without subject header
* Defect #12399: Non ASCII attachment filename encoding broken (MOJIBAKE) in receiving mail on Ruby 1.8
* Defect #12409: Git: changesets aren't read after clear_changesets call
* Defect #12431: Project.rebuild! sorts root projects by id instead of name
== 2012-11-17 v2.1.3
* Defect #12050: :export links to repository files lead to a 404 error
* Defect #12189: Missing tmp/pdf directory
* Defect #12195: Javascript error with IE7 / IE8 on new issue form
* Defect #12196: "Page not found" on OK button in SCM "View all revisions" page
* Defect #12199: Confirmation message displayed when clicking a disabled delete link in the context menu
* Defect #12231: Hardcoded "Back" in Repository
* Defect #12294: Incorrect german translation for "registered" users filter
* Defect #12349: Watchers auto-complete search on non-latin chars
* Defect #12358: 'None' grouped issue list section should be translated
* Defect #12359: Version date field regex validation accepts invalid date
* Defect #12375: Receiving mail subject encoding broken (MOJIBAKE) in some cases on Ruby 1.8
* Patch #9732: German translations
* Patch #12021: Russian locale translations
* Patch #12188: Simplified Chinese translation with zh.yml file based on Rev:10681
* Patch #12235: German translation for 2.1-stable
* Patch #12237: Added German Translation
== 2012-09-30 v2.1.2 == 2012-09-30 v2.1.2
* Defect #11929: XSS vulnerability in Redmine 2.1.x * Defect #11929: XSS vulnerability in Redmine 2.1.x
@@ -30,7 +30,7 @@ module Redmine
attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym attachable_options[:delete_permission] = options.delete(:delete_permission) || "edit_#{self.name.pluralize.underscore}".to_sym
has_many :attachments, options.merge(:as => :container, has_many :attachments, options.merge(:as => :container,
:order => "#{Attachment.table_name}.created_on ASC, #{Attachment.table_name}.id ASC", :order => "#{Attachment.table_name}.created_on",
:dependent => :destroy) :dependent => :destroy)
send :include, Redmine::Acts::Attachable::InstanceMethods send :include, Redmine::Acts::Attachable::InstanceMethods
before_save :attach_saved_attachments before_save :attach_saved_attachments
@@ -62,19 +62,7 @@ module Redmine
def save_attachments(attachments, author=User.current) def save_attachments(attachments, author=User.current)
if attachments.is_a?(Hash) if attachments.is_a?(Hash)
attachments = attachments.stringify_keys attachments = attachments.values
attachments = attachments.to_a.sort {|a, b|
if a.first.to_i > 0 && b.first.to_i > 0
a.first.to_i <=> b.first.to_i
elsif a.first.to_i > 0
1
elsif b.first.to_i > 0
-1
else
a.first <=> b.first
end
}
attachments = attachments.map(&:last)
end end
if attachments.is_a?(Array) if attachments.is_a?(Array)
attachments.each do |attachment| attachments.each do |attachment|
@@ -186,7 +186,7 @@ module CollectiveIdea #:nodoc:
end end
# Find root node(s) # Find root node(s)
root_nodes = where("#{quoted_parent_column_name} IS NULL").order(acts_as_nested_set_options[:order]).each do |root_node| root_nodes = where("#{quoted_parent_column_name} IS NULL").order("#{quoted_left_column_name}, #{quoted_right_column_name}, id").each do |root_node|
# setup index for this scope # setup index for this scope
indices[scope.call(root_node)] ||= 0 indices[scope.call(root_node)] ||= 0
set_left_and_rights.call(root_node) set_left_and_rights.call(root_node)
+1 -1
View File
@@ -422,7 +422,7 @@ module Redmine
if query.grouped? && if query.grouped? &&
(group = query.group_by_column.value(issue)) != previous_group (group = query.group_by_column.value(issue)) != previous_group
pdf.SetFontStyle('B',10) pdf.SetFontStyle('B',10)
group_label = group.blank? ? 'None' : group.to_s.dup group_label = group.blank? ? 'None' : group.to_s
group_label << " (#{query.issue_count_by_group[group]})" group_label << " (#{query.issue_count_by_group[group]})"
pdf.Bookmark group_label, 0, -1 pdf.Bookmark group_label, 0, -1
pdf.RDMCell(table_width + col_id_width, row_height * 2, group_label, 1, 1, 'L') pdf.RDMCell(table_width + col_id_width, row_height * 2, group_label, 1, 1, 'L')
+1 -1
View File
@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc: module VERSION #:nodoc:
MAJOR = 2 MAJOR = 2
MINOR = 1 MINOR = 1
TINY = 5 TINY = 2
# Branch values: # Branch values:
# * official release: nil # * official release: nil
+1 -1
View File
@@ -48,7 +48,7 @@ module Redmine
def extract_macro_options(args, *keys) def extract_macro_options(args, *keys)
options = {} options = {}
while args.last.to_s.strip =~ %r{^(.+?)\=(.+)$} && keys.include?($1.downcase.to_sym) while args.last.to_s.strip =~ %r{^(.+)\=(.+)$} && keys.include?($1.downcase.to_sym)
options[$1.downcase.to_sym] = $2 options[$1.downcase.to_sym] = $2
args.pop args.pop
end end
+3 -5
View File
@@ -464,11 +464,9 @@ function updateBulkEditFrom(url) {
} }
function observeAutocompleteField(fieldId, url) { function observeAutocompleteField(fieldId, url) {
$(document).ready(function() { $('#'+fieldId).autocomplete({
$('#'+fieldId).autocomplete({ source: url,
source: url, minLength: 2,
minLength: 2
});
}); });
} }
+1 -1
View File
@@ -25,7 +25,7 @@ function contextMenuClick(event) {
} }
contextMenuHide(); contextMenuHide();
if (target.is('a') || target.is('img')) { return; } if (target.is('a') || target.is('img')) { return; }
if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) { if (event.which == 1 /*TODO || (navigator.appVersion.match(/\bMSIE\b/))*/) {
var tr = target.parents('tr').first(); var tr = target.parents('tr').first();
if (tr.length && tr.hasClass('hascontextmenu')) { if (tr.length && tr.hasClass('hascontextmenu')) {
// a row was clicked, check if the click was on checkbox // a row was clicked, check if the click was on checkbox
@@ -1,26 +0,0 @@
Date: Tue, 20 Nov 2012 23:08:25 +0900
Message-ID: <CANBr5-UZM=Odz4U3Q6vHd_9cd2tCT-_P9xDd=hRJ0aoMNTWXbw@mail.gmail.com>
Subject: test
From: John Smith <JSmith@somenet.foo>
To: redmine@somenet.foo
Content-Type: multipart/mixed; boundary=14dae93a13bf76ca5d04ceedc458
--14dae93a13bf76ca5d04ceedc458
Content-Type: text/plain; charset=ISO-8859-1
test
--14dae93a13bf76ca5d04ceedc458
Content-Type: text/plain; charset=US-ASCII;
name="=?ISO-8859-1?B?xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tw=?=
=?ISO-8859-1?B?/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc?=
=?ISO-8859-1?B?/MTk1vbc/C50eHQ=?="
Content-Disposition: attachment;
filename="=?ISO-8859-1?B?xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tz8xOTW9tw=?=
=?ISO-8859-1?B?/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc/MTk1vbc?=
=?ISO-8859-1?B?/MTk1vbc/C50eHQ=?="
Content-Transfer-Encoding: base64
X-Attachment-Id: f_h9r3mcjz0
dGVzdAo=
--14dae93a13bf76ca5d04ceedc458--
-20
View File
@@ -1,20 +0,0 @@
Date: Mon, 19 Nov 2012 10:17:45 +0900
Message-ID: <CANBr5-U6cXMfLek5QiB2ZrBPR3vTThn9_Upvdkf3Dkod664+Xw@mail.gmail.com>
Subject: test
From: John Smith <JSmith@somenet.foo>
To: redmine@somenet.foo
Content-Type: multipart/mixed; boundary=bcaec54ee4ea84f77904cecee22e
--bcaec54ee4ea84f77904cecee22e
Content-Type: text/plain; charset=ISO-8859-1
test
--bcaec54ee4ea84f77904cecee22e
Content-Type: text/plain; charset=US-ASCII; name="=?ISO-2022-JP?B?GyRCJUYlOSVIGyhCLnR4dA==?="
Content-Disposition: attachment; filename="=?ISO-2022-JP?B?GyRCJUYlOSVIGyhCLnR4dA==?="
Content-Transfer-Encoding: base64
X-Attachment-Id: f_h9owndpv0
dGVzdAo=
--bcaec54ee4ea84f77904cecee22e--
-10
View File
@@ -1,10 +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>
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
-7
View File
@@ -1,7 +0,0 @@
From: John Smith <JSmith@somenet.foo>
To: "redmine@somenet.foo" <redmine@somenet.foo>
Subject: =?iso-2022-jp?b?GyRCJUYlOSVIGyhCCg=?=
Date: Fri, 1 Jun 2012 14:39:38 +0200
Message-ID: <87C31D42249DD0489D1A1444E3232DD7019D6183@foo.bar>
Fixture
-7
View File
@@ -1,7 +0,0 @@
From: John Smith <JSmith@somenet.foo>
To: "redmine@somenet.foo" <redmine@somenet.foo>
Subject: Re: =?iso-2022-jp?b?GyRCJUYlOSVIGyhCCg=?=
Date: Fri, 1 Jun 2012 14:39:38 +0200
Message-ID: <87C31D42249DD0489D1A1444E3232DD7019D6183@foo.bar>
Fixture
@@ -1,34 +0,0 @@
Message-ID: <50AB9546.7020800@gmail.com>
Date: Tue, 20 Nov 2012 23:35:50 +0900
From: John Smith <JSmith@somenet.foo>
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc13 Thunderbird/3.1.10
MIME-Version: 1.0
To: redmine@somenet.foo
Subject: test
Content-Type: multipart/mixed;
boundary="------------050902080306030406090208"
This is a multi-part message in MIME format.
--------------050902080306030406090208
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
test
--------------050902080306030406090208
Content-Type: image/png;
name="=?ISO-8859-1?Q?=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4?=
=?ISO-8859-1?Q?=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6?=
=?ISO-8859-1?Q?=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6=DC=FC=C4=E4=D6=F6?=
=?ISO-8859-1?Q?=DC=FC=C4=E4=D6=F6=DC=FC=2Epng?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename*0*=ISO-8859-1''%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6;
filename*1*=%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC;
filename*2*=%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%C4%E4;
filename*3*=%D6%F6%DC%FC%C4%E4%D6%F6%DC%FC%2E%70%6E%67
iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlz
AAALEwAACxMBAJqcGAAAAAd0SU1FB9wLFA4fJhRKIUQAAAAUSURBVAjXY/z//z8DEmBiQAWk
8gHq9gMHP8uZWAAAAABJRU5ErkJggg==
--------------050902080306030406090208--
@@ -1,26 +0,0 @@
Message-ID: <50AA00C6.4070108@gmail.com>
Date: Mon, 19 Nov 2012 18:49:58 +0900
From: John Smith <JSmith@somenet.foo>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.15) Gecko/20101027 Fedora/3.0.10-1.fc12 Lightning/1.0b1 Thunderbird/3.0.10
MIME-Version: 1.0
To: redmine@somenet.foo
Subject: test
Content-Type: multipart/mixed;
boundary="------------030104060902010800050907"
This is a multi-part message in MIME format.
--------------030104060902010800050907
Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit
test
--------------030104060902010800050907
Content-Type: text/plain;
name="=?ISO-2022-JP?B?GyRCJUYlOSVIGyhCLnR4dA==?="
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename*=ISO-2022-JP''%1B%24%42%25%46%25%39%25%48%1B%28%42%2E%74%78%74
dGVzdAo=
--------------030104060902010800050907--
@@ -39,4 +39,3 @@ pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
category: Stock management category: Stock management
searchable field: Value for a custom field searchable field: Value for a custom field
Database: postgresql
@@ -532,21 +532,6 @@ class RepositoriesGitControllerTest < ActionController::TestCase
end end
end end
def test_revisions
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets
@project.reload
assert_equal NUM_REV, @repository.changesets.count
get :revisions, :id => PRJ_ID
assert_response :success
assert_template 'revisions'
assert_tag :tag => 'form',
:attributes => {
:method => 'get',
:action => '/projects/subproject1/repository/revision'
}
end
def test_revision def test_revision
assert_equal 0, @repository.changesets.count assert_equal 0, @repository.changesets.count
@repository.fetch_changesets @repository.fetch_changesets
-1
View File
@@ -25,7 +25,6 @@ class ApiTest::IssuesTest < ActionController::IntegrationTest
:member_roles, :member_roles,
:issues, :issues,
:issue_statuses, :issue_statuses,
:issue_relations,
:versions, :versions,
:trackers, :trackers,
:projects_trackers, :projects_trackers,
-2
View File
@@ -61,8 +61,6 @@ module ObjectHelpers
def Issue.generate!(attributes={}) def Issue.generate!(attributes={})
issue = Issue.new(attributes) issue = Issue.new(attributes)
issue.project ||= Project.find(1)
issue.tracker ||= issue.project.trackers.first
issue.subject = 'Generated' if issue.subject.blank? issue.subject = 'Generated' if issue.subject.blank?
issue.author ||= User.find(2) issue.author ||= User.find(2)
yield issue if block_given? yield issue if block_given?
-5
View File
@@ -212,9 +212,4 @@ class CustomFieldTest < ActiveSupport::TestCase
assert_nil CustomField.new(:field_format => 'text').value_class assert_nil CustomField.new(:field_format => 'text').value_class
assert_nil CustomField.new.value_class assert_nil CustomField.new.value_class
end end
def test_value_from_keyword_for_list_custom_field
field = CustomField.find(1)
assert_equal 'PostgreSQL', field.value_from_keyword('postgresql', Issue.find(1))
end
end end
+8 -19
View File
@@ -253,15 +253,8 @@ RAW
project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'} project_url = {:controller => 'projects', :action => 'show', :id => 'subproject1'}
source_url = '/projects/ecookbook/repository/entry/some/file' source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
source_url_with_rev = '/projects/ecookbook/repository/revisions/52/entry/some/file' source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
source_url_with_ext = '/projects/ecookbook/repository/entry/some/file.ext'
source_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/entry/some/file.ext'
export_url = '/projects/ecookbook/repository/raw/some/file'
export_url_with_rev = '/projects/ecookbook/repository/revisions/52/raw/some/file'
export_url_with_ext = '/projects/ecookbook/repository/raw/some/file.ext'
export_url_with_rev_and_ext = '/projects/ecookbook/repository/revisions/52/raw/some/file.ext'
to_test = { to_test = {
# tickets # tickets
@@ -291,16 +284,12 @@ RAW
'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".", 'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".", 'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",", 'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
'source:/some/file@52' => link_to('source:/some/file@52', source_url_with_rev, :class => 'source'), 'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_rev_and_ext, :class => 'source'), 'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
'source:/some/file#L110' => link_to('source:/some/file#L110', source_url + "#L110", :class => 'source'), 'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext + "#L110", :class => 'source'), 'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url_with_rev + "#L110", :class => 'source'), 'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
# export 'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
'export:/some/file' => link_to('export:/some/file', export_url, :class => 'source download'),
'export:/some/file.ext' => link_to('export:/some/file.ext', export_url_with_ext, :class => 'source download'),
'export:/some/file@52' => link_to('export:/some/file@52', export_url_with_rev, :class => 'source download'),
'export:/some/file.ext@52' => link_to('export:/some/file.ext@52', export_url_with_rev_and_ext, :class => 'source download'),
# forum # forum
'forum#2' => link_to('Discussion', board_url, :class => 'board'), 'forum#2' => link_to('Discussion', board_url, :class => 'board'),
'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'), 'forum:Discussion' => link_to('Discussion', board_url, :class => 'board'),
+29 -33
View File
@@ -109,55 +109,51 @@ class IssuesHelperTest < ActionView::TestCase
end end
end end
context "with a start_date attribute" do def test_with_a_start_date_attribute_should_format_the_current_date
should "format the current date" do @detail = JournalDetail.new(
@detail = JournalDetail.new(
:property => 'attr', :property => 'attr',
:old_value => '2010-01-01', :old_value => '2010-01-01',
:value => '2010-01-31', :value => '2010-01-31',
:prop_key => 'start_date' :prop_key => 'start_date'
) )
with_settings :date_format => '%m/%d/%Y' do with_settings :date_format => '%m/%d/%Y' do
assert_match "01/31/2010", show_detail(@detail, true) assert_match "01/31/2010", show_detail(@detail, true)
end
end
should "format the old date" do
@detail = JournalDetail.new(
:property => 'attr',
:old_value => '2010-01-01',
:value => '2010-01-31',
:prop_key => 'start_date'
)
with_settings :date_format => '%m/%d/%Y' do
assert_match "01/01/2010", show_detail(@detail, true)
end
end end
end end
context "with a due_date attribute" do def test_with_a_start_date_attribute_should_format_the_old_date
should "format the current date" do @detail = JournalDetail.new(
@detail = JournalDetail.new( :property => 'attr',
:property => 'attr', :old_value => '2010-01-01',
:old_value => '2010-01-01', :value => '2010-01-31',
:value => '2010-01-31', :prop_key => 'start_date'
:prop_key => 'due_date'
) )
with_settings :date_format => '%m/%d/%Y' do with_settings :date_format => '%m/%d/%Y' do
assert_match "01/31/2010", show_detail(@detail, true) assert_match "01/01/2010", show_detail(@detail, true)
end
end end
end
should "format the old date" do def test_with_a_due_date_attribute_should_with_a_due_date_attribute
@detail = JournalDetail.new( @detail = JournalDetail.new(
:property => 'attr', :property => 'attr',
:old_value => '2010-01-01', :old_value => '2010-01-01',
:value => '2010-01-31', :value => '2010-01-31',
:prop_key => 'due_date' :prop_key => 'due_date'
) )
with_settings :date_format => '%m/%d/%Y' do with_settings :date_format => '%m/%d/%Y' do
assert_match "01/01/2010", show_detail(@detail, true) assert_match "01/31/2010", show_detail(@detail, true)
end end
end
def test_with_a_due_date_attribute_should_format_the_old_date
@detail = JournalDetail.new(
:property => 'attr',
:old_value => '2010-01-01',
:value => '2010-01-31',
:prop_key => 'due_date'
)
with_settings :date_format => '%m/%d/%Y' do
assert_match "01/01/2010", show_detail(@detail, true)
end end
end end
+1 -11
View File
@@ -18,17 +18,7 @@
require File.expand_path('../../test_helper', __FILE__) require File.expand_path('../../test_helper', __FILE__)
class IssueRelationTest < ActiveSupport::TestCase class IssueRelationTest < ActiveSupport::TestCase
fixtures :projects, fixtures :issue_relations, :issues
:users,
:roles,
:members,
:member_roles,
:issues,
:issue_statuses,
:issue_relations,
:enabled_modules,
:enumerations,
:trackers
def test_create def test_create
from = Issue.find(1) from = Issue.find(1)
-14
View File
@@ -1576,18 +1576,4 @@ class IssueTest < ActiveSupport::TestCase
def test_journals_after_with_blank_arg_should_return_all_journals def test_journals_after_with_blank_arg_should_return_all_journals
assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('') assert_equal [Journal.find(1), Journal.find(2)], Issue.find(1).journals_after('')
end end
def test_save_attachments_with_hash_should_save_attachments_in_keys_order
set_tmp_attachments_directory
issue = Issue.generate!
issue.save_attachments({
'p0' => {'file' => mock_file_with_options(:original_filename => 'upload')},
'3' => {'file' => mock_file_with_options(:original_filename => 'bar')},
'1' => {'file' => mock_file_with_options(:original_filename => 'foo')}
})
issue.attach_saved_attachments
assert_equal 3, issue.reload.attachments.count
assert_equal %w(upload foo bar), issue.attachments.map(&:filename)
end
end end
@@ -100,25 +100,6 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(text, :object => Issue.find(1)) assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(text, :object => Issue.find(1))
end end
def test_extract_macro_options_should_with_args
options = extract_macro_options(["arg1", "arg2"], :foo, :size)
assert_equal([["arg1", "arg2"], {}], options)
end
def test_extract_macro_options_should_with_options
options = extract_macro_options(["foo=bar", "size=2"], :foo, :size)
assert_equal([[], {:foo => "bar", :size => "2"}], options)
end
def test_extract_macro_options_should_with_args_and_options
options = extract_macro_options(["arg1", "arg2", "foo=bar", "size=2"], :foo, :size)
assert_equal([["arg1", "arg2"], {:foo => "bar", :size => "2"}], options)
end
def test_extract_macro_options_should_parse_options_lazily
options = extract_macro_options(["params=x=1&y=2"], :params)
assert_equal([[], {:params => "x=1&y=2"}], options)
end
def test_macro_exception_should_be_displayed def test_macro_exception_should_be_displayed
Redmine::WikiFormatting::Macros.macro :exception do |obj, args| Redmine::WikiFormatting::Macros.macro :exception do |obj, args|
+2 -107
View File
@@ -177,8 +177,8 @@ class MailHandlerTest < ActiveSupport::TestCase
assert !issue.new_record? assert !issue.new_record?
issue.reload issue.reload
assert_equal 'New ticket with custom field values', issue.subject assert_equal 'New ticket with custom field values', issue.subject
assert_equal 'PostgreSQL', issue.custom_field_value(1) assert_equal 'Value for a custom field',
assert_equal 'Value for a custom field', issue.custom_field_value(2) issue.custom_value_for(CustomField.find_by_name('Searchable field')).value
assert !issue.description.match(/^searchable field:/i) assert !issue.description.match(/^searchable field:/i)
end end
@@ -373,80 +373,6 @@ class MailHandlerTest < ActiveSupport::TestCase
assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest assert_equal 'caaf384198bcbc9563ab5c058acd73cd', attachment.digest
end end
def test_thunderbird_with_attachment_ja
issue = submit_email(
'thunderbird_with_attachment_ja.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
attachment = issue.attachments.first
assert_equal ja, attachment.filename
assert_equal 5, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 5, File.size(attachment.diskfile)
assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
end
def test_gmail_with_attachment_ja
issue = submit_email(
'gmail_with_attachment_ja.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt"
ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
attachment = issue.attachments.first
assert_equal ja, attachment.filename
assert_equal 5, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 5, File.size(attachment.diskfile)
assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
end
def test_thunderbird_with_attachment_latin1
issue = submit_email(
'thunderbird_with_attachment_iso-8859-1.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
u = ""
u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
11.times { u << u1 }
attachment = issue.attachments.first
assert_equal "#{u}.png", attachment.filename
assert_equal 130, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 130, File.size(attachment.diskfile)
assert_equal '4d80e667ac37dddfe05502530f152abb', attachment.digest
end
def test_gmail_with_attachment_latin1
issue = submit_email(
'gmail_with_attachment_iso-8859-1.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal 1, issue.attachments.size
u = ""
u.force_encoding('UTF-8') if u.respond_to?(:force_encoding)
u1 = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc"
u1.force_encoding('UTF-8') if u1.respond_to?(:force_encoding)
11.times { u << u1 }
attachment = issue.attachments.first
assert_equal "#{u}.txt", attachment.filename
assert_equal 5, attachment.filesize
assert File.exist?(attachment.diskfile)
assert_equal 5, File.size(attachment.diskfile)
assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest
end
def test_add_issue_with_iso_8859_1_subject def test_add_issue_with_iso_8859_1_subject
issue = submit_email( issue = submit_email(
'subject_as_iso-8859-1.eml', 'subject_as_iso-8859-1.eml',
@@ -456,37 +382,6 @@ class MailHandlerTest < ActiveSupport::TestCase
assert_equal 'Testmail from Webmail: ä ö ü...', issue.subject assert_equal 'Testmail from Webmail: ä ö ü...', issue.subject
end end
def test_add_issue_with_japanese_subject
issue = submit_email(
'subject_japanese_1.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
assert_equal ja, issue.subject
end
def test_add_issue_with_no_subject_header
issue = submit_email(
'no_subject_header.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
assert_equal '(no subject)', issue.subject
end
def test_add_issue_with_mixed_japanese_subject
issue = submit_email(
'subject_japanese_2.eml',
:issue => {:project => 'ecookbook'}
)
assert_kind_of Issue, issue
ja = "Re: \xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88"
ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding)
assert_equal ja, issue.subject
end
def test_should_ignore_emails_from_locked_users def test_should_ignore_emails_from_locked_users
User.find(2).lock! User.find(2).lock!
-9
View File
@@ -1,5 +1,3 @@
# encoding: utf-8
#
# Redmine - project management software # Redmine - project management software
# Copyright (C) 2006-2012 Jean-Philippe Lang # Copyright (C) 2006-2012 Jean-Philippe Lang
# #
@@ -108,11 +106,4 @@ class PrincipalTest < ActiveSupport::TestCase
assert_equal @palmer, results.first assert_equal @palmer, results.first
end end
end end
def test_like_scope_with_cyrillic_name
user = User.generate!(:firstname => 'Соболев', :lastname => 'Денис')
results = Principal.like('Собо')
assert_equal 1, results.count
assert_equal user, results.first
end
end end
+6 -13
View File
@@ -28,17 +28,17 @@ class ProjectNestedSetTest < ActiveSupport::TestCase
@a2 = Project.create!(:name => 'A2', :identifier => 'projecta2') @a2 = Project.create!(:name => 'A2', :identifier => 'projecta2')
@a2.set_parent!(@a) @a2.set_parent!(@a)
@c = Project.create!(:name => 'C', :identifier => 'projectc')
@c1 = Project.create!(:name => 'C1', :identifier => 'projectc1')
@c1.set_parent!(@c)
@b = Project.create!(:name => 'B', :identifier => 'projectb') @b = Project.create!(:name => 'B', :identifier => 'projectb')
@b2 = Project.create!(:name => 'B2', :identifier => 'projectb2')
@b2.set_parent!(@b)
@b1 = Project.create!(:name => 'B1', :identifier => 'projectb1') @b1 = Project.create!(:name => 'B1', :identifier => 'projectb1')
@b1.set_parent!(@b) @b1.set_parent!(@b)
@b11 = Project.create!(:name => 'B11', :identifier => 'projectb11') @b11 = Project.create!(:name => 'B11', :identifier => 'projectb11')
@b11.set_parent!(@b1) @b11.set_parent!(@b1)
@b2 = Project.create!(:name => 'B2', :identifier => 'projectb2')
@b2.set_parent!(@b)
@c = Project.create!(:name => 'C', :identifier => 'projectc')
@c1 = Project.create!(:name => 'C1', :identifier => 'projectc1')
@c1.set_parent!(@c)
@a, @a1, @a2, @b, @b1, @b11, @b2, @c, @c1 = *(Project.all.sort_by(&:name)) @a, @a1, @a2, @b, @b1, @b11, @b2, @c, @c1 = *(Project.all.sort_by(&:name))
end end
@@ -47,13 +47,6 @@ class ProjectNestedSetTest < ActiveSupport::TestCase
assert_valid_nested_set assert_valid_nested_set
end end
def test_rebuild_should_build_valid_tree
Project.update_all "lft = NULL, rgt = NULL"
Project.rebuild!
assert_valid_nested_set
end
def test_moving_a_child_to_a_different_parent_should_keep_valid_tree def test_moving_a_child_to_a_different_parent_should_keep_valid_tree
assert_no_difference 'Project.count' do assert_no_difference 'Project.count' do
Project.find_by_name('B1').set_parent!(Project.find_by_name('A2')) Project.find_by_name('B1').set_parent!(Project.find_by_name('A2'))
-34
View File
@@ -217,40 +217,6 @@ class RepositoryGitTest < ActiveSupport::TestCase
assert_equal h1, h2 assert_equal h1, h2
end end
def test_keep_extra_report_last_commit_in_clear_changesets
assert_nil @repository.extra_info
h = {}
h["extra_report_last_commit"] = "1"
@repository.merge_extra_info(h)
@repository.save
@project.reload
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets
@project.reload
assert_equal NUM_REV, @repository.changesets.count
@repository.send(:clear_changesets)
assert_equal 1, @repository.extra_info.size
assert_equal "1", @repository.extra_info["extra_report_last_commit"]
end
def test_refetch_after_clear_changesets
assert_nil @repository.extra_info
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets
@project.reload
assert_equal NUM_REV, @repository.changesets.count
@repository.send(:clear_changesets)
@project.reload
assert_equal 0, @repository.changesets.count
@repository.fetch_changesets
@project.reload
assert_equal NUM_REV, @repository.changesets.count
end
def test_parents def test_parents
assert_equal 0, @repository.changesets.count assert_equal 0, @repository.changesets.count
@repository.fetch_changesets @repository.fetch_changesets
+1 -7
View File
@@ -32,13 +32,7 @@ class VersionTest < ActiveSupport::TestCase
def test_invalid_effective_date_validation def test_invalid_effective_date_validation
v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01') v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
assert !v.valid? assert !v.save
v.effective_date = '2012-11-33'
assert !v.valid?
v.effective_date = '2012-31-11'
assert !v.valid?
v.effective_date = 'ABC'
assert !v.valid?
assert_include I18n.translate('activerecord.errors.messages.not_a_date'), assert_include I18n.translate('activerecord.errors.messages.not_a_date'),
v.errors[:effective_date] v.errors[:effective_date]
end end
View File