Compare commits

..
1 Commits
Author SHA1 Message Date
Jean-Philippe Lang fc6ccc1ea2 tagged version 0.9.3
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/tags/0.9.3@3515 e93f8b46-1217-0410-a6f0-8f06a7374b81
2010-02-28 15:12:09 +00:00
94 changed files with 179 additions and 478 deletions
+6 -11
View File
@@ -25,7 +25,8 @@ class AccountController < ApplicationController
# Login request and validation # Login request and validation
def login def login
if request.get? if request.get?
logout_user # Logout user
self.logged_user = nil
else else
# Authenticate user # Authenticate user
if Setting.openid? && using_open_id? if Setting.openid? && using_open_id?
@@ -38,7 +39,9 @@ class AccountController < ApplicationController
# Log out current user and redirect to welcome page # Log out current user and redirect to welcome page
def logout def logout
logout_user cookies.delete :autologin
Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin']) if User.current.logged?
self.logged_user = nil
redirect_to home_url redirect_to home_url
end end
@@ -131,15 +134,7 @@ class AccountController < ApplicationController
end end
private private
def logout_user
if User.current.logged?
cookies.delete :autologin
Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin'])
self.logged_user = nil
end
end
def password_authentication def password_authentication
user = User.try_to_login(params[:username], params[:password]) user = User.try_to_login(params[:username], params[:password])
+1 -2
View File
@@ -107,9 +107,8 @@ class ApplicationController < ActionController::Base
lang = find_language(User.current.language) lang = find_language(User.current.language)
end end
if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE'] if lang.nil? && request.env['HTTP_ACCEPT_LANGUAGE']
accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
if !accept_lang.blank? if !accept_lang.blank?
accept_lang = accept_lang.downcase
lang = find_language(accept_lang) || find_language(accept_lang.split('-').first) lang = find_language(accept_lang) || find_language(accept_lang.split('-').first)
end end
end end
+2 -2
View File
@@ -76,12 +76,12 @@ class EnumerationsController < ApplicationController
@enumeration.destroy @enumeration.destroy
redirect_to :action => 'index' redirect_to :action => 'index'
elsif params[:reassign_to_id] elsif params[:reassign_to_id]
if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id]) if reassign_to = Enumeration.find_by_type_and_id(@enumeration.type, params[:reassign_to_id])
@enumeration.destroy(reassign_to) @enumeration.destroy(reassign_to)
redirect_to :action => 'index' redirect_to :action => 'index'
end end
end end
@enumerations = @enumeration.class.find(:all) - [@enumeration] @enumerations = Enumeration.find(:all, :conditions => ['type = (?)', @enumeration.type]) - [@enumeration]
#rescue #rescue
# flash[:error] = 'Unable to delete enumeration' # flash[:error] = 'Unable to delete enumeration'
# redirect_to :action => 'index' # redirect_to :action => 'index'
+12 -8
View File
@@ -149,7 +149,7 @@ class IssuesController < ApplicationController
if request.get? || request.xhr? if request.get? || request.xhr?
@issue.start_date ||= Date.today @issue.start_date ||= Date.today
else else
requested_status = IssueStatus.find_by_id(params[:issue][:status_id]) if params[:issue] requested_status = IssueStatus.find_by_id(params[:issue][:status_id])
# Check that the user is allowed to apply the requested status # Check that the user is allowed to apply the requested status
@issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status @issue.status = (@allowed_statuses.include? requested_status) ? requested_status : default_status
call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue }) call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue })
@@ -223,13 +223,10 @@ class IssuesController < ApplicationController
user = @issue.author user = @issue.author
text = @issue.description text = @issue.description
end end
# Replaces pre blocks with [...] content = "#{ll(Setting.default_language, :text_user_wrote, user)}\\n> "
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]') content << text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub('"', '\"').gsub(/(\r?\n|\r\n?)/, "\\n> ") + "\\n\\n"
content = "#{ll(Setting.default_language, :text_user_wrote, user)}\n> "
content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
render(:update) { |page| render(:update) { |page|
page.<< "$('notes').value = \"#{escape_javascript content}\";" page.<< "$('notes').value = \"#{content}\";"
page.show 'update' page.show 'update'
page << "Form.Element.focus('notes');" page << "Form.Element.focus('notes');"
page << "Element.scrollTo('update');" page << "Element.scrollTo('update');"
@@ -283,7 +280,14 @@ class IssuesController < ApplicationController
def move def move
@copy = params[:copy_options] && params[:copy_options][:copy] @copy = params[:copy_options] && params[:copy_options][:copy]
@allowed_projects = Issue.allowed_target_projects_on_move @allowed_projects = []
# find projects to which the user is allowed to move the issue
if User.current.admin?
# admin is allowed to move issues to any active (visible) project
@allowed_projects = Project.find(:all, :conditions => Project.visible_by(User.current))
else
User.current.memberships.each {|m| @allowed_projects << m.project if m.roles.detect {|r| r.allowed_to?(:move_issues)}}
end
@target_project = @allowed_projects.detect {|p| p.id.to_s == params[:new_project_id]} if params[:new_project_id] @target_project = @allowed_projects.detect {|p| p.id.to_s == params[:new_project_id]} if params[:new_project_id]
@target_project ||= @project @target_project ||= @project
@trackers = @target_project.trackers @trackers = @target_project.trackers
+1 -7
View File
@@ -38,7 +38,6 @@ class MembersController < ApplicationController
format.js { format.js {
render(:update) {|page| render(:update) {|page|
page.replace_html "tab-content-members", :partial => 'projects/settings/members' page.replace_html "tab-content-members", :partial => 'projects/settings/members'
page << 'hideOnLoad()'
members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") } members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") }
} }
} }
@@ -52,7 +51,6 @@ class MembersController < ApplicationController
format.js { format.js {
render(:update) {|page| render(:update) {|page|
page.replace_html "tab-content-members", :partial => 'projects/settings/members' page.replace_html "tab-content-members", :partial => 'projects/settings/members'
page << 'hideOnLoad()'
page.visual_effect(:highlight, "member-#{@member.id}") page.visual_effect(:highlight, "member-#{@member.id}")
} }
} }
@@ -66,11 +64,7 @@ class MembersController < ApplicationController
end end
respond_to do |format| respond_to do |format|
format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project } format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
format.js { render(:update) {|page| format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
page.replace_html "tab-content-members", :partial => 'projects/settings/members'
page << 'hideOnLoad()'
}
}
end end
end end
+13 -15
View File
@@ -27,7 +27,7 @@ class ProjectsController < ApplicationController
before_filter :authorize, :except => [ :index, :list, :add, :copy, :archive, :unarchive, :destroy, :activity ] before_filter :authorize, :except => [ :index, :list, :add, :copy, :archive, :unarchive, :destroy, :activity ]
before_filter :authorize_global, :only => :add before_filter :authorize_global, :only => :add
before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ] before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
accept_key_auth :activity, :index accept_key_auth :activity
after_filter :only => [:add, :edit, :archive, :unarchive, :destroy] do |controller| after_filter :only => [:add, :edit, :archive, :unarchive, :destroy] do |controller|
if controller.request.post? if controller.request.post?
@@ -102,20 +102,18 @@ class ProjectsController < ApplicationController
redirect_to :controller => 'admin', :action => 'projects' redirect_to :controller => 'admin', :action => 'projects'
end end
else else
Mailer.with_deliveries(params[:notifications] == '1') do @project = Project.new(params[:project])
@project = Project.new(params[:project]) @project.enabled_module_names = params[:enabled_modules]
@project.enabled_module_names = params[:enabled_modules] if validate_parent_id && @project.copy(@source_project, :only => params[:only])
if validate_parent_id && @project.copy(@source_project, :only => params[:only]) @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
@project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id') flash[:notice] = l(:notice_successful_create)
flash[:notice] = l(:notice_successful_create) redirect_to :controller => 'admin', :action => 'projects'
redirect_to :controller => 'admin', :action => 'projects' elsif !@project.new_record?
elsif !@project.new_record? # Project was created
# Project was created # But some objects were not copied due to validation failures
# But some objects were not copied due to validation failures # (eg. issues from disabled trackers)
# (eg. issues from disabled trackers) # TODO: inform about that
# TODO: inform about that redirect_to :controller => 'admin', :action => 'projects'
redirect_to :controller => 'admin', :action => 'projects'
end
end end
end end
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
+1 -1
View File
@@ -74,7 +74,7 @@ private
def find_optional_project def find_optional_project
@project = Project.find(params[:project_id]) if params[:project_id] @project = Project.find(params[:project_id]) if params[:project_id]
render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true) User.current.allowed_to?(:save_queries, @project, :global => true)
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
render_404 render_404
end end
+2 -2
View File
@@ -61,7 +61,7 @@ class ReportsController < ApplicationController
render :template => "reports/issue_report_details" render :template => "reports/issue_report_details"
when "subproject" when "subproject"
@field = "project_id" @field = "project_id"
@rows = @project.descendants.visible @rows = @project.descendants.active
@data = issues_by_subproject @data = issues_by_subproject
@report_title = l(:field_subproject) @report_title = l(:field_subproject)
render :template => "reports/issue_report_details" render :template => "reports/issue_report_details"
@@ -72,7 +72,7 @@ class ReportsController < ApplicationController
@categories = @project.issue_categories @categories = @project.issue_categories
@assignees = @project.members.collect { |m| m.user }.sort @assignees = @project.members.collect { |m| m.user }.sort
@authors = @project.members.collect { |m| m.user }.sort @authors = @project.members.collect { |m| m.user }.sort
@subprojects = @project.descendants.visible @subprojects = @project.descendants.active
issues_by_tracker issues_by_tracker
issues_by_version issues_by_version
issues_by_priority issues_by_priority
+5 -7
View File
@@ -46,13 +46,11 @@ class VersionsController < ApplicationController
end end
def destroy def destroy
if @version.fixed_issues.empty? @version.destroy
@version.destroy redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project rescue
else flash[:error] = l(:notice_unable_delete_version)
flash[:error] = l(:notice_unable_delete_version) redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
end
end end
def status_by def status_by
+14 -20
View File
@@ -52,19 +52,17 @@ module RepositoriesHelper
else else
change change
end end
end.compact end.compact
tree = { } tree = { }
changes.each do |change| changes.each do |change|
p = tree p = tree
dirs = change.path.to_s.split('/').select {|d| !d.blank?} dirs = change.path.to_s.split('/').select {|d| !d.blank?}
path = ''
dirs.each do |dir| dirs.each do |dir|
path += '/' + dir
p[:s] ||= {} p[:s] ||= {}
p = p[:s] p = p[:s]
p[path] ||= {} p[dir] ||= {}
p = p[path] p = p[dir]
end end
p[:c] = change p[:c] = change
end end
@@ -78,26 +76,21 @@ module RepositoriesHelper
output = '' output = ''
output << '<ul>' output << '<ul>'
tree.keys.sort.each do |file| tree.keys.sort.each do |file|
s = !tree[file][:s].nil?
c = tree[file][:c]
style = 'change' style = 'change'
text = File.basename(h(file)) style << ' folder' if s
if s = tree[file][:s] style << " change-#{c.action}" if c
style << ' folder'
path_param = to_path_param(@repository.relative_path(file)) text = h(file)
text = link_to(text, :controller => 'repositories', unless c.nil?
:action => 'show',
:id => @project,
:path => path_param,
:rev => @changeset.revision)
output << "<li class='#{style}'>#{text}</li>"
output << render_changes_tree(s)
elsif c = tree[file][:c]
style << " change-#{c.action}"
path_param = to_path_param(@repository.relative_path(c.path)) path_param = to_path_param(@repository.relative_path(c.path))
text = link_to(text, :controller => 'repositories', text = link_to(text, :controller => 'repositories',
:action => 'entry', :action => 'entry',
:id => @project, :id => @project,
:path => path_param, :path => path_param,
:rev => @changeset.revision) unless c.action == 'D' :rev => @changeset.revision) unless s || c.action == 'D'
text << " - #{c.revision}" unless c.revision.blank? text << " - #{c.revision}" unless c.revision.blank?
text << ' (' + link_to('diff', :controller => 'repositories', text << ' (' + link_to('diff', :controller => 'repositories',
:action => 'diff', :action => 'diff',
@@ -105,8 +98,9 @@ module RepositoriesHelper
:path => path_param, :path => path_param,
:rev => @changeset.revision) + ') ' if c.action == 'M' :rev => @changeset.revision) + ') ' if c.action == 'M'
text << ' ' + content_tag('span', c.from_path, :class => 'copied-from') unless c.from_path.blank? text << ' ' + content_tag('span', c.from_path, :class => 'copied-from') unless c.from_path.blank?
output << "<li class='#{style}'>#{text}</li>"
end end
output << "<li class='#{style}'>#{text}</li>"
output << render_changes_tree(tree[file][:s]) if s
end end
output << '</ul>' output << '</ul>'
output output
+1 -6
View File
@@ -182,11 +182,6 @@ class Changeset < ActiveRecord::Base
end end
end end
# removes invalid UTF8 sequences # removes invalid UTF8 sequences
begin Iconv.conv('UTF-8//IGNORE', 'UTF-8', str + ' ')[0..-3]
Iconv.conv('UTF-8//IGNORE', 'UTF-8', str + ' ')[0..-3]
rescue Iconv::InvalidEncoding
# "UTF-8//IGNORE" is not supported on some OS
str
end
end end
end end
+5 -21
View File
@@ -80,7 +80,7 @@ class Issue < ActiveRecord::Base
end end
def copy_from(arg) def copy_from(arg)
issue = arg.is_a?(Issue) ? arg : Issue.visible.find(arg) issue = arg.is_a?(Issue) ? arg : Issue.find(arg)
self.attributes = issue.attributes.dup.except("id", "created_on", "updated_on") self.attributes = issue.attributes.dup.except("id", "created_on", "updated_on")
self.custom_values = issue.custom_values.collect {|v| v.clone} self.custom_values = issue.custom_values.collect {|v| v.clone}
self.status = issue.status self.status = issue.status
@@ -92,7 +92,7 @@ class Issue < ActiveRecord::Base
def move_to(new_project, new_tracker = nil, options = {}) def move_to(new_project, new_tracker = nil, options = {})
options ||= {} options ||= {}
issue = options[:copy] ? self.clone : self issue = options[:copy] ? self.clone : self
ret = Issue.transaction do transaction do
if new_project && issue.project_id != new_project.id if new_project && issue.project_id != new_project.id
# delete issue relations # delete issue relations
unless Setting.cross_project_issue_relations? unless Setting.cross_project_issue_relations?
@@ -129,12 +129,12 @@ class Issue < ActiveRecord::Base
# Manually update project_id on related time entries # Manually update project_id on related time entries
TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id}) TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id})
end end
true
else else
raise ActiveRecord::Rollback Issue.connection.rollback_db_transaction
return false
end end
end end
ret ? issue : false return issue
end end
def priority_id=(pid) def priority_id=(pid)
@@ -389,22 +389,6 @@ class Issue < ActiveRecord::Base
Issue.update_versions(["#{Version.table_name}.project_id IN (?) OR #{Issue.table_name}.project_id IN (?)", moved_project_ids, moved_project_ids]) Issue.update_versions(["#{Version.table_name}.project_id IN (?) OR #{Issue.table_name}.project_id IN (?)", moved_project_ids, moved_project_ids])
end end
# Returns an array of projects that current user can move issues to
def self.allowed_target_projects_on_move
projects = []
if User.current.admin?
# admin is allowed to move issues to any active (visible) project
projects = Project.visible.all
elsif User.current.logged?
if Role.non_member.allowed_to?(:move_issues)
projects = Project.visible.all
else
User.current.memberships.each {|m| projects << m.project if m.roles.detect {|r| r.allowed_to?(:move_issues)}}
end
end
projects
end
private private
# Update issues so their versions are not pointing to a # Update issues so their versions are not pointing to a
+1 -1
View File
@@ -49,7 +49,7 @@ class MailHandler < ActionMailer::Base
logger.info "MailHandler: ignoring email from Redmine emission address [#{sender_email}]" if logger && logger.info logger.info "MailHandler: ignoring email from Redmine emission address [#{sender_email}]" if logger && logger.info
return false return false
end end
@user = User.find_by_mail(sender_email) if sender_email.present? @user = User.find_by_mail(sender_email)
if @user && !@user.active? if @user && !@user.active?
logger.info "MailHandler: ignoring email from non-active user [#{@user.login}]" if logger && logger.info logger.info "MailHandler: ignoring email from non-active user [#{@user.login}]" if logger && logger.info
return false return false
+2 -11
View File
@@ -114,11 +114,11 @@ class Mailer < ActionMailer::Base
when 'Project' when 'Project'
added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container) added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container)
added_to = "#{l(:label_project)}: #{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' when 'Version'
added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container.project_id) added_to_url = url_for(:controller => 'projects', :action => 'list_files', :id => container.project_id)
added_to = "#{l(:label_version)}: #{container.name}" 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' when 'Document'
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id) added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
added_to = "#{l(:label_document)}: #{container.title}" added_to = "#{l(:label_document)}: #{container.title}"
@@ -310,15 +310,6 @@ class Mailer < ActionMailer::Base
deliver_reminder(assignee, issues, days) unless assignee.nil? deliver_reminder(assignee, issues, days) unless assignee.nil?
end end
end end
# Activates/desactivates email deliveries during +block+
def self.with_deliveries(enabled = true, &block)
was_enabled = ActionMailer::Base.perform_deliveries
ActionMailer::Base.perform_deliveries = !!enabled
yield
ensure
ActionMailer::Base.perform_deliveries = was_enabled
end
private private
def initialize_defaults(method_name) def initialize_defaults(method_name)
+1 -1
View File
@@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Principal < ActiveRecord::Base class Principal < ActiveRecord::Base
set_table_name "#{table_name_prefix}users#{table_name_suffix}" set_table_name 'users'
has_many :members, :foreign_key => 'user_id', :dependent => :destroy has_many :members, :foreign_key => 'user_id', :dependent => :destroy
has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name" has_many :memberships, :class_name => 'Member', :foreign_key => 'user_id', :include => [ :project, :roles ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name"
+8 -4
View File
@@ -1,5 +1,5 @@
# Redmine - project management software # redMine - project management software
# Copyright (C) 2006-2010 Jean-Philippe Lang # Copyright (C) 2006 Jean-Philippe Lang
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@@ -16,9 +16,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Version < ActiveRecord::Base class Version < ActiveRecord::Base
before_destroy :check_integrity
after_update :update_issues_from_sharing_change after_update :update_issues_from_sharing_change
belongs_to :project belongs_to :project
has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id', :dependent => :nullify has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id'
acts_as_customizable acts_as_customizable
acts_as_attachable :view_permission => :view_files, acts_as_attachable :view_permission => :view_files,
:delete_permission => :manage_files :delete_permission => :manage_files
@@ -154,7 +155,10 @@ class Version < ActiveRecord::Base
end end
end end
private private
def check_integrity
raise "Can't delete version" if self.fixed_issues.find(:first)
end
# Update the issue's fixed versions. Used if a version's sharing changes. # Update the issue's fixed versions. Used if a version's sharing changes.
def update_issues_from_sharing_change def update_issues_from_sharing_change
-2
View File
@@ -1,4 +1,3 @@
<%= call_hook :view_account_login_top %>
<div id="login-form"> <div id="login-form">
<% form_tag({:action=> "login"}) do %> <% form_tag({:action=> "login"}) do %>
<%= back_url_hidden_field_tag %> <%= back_url_hidden_field_tag %>
@@ -39,4 +38,3 @@
<%= javascript_tag "Form.Element.focus('username');" %> <%= javascript_tag "Form.Element.focus('username');" %>
<% end %> <% end %>
</div> </div>
<%= call_hook :view_account_login_bottom %>
-4
View File
@@ -26,7 +26,3 @@
<% end %> <% end %>
<% html_title @document.title -%> <% html_title @document.title -%>
<% content_for :header_tags do %>
<%= stylesheet_link_tag 'scm' %>
<% end %>
+1 -1
View File
@@ -29,7 +29,7 @@
<% remote_form_for(:group, @group, :url => {:controller => 'groups', :action => 'add_users', :id => @group}, :method => :post) do |f| %> <% remote_form_for(:group, @group, :url => {:controller => 'groups', :action => 'add_users', :id => @group}, :method => :post) do |f| %>
<fieldset><legend><%=l(:label_user_new)%></legend> <fieldset><legend><%=l(:label_user_new)%></legend>
<p><%= text_field_tag 'user_search', nil %></p> <p><%= text_field_tag 'user_search', nil, :size => "40" %></p>
<%= observe_field(:user_search, <%= observe_field(:user_search,
:frequency => 0.5, :frequency => 0.5,
:update => :users, :update => :users,
+1 -1
View File
@@ -26,7 +26,7 @@
<% end %> <% end %>
<tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>"> <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %>">
<td class="checkbox"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td> <td class="checkbox"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
<td class="id"><%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %></td> <td><%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %></td>
<% query.columns.each do |column| %><%= content_tag 'td', column_content(column, issue), :class => column.name %><% end %> <% query.columns.each do |column| %><%= content_tag 'td', column_content(column, issue), :class => column.name %><% end %>
</tr> </tr>
<% end -%> <% end -%>
+4 -4
View File
@@ -10,10 +10,10 @@
<% form_tag({ :controller => 'queries', :action => 'new' }, :id => 'query_form') do %> <% form_tag({ :controller => 'queries', :action => 'new' }, :id => 'query_form') do %>
<%= hidden_field_tag('project_id', @project.to_param) if @project %> <%= hidden_field_tag('project_id', @project.to_param) if @project %>
<div id="query_form_content" class="hide-when-print"> <div id="query_form_content">
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>"> <fieldset id="filters" class="collapsible">
<legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend> <legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
<div style="<%= @query.new_record? ? "" : "display: none;" %>"> <div>
<%= render :partial => 'queries/filters', :locals => {:query => @query} %> <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
</div> </div>
</fieldset> </fieldset>
@@ -33,7 +33,7 @@
</div> </div>
</fieldset> </fieldset>
</div> </div>
<p class="buttons hide-when-print"> <p class="buttons">
<%= link_to_remote l(:button_apply), <%= link_to_remote l(:button_apply),
{ :url => { :set_filter => 1 }, { :url => { :set_filter => 1 },
-2
View File
@@ -40,11 +40,9 @@
<h1><%= page_header_title %></h1> <h1><%= page_header_title %></h1>
<% if display_main_menu?(@project) %>
<div id="main-menu"> <div id="main-menu">
<%= render_main_menu(@project) %> <%= render_main_menu(@project) %>
</div> </div>
<% end %>
</div> </div>
<%= tag('div', {:id => 'main', :class => (has_content?(:sidebar) ? '' : 'nosidebar')}, true) %> <%= tag('div', {:id => 'main', :class => (has_content?(:sidebar) ? '' : 'nosidebar')}, true) %>
+2 -2
View File
@@ -17,10 +17,10 @@
<% if Setting.rest_api_enabled? %> <% if Setting.rest_api_enabled? %>
<h4><%= l(:label_api_access_key) %></h4> <h4><%= l(:label_api_access_key) %></h4>
<div> <p>
<%= link_to_function(l(:button_show), "$('api-access-key').toggle();")%> <%= link_to_function(l(:button_show), "$('api-access-key').toggle();")%>
<pre id='api-access-key' class='autoscroll'><%= @user.api_key %></pre> <pre id='api-access-key' class='autoscroll'><%= @user.api_key %></pre>
</div> </p>
<%= javascript_tag("$('api-access-key').hide();") %> <%= javascript_tag("$('api-access-key').hide();") %>
<p> <p>
<% if @user.api_token %> <% if @user.api_token %>
-2
View File
@@ -21,8 +21,6 @@
<label class="block"><%= check_box_tag 'only[]', 'boards', true %> <%= l(:label_board_plural) %> (<%= @source_project.boards.count %>)</label> <label class="block"><%= check_box_tag 'only[]', 'boards', true %> <%= l(:label_board_plural) %> (<%= @source_project.boards.count %>)</label>
<label class="block"><%= check_box_tag 'only[]', 'wiki', true %> <%= l(:label_wiki_page_plural) %> (<%= @source_project.wiki.nil? ? 0 : @source_project.wiki.pages.count %>)</label> <label class="block"><%= check_box_tag 'only[]', 'wiki', true %> <%= l(:label_wiki_page_plural) %> (<%= @source_project.wiki.nil? ? 0 : @source_project.wiki.pages.count %>)</label>
<%= hidden_field_tag 'only[]', '' %> <%= hidden_field_tag 'only[]', '' %>
<br />
<label class="block"><%= check_box_tag 'notifications', 1, params[:notifications] %> <%= l(:label_project_copy_notifications) %></label>
</fieldset> </fieldset>
<%= submit_tag l(:button_copy) %> <%= submit_tag l(:button_copy) %>
-4
View File
@@ -1,7 +1,3 @@
<% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, {:action => 'index', :format => 'atom', :key => User.current.rss_key}) %>
<% end %>
<div class="contextual"> <div class="contextual">
<%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %> <%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %>
<%= link_to(l(:label_issue_view_all), { :controller => 'issues' }) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %> <%= link_to(l(:label_issue_view_all), { :controller => 'issues' }) + ' |' if User.current.allowed_to?(:view_issues, nil, :global => true) %>
+1 -1
View File
@@ -58,7 +58,7 @@
<% remote_form_for(:member, @member, :url => {:controller => 'members', :action => 'new', :id => @project}, :method => :post) do |f| %> <% remote_form_for(:member, @member, :url => {:controller => 'members', :action => 'new', :id => @project}, :method => :post) do |f| %>
<fieldset><legend><%=l(:label_member_new)%></legend> <fieldset><legend><%=l(:label_member_new)%></legend>
<p><%= text_field_tag 'principal_search', nil %></p> <p><%= text_field_tag 'principal_search', nil, :size => "40" %></p>
<%= observe_field(:principal_search, <%= observe_field(:principal_search,
:frequency => 0.5, :frequency => 0.5,
:update => :principals, :update => :principals,
+1 -3
View File
@@ -7,9 +7,7 @@
<h2><%=l(:label_overview)%></h2> <h2><%=l(:label_overview)%></h2>
<div class="splitcontentleft"> <div class="splitcontentleft">
<div class="wiki"> <%= textilizable @project.description %>
<%= textilizable @project.description %>
</div>
<ul> <ul>
<% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link(h(@project.homepage)) %></li><% end %> <% unless @project.homepage.blank? %><li><%=l(:field_homepage)%>: <%= auto_link(h(@project.homepage)) %></li><% end %>
<% if @subprojects.any? %> <% if @subprojects.any? %>
+1 -1
View File
@@ -16,6 +16,6 @@ dirs.each do |dir|
/ <%= link_to h(filename), :action => 'changes', :id => @project, :path => to_path_param("#{link_path}/#{filename}"), :rev => @rev %> / <%= link_to h(filename), :action => 'changes', :id => @project, :path => to_path_param("#{link_path}/#{filename}"), :rev => @rev %>
<% end %> <% end %>
<%= "@ #{h revision}" if revision %> <%= "@ #{revision}" if revision %>
<% html_title(with_leading_slash(path)) -%> <% html_title(with_leading_slash(path)) -%>
+29 -1
View File
@@ -1 +1,29 @@
instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb')) # Settings specified here will take precedence over those in config/environment.rb
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :test
config.action_controller.session = {
:session_key => "_test_session",
:secret => "some secret phrase for the tests."
}
# Skip protect_from_forgery in requests http://m.onkey.org/2007/9/28/csrf-protection-for-your-existing-rails-application
config.action_controller.allow_forgery_protection = false
config.gem "thoughtbot-shoulda", :lib => "shoulda", :source => "http://gems.github.com"
config.gem "nofxx-object_daddy", :lib => "object_daddy", :source => "http://gems.github.com"
config.gem "mocha"
+29 -1
View File
@@ -1 +1,29 @@
instance_eval File.read(File.join(File.dirname(__FILE__), 'test.rb')) # Settings specified here will take precedence over those in config/environment.rb
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :test
config.action_controller.session = {
:session_key => "_test_session",
:secret => "some secret phrase for the tests."
}
# Skip protect_from_forgery in requests http://m.onkey.org/2007/9/28/csrf-protection-for-your-existing-rails-application
config.action_controller.allow_forgery_protection = false
config.gem "thoughtbot-shoulda", :lib => "shoulda", :source => "http://gems.github.com"
config.gem "nofxx-object_daddy", :lib => "object_daddy", :source => "http://gems.github.com"
config.gem "mocha"
+1 -1
View File
@@ -881,4 +881,4 @@ bg:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -905,4 +905,3 @@ bs:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -884,4 +884,3 @@ ca:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -887,4 +887,3 @@ cs:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -907,4 +907,3 @@ da:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -907,4 +907,3 @@ de:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -887,4 +887,3 @@ el:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -748,7 +748,6 @@ en:
label_api_access_key: API access key label_api_access_key: API access key
label_missing_api_access_key: Missing an API access key label_missing_api_access_key: Missing an API access key
label_api_access_key_created_on: "API access key created {{value}} ago" label_api_access_key_created_on: "API access key created {{value}} ago"
label_project_copy_notifications: Send email notifications during the project copy
button_login: Login button_login: Login
button_submit: Submit button_submit: Submit
-1
View File
@@ -931,4 +931,3 @@ es:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -917,4 +917,3 @@ fi:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
+2 -3
View File
@@ -764,7 +764,6 @@ fr:
label_missing_feeds_access_key: Clé d'accès RSS manquante label_missing_feeds_access_key: Clé d'accès RSS manquante
label_close_versions: Fermer les versions terminées label_close_versions: Fermer les versions terminées
label_revision_id: Revision {{value}} label_revision_id: Revision {{value}}
label_project_copy_notifications: Envoyer les notifications durant la copie du projet
button_login: Connexion button_login: Connexion
button_submit: Soumettre button_submit: Soumettre
@@ -812,10 +811,10 @@ fr:
status_active: actif status_active: actif
status_registered: enregistré status_registered: enregistré
status_locked: verrouillé status_locked: vérouillé
version_status_open: ouvert version_status_open: ouvert
version_status_locked: verrouillé version_status_locked: vérouillé
version_status_closed: fermé version_status_closed: fermé
text_select_mail_notifications: Actions pour lesquelles une notification par e-mail est envoyée text_select_mail_notifications: Actions pour lesquelles une notification par e-mail est envoyée
-1
View File
@@ -907,4 +907,3 @@ gl:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -891,4 +891,3 @@ he:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -894,4 +894,3 @@ hr:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -912,4 +912,3 @@
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -899,4 +899,3 @@ id:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
+1 -1
View File
@@ -894,4 +894,4 @@ it:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -916,4 +916,3 @@ ja:
enumeration_activities: 作業分類 (時間トラッキング) enumeration_activities: 作業分類 (時間トラッキング)
enumeration_system_activity: システム作業分類 enumeration_system_activity: システム作業分類
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -947,4 +947,3 @@ ko:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -955,4 +955,3 @@ lt:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -869,4 +869,3 @@ nl:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -882,4 +882,3 @@
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -912,4 +912,3 @@ pl:
permission_export_wiki_pages: Eksport stron wiki permission_export_wiki_pages: Eksport stron wiki
permission_manage_project_activities: Zarządzanie aktywnościami projektu permission_manage_project_activities: Zarządzanie aktywnościami projektu
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -915,4 +915,3 @@ pt-BR:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -899,4 +899,3 @@ pt:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -884,4 +884,3 @@ ro:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -995,4 +995,3 @@ ru:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -886,4 +886,3 @@ sk:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -883,4 +883,3 @@ sl:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -902,4 +902,3 @@
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -936,4 +936,3 @@ sv:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -884,4 +884,3 @@ th:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -914,4 +914,3 @@ tr:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -883,4 +883,3 @@ uk:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -946,4 +946,3 @@ vi:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-1
View File
@@ -978,4 +978,3 @@
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
+1 -1
View File
@@ -909,4 +909,4 @@ zh:
permission_export_wiki_pages: Export wiki pages permission_export_wiki_pages: Export wiki pages
setting_cache_formatted_text: Cache formatted text setting_cache_formatted_text: Cache formatted text
permission_manage_project_activities: Manage project activities permission_manage_project_activities: Manage project activities
label_project_copy_notifications: Send email notifications during the project copy
-56
View File
@@ -4,62 +4,6 @@ Redmine - project management software
Copyright (C) 2006-2010 Jean-Philippe Lang Copyright (C) 2006-2010 Jean-Philippe Lang
http://www.redmine.org/ http://www.redmine.org/
== v1.0.0
Adds context menu to the roadmap issue lists
== 2010-07-07 v0.9.6
Fixed: Redmine.pm access by unauthorized users
== 2010-06-24 v0.9.5
Linkify folder names on revision view
"fiters" and "options" should be hidden in print view via css
Fixed: NoMethodError when no issue params are submitted
Fixed: projects.atom with required authentication
Fixed: External links not correctly displayed in Wiki TOC
Fixed: Member role forms in project settings are not hidden after member added
Fixed: pre can't be inside p
Fixed: session cookie path does not respect RAILS_RELATIVE_URL_ROOT
Fixed: mail handler fails when the from address is empty
== 2010-05-01 v0.9.4
Filters collapsed by default on issues index page for a saved query
Fixed: When categories list is too big the popup menu doesn't adjust (ex. in the issue list)
Fixed: remove "main-menu" div when the menu is empty
Fixed: Code syntax highlighting not working in Document page
Fixed: Git blame/annotate fails on moved files
Fixed: Failing test in test_show_atom
Fixed: Migrate from trac - not displayed Wikis
Fixed: Email notifications on file upload sent to empty recipient list
Fixed: Migrating from trac is not possible, fails to allocate memory
Fixed: Lost password no longer flashes a confirmation message
Fixed: Crash while deleting in-use enumeration
Fixed: Hard coded English string at the selection of issue watchers
Fixed: Bazaar v2.1.0 changed behaviour
Fixed: Roadmap display can raise an exception if no trackers are selected
Fixed: Gravatar breaks layout of "logged in" page
Fixed: Reposman.rb on Windows
Fixed: Possible error 500 while moving an issue to another project with SQLite
Fixed: backslashes in issue description/note should be escaped when quoted
Fixed: Long text in <pre> disrupts Associated revisions
Fixed: Links to missing wiki pages not red on project overview page
Fixed: Cannot delete a project with subprojects that shares versions
Fixed: Update of Subversion changesets broken under Solaris
Fixed: "Move issues" permission not working for Non member
Fixed: Sidebar overlap on Users tab of Group editor
Fixed: Error on db:migrate with table prefix set (hardcoded name in principal.rb)
Fixed: Report shows sub-projects for non-members
Fixed: 500 internal error when browsing any Redmine page in epiphany
Fixed: Watchers selection lost when issue creation fails
Fixed: When copying projects, redmine should not generate an email to people who created issues
Fixed: Issue "#" table cells should have a class attribute to enable fine-grained CSS theme
Fixed: Plugin generators should display help if no parameter is given
== 2010-02-28 v0.9.3 == 2010-02-28 v0.9.3
Adds filter for system shared versions on the cross project issue list Adds filter for system shared versions on the cross project issue list
+1 -1
View File
@@ -33,7 +33,7 @@ Optional:
4. Generate a session store secret 4. Generate a session store secret
Redmine stores session data in cookies by default, which requires Redmine stores session data in cookies by default, which requires
a secret to be generated. Run: a secret to be generated. Run:
rake generate_session_store rake config/initializers/session_store.rb
5. Create the database structure. Under the application main directory: 5. Create the database structure. Under the application main directory:
rake db:migrate RAILS_ENV="production" rake db:migrate RAILS_ENV="production"
+2 -2
View File
@@ -12,12 +12,12 @@ http://www.redmine.org/
2. Copy your database settings (RAILS_ROOT/config/database.yml) 2. Copy your database settings (RAILS_ROOT/config/database.yml)
and SMTP settings (RAILS_ROOT/config/email.yml) and SMTP settings (RAILS_ROOT/config/email.yml)
into the new config directory into the new config directory
DO NOT REPLACE OR EDIT ANY OTHER FILES. DO NOT REPLACE ANY OTHERS FILES.
3. Generate a session store secret 3. Generate a session store secret
Redmine stores session data in cookies by default, which requires Redmine stores session data in cookies by default, which requires
a secret to be generated. Run: a secret to be generated. Run:
rake generate_session_store rake config/initializers/session_store.rb
4. Migrate your database (please make a backup before doing this): 4. Migrate your database (please make a backup before doing this):
rake db:migrate RAILS_ENV="production" rake db:migrate RAILS_ENV="production"
+1 -32
View File
@@ -227,38 +227,9 @@ sub authen_handler {
} }
} }
# check if authentication is forced
sub is_authentication_forced {
my $r = shift;
my $dbh = connect_database($r);
my $sth = $dbh->prepare(
"SELECT value FROM settings where settings.name = 'login_required';"
);
$sth->execute();
my $ret = 0;
if (my @row = $sth->fetchrow_array) {
if ($row[0] eq "1" || $row[0] eq "t") {
$ret = 1;
}
}
$sth->finish();
undef $sth;
$dbh->disconnect();
undef $dbh;
$ret;
}
sub is_public_project { sub is_public_project {
my $project_id = shift; my $project_id = shift;
my $r = shift; my $r = shift;
if (is_authentication_forced($r)) {
return 0;
}
my $dbh = connect_database($r); my $dbh = connect_database($r);
my $sth = $dbh->prepare( my $sth = $dbh->prepare(
@@ -338,9 +309,7 @@ sub is_member {
bindpw => $rowldap[4] ? $rowldap[4] : "", bindpw => $rowldap[4] ? $rowldap[4] : "",
filter => "(".$rowldap[6]."=%s)" filter => "(".$rowldap[6]."=%s)"
); );
my $method = $r->method; $ret = 1 if ($ldap->authenticate($redmine_user, $redmine_pass));
$ret = 1 if ($ldap->authenticate($redmine_user, $redmine_pass) && ((defined $read_only_methods{$method} && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/));
} }
$sthldap->finish(); $sthldap->finish();
undef $sthldap; undef $sthldap;
+2 -6
View File
@@ -221,14 +221,10 @@ def other_read_right?(file)
end end
def owner_name(file) def owner_name(file)
mswin? ? RUBY_PLATFORM =~ /mswin/ ?
$svn_owner : $svn_owner :
Etc.getpwuid( File.stat(file).uid ).name Etc.getpwuid( File.stat(file).uid ).name
end end
def mswin?
(RUBY_PLATFORM =~ /(:?mswin|mingw)/) || (RUBY_PLATFORM == 'java' && (ENV['OS'] || ENV['os']) =~ /windows/i)
end
projects.each do |project| projects.each do |project|
log("treating project #{project.name}", :level => 1) log("treating project #{project.name}", :level => 1)
@@ -307,4 +303,4 @@ projects.each do |project|
end end
end end
@@ -6,7 +6,6 @@ class RedminePluginControllerGenerator < ControllerGenerator
def initialize(runtime_args, runtime_options = {}) def initialize(runtime_args, runtime_options = {})
runtime_args = runtime_args.dup runtime_args = runtime_args.dup
usage if runtime_args.empty?
@plugin_name = "redmine_" + runtime_args.shift.underscore @plugin_name = "redmine_" + runtime_args.shift.underscore
@plugin_pretty_name = plugin_name.titleize @plugin_pretty_name = plugin_name.titleize
@plugin_path = "vendor/plugins/#{plugin_name}" @plugin_path = "vendor/plugins/#{plugin_name}"
@@ -6,7 +6,6 @@ class RedminePluginModelGenerator < ModelGenerator
def initialize(runtime_args, runtime_options = {}) def initialize(runtime_args, runtime_options = {})
runtime_args = runtime_args.dup runtime_args = runtime_args.dup
usage if runtime_args.empty?
@plugin_name = "redmine_" + runtime_args.shift.underscore @plugin_name = "redmine_" + runtime_args.shift.underscore
@plugin_pretty_name = plugin_name.titleize @plugin_pretty_name = plugin_name.titleize
@plugin_path = "vendor/plugins/#{plugin_name}" @plugin_path = "vendor/plugins/#{plugin_name}"
+1 -1
View File
@@ -818,7 +818,7 @@ class RedCloth3 < String
post = ")"+post # add closing parenth to post post = ")"+post # add closing parenth to post
end end
atts = pba( atts ) atts = pba( atts )
atts = " href=\"#{ htmlesc url }#{ slash }\"#{ atts }" atts = " href=\"#{ url }#{ slash }\"#{ atts }"
atts << " title=\"#{ htmlesc title }\"" if title atts << " title=\"#{ htmlesc title }\"" if title
atts = shelve( atts ) if atts atts = shelve( atts ) if atts
-5
View File
@@ -166,11 +166,6 @@ module Redmine
render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project) render_menu((project && !project.new_record?) ? :project_menu : :application_menu, project)
end end
def display_main_menu?(project)
menu_name = project && !project.new_record? ? :project_menu : :application_menu
Redmine::MenuManager.items(menu_name).size > 1 # 1 element is the root
end
def render_menu(menu, project=nil) def render_menu(menu, project=nil)
links = [] links = []
menu_items_for(menu, project) do |node| menu_items_for(menu, project) do |node|
+5 -5
View File
@@ -56,14 +56,14 @@ module Redmine
shellout(cmd) do |io| shellout(cmd) do |io|
prefix = "#{url}/#{path}".gsub('\\', '/') prefix = "#{url}/#{path}".gsub('\\', '/')
logger.debug "PREFIX: #{prefix}" logger.debug "PREFIX: #{prefix}"
re = %r{^V\s+(#{Regexp.escape(prefix)})?(\/?)([^\/]+)(\/?)\s+(\S+)$} re = %r{^V\s+#{Regexp.escape(prefix)}(\/?)([^\/]+)(\/?)\s+(\S+)$}
io.each_line do |line| io.each_line do |line|
next unless line =~ re next unless line =~ re
entries << Entry.new({:name => $3.strip, entries << Entry.new({:name => $2.strip,
:path => ((path.empty? ? "" : "#{path}/") + $3.strip), :path => ((path.empty? ? "" : "#{path}/") + $2.strip),
:kind => ($4.blank? ? 'file' : 'dir'), :kind => ($3.blank? ? 'file' : 'dir'),
:size => nil, :size => nil,
:lastrev => Revision.new(:revision => $5.strip) :lastrev => Revision.new(:revision => $4.strip)
}) })
end end
end end
+3 -13
View File
@@ -227,26 +227,16 @@ module Redmine
def annotate(path, identifier=nil) def annotate(path, identifier=nil)
identifier = 'HEAD' if identifier.blank? identifier = 'HEAD' if identifier.blank?
cmd = "#{GIT_BIN} --git-dir #{target('')} blame -p #{shell_quote identifier} -- #{shell_quote path}" cmd = "#{GIT_BIN} --git-dir #{target('')} blame -l #{shell_quote identifier} -- #{shell_quote path}"
blame = Annotate.new blame = Annotate.new
content = nil content = nil
shellout(cmd) { |io| io.binmode; content = io.read } shellout(cmd) { |io| io.binmode; content = io.read }
return nil if $? && $?.exitstatus != 0 return nil if $? && $?.exitstatus != 0
# git annotates binary files # git annotates binary files
return nil if content.is_binary_data? return nil if content.is_binary_data?
identifier = ''
# git shows commit author on the first occurrence only
authors_by_commit = {}
content.split("\n").each do |line| content.split("\n").each do |line|
if line =~ /^([0-9a-f]{39,40})\s.*/ next unless line =~ /([0-9a-f]{39,40})\s\((\w*)[^\)]*\)(.*)/
identifier = $1 blame.add_line($3.rstrip, Revision.new(:identifier => $1, :author => $2.strip))
elsif line =~ /^author (.+)/
authors_by_commit[identifier] = $1.strip
elsif line =~ /^\t(.*)/
blame.add_line($1, Revision.new(:identifier => identifier, :author => authors_by_commit[identifier]))
identifier = ''
author = ''
end
end end
blame blame
end end
+1 -1
View File
@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc: module VERSION #:nodoc:
MAJOR = 0 MAJOR = 0
MINOR = 9 MINOR = 9
TINY = 6 TINY = 3
# Branch values: # Branch values:
# * official release: nil # * official release: nil
@@ -22,7 +22,6 @@ module Redmine
module WikiFormatting module WikiFormatting
module Textile module Textile
class Formatter < RedCloth3 class Formatter < RedCloth3
include ActionView::Helpers::TagHelper
# auto_link rule after textile rules so that it doesn't break !image_url! tags # auto_link rule after textile rules so that it doesn't break !image_url! tags
RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_toc, :inline_macros] RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_toc, :inline_macros]
@@ -67,11 +66,6 @@ module Redmine
def textile_p_withtoc(tag, atts, cite, content) def textile_p_withtoc(tag, atts, cite, content)
# removes wiki links from the item # removes wiki links from the item
toc_item = content.gsub(/(\[\[([^\]\|]*)(\|([^\]]*))?\]\])/) { $4 || $2 } toc_item = content.gsub(/(\[\[([^\]\|]*)(\|([^\]]*))?\]\])/) { $4 || $2 }
# sanitizes titles from links
# see redcloth3.rb, same as "#{pre}#{text}#{post}"
toc_item.gsub!(LINK_RE) { [$2, $4, $9].join }
# sanitizes image links from titles
toc_item.gsub!(IMAGE_RE) { [$5].join }
# removes styles # removes styles
# eg. %{color:red}Triggers% => Triggers # eg. %{color:red}Triggers% => Triggers
toc_item.gsub! %r[%\{[^\}]*\}([^%]+)%], '\\1' toc_item.gsub! %r[%\{[^\}]*\}([^%]+)%], '\\1'
@@ -168,8 +162,7 @@ module Redmine
url=url[0..-2] # discard closing parenth from url url=url[0..-2] # discard closing parenth from url
post = ")"+post # add closing parenth to post post = ")"+post # add closing parenth to post
end end
tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external') %(#{leading}<a class="external" href="#{proto=="www."?"http://www.":proto}#{url}">#{proto + url}</a>#{post})
%(#{leading}#{tag}#{post})
end end
end end
end end
@@ -181,7 +174,7 @@ module Redmine
if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/) if text.match(/<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/)
mail mail
else else
content_tag('a', mail, :href => "mailto:#{mail}", :class => "email") %{<a href="mailto:#{mail}" class="email">#{mail}</a>}
end end
end end
end end
-7
View File
@@ -17,13 +17,6 @@ file 'config/initializers/session_store.rb' do
# you'll be exposed to dictionary attacks. # you'll be exposed to dictionary attacks.
ActionController::Base.session = { ActionController::Base.session = {
:session_key => '_redmine_session', :session_key => '_redmine_session',
#
# Uncomment and edit the :session_path below if are hosting your Redmine
# at a suburi and don't want the top level path to access the cookies
#
# See: http://www.redmine.org/issues/3968
#
# :session_path => '/url_path_to/your/redmine/',
:secret => '#{secret}' :secret => '#{secret}'
} }
EOF EOF
+1 -2
View File
@@ -310,7 +310,7 @@ namespace :redmine do
# Ticket number re-writing # Ticket number re-writing
text = text.gsub(/#(\d+)/) do |s| text = text.gsub(/#(\d+)/) do |s|
if $1.length < 10 if $1.length < 10
# TICKET_MAP[$1.to_i] ||= $1 TICKET_MAP[$1.to_i] ||= $1
"\##{TICKET_MAP[$1.to_i] || $1}" "\##{TICKET_MAP[$1.to_i] || $1}"
else else
s s
@@ -682,7 +682,6 @@ namespace :redmine do
project.trackers << TRACKER_BUG unless project.trackers.include?(TRACKER_BUG) project.trackers << TRACKER_BUG unless project.trackers.include?(TRACKER_BUG)
project.trackers << TRACKER_FEATURE unless project.trackers.include?(TRACKER_FEATURE) project.trackers << TRACKER_FEATURE unless project.trackers.include?(TRACKER_FEATURE)
@target_project = project.new_record? ? nil : project @target_project = project.new_record? ? nil : project
@target_project.reload
end end
def self.connection_params def self.connection_params
-9
View File
@@ -207,12 +207,3 @@ Ajax.Responders.register({
} }
} }
}); });
function hideOnLoad() {
$$('.hol').each(function(el) {
el.hide();
});
}
Event.observe(window, 'load', hideOnLoad);
+5 -8
View File
@@ -399,8 +399,6 @@ div#tab-content-members fieldset div, div#tab-content-users fieldset div { max-h
table.members td.group { padding-left: 20px; background: url(../images/group.png) no-repeat 0% 50%; } table.members td.group { padding-left: 20px; background: url(../images/group.png) no-repeat 0% 50%; }
input#principal_search, input#user_search {width:100%}
* html div#tab-content-members fieldset div { height: 450px; } * html div#tab-content-members fieldset div { height: 450px; }
/***** Flash & error messages ****/ /***** Flash & error messages ****/
@@ -642,7 +640,7 @@ div.wiki pre {
padding: 2px; padding: 2px;
background-color: #fafafa; background-color: #fafafa;
border: 1px solid #dadada; border: 1px solid #dadada;
width:auto; width:95%;
overflow-x: auto; overflow-x: auto;
} }
@@ -817,14 +815,14 @@ div.issue table img.gravatar {
h2 img.gravatar { h2 img.gravatar {
padding: 3px; padding: 3px;
margin: -2px 4px -4px 0; margin: -2px 4px 0 0;
vertical-align: top; float: left;
} }
h4 img.gravatar { h4 img.gravatar {
padding: 3px; padding: 3px;
margin: -6px 0 -4px 0; margin: -6px 4px 0 0;
vertical-align: top; float: left;
} }
td.username img.gravatar { td.username img.gravatar {
@@ -852,5 +850,4 @@ h2 img { vertical-align:middle; }
#main { background: #fff; } #main { background: #fff; }
#content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;} #content { width: 99%; margin: 0; padding: 0; border: 0; background: #fff; overflow: visible !important;}
#wiki_add_attachment { display:none; } #wiki_add_attachment { display:none; }
.hide-when-print { display: none; }
} }
+1 -1
View File
@@ -22,7 +22,7 @@
padding:1px; padding:1px;
z-index:39; z-index:39;
} }
#context-menu li.folder ul { position:absolute; left:168px; /* IE6 */ top:-2px; max-height:300px; overflow:hidden; overflow-y: auto; } #context-menu li.folder ul { position:absolute; left:168px; /* IE6 */ top:-2px; }
#context-menu li.folder>ul { left:148px; } #context-menu li.folder>ul { left:148px; }
#context-menu.reverse-y li.folder>ul { top:auto; bottom:0; } #context-menu.reverse-y li.folder>ul { top:auto; bottom:0; }
-17
View File
@@ -1,17 +0,0 @@
Return-Path: <john.doe@somenet.foo>
Received: from osiris ([127.0.0.1])
by OSIRIS
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
To: <redmine@somenet.foo>
Subject: Ticket by unknown user
Date: Sun, 22 Jun 2008 12:28:07 +0200
MIME-Version: 1.0
Content-Type: text/plain;
format=flowed;
charset="iso-8859-1";
reply-type=original
Content-Transfer-Encoding: 7bit
This is a ticket submitted by an unknown user.
+1 -7
View File
@@ -436,7 +436,7 @@ class IssuesControllerTest < ActionController::TestCase
assert_response :success assert_response :success
assert_template 'changes.rxml' assert_template 'changes.rxml'
# Inline image # Inline image
assert_select 'content', :text => Regexp.new(Regexp.quote('http://test.host/attachments/download/10')) assert @response.body.include?("&lt;img src=\"http://test.host/attachments/download/10\" alt=\"\" /&gt;"), "Body did not match. Body: #{@response.body}"
end end
def test_new_routing def test_new_routing
@@ -649,12 +649,6 @@ class IssuesControllerTest < ActionController::TestCase
:value => 'Value for field 2'} :value => 'Value for field 2'}
end end
test "POST new with no issue params" do
@request.session[:user_id] = 2
post :new, :project_id => 1
assert_response :success
end
def test_copy_routing def test_copy_routing
assert_routing( assert_routing(
{:method => :get, :path => '/projects/world_domination/issues/567/copy'}, {:method => :get, :path => '/projects/world_domination/issues/567/copy'},
-15
View File
@@ -15,21 +15,6 @@ class GitAdapterTest < ActiveSupport::TestCase
def test_getting_all_revisions def test_getting_all_revisions
assert_equal 12, @adapter.revisions('',nil,nil,:all => true).length assert_equal 12, @adapter.revisions('',nil,nil,:all => true).length
end end
def test_annotate
annotate = @adapter.annotate('sources/watchers_controller.rb')
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
assert_equal 41, annotate.lines.size
assert_equal "# This program is free software; you can redistribute it and/or", annotate.lines[4].strip
assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", annotate.revisions[4].identifier
assert_equal "jsmith", annotate.revisions[4].author
end
def test_annotate_moved_file
annotate = @adapter.annotate('renamed_test.txt')
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
assert_equal 2, annotate.lines.size
end
else else
puts "Git test repository NOT FOUND. Skipping unit tests !!!" puts "Git test repository NOT FOUND. Skipping unit tests !!!"
def test_fake; assert true end def test_fake; assert true end
+2 -12
View File
@@ -59,14 +59,12 @@ class ApplicationHelperTest < HelperTestCase
'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>', 'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
# two exclamation marks # two exclamation marks
'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>', 'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
# escaping
'http://foo"bar' => '<a class="external" href="http://foo&quot;bar">http://foo"bar</a>',
} }
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
end end
def test_auto_mailto def test_auto_mailto
assert_equal '<p><a class="email" href="mailto:test@foo.bar">test@foo.bar</a></p>', assert_equal '<p><a href="mailto:test@foo.bar" class="email">test@foo.bar</a></p>',
textilizable('test@foo.bar') textilizable('test@foo.bar')
end end
@@ -131,8 +129,6 @@ RAW
"\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>", "\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
# two exclamation marks # two exclamation marks
'"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>', '"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
# escaping
'"test":http://foo"bar' => '<a href="http://foo&quot;bar" class="external">test</a>',
} }
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) } to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
end end
@@ -364,10 +360,6 @@ h2. Subtitle with %{color:red}red text%
h1. Another title h1. Another title
h2. An "Internet link":http://www.redmine.org/ inside subtitle
h2. "Project Name !/attachments/1234/logo_small.gif! !/attachments/5678/logo_2.png!":/projects/projectname/issues
RAW RAW
expected = '<ul class="toc">' + expected = '<ul class="toc">' +
@@ -376,10 +368,8 @@ RAW
'<li class="heading2"><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' + '<li class="heading2"><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
'<li class="heading2"><a href="#Subtitle-with-red-text">Subtitle with red text</a></li>' + '<li class="heading2"><a href="#Subtitle-with-red-text">Subtitle with red text</a></li>' +
'<li class="heading1"><a href="#Another-title">Another title</a></li>' + '<li class="heading1"><a href="#Another-title">Another title</a></li>' +
'<li class="heading2"><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
'<li class="heading2"><a href="#Project-Name">Project Name</a></li>' +
'</ul>' '</ul>'
assert textilizable(raw).gsub("\n", "").include?(expected) assert textilizable(raw).gsub("\n", "").include?(expected)
end end
-26
View File
@@ -386,16 +386,6 @@ class IssueTest < ActiveSupport::TestCase
assert_equal 7, issue.fixed_version_id assert_equal 7, issue.fixed_version_id
end end
def test_move_to_another_project_with_disabled_tracker
issue = Issue.find(1)
target = Project.find(2)
target.tracker_ids = [3]
target.save
assert_equal false, issue.move_to(target)
issue.reload
assert_equal 1, issue.project_id
end
def test_copy_to_the_same_project def test_copy_to_the_same_project
issue = Issue.find(1) issue = Issue.find(1)
copy = nil copy = nil
@@ -599,20 +589,4 @@ class IssueTest < ActiveSupport::TestCase
end end
end end
end end
context ".allowed_target_projects_on_move" do
should "return all active projects for admin users" do
User.current = User.find(1)
assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
end
should "return allowed projects for non admin users" do
User.current = User.find(2)
Role.non_member.remove_permission! :move_issues
assert_equal 3, Issue.allowed_target_projects_on_move.size
Role.non_member.add_permission! :move_issues
assert_equal Project.active.count, Issue.allowed_target_projects_on_move.size
end
end
end end
-9
View File
@@ -166,15 +166,6 @@ class MailHandlerTest < ActiveSupport::TestCase
assert issue.author.anonymous? assert issue.author.anonymous?
end end
end end
def test_add_issue_by_anonymous_user_with_no_from_address
Role.anonymous.add_permission!(:add_issues)
assert_no_difference 'User.count' do
issue = submit_email('ticket_by_empty_user.eml', :issue => {:project => 'ecookbook'}, :unknown_user => 'accept')
assert issue.is_a?(Issue)
assert issue.author.anonymous?
end
end
def test_add_issue_by_anonymous_user_on_private_project def test_add_issue_by_anonymous_user_on_private_project
Role.anonymous.add_permission!(:add_issues) Role.anonymous.add_permission!(:add_issues)
-37
View File
@@ -21,12 +21,6 @@ class MailerTest < ActiveSupport::TestCase
include Redmine::I18n include Redmine::I18n
include ActionController::Assertions::SelectorAssertions include ActionController::Assertions::SelectorAssertions
fixtures :projects, :enabled_modules, :issues, :users, :members, :member_roles, :roles, :documents, :attachments, :news, :tokens, :journals, :journal_details, :changesets, :trackers, :issue_statuses, :enumerations, :messages, :boards, :repositories fixtures :projects, :enabled_modules, :issues, :users, :members, :member_roles, :roles, :documents, :attachments, :news, :tokens, :journals, :journal_details, :changesets, :trackers, :issue_statuses, :enumerations, :messages, :boards, :repositories
def setup
ActionMailer::Base.deliveries.clear
Setting.host_name = 'mydomain.foo'
Setting.protocol = 'http'
end
def test_generated_links_in_emails def test_generated_links_in_emails
ActionMailer::Base.deliveries.clear ActionMailer::Base.deliveries.clear
@@ -237,20 +231,6 @@ class MailerTest < ActiveSupport::TestCase
end end
end end
def test_version_file_added
attachements = [ Attachment.find_by_container_type('Version') ]
assert Mailer.deliver_attachments_added(attachements)
assert_not_nil last_email.bcc
assert last_email.bcc.any?
end
def test_project_file_added
attachements = [ Attachment.find_by_container_type('Project') ]
assert Mailer.deliver_attachments_added(attachements)
assert_not_nil last_email.bcc
assert last_email.bcc.any?
end
def test_news_added def test_news_added
news = News.find(:first) news = News.find(:first)
valid_languages.each do |lang| valid_languages.each do |lang|
@@ -302,14 +282,6 @@ class MailerTest < ActiveSupport::TestCase
end end
end end
def test_test
user = User.find(1)
valid_languages.each do |lang|
user.update_attribute :language, lang.to_s
assert Mailer.deliver_test(user)
end
end
def test_reminders def test_reminders
ActionMailer::Base.deliveries.clear ActionMailer::Base.deliveries.clear
Mailer.reminders(:days => 42) Mailer.reminders(:days => 42)
@@ -338,13 +310,4 @@ class MailerTest < ActiveSupport::TestCase
assert_equal :it, current_language assert_equal :it, current_language
end end
def test_with_deliveries_off
Mailer.with_deliveries false do
Mailer.deliver_test(User.find(1))
end
assert ActionMailer::Base.deliveries.empty?
# should restore perform_deliveries
assert ActionMailer::Base.perform_deliveries
end
end end
-6
View File
@@ -47,12 +47,6 @@ class WatcherTest < ActiveSupport::TestCase
assert Issue.watched_by(@user).include?(@issue) assert Issue.watched_by(@user).include?(@issue)
end end
def test_watcher_user_ids
issue = Issue.new
issue.watcher_user_ids = ['1', '3']
assert issue.watched_by?(User.find(1))
end
def test_recipients def test_recipients
@issue.watchers.delete_all @issue.watchers.delete_all
@issue.reload @issue.reload
+2 -2
View File
@@ -46,9 +46,9 @@ module Redmine
watching ? add_watcher(user) : remove_watcher(user) watching ? add_watcher(user) : remove_watcher(user)
end end
# Returns true if object is watched by +user+ # Returns true if object is watched by user
def watched_by?(user) def watched_by?(user)
!!(user && self.watcher_user_ids.detect {|uid| uid == user.id }) !!(user && self.watchers.detect {|w| w.user_id == user.id })
end end
# Returns an array of watchers' email addresses # Returns an array of watchers' email addresses