Compare commits

..
1 Commits
Author SHA1 Message Date
Jean-Philippe Lang d21776215b tagged version 1.1.1
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/tags/1.1.1@4786 e93f8b46-1217-0410-a6f0-8f06a7374b81
2011-01-30 14:53:24 +00:00
32 changed files with 142 additions and 261 deletions
-2
View File
@@ -1,5 +1,3 @@
/.project
/.loadpath
/config/additional_environment.rb /config/additional_environment.rb
/config/database.yml /config/database.yml
/config/email.yml /config/email.yml
-2
View File
@@ -1,7 +1,5 @@
syntax: glob syntax: glob
.project
.loadpath
config/additional_environment.rb config/additional_environment.rb
config/database.yml config/database.yml
config/email.yml config/email.yml
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>1.1-stable</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.rubypeople.rdt.core.rubybuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.aptana.ide.core.unifiedBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.aptana.ide.project.nature.web</nature>
<nature>org.rubypeople.rdt.core.rubynature</nature>
<nature>org.radrails.rails.core.railsnature</nature>
</natures>
</projectDescription>
-9
View File
@@ -23,7 +23,6 @@ class JournalsController < ApplicationController
accept_key_auth :index accept_key_auth :index
helper :issues helper :issues
helper :custom_fields
helper :queries helper :queries
include QueriesHelper include QueriesHelper
helper :sort helper :sort
@@ -76,14 +75,6 @@ class JournalsController < ApplicationController
format.html { redirect_to :controller => 'issues', :action => 'show', :id => @journal.journalized_id } format.html { redirect_to :controller => 'issues', :action => 'show', :id => @journal.journalized_id }
format.js { render :action => 'update' } format.js { render :action => 'update' }
end end
else
respond_to do |format|
format.html {
# TODO: implement non-JS journal update
render :nothing => true
}
format.js
end
end end
end end
+2 -2
View File
@@ -123,7 +123,7 @@ class RepositoriesController < ApplicationController
(show_error_not_found; return) unless @content (show_error_not_found; return) unless @content
if 'raw' == params[:format] || @content.is_binary_data? || (@entry.size && @entry.size > Setting.file_max_size_displayed.to_i.kilobyte) if 'raw' == params[:format] || @content.is_binary_data? || (@entry.size && @entry.size > Setting.file_max_size_displayed.to_i.kilobyte)
# Force the download # Force the download
send_data @content, :filename => filename_for_content_disposition(@path.split('/').last) send_data @content, :filename => @path.split('/').last
else else
# Prevent empty lines when displaying a file with Windows style eol # Prevent empty lines when displaying a file with Windows style eol
@content.gsub!("\r\n", "\n") @content.gsub!("\r\n", "\n")
@@ -213,7 +213,7 @@ class RepositoriesController < ApplicationController
@rev = params[:rev].blank? ? @repository.default_branch : params[:rev].strip @rev = params[:rev].blank? ? @repository.default_branch : params[:rev].strip
@rev_to = params[:rev_to] @rev_to = params[:rev_to]
unless @rev.to_s.match(REV_PARAM_RE) && @rev_to.to_s.match(REV_PARAM_RE) unless @rev.to_s.match(REV_PARAM_RE) && @rev.to_s.match(REV_PARAM_RE)
if @repository.branches.blank? if @repository.branches.blank?
raise InvalidRevisionParam raise InvalidRevisionParam
end end
+2 -4
View File
@@ -97,13 +97,11 @@ class Changeset < ActiveRecord::Base
TIMELOG_RE = / TIMELOG_RE = /
( (
((\d+)(h|hours?))((\d+)(m|min)?)? (\d+([.,]\d+)?)h?
|
((\d+)(h|hours?|m|min))
| |
(\d+):(\d+) (\d+):(\d+)
| |
(\d+([\.,]\d+)?)h? ((\d+)(h|hours?))?((\d+)(m|min)?)?
) )
/x /x
+1 -5
View File
@@ -100,7 +100,7 @@ class MailHandler < ActionMailer::Base
elsif m = email.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 receive_issue
end end
rescue ActiveRecord::RecordInvalid => e rescue ActiveRecord::RecordInvalid => e
# TODO: send a email to the user # TODO: send a email to the user
@@ -113,10 +113,6 @@ class MailHandler < ActionMailer::Base
logger.error "MailHandler: unauthorized attempt from #{user}" if logger logger.error "MailHandler: unauthorized attempt from #{user}" if logger
false false
end end
def dispatch_to_default
receive_issue
end
# Creates a new issue # Creates a new issue
def receive_issue def receive_issue
+2 -12
View File
@@ -566,19 +566,9 @@ class Query < ActiveRecord::Base
sql = '' sql = ''
case operator case operator
when "=" when "="
if value.any? sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
else
# IN an empty set
sql = "1=0"
end
when "!" when "!"
if value.any? sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
sql = "(#{db_table}.#{db_field} IS NULL OR #{db_table}.#{db_field} NOT IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + "))"
else
# NOT IN an empty set
sql = "1=1"
end
when "!*" when "!*"
sql = "#{db_table}.#{db_field} IS NULL" sql = "#{db_table}.#{db_field} IS NULL"
sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter sql << " OR #{db_table}.#{db_field} = ''" if is_custom_filter
-1
View File
@@ -69,5 +69,4 @@
<% content_for :header_tags do %> <% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@project}: #{@board}") %> <%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@project}: #{@board}") %>
<%= stylesheet_link_tag 'scm' %>
<% end %> <% end %>
+1 -1
View File
@@ -60,7 +60,7 @@ end
# Width of the entire chart # Width of the entire chart
g_width = (@gantt.date_to - @gantt.date_from + 1)*zoom g_width = (@gantt.date_to - @gantt.date_from + 1)*zoom
@gantt.render(:top => headers_height + 8, :zoom => zoom, :g_width => g_width, :subject_width => subject_width) @gantt.render(:top => headers_height + 8, :zoom => zoom, :g_width => g_width)
g_height = [(20 * (@gantt.number_of_rows + 6))+150, 206].max g_height = [(20 * (@gantt.number_of_rows + 6))+150, 206].max
t_height = g_height + headers_height t_height = g_height + headers_height
+1 -1
View File
@@ -21,7 +21,7 @@
<!-- page specific tags --> <!-- page specific tags -->
<%= yield :header_tags -%> <%= yield :header_tags -%>
</head> </head>
<body class="<%=h body_css_classes %>"> <body class="<%= body_css_classes %>">
<div id="wrapper"> <div id="wrapper">
<div id="wrapper2"> <div id="wrapper2">
<div id="top-menu"> <div id="top-menu">
-4
View File
@@ -12,7 +12,3 @@
}, :accesskey => accesskey(:preview) %> }, :accesskey => accesskey(:preview) %>
<% end %> <% end %>
<div id="preview" class="wiki"></div> <div id="preview" class="wiki"></div>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'scm' %>
<% end %>
+1 -1
View File
@@ -15,7 +15,7 @@
<p><%= setting_check_box :gravatar_enabled %></p> <p><%= setting_check_box :gravatar_enabled %></p>
<p><%= setting_select :gravatar_default, [["Wavatars", 'wavatar'], ["Identicons", 'identicon'], ["Monster ids", 'monsterid'], ["Retro", "retro"]], :blank => :label_none %></p> <p><%= setting_select :gravatar_default, [["Wavatars", 'wavatar'], ["Identicons", 'identicon'], ["Monster ids", 'monsterid']], :blank => :label_none %></p>
</div> </div>
<%= submit_tag l(:button_save) %> <%= submit_tag l(:button_save) %>
+1 -1
View File
@@ -24,7 +24,7 @@
<td><%= h tracker %></td> <td><%= h tracker %></td>
<% roles.each do |role, count| -%> <% roles.each do |role, count| -%>
<td align="center"> <td align="center">
<%= link_to((count > 0 ? count : image_tag('false.png')), {:action => 'edit', :role_id => role, :tracker_id => tracker}, :title => l(:button_edit)) %> <%= link_to((count > 1 ? count : image_tag('false.png')), {:action => 'edit', :role_id => role, :tracker_id => tracker}, :title => l(:button_edit)) %>
</td> </td>
<% end -%> <% end -%>
</tr> </tr>
+1 -1
View File
@@ -897,7 +897,7 @@ bg:
text_user_wrote: "%{value} написа:" text_user_wrote: "%{value} написа:"
text_enumeration_destroy_question: "%{count} обекта са свързани с тази стойност." text_enumeration_destroy_question: "%{count} обекта са свързани с тази стойност."
text_enumeration_category_reassign_to: 'Пресвържете ги към тази стойност:' text_enumeration_category_reassign_to: 'Пресвържете ги към тази стойност:'
text_email_delivery_not_configured: "Изпращането на e-mail-и не е конфигурирано и известията не са разрешени.\nКонфигурирайте вашия SMTP сървър в config/email.yml и рестартирайте Redmine, за да ги разрешите." text_email_delivery_not_configured: "Изпращането на e-mail-и не е конфигурирано и известията не са разрешени.\nКонфигурирайте вашия SMTP сървър в config/configuration.yml и рестартирайте Redmine, за да ги разрешите."
text_repository_usernames_mapping: "Изберете или променете потребителите в Redmine, съответстващи на потребителите в дневника на хранилището (repository).\nПотребителите с еднакви имена в Redmine и хранилищата се съвместяват автоматично." text_repository_usernames_mapping: "Изберете или променете потребителите в Redmine, съответстващи на потребителите в дневника на хранилището (repository).\nПотребителите с еднакви имена в Redmine и хранилищата се съвместяват автоматично."
text_diff_truncated: '... Този diff не е пълен, понеже е надхвърля максималния размер, който може да бъде показан.' text_diff_truncated: '... Този diff не е пълен, понеже е надхвърля максималния размер, който може да бъде показан.'
text_custom_field_possible_values_info: 'Една стойност на ред' text_custom_field_possible_values_info: 'Една стойност на ред'
+7 -7
View File
@@ -169,7 +169,7 @@ fr:
notice_successful_connection: Connexion réussie. notice_successful_connection: Connexion réussie.
notice_file_not_found: "La page à laquelle vous souhaitez accéder n'existe pas ou a été supprimée." notice_file_not_found: "La page à laquelle vous souhaitez accéder n'existe pas ou a été supprimée."
notice_locking_conflict: Les données ont été mises à jour par un autre utilisateur. Mise à jour impossible. notice_locking_conflict: Les données ont été mises à jour par un autre utilisateur. Mise à jour impossible.
notice_not_authorized: "Vous n'êtes pas autorisé à accéder à cette page." notice_not_authorized: "Vous n'êtes pas autorisés à accéder à cette page."
notice_not_authorized_archived_project: Le projet auquel vous tentez d'accéder a été archivé. notice_not_authorized_archived_project: Le projet auquel vous tentez d'accéder a été archivé.
notice_email_sent: "Un email a été envoyé à %{value}" notice_email_sent: "Un email a été envoyé à %{value}"
notice_email_error: "Erreur lors de l'envoi de l'email (%{value})" notice_email_error: "Erreur lors de l'envoi de l'email (%{value})"
@@ -323,11 +323,11 @@ fr:
setting_text_formatting: Formatage du texte setting_text_formatting: Formatage du texte
setting_wiki_compression: Compression historique wiki setting_wiki_compression: Compression historique wiki
setting_feeds_limit: Limite du contenu des flux RSS setting_feeds_limit: Limite du contenu des flux RSS
setting_default_projects_public: Définir les nouveaux projets comme publics par défaut setting_default_projects_public: Définir les nouveaux projects comme publics par défaut
setting_autofetch_changesets: Récupération auto. des commits setting_autofetch_changesets: Récupération auto. des commits
setting_sys_api_enabled: Activer les WS pour la gestion des dépôts setting_sys_api_enabled: Activer les WS pour la gestion des dépôts
setting_commit_ref_keywords: Mots-clés de référencement setting_commit_ref_keywords: Mot-clés de référencement
setting_commit_fix_keywords: Mots-clés de résolution setting_commit_fix_keywords: Mot-clés de résolution
setting_autologin: Autologin setting_autologin: Autologin
setting_date_format: Format de date setting_date_format: Format de date
setting_time_format: Format d'heure setting_time_format: Format d'heure
@@ -349,7 +349,7 @@ fr:
setting_gravatar_enabled: Afficher les Gravatar des utilisateurs setting_gravatar_enabled: Afficher les Gravatar des utilisateurs
setting_diff_max_lines_displayed: Nombre maximum de lignes de diff affichées setting_diff_max_lines_displayed: Nombre maximum de lignes de diff affichées
setting_file_max_size_displayed: Taille maximum des fichiers texte affichés en ligne setting_file_max_size_displayed: Taille maximum des fichiers texte affichés en ligne
setting_repository_log_display_limit: "Nombre maximum de révisions affichées sur l'historique d'un fichier" setting_repository_log_display_limit: "Nombre maximum de revisions affichées sur l'historique d'un fichier"
setting_openid: "Autoriser l'authentification et l'enregistrement OpenID" setting_openid: "Autoriser l'authentification et l'enregistrement OpenID"
setting_password_min_length: Longueur minimum des mots de passe setting_password_min_length: Longueur minimum des mots de passe
setting_new_project_user_role_id: Rôle donné à un utilisateur non-administrateur qui crée un projet setting_new_project_user_role_id: Rôle donné à un utilisateur non-administrateur qui crée un projet
@@ -369,7 +369,7 @@ fr:
permission_add_subprojects: Créer des sous-projets permission_add_subprojects: Créer des sous-projets
permission_edit_project: Modifier le projet permission_edit_project: Modifier le projet
permission_select_project_modules: Choisir les modules permission_select_project_modules: Choisir les modules
permission_manage_members: Gérer les membres permission_manage_members: Gérer les members
permission_manage_versions: Gérer les versions permission_manage_versions: Gérer les versions
permission_manage_categories: Gérer les catégories de demandes permission_manage_categories: Gérer les catégories de demandes
permission_view_issues: Voir les demandes permission_view_issues: Voir les demandes
@@ -859,7 +859,7 @@ fr:
text_issue_added: "La demande %{id} a été soumise par %{author}." text_issue_added: "La demande %{id} a été soumise par %{author}."
text_issue_updated: "La demande %{id} a été mise à jour par %{author}." text_issue_updated: "La demande %{id} a été mise à jour par %{author}."
text_wiki_destroy_confirmation: Etes-vous sûr de vouloir supprimer ce wiki et tout son contenu ? text_wiki_destroy_confirmation: Etes-vous sûr de vouloir supprimer ce wiki et tout son contenu ?
text_issue_category_destroy_question: "%{count} demandes sont affectées à cette catégorie. Que voulez-vous faire ?" text_issue_category_destroy_question: "%{count} demandes sont affectées à cette catégories. Que voulez-vous faire ?"
text_issue_category_destroy_assignments: N'affecter les demandes à aucune autre catégorie text_issue_category_destroy_assignments: N'affecter les demandes à aucune autre catégorie
text_issue_category_reassign_to: Réaffecter les demandes à cette catégorie text_issue_category_reassign_to: Réaffecter les demandes à cette catégorie
text_user_mail_option: "Pour les projets non sélectionnés, vous recevrez seulement des notifications pour ce que vous surveillez ou à quoi vous participez (exemple: demandes dont vous êtes l'auteur ou la personne assignée)." text_user_mail_option: "Pour les projets non sélectionnés, vous recevrez seulement des notifications pour ce que vous surveillez ou à quoi vous participez (exemple: demandes dont vous êtes l'auteur ou la personne assignée)."
+46 -46
View File
@@ -5,25 +5,25 @@ nl:
# Use the strftime parameters for formats. # Use the strftime parameters for formats.
# When no format has been given, it uses default. # When no format has been given, it uses default.
# You can provide other formats here if you like! # You can provide other formats here if you like!
default: "%d-%m-%Y" default: "%Y-%m-%d"
short: "%e %b" short: "%b %d"
long: "%d %B, %Y" long: "%B %d, %Y"
day_names: [zondag, maandag, dinsdag, woensdag, donderdag, vrijdag, zaterdag] day_names: [Zondag, Maandag, Dinsdag, Woensdag, Donderdag, Vrijdag, Zaterdag]
abbr_day_names: [zo, ma, di, wo, do, vr, za] abbr_day_names: [Zo, Ma, Di, Woe, Do, Vr, Zat]
# Don't forget the nil at the beginning; there's no such thing as a 0th month # Don't forget the nil at the beginning; there's no such thing as a 0th month
month_names: [~, januari, februari, maart, april, mei, juni, juli, augustus, september, oktober, november, december] month_names: [~, Januari, Februari, Maart, April, Mei, Juni, Juli, Augustus, September, Oktober, November, December]
abbr_month_names: [~, jan, feb, mar, apr, mei, jun, jul, aug, sep, okt, nov, dec] abbr_month_names: [~, Jan, Feb, Mar, Apr, Mei, Jun, Jul, Aug, Sep, Okt, Nov, Dec]
# Used in date_select and datime_select. # Used in date_select and datime_select.
order: [ :day, :month, :year ] order: [ :year, :month, :day ]
time: time:
formats: formats:
default: "%a, %d %b %Y %H:%M:%S %z" default: "%a, %d %b %Y %H:%M:%S %z"
time: "%H:%M" time: "%H:%M"
short: "%e %b %H:%M" short: "%d %b %H:%M"
long: "%d %B, %Y %H:%M" long: "%B %d, %Y %H:%M"
am: "am" am: "am"
pm: "pm" pm: "pm"
@@ -32,7 +32,7 @@ nl:
half_a_minute: "halve minuut" half_a_minute: "halve minuut"
less_than_x_seconds: less_than_x_seconds:
one: "minder dan een seconde" one: "minder dan een seconde"
other: "minder dan %{count} seconden" other: "mindera dan %{count} seconden"
x_seconds: x_seconds:
one: "1 seconde" one: "1 seconde"
other: "%{count} seconden" other: "%{count} seconden"
@@ -56,13 +56,13 @@ nl:
other: "%{count} maanden" other: "%{count} maanden"
about_x_years: about_x_years:
one: "ongeveer 1 jaar" one: "ongeveer 1 jaar"
other: "ongeveer %{count} jaar" other: "ongeveer %{count} jaren"
over_x_years: over_x_years:
one: "meer dan 1 jaar" one: "over 1 jaar"
other: "meer dan %{count} jaar" other: "over %{count} jaren"
almost_x_years: almost_x_years:
one: "bijna 1 jaar" one: "almost 1 year"
other: "bijna %{count} jaar" other: "almost %{count} years"
number: number:
format: format:
@@ -94,8 +94,8 @@ nl:
errors: errors:
template: template:
header: header:
one: "Door een fout kon dit %{model} niet worden opgeslagen" one: "1 error prohibited this %{model} from being saved"
other: "Door %{count} fouten kon dit %{model} niet worden opgeslagen" other: "%{count} errors prohibited this %{model} from being saved"
messages: messages:
inclusion: "staat niet in de lijst" inclusion: "staat niet in de lijst"
exclusion: "is gereserveerd" exclusion: "is gereserveerd"
@@ -143,7 +143,7 @@ nl:
button_edit: Bewerk button_edit: Bewerk
button_list: Lijst button_list: Lijst
button_lock: Sluit button_lock: Sluit
button_log_time: Registreer tijd button_log_time: Log tijd
button_login: Inloggen button_login: Inloggen
button_move: Verplaatsen button_move: Verplaatsen
button_quote: Citaat button_quote: Citaat
@@ -513,9 +513,9 @@ nl:
one: 1 project one: 1 project
other: "%{count} projects" other: "%{count} projects"
label_public_projects: Publieke projecten label_public_projects: Publieke projecten
label_query: Eigen zoekopdracht label_query: Eigen zoekvraag
label_query_new: Nieuwe zoekopdracht label_query_new: Nieuwe zoekvraag
label_query_plural: Eigen zoekopdrachten label_query_plural: Eigen zoekvragen
label_read: Lees... label_read: Lees...
label_register: Registreer label_register: Registreer
label_registered_on: Geregistreerd op label_registered_on: Geregistreerd op
@@ -581,7 +581,7 @@ nl:
label_used_by: Gebruikt door label_used_by: Gebruikt door
label_user: Gebruiker label_user: Gebruiker
label_user_activity: "%{value}'s activiteit" label_user_activity: "%{value}'s activiteit"
label_user_mail_no_self_notified: Ik wil niet op de hoogte gehouden worden van mijn eigen wijzigingen label_user_mail_no_self_notified: "Ik wil niet op de hoogte gehouden worden van wijzigingen die ik zelf maak."
label_user_mail_option_all: "Bij elk gebeurtenis in al mijn projecten..." label_user_mail_option_all: "Bij elk gebeurtenis in al mijn projecten..."
label_user_mail_option_selected: "Enkel bij elke gebeurtenis op het geselecteerde project..." label_user_mail_option_selected: "Enkel bij elke gebeurtenis op het geselecteerde project..."
label_user_new: Nieuwe gebruiker label_user_new: Nieuwe gebruiker
@@ -718,7 +718,7 @@ nl:
setting_mail_from: Afzender e-mail adres setting_mail_from: Afzender e-mail adres
setting_mail_handler_api_enabled: Schakel WS in voor inkomende mail. setting_mail_handler_api_enabled: Schakel WS in voor inkomende mail.
setting_mail_handler_api_key: API sleutel setting_mail_handler_api_key: API sleutel
setting_per_page_options: Aantal objecten per pagina (opties) setting_per_page_options: Objects per pagina-opties
setting_plain_text_mail: platte tekst (geen HTML) setting_plain_text_mail: platte tekst (geen HTML)
setting_protocol: Protocol setting_protocol: Protocol
setting_repositories_encodings: Repositories coderingen setting_repositories_encodings: Repositories coderingen
@@ -773,7 +773,7 @@ nl:
text_tip_issue_end_day: issue die op deze dag eindigt text_tip_issue_end_day: issue die op deze dag eindigt
text_tracker_no_workflow: Geen workflow gedefinieerd voor deze tracker text_tracker_no_workflow: Geen workflow gedefinieerd voor deze tracker
text_unallowed_characters: Niet toegestane tekens text_unallowed_characters: Niet toegestane tekens
text_user_mail_option: "Bij niet-geselecteerde projecten zult u enkel mededelingen ontvangen voor issues die u monitort of waar u bij betrokken bent (als auteur of toegewezen persoon)." text_user_mail_option: "Bij niet-geselecteerde projecten zult u enkel notificaties ontvangen voor issues die u monitort of waar u bij betrokken bent (als auteur of toegewezen persoon)."
text_user_wrote: "%{value} schreef:" text_user_wrote: "%{value} schreef:"
text_wiki_destroy_confirmation: Weet u zeker dat u deze wiki en zijn inhoud wenst te verwijderen? text_wiki_destroy_confirmation: Weet u zeker dat u deze wiki en zijn inhoud wenst te verwijderen?
text_workflow_edit: Selecteer een rol en een tracker om de workflow te wijzigen text_workflow_edit: Selecteer een rol en een tracker om de workflow te wijzigen
@@ -795,7 +795,7 @@ nl:
label_date_from_to: Van %{start} tot %{end} label_date_from_to: Van %{start} tot %{end}
label_greater_or_equal: ">=" label_greater_or_equal: ">="
label_less_or_equal: <= label_less_or_equal: <=
text_wiki_page_destroy_question: Deze pagina heeft %{descendants} subpagina's en onderliggende pagina's?. Wat wilt u hiermee doen? text_wiki_page_destroy_question: Deze pagina heeft %{descendants} subpagina's en onderliggende pagina's?. Wil wil je ermee doen?
text_wiki_page_reassign_children: Alle subpagina's toewijzen aan deze hoofdpagina text_wiki_page_reassign_children: Alle subpagina's toewijzen aan deze hoofdpagina
text_wiki_page_nullify_children: Behoud subpagina's als hoofdpagina's text_wiki_page_nullify_children: Behoud subpagina's als hoofdpagina's
text_wiki_page_destroy_children: Verwijder alle subpagina's en onderliggende pagina's text_wiki_page_destroy_children: Verwijder alle subpagina's en onderliggende pagina's
@@ -804,9 +804,9 @@ nl:
mail_subject_wiki_content_updated: "'%{id}' wiki pagina is bijgewerkt" mail_subject_wiki_content_updated: "'%{id}' wiki pagina is bijgewerkt"
label_wiki_content_added: Wiki pagina toegevoegd label_wiki_content_added: Wiki pagina toegevoegd
mail_subject_wiki_content_added: "'%{id}' wiki pagina is toegevoegd" mail_subject_wiki_content_added: "'%{id}' wiki pagina is toegevoegd"
mail_body_wiki_content_added: De '%{id}' wiki pagina is toegevoegd door %{author}. mail_body_wiki_content_added: The '%{id}' wiki pagina is toegevoegd door %{author}.
label_wiki_content_updated: Wiki pagina bijgewerkt label_wiki_content_updated: Wiki pagina bijgewerkt
mail_body_wiki_content_updated: De '%{id}' wiki pagina is bijgewerkt door %{author}. mail_body_wiki_content_updated: The '%{id}' wiki pagina is bijgewerkt door %{author}.
permission_add_project: Maak project permission_add_project: Maak project
setting_new_project_user_role_id: Rol van gebruiker die een project maakt setting_new_project_user_role_id: Rol van gebruiker die een project maakt
label_view_all_revisions: Bekijk alle revisies label_view_all_revisions: Bekijk alle revisies
@@ -895,26 +895,26 @@ nl:
text_zoom_in: Zoom in text_zoom_in: Zoom in
notice_unable_delete_time_entry: Verwijderen niet mogelijk van tijd log invoer. notice_unable_delete_time_entry: Verwijderen niet mogelijk van tijd log invoer.
label_overall_spent_time: Totaal bestede tijd label_overall_spent_time: Totaal bestede tijd
field_time_entries: Registreer tijd field_time_entries: Log tijd
project_module_gantt: Gantt project_module_gantt: Gantt
project_module_calendar: Kalender project_module_calendar: Kalender
button_edit_associated_wikipage: "Bewerk bijbehorende wiki pagina: %{page_title}" button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
text_are_you_sure_with_children: Verwijder issue en alle onderliggende issues? text_are_you_sure_with_children: Delete issue and all child issues?
field_text: Tekst veld field_text: Text field
label_user_mail_option_only_owner: Alleen voor dingen waarvan ik de auteur ben label_user_mail_option_only_owner: Only for things I am the owner of
setting_default_notification_option: Standaard instelling voor mededelingen setting_default_notification_option: Default notification option
label_user_mail_option_only_my_events: Alleen voor dingen die ik volg of bij betrokken ben label_user_mail_option_only_my_events: Only for things I watch or I'm involved in
label_user_mail_option_only_assigned: Alleen voor dingen die aan mij zijn toegewezen label_user_mail_option_only_assigned: Only for things I am assigned to
label_user_mail_option_none: Bij geen enkele gebeurtenis label_user_mail_option_none: No events
field_member_of_group: Assignee's group field_member_of_group: Assignee's group
field_assigned_to_role: Assignee's role field_assigned_to_role: Assignee's role
notice_not_authorized_archived_project: Het project dat u wilt bezoeken is gearchiveerd. notice_not_authorized_archived_project: The project you're trying to access has been archived.
label_principal_search: "Zoek naar gebruiker of groep:" label_principal_search: "Search for user or group:"
label_user_search: "Zoek naar gebruiker:" label_user_search: "Search for user:"
field_visible: Zichtbaar field_visible: Visible
setting_emails_header: Emails header setting_emails_header: Emails header
setting_commit_logtime_activity_id: Standaard activiteit voor tijdregistratie setting_commit_logtime_activity_id: Activity for logged time
text_time_logged_by_changeset: Toegepast in changeset %{value}. text_time_logged_by_changeset: Applied in changeset %{value}.
setting_commit_logtime_enabled: Activeer tijdregistratie setting_commit_logtime_enabled: Enable time logging
notice_gantt_chart_truncated: De gantt chart is ingekort omdat het meer objecten bevat dan kan worden weergegeven, (%{max}) notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
setting_gantt_items_limit: Max. aantal objecten op gantt chart setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
+16 -19
View File
@@ -315,7 +315,7 @@ pt-BR:
setting_issue_list_default_columns: Colunas padrão visíveis na lista de tarefas setting_issue_list_default_columns: Colunas padrão visíveis na lista de tarefas
setting_repositories_encodings: Codificação dos repositórios setting_repositories_encodings: Codificação dos repositórios
setting_commit_logs_encoding: Codificação das mensagens de commit setting_commit_logs_encoding: Codificação das mensagens de commit
setting_emails_footer: Rodapé do e-mail setting_emails_footer: Rodapé dos e-mails
setting_protocol: Protocolo setting_protocol: Protocolo
setting_per_page_options: Número de itens exibidos por página setting_per_page_options: Número de itens exibidos por página
setting_user_format: Formato de exibição de nome de usuário setting_user_format: Formato de exibição de nome de usuário
@@ -354,9 +354,6 @@ pt-BR:
label_issues_by: "Tarefas por %{value}" label_issues_by: "Tarefas por %{value}"
label_issue_added: Tarefa adicionada label_issue_added: Tarefa adicionada
label_issue_updated: Tarefa atualizada label_issue_updated: Tarefa atualizada
label_issue_note_added: Nota adicionada
label_issue_status_updated: Situação atualizada
label_issue_priority_updated: Prioridade atualizada
label_document: Documento label_document: Documento
label_document_new: Novo documento label_document_new: Novo documento
label_document_plural: Documentos label_document_plural: Documentos
@@ -560,7 +557,7 @@ pt-BR:
label_spent_time: Tempo gasto label_spent_time: Tempo gasto
label_f_hour: "%{value} hora" label_f_hour: "%{value} hora"
label_f_hour_plural: "%{value} horas" label_f_hour_plural: "%{value} horas"
label_time_tracking: Registro de horas label_time_tracking: Controle de horas
label_change_plural: Alterações label_change_plural: Alterações
label_statistics: Estatísticas label_statistics: Estatísticas
label_commits_per_month: Commits por mês label_commits_per_month: Commits por mês
@@ -757,7 +754,7 @@ pt-BR:
enumeration_issue_priorities: Prioridade das tarefas enumeration_issue_priorities: Prioridade das tarefas
enumeration_doc_categories: Categorias de documento enumeration_doc_categories: Categorias de documento
enumeration_activities: Atividades (registro de horas) enumeration_activities: Atividades (time tracking)
notice_unable_delete_version: Não foi possível excluir a versão notice_unable_delete_version: Não foi possível excluir a versão
label_renamed: renomeado label_renamed: renomeado
label_copied: copiado label_copied: copiado
@@ -946,16 +943,16 @@ pt-BR:
setting_default_notification_option: Opção padrão de notificação setting_default_notification_option: Opção padrão de notificação
label_user_mail_option_only_my_events: Somente para as coisas que eu esteja observando ou esteja envolvido label_user_mail_option_only_my_events: Somente para as coisas que eu esteja observando ou esteja envolvido
label_user_mail_option_only_assigned: Somente para as coisas que estejam atribuídas a mim label_user_mail_option_only_assigned: Somente para as coisas que estejam atribuídas a mim
label_user_mail_option_none: Sem eventos label_user_mail_option_none: No events
field_member_of_group: Grupo do responsável field_member_of_group: Assignee's group
field_assigned_to_role: Papel do responsável field_assigned_to_role: Assignee's role
notice_not_authorized_archived_project: O projeto que você está tentando acessar foi arquivado. notice_not_authorized_archived_project: The project you're trying to access has been archived.
label_principal_search: "Pesquisar por usuários ou grupos:" label_principal_search: "Search for user or group:"
label_user_search: "Pesquisar por usuário:" label_user_search: "Search for user:"
field_visible: Visível field_visible: Visible
setting_emails_header: Cabeçalho do e-mail setting_emails_header: Emails header
setting_commit_logtime_activity_id: Atividade para registrar horas setting_commit_logtime_activity_id: Activity for logged time
text_time_logged_by_changeset: Aplicado no changeset %{value}. text_time_logged_by_changeset: Applied in changeset %{value}.
setting_commit_logtime_enabled: Habilitar registro de horas setting_commit_logtime_enabled: Enable time logging
notice_gantt_chart_truncated: O gráfico foi cortado por exceder o tamanho máximo de linhas que podem ser exibidas (%{max}) notice_gantt_chart_truncated: The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})
setting_gantt_items_limit: Número máximo de itens exibidos no gráfico gatt setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
-18
View File
@@ -4,24 +4,6 @@ Redmine - project management software
Copyright (C) 2006-2011 Jean-Philippe Lang Copyright (C) 2006-2011 Jean-Philippe Lang
http://www.redmine.org/ http://www.redmine.org/
== 2011-03-07 v1.1.2
* Defect #3132: Bulk editing menu non-functional in Opera browser
* Defect #6090: Most binary files become corrupted when downloading from CVS repository browser when Redmine is running on a Windows server
* Defect #7280: Issues subjects wrap in Gantt
* Defect #7288: Non ASCII filename downloaded from repo is broken on Internet Explorer.
* Defect #7317: Gantt tab gives internal error due to nil avatar icon
* Defect #7497: Aptana Studio .project file added to version 1.1.1-stable
* Defect #7611: Workflow summary shows X icon for workflow with exactly 1 status transition
* Defect #7625: Syntax highlighting unavailable from board new topic or topic edit preview
* Defect #7630: Spent time in commits not recognized
* Defect #7656: MySQL SQL Syntax Error when filtering issues by Assignee's Group
* Defect #7718: Minutes logged in commit message are converted to hours
* Defect #7763: Email notification are sent to watchers even if 'No events' setting is chosen
* Feature #7608: Add "retro" gravatars
* Patch #7598: Extensible MailHandler
* Patch #7795: Internal server error at journals#index with custom fields
== 2011-01-30 v1.1.1 == 2011-01-30 v1.1.1
* Defect #4899: Redmine fails to list files for darcs repository * Defect #4899: Redmine fails to list files for darcs repository
+5 -6
View File
@@ -353,11 +353,11 @@ module Redmine
subject = "<span class='#{css_classes}'>" subject = "<span class='#{css_classes}'>"
if issue.assigned_to.present? if issue.assigned_to.present?
assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name assigned_string = l(:field_assigned_to) + ": " + issue.assigned_to.name
subject << view.avatar(issue.assigned_to, :class => 'gravatar icon-gravatar', :size => 10, :title => assigned_string).to_s subject << view.avatar(issue.assigned_to, :class => 'gravatar icon-gravatar', :size => 10, :title => assigned_string)
end end
subject << view.link_to_issue(issue) subject << view.link_to_issue(issue)
subject << '</span>' subject << '</span>'
html_subject(options, subject, :css => "issue-subject", :title => issue.subject) + "\n" html_subject(options, subject, :css => "issue-subject") + "\n"
when :image when :image
image_subject(options, issue.subject) image_subject(options, issue.subject)
when :pdf when :pdf
@@ -709,10 +709,9 @@ module Redmine
end end
def html_subject(params, subject, options={}) def html_subject(params, subject, options={})
style = "position: absolute;top:#{params[:top]}px;left:#{params[:indent]}px;" output = "<div class=' #{options[:css] }' style='position: absolute;line-height:1.2em;height:16px;top:#{params[:top]}px;left:#{params[:indent]}px;overflow:hidden;'>"
style << "width:#{params[:subject_width] - params[:indent]}px;" if params[:subject_width] output << subject
output << "</div>"
output = view.content_tag 'div', subject, :class => options[:css], :style => style, :title => options[:title]
@subjects << output @subjects << output
output output
end end
-1
View File
@@ -249,7 +249,6 @@ module Redmine
cmd << " -p #{shell_quote path_with_project}" cmd << " -p #{shell_quote path_with_project}"
cat = nil cat = nil
shellout(cmd) do |io| shellout(cmd) do |io|
io.binmode
cat = io.read cat = io.read
end end
return nil if $? && $?.exitstatus != 0 return nil if $? && $?.exitstatus != 0
+1 -1
View File
@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc: module VERSION #:nodoc:
MAJOR = 1 MAJOR = 1
MINOR = 1 MINOR = 1
TINY = 2 TINY = 1
# Branch values: # Branch values:
# * official release: nil # * official release: nil
-27
View File
@@ -1,10 +1,3 @@
desc 'Updates and checks locales against en.yml'
task :locales do
%w(locales:update locales:check_interpolation).collect do |task|
Rake::Task[task].invoke
end
end
namespace :locales do namespace :locales do
desc 'Updates language files based on en.yml content (only works for new top level keys).' desc 'Updates language files based on en.yml content (only works for new top level keys).'
task :update do task :update do
@@ -35,26 +28,6 @@ namespace :locales do
lang.close lang.close
end end
end end
desc 'Checks interpolation arguments in locals against en.yml'
task :check_interpolation do
dir = ENV['DIR'] || './config/locales'
en_strings = YAML.load(File.read(File.join(dir,'en.yml')))['en']
files = Dir.glob(File.join(dir,'*.{yaml,yml}'))
files.each do |file|
file_strings = YAML.load(File.read(file))
file_strings = file_strings[file_strings.keys.first]
file_strings.each do |key, string|
next unless string.is_a?(String)
string.scan /%\{\w+\}/ do |match|
unless en_strings[key].nil? || en_strings[key].include?(match)
puts "#{file}: #{key} uses #{match} not found in en.yml"
end
end
end
end
end
desc <<-END_DESC desc <<-END_DESC
Removes a translation string from all locale file (only works for top-level childless non-multiline keys, probably doesn\'t work on windows). Removes a translation string from all locale file (only works for top-level childless non-multiline keys, probably doesn\'t work on windows).
+4 -1
View File
@@ -11,7 +11,7 @@ ContextMenu.prototype = {
if (!observingContextMenuClick) { if (!observingContextMenuClick) {
Event.observe(document, 'click', this.Click.bindAsEventListener(this)); Event.observe(document, 'click', this.Click.bindAsEventListener(this));
Event.observe(document, 'contextmenu', this.RightClick.bindAsEventListener(this)); Event.observe(document, (window.opera ? 'click' : 'contextmenu'), this.RightClick.bindAsEventListener(this));
observingContextMenuClick = true; observingContextMenuClick = true;
} }
@@ -23,6 +23,8 @@ ContextMenu.prototype = {
this.hideMenu(); this.hideMenu();
// do not show the context menu on links // do not show the context menu on links
if (Event.element(e).tagName == 'A') { return; } if (Event.element(e).tagName == 'A') { return; }
// right-click simulated by Alt+Click with Opera
if (window.opera && !e.altKey) { return; }
var tr = Event.findElement(e, 'tr'); var tr = Event.findElement(e, 'tr');
if (tr == document || tr == undefined || !tr.hasClassName('hascontextmenu')) { return; } if (tr == document || tr == undefined || !tr.hasClassName('hascontextmenu')) { return; }
Event.stop(e); Event.stop(e);
@@ -37,6 +39,7 @@ ContextMenu.prototype = {
Click: function(e) { Click: function(e) {
this.hideMenu(); this.hideMenu();
if (Event.element(e).tagName == 'A') { return; } if (Event.element(e).tagName == 'A') { return; }
if (window.opera && e.altKey) { return; }
if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) { if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) {
var tr = Event.findElement(e, 'tr'); var tr = Event.findElement(e, 'tr');
if (tr!=null && tr!=document && tr.hasClassName('hascontextmenu')) { if (tr!=null && tr!=document && tr.hasClassName('hascontextmenu')) {
-1
View File
@@ -783,7 +783,6 @@ background-image:url('../images/close_hl.png');
} }
.gantt_subjects { font-size: 0.8em; } .gantt_subjects { font-size: 0.8em; }
.gantt_subjects div { line-height:1.2em;height:16px;overflow:hidden;white-space:nowrap;text-overflow: ellipsis; }
.task { .task {
position: absolute; position: absolute;
-7
View File
@@ -20,10 +20,3 @@ journal_details_003:
value: "6" value: "6"
prop_key: fixed_version_id prop_key: fixed_version_id
journal_id: 4 journal_id: 4
journal_details_005:
old_value: Old value
property: cf
id: 5
value: New value
prop_key: 2
journal_id: 3
+1 -2
View File
@@ -22,8 +22,7 @@ require 'journals_controller'
class JournalsController; def rescue_action(e) raise e end; end class JournalsController; def rescue_action(e) raise e end; end
class JournalsControllerTest < ActionController::TestCase class JournalsControllerTest < ActionController::TestCase
fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules, fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules
:trackers, :issue_statuses, :enumerations, :custom_fields, :custom_values, :custom_fields_projects
def setup def setup
@controller = JournalsController.new @controller = JournalsController.new
@@ -172,12 +172,6 @@ class RepositoriesSubversionControllerTest < ActionController::TestCase
assert_error_tag :content => /was not found/ assert_error_tag :content => /was not found/
end end
def test_invalid_revision_diff
get :diff, :id => 1, :rev => '1', :rev_to => 'something_weird'
assert_response 404
assert_error_tag :content => /was not found/
end
def test_empty_revision def test_empty_revision
['', ' ', nil].each do |r| ['', ' ', nil].each do |r|
get :revision, :id => 1, :rev => r get :revision, :id => 1, :rev => r
+18 -34
View File
@@ -72,40 +72,24 @@ class ChangesetTest < ActiveSupport::TestCase
Setting.commit_ref_keywords = '*' Setting.commit_ref_keywords = '*'
Setting.commit_logtime_enabled = '1' Setting.commit_logtime_enabled = '1'
{ c = Changeset.new(:repository => Project.find(1).repository,
'2' => 2.0, :committed_on => 24.hours.ago,
'2h' => 2.0, :comments => 'Worked on this issue #1 @2h',
'2hours' => 2.0, :revision => '520',
'15m' => 0.25, :user => User.find(2))
'15min' => 0.25, assert_difference 'TimeEntry.count' do
'3h15' => 3.25, c.scan_comment_for_issue_ids
'3h15m' => 3.25,
'3h15min' => 3.25,
'3:15' => 3.25,
'3.25' => 3.25,
'3.25h' => 3.25,
'3,25' => 3.25,
'3,25h' => 3.25,
}.each do |syntax, expected_hours|
c = Changeset.new(:repository => Project.find(1).repository,
:committed_on => 24.hours.ago,
:comments => "Worked on this issue #1 @#{syntax}",
:revision => '520',
:user => User.find(2))
assert_difference 'TimeEntry.count' do
c.scan_comment_for_issue_ids
end
assert_equal [1], c.issue_ids.sort
time = TimeEntry.first(:order => 'id desc')
assert_equal 1, time.issue_id
assert_equal 1, time.project_id
assert_equal 2, time.user_id
assert_equal expected_hours, time.hours, "@#{syntax} should be logged as #{expected_hours} hours but was #{time.hours}"
assert_equal Date.yesterday, time.spent_on
assert time.activity.is_default?
assert time.comments.include?('r520'), "r520 was expected in time_entry comments: #{time.comments}"
end end
assert_equal [1], c.issue_ids.sort
time = TimeEntry.first(:order => 'id desc')
assert_equal 1, time.issue_id
assert_equal 1, time.project_id
assert_equal 2, time.user_id
assert_equal 2.0, time.hours
assert_equal Date.yesterday, time.spent_on
assert time.activity.is_default?
assert time.comments.include?('r520'), "r520 was expected in time_entry comments: #{time.comments}"
end end
def test_ref_keywords_closing_with_timelog def test_ref_keywords_closing_with_timelog
@@ -116,7 +100,7 @@ class ChangesetTest < ActiveSupport::TestCase
c = Changeset.new(:repository => Project.find(1).repository, c = Changeset.new(:repository => Project.find(1).repository,
:committed_on => Time.now, :committed_on => Time.now,
:comments => 'This is a comment. Fixes #1 @4.5, #2 @1', :comments => 'This is a comment. Fixes #1 @2.5, #2 @1',
:user => User.find(2)) :user => User.find(2))
assert_difference 'TimeEntry.count', 2 do assert_difference 'TimeEntry.count', 2 do
c.scan_comment_for_issue_ids c.scan_comment_for_issue_ids
+2 -32
View File
@@ -484,6 +484,7 @@ class QueryTest < ActiveSupport::TestCase
# Users not in a group # Users not in a group
assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')" assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IS NULL OR #{Issue.table_name}.assigned_to_id NOT IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
assert_find_issues_with_query_is_successful @query assert_find_issues_with_query_is_successful @query
end end
should "search assigned to any group member (all)" do should "search assigned to any group member (all)" do
@@ -493,22 +494,7 @@ class QueryTest < ActiveSupport::TestCase
# Only users in a group # Only users in a group
assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')" assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@user_in_group.id}','#{@second_user_in_group.id}','#{@user_in_group2.id}')"
assert_find_issues_with_query_is_successful @query assert_find_issues_with_query_is_successful @query
end
should "return an empty set with = empty group" do
@empty_group = Group.generate!
@query = Query.new(:name => '_')
@query.add_filter('member_of_group', '=', [@empty_group.id.to_s])
assert_equal [], find_issues_with_query(@query)
end
should "return issues with ! empty group" do
@empty_group = Group.generate!
@query = Query.new(:name => '_')
@query.add_filter('member_of_group', '!', [@empty_group.id.to_s])
assert_find_issues_with_query_is_successful @query
end end
end end
@@ -554,22 +540,6 @@ class QueryTest < ActiveSupport::TestCase
assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')" assert_query_statement_includes @query, "#{Issue.table_name}.assigned_to_id IN ('#{@manager.id}','#{@developer.id}','#{@boss.id}')"
assert_find_issues_with_query_is_successful @query assert_find_issues_with_query_is_successful @query
end end
should "return an empty set with empty role" do
@empty_role = Role.generate!
@query = Query.new(:name => '_')
@query.add_filter('assigned_to_role', '=', [@empty_role.id.to_s])
assert_equal [], find_issues_with_query(@query)
end
should "return issues with ! empty role" do
@empty_role = Role.generate!
@query = Query.new(:name => '_')
@query.add_filter('member_of_group', '!', [@empty_role.id.to_s])
assert_find_issues_with_query_is_successful @query
end
end end
end end
+5 -5
View File
@@ -60,15 +60,15 @@ class WatcherTest < ActiveSupport::TestCase
assert @issue.watcher_recipients.empty? assert @issue.watcher_recipients.empty?
assert @issue.add_watcher(@user) assert @issue.add_watcher(@user)
@user.mail_notification = 'all' @user.mail_notification = true
@user.save! @user.save
@issue.reload @issue.reload
assert @issue.watcher_recipients.include?(@user.mail) assert @issue.watcher_recipients.include?(@user.mail)
@user.mail_notification = 'none' @user.mail_notification = false
@user.save! @user.save
@issue.reload @issue.reload
assert !@issue.watcher_recipients.include?(@user.mail) assert @issue.watcher_recipients.include?(@user.mail)
end end
def test_unwatch def test_unwatch
+1 -2
View File
@@ -58,8 +58,7 @@ module Redmine
# Returns an array of watchers' email addresses # Returns an array of watchers' email addresses
def watcher_recipients def watcher_recipients
notified = watcher_users.active notified = watcher_users.active
notified.reject! {|user| user.mail_notification == 'none'}
if respond_to?(:visible?) if respond_to?(:visible?)
notified.reject! {|user| !visible?(user)} notified.reject! {|user| !visible?(user)}
end end