Compare commits
50
Commits
1.3.1
..
1.3-stable
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f2ebc202d | ||
|
|
d85f8425d9 | ||
|
|
4215198570 | ||
|
|
ed0d0533e7 | ||
|
|
22d639402c | ||
|
|
cda408dd81 | ||
|
|
bec5e4443d | ||
|
|
cb37643ea9 | ||
|
|
3e24f6f110 | ||
|
|
2e6347a2f1 | ||
|
|
8a2a17b8eb | ||
|
|
b24ad1f0bc | ||
|
|
898e10491f | ||
|
|
4a9013917d | ||
|
|
4e64c01a32 | ||
|
|
177ff05b97 | ||
|
|
e41afb4fe9 | ||
|
|
5475e0dcc5 | ||
|
|
985c885f98 | ||
|
|
210419047c | ||
|
|
add23a54b5 | ||
|
|
8f66932a46 | ||
|
|
bddc546bf0 | ||
|
|
5141f1e474 | ||
|
|
94a0d1abf0 | ||
|
|
ee6450f812 | ||
|
|
4b141793ab | ||
|
|
fc584eb3ad | ||
|
|
6f30f85f96 | ||
|
|
8c6f674973 | ||
|
|
0b0f819cfa | ||
|
|
41dba6864a | ||
|
|
4cf38052c2 | ||
|
|
f587807f6b | ||
|
|
f74e4eddba | ||
|
|
39af3f1b79 | ||
|
|
92dde0d75f | ||
|
|
488926276d | ||
|
|
90c6a8579b | ||
|
|
4930b3e8bf | ||
|
|
09ea1fd58d | ||
|
|
8eb4bc9c29 | ||
|
|
ffc6c99ae8 | ||
|
|
294accf197 | ||
|
|
8270de39f0 | ||
|
|
26db0de8cc | ||
|
|
f8875ee513 | ||
|
|
cbd90fdeaf | ||
|
|
d5573e67e9 | ||
|
|
5b0178299b |
@@ -73,9 +73,7 @@ class AdminController < ApplicationController
|
|||||||
def info
|
def info
|
||||||
@db_adapter_name = ActiveRecord::Base.connection.adapter_name
|
@db_adapter_name = ActiveRecord::Base.connection.adapter_name
|
||||||
@checklist = [
|
@checklist = [
|
||||||
[:text_default_administrator_account_changed,
|
[:text_default_administrator_account_changed, User.default_admin_account_changed?],
|
||||||
User.find(:first,
|
|
||||||
:conditions => ["login=? and hashed_password=?", 'admin', User.hash_password('admin')]).nil?],
|
|
||||||
[:text_file_repository_writable, File.writable?(Attachment.storage_path)],
|
[:text_file_repository_writable, File.writable?(Attachment.storage_path)],
|
||||||
[:text_plugin_assets_writable, File.writable?(Engines.public_directory)],
|
[:text_plugin_assets_writable, File.writable?(Engines.public_directory)],
|
||||||
[:text_rmagick_available, Object.const_defined?(:Magick)]
|
[:text_rmagick_available, Object.const_defined?(:Magick)]
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ class BoardsController < ApplicationController
|
|||||||
verify :method => :post, :only => [ :destroy ], :redirect_to => { :action => :index }
|
verify :method => :post, :only => [ :destroy ], :redirect_to => { :action => :index }
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@board = Board.new(params[:board])
|
@board = Board.new
|
||||||
|
@board.safe_attributes = params[:board]
|
||||||
@board.project = @project
|
@board.project = @project
|
||||||
if request.post? && @board.save
|
if request.post? && @board.save
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
@@ -74,7 +75,8 @@ class BoardsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
if request.post? && @board.update_attributes(params[:board])
|
@board.safe_attributes = params[:board]
|
||||||
|
if request.post? && @board.save
|
||||||
redirect_to_settings_in_projects
|
redirect_to_settings_in_projects
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ class CommentsController < ApplicationController
|
|||||||
|
|
||||||
verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
|
verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
|
||||||
def create
|
def create
|
||||||
@comment = Comment.new(params[:comment])
|
@comment = Comment.new
|
||||||
|
@comment.safe_attributes = params[:comment]
|
||||||
@comment.author = User.current
|
@comment.author = User.current
|
||||||
if @news.comments << @comment
|
if @news.comments << @comment
|
||||||
flash[:notice] = l(:label_comment_added)
|
flash[:notice] = l(:label_comment_added)
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ class DocumentsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@document = @project.documents.build(params[:document])
|
@document = @project.documents.build
|
||||||
|
@document.safe_attributes = params[:document]
|
||||||
if request.post? and @document.save
|
if request.post? and @document.save
|
||||||
attachments = Attachment.attach_files(@document, params[:attachments])
|
attachments = Attachment.attach_files(@document, params[:attachments])
|
||||||
render_attachment_warning_if_needed(@document)
|
render_attachment_warning_if_needed(@document)
|
||||||
@@ -58,7 +59,8 @@ class DocumentsController < ApplicationController
|
|||||||
|
|
||||||
def edit
|
def edit
|
||||||
@categories = DocumentCategory.active #TODO: use it in the views
|
@categories = DocumentCategory.active #TODO: use it in the views
|
||||||
if request.post? and @document.update_attributes(params[:document])
|
@document.safe_attributes = params[:document]
|
||||||
|
if request.post? and @document.save
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'show', :id => @document
|
redirect_to :action => 'show', :id => @document
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -39,12 +39,14 @@ class IssueCategoriesController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@category = @project.issue_categories.build(params[:issue_category])
|
@category = @project.issue_categories.build
|
||||||
|
@category.safe_attributes = params[:issue_category]
|
||||||
end
|
end
|
||||||
|
|
||||||
verify :method => :post, :only => :create
|
verify :method => :post, :only => :create
|
||||||
def create
|
def create
|
||||||
@category = @project.issue_categories.build(params[:issue_category])
|
@category = @project.issue_categories.build
|
||||||
|
@category.safe_attributes = params[:issue_category]
|
||||||
if @category.save
|
if @category.save
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
@@ -75,7 +77,8 @@ class IssueCategoriesController < ApplicationController
|
|||||||
|
|
||||||
verify :method => :put, :only => :update
|
verify :method => :put, :only => :update
|
||||||
def update
|
def update
|
||||||
if @category.update_attributes(params[:issue_category])
|
@category.safe_attributes = params[:issue_category]
|
||||||
|
if @category.save
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {
|
format.html {
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ class MembersController < ApplicationController
|
|||||||
attrs = params[:member].dup
|
attrs = params[:member].dup
|
||||||
if (user_ids = attrs.delete(:user_ids))
|
if (user_ids = attrs.delete(:user_ids))
|
||||||
user_ids.each do |user_id|
|
user_ids.each do |user_id|
|
||||||
members << Member.new(attrs.merge(:user_id => user_id))
|
members << Member.new(:role_ids => params[:member][:role_ids], :user_id => user_id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
members << Member.new(attrs)
|
members << Member.new(:role_ids => params[:member][:role_ids], :user_id => params[:member][:user_id])
|
||||||
end
|
end
|
||||||
@project.members << members
|
@project.members << members
|
||||||
end
|
end
|
||||||
@@ -64,7 +64,10 @@ class MembersController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
if request.post? and @member.update_attributes(params[:member])
|
if params[:member]
|
||||||
|
@member.role_ids = params[:member][:role_ids]
|
||||||
|
end
|
||||||
|
if request.post? and @member.save
|
||||||
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 {
|
format.js {
|
||||||
@@ -93,7 +96,7 @@ class MembersController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def autocomplete_for_member
|
def autocomplete_for_member
|
||||||
@principals = Principal.active.like(params[:q]).find(:all, :limit => 100) - @project.principals
|
@principals = Principal.active.not_member_of(@project).like(params[:q]).all(:limit => 100)
|
||||||
render :layout => false
|
render :layout => false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -53,13 +53,10 @@ class MessagesController < ApplicationController
|
|||||||
|
|
||||||
# Create a new topic
|
# Create a new topic
|
||||||
def new
|
def new
|
||||||
@message = Message.new(params[:message])
|
@message = Message.new
|
||||||
@message.author = User.current
|
@message.author = User.current
|
||||||
@message.board = @board
|
@message.board = @board
|
||||||
if params[:message] && User.current.allowed_to?(:edit_messages, @project)
|
@message.safe_attributes = params[:message]
|
||||||
@message.locked = params[:message]['locked']
|
|
||||||
@message.sticky = params[:message]['sticky']
|
|
||||||
end
|
|
||||||
if request.post? && @message.save
|
if request.post? && @message.save
|
||||||
call_hook(:controller_messages_new_after_save, { :params => params, :message => @message})
|
call_hook(:controller_messages_new_after_save, { :params => params, :message => @message})
|
||||||
attachments = Attachment.attach_files(@message, params[:attachments])
|
attachments = Attachment.attach_files(@message, params[:attachments])
|
||||||
@@ -70,9 +67,10 @@ class MessagesController < ApplicationController
|
|||||||
|
|
||||||
# Reply to a topic
|
# Reply to a topic
|
||||||
def reply
|
def reply
|
||||||
@reply = Message.new(params[:reply])
|
@reply = Message.new
|
||||||
@reply.author = User.current
|
@reply.author = User.current
|
||||||
@reply.board = @board
|
@reply.board = @board
|
||||||
|
@reply.safe_attributes = params[:reply]
|
||||||
@topic.children << @reply
|
@topic.children << @reply
|
||||||
if !@reply.new_record?
|
if !@reply.new_record?
|
||||||
call_hook(:controller_messages_reply_after_save, { :params => params, :message => @reply})
|
call_hook(:controller_messages_reply_after_save, { :params => params, :message => @reply})
|
||||||
@@ -85,11 +83,8 @@ class MessagesController < ApplicationController
|
|||||||
# Edit a message
|
# Edit a message
|
||||||
def edit
|
def edit
|
||||||
(render_403; return false) unless @message.editable_by?(User.current)
|
(render_403; return false) unless @message.editable_by?(User.current)
|
||||||
if params[:message]
|
@message.safe_attributes = params[:message]
|
||||||
@message.locked = params[:message]['locked']
|
if request.post? && @message.save
|
||||||
@message.sticky = params[:message]['sticky']
|
|
||||||
end
|
|
||||||
if request.post? && @message.update_attributes(params[:message])
|
|
||||||
attachments = Attachment.attach_files(@message, params[:attachments])
|
attachments = Attachment.attach_files(@message, params[:attachments])
|
||||||
render_attachment_warning_if_needed(@message)
|
render_attachment_warning_if_needed(@message)
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
|
|||||||
@@ -67,8 +67,8 @@ class NewsController < ApplicationController
|
|||||||
|
|
||||||
def create
|
def create
|
||||||
@news = News.new(:project => @project, :author => User.current)
|
@news = News.new(:project => @project, :author => User.current)
|
||||||
|
@news.safe_attributes = params[:news]
|
||||||
if request.post?
|
if request.post?
|
||||||
@news.attributes = params[:news]
|
|
||||||
if @news.save
|
if @news.save
|
||||||
flash[:notice] = l(:notice_successful_create)
|
flash[:notice] = l(:notice_successful_create)
|
||||||
redirect_to :controller => 'news', :action => 'index', :project_id => @project
|
redirect_to :controller => 'news', :action => 'index', :project_id => @project
|
||||||
@@ -82,7 +82,8 @@ class NewsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if request.put? and @news.update_attributes(params[:news])
|
@news.safe_attributes = params[:news]
|
||||||
|
if request.put? and @news.save
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
redirect_to :action => 'show', :id => @news
|
redirect_to :action => 'show', :id => @news
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ class ProjectsController < ApplicationController
|
|||||||
def new
|
def new
|
||||||
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
@issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
|
||||||
@trackers = Tracker.all
|
@trackers = Tracker.all
|
||||||
@project = Project.new(params[:project])
|
@project = Project.new
|
||||||
|
@project.safe_attributes = params[:project]
|
||||||
end
|
end
|
||||||
|
|
||||||
verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
|
verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class TimelogController < ApplicationController
|
|||||||
|
|
||||||
def new
|
def new
|
||||||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
||||||
@time_entry.attributes = params[:time_entry]
|
@time_entry.safe_attributes = params[:time_entry]
|
||||||
|
|
||||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||||
render :action => 'edit'
|
render :action => 'edit'
|
||||||
@@ -114,7 +114,7 @@ class TimelogController < ApplicationController
|
|||||||
verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
|
verify :method => :post, :only => :create, :render => {:nothing => true, :status => :method_not_allowed }
|
||||||
def create
|
def create
|
||||||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
||||||
@time_entry.attributes = params[:time_entry]
|
@time_entry.safe_attributes = params[:time_entry]
|
||||||
|
|
||||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||||
|
|
||||||
@@ -135,14 +135,14 @@ class TimelogController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@time_entry.attributes = params[:time_entry]
|
@time_entry.safe_attributes = params[:time_entry]
|
||||||
|
|
||||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||||
end
|
end
|
||||||
|
|
||||||
verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
|
verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed }
|
||||||
def update
|
def update
|
||||||
@time_entry.attributes = params[:time_entry]
|
@time_entry.safe_attributes = params[:time_entry]
|
||||||
|
|
||||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ class TimelogController < ApplicationController
|
|||||||
unsaved_time_entry_ids = []
|
unsaved_time_entry_ids = []
|
||||||
@time_entries.each do |time_entry|
|
@time_entries.each do |time_entry|
|
||||||
time_entry.reload
|
time_entry.reload
|
||||||
time_entry.attributes = attributes
|
time_entry.safe_attributes = attributes
|
||||||
call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry })
|
call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry })
|
||||||
unless time_entry.save
|
unless time_entry.save
|
||||||
# Keep unsaved time_entry ids to display them in flash error
|
# Keep unsaved time_entry ids to display them in flash error
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class VersionsController < ApplicationController
|
|||||||
before_filter :find_project, :only => [:index, :new, :create, :close_completed]
|
before_filter :find_project, :only => [:index, :new, :create, :close_completed]
|
||||||
before_filter :authorize
|
before_filter :authorize
|
||||||
|
|
||||||
accept_api_auth :index, :create, :update, :destroy
|
accept_api_auth :index, :show, :create, :update, :destroy
|
||||||
|
|
||||||
helper :custom_fields
|
helper :custom_fields
|
||||||
helper :projects
|
helper :projects
|
||||||
@@ -75,7 +75,7 @@ class VersionsController < ApplicationController
|
|||||||
if params[:version]
|
if params[:version]
|
||||||
attributes = params[:version].dup
|
attributes = params[:version].dup
|
||||||
attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
|
attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
|
||||||
@version.attributes = attributes
|
@version.safe_attributes = attributes
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ class VersionsController < ApplicationController
|
|||||||
if params[:version]
|
if params[:version]
|
||||||
attributes = params[:version].dup
|
attributes = params[:version].dup
|
||||||
attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
|
attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
|
||||||
@version.attributes = attributes
|
@version.safe_attributes = attributes
|
||||||
end
|
end
|
||||||
|
|
||||||
if request.post?
|
if request.post?
|
||||||
@@ -124,7 +124,8 @@ class VersionsController < ApplicationController
|
|||||||
if request.put? && params[:version]
|
if request.put? && params[:version]
|
||||||
attributes = params[:version].dup
|
attributes = params[:version].dup
|
||||||
attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
|
attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
|
||||||
if @version.update_attributes(attributes)
|
@version.safe_attributes = attributes
|
||||||
|
if @version.save
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {
|
format.html {
|
||||||
flash[:notice] = l(:notice_successful_update)
|
flash[:notice] = l(:notice_successful_update)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class WikisController < ApplicationController
|
|||||||
# Create or update a project's wiki
|
# Create or update a project's wiki
|
||||||
def edit
|
def edit
|
||||||
@wiki = @project.wiki || Wiki.new(:project => @project)
|
@wiki = @project.wiki || Wiki.new(:project => @project)
|
||||||
@wiki.attributes = params[:wiki]
|
@wiki.safe_attributes = params[:wiki]
|
||||||
@wiki.save if request.post?
|
@wiki.save if request.post?
|
||||||
render(:update) {|page| page.replace_html "tab-content-wiki", :partial => 'projects/settings/wiki'}
|
render(:update) {|page| page.replace_html "tab-content-wiki", :partial => 'projects/settings/wiki'}
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -490,12 +490,16 @@ module ApplicationHelper
|
|||||||
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr)
|
text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr)
|
||||||
|
|
||||||
@parsed_headings = []
|
@parsed_headings = []
|
||||||
|
@heading_anchors = {}
|
||||||
@current_section = 0 if options[:edit_section_links]
|
@current_section = 0 if options[:edit_section_links]
|
||||||
|
|
||||||
|
parse_sections(text, project, obj, attr, only_path, options)
|
||||||
text = parse_non_pre_blocks(text) do |text|
|
text = parse_non_pre_blocks(text) do |text|
|
||||||
[:parse_sections, :parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_macros, :parse_headings].each do |method_name|
|
[:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_macros].each do |method_name|
|
||||||
send method_name, text, project, obj, attr, only_path, options
|
send method_name, text, project, obj, attr, only_path, options
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
parse_headings(text, project, obj, attr, only_path, options)
|
||||||
|
|
||||||
if @parsed_headings.any?
|
if @parsed_headings.any?
|
||||||
replace_toc(text, @parsed_headings)
|
replace_toc(text, @parsed_headings)
|
||||||
@@ -778,6 +782,11 @@ module ApplicationHelper
|
|||||||
anchor = sanitize_anchor_name(item)
|
anchor = sanitize_anchor_name(item)
|
||||||
# used for single-file wiki export
|
# used for single-file wiki export
|
||||||
anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version))
|
anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version))
|
||||||
|
@heading_anchors[anchor] ||= 0
|
||||||
|
idx = (@heading_anchors[anchor] += 1)
|
||||||
|
if idx > 1
|
||||||
|
anchor = "#{anchor}-#{idx}"
|
||||||
|
end
|
||||||
@parsed_headings << [level, anchor, item]
|
@parsed_headings << [level, anchor, item]
|
||||||
"<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">¶</a></h#{level}>"
|
"<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">¶</a></h#{level}>"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +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 Board < ActiveRecord::Base
|
class Board < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
|
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
|
||||||
has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
|
has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
|
||||||
@@ -30,6 +31,8 @@ class Board < ActiveRecord::Base
|
|||||||
named_scope :visible, lambda {|*args| { :include => :project,
|
named_scope :visible, lambda {|*args| { :include => :project,
|
||||||
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
|
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
|
||||||
|
|
||||||
|
safe_attributes 'name', 'description', 'move_to'
|
||||||
|
|
||||||
def visible?(user=User.current)
|
def visible?(user=User.current)
|
||||||
!user.nil? && user.allowed_to?(:view_messages, project)
|
!user.nil? && user.allowed_to?(:view_messages, project)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -151,12 +151,16 @@ class Changeset < ActiveRecord::Base
|
|||||||
@long_comments || split_comments.last
|
@long_comments || split_comments.last
|
||||||
end
|
end
|
||||||
|
|
||||||
def text_tag
|
def text_tag(ref_project=nil)
|
||||||
if scmid?
|
tag = if scmid?
|
||||||
"commit:#{scmid}"
|
"commit:#{scmid}"
|
||||||
else
|
else
|
||||||
"r#{revision}"
|
"r#{revision}"
|
||||||
end
|
end
|
||||||
|
if ref_project && project && ref_project != project
|
||||||
|
tag = "#{project.identifier}:#{tag}"
|
||||||
|
end
|
||||||
|
tag
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the previous changeset
|
# Returns the previous changeset
|
||||||
@@ -213,7 +217,7 @@ class Changeset < ActiveRecord::Base
|
|||||||
# don't change the status is the issue is closed
|
# don't change the status is the issue is closed
|
||||||
return if issue.status && issue.status.is_closed?
|
return if issue.status && issue.status.is_closed?
|
||||||
|
|
||||||
journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag))
|
journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project)))
|
||||||
issue.status = status
|
issue.status = status
|
||||||
unless Setting.commit_fix_done_ratio.blank?
|
unless Setting.commit_fix_done_ratio.blank?
|
||||||
issue.done_ratio = Setting.commit_fix_done_ratio.to_i
|
issue.done_ratio = Setting.commit_fix_done_ratio.to_i
|
||||||
@@ -232,7 +236,7 @@ class Changeset < ActiveRecord::Base
|
|||||||
:hours => hours,
|
:hours => hours,
|
||||||
:issue => issue,
|
:issue => issue,
|
||||||
:spent_on => commit_date,
|
:spent_on => commit_date,
|
||||||
:comments => l(:text_time_logged_by_changeset, :value => text_tag,
|
:comments => l(:text_time_logged_by_changeset, :value => text_tag(issue.project),
|
||||||
:locale => Setting.default_language)
|
:locale => Setting.default_language)
|
||||||
)
|
)
|
||||||
time_entry.activity = log_time_activity unless log_time_activity.nil?
|
time_entry.activity = log_time_activity unless log_time_activity.nil?
|
||||||
|
|||||||
@@ -16,8 +16,11 @@
|
|||||||
# 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 Comment < ActiveRecord::Base
|
class Comment < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
belongs_to :commented, :polymorphic => true, :counter_cache => true
|
belongs_to :commented, :polymorphic => true, :counter_cache => true
|
||||||
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||||
|
|
||||||
validates_presence_of :commented, :author, :comments
|
validates_presence_of :commented, :author, :comments
|
||||||
|
|
||||||
|
safe_attributes 'comments'
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +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 Document < ActiveRecord::Base
|
class Document < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
|
belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
|
||||||
acts_as_attachable :delete_permission => :manage_documents
|
acts_as_attachable :delete_permission => :manage_documents
|
||||||
@@ -32,6 +33,8 @@ class Document < ActiveRecord::Base
|
|||||||
named_scope :visible, lambda {|*args| { :include => :project,
|
named_scope :visible, lambda {|*args| { :include => :project,
|
||||||
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_documents, *args) } }
|
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_documents, *args) } }
|
||||||
|
|
||||||
|
safe_attributes 'category_id', 'title', 'description'
|
||||||
|
|
||||||
def visible?(user=User.current)
|
def visible?(user=User.current)
|
||||||
!user.nil? && user.allowed_to?(:view_documents, project)
|
!user.nil? && user.allowed_to?(:view_documents, project)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +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 IssueCategory < ActiveRecord::Base
|
class IssueCategory < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :assigned_to, :class_name => 'Principal', :foreign_key => 'assigned_to_id'
|
belongs_to :assigned_to, :class_name => 'Principal', :foreign_key => 'assigned_to_id'
|
||||||
has_many :issues, :foreign_key => 'category_id', :dependent => :nullify
|
has_many :issues, :foreign_key => 'category_id', :dependent => :nullify
|
||||||
@@ -24,7 +25,7 @@ class IssueCategory < ActiveRecord::Base
|
|||||||
validates_uniqueness_of :name, :scope => [:project_id]
|
validates_uniqueness_of :name, :scope => [:project_id]
|
||||||
validates_length_of :name, :maximum => 30
|
validates_length_of :name, :maximum => 30
|
||||||
|
|
||||||
attr_protected :project_id
|
safe_attributes 'name', 'assigned_to_id'
|
||||||
|
|
||||||
named_scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}}
|
named_scope :named, lambda {|arg| { :conditions => ["LOWER(#{table_name}.name) = LOWER(?)", arg.to_s.strip]}}
|
||||||
|
|
||||||
|
|||||||
@@ -354,7 +354,7 @@ class Mailer < ActionMailer::Base
|
|||||||
:conditions => s.conditions
|
:conditions => s.conditions
|
||||||
).group_by(&:assigned_to)
|
).group_by(&:assigned_to)
|
||||||
issues_by_assignee.each do |assignee, issues|
|
issues_by_assignee.each do |assignee, issues|
|
||||||
deliver_reminder(assignee, issues, days) if assignee && assignee.active?
|
deliver_reminder(assignee, issues, days) if assignee.is_a?(User) && assignee.active?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+11
-1
@@ -50,7 +50,17 @@ class Member < ActiveRecord::Base
|
|||||||
|
|
||||||
def <=>(member)
|
def <=>(member)
|
||||||
a, b = roles.sort.first, member.roles.sort.first
|
a, b = roles.sort.first, member.roles.sort.first
|
||||||
a == b ? (principal <=> member.principal) : (a <=> b)
|
if a == b
|
||||||
|
if principal
|
||||||
|
principal <=> member.principal
|
||||||
|
else
|
||||||
|
1
|
||||||
|
end
|
||||||
|
elsif a
|
||||||
|
a <=> b
|
||||||
|
else
|
||||||
|
1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def deletable?
|
def deletable?
|
||||||
|
|||||||
@@ -16,6 +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 Message < ActiveRecord::Base
|
class Message < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
belongs_to :board
|
belongs_to :board
|
||||||
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||||
acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
|
acts_as_tree :counter_cache => :replies_count, :order => "#{Message.table_name}.created_on ASC"
|
||||||
@@ -36,7 +37,6 @@ class Message < ActiveRecord::Base
|
|||||||
:author_key => :author_id
|
:author_key => :author_id
|
||||||
acts_as_watchable
|
acts_as_watchable
|
||||||
|
|
||||||
attr_protected :locked, :sticky
|
|
||||||
validates_presence_of :board, :subject, :content
|
validates_presence_of :board, :subject, :content
|
||||||
validates_length_of :subject, :maximum => 255
|
validates_length_of :subject, :maximum => 255
|
||||||
validate :cannot_reply_to_locked_topic, :on => :create
|
validate :cannot_reply_to_locked_topic, :on => :create
|
||||||
@@ -48,6 +48,12 @@ class Message < ActiveRecord::Base
|
|||||||
named_scope :visible, lambda {|*args| { :include => {:board => :project},
|
named_scope :visible, lambda {|*args| { :include => {:board => :project},
|
||||||
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
|
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_messages, *args) } }
|
||||||
|
|
||||||
|
safe_attributes 'subject', 'content'
|
||||||
|
safe_attributes 'locked', 'sticky', 'board_id',
|
||||||
|
:if => lambda {|message, user|
|
||||||
|
user.allowed_to?(:edit_messages, message.project)
|
||||||
|
}
|
||||||
|
|
||||||
def visible?(user=User.current)
|
def visible?(user=User.current)
|
||||||
!user.nil? && user.allowed_to?(:view_messages, project)
|
!user.nil? && user.allowed_to?(:view_messages, project)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +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 News < ActiveRecord::Base
|
class News < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||||
has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
|
has_many :comments, :as => :commented, :dependent => :delete_all, :order => "created_on"
|
||||||
@@ -37,6 +38,8 @@ class News < ActiveRecord::Base
|
|||||||
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_news, *args)
|
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_news, *args)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
safe_attributes 'title', 'summary', 'description'
|
||||||
|
|
||||||
def visible?(user=User.current)
|
def visible?(user=User.current)
|
||||||
!user.nil? && user.allowed_to?(:view_news, project)
|
!user.nil? && user.allowed_to?(:view_news, project)
|
||||||
end
|
end
|
||||||
|
|||||||
+13
-1
@@ -32,6 +32,16 @@ class Principal < ActiveRecord::Base
|
|||||||
:order => 'type, login, lastname, firstname, mail'
|
:order => 'type, login, lastname, firstname, mail'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# Principals that are not members of projects
|
||||||
|
named_scope :not_member_of, lambda {|projects|
|
||||||
|
projects = [projects] unless projects.is_a?(Array)
|
||||||
|
if projects.empty?
|
||||||
|
{:conditions => "1=0"}
|
||||||
|
else
|
||||||
|
ids = projects.map(&:id)
|
||||||
|
{:conditions => ["#{Principal.table_name}.id NOT IN (SELECT DISTINCT user_id FROM #{Member.table_name} WHERE project_id IN (?))", ids]}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
before_create :set_default_empty_values
|
before_create :set_default_empty_values
|
||||||
|
|
||||||
@@ -40,7 +50,9 @@ class Principal < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def <=>(principal)
|
def <=>(principal)
|
||||||
if self.class.name == principal.class.name
|
if principal.nil?
|
||||||
|
-1
|
||||||
|
elsif self.class.name == principal.class.name
|
||||||
self.to_s.downcase <=> principal.to_s.downcase
|
self.to_s.downcase <=> principal.to_s.downcase
|
||||||
else
|
else
|
||||||
# groups after users
|
# groups after users
|
||||||
|
|||||||
+10
-5
@@ -253,7 +253,7 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
# id is used for projects with a numeric identifier (compatibility)
|
# id is used for projects with a numeric identifier (compatibility)
|
||||||
@to_param ||= (identifier.to_s =~ %r{^\d*$} ? id : identifier)
|
@to_param ||= (identifier.to_s =~ %r{^\d*$} ? id.to_s : identifier)
|
||||||
end
|
end
|
||||||
|
|
||||||
def active?
|
def active?
|
||||||
@@ -390,16 +390,21 @@ class Project < ActiveRecord::Base
|
|||||||
|
|
||||||
# Returns a scope of the Versions used by the project
|
# Returns a scope of the Versions used by the project
|
||||||
def shared_versions
|
def shared_versions
|
||||||
@shared_versions ||= begin
|
if new_record?
|
||||||
r = root? ? self : root
|
|
||||||
Version.scoped(:include => :project,
|
Version.scoped(:include => :project,
|
||||||
:conditions => "#{Project.table_name}.id = #{id}" +
|
:conditions => "#{Project.table_name}.status = #{Project::STATUS_ACTIVE} AND #{Version.table_name}.sharing = 'system'")
|
||||||
" OR (#{Project.table_name}.status = #{Project::STATUS_ACTIVE} AND (" +
|
else
|
||||||
|
@shared_versions ||= begin
|
||||||
|
r = root? ? self : root
|
||||||
|
Version.scoped(:include => :project,
|
||||||
|
:conditions => "#{Project.table_name}.id = #{id}" +
|
||||||
|
" OR (#{Project.table_name}.status = #{Project::STATUS_ACTIVE} AND (" +
|
||||||
" #{Version.table_name}.sharing = 'system'" +
|
" #{Version.table_name}.sharing = 'system'" +
|
||||||
" OR (#{Project.table_name}.lft >= #{r.lft} AND #{Project.table_name}.rgt <= #{r.rgt} AND #{Version.table_name}.sharing = 'tree')" +
|
" OR (#{Project.table_name}.lft >= #{r.lft} AND #{Project.table_name}.rgt <= #{r.rgt} AND #{Version.table_name}.sharing = 'tree')" +
|
||||||
" OR (#{Project.table_name}.lft < #{lft} AND #{Project.table_name}.rgt > #{rgt} AND #{Version.table_name}.sharing IN ('hierarchy', 'descendants'))" +
|
" OR (#{Project.table_name}.lft < #{lft} AND #{Project.table_name}.rgt > #{rgt} AND #{Version.table_name}.sharing IN ('hierarchy', 'descendants'))" +
|
||||||
" OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt} AND #{Version.table_name}.sharing = 'hierarchy')" +
|
" OR (#{Project.table_name}.lft > #{lft} AND #{Project.table_name}.rgt < #{rgt} AND #{Version.table_name}.sharing = 'hierarchy')" +
|
||||||
"))")
|
"))")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,10 @@ private
|
|||||||
name = name.to_s
|
name = name.to_s
|
||||||
raise "There's no setting named #{name}" unless @@available_settings.has_key?(name)
|
raise "There's no setting named #{name}" unless @@available_settings.has_key?(name)
|
||||||
setting = find_by_name(name)
|
setting = find_by_name(name)
|
||||||
setting ||= new(:name => name, :value => @@available_settings[name]['default']) if @@available_settings.has_key? name
|
unless setting
|
||||||
|
setting = new(:name => name)
|
||||||
|
setting.value = @@available_settings[name]['default']
|
||||||
|
end
|
||||||
|
setting
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +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 TimeEntry < ActiveRecord::Base
|
class TimeEntry < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
# could have used polymorphic association
|
# could have used polymorphic association
|
||||||
# project association here allows easy loading of time entries at project level with one database trip
|
# project association here allows easy loading of time entries at project level with one database trip
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
@@ -46,6 +47,8 @@ class TimeEntry < ActiveRecord::Base
|
|||||||
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args)
|
:conditions => Project.allowed_to_condition(args.shift || User.current, :view_time_entries, *args)
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
safe_attributes 'hours', 'comments', 'issue_id', 'activity_id', 'spent_on', 'custom_field_values'
|
||||||
|
|
||||||
def after_initialize
|
def after_initialize
|
||||||
if new_record? && self.activity.nil?
|
if new_record? && self.activity.nil?
|
||||||
if default_activity = TimeEntryActivity.default
|
if default_activity = TimeEntryActivity.default
|
||||||
|
|||||||
@@ -343,6 +343,11 @@ class User < Principal
|
|||||||
find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
|
find(:first, :conditions => ["LOWER(mail) = ?", mail.to_s.downcase])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns true if the default admin account can no longer be used
|
||||||
|
def self.default_admin_account_changed?
|
||||||
|
!User.active.find_by_login("admin").try(:check_password?, "admin")
|
||||||
|
end
|
||||||
|
|
||||||
def to_s
|
def to_s
|
||||||
name
|
name
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class UserPreference < ActiveRecord::Base
|
|||||||
belongs_to :user
|
belongs_to :user
|
||||||
serialize :others
|
serialize :others
|
||||||
|
|
||||||
attr_protected :others
|
attr_protected :others, :user_id
|
||||||
|
|
||||||
def initialize(attributes = nil)
|
def initialize(attributes = nil)
|
||||||
super
|
super
|
||||||
|
|||||||
@@ -16,6 +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 Version < ActiveRecord::Base
|
class Version < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
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', :dependent => :nullify
|
||||||
@@ -38,6 +39,15 @@ class Version < ActiveRecord::Base
|
|||||||
named_scope :visible, lambda {|*args| { :include => :project,
|
named_scope :visible, lambda {|*args| { :include => :project,
|
||||||
:conditions => Project.allowed_to_condition(args.first || User.current, :view_issues) } }
|
:conditions => Project.allowed_to_condition(args.first || User.current, :view_issues) } }
|
||||||
|
|
||||||
|
safe_attributes 'name',
|
||||||
|
'description',
|
||||||
|
'effective_date',
|
||||||
|
'due_date',
|
||||||
|
'wiki_page_title',
|
||||||
|
'status',
|
||||||
|
'sharing',
|
||||||
|
'custom_field_values'
|
||||||
|
|
||||||
# Returns true if +user+ or current user is allowed to view the version
|
# Returns true if +user+ or current user is allowed to view the version
|
||||||
def visible?(user=User.current)
|
def visible?(user=User.current)
|
||||||
user.allowed_to?(:view_issues, self.project)
|
user.allowed_to?(:view_issues, self.project)
|
||||||
|
|||||||
@@ -16,6 +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 Wiki < ActiveRecord::Base
|
class Wiki < ActiveRecord::Base
|
||||||
|
include Redmine::SafeAttributes
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
has_many :pages, :class_name => 'WikiPage', :dependent => :destroy, :order => 'title'
|
has_many :pages, :class_name => 'WikiPage', :dependent => :destroy, :order => 'title'
|
||||||
has_many :redirects, :class_name => 'WikiRedirect', :dependent => :delete_all
|
has_many :redirects, :class_name => 'WikiRedirect', :dependent => :delete_all
|
||||||
@@ -25,6 +26,8 @@ class Wiki < ActiveRecord::Base
|
|||||||
validates_presence_of :start_page
|
validates_presence_of :start_page
|
||||||
validates_format_of :start_page, :with => /^[^,\.\/\?\;\|\:]*$/
|
validates_format_of :start_page, :with => /^[^,\.\/\?\;\|\:]*$/
|
||||||
|
|
||||||
|
safe_attributes 'start_page'
|
||||||
|
|
||||||
def visible?(user=User.current)
|
def visible?(user=User.current)
|
||||||
!user.nil? && user.allowed_to?(:view_wiki_pages, project)
|
!user.nil? && user.allowed_to?(:view_wiki_pages, project)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
<td class="start_date"><%= format_date(relation.other_issue(@issue).start_date) %></td>
|
<td class="start_date"><%= format_date(relation.other_issue(@issue).start_date) %></td>
|
||||||
<td class="due_date"><%= format_date(relation.other_issue(@issue).due_date) %></td>
|
<td class="due_date"><%= format_date(relation.other_issue(@issue).due_date) %></td>
|
||||||
<td class="buttons"><%= link_to_remote(image_tag('link_break.png'), { :url => {:controller => 'issue_relations', :action => 'destroy', :id => relation},
|
<td class="buttons"><%= link_to_remote(image_tag('link_break.png'), { :url => {:controller => 'issue_relations', :action => 'destroy', :id => relation},
|
||||||
:method => :delete
|
:method => :delete,
|
||||||
|
:confirm => l(:text_are_you_sure)
|
||||||
}, :title => l(:label_relation_delete)) if authorize_for('issue_relations', 'destroy') %></td>
|
}, :title => l(:label_relation_delete)) if authorize_for('issue_relations', 'destroy') %></td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% principals = Principal.active.find(:all, :limit => 100, :order => 'type, login, lastname ASC') - @project.principals %>
|
<% principals = Principal.active.not_member_of(@project).all(:limit => 100, :order => 'type, login, lastname ASC') %>
|
||||||
|
|
||||||
<div class="splitcontentright">
|
<div class="splitcontentright">
|
||||||
<% if roles.any? && principals.any? %>
|
<% if roles.any? && principals.any? %>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<%= label_tag('repository_scm', l(:label_scm)) %><%= scm_select_tag(@repository) %>
|
<%= label_tag('repository_scm', l(:label_scm)) %><%= scm_select_tag(@repository) %>
|
||||||
<% if @repository && ! @repository.class.scm_available %>
|
<% if @repository && ! @repository.class.scm_available %>
|
||||||
<br />
|
<br />
|
||||||
<em><%= content_tag 'span', l(:text_scm_command_not_available), :class => 'error' %></em>
|
<em class="info error"><%= content_tag 'span', l(:text_scm_command_not_available) %></em>
|
||||||
<% end %>
|
<% end %>
|
||||||
</p>
|
</p>
|
||||||
<% button_disabled = true %>
|
<% button_disabled = true %>
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ bg:
|
|||||||
setting_time_format: Формат на часа
|
setting_time_format: Формат на часа
|
||||||
setting_cross_project_issue_relations: Релации на задачи между проекти
|
setting_cross_project_issue_relations: Релации на задачи между проекти
|
||||||
setting_issue_list_default_columns: Показвани колони по подразбиране
|
setting_issue_list_default_columns: Показвани колони по подразбиране
|
||||||
setting_repositories_encodings: Attachments and repositories encodings
|
setting_repositories_encodings: Кодова таблица на прикачените файлове и хранилищата
|
||||||
setting_emails_header: Emails header
|
setting_emails_header: Emails header
|
||||||
setting_emails_footer: Подтекст за e-mail
|
setting_emails_footer: Подтекст за e-mail
|
||||||
setting_protocol: Протокол
|
setting_protocol: Протокол
|
||||||
@@ -370,7 +370,7 @@ bg:
|
|||||||
setting_issue_done_ratio_issue_status: Използване на състоянието на задачите
|
setting_issue_done_ratio_issue_status: Използване на състоянието на задачите
|
||||||
setting_start_of_week: Първи ден на седмицата
|
setting_start_of_week: Първи ден на седмицата
|
||||||
setting_rest_api_enabled: Разрешаване на REST web сървис
|
setting_rest_api_enabled: Разрешаване на REST web сървис
|
||||||
setting_cache_formatted_text: Кещиране на форматираните текстове
|
setting_cache_formatted_text: Кеширане на форматираните текстове
|
||||||
setting_default_notification_option: Подразбиращ се начин за известяване
|
setting_default_notification_option: Подразбиращ се начин за известяване
|
||||||
setting_commit_logtime_enabled: Разрешаване на отчитането на работното време
|
setting_commit_logtime_enabled: Разрешаване на отчитането на работното време
|
||||||
setting_commit_logtime_activity_id: Дейност при отчитане на работното време
|
setting_commit_logtime_activity_id: Дейност при отчитане на работното време
|
||||||
|
|||||||
+27
-27
@@ -979,31 +979,31 @@ it:
|
|||||||
label_between: tra
|
label_between: tra
|
||||||
setting_issue_group_assignment: Permetti di assegnare una segnalazione a gruppi
|
setting_issue_group_assignment: Permetti di assegnare una segnalazione a gruppi
|
||||||
label_diff: diff
|
label_diff: diff
|
||||||
text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
|
text_git_repository_note: Il repository è spoglio e locale (e.g. /gitrepo, c:\gitrepo)
|
||||||
description_query_sort_criteria_direction: Sort direction
|
description_query_sort_criteria_direction: Ordinamento
|
||||||
description_project_scope: Search scope
|
description_project_scope: Search scope
|
||||||
description_filter: Filter
|
description_filter: Filtro
|
||||||
description_user_mail_notification: Mail notification settings
|
description_user_mail_notification: Impostazioni notifica via mail
|
||||||
description_date_from: Enter start date
|
description_date_from: Inserisci la data d'inizio
|
||||||
description_message_content: Message content
|
description_message_content: Contenuto del messaggio
|
||||||
description_available_columns: Available Columns
|
description_available_columns: Colonne disponibili
|
||||||
description_date_range_interval: Choose range by selecting start and end date
|
description_date_range_interval: Scegli l'intervallo selezionando la data di inizio e di fine
|
||||||
description_issue_category_reassign: Choose issue category
|
description_issue_category_reassign: Scegli la categoria della segnalazione
|
||||||
description_search: Searchfield
|
description_search: Campo di ricerca
|
||||||
description_notes: Notes
|
description_notes: Note
|
||||||
description_date_range_list: Choose range from list
|
description_date_range_list: Scegli l'intervallo dalla lista
|
||||||
description_choose_project: Projects
|
description_choose_project: Progetti
|
||||||
description_date_to: Enter end date
|
description_date_to: Inserisci la data di fine
|
||||||
description_query_sort_criteria_attribute: Sort attribute
|
description_query_sort_criteria_attribute: Attributo di ordinamento
|
||||||
description_wiki_subpages_reassign: Choose new parent page
|
description_wiki_subpages_reassign: Scegli la nuova pagina padre
|
||||||
description_selected_columns: Selected Columns
|
description_selected_columns: Colonne selezionate
|
||||||
label_parent_revision: Parent
|
label_parent_revision: Padre
|
||||||
label_child_revision: Child
|
label_child_revision: Figlio
|
||||||
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size.
|
error_scm_annotate_big_text_file: La nota non può essere salvata, supera la dimensiona massima del campo di testo.
|
||||||
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
|
setting_default_issue_start_date_to_creation_date: Usa la data corrente come data d'inizio per le nuove segnalazioni
|
||||||
button_edit_section: Edit this section
|
button_edit_section: Modifica questa sezione
|
||||||
setting_repositories_encodings: Attachments and repositories encodings
|
setting_repositories_encodings: Codifica degli allegati e dei repository
|
||||||
description_all_columns: All Columns
|
description_all_columns: Tutte le colonne
|
||||||
button_export: Export
|
button_export: Esporta
|
||||||
label_export_options: "%{export_format} export options"
|
label_export_options: "%{export_format} opzioni per l'export"
|
||||||
error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
|
error_attachment_too_big: Questo file non può essere caricato in quanto la sua dimensione supera la massima consentita (%{max_size})
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ nl:
|
|||||||
label_f_hour_plural: "%{value} uren"
|
label_f_hour_plural: "%{value} uren"
|
||||||
label_feed_plural: Feeds
|
label_feed_plural: Feeds
|
||||||
label_feeds_access_key_created_on: "RSS toegangssleutel %{value} geleden gemaakt."
|
label_feeds_access_key_created_on: "RSS toegangssleutel %{value} geleden gemaakt."
|
||||||
label_file_added: Bericht toegevoegd
|
label_file_added: Bestand toegevoegd
|
||||||
label_file_plural: Bestanden
|
label_file_plural: Bestanden
|
||||||
label_filter_add: Voeg filter toe
|
label_filter_add: Voeg filter toe
|
||||||
label_filter_plural: Filters
|
label_filter_plural: Filters
|
||||||
|
|||||||
@@ -1002,9 +1002,9 @@ zh:
|
|||||||
label_child_revision: 子修订
|
label_child_revision: 子修订
|
||||||
error_scm_annotate_big_text_file: 输入文本内容超长,无法输入。
|
error_scm_annotate_big_text_file: 输入文本内容超长,无法输入。
|
||||||
setting_default_issue_start_date_to_creation_date: 使用当前日期作为新问题的开始日期
|
setting_default_issue_start_date_to_creation_date: 使用当前日期作为新问题的开始日期
|
||||||
button_edit_section: Edit this section
|
button_edit_section: 编辑此区域
|
||||||
setting_repositories_encodings: Attachments and repositories encodings
|
setting_repositories_encodings: 附件和版本库编码
|
||||||
description_all_columns: All Columns
|
description_all_columns: 所有列
|
||||||
button_export: Export
|
button_export: 导出
|
||||||
label_export_options: "%{export_format} export options"
|
label_export_options: "%{export_format} 导出选项"
|
||||||
error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})
|
error_attachment_too_big: 该文件无法上传。超过文件大小限制 (%{max_size})
|
||||||
|
|||||||
@@ -4,6 +4,36 @@ Redmine - project management software
|
|||||||
Copyright (C) 2006-2012 Jean-Philippe Lang
|
Copyright (C) 2006-2012 Jean-Philippe Lang
|
||||||
http://www.redmine.org/
|
http://www.redmine.org/
|
||||||
|
|
||||||
|
== 2012-04-14 v1.3.3
|
||||||
|
|
||||||
|
* Defect #10505: Error when exporting to PDF with NoMethodError (undefined method `downcase' for nil:NilClass)
|
||||||
|
* Defect #10554: Defect symbols when exporting tasks in pdf
|
||||||
|
* Defect #10564: Unable to change locked, sticky flags and board when editing a message
|
||||||
|
* Defect #10591: Dutch "label_file_added" translation is wrong
|
||||||
|
* Defect #10622: "Default administrator account changed" is always true
|
||||||
|
* Patch #10555: rake redmine:send_reminders aborted if issue assigned to group
|
||||||
|
* Patch #10611: Simplified Chinese translations for 1.3-stable
|
||||||
|
|
||||||
|
== 2012-03-11 v1.3.2
|
||||||
|
|
||||||
|
* Defect #8194: {{toc}} uses identical anchors for subsections with the same name
|
||||||
|
* Defect #9143: Partial diff comparison should be done on actual code, not on html
|
||||||
|
* Defect #9523: {{toc}} does not display headers with @ code markup
|
||||||
|
* Defect #9815: Release 1.3.0 does not detect rubytree with rubgems 1.8
|
||||||
|
* Defect #10053: undefined method `<=>' for nil:NilClass when accessing the settings of a project
|
||||||
|
* Defect #10135: ActionView::TemplateError (can't convert Fixnum into String)
|
||||||
|
* Defect #10193: Unappropriate icons in highlighted code block
|
||||||
|
* Defect #10199: No wiki section edit when title contains code
|
||||||
|
* Defect #10218: Error when creating a project with a version custom field
|
||||||
|
* Defect #10241: "get version by ID" fails with "401 not authorized" error when using API access key
|
||||||
|
* Defect #10284: Note added by commit from a subproject does not contain project identifier
|
||||||
|
* Defect #10374: User list is empty when adding users to project / group if remaining users are added late
|
||||||
|
* Defect #10390: Mass assignment security vulnerability
|
||||||
|
* Patch #8413: Confirmation message before deleting a relationship
|
||||||
|
* Patch #10160: Bulgarian translation (r8777)
|
||||||
|
* Patch #10242: Migrate Redmine.pm from Digest::Sha1 to Digest::Sha
|
||||||
|
* Patch #10258: Italian translation for 1.3-stable
|
||||||
|
|
||||||
== 2012-02-06 v1.3.1
|
== 2012-02-06 v1.3.1
|
||||||
|
|
||||||
* Defect #9775: app/views/repository/_revision_graph.html.erb sets window.onload directly..
|
* Defect #9775: app/views/repository/_revision_graph.html.erb sets window.onload directly..
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ use strict;
|
|||||||
use warnings FATAL => 'all', NONFATAL => 'redefine';
|
use warnings FATAL => 'all', NONFATAL => 'redefine';
|
||||||
|
|
||||||
use DBI;
|
use DBI;
|
||||||
use Digest::SHA1;
|
use Digest::SHA;
|
||||||
# optional module for LDAP authentication
|
# optional module for LDAP authentication
|
||||||
my $CanUseLDAPAuth = eval("use Authen::Simple::LDAP; 1");
|
my $CanUseLDAPAuth = eval("use Authen::Simple::LDAP; 1");
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ sub is_member {
|
|||||||
my $dbh = connect_database($r);
|
my $dbh = connect_database($r);
|
||||||
my $project_id = get_project_identifier($r);
|
my $project_id = get_project_identifier($r);
|
||||||
|
|
||||||
my $pass_digest = Digest::SHA1::sha1_hex($redmine_pass);
|
my $pass_digest = Digest::SHA::sha1_hex($redmine_pass);
|
||||||
|
|
||||||
my $access_mode = defined $read_only_methods{$r->method} ? "R" : "W";
|
my $access_mode = defined $read_only_methods{$r->method} ? "R" : "W";
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ sub is_member {
|
|||||||
|
|
||||||
unless ($auth_source_id) {
|
unless ($auth_source_id) {
|
||||||
my $method = $r->method;
|
my $method = $r->method;
|
||||||
my $salted_password = Digest::SHA1::sha1_hex($salt.$pass_digest);
|
my $salted_password = Digest::SHA::sha1_hex($salt.$pass_digest);
|
||||||
if ($hashed_password eq $salted_password && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) {
|
if ($hashed_password eq $salted_password && (($access_mode eq "R" && $permissions =~ /:browse_repository/) || $permissions =~ /:commit_access/) ) {
|
||||||
$ret = 1;
|
$ret = 1;
|
||||||
last;
|
last;
|
||||||
|
|||||||
+3
-3
@@ -340,9 +340,9 @@ class RedCloth3 < String
|
|||||||
#
|
#
|
||||||
A_HLGN = /(?:(?:<>|<|>|\=|[()]+)+)/
|
A_HLGN = /(?:(?:<>|<|>|\=|[()]+)+)/
|
||||||
A_VLGN = /[\-^~]/
|
A_VLGN = /[\-^~]/
|
||||||
C_CLAS = '(?:\([^)]+\))'
|
C_CLAS = '(?:\([^")]+\))'
|
||||||
C_LNGE = '(?:\[[^\[\]]+\])'
|
C_LNGE = '(?:\[[^"\[\]]+\])'
|
||||||
C_STYL = '(?:\{[^}]+\})'
|
C_STYL = '(?:\{[^"}]+\})'
|
||||||
S_CSPN = '(?:\\\\\d+)'
|
S_CSPN = '(?:\\\\\d+)'
|
||||||
S_RSPN = '(?:/\d+)'
|
S_RSPN = '(?:/\d+)'
|
||||||
A = "(?:#{A_HLGN}?#{A_VLGN}?|#{A_VLGN}?#{A_HLGN}?)"
|
A = "(?:#{A_HLGN}?#{A_VLGN}?|#{A_VLGN}?#{A_HLGN}?)"
|
||||||
|
|||||||
+25
-24
@@ -112,11 +112,6 @@ module Redmine
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Escape the HTML for the diff
|
|
||||||
def escapeHTML(line)
|
|
||||||
CGI.escapeHTML(line)
|
|
||||||
end
|
|
||||||
|
|
||||||
def diff_for_added_line
|
def diff_for_added_line
|
||||||
if @type == 'sbs' && @removed > 0 && @added < @removed
|
if @type == 'sbs' && @removed > 0 && @added < @removed
|
||||||
self[-(@removed - @added)]
|
self[-(@removed - @added)]
|
||||||
@@ -130,7 +125,7 @@ module Redmine
|
|||||||
def parse_line(line, type="inline")
|
def parse_line(line, type="inline")
|
||||||
if line[0, 1] == "+"
|
if line[0, 1] == "+"
|
||||||
diff = diff_for_added_line
|
diff = diff_for_added_line
|
||||||
diff.line_right = escapeHTML line[1..-1]
|
diff.line_right = line[1..-1]
|
||||||
diff.nb_line_right = @line_num_r
|
diff.nb_line_right = @line_num_r
|
||||||
diff.type_diff_right = 'diff_in'
|
diff.type_diff_right = 'diff_in'
|
||||||
@line_num_r += 1
|
@line_num_r += 1
|
||||||
@@ -138,7 +133,7 @@ module Redmine
|
|||||||
true
|
true
|
||||||
elsif line[0, 1] == "-"
|
elsif line[0, 1] == "-"
|
||||||
diff = Diff.new
|
diff = Diff.new
|
||||||
diff.line_left = escapeHTML line[1..-1]
|
diff.line_left = line[1..-1]
|
||||||
diff.nb_line_left = @line_num_l
|
diff.nb_line_left = @line_num_l
|
||||||
diff.type_diff_left = 'diff_out'
|
diff.type_diff_left = 'diff_out'
|
||||||
self << diff
|
self << diff
|
||||||
@@ -149,9 +144,9 @@ module Redmine
|
|||||||
write_offsets
|
write_offsets
|
||||||
if line[0, 1] =~ /\s/
|
if line[0, 1] =~ /\s/
|
||||||
diff = Diff.new
|
diff = Diff.new
|
||||||
diff.line_right = escapeHTML line[1..-1]
|
diff.line_right = line[1..-1]
|
||||||
diff.nb_line_right = @line_num_r
|
diff.nb_line_right = @line_num_r
|
||||||
diff.line_left = escapeHTML line[1..-1]
|
diff.line_left = line[1..-1]
|
||||||
diff.nb_line_left = @line_num_l
|
diff.nb_line_left = @line_num_l
|
||||||
self << diff
|
self << diff
|
||||||
@line_num_l += 1
|
@line_num_l += 1
|
||||||
@@ -224,27 +219,15 @@ module Redmine
|
|||||||
end
|
end
|
||||||
|
|
||||||
def html_line_left
|
def html_line_left
|
||||||
if offsets
|
line_to_html(line_left, offsets)
|
||||||
line_left.dup.insert(offsets.first, '<span>').insert(offsets.last, '</span>')
|
|
||||||
else
|
|
||||||
line_left
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def html_line_right
|
def html_line_right
|
||||||
if offsets
|
line_to_html(line_right, offsets)
|
||||||
line_right.dup.insert(offsets.first, '<span>').insert(offsets.last, '</span>')
|
|
||||||
else
|
|
||||||
line_right
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def html_line
|
def html_line
|
||||||
if offsets
|
line_to_html(line, offsets)
|
||||||
line.dup.insert(offsets.first, '<span>').insert(offsets.last, '</span>')
|
|
||||||
else
|
|
||||||
line
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
@@ -254,5 +237,23 @@ module Redmine
|
|||||||
puts self.nb_line_right
|
puts self.nb_line_right
|
||||||
puts self.line_right
|
puts self.line_right
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def line_to_html(line, offsets)
|
||||||
|
if offsets
|
||||||
|
s = ''
|
||||||
|
unless offsets.first == 0
|
||||||
|
s << CGI.escapeHTML(line[0..offsets.first-1])
|
||||||
|
end
|
||||||
|
s << '<span>' + CGI.escapeHTML(line[offsets.first..offsets.last]) + '</span>'
|
||||||
|
unless offsets.last == -1
|
||||||
|
s << CGI.escapeHTML(line[offsets.last+1..-1])
|
||||||
|
end
|
||||||
|
s
|
||||||
|
else
|
||||||
|
CGI.escapeHTML(line)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module Redmine
|
|||||||
module VERSION #:nodoc:
|
module VERSION #:nodoc:
|
||||||
MAJOR = 1
|
MAJOR = 1
|
||||||
MINOR = 3
|
MINOR = 3
|
||||||
TINY = 1
|
TINY = 3
|
||||||
|
|
||||||
# Branch values:
|
# Branch values:
|
||||||
# * official release: nil
|
# * official release: nil
|
||||||
|
|||||||
@@ -481,6 +481,9 @@ p.other-formats { text-align: right; font-size:0.9em; color: #666; }
|
|||||||
|
|
||||||
a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
|
a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px 3px 16px; }
|
||||||
|
|
||||||
|
em.info {font-style:normal;font-size:90%;color:#888;display:block;}
|
||||||
|
em.info.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;}
|
||||||
|
|
||||||
/* Project members tab */
|
/* Project members tab */
|
||||||
div#tab-content-members .splitcontentleft, div#tab-content-memberships .splitcontentleft, div#tab-content-users .splitcontentleft { width: 64% }
|
div#tab-content-members .splitcontentleft, div#tab-content-memberships .splitcontentleft, div#tab-content-users .splitcontentleft { width: 64% }
|
||||||
div#tab-content-members .splitcontentright, div#tab-content-memberships .splitcontentright, div#tab-content-users .splitcontentright { width: 34% }
|
div#tab-content-members .splitcontentright, div#tab-content-memberships .splitcontentright, div#tab-content-users .splitcontentright { width: 34% }
|
||||||
@@ -534,8 +537,6 @@ div.flash.warning {
|
|||||||
color: #A6750C;
|
color: #A6750C;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.error {padding-left:20px; background:url(../images/exclamation.png) no-repeat 0 50%;}
|
|
||||||
|
|
||||||
#errorExplanation ul { font-size: 0.9em;}
|
#errorExplanation ul { font-size: 0.9em;}
|
||||||
#errorExplanation h2, #errorExplanation p { display: none; }
|
#errorExplanation h2, #errorExplanation p { display: none; }
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,14 @@ class BoardsControllerTest < ActionController::TestCase
|
|||||||
assert_equal 'Testing', Board.find(2).name
|
assert_equal 'Testing', Board.find(2).name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_update_position
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
post :edit, :project_id => 1, :id => 2, :board => { :move_to => 'highest'}
|
||||||
|
assert_redirected_to '/projects/ecookbook/settings/boards'
|
||||||
|
board = Board.find(2)
|
||||||
|
assert_equal 1, board.position
|
||||||
|
end
|
||||||
|
|
||||||
def test_post_destroy
|
def test_post_destroy
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
assert_difference 'Board.count', -1 do
|
assert_difference 'Board.count', -1 do
|
||||||
|
|||||||
@@ -147,7 +147,6 @@ class IssuesControllerTest < ActionController::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_index_with_short_filters
|
def test_index_with_short_filters
|
||||||
|
|
||||||
to_test = {
|
to_test = {
|
||||||
'status_id' => {
|
'status_id' => {
|
||||||
'o' => { :op => 'o', :values => [''] },
|
'o' => { :op => 'o', :values => [''] },
|
||||||
@@ -181,9 +180,9 @@ class IssuesControllerTest < ActionController::TestCase
|
|||||||
't-2' => { :op => 't-', :values => ['2'] }},
|
't-2' => { :op => 't-', :values => ['2'] }},
|
||||||
'created_on' => {
|
'created_on' => {
|
||||||
'>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
|
'>=2011-10-12' => { :op => '>=', :values => ['2011-10-12'] },
|
||||||
'<t+2' => { :op => '=', :values => ['<t+2'] },
|
'<t-2' => { :op => '<t-', :values => ['2'] },
|
||||||
'>t+2' => { :op => '=', :values => ['>t+2'] },
|
'>t-2' => { :op => '>t-', :values => ['2'] },
|
||||||
't+2' => { :op => 't', :values => ['+2'] }},
|
't-2' => { :op => 't-', :values => ['2'] }},
|
||||||
'cf_1' => {
|
'cf_1' => {
|
||||||
'c' => { :op => '=', :values => ['c'] },
|
'c' => { :op => '=', :values => ['c'] },
|
||||||
'!c' => { :op => '!', :values => ['c'] },
|
'!c' => { :op => '!', :values => ['c'] },
|
||||||
@@ -215,7 +214,6 @@ class IssuesControllerTest < ActionController::TestCase
|
|||||||
assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
|
assert_equal(default_filter.merge({field => {:operator => expected[:op], :values => expected[:values]}}), query.filters)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_index_with_project_and_empty_filters
|
def test_index_with_project_and_empty_filters
|
||||||
@@ -933,7 +931,7 @@ class IssuesControllerTest < ActionController::TestCase
|
|||||||
def test_post_new_with_group_assignment
|
def test_post_new_with_group_assignment
|
||||||
group = Group.find(11)
|
group = Group.find(11)
|
||||||
project = Project.find(1)
|
project = Project.find(1)
|
||||||
project.members << Member.new(:principal => group, :roles => [Role.first])
|
project.members << Member.new(:principal => group, :roles => [Role.givable.first])
|
||||||
|
|
||||||
with_settings :issue_group_assignment => '1' do
|
with_settings :issue_group_assignment => '1' do
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
@@ -1803,7 +1801,7 @@ class IssuesControllerTest < ActionController::TestCase
|
|||||||
def test_bulk_update_with_group_assignee
|
def test_bulk_update_with_group_assignee
|
||||||
group = Group.find(11)
|
group = Group.find(11)
|
||||||
project = Project.find(1)
|
project = Project.find(1)
|
||||||
project.members << Member.new(:principal => group, :roles => [Role.first])
|
project.members << Member.new(:principal => group, :roles => [Role.givable.first])
|
||||||
|
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
# update issues assignee
|
# update issues assignee
|
||||||
|
|||||||
@@ -131,6 +131,30 @@ class MessagesControllerTest < ActionController::TestCase
|
|||||||
assert_equal 'New body', message.content
|
assert_equal 'New body', message.content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_post_edit_sticky_and_locked
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
post :edit, :board_id => 1, :id => 1,
|
||||||
|
:message => { :subject => 'New subject',
|
||||||
|
:content => 'New body',
|
||||||
|
:locked => '1',
|
||||||
|
:sticky => '1'}
|
||||||
|
assert_redirected_to '/boards/1/topics/1'
|
||||||
|
message = Message.find(1)
|
||||||
|
assert_equal true, message.sticky?
|
||||||
|
assert_equal true, message.locked?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_post_edit_should_allow_to_change_board
|
||||||
|
@request.session[:user_id] = 2
|
||||||
|
post :edit, :board_id => 1, :id => 1,
|
||||||
|
:message => { :subject => 'New subject',
|
||||||
|
:content => 'New body',
|
||||||
|
:board_id => 2}
|
||||||
|
assert_redirected_to '/boards/2/topics/1'
|
||||||
|
message = Message.find(1)
|
||||||
|
assert_equal Board.find(2), message.board
|
||||||
|
end
|
||||||
|
|
||||||
def test_reply
|
def test_reply
|
||||||
@request.session[:user_id] = 2
|
@request.session[:user_id] = 2
|
||||||
post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' }
|
post :reply, :board_id => 1, :id => 1, :reply => { :content => 'This is a test reply', :subject => 'Test reply' }
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class ProjectEnumerationsControllerTest < ActionController::TestCase
|
|||||||
:custom_fields_trackers, :custom_values,
|
:custom_fields_trackers, :custom_values,
|
||||||
:time_entries
|
:time_entries
|
||||||
|
|
||||||
|
self.use_transactional_fixtures = false
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@request.session[:user_id] = nil
|
@request.session[:user_id] = nil
|
||||||
Setting.default_language = 'en'
|
Setting.default_language = 'en'
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class TrackersControllerTest < ActionController::TestCase
|
|||||||
tracker = Tracker.first(:order => 'id DESC')
|
tracker = Tracker.first(:order => 'id DESC')
|
||||||
assert_equal 'New tracker', tracker.name
|
assert_equal 'New tracker', tracker.name
|
||||||
assert_equal [1], tracker.project_ids.sort
|
assert_equal [1], tracker.project_ids.sort
|
||||||
assert_equal [1, 6], tracker.custom_field_ids
|
assert_equal [1, 6], tracker.custom_field_ids.sort
|
||||||
assert_equal 0, tracker.workflows.count
|
assert_equal 0, tracker.workflows.count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,24 @@ class ChangesetTest < ActiveSupport::TestCase
|
|||||||
assert c.issues.first.project != c.project
|
assert c.issues.first.project != c.project
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_commit_closing_a_subproject_issue
|
||||||
|
with_settings :commit_fix_status_id => 5, :commit_fix_keywords => 'closes' do
|
||||||
|
issue = Issue.find(5)
|
||||||
|
assert !issue.closed?
|
||||||
|
assert_difference 'Journal.count' do
|
||||||
|
c = Changeset.new(:repository => Project.find(1).repository,
|
||||||
|
:committed_on => Time.now,
|
||||||
|
:comments => 'closes #5, a subproject issue',
|
||||||
|
:revision => '12345')
|
||||||
|
assert c.save
|
||||||
|
end
|
||||||
|
assert issue.reload.closed?
|
||||||
|
journal = Journal.first(:order => 'id DESC')
|
||||||
|
assert_equal issue, journal.issue
|
||||||
|
assert_include "Applied in changeset ecookbook:r12345.", journal.notes
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_commit_referencing_a_parent_project_issue
|
def test_commit_referencing_a_parent_project_issue
|
||||||
# repository of child project
|
# repository of child project
|
||||||
r = Repository::Subversion.create!(
|
r = Repository::Subversion.create!(
|
||||||
@@ -197,6 +215,16 @@ class ChangesetTest < ActiveSupport::TestCase
|
|||||||
assert_equal 'r520', c.text_tag
|
assert_equal 'r520', c.text_tag
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_text_tag_revision_with_same_project
|
||||||
|
c = Changeset.new(:revision => '520', :repository => Project.find(1).repository)
|
||||||
|
assert_equal 'r520', c.text_tag(Project.find(1))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_text_tag_revision_with_different_project
|
||||||
|
c = Changeset.new(:revision => '520', :repository => Project.find(1).repository)
|
||||||
|
assert_equal 'ecookbook:r520', c.text_tag(Project.find(2))
|
||||||
|
end
|
||||||
|
|
||||||
def test_text_tag_hash
|
def test_text_tag_hash
|
||||||
c = Changeset.new(
|
c = Changeset.new(
|
||||||
:scmid => '7234cb2750b63f47bff735edc50a1c0a433c2518',
|
:scmid => '7234cb2750b63f47bff735edc50a1c0a433c2518',
|
||||||
@@ -204,6 +232,16 @@ class ChangesetTest < ActiveSupport::TestCase
|
|||||||
assert_equal 'commit:7234cb2750b63f47bff735edc50a1c0a433c2518', c.text_tag
|
assert_equal 'commit:7234cb2750b63f47bff735edc50a1c0a433c2518', c.text_tag
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_text_tag_hash_with_same_project
|
||||||
|
c = Changeset.new(:revision => '7234cb27', :scmid => '7234cb27', :repository => Project.find(1).repository)
|
||||||
|
assert_equal 'commit:7234cb27', c.text_tag(Project.find(1))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_text_tag_hash_with_different_project
|
||||||
|
c = Changeset.new(:revision => '7234cb27', :scmid => '7234cb27', :repository => Project.find(1).repository)
|
||||||
|
assert_equal 'ecookbook:commit:7234cb27', c.text_tag(Project.find(2))
|
||||||
|
end
|
||||||
|
|
||||||
def test_text_tag_hash_all_number
|
def test_text_tag_hash_all_number
|
||||||
c = Changeset.new(:scmid => '0123456789', :revision => '0123456789')
|
c = Changeset.new(:scmid => '0123456789', :revision => '0123456789')
|
||||||
assert_equal 'commit:0123456789', c.text_tag
|
assert_equal 'commit:0123456789', c.text_tag
|
||||||
|
|||||||
@@ -732,6 +732,8 @@ some code
|
|||||||
|
|
||||||
h3. Subtitle with *some* _modifiers_
|
h3. Subtitle with *some* _modifiers_
|
||||||
|
|
||||||
|
h3. Subtitle with @inline code@
|
||||||
|
|
||||||
h1. Another title
|
h1. Another title
|
||||||
|
|
||||||
h3. An "Internet link":http://www.redmine.org/ inside subtitle
|
h3. An "Internet link":http://www.redmine.org/ inside subtitle
|
||||||
@@ -748,6 +750,7 @@ RAW
|
|||||||
'<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
|
'<li><a href="#Subtitle-with-red-text">Subtitle with red text</a>' +
|
||||||
'<ul>' +
|
'<ul>' +
|
||||||
'<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
|
'<li><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
|
||||||
|
'<li><a href="#Subtitle-with-inline-code">Subtitle with inline code</a></li>' +
|
||||||
'</ul>' +
|
'</ul>' +
|
||||||
'</li>' +
|
'</li>' +
|
||||||
'</ul>' +
|
'</ul>' +
|
||||||
@@ -768,6 +771,33 @@ RAW
|
|||||||
assert textilizable(raw).gsub("\n", "").include?(expected)
|
assert textilizable(raw).gsub("\n", "").include?(expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_table_of_content_should_generate_unique_anchors
|
||||||
|
raw = <<-RAW
|
||||||
|
{{toc}}
|
||||||
|
|
||||||
|
h1. Title
|
||||||
|
|
||||||
|
h2. Subtitle
|
||||||
|
|
||||||
|
h2. Subtitle
|
||||||
|
RAW
|
||||||
|
|
||||||
|
expected = '<ul class="toc">' +
|
||||||
|
'<li><a href="#Title">Title</a>' +
|
||||||
|
'<ul>' +
|
||||||
|
'<li><a href="#Subtitle">Subtitle</a></li>' +
|
||||||
|
'<li><a href="#Subtitle-2">Subtitle</a></li>'
|
||||||
|
'</ul>'
|
||||||
|
'</li>' +
|
||||||
|
'</ul>'
|
||||||
|
|
||||||
|
@project = Project.find(1)
|
||||||
|
result = textilizable(raw).gsub("\n", "")
|
||||||
|
assert_include expected, result
|
||||||
|
assert_include '<a name="Subtitle">', result
|
||||||
|
assert_include '<a name="Subtitle-2">', result
|
||||||
|
end
|
||||||
|
|
||||||
def test_table_of_content_should_contain_included_page_headings
|
def test_table_of_content_should_contain_included_page_headings
|
||||||
raw = <<-RAW
|
raw = <<-RAW
|
||||||
{{toc}}
|
{{toc}}
|
||||||
@@ -786,6 +816,48 @@ RAW
|
|||||||
assert textilizable(raw).gsub("\n", "").include?(expected)
|
assert textilizable(raw).gsub("\n", "").include?(expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_section_edit_links
|
||||||
|
raw = <<-RAW
|
||||||
|
h1. Title
|
||||||
|
|
||||||
|
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||||
|
|
||||||
|
h2. Subtitle with a [[Wiki]] link
|
||||||
|
|
||||||
|
h2. Subtitle with *some* _modifiers_
|
||||||
|
|
||||||
|
h2. Subtitle with @inline code@
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
some code
|
||||||
|
|
||||||
|
h2. heading inside pre
|
||||||
|
|
||||||
|
<h2>html heading inside pre</h2>
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
h2. Subtitle after pre tag
|
||||||
|
RAW
|
||||||
|
|
||||||
|
@project = Project.find(1)
|
||||||
|
set_language_if_valid 'en'
|
||||||
|
result = textilizable(raw, :edit_section_links => {:controller => 'wiki', :action => 'edit', :project_id => '1', :id => 'Test'}).gsub("\n", "")
|
||||||
|
|
||||||
|
# heading that contains inline code
|
||||||
|
assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
|
||||||
|
'<a href="/projects/1/wiki/Test/edit\?section=4"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
|
||||||
|
'<a name="Subtitle-with-inline-code"></a>' +
|
||||||
|
'<h2 >Subtitle with <code>inline code</code><a href="#Subtitle-with-inline-code" class="wiki-anchor">¶</a></h2>'),
|
||||||
|
result
|
||||||
|
|
||||||
|
# last heading
|
||||||
|
assert_match Regexp.new('<div class="contextual" title="Edit this section">' +
|
||||||
|
'<a href="/projects/1/wiki/Test/edit\?section=5"><img alt="Edit" src="/images/edit.png(\?\d+)?" /></a></div>' +
|
||||||
|
'<a name="Subtitle-after-pre-tag"></a>' +
|
||||||
|
'<h2 >Subtitle after pre tag<a href="#Subtitle-after-pre-tag" class="wiki-anchor">¶</a></h2>'),
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
def test_default_formatter
|
def test_default_formatter
|
||||||
Setting.text_formatting = 'unknown'
|
Setting.text_formatting = 'unknown'
|
||||||
text = 'a *link*: http://www.example.net/'
|
text = 'a *link*: http://www.example.net/'
|
||||||
@@ -853,6 +925,14 @@ RAW
|
|||||||
link_to_project(project, {:action => 'settings'}, :class => "project")
|
link_to_project(project, {:action => 'settings'}, :class => "project")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_link_to_legacy_project_with_numerical_identifier_should_use_id
|
||||||
|
# numeric identifier are no longer allowed
|
||||||
|
Project.update_all "identifier=25", "id=1"
|
||||||
|
|
||||||
|
assert_equal '<a href="/projects/1">eCookbook</a>',
|
||||||
|
link_to_project(Project.find(1))
|
||||||
|
end
|
||||||
|
|
||||||
def test_principals_options_for_select_with_users
|
def test_principals_options_for_select_with_users
|
||||||
users = [User.find(2), User.find(4)]
|
users = [User.find(2), User.find(4)]
|
||||||
assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
|
assert_equal %(<option value="2">John Smith</option><option value="4">Robert Hill</option>),
|
||||||
|
|||||||
@@ -91,6 +91,29 @@ class Redmine::UnifiedDiffTest < ActiveSupport::TestCase
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_partials_with_html_entities
|
||||||
|
raw = <<-DIFF
|
||||||
|
--- test.orig.txt Wed Feb 15 16:10:39 2012
|
||||||
|
+++ test.new.txt Wed Feb 15 16:11:25 2012
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
Semicolons were mysteriously appearing in code diffs in the repository
|
||||||
|
|
||||||
|
-void DoSomething(std::auto_ptr<MyClass> myObj)
|
||||||
|
+void DoSomething(const MyClass& myObj)
|
||||||
|
|
||||||
|
DIFF
|
||||||
|
|
||||||
|
diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
|
||||||
|
assert_equal 1, diff.size
|
||||||
|
assert_equal 'void DoSomething(<span>std::auto_ptr<MyClass></span> myObj)', diff.first[2].html_line_left
|
||||||
|
assert_equal 'void DoSomething(<span>const MyClass&</span> myObj)', diff.first[2].html_line_right
|
||||||
|
|
||||||
|
diff = Redmine::UnifiedDiff.new(raw, :type => 'inline')
|
||||||
|
assert_equal 1, diff.size
|
||||||
|
assert_equal 'void DoSomething(<span>std::auto_ptr<MyClass></span> myObj)', diff.first[2].html_line
|
||||||
|
assert_equal 'void DoSomething(<span>const MyClass&</span> myObj)', diff.first[3].html_line
|
||||||
|
end
|
||||||
|
|
||||||
def test_line_starting_with_dashes
|
def test_line_starting_with_dashes
|
||||||
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
||||||
--- old.txt Wed Nov 11 14:24:58 2009
|
--- old.txt Wed Nov 11 14:24:58 2009
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ class MailerTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_wiki_content_added
|
def test_wiki_content_added
|
||||||
content = WikiContent.find(:first)
|
content = WikiContent.find(1)
|
||||||
valid_languages.each do |lang|
|
valid_languages.each do |lang|
|
||||||
Setting.default_language = lang.to_s
|
Setting.default_language = lang.to_s
|
||||||
assert_difference 'ActionMailer::Base.deliveries.size' do
|
assert_difference 'ActionMailer::Base.deliveries.size' do
|
||||||
@@ -380,7 +380,7 @@ class MailerTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_wiki_content_updated
|
def test_wiki_content_updated
|
||||||
content = WikiContent.find(:first)
|
content = WikiContent.find(1)
|
||||||
valid_languages.each do |lang|
|
valid_languages.each do |lang|
|
||||||
Setting.default_language = lang.to_s
|
Setting.default_language = lang.to_s
|
||||||
assert_difference 'ActionMailer::Base.deliveries.size' do
|
assert_difference 'ActionMailer::Base.deliveries.size' do
|
||||||
|
|||||||
@@ -82,6 +82,23 @@ class MemberTest < ActiveSupport::TestCase
|
|||||||
assert_raise(ActiveRecord::RecordNotFound) { Member.find(@jsmith.id) }
|
assert_raise(ActiveRecord::RecordNotFound) { Member.find(@jsmith.id) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_sort_without_roles
|
||||||
|
a = Member.new(:roles => [Role.first])
|
||||||
|
b = Member.new
|
||||||
|
|
||||||
|
assert_equal -1, a <=> b
|
||||||
|
assert_equal 1, b <=> a
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sort_without_principal
|
||||||
|
role = Role.first
|
||||||
|
a = Member.new(:roles => [role], :principal => User.first)
|
||||||
|
b = Member.new(:roles => [role])
|
||||||
|
|
||||||
|
assert_equal -1, a <=> b
|
||||||
|
assert_equal 1, b <=> a
|
||||||
|
end
|
||||||
|
|
||||||
context "removing permissions" do
|
context "removing permissions" do
|
||||||
setup do
|
setup do
|
||||||
Watcher.delete_all("user_id = 9")
|
Watcher.delete_all("user_id = 9")
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class NewsTest < ActiveSupport::TestCase
|
|||||||
def test_create_should_send_email_notification
|
def test_create_should_send_email_notification
|
||||||
ActionMailer::Base.deliveries.clear
|
ActionMailer::Base.deliveries.clear
|
||||||
Setting.notified_events << 'news_added'
|
Setting.notified_events << 'news_added'
|
||||||
news = Project.find(:first).news.new(valid_news)
|
news = Project.find(1).news.new(valid_news)
|
||||||
|
|
||||||
assert news.save
|
assert news.save
|
||||||
assert_equal 1, ActionMailer::Base.deliveries.size
|
assert_equal 1, ActionMailer::Base.deliveries.size
|
||||||
|
|||||||
@@ -18,6 +18,13 @@
|
|||||||
require File.expand_path('../../test_helper', __FILE__)
|
require File.expand_path('../../test_helper', __FILE__)
|
||||||
|
|
||||||
class PrincipalTest < ActiveSupport::TestCase
|
class PrincipalTest < ActiveSupport::TestCase
|
||||||
|
fixtures :users, :projects, :members, :member_roles
|
||||||
|
|
||||||
|
def test_not_member_of_scope_should_return_users_that_have_no_memberships
|
||||||
|
projects = Project.find_all_by_id(1, 2)
|
||||||
|
expected = (Principal.all - projects.map(&:memberships).flatten.map(&:principal)).sort
|
||||||
|
assert_equal expected, Principal.not_member_of(projects).sort
|
||||||
|
end
|
||||||
|
|
||||||
context "#like" do
|
context "#like" do
|
||||||
setup do
|
setup do
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ class ProjectTest < ActiveSupport::TestCase
|
|||||||
assert_equal ['issue_tracking', 'repository'], Project.new.enabled_module_names
|
assert_equal ['issue_tracking', 'repository'], Project.new.enabled_module_names
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal Tracker.all, Project.new.trackers
|
assert_equal Tracker.all.sort, Project.new.trackers.sort
|
||||||
assert_equal Tracker.find(1, 3), Project.new(:tracker_ids => [1, 3]).trackers
|
assert_equal Tracker.find(1, 3).sort, Project.new(:tracker_ids => [1, 3]).trackers.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_update
|
def test_update
|
||||||
@@ -586,6 +586,13 @@ class ProjectTest < ActiveSupport::TestCase
|
|||||||
assert !versions.collect(&:id).include?(6)
|
assert !versions.collect(&:id).include?(6)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_shared_versions_for_new_project_should_include_system_shared_versions
|
||||||
|
p = Project.find(5)
|
||||||
|
v = Version.create!(:name => 'system_sharing', :project => p, :sharing => 'system')
|
||||||
|
|
||||||
|
assert_include v, Project.new.shared_versions
|
||||||
|
end
|
||||||
|
|
||||||
def test_next_identifier
|
def test_next_identifier
|
||||||
ProjectCustomField.delete_all
|
ProjectCustomField.delete_all
|
||||||
Project.create!(:name => 'last', :identifier => 'p2008040')
|
Project.create!(:name => 'last', :identifier => 'p2008040')
|
||||||
|
|||||||
@@ -574,6 +574,38 @@ class UserTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_default_admin_account_changed_should_return_false_if_account_was_not_changed
|
||||||
|
user = User.find_by_login("admin")
|
||||||
|
user.password = "admin"
|
||||||
|
user.save!
|
||||||
|
|
||||||
|
assert_equal false, User.default_admin_account_changed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_default_admin_account_changed_should_return_true_if_password_was_changed
|
||||||
|
user = User.find_by_login("admin")
|
||||||
|
user.password = "newpassword"
|
||||||
|
user.save!
|
||||||
|
|
||||||
|
assert_equal true, User.default_admin_account_changed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_default_admin_account_changed_should_return_true_if_account_is_disabled
|
||||||
|
user = User.find_by_login("admin")
|
||||||
|
user.password = "admin"
|
||||||
|
user.status = User::STATUS_LOCKED
|
||||||
|
user.save!
|
||||||
|
|
||||||
|
assert_equal true, User.default_admin_account_changed?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_default_admin_account_changed_should_return_true_if_account_does_not_exist
|
||||||
|
user = User.find_by_login("admin")
|
||||||
|
user.destroy
|
||||||
|
|
||||||
|
assert_equal true, User.default_admin_account_changed?
|
||||||
|
end
|
||||||
|
|
||||||
def test_roles_for_project
|
def test_roles_for_project
|
||||||
# user with a role
|
# user with a role
|
||||||
roles = @jsmith.roles_for_project(Project.find(1))
|
roles = @jsmith.roles_for_project(Project.find(1))
|
||||||
|
|||||||
+2
-11
@@ -11,17 +11,8 @@ cert_chain: []
|
|||||||
|
|
||||||
date: 2007-12-20 00:00:00 -08:00
|
date: 2007-12-20 00:00:00 -08:00
|
||||||
default_executable:
|
default_executable:
|
||||||
dependencies:
|
dependencies: []
|
||||||
- !ruby/object:Gem::Dependency
|
|
||||||
name: hoe
|
|
||||||
type: :runtime
|
|
||||||
version_requirement:
|
|
||||||
version_requirements: !ruby/object:Gem::Requirement
|
|
||||||
requirements:
|
|
||||||
- - ">="
|
|
||||||
- !ruby/object:Gem::Version
|
|
||||||
version: 1.3.0
|
|
||||||
version:
|
|
||||||
description: "Provides a generic tree data-structure with ability to store keyed node-elements in the tree. The implementation mixes in the Enumerable module. Website: http://rubytree.rubyforge.org/"
|
description: "Provides a generic tree data-structure with ability to store keyed node-elements in the tree. The implementation mixes in the Enumerable module. Website: http://rubytree.rubyforge.org/"
|
||||||
email: anupamsg@gmail.com
|
email: anupamsg@gmail.com
|
||||||
executables: []
|
executables: []
|
||||||
|
|||||||
Vendored
+9
-9
@@ -1803,7 +1803,7 @@ class TCPDF
|
|||||||
w = @w - @r_margin - @x;
|
w = @w - @r_margin - @x;
|
||||||
end
|
end
|
||||||
|
|
||||||
wmax = (w - 2 * @c_margin);
|
wmax = (w - 3 * @c_margin);
|
||||||
|
|
||||||
s = txt.gsub("\r", ''); # remove carriage returns
|
s = txt.gsub("\r", ''); # remove carriage returns
|
||||||
nb = s.length;
|
nb = s.length;
|
||||||
@@ -1862,7 +1862,7 @@ class TCPDF
|
|||||||
ns += 1;
|
ns += 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
l = GetStringWidth(s[from_j, to_index - from_j + 1]);
|
l = GetStringWidth(s[from_j, to_index - from_j]);
|
||||||
|
|
||||||
if (l > wmax)
|
if (l > wmax)
|
||||||
#Automatic line break
|
#Automatic line break
|
||||||
@@ -1945,7 +1945,7 @@ class TCPDF
|
|||||||
|
|
||||||
#Output text in flowing mode
|
#Output text in flowing mode
|
||||||
w = @w - @r_margin - @x;
|
w = @w - @r_margin - @x;
|
||||||
wmax = (w - 2 * @c_margin);
|
wmax = (w - 3 * @c_margin);
|
||||||
|
|
||||||
s = txt.gsub("\r", '');
|
s = txt.gsub("\r", '');
|
||||||
nb = s.length;
|
nb = s.length;
|
||||||
@@ -1974,7 +1974,7 @@ class TCPDF
|
|||||||
if (nl == 1)
|
if (nl == 1)
|
||||||
@x = @l_margin;
|
@x = @l_margin;
|
||||||
w = @w - @r_margin - @x;
|
w = @w - @r_margin - @x;
|
||||||
wmax = (w - 2 * @c_margin);
|
wmax = (w - 3 * @c_margin);
|
||||||
end
|
end
|
||||||
nl += 1;
|
nl += 1;
|
||||||
next
|
next
|
||||||
@@ -1982,7 +1982,7 @@ class TCPDF
|
|||||||
if (c == " "[0])
|
if (c == " "[0])
|
||||||
sep= i;
|
sep= i;
|
||||||
end
|
end
|
||||||
l = GetStringWidth(s[j, i - j + 1]);
|
l = GetStringWidth(s[j, i - j]);
|
||||||
if (l > wmax)
|
if (l > wmax)
|
||||||
#Automatic line break (word wrapping)
|
#Automatic line break (word wrapping)
|
||||||
if (sep == -1)
|
if (sep == -1)
|
||||||
@@ -1991,7 +1991,7 @@ class TCPDF
|
|||||||
@x = @l_margin;
|
@x = @l_margin;
|
||||||
@y += h;
|
@y += h;
|
||||||
w=@w - @r_margin - @x;
|
w=@w - @r_margin - @x;
|
||||||
wmax=(w - 2 * @c_margin);
|
wmax=(w - 3 * @c_margin);
|
||||||
i += 1
|
i += 1
|
||||||
nl += 1
|
nl += 1
|
||||||
next
|
next
|
||||||
@@ -2010,7 +2010,7 @@ class TCPDF
|
|||||||
if (nl==1)
|
if (nl==1)
|
||||||
@x = @l_margin;
|
@x = @l_margin;
|
||||||
w = @w - @r_margin - @x;
|
w = @w - @r_margin - @x;
|
||||||
wmax = (w - 2 * @c_margin);
|
wmax = (w - 3 * @c_margin);
|
||||||
end
|
end
|
||||||
nl += 1;
|
nl += 1;
|
||||||
else
|
else
|
||||||
@@ -3474,7 +3474,7 @@ class TCPDF
|
|||||||
#Extract attributes
|
#Extract attributes
|
||||||
# get tag name
|
# get tag name
|
||||||
tag = element.scan(/([a-zA-Z0-9]*)/).flatten.delete_if {|x| x.length == 0}
|
tag = element.scan(/([a-zA-Z0-9]*)/).flatten.delete_if {|x| x.length == 0}
|
||||||
tag = tag[0].downcase;
|
tag = tag[0].to_s.downcase;
|
||||||
|
|
||||||
# get attributes
|
# get attributes
|
||||||
attr_array = element.scan(/([^=\s]*)=["\']?([^"\']*)["\']?/)
|
attr_array = element.scan(/([^=\s]*)=["\']?([^"\']*)["\']?/)
|
||||||
@@ -3497,7 +3497,7 @@ class TCPDF
|
|||||||
#Extract attributes
|
#Extract attributes
|
||||||
# get tag name
|
# get tag name
|
||||||
tag = element.scan(/([a-zA-Z0-9]*)/).flatten.delete_if {|x| x.length == 0}
|
tag = element.scan(/([a-zA-Z0-9]*)/).flatten.delete_if {|x| x.length == 0}
|
||||||
tag = tag[0].downcase;
|
tag = tag[0].to_s.downcase;
|
||||||
|
|
||||||
# get attributes
|
# get attributes
|
||||||
attr_array = element.scan(/([^=\s]*)=["\']?([^"\']*)["\']?/)
|
attr_array = element.scan(/([^=\s]*)=["\']?([^"\']*)["\']?/)
|
||||||
|
|||||||
Reference in New Issue
Block a user