summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/application-legacy.js2
-rw-r--r--app/controllers/reactions_controller.rb2
-rw-r--r--app/helpers/avatars_helper.rb1
-rw-r--r--app/helpers/reactions_helper.rb8
-rw-r--r--app/helpers/settings_helper.rb3
-rw-r--r--app/models/reaction.rb19
-rw-r--r--app/models/user.rb17
-rw-r--r--app/views/settings/_display.html.erb22
-rw-r--r--config/locales/ar.yml2
-rw-r--r--config/locales/az.yml2
-rw-r--r--config/locales/bg.yml23
-rw-r--r--config/locales/bs.yml2
-rw-r--r--config/locales/ca.yml2
-rw-r--r--config/locales/cs.yml2
-rw-r--r--config/locales/da.yml2
-rw-r--r--config/locales/de.yml2
-rw-r--r--config/locales/el.yml2
-rw-r--r--config/locales/en-GB.yml2
-rw-r--r--config/locales/en.yml1
-rw-r--r--config/locales/es-PA.yml2
-rw-r--r--config/locales/es.yml2
-rw-r--r--config/locales/et.yml2
-rw-r--r--config/locales/eu.yml2
-rw-r--r--config/locales/fa.yml2
-rw-r--r--config/locales/fi.yml2
-rw-r--r--config/locales/fr.yml2
-rw-r--r--config/locales/gl.yml2
-rw-r--r--config/locales/he.yml2
-rw-r--r--config/locales/hr.yml2
-rw-r--r--config/locales/hu.yml2
-rw-r--r--config/locales/id.yml2
-rw-r--r--config/locales/it.yml2
-rw-r--r--config/locales/ja.yml2
-rw-r--r--config/locales/ko.yml2
-rw-r--r--config/locales/lt.yml2
-rw-r--r--config/locales/lv.yml2
-rw-r--r--config/locales/mk.yml2
-rw-r--r--config/locales/mn.yml2
-rw-r--r--config/locales/nl.yml2
-rw-r--r--config/locales/no.yml2
-rw-r--r--config/locales/pl.yml2
-rw-r--r--config/locales/pt-BR.yml2
-rw-r--r--config/locales/pt.yml2
-rw-r--r--config/locales/ro.yml2
-rw-r--r--config/locales/ru.yml2
-rw-r--r--config/locales/sk.yml2
-rw-r--r--config/locales/sl.yml2
-rw-r--r--config/locales/sq.yml2
-rw-r--r--config/locales/sr-YU.yml2
-rw-r--r--config/locales/sr.yml2
-rw-r--r--config/locales/sv.yml2
-rw-r--r--config/locales/ta-IN.yml2
-rw-r--r--config/locales/th.yml2
-rw-r--r--config/locales/tr.yml2
-rw-r--r--config/locales/uk.yml2
-rw-r--r--config/locales/vi.yml2
-rw-r--r--config/locales/zh-TW.yml2
-rw-r--r--config/locales/zh.yml2
-rw-r--r--lib/plugins/gravatar/lib/gravatar.rb2
-rw-r--r--lib/redmine/reaction.rb4
-rw-r--r--test/application_system_test_case.rb2
-rw-r--r--test/functional/issues_controller_test.rb4
-rw-r--r--test/helpers/avatars_helper_test.rb12
-rw-r--r--test/helpers/reactions_helper_test.rb12
-rw-r--r--test/unit/lib/redmine/reaction_test.rb20
-rw-r--r--test/unit/reaction_test.rb2
-rw-r--r--test/unit/user_test.rb21
67 files changed, 216 insertions, 57 deletions
diff --git a/app/assets/javascripts/application-legacy.js b/app/assets/javascripts/application-legacy.js
index 286e3e2e6..deaaa66b6 100644
--- a/app/assets/javascripts/application-legacy.js
+++ b/app/assets/javascripts/application-legacy.js
@@ -679,7 +679,7 @@ function copyDataClipboardTextToClipboard(target) {
}
function setupCopyButtonsToPreElements() {
- document.querySelectorAll('pre:not(.pre-wrapper pre)').forEach((pre) => {
+ document.querySelectorAll('.wiki pre:not(.pre-wrapper pre)').forEach((pre) => {
// Wrap the <pre> element with a container and add a copy button
const wrapper = document.createElement("div");
wrapper.classList.add("pre-wrapper");
diff --git a/app/controllers/reactions_controller.rb b/app/controllers/reactions_controller.rb
index f768f939d..71b37e5f8 100644
--- a/app/controllers/reactions_controller.rb
+++ b/app/controllers/reactions_controller.rb
@@ -60,6 +60,6 @@ class ReactionsController < ApplicationController
end
def authorize_reactable
- render_403 unless Redmine::Reaction.writable?(@object, User.current)
+ render_403 unless Redmine::Reaction.editable?(@object, User.current)
end
end
diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb
index b39427bda..88a571b62 100644
--- a/app/helpers/avatars_helper.rb
+++ b/app/helpers/avatars_helper.rb
@@ -44,6 +44,7 @@ module AvatarsHelper
if user.respond_to?(:mail)
email = user.mail
options[:title] = user.name unless options[:title]
+ options[:initials] = user.initials if options[:default] == "initials"
elsif user.to_s =~ %r{<(.+?)>}
email = $1
end
diff --git a/app/helpers/reactions_helper.rb b/app/helpers/reactions_helper.rb
index 911da7127..5c0b807ee 100644
--- a/app/helpers/reactions_helper.rb
+++ b/app/helpers/reactions_helper.rb
@@ -26,15 +26,15 @@ module ReactionsHelper
detail = object.reaction_detail
- reaction = detail.user_reaction
+ user_reaction = detail.user_reaction
count = detail.reaction_count
visible_user_names = detail.visible_users.take(DISPLAY_REACTION_USERS_LIMIT).map(&:name)
tooltip = build_reaction_tooltip(visible_user_names, count)
- if Redmine::Reaction.writable?(object, User.current)
- if reaction&.persisted?
- reaction_button_reacted(object, reaction, count, tooltip)
+ if Redmine::Reaction.editable?(object, User.current)
+ if user_reaction.present?
+ reaction_button_reacted(object, user_reaction, count, tooltip)
else
reaction_button_not_reacted(object, count, tooltip)
end
diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb
index 39a836a03..c1f989805 100644
--- a/app/helpers/settings_helper.rb
+++ b/app/helpers/settings_helper.rb
@@ -244,6 +244,7 @@ module SettingsHelper
['Mystery man', 'mm'],
['Retro', 'retro'],
['Robohash', 'robohash'],
- ['Wavatars', 'wavatar']]
+ ['Wavatars', 'wavatar'],
+ ['Initials', 'initials']]
end
end
diff --git a/app/models/reaction.rb b/app/models/reaction.rb
index 84c982043..184ed2d6e 100644
--- a/app/models/reaction.rb
+++ b/app/models/reaction.rb
@@ -25,39 +25,34 @@ class Reaction < ApplicationRecord
scope :by, ->(user) { where(user: user) }
scope :for_reactable, ->(reactable) { where(reactable: reactable) }
+ scope :visible, ->(user) { where(user: User.visible(user)) }
# Represents reaction details for a reactable object
Detail = Struct.new(
- # Total number of reactions
- :reaction_count,
# Users who reacted and are visible to the target user
:visible_users,
# Reaction of the target user
:user_reaction
) do
- def initialize(reaction_count: 0, visible_users: [], user_reaction: nil)
+ def initialize(visible_users: [], user_reaction: nil)
super
end
+
+ def reaction_count = visible_users.size
end
def self.build_detail_map_for(reactables, user)
- reactions = preload(:user)
+ reactions = visible(user)
.for_reactable(reactables)
+ .preload(:user)
.select(:id, :reactable_id, :user_id)
.order(id: :desc)
- # Prepare IDs of users who reacted and are visible to the user
- visible_user_ids = User.visible(user)
- .joins(:reactions)
- .where(reactions: for_reactable(reactables))
- .pluck(:id).to_set
-
reactions.each_with_object({}) do |reaction, m|
m[reaction.reactable_id] ||= Detail.new
m[reaction.reactable_id].then do |detail|
- detail.reaction_count += 1
- detail.visible_users << reaction.user if visible_user_ids.include?(reaction.user.id)
+ detail.visible_users << reaction.user
detail.user_reaction = reaction if reaction.user == user
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 9f74a60fb..c1a860f5a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -28,46 +28,55 @@ class User < Principal
USER_FORMATS = {
:firstname_lastname => {
:string => '#{firstname} #{lastname}',
+ :initials => '#{firstname.to_s.first}#{lastname.to_s.first}',
:order => %w(firstname lastname id),
:setting_order => 1
},
:firstname_lastinitial => {
:string => '#{firstname} #{lastname.to_s.chars.first}.',
+ :initials => '#{firstname.to_s.first}#{lastname.to_s.first}',
:order => %w(firstname lastname id),
:setting_order => 2
},
:firstinitial_lastname => {
:string => '#{firstname.to_s.gsub(/(([[:alpha:]])[[:alpha:]]*\.?)/, \'\2.\')} #{lastname}',
+ :initials => '#{firstname.to_s.gsub(/(([[:alpha:]])[[:alpha:]]*\.?)/, \'\2.\').first}#{lastname.to_s.first}',
:order => %w(firstname lastname id),
:setting_order => 2
},
:firstname => {
:string => '#{firstname}',
+ :initials => '#{firstname.to_s.first(2)}',
:order => %w(firstname id),
:setting_order => 3
},
:lastname_firstname => {
:string => '#{lastname} #{firstname}',
+ :initials => '#{lastname.to_s.first}#{firstname.to_s.first}',
:order => %w(lastname firstname id),
:setting_order => 4
},
:lastnamefirstname => {
:string => '#{lastname}#{firstname}',
+ :initials => '#{lastname.to_s.first}#{firstname.to_s.first}',
:order => %w(lastname firstname id),
:setting_order => 5
},
:lastname_comma_firstname => {
:string => '#{lastname}, #{firstname}',
+ :initials => '#{lastname.to_s.first}#{firstname.to_s.first}',
:order => %w(lastname firstname id),
:setting_order => 6
},
:lastname => {
:string => '#{lastname}',
+ :initials => '#{lastname.to_s.first(2)}',
:order => %w(lastname id),
:setting_order => 7
},
:username => {
:string => '#{login}',
+ :initials => '#{login.to_s.first(2)}',
:order => %w(login id),
:setting_order => 8
},
@@ -275,6 +284,14 @@ class User < Principal
end
end
+ # Return user's initials based on name format
+ def initials(formatter = nil)
+ f = self.class.name_formatter(formatter)
+ format = f[:initials] || USER_FORMATS[:firstname_lastname][:initials]
+ initials = eval('"' + format + '"')
+ initials.upcase
+ end
+
def registered?
self.status == STATUS_REGISTERED
end
diff --git a/app/views/settings/_display.html.erb b/app/views/settings/_display.html.erb
index 62c53dfbb..3b2f95798 100644
--- a/app/views/settings/_display.html.erb
+++ b/app/views/settings/_display.html.erb
@@ -22,7 +22,12 @@
<p><%= setting_check_box :gravatar_enabled, :data => {:enables => '#settings_gravatar_default'} %>
<em class="info"><%= t(:text_avatar_server_config_html, :url => Redmine::Configuration['avatar_server_url']) %></em></p>
-<p><%= setting_select :gravatar_default, gravatar_default_setting_options, :blank => :label_none %></p>
+<p>
+ <%= setting_select :gravatar_default, gravatar_default_setting_options, :blank => :label_none %>
+ <em class="<%= Setting.gravatar_default == "initials" ? "info" : "hidden" %>">
+ <%= t(:text_setting_gravatar_default_initials_html) %>
+ </em>
+</p>
<p><%= setting_check_box :thumbnails_enabled, :data => {:enables => '#settings_thumbnails_size'} %></p>
@@ -35,3 +40,18 @@
<%= submit_tag l(:button_save) %>
<% end %>
+
+<%= javascript_tag do %>
+ $('#settings_gravatar_default').on('change', function(e){
+ const gravatar_default = e.target.value;
+ const em = e.target.parentElement.getElementsByTagName('em')[0];
+
+ if (gravatar_default === 'initials') {
+ em.classList.remove('hidden');
+ em.classList.add('info');
+ } else {
+ em.classList.add('hidden');
+ em.classList.remove('info');
+ }
+ });
+<% end %> \ No newline at end of file
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index e291b2cf7..b3c5e11cc 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -1511,3 +1511,5 @@ ar:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/az.yml b/config/locales/az.yml
index ca5ba2e71..68c1669a1 100644
--- a/config/locales/az.yml
+++ b/config/locales/az.yml
@@ -1602,3 +1602,5 @@ az:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 3d7ee8f1a..0a310a9b8 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -211,6 +211,7 @@ bg:
error_can_not_delete_custom_field: Невъзможност за изтриване на потребителско поле
error_can_not_delete_tracker_html: Този тракер съдържа задачи и не може да бъде изтрит.<p>The following projects have issues with this tracker:<br>%{projects}</p>
error_can_not_remove_role: Тази роля се използва и не може да бъде изтрита.
+ error_can_not_remove_role_reason_members_html: "<p>Следващите проекти имат членове с тази роля:<br>%{projects}</p>"
error_can_not_reopen_issue_on_closed_version: Задача, асоциирана със затворена версия не може да бъде отворена отново
error_can_not_archive_project: Този проект не може да бъде архивиран
error_issue_done_ratios_not_updated: Процентът на завършените задачи не е обновен.
@@ -239,6 +240,7 @@ bg:
error_exceeds_maximum_hours_per_day: Не можете да запишете повече от %{max_hours} часа на един ден (%{logged_hours} часове вече са записани)
error_can_not_delete_auth_source: Този режим за идентификация се използва и не може да бъде премахнат.
error_spent_on_future_date: Не е възможно да се отчете изразходвано време на дата в бъдещето
+ error_spent_on_closed_issue: Не е възможно да се отчете изразходвано време за затворена задача
error_not_allowed_to_log_time_for_other_users: Вие нямате разрешение да записвате изразходвано време за други потребители
error_can_not_execute_macro_html: Грешка при изпълнение на <strong>%{name}</strong> макрос
(%{error})
@@ -523,9 +525,13 @@ bg:
setting_timelog_accept_0_hours: Приемане на записи с 0 часа
setting_timelog_max_hours_per_day: Максимум часове, които могат да бъдат записани за ден и за потребител
setting_timelog_accept_future_dates: Разрешено отчитане на изразходвано време на дата в бъдещето
+ setting_timelog_accept_closed_issues: Разрешено отчитане на изразходвано време за затворени задачи
setting_show_status_changes_in_mail_subject: Показване на промените на състоянието на задачите в поле Относно на имейлите
setting_project_list_defaults: Проектен списък
setting_twofa: Двуфакторна автентикация
+ setting_related_issues_default_columns: Колони по подразбиране за свързани и подзадачи
+ setting_display_related_issues_table_headers: Показване на заглавия на таблиците
+ setting_reactions_enabled: Разрешаване на реакциите
permission_add_project: Създаване на проект
permission_add_subprojects: Създаване на подпроекти
@@ -1390,6 +1396,7 @@ bg:
label_import_time_entries: Импортиране на записи за използвано време
label_import_users: Импортиране на потребители
sudo_mode_new_info_html: "<strong>Какво се случва?</strong> Трябва да потвърдите вашата парола преди да предприемете административни действия. Това осигурява вашият акаунт."
+ label_progressbar: Прогрес бар
twofa__totp__name: Authenticator app
twofa__totp__text_pairing_info_html: Сканирайте този QR код или въведете текстовия ключ
@@ -1444,15 +1451,9 @@ bg:
За да потвърдите, въведете името (%{login}) по-долу.
text_project_destroy_enter_identifier: За да потвърдите действието, въведете идентификатора на проекта (%{identifier}) по-долу.
field_name_or_email_or_login: Име, e-mail или login име
- setting_wiki_tablesort_enabled: Javascript based table sorting in wiki content
- label_progressbar: Progress bar
- error_spent_on_closed_issue: Cannot log time on a closed issue
- setting_timelog_accept_closed_issues: Accept time logs on closed issues
- setting_related_issues_default_columns: Related and sub issues list defaults
- setting_display_related_issues_table_headers: Show table headers
- error_can_not_remove_role_reason_members_html: "<p>The following projects have members
- with this role:<br>%{projects}</p>"
- setting_reactions_enabled: Enable reactions
+ setting_wiki_tablesort_enabled: Сортиране на таблици чрез Javascript във wiki страници
reaction_text_x_other_users:
- one: 1 other
- other: "%{count} others"
+ one: 1 друг
+ other: "%{count} други"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/bs.yml b/config/locales/bs.yml
index d1c0a5cec..df4886133 100644
--- a/config/locales/bs.yml
+++ b/config/locales/bs.yml
@@ -1497,3 +1497,5 @@ bs:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index fc0345104..30204cda2 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -1498,3 +1498,5 @@ ca:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index c5e4d679d..4101a8a3d 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -1493,3 +1493,5 @@ cs:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/da.yml b/config/locales/da.yml
index 0f577d1bd..c053f2e43 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -1528,3 +1528,5 @@ da:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/de.yml b/config/locales/de.yml
index c320099dc..5b0f9bd35 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -1475,3 +1475,5 @@ de:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/el.yml b/config/locales/el.yml
index df14ae051..a99dcc6bb 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -1511,3 +1511,5 @@ el:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml
index 3a119d7a2..2084749f4 100644
--- a/config/locales/en-GB.yml
+++ b/config/locales/en-GB.yml
@@ -1512,3 +1512,5 @@ en-GB:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 5f7291593..dca278e23 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1342,6 +1342,7 @@ en:
text_no_subject: no subject
text_allowed_queries_to_select: Public (to any users) queries only selectable
text_setting_config_change: You can configure the behaviour in config/configuration.yml. Please restart the application after editing it.
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a> to generate their avatars.
default_role_manager: Manager
default_role_developer: Developer
diff --git a/config/locales/es-PA.yml b/config/locales/es-PA.yml
index 195f8df94..4ba2fb881 100644
--- a/config/locales/es-PA.yml
+++ b/config/locales/es-PA.yml
@@ -1542,3 +1542,5 @@ es-PA:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 4539055d5..1f4b20047 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -1578,3 +1578,5 @@ es:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/et.yml b/config/locales/et.yml
index d503f28ce..d842dbb93 100644
--- a/config/locales/et.yml
+++ b/config/locales/et.yml
@@ -1516,3 +1516,5 @@ et:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index 1334715ee..fd706c42c 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -1512,3 +1512,5 @@ eu:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index 71f617f3c..48e2ff769 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -1445,3 +1445,5 @@ fa:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 01249963b..470c40c6e 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -1529,3 +1529,5 @@ fi:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 6093796b6..602546b5a 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -1488,3 +1488,5 @@ fr:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index ef76a3dab..9ca59ab25 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -1517,3 +1517,5 @@ gl:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/he.yml b/config/locales/he.yml
index 62b9f78b7..c2886f451 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -1516,3 +1516,5 @@ he:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/hr.yml b/config/locales/hr.yml
index 04dc5717a..61456ac24 100644
--- a/config/locales/hr.yml
+++ b/config/locales/hr.yml
@@ -1508,3 +1508,5 @@ hr:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index ecde7c812..b3852a60e 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -1500,3 +1500,5 @@
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/id.yml b/config/locales/id.yml
index 9ac93271f..1a3080b69 100644
--- a/config/locales/id.yml
+++ b/config/locales/id.yml
@@ -1513,3 +1513,5 @@ id:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/it.yml b/config/locales/it.yml
index ff63fbf98..bd71f356c 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -1450,3 +1450,5 @@ it:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 9bb11c884..c088546c3 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -1461,3 +1461,5 @@ ja:
reaction_text_x_other_users:
one: 他1人
other: "他%{count}人"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index 04f44e11c..af8311a39 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -1528,3 +1528,5 @@ ko:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
index 5ef2561f0..b3d741048 100644
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -1472,3 +1472,5 @@ lt:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index d813060f4..85b660821 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -1505,3 +1505,5 @@ lv:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/mk.yml b/config/locales/mk.yml
index f75c6f92b..eeb0b17c6 100644
--- a/config/locales/mk.yml
+++ b/config/locales/mk.yml
@@ -1511,3 +1511,5 @@ mk:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/mn.yml b/config/locales/mn.yml
index 4bf0d3755..fe451153e 100644
--- a/config/locales/mn.yml
+++ b/config/locales/mn.yml
@@ -1511,3 +1511,5 @@ mn:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 3ba829886..66f729afc 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -1486,3 +1486,5 @@ nl:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 96f2591c5..85151f8d7 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -1502,3 +1502,5 @@
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index 0a048d896..934c824f1 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -1455,3 +1455,5 @@ pl:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 46f766a7d..e7172c32b 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -1516,3 +1516,5 @@ pt-BR:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/pt.yml b/config/locales/pt.yml
index e3ec71bae..2bd109c28 100644
--- a/config/locales/pt.yml
+++ b/config/locales/pt.yml
@@ -1504,3 +1504,5 @@ pt:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/ro.yml b/config/locales/ro.yml
index 1de200dfd..95bd68520 100644
--- a/config/locales/ro.yml
+++ b/config/locales/ro.yml
@@ -1506,3 +1506,5 @@ ro:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 3dbe719fc..60504bbae 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -1580,3 +1580,5 @@ ru:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index d7ca435fb..c6b6b91c0 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -1500,3 +1500,5 @@ sk:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index 1879c3f99..0c5e1e1ec 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -1511,3 +1511,5 @@ sl:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index b0f4991f0..55f577441 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -1473,3 +1473,5 @@ sq:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/sr-YU.yml b/config/locales/sr-YU.yml
index 91926f1f3..7c049c178 100644
--- a/config/locales/sr-YU.yml
+++ b/config/locales/sr-YU.yml
@@ -1513,3 +1513,5 @@ sr-YU:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 109e60f74..43ca65c14 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -1512,3 +1512,5 @@ sr:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 2afeb2dcf..54a0e4024 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -1544,3 +1544,5 @@ sv:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/ta-IN.yml b/config/locales/ta-IN.yml
index cbac93a2f..526209edb 100644
--- a/config/locales/ta-IN.yml
+++ b/config/locales/ta-IN.yml
@@ -1466,3 +1466,5 @@ ta-IN:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 89fb4c70d..12232eb22 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -1507,3 +1507,5 @@ th:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index d5ab86b79..9d710f971 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -1510,3 +1510,5 @@ tr:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index d1218083d..4a7f70b47 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -1499,3 +1499,5 @@ uk:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index 6f08cad0c..c96dbd5c4 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -1515,3 +1515,5 @@ vi:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 906c11be6..efce04fa1 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -1525,3 +1525,5 @@
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/config/locales/zh.yml b/config/locales/zh.yml
index 84ba6e80f..9f0cd8ef1 100644
--- a/config/locales/zh.yml
+++ b/config/locales/zh.yml
@@ -1447,3 +1447,5 @@ zh:
reaction_text_x_other_users:
one: 1 other
other: "%{count} others"
+ text_setting_gravatar_default_initials_html: Users' initials are sent to <a href="https://www.gravatar.com">https://www.gravatar.com</a>
+ to generate their avatars.
diff --git a/lib/plugins/gravatar/lib/gravatar.rb b/lib/plugins/gravatar/lib/gravatar.rb
index 4dc27db52..316a01b19 100644
--- a/lib/plugins/gravatar/lib/gravatar.rb
+++ b/lib/plugins/gravatar/lib/gravatar.rb
@@ -69,7 +69,7 @@ module GravatarHelper
options[:default] = CGI::escape(options[:default]) unless options[:default].nil?
gravatar_api_url(email_hash).tap do |url|
opts = []
- [:rating, :size, :default].each do |opt|
+ [:rating, :size, :default, :initials].each do |opt|
unless options[opt].nil?
value = h(options[opt])
opts << [opt, value].join('=')
diff --git a/lib/redmine/reaction.rb b/lib/redmine/reaction.rb
index b6f2bf075..09fb78ef8 100644
--- a/lib/redmine/reaction.rb
+++ b/lib/redmine/reaction.rb
@@ -22,13 +22,13 @@ module Redmine
# Types of objects that can have reactions
REACTABLE_TYPES = %w(Journal Issue Message News Comment)
- # Returns true if the user can view the reaction information of the object
+ # Returns true if the user can view the reaction of the object
def self.visible?(object, user = User.current)
Setting.reactions_enabled? && object.visible?(user)
end
# Returns true if the user can add/remove a reaction to/from the object
- def self.writable?(object, user = User.current)
+ def self.editable?(object, user = User.current)
user.logged? && visible?(object, user) && object&.project&.active?
end
diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb
index 040667c39..38d69e7c8 100644
--- a/test/application_system_test_case.rb
+++ b/test/application_system_test_case.rb
@@ -72,8 +72,8 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
# Should not depend on locale since Redmine displays login page
# using default browser locale which depend on system locale for "real" browsers drivers
def log_user(login, password)
+ visit '/my/page'
assert_current_path '/login', :ignore_query => true
- assert_equal '/login', current_path
within('#login-form form') do
fill_in 'username', :with => login
fill_in 'password', :with => password
diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb
index b7e0321d4..1230ec1eb 100644
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -3347,8 +3347,8 @@ class IssuesControllerTest < Redmine::ControllerTest
# The current_user can only see members who belong to projects that the current_user has access to.
# Since the Redmine Admin user does not belong to any projects visible to the current_user,
# the Redmine Admin user's name is not displayed in the reaction user list. Instead, "1 other" is shown.
- assert_select 'a.reaction-button[title=?]', 'Dave Lopper, John Smith, and 1 other' do
- assert_select 'span.icon-label', '3'
+ assert_select 'a.reaction-button[title=?]', 'Dave Lopper and John Smith' do
+ assert_select 'span.icon-label', '2'
end
end
diff --git a/test/helpers/avatars_helper_test.rb b/test/helpers/avatars_helper_test.rb
index f407ae09e..baa64a653 100644
--- a/test/helpers/avatars_helper_test.rb
+++ b/test/helpers/avatars_helper_test.rb
@@ -68,6 +68,18 @@ class AvatarsHelperTest < Redmine::HelperTest
assert_include 'class="gravatar picture"', avatar('jsmith <jsmith@somenet.foo>', :class => 'picture')
end
+ def test_avatar_with_initials
+ with_settings :gravatar_default => 'initials' do
+ assert_include 'initials="RA"', avatar(User.find(1))
+ end
+ end
+
+ def test_avatar_should_reject_initials_if_default_is_not_initials
+ with_settings :gravatar_default => 'identicon' do
+ assert_not_include 'initials="RA"', avatar(User.find(1))
+ end
+ end
+
def test_avatar_disabled
with_settings :gravatar_enabled => '0' do
assert_equal '', avatar(User.find_by_mail('jsmith@somenet.foo'))
diff --git a/test/helpers/reactions_helper_test.rb b/test/helpers/reactions_helper_test.rb
index f3a4e38d8..ab722e3ca 100644
--- a/test/helpers/reactions_helper_test.rb
+++ b/test/helpers/reactions_helper_test.rb
@@ -106,12 +106,10 @@ class ReactionsHelperTest < ActionView::TestCase
assert_select_in result, 'a.reaction-button[title=?]', expected_tooltip
end
- test 'reaction_button displays non-visible users as "X other" in the tooltip' do
+ test 'reaction_button should not count and display non-visible users' do
issue2 = issues(:issues_002)
issue2.reaction_detail = Reaction::Detail.new(
- # The remaining 3 users are non-visible users
- reaction_count: 5,
visible_users: users(:users_002, :users_003)
)
@@ -119,11 +117,10 @@ class ReactionsHelperTest < ActionView::TestCase
reaction_button(issue2)
end
- assert_select_in result, 'a.reaction-button[title=?]', 'John Smith, Dave Lopper, and 3 others'
+ assert_select_in result, 'a.reaction-button[title=?]', 'John Smith and Dave Lopper'
# When all users are non-visible users
issue2.reaction_detail = Reaction::Detail.new(
- reaction_count: 2,
visible_users: []
)
@@ -131,7 +128,10 @@ class ReactionsHelperTest < ActionView::TestCase
reaction_button(issue2)
end
- assert_select_in result, 'a.reaction-button[title=?]', '2 others'
+ assert_select_in result, 'a.reaction-button[title]', false
+ assert_select_in result, 'a.reaction-button' do
+ assert_select 'span.icon-label', '0'
+ end
end
test 'reaction_button formats the tooltip content based on the support.array settings of each locale' do
diff --git a/test/unit/lib/redmine/reaction_test.rb b/test/unit/lib/redmine/reaction_test.rb
index bed4600d0..f3228a3bd 100644
--- a/test/unit/lib/redmine/reaction_test.rb
+++ b/test/unit/lib/redmine/reaction_test.rb
@@ -42,7 +42,6 @@ class Redmine::ReactionTest < ActiveSupport::TestCase
Issue.preload_reaction_details([issue1, issue2])
expected_issue1_reaction_detail = Reaction::Detail.new(
- reaction_count: 3,
visible_users: [users(:users_003), users(:users_002), users(:users_001)],
user_reaction: reactions(:reaction_002)
)
@@ -53,7 +52,6 @@ class Redmine::ReactionTest < ActiveSupport::TestCase
# Even when an object has no reactions, an empty ReactionDetail is set.
assert_equal Reaction::Detail.new(
- reaction_count: 0,
visible_users: [],
user_reaction: nil
), issue2.reaction_detail
@@ -107,7 +105,6 @@ class Redmine::ReactionTest < ActiveSupport::TestCase
assert_nil message7.instance_variable_get(:@reaction_detail)
assert_equal Reaction::Detail.new(
- reaction_count: 1,
visible_users: [users(:users_002)],
user_reaction: reactions(:reaction_009)
), message7.reaction_detail
@@ -122,7 +119,6 @@ class Redmine::ReactionTest < ActiveSupport::TestCase
comment1.load_reaction_detail
assert_equal Reaction::Detail.new(
- reaction_count: 1,
visible_users: [users(:users_002)],
user_reaction: nil
), comment1.reaction_detail
@@ -153,7 +149,7 @@ class Redmine::ReactionTest < ActiveSupport::TestCase
assert_not Redmine::Reaction.visible?(object, user)
end
- test 'writable? returns true for various reactable objects when user is logged in, object is visible, and project is active' do
+ test 'editable? returns true for various reactable objects when user is logged in, object is visible, and project is active' do
reactable_objects = {
issue: issues(:issues_007),
message: messages(:messages_001),
@@ -164,30 +160,30 @@ class Redmine::ReactionTest < ActiveSupport::TestCase
user = users(:users_002)
reactable_objects.each do |type, object|
- assert Redmine::Reaction.writable?(object, user), "Expected writable? to return true for #{type}"
+ assert Redmine::Reaction.editable?(object, user), "Expected editable? to return true for #{type}"
end
end
- test 'writable? returns false when user is not logged in' do
+ test 'editable? returns false when user is not logged in' do
object = issues(:issues_007)
user = User.anonymous
- assert_not Redmine::Reaction.writable?(object, user)
+ assert_not Redmine::Reaction.editable?(object, user)
end
- test 'writable? returns false when project is inactive' do
+ test 'editable? returns false when project is inactive' do
object = issues(:issues_007)
user = users(:users_002)
object.project.update!(status: Project::STATUS_ARCHIVED)
- assert_not Redmine::Reaction.writable?(object, user)
+ assert_not Redmine::Reaction.editable?(object, user)
end
- test 'writable? returns false when project is closed' do
+ test 'editable? returns false when project is closed' do
object = issues(:issues_007)
user = users(:users_002)
object.project.update!(status: Project::STATUS_CLOSED)
- assert_not Redmine::Reaction.writable?(object, user)
+ assert_not Redmine::Reaction.editable?(object, user)
end
end
diff --git a/test/unit/reaction_test.rb b/test/unit/reaction_test.rb
index 2690da351..9b3da0738 100644
--- a/test/unit/reaction_test.rb
+++ b/test/unit/reaction_test.rb
@@ -75,12 +75,10 @@ class ReactionTest < ActiveSupport::TestCase
expected = {
1 => Reaction::Detail.new(
- reaction_count: 3,
visible_users: [users(:users_003), users(:users_002), users(:users_001)],
user_reaction: reactions(:reaction_003)
),
6 => Reaction::Detail.new(
- reaction_count: 1,
visible_users: [users(:users_002)],
user_reaction: nil
)
diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb
index aeae62df8..8474e174b 100644
--- a/test/unit/user_test.rb
+++ b/test/unit/user_test.rb
@@ -589,6 +589,27 @@ class UserTest < ActiveSupport::TestCase
end
end
+ def test_initials_format
+ assert_equal 'JS', @jsmith.initials(:firstname_lastinitial)
+ assert_equal 'SJ', @jsmith.initials(:lastname_comma_firstname)
+ assert_equal 'SJ', @jsmith.initials(:lastname_firstname)
+ assert_equal 'JS', @jsmith.initials(:firstinitial_lastname)
+ assert_equal 'JL', User.new(:firstname => 'Jean-Philippe', :lastname => 'Lang').initials(:firstinitial_lastname)
+ assert_equal 'JS', @jsmith.initials(:undefined_format)
+ end
+
+ def test_initials_should_use_setting_as_default_format
+ with_settings :user_format => :firstname_lastname do
+ assert_equal 'JS', @jsmith.reload.initials
+ end
+ with_settings :user_format => :username do
+ assert_equal 'JS', @jsmith.reload.initials
+ end
+ with_settings :user_format => :lastname do
+ assert_equal 'SM', @jsmith.reload.initials
+ end
+ end
+
def test_lastname_should_accept_255_characters
u = User.first
u.lastname = 'a' * 255