mirror of
https://github.com/meineerde/redmine.git
synced 2025-10-17 17:01:01 +00:00
Add support for multiple email addresses per user (#4244).
git-svn-id: http://svn.redmine.org/redmine/trunk@13886 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
7f29c2fd88
commit
e3618bdbec
105
app/controllers/email_addresses_controller.rb
Normal file
105
app/controllers/email_addresses_controller.rb
Normal file
@ -0,0 +1,105 @@
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2015 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class EmailAddressesController < ApplicationController
|
||||
before_filter :find_user, :require_admin_or_current_user
|
||||
before_filter :find_email_address, :only => [:update, :destroy]
|
||||
|
||||
def index
|
||||
@addresses = @user.email_addresses.order(:id).where(:is_default => false).to_a
|
||||
@address ||= EmailAddress.new
|
||||
end
|
||||
|
||||
def create
|
||||
saved = false
|
||||
if @user.email_addresses.count <= Setting.max_additional_emails.to_i
|
||||
@address = EmailAddress.new(:user => @user, :is_default => false)
|
||||
attrs = params[:email_address]
|
||||
if attrs.is_a?(Hash)
|
||||
@address.address = attrs[:address].to_s
|
||||
end
|
||||
saved = @address.save
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
if saved
|
||||
redirect_to user_email_addresses_path(@user)
|
||||
else
|
||||
index
|
||||
render :action => 'index'
|
||||
end
|
||||
}
|
||||
format.js {
|
||||
@address = nil if saved
|
||||
index
|
||||
render :action => 'index'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if params[:notify].present?
|
||||
@address.notify = params[:notify].to_s
|
||||
end
|
||||
@address.save
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
redirect_to user_email_addresses_path(@user)
|
||||
}
|
||||
format.js {
|
||||
@address = nil
|
||||
index
|
||||
render :action => 'index'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@address.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
redirect_to user_email_addresses_path(@user)
|
||||
}
|
||||
format.js {
|
||||
@address = nil
|
||||
index
|
||||
render :action => 'index'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_user
|
||||
@user = User.find(params[:user_id])
|
||||
end
|
||||
|
||||
def find_email_address
|
||||
@address = @user.email_addresses.where(:is_default => false).find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def require_admin_or_current_user
|
||||
unless @user == User.current
|
||||
require_admin
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -41,7 +41,7 @@ class UsersController < ApplicationController
|
||||
|
||||
@status = params[:status] || 1
|
||||
|
||||
scope = User.logged.status(@status)
|
||||
scope = User.logged.status(@status).preload(:email_address)
|
||||
scope = scope.like(params[:name]) if params[:name].present?
|
||||
scope = scope.in_group(params[:group_id]) if params[:group_id].present?
|
||||
|
||||
|
||||
38
app/helpers/email_addresses_helper.rb
Normal file
38
app/helpers/email_addresses_helper.rb
Normal file
@ -0,0 +1,38 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2015 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
module EmailAddressesHelper
|
||||
|
||||
# Returns a link to enable or disable notifications for the address
|
||||
def toggle_email_address_notify_link(address)
|
||||
if address.notify?
|
||||
link_to image_tag('email.png'),
|
||||
user_email_address_path(address.user, address, :notify => '0'),
|
||||
:method => :put,
|
||||
:title => l(:label_disable_notifications),
|
||||
:remote => true
|
||||
else
|
||||
link_to image_tag('email_disabled.png'),
|
||||
user_email_address_path(address.user, address, :notify => '1'),
|
||||
:method => :put,
|
||||
:title => l(:label_enable_notifications),
|
||||
:remote => true
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -42,6 +42,12 @@ module UsersHelper
|
||||
end
|
||||
end
|
||||
|
||||
def additional_emails_link(user)
|
||||
if user.email_addresses.count > 1 || Setting.max_additional_emails.to_i > 0
|
||||
link_to l(:label_email_address_plural), user_email_addresses_path(@user), :class => 'icon icon-email-add', :remote => true
|
||||
end
|
||||
end
|
||||
|
||||
def user_settings_tabs
|
||||
tabs = [{:name => 'general', :partial => 'users/general', :label => :label_general},
|
||||
{:name => 'memberships', :partial => 'users/memberships', :label => :label_project_plural}
|
||||
|
||||
@ -60,6 +60,10 @@ class Document < ActiveRecord::Base
|
||||
@updated_on
|
||||
end
|
||||
|
||||
def notified_users
|
||||
project.notified_users.reject {|user| !visible?(user)}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def send_notification
|
||||
|
||||
54
app/models/email_address.rb
Normal file
54
app/models/email_address.rb
Normal file
@ -0,0 +1,54 @@
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2015 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class EmailAddress < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
attr_protected :id
|
||||
|
||||
after_update :destroy_tokens
|
||||
after_destroy :destroy_tokens
|
||||
|
||||
validates_presence_of :address
|
||||
validates_format_of :address, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
|
||||
validates_length_of :address, :maximum => User::MAIL_LENGTH_LIMIT, :allow_nil => true
|
||||
validates_uniqueness_of :address, :case_sensitive => false,
|
||||
:if => Proc.new {|email| email.address_changed? && email.address.present?}
|
||||
|
||||
def address=(arg)
|
||||
write_attribute(:address, arg.to_s.strip)
|
||||
end
|
||||
|
||||
def destroy
|
||||
if is_default?
|
||||
false
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Delete all outstanding password reset tokens on email change.
|
||||
# This helps to keep the account secure in case the associated email account
|
||||
# was compromised.
|
||||
def destroy_tokens
|
||||
if address_changed? || destroyed?
|
||||
tokens = ['recovery']
|
||||
Token.where(:user_id => user_id, :action => tokens).delete_all
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -306,7 +306,7 @@ class MailHandler < ActionMailer::Base
|
||||
if user.allowed_to?("add_#{obj.class.name.underscore}_watchers".to_sym, obj.project)
|
||||
addresses = [email.to, email.cc].flatten.compact.uniq.collect {|a| a.strip.downcase}
|
||||
unless addresses.empty?
|
||||
User.active.where('LOWER(mail) IN (?)', addresses).each do |w|
|
||||
User.active.having_mail(addresses).each do |w|
|
||||
obj.add_watcher(w)
|
||||
end
|
||||
end
|
||||
|
||||
@ -39,8 +39,8 @@ class Mailer < ActionMailer::Base
|
||||
@issue = issue
|
||||
@users = to_users + cc_users
|
||||
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
|
||||
mail :to => to_users.map(&:mail),
|
||||
:cc => cc_users.map(&:mail),
|
||||
mail :to => to_users,
|
||||
:cc => cc_users,
|
||||
:subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
|
||||
end
|
||||
|
||||
@ -71,8 +71,8 @@ class Mailer < ActionMailer::Base
|
||||
@journal = journal
|
||||
@journal_details = journal.visible_details(@users.first)
|
||||
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
|
||||
mail :to => to_users.map(&:mail),
|
||||
:cc => cc_users.map(&:mail),
|
||||
mail :to => to_users,
|
||||
:cc => cc_users,
|
||||
:subject => s
|
||||
end
|
||||
|
||||
@ -95,7 +95,7 @@ class Mailer < ActionMailer::Base
|
||||
@issues_url = url_for(:controller => 'issues', :action => 'index',
|
||||
:set_filter => 1, :assigned_to_id => user.id,
|
||||
:sort => 'due_date:asc')
|
||||
mail :to => user.mail,
|
||||
mail :to => user,
|
||||
:subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
|
||||
end
|
||||
|
||||
@ -109,7 +109,7 @@ class Mailer < ActionMailer::Base
|
||||
@author = User.current
|
||||
@document = document
|
||||
@document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
|
||||
mail :to => document.recipients,
|
||||
mail :to => document.notified_users,
|
||||
:subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
|
||||
end
|
||||
|
||||
@ -127,15 +127,15 @@ class Mailer < ActionMailer::Base
|
||||
when 'Project'
|
||||
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
|
||||
added_to = "#{l(:label_project)}: #{container}"
|
||||
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
|
||||
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
|
||||
when 'Version'
|
||||
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
|
||||
added_to = "#{l(:label_version)}: #{container.name}"
|
||||
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}.collect {|u| u.mail}
|
||||
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
|
||||
when 'Document'
|
||||
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
|
||||
added_to = "#{l(:label_document)}: #{container.title}"
|
||||
recipients = container.recipients
|
||||
recipients = container.notified_users
|
||||
end
|
||||
redmine_headers 'Project' => container.project.identifier
|
||||
@attachments = attachments
|
||||
@ -157,8 +157,8 @@ class Mailer < ActionMailer::Base
|
||||
references news
|
||||
@news = news
|
||||
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
|
||||
mail :to => news.recipients,
|
||||
:cc => news.cc_for_added_news,
|
||||
mail :to => news.notified_users,
|
||||
:cc => news.notified_watchers_for_added_news,
|
||||
:subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
||||
end
|
||||
|
||||
@ -176,8 +176,8 @@ class Mailer < ActionMailer::Base
|
||||
@news = news
|
||||
@comment = comment
|
||||
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
|
||||
mail :to => news.recipients,
|
||||
:cc => news.watcher_recipients,
|
||||
mail :to => news.notified_users,
|
||||
:cc => news.notified_watchers,
|
||||
:subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
||||
end
|
||||
|
||||
@ -192,8 +192,8 @@ class Mailer < ActionMailer::Base
|
||||
@author = message.author
|
||||
message_id message
|
||||
references message.root
|
||||
recipients = message.recipients
|
||||
cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients)
|
||||
recipients = message.notified_users
|
||||
cc = ((message.root.notified_watchers + message.board.notified_watchers).uniq - recipients)
|
||||
@message = message
|
||||
@message_url = url_for(message.event_url)
|
||||
mail :to => recipients,
|
||||
@ -211,8 +211,8 @@ class Mailer < ActionMailer::Base
|
||||
'Wiki-Page-Id' => wiki_content.page.id
|
||||
@author = wiki_content.author
|
||||
message_id wiki_content
|
||||
recipients = wiki_content.recipients
|
||||
cc = wiki_content.page.wiki.watcher_recipients - recipients
|
||||
recipients = wiki_content.notified_users
|
||||
cc = wiki_content.page.wiki.notified_watchers - recipients
|
||||
@wiki_content = wiki_content
|
||||
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
|
||||
:project_id => wiki_content.project,
|
||||
@ -232,8 +232,8 @@ class Mailer < ActionMailer::Base
|
||||
'Wiki-Page-Id' => wiki_content.page.id
|
||||
@author = wiki_content.author
|
||||
message_id wiki_content
|
||||
recipients = wiki_content.recipients
|
||||
cc = wiki_content.page.wiki.watcher_recipients + wiki_content.page.watcher_recipients - recipients
|
||||
recipients = wiki_content.notified_users
|
||||
cc = wiki_content.page.wiki.notified_watchers + wiki_content.page.notified_watchers - recipients
|
||||
@wiki_content = wiki_content
|
||||
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
|
||||
:project_id => wiki_content.project,
|
||||
@ -267,7 +267,7 @@ class Mailer < ActionMailer::Base
|
||||
# Mailer.account_activation_request(user).deliver => sends an email to all active administrators
|
||||
def account_activation_request(user)
|
||||
# Send the email to all active administrators
|
||||
recipients = User.active.where(:admin => true).collect { |u| u.mail }.compact
|
||||
recipients = User.active.where(:admin => true)
|
||||
@user = user
|
||||
@url = url_for(:controller => 'users', :action => 'index',
|
||||
:status => User::STATUS_REGISTERED,
|
||||
@ -378,12 +378,20 @@ class Mailer < ActionMailer::Base
|
||||
'From' => Setting.mail_from,
|
||||
'List-Id' => "<#{Setting.mail_from.to_s.gsub('@', '.')}>"
|
||||
|
||||
# Replaces users with their email addresses
|
||||
[:to, :cc, :bcc].each do |key|
|
||||
if headers[key].present?
|
||||
headers[key] = self.class.email_addresses(headers[key])
|
||||
end
|
||||
end
|
||||
|
||||
# Removes the author from the recipients and cc
|
||||
# if the author does not want to receive notifications
|
||||
# about what the author do
|
||||
if @author && @author.logged? && @author.pref.no_self_notified
|
||||
headers[:to].delete(@author.mail) if headers[:to].is_a?(Array)
|
||||
headers[:cc].delete(@author.mail) if headers[:cc].is_a?(Array)
|
||||
addresses = @author.mails
|
||||
headers[:to] -= addresses if headers[:to].is_a?(Array)
|
||||
headers[:cc] -= addresses if headers[:cc].is_a?(Array)
|
||||
end
|
||||
|
||||
if @author && @author.logged?
|
||||
@ -447,6 +455,25 @@ class Mailer < ActionMailer::Base
|
||||
end
|
||||
end
|
||||
|
||||
# Returns an array of email addresses to notify by
|
||||
# replacing users in arg with their notified email addresses
|
||||
#
|
||||
# Example:
|
||||
# Mailer.email_addresses(users)
|
||||
# => ["foo@example.net", "bar@example.net"]
|
||||
def self.email_addresses(arg)
|
||||
arr = Array.wrap(arg)
|
||||
mails = arr.reject {|a| a.is_a? Principal}
|
||||
users = arr - mails
|
||||
if users.any?
|
||||
mails += EmailAddress.
|
||||
where(:user_id => users.map(&:id)).
|
||||
where("is_default = ? OR notify = ?", true, true).
|
||||
pluck(:address)
|
||||
end
|
||||
mails
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Appends a Redmine header field (name is prepended with 'X-Redmine-')
|
||||
|
||||
@ -103,6 +103,10 @@ class Message < ActiveRecord::Base
|
||||
usr && usr.logged? && (usr.allowed_to?(:delete_messages, project) || (self.author == usr && usr.allowed_to?(:delete_own_messages, project)))
|
||||
end
|
||||
|
||||
def notified_users
|
||||
project.notified_users.reject {|user| !visible?(user)}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_author_as_watcher
|
||||
|
||||
@ -54,20 +54,29 @@ class News < ActiveRecord::Base
|
||||
user.allowed_to?(:comment_news, project)
|
||||
end
|
||||
|
||||
def notified_users
|
||||
project.users.select {|user| user.notify_about?(self) && user.allowed_to?(:view_news, project)}
|
||||
end
|
||||
|
||||
def recipients
|
||||
project.users.select {|user| user.notify_about?(self) && user.allowed_to?(:view_news, project)}.map(&:mail)
|
||||
notified_users.map(&:mail)
|
||||
end
|
||||
|
||||
# Returns the users that should be cc'd when a new news is added
|
||||
def notified_watchers_for_added_news
|
||||
watchers = []
|
||||
if m = project.enabled_module('news')
|
||||
watchers = m.notified_watchers
|
||||
unless project.is_public?
|
||||
watchers = watchers.select {|user| project.users.include?(user)}
|
||||
end
|
||||
end
|
||||
watchers
|
||||
end
|
||||
|
||||
# Returns the email addresses that should be cc'd when a new news is added
|
||||
def cc_for_added_news
|
||||
cc = []
|
||||
if m = project.enabled_module('news')
|
||||
cc = m.notified_watchers
|
||||
unless project.is_public?
|
||||
cc = cc.select {|user| project.users.include?(user)}
|
||||
end
|
||||
end
|
||||
cc.map(&:mail)
|
||||
notified_watchers_for_added_news.map(&:mail)
|
||||
end
|
||||
|
||||
# returns latest news for projects visible by user
|
||||
|
||||
@ -68,7 +68,8 @@ class Principal < ActiveRecord::Base
|
||||
where({})
|
||||
else
|
||||
pattern = "%#{q}%"
|
||||
sql = %w(login firstname lastname mail).map {|column| "LOWER(#{table_name}.#{column}) LIKE LOWER(:p)"}.join(" OR ")
|
||||
sql = %w(login firstname lastname).map {|column| "LOWER(#{table_name}.#{column}) LIKE LOWER(:p)"}.join(" OR ")
|
||||
sql << " OR #{table_name}.id IN (SELECT user_id FROM #{EmailAddress.table_name} WHERE LOWER(address) LIKE LOWER(:p))"
|
||||
params = {:p => pattern}
|
||||
if q =~ /^(.+)\s+(.+)$/
|
||||
a, b = "#{$1}%", "#{$2}%"
|
||||
@ -108,6 +109,14 @@ class Principal < ActiveRecord::Base
|
||||
to_s
|
||||
end
|
||||
|
||||
def mail=(*args)
|
||||
nil
|
||||
end
|
||||
|
||||
def mail
|
||||
nil
|
||||
end
|
||||
|
||||
def visible?(user=User.current)
|
||||
Principal.visible(user).where(:id => id).first == self
|
||||
end
|
||||
@ -145,7 +154,6 @@ class Principal < ActiveRecord::Base
|
||||
self.hashed_password ||= ''
|
||||
self.firstname ||= ''
|
||||
self.lastname ||= ''
|
||||
self.mail ||= ''
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
@ -81,6 +81,8 @@ class User < Principal
|
||||
has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
|
||||
has_one :rss_token, lambda {where "action='feeds'"}, :class_name => 'Token'
|
||||
has_one :api_token, lambda {where "action='api'"}, :class_name => 'Token'
|
||||
has_one :email_address, lambda {where :is_default => true}, :autosave => true
|
||||
has_many :email_addresses, :dependent => :delete_all
|
||||
belongs_to :auth_source
|
||||
|
||||
scope :logged, lambda { where("#{User.table_name}.status <> #{STATUS_ANONYMOUS}") }
|
||||
@ -96,15 +98,12 @@ class User < Principal
|
||||
LOGIN_LENGTH_LIMIT = 60
|
||||
MAIL_LENGTH_LIMIT = 60
|
||||
|
||||
validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
|
||||
validates_presence_of :login, :firstname, :lastname, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
|
||||
validates_uniqueness_of :login, :if => Proc.new { |user| user.login_changed? && user.login.present? }, :case_sensitive => false
|
||||
validates_uniqueness_of :mail, :if => Proc.new { |user| user.mail_changed? && user.mail.present? }, :case_sensitive => false
|
||||
# Login must contain letters, numbers, underscores only
|
||||
validates_format_of :login, :with => /\A[a-z0-9_\-@\.]*\z/i
|
||||
validates_length_of :login, :maximum => LOGIN_LENGTH_LIMIT
|
||||
validates_length_of :firstname, :lastname, :maximum => 30
|
||||
validates_format_of :mail, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, :allow_blank => true
|
||||
validates_length_of :mail, :maximum => MAIL_LENGTH_LIMIT, :allow_nil => true
|
||||
validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true
|
||||
validate :validate_password_length
|
||||
validate do
|
||||
@ -113,6 +112,7 @@ class User < Principal
|
||||
end
|
||||
end
|
||||
|
||||
before_validation :instantiate_email_address
|
||||
before_create :set_mail_notification
|
||||
before_save :generate_password_if_needed, :update_hashed_password
|
||||
before_destroy :remove_references_before_destroy
|
||||
@ -127,6 +127,14 @@ class User < Principal
|
||||
where("#{User.table_name}.id NOT IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id)
|
||||
}
|
||||
scope :sorted, lambda { order(*User.fields_for_order_statement)}
|
||||
scope :having_mail, lambda {|arg|
|
||||
addresses = Array.wrap(arg).map {|a| a.to_s.downcase}
|
||||
if addresses.any?
|
||||
joins(:email_addresses).where("LOWER(address) IN (?)", addresses).uniq
|
||||
else
|
||||
none
|
||||
end
|
||||
}
|
||||
|
||||
def set_mail_notification
|
||||
self.mail_notification = Setting.default_notification_option if self.mail_notification.blank?
|
||||
@ -152,8 +160,21 @@ class User < Principal
|
||||
base_reload(*args)
|
||||
end
|
||||
|
||||
def mail
|
||||
email_address.try(:address)
|
||||
end
|
||||
|
||||
def mail=(arg)
|
||||
write_attribute(:mail, arg.to_s.strip)
|
||||
email = email_address || build_email_address
|
||||
email.address = arg
|
||||
end
|
||||
|
||||
def mail_changed?
|
||||
email_address.try(:address_changed?)
|
||||
end
|
||||
|
||||
def mails
|
||||
email_addresses.pluck(:address)
|
||||
end
|
||||
|
||||
def self.find_or_initialize_by_identity_url(url)
|
||||
@ -421,7 +442,7 @@ class User < Principal
|
||||
|
||||
# Makes find_by_mail case-insensitive
|
||||
def self.find_by_mail(mail)
|
||||
where("LOWER(mail) = ?", mail.to_s.downcase).first
|
||||
having_mail(mail).first
|
||||
end
|
||||
|
||||
# Returns true if the default admin account can no longer be used
|
||||
@ -669,7 +690,7 @@ class User < Principal
|
||||
def self.anonymous
|
||||
anonymous_user = AnonymousUser.first
|
||||
if anonymous_user.nil?
|
||||
anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
|
||||
anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :login => '', :status => 0)
|
||||
raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
|
||||
end
|
||||
anonymous_user
|
||||
@ -699,6 +720,10 @@ class User < Principal
|
||||
end
|
||||
end
|
||||
|
||||
def instantiate_email_address
|
||||
email_address || build_email_address
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_password_if_needed
|
||||
@ -708,16 +733,13 @@ class User < Principal
|
||||
end
|
||||
end
|
||||
|
||||
# Delete all outstanding password reset tokens on password or email change.
|
||||
# Delete all outstanding password reset tokens on password change.
|
||||
# Delete the autologin tokens on password change to prohibit session leakage.
|
||||
# This helps to keep the account secure in case the associated email account
|
||||
# was compromised.
|
||||
def destroy_tokens
|
||||
tokens = []
|
||||
tokens |= ['recovery', 'autologin'] if hashed_password_changed?
|
||||
tokens |= ['recovery'] if mail_changed?
|
||||
|
||||
if tokens.any?
|
||||
if hashed_password_changed?
|
||||
tokens = ['recovery', 'autologin']
|
||||
Token.where(:user_id => id, :action => tokens).delete_all
|
||||
end
|
||||
end
|
||||
@ -779,6 +801,7 @@ class AnonymousUser < User
|
||||
def logged?; false end
|
||||
def admin; false end
|
||||
def name(*args); I18n.t(:label_user_anonymous) end
|
||||
def mail=(*args); nil end
|
||||
def mail; nil end
|
||||
def time_zone; nil end
|
||||
def rss_key; nil end
|
||||
@ -804,4 +827,9 @@ class AnonymousUser < User
|
||||
def destroy
|
||||
false
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def instantiate_email_address
|
||||
end
|
||||
end
|
||||
|
||||
@ -41,11 +41,13 @@ class WikiContent < ActiveRecord::Base
|
||||
page.nil? ? [] : page.attachments
|
||||
end
|
||||
|
||||
def notified_users
|
||||
project.notified_users.reject {|user| !visible?(user)}
|
||||
end
|
||||
|
||||
# Returns the mail addresses of users that should be notified
|
||||
def recipients
|
||||
notified = project.notified_users
|
||||
notified.reject! {|user| !visible?(user)}
|
||||
notified.collect(&:mail)
|
||||
notified_users.collect(&:mail)
|
||||
end
|
||||
|
||||
# Return true if the content is the current page content
|
||||
|
||||
26
app/views/email_addresses/_index.html.erb
Normal file
26
app/views/email_addresses/_index.html.erb
Normal file
@ -0,0 +1,26 @@
|
||||
<% if @addresses.present? %>
|
||||
<table class="list email_addresses">
|
||||
<% @addresses.each do |address| %>
|
||||
<tr class="<%= cycle("odd", "even") %>">
|
||||
<td class="email"><%= address.address %></td>
|
||||
<td class="buttons">
|
||||
<%= toggle_email_address_notify_link(address) %>
|
||||
<%= delete_link user_email_address_path(@user, address), :remote => true %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
<% unless @addresses.size >= Setting.max_additional_emails.to_i %>
|
||||
<div>
|
||||
<%= form_for @address, :url => user_email_addresses_path(@user), :remote => true do |f| %>
|
||||
<p><%= l(:label_email_address_add) %></p>
|
||||
<%= error_messages_for @address %>
|
||||
<p>
|
||||
<%= f.text_field :address, :size => 40 %>
|
||||
<%= submit_tag l(:button_add) %>
|
||||
</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
2
app/views/email_addresses/index.html.erb
Normal file
2
app/views/email_addresses/index.html.erb
Normal file
@ -0,0 +1,2 @@
|
||||
<h2><%= @user.name %></h2>
|
||||
<%= render :partial => 'email_addresses/index' %>
|
||||
3
app/views/email_addresses/index.js.erb
Normal file
3
app/views/email_addresses/index.js.erb
Normal file
@ -0,0 +1,3 @@
|
||||
$('#ajax-modal').html('<%= escape_javascript(render :partial => 'email_addresses/index') %>');
|
||||
showModal('ajax-modal', '600px', '<%= escape_javascript l(:label_email_address_plural) %>');
|
||||
$('#email_address_address').focus();
|
||||
@ -1,4 +1,5 @@
|
||||
<div class="contextual">
|
||||
<%= additional_emails_link(@user) %>
|
||||
<%= link_to(l(:button_change_password), {:action => 'password'}, :class => 'icon icon-passwd') if @user.change_password_allowed? %>
|
||||
<%= call_hook(:view_my_account_contextual, :user => @user)%>
|
||||
</div>
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
|
||||
<p><%= setting_check_box :lost_password, :label => :label_password_lost %></p>
|
||||
|
||||
<p><%= setting_text_field :max_additional_emails, :size => 6 %></p>
|
||||
|
||||
<p><%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %></p>
|
||||
|
||||
<p><%= setting_check_box :rest_api_enabled %></p>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<div class="contextual">
|
||||
<%= link_to l(:label_profile), user_path(@user), :class => 'icon icon-user' %>
|
||||
<%= additional_emails_link(@user) %>
|
||||
<%= change_status_link(@user) %>
|
||||
<%= delete_link user_path(@user) if User.current != @user %>
|
||||
</div>
|
||||
|
||||
@ -5,8 +5,7 @@ module ActiveRecord
|
||||
include Redmine::I18n
|
||||
# Translate attribute names for validation errors display
|
||||
def self.human_attribute_name(attr, *args)
|
||||
attr = attr.to_s.sub(/_id$/, '')
|
||||
|
||||
attr = attr.to_s.sub(/_id$/, '').sub(/^.+\./, '')
|
||||
l("field_#{name.underscore.gsub('/', '_')}_#{attr}", :default => ["field_#{attr}".to_sym, attr])
|
||||
end
|
||||
end
|
||||
|
||||
@ -227,6 +227,7 @@ en:
|
||||
field_firstname: First name
|
||||
field_lastname: Last name
|
||||
field_mail: Email
|
||||
field_address: Email
|
||||
field_filename: File
|
||||
field_filesize: Size
|
||||
field_downloads: Downloads
|
||||
@ -413,6 +414,7 @@ en:
|
||||
setting_force_default_language_for_anonymous: Force default language for anonymous users
|
||||
setting_force_default_language_for_loggedin: Force default language for logged-in users
|
||||
setting_link_copied_issue: Link issues on copy
|
||||
setting_max_additional_emails: Maximum number of additional email addresses
|
||||
|
||||
permission_add_project: Create project
|
||||
permission_add_subprojects: Create subprojects
|
||||
@ -931,6 +933,10 @@ en:
|
||||
label_search_attachments_no: Do not search attachments
|
||||
label_search_attachments_only: Search attachments only
|
||||
label_search_open_issues_only: Open issues only
|
||||
label_email_address_plural: Emails
|
||||
label_email_address_add: Add email address
|
||||
label_enable_notifications: Enable notifications
|
||||
label_disable_notifications: Disable notifications
|
||||
|
||||
button_login: Login
|
||||
button_submit: Submit
|
||||
|
||||
@ -247,6 +247,7 @@ fr:
|
||||
field_firstname: Prénom
|
||||
field_lastname: Nom
|
||||
field_mail: Email
|
||||
field_address: Email
|
||||
field_filename: Fichier
|
||||
field_filesize: Taille
|
||||
field_downloads: Téléchargements
|
||||
@ -433,6 +434,7 @@ fr:
|
||||
setting_force_default_language_for_anonymous: Forcer la langue par défault pour les utilisateurs anonymes
|
||||
setting_force_default_language_for_loggedin: Forcer la langue par défault pour les utilisateurs identifiés
|
||||
setting_link_copied_issue: Lier les demandes lors de la copie
|
||||
setting_max_additional_emails: Nombre maximal d'adresses email additionnelles
|
||||
|
||||
permission_add_project: Créer un projet
|
||||
permission_add_subprojects: Créer des sous-projets
|
||||
@ -951,6 +953,10 @@ fr:
|
||||
label_search_attachments_no: Ne pas rechercher les fichiers
|
||||
label_search_attachments_only: Rechercher les fichiers uniquement
|
||||
label_search_open_issues_only: Demandes ouvertes uniquement
|
||||
label_email_address_plural: Emails
|
||||
label_email_address_add: Ajouter une adresse email
|
||||
label_enable_notifications: Activer les notifications
|
||||
label_disable_notifications: Désactiver les notifications
|
||||
|
||||
button_login: Connexion
|
||||
button_submit: Soumettre
|
||||
|
||||
@ -75,6 +75,7 @@ Rails.application.routes.draw do
|
||||
|
||||
resources :users do
|
||||
resources :memberships, :controller => 'principal_memberships'
|
||||
resources :email_addresses, :only => [:index, :create, :update, :destroy]
|
||||
end
|
||||
|
||||
post 'watchers/watch', :to => 'watchers#watch', :as => 'watch'
|
||||
|
||||
@ -36,6 +36,10 @@ unsubscribe:
|
||||
password_min_length:
|
||||
format: int
|
||||
default: 8
|
||||
# Maximum number of additional email addresses per user
|
||||
max_additional_emails:
|
||||
format: int
|
||||
default: 5
|
||||
# Maximum lifetime of user sessions in minutes
|
||||
session_lifetime:
|
||||
format: int
|
||||
|
||||
12
db/migrate/20150113194759_create_email_addresses.rb
Normal file
12
db/migrate/20150113194759_create_email_addresses.rb
Normal file
@ -0,0 +1,12 @@
|
||||
class CreateEmailAddresses < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :email_addresses do |t|
|
||||
t.column :user_id, :integer, :null => false
|
||||
t.column :address, :string, :null => false
|
||||
t.column :is_default, :boolean, :null => false, :default => false
|
||||
t.column :notify, :boolean, :null => false, :default => true
|
||||
t.column :created_on, :timestamp, :null => false
|
||||
t.column :updated_on, :timestamp, :null => false
|
||||
end
|
||||
end
|
||||
end
|
||||
14
db/migrate/20150113211532_populate_email_addresses.rb
Normal file
14
db/migrate/20150113211532_populate_email_addresses.rb
Normal file
@ -0,0 +1,14 @@
|
||||
class PopulateEmailAddresses < ActiveRecord::Migration
|
||||
def self.up
|
||||
t = EmailAddress.connection.quoted_true
|
||||
n = EmailAddress.connection.quoted_date(Time.now)
|
||||
|
||||
sql = "INSERT INTO #{EmailAddress.table_name} (user_id, address, is_default, notify, created_on, updated_on)" +
|
||||
" SELECT id, mail, #{t}, #{t}, '#{n}', '#{n}' FROM #{User.table_name} WHERE type = 'User' ORDER BY id"
|
||||
EmailAddress.connection.execute(sql)
|
||||
end
|
||||
|
||||
def self.down
|
||||
EmailAddress.delete_all
|
||||
end
|
||||
end
|
||||
9
db/migrate/20150113213922_remove_users_mail.rb
Normal file
9
db/migrate/20150113213922_remove_users_mail.rb
Normal file
@ -0,0 +1,9 @@
|
||||
class RemoveUsersMail < ActiveRecord::Migration
|
||||
def self.up
|
||||
remove_column :users, :mail
|
||||
end
|
||||
|
||||
def self.down
|
||||
raise IrreversibleMigration
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,9 @@
|
||||
class AddEmailAddressesUserIdIndex < ActiveRecord::Migration
|
||||
def up
|
||||
add_index :email_addresses, :user_id
|
||||
end
|
||||
|
||||
def down
|
||||
remove_index :email_addresses, :user_id
|
||||
end
|
||||
end
|
||||
BIN
public/images/email.png
Normal file
BIN
public/images/email.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 641 B |
BIN
public/images/email_add.png
Normal file
BIN
public/images/email_add.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 761 B |
BIN
public/images/email_disabled.png
Normal file
BIN
public/images/email_disabled.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 386 B |
@ -378,10 +378,10 @@ function setPredecessorFieldsVisibility() {
|
||||
}
|
||||
}
|
||||
|
||||
function showModal(id, width) {
|
||||
function showModal(id, width, title) {
|
||||
var el = $('#'+id).first();
|
||||
if (el.length === 0 || el.is(':visible')) {return;}
|
||||
var title = el.find('h3.title').text();
|
||||
if (!title) title = el.find('h3.title').text();
|
||||
el.dialog({
|
||||
width: width,
|
||||
modal: true,
|
||||
|
||||
@ -132,6 +132,7 @@ table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
|
||||
table.list td.checkbox input {padding:0px;}
|
||||
table.list td.buttons { width: 15%; white-space:nowrap; text-align: right; }
|
||||
table.list td.buttons a { padding-right: 0.6em; }
|
||||
table.list td.buttons img {vertical-align:middle;}
|
||||
table.list td.reorder {width:15%; white-space:nowrap; text-align:center; }
|
||||
table.list caption { text-align: left; padding: 0.5em 0.5em 0.5em 0; }
|
||||
|
||||
@ -209,7 +210,7 @@ tr.version.shared td.name { background: url(../images/link.png) no-repeat 0% 70%
|
||||
tr.version td.date, tr.version td.status, tr.version td.sharing { text-align: center; white-space:nowrap; }
|
||||
|
||||
tr.user td {width:13%;white-space: nowrap;}
|
||||
tr.user td.username, tr.user td.firstname, tr.user td.lastname, tr.user td.email {text-align:left;}
|
||||
td.username, td.firstname, td.lastname, td.email {text-align:left !important;}
|
||||
tr.user td.email { width:18%; }
|
||||
tr.user.locked, tr.user.registered { color: #aaa; }
|
||||
tr.user.locked a, tr.user.registered a { color: #aaa; }
|
||||
@ -1046,6 +1047,7 @@ a.close-icon:hover {background-image:url('../images/close_hl.png');}
|
||||
.icon-zoom-out { background-image: url(../images/zoom_out.png); }
|
||||
.icon-passwd { background-image: url(../images/textfield_key.png); }
|
||||
.icon-test { background-image: url(../images/bullet_go.png); }
|
||||
.icon-email-add { background-image: url(../images/email_add.png); }
|
||||
|
||||
.icon-file { background-image: url(../images/files/default.png); }
|
||||
.icon-file.text-plain { background-image: url(../images/files/text.png); }
|
||||
|
||||
57
test/fixtures/email_addresses.yml
vendored
Normal file
57
test/fixtures/email_addresses.yml
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
email_address_001:
|
||||
id: 1
|
||||
user_id: 1
|
||||
address: admin@somenet.foo
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
email_address_002:
|
||||
id: 2
|
||||
user_id: 2
|
||||
address: jsmith@somenet.foo
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
email_address_003:
|
||||
id: 3
|
||||
user_id: 3
|
||||
address: dlopper@somenet.foo
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
email_address_004:
|
||||
id: 4
|
||||
user_id: 4
|
||||
address: rhill@somenet.foo
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
email_address_005:
|
||||
id: 5
|
||||
user_id: 5
|
||||
address: dlopper2@somenet.foo
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
email_address_007:
|
||||
id: 7
|
||||
user_id: 7
|
||||
address: someone@foo.bar
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
email_address_008:
|
||||
id: 8
|
||||
user_id: 8
|
||||
address: miscuser8@foo.bar
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
email_address_009:
|
||||
id: 9
|
||||
user_id: 9
|
||||
address: miscuser9@foo.bar
|
||||
is_default: true
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
43
test/fixtures/users.yml
vendored
43
test/fixtures/users.yml
vendored
@ -1,22 +1,4 @@
|
||||
---
|
||||
users_004:
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
status: 1
|
||||
last_login_on:
|
||||
language: en
|
||||
# password = foo
|
||||
salt: 3126f764c3c5ac61cbfc103f25f934cf
|
||||
hashed_password: 9e4dd7eeb172c12a0691a6d9d3a269f7e9fe671b
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
admin: false
|
||||
mail: rhill@somenet.foo
|
||||
lastname: Hill
|
||||
firstname: Robert
|
||||
id: 4
|
||||
auth_source_id:
|
||||
mail_notification: all
|
||||
login: rhill
|
||||
type: User
|
||||
users_001:
|
||||
created_on: 2006-07-19 19:12:21 +02:00
|
||||
status: 1
|
||||
@ -27,7 +9,6 @@ users_001:
|
||||
hashed_password: b5b6ff9543bf1387374cdfa27a54c96d236a7150
|
||||
updated_on: 2006-07-19 22:57:52 +02:00
|
||||
admin: true
|
||||
mail: admin@somenet.foo
|
||||
lastname: Admin
|
||||
firstname: Redmine
|
||||
id: 1
|
||||
@ -45,7 +26,6 @@ users_002:
|
||||
hashed_password: bfbe06043353a677d0215b26a5800d128d5413bc
|
||||
updated_on: 2006-07-19 22:42:15 +02:00
|
||||
admin: false
|
||||
mail: jsmith@somenet.foo
|
||||
lastname: Smith
|
||||
firstname: John
|
||||
id: 2
|
||||
@ -63,7 +43,6 @@ users_003:
|
||||
hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
|
||||
updated_on: 2006-07-19 19:33:19 +02:00
|
||||
admin: false
|
||||
mail: dlopper@somenet.foo
|
||||
lastname: Lopper
|
||||
firstname: Dave
|
||||
id: 3
|
||||
@ -71,6 +50,23 @@ users_003:
|
||||
mail_notification: all
|
||||
login: dlopper
|
||||
type: User
|
||||
users_004:
|
||||
created_on: 2006-07-19 19:34:07 +02:00
|
||||
status: 1
|
||||
last_login_on:
|
||||
language: en
|
||||
# password = foo
|
||||
salt: 3126f764c3c5ac61cbfc103f25f934cf
|
||||
hashed_password: 9e4dd7eeb172c12a0691a6d9d3a269f7e9fe671b
|
||||
updated_on: 2006-07-19 19:34:07 +02:00
|
||||
admin: false
|
||||
lastname: Hill
|
||||
firstname: Robert
|
||||
id: 4
|
||||
auth_source_id:
|
||||
mail_notification: all
|
||||
login: rhill
|
||||
type: User
|
||||
users_005:
|
||||
id: 5
|
||||
created_on: 2006-07-19 19:33:19 +02:00
|
||||
@ -81,7 +77,6 @@ users_005:
|
||||
hashed_password: 1
|
||||
updated_on: 2006-07-19 19:33:19 +02:00
|
||||
admin: false
|
||||
mail: dlopper2@somenet.foo
|
||||
lastname: Lopper2
|
||||
firstname: Dave2
|
||||
auth_source_id:
|
||||
@ -97,7 +92,6 @@ users_006:
|
||||
hashed_password: 1
|
||||
updated_on: 2006-07-19 19:33:19 +02:00
|
||||
admin: false
|
||||
mail: ''
|
||||
lastname: Anonymous
|
||||
firstname: ''
|
||||
auth_source_id:
|
||||
@ -116,7 +110,6 @@ users_007:
|
||||
hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
|
||||
updated_on: 2006-07-19 19:33:19 +02:00
|
||||
admin: false
|
||||
mail: someone@foo.bar
|
||||
lastname: One
|
||||
firstname: Some
|
||||
auth_source_id:
|
||||
@ -134,7 +127,6 @@ users_008:
|
||||
hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed
|
||||
updated_on: 2006-07-19 19:33:19 +02:00
|
||||
admin: false
|
||||
mail: miscuser8@foo.bar
|
||||
lastname: Misc
|
||||
firstname: User
|
||||
auth_source_id:
|
||||
@ -150,7 +142,6 @@ users_009:
|
||||
hashed_password: 1
|
||||
updated_on: 2006-07-19 19:33:19 +02:00
|
||||
admin: false
|
||||
mail: miscuser9@foo.bar
|
||||
lastname: Misc
|
||||
firstname: User
|
||||
auth_source_id:
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class AdminControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :users, :roles
|
||||
fixtures :projects, :users, :email_addresses, :roles
|
||||
|
||||
def setup
|
||||
User.current = nil
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class DocumentsControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:enabled_modules, :documents, :enumerations,
|
||||
:groups_users, :attachments
|
||||
|
||||
|
||||
144
test/functional/email_addresses_controller_test.rb
Normal file
144
test/functional/email_addresses_controller_test.rb
Normal file
@ -0,0 +1,144 @@
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2015 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class EmailAddressesControllerTest < ActionController::TestCase
|
||||
fixtures :users, :email_addresses
|
||||
|
||||
def setup
|
||||
User.current = nil
|
||||
end
|
||||
|
||||
def test_index_with_no_additional_emails
|
||||
@request.session[:user_id] = 2
|
||||
get :index, :user_id => 2
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
end
|
||||
|
||||
def test_index_with_additional_emails
|
||||
@request.session[:user_id] = 2
|
||||
EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||
|
||||
get :index, :user_id => 2
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
assert_select '.email', :text => 'another@somenet.foo'
|
||||
end
|
||||
|
||||
def test_index_with_additional_emails_as_js
|
||||
@request.session[:user_id] = 2
|
||||
EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||
|
||||
xhr :get, :index, :user_id => 2
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
assert_include 'another@somenet.foo', response.body
|
||||
end
|
||||
|
||||
def test_index_by_admin_should_be_allowed
|
||||
@request.session[:user_id] = 1
|
||||
get :index, :user_id => 2
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
end
|
||||
|
||||
def test_index_by_another_user_should_be_denied
|
||||
@request.session[:user_id] = 3
|
||||
get :index, :user_id => 2
|
||||
assert_response 403
|
||||
end
|
||||
|
||||
def test_create
|
||||
@request.session[:user_id] = 2
|
||||
assert_difference 'EmailAddress.count' do
|
||||
post :create, :user_id => 2, :email_address => {:address => 'another@somenet.foo'}
|
||||
assert_response 302
|
||||
assert_redirected_to '/users/2/email_addresses'
|
||||
end
|
||||
email = EmailAddress.order('id DESC').first
|
||||
assert_equal 2, email.user_id
|
||||
assert_equal 'another@somenet.foo', email.address
|
||||
end
|
||||
|
||||
def test_create_as_js
|
||||
@request.session[:user_id] = 2
|
||||
assert_difference 'EmailAddress.count' do
|
||||
xhr :post, :create, :user_id => 2, :email_address => {:address => 'another@somenet.foo'}
|
||||
assert_response 200
|
||||
end
|
||||
end
|
||||
|
||||
def test_create_with_failure
|
||||
@request.session[:user_id] = 2
|
||||
assert_no_difference 'EmailAddress.count' do
|
||||
post :create, :user_id => 2, :email_address => {:address => 'invalid'}
|
||||
assert_response 200
|
||||
end
|
||||
end
|
||||
|
||||
def test_update
|
||||
@request.session[:user_id] = 2
|
||||
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||
|
||||
put :update, :user_id => 2, :id => email.id, :notify => '0'
|
||||
assert_response 302
|
||||
|
||||
assert_equal false, email.reload.notify
|
||||
end
|
||||
|
||||
def test_update_as_js
|
||||
@request.session[:user_id] = 2
|
||||
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||
|
||||
xhr :put, :update, :user_id => 2, :id => email.id, :notify => '0'
|
||||
assert_response 200
|
||||
|
||||
assert_equal false, email.reload.notify
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
@request.session[:user_id] = 2
|
||||
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||
|
||||
assert_difference 'EmailAddress.count', -1 do
|
||||
delete :destroy, :user_id => 2, :id => email.id
|
||||
assert_response 302
|
||||
assert_redirected_to '/users/2/email_addresses'
|
||||
end
|
||||
end
|
||||
|
||||
def test_destroy_as_js
|
||||
@request.session[:user_id] = 2
|
||||
email = EmailAddress.create!(:user_id => 2, :address => 'another@somenet.foo')
|
||||
|
||||
assert_difference 'EmailAddress.count', -1 do
|
||||
xhr :delete, :destroy, :user_id => 2, :id => email.id
|
||||
assert_response 200
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_destroy_default
|
||||
@request.session[:user_id] = 2
|
||||
|
||||
assert_no_difference 'EmailAddress.count' do
|
||||
delete :destroy, :user_id => 2, :id => User.find(2).email_address.id
|
||||
assert_response 404
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -19,7 +19,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class IssuesControllerTest < ActionController::TestCase
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:users, :email_addresses,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class IssuesCustomFieldsVisibilityTest < ActionController::TestCase
|
||||
tests IssuesController
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:users, :email_addresses,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class MailHandlerControllerTest < ActionController::TestCase
|
||||
fixtures :users, :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :issue_statuses,
|
||||
fixtures :users, :email_addresses, :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :issue_statuses,
|
||||
:trackers, :projects_trackers, :enumerations
|
||||
|
||||
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class MessagesControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :users, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
|
||||
fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles, :boards, :messages, :enabled_modules
|
||||
|
||||
def setup
|
||||
User.current = nil
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class MyControllerTest < ActionController::TestCase
|
||||
fixtures :users, :user_preferences, :roles, :projects, :members, :member_roles,
|
||||
fixtures :users, :email_addresses, :user_preferences, :roles, :projects, :members, :member_roles,
|
||||
:issues, :issue_statuses, :trackers, :enumerations, :custom_fields, :auth_sources
|
||||
|
||||
def setup
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class NewsControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:enabled_modules, :news, :comments,
|
||||
:attachments
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class ProjectsControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :versions, :users, :roles, :members,
|
||||
fixtures :projects, :versions, :users, :email_addresses, :roles, :members,
|
||||
:member_roles, :issues, :journals, :journal_details,
|
||||
:trackers, :projects_trackers, :issue_statuses,
|
||||
:enabled_modules, :enumerations, :boards, :messages,
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class RepositoriesBazaarControllerTest < ActionController::TestCase
|
||||
tests RepositoriesController
|
||||
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:repositories, :enabled_modules
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class RepositoriesControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles, :enabled_modules,
|
||||
:repositories, :issues, :issue_statuses, :changesets, :changes,
|
||||
:issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class RepositoriesCvsControllerTest < ActionController::TestCase
|
||||
tests RepositoriesController
|
||||
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:repositories, :enabled_modules
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class RepositoriesDarcsControllerTest < ActionController::TestCase
|
||||
tests RepositoriesController
|
||||
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:repositories, :enabled_modules
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class RepositoriesFilesystemControllerTest < ActionController::TestCase
|
||||
tests RepositoriesController
|
||||
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:repositories, :enabled_modules
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class RepositoriesGitControllerTest < ActionController::TestCase
|
||||
tests RepositoriesController
|
||||
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:repositories, :enabled_modules
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class RepositoriesMercurialControllerTest < ActionController::TestCase
|
||||
tests RepositoriesController
|
||||
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:repositories, :enabled_modules
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class RepositoriesSubversionControllerTest < ActionController::TestCase
|
||||
tests RepositoriesController
|
||||
|
||||
fixtures :projects, :users, :roles, :members, :member_roles, :enabled_modules,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles, :enabled_modules,
|
||||
:repositories, :issues, :issue_statuses, :changesets, :changes,
|
||||
:issue_categories, :enumerations, :custom_fields, :custom_values, :trackers
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class UsersControllerTest < ActionController::TestCase
|
||||
include Redmine::I18n
|
||||
|
||||
fixtures :users, :projects, :members, :member_roles, :roles,
|
||||
fixtures :users, :email_addresses, :projects, :members, :member_roles, :roles,
|
||||
:custom_fields, :custom_values, :groups_users,
|
||||
:auth_sources,
|
||||
:enabled_modules,
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class WikiControllerTest < ActionController::TestCase
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
fixtures :projects, :users, :email_addresses, :roles, :members, :member_roles,
|
||||
:enabled_modules, :wikis, :wiki_pages, :wiki_contents,
|
||||
:wiki_content_versions, :attachments,
|
||||
:issues, :issue_statuses
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class AccountTest < Redmine::IntegrationTest
|
||||
fixtures :users, :roles
|
||||
fixtures :users, :email_addresses, :roles
|
||||
|
||||
def test_login
|
||||
get "/my/page"
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
|
||||
fixtures :users, :members, :member_roles, :roles, :projects
|
||||
fixtures :users, :email_addresses, :members, :member_roles, :roles, :projects
|
||||
|
||||
test "GET /users.xml should return users" do
|
||||
get '/users.xml', {}, credentials('admin')
|
||||
|
||||
@ -19,7 +19,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class IssuesTest < Redmine::IntegrationTest
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:users, :email_addresses,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class UsersTest < Redmine::IntegrationTest
|
||||
fixtures :users
|
||||
fixtures :users, :email_addresses
|
||||
|
||||
def test_destroy_should_not_accept_get_requests
|
||||
assert_no_difference 'User.count' do
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class DocumentTest < ActiveSupport::TestCase
|
||||
fixtures :projects, :enumerations, :documents, :attachments,
|
||||
:enabled_modules,
|
||||
:users, :members, :member_roles, :roles,
|
||||
:users, :email_addresses, :members, :member_roles, :roles,
|
||||
:groups_users
|
||||
|
||||
def test_create
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class IssueTest < ActiveSupport::TestCase
|
||||
fixtures :projects, :users, :members, :member_roles, :roles,
|
||||
fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles,
|
||||
:groups_users,
|
||||
:trackers, :projects_trackers,
|
||||
:enabled_modules,
|
||||
|
||||
@ -223,6 +223,17 @@ class MailHandlerTest < ActiveSupport::TestCase
|
||||
assert_equal 1, issue.watcher_user_ids.size
|
||||
end
|
||||
|
||||
def test_add_issue_from_additional_email_address
|
||||
user = User.find(2)
|
||||
user.mail = 'mainaddress@somenet.foo'
|
||||
user.save!
|
||||
EmailAddress.create!(:user => user, :address => 'jsmith@somenet.foo')
|
||||
|
||||
issue = submit_email('ticket_on_given_project.eml')
|
||||
assert issue
|
||||
assert_equal user, issue.author
|
||||
end
|
||||
|
||||
def test_add_issue_by_unknown_user
|
||||
assert_no_difference 'User.count' do
|
||||
assert_equal false,
|
||||
|
||||
@ -20,7 +20,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
||||
class MailerTest < ActiveSupport::TestCase
|
||||
include Redmine::I18n
|
||||
include ActionDispatch::Assertions::SelectorAssertions
|
||||
fixtures :projects, :enabled_modules, :issues, :users, :members,
|
||||
fixtures :projects, :enabled_modules, :issues, :users, :email_addresses, :members,
|
||||
:member_roles, :roles, :documents, :attachments, :news,
|
||||
:tokens, :journals, :journal_details, :changesets,
|
||||
:trackers, :projects_trackers,
|
||||
@ -298,6 +298,14 @@ class MailerTest < ActiveSupport::TestCase
|
||||
assert last_email.bcc.include?('dlopper@somenet.foo')
|
||||
end
|
||||
|
||||
def test_issue_add_should_send_mail_to_all_user_email_address
|
||||
EmailAddress.create!(:user_id => 3, :address => 'otheremail@somenet.foo')
|
||||
issue = Issue.find(1)
|
||||
assert Mailer.deliver_issue_add(issue)
|
||||
assert last_email.bcc.include?('dlopper@somenet.foo')
|
||||
assert last_email.bcc.include?('otheremail@somenet.foo')
|
||||
end
|
||||
|
||||
test "#issue_add should not notify project members that are not allow to view the issue" do
|
||||
issue = Issue.find(1)
|
||||
Role.find(2).remove_permission!(:view_issues)
|
||||
@ -771,6 +779,30 @@ class MailerTest < ActiveSupport::TestCase
|
||||
ActionMailer::Base.delivery_method = :test
|
||||
end
|
||||
|
||||
def test_email_addresses_should_keep_addresses
|
||||
assert_equal ["foo@example.net"],
|
||||
Mailer.email_addresses("foo@example.net")
|
||||
|
||||
assert_equal ["foo@example.net", "bar@example.net"],
|
||||
Mailer.email_addresses(["foo@example.net", "bar@example.net"])
|
||||
end
|
||||
|
||||
def test_email_addresses_should_replace_users_with_their_email_addresses
|
||||
assert_equal ["admin@somenet.foo"],
|
||||
Mailer.email_addresses(User.find(1))
|
||||
|
||||
assert_equal ["admin@somenet.foo", "jsmith@somenet.foo"],
|
||||
Mailer.email_addresses(User.where(:id => [1,2])).sort
|
||||
end
|
||||
|
||||
def test_email_addresses_should_include_notified_emails_addresses_only
|
||||
EmailAddress.create!(:user_id => 2, :address => "another@somenet.foo", :notify => false)
|
||||
EmailAddress.create!(:user_id => 2, :address => "another2@somenet.foo")
|
||||
|
||||
assert_equal ["another2@somenet.foo", "jsmith@somenet.foo"],
|
||||
Mailer.email_addresses(User.find(2)).sort
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def last_email
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class UserTest < ActiveSupport::TestCase
|
||||
fixtures :users, :members, :projects, :roles, :member_roles, :auth_sources,
|
||||
fixtures :users, :email_addresses, :members, :projects, :roles, :member_roles, :auth_sources,
|
||||
:trackers, :issue_statuses,
|
||||
:projects_trackers,
|
||||
:watchers,
|
||||
@ -57,11 +57,41 @@ class UserTest < ActiveSupport::TestCase
|
||||
assert_equal "foo@bar.com", u.mail
|
||||
end
|
||||
|
||||
def test_mail_validation
|
||||
u = User.new
|
||||
def test_should_create_email_address
|
||||
u = User.new(:firstname => "new", :lastname => "user")
|
||||
u.login = "create_email_address"
|
||||
u.mail = "defaultemail@somenet.foo"
|
||||
assert u.save
|
||||
u.reload
|
||||
assert u.email_address
|
||||
assert_equal "defaultemail@somenet.foo", u.email_address.address
|
||||
assert_equal true, u.email_address.is_default
|
||||
assert_equal true, u.email_address.notify
|
||||
end
|
||||
|
||||
def test_should_not_create_user_without_mail
|
||||
set_language_if_valid 'en'
|
||||
u = User.new(:firstname => "new", :lastname => "user")
|
||||
u.login = "user_without_mail"
|
||||
assert !u.save
|
||||
assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
|
||||
end
|
||||
|
||||
def test_should_not_create_user_with_blank_mail
|
||||
set_language_if_valid 'en'
|
||||
u = User.new(:firstname => "new", :lastname => "user")
|
||||
u.login = "user_with_blank_mail"
|
||||
u.mail = ''
|
||||
assert !u.valid?
|
||||
assert_include I18n.translate('activerecord.errors.messages.blank'), u.errors[:mail]
|
||||
assert !u.save
|
||||
assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
|
||||
end
|
||||
|
||||
def test_should_not_update_user_with_blank_mail
|
||||
set_language_if_valid 'en'
|
||||
u = User.find(2)
|
||||
u.mail = ''
|
||||
assert !u.save
|
||||
assert_equal ["Email #{I18n.translate('activerecord.errors.messages.blank')}"], u.errors.full_messages
|
||||
end
|
||||
|
||||
def test_login_length_validation
|
||||
@ -151,6 +181,7 @@ class UserTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
def test_mail_uniqueness_should_not_be_case_sensitive
|
||||
set_language_if_valid 'en'
|
||||
u = User.new(:firstname => "new", :lastname => "user", :mail => "newuser@somenet.foo")
|
||||
u.login = 'newuser1'
|
||||
u.password, u.password_confirmation = "password", "password"
|
||||
@ -160,7 +191,7 @@ class UserTest < ActiveSupport::TestCase
|
||||
u.login = 'newuser2'
|
||||
u.password, u.password_confirmation = "password", "password"
|
||||
assert !u.save
|
||||
assert_include I18n.translate('activerecord.errors.messages.taken'), u.errors[:mail]
|
||||
assert_include "Email #{I18n.translate('activerecord.errors.messages.taken')}", u.errors.full_messages
|
||||
end
|
||||
|
||||
def test_update
|
||||
@ -677,7 +708,7 @@ class UserTest < ActiveSupport::TestCase
|
||||
assert_kind_of AnonymousUser, anon1
|
||||
anon2 = AnonymousUser.create(
|
||||
:lastname => 'Anonymous', :firstname => '',
|
||||
:mail => '', :login => '', :status => 0)
|
||||
:login => '', :status => 0)
|
||||
assert_equal 1, anon2.errors.count
|
||||
end
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class WatcherTest < ActiveSupport::TestCase
|
||||
fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules,
|
||||
fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles, :enabled_modules,
|
||||
:issues, :issue_statuses, :enumerations, :trackers, :projects_trackers,
|
||||
:boards, :messages,
|
||||
:wikis, :wiki_pages,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user