Merged r1385 and r1426 to r1434 from trunk.

git-svn-id: http://redmine.rubyforge.org/svn/branches/0.7-stable@1437 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang committed 2008-05-18 16:53:23 +00:00
1 parent c0db7007fa
commit 729d1176ea
16 files changed
+158 -31

No files matched your search

+14 -1
View File
@@ -40,7 +40,7 @@ class Attachment < ActiveRecord::Base
@temp_file = incoming_file @temp_file = incoming_file
if @temp_file.size > 0 if @temp_file.size > 0
self.filename = sanitize_filename(@temp_file.original_filename) self.filename = sanitize_filename(@temp_file.original_filename)
self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename self.disk_filename = Attachment.disk_filename(filename)
self.content_type = @temp_file.content_type.to_s.chomp self.content_type = @temp_file.content_type.to_s.chomp
self.filesize = @temp_file.size self.filesize = @temp_file.size
end end
@@ -100,4 +100,17 @@ private
# Finally, replace all non alphanumeric, hyphens or periods with underscore # Finally, replace all non alphanumeric, hyphens or periods with underscore
@filename = just_filename.gsub(/[^\w\.\-]/,'_') @filename = just_filename.gsub(/[^\w\.\-]/,'_')
end end
# Returns an ASCII or hashed filename
def self.disk_filename(filename)
df = DateTime.now.strftime("%y%m%d%H%M%S") + "_"
if filename =~ %r{^[a-zA-Z0-9_\.\-]*$}
df << filename
else
df << Digest::MD5.hexdigest(filename)
# keep the extension if any
df << $1 if filename =~ %r{(\.[a-zA-Z0-9]+)$}
end
df
end
end end
+4 -3
View File
@@ -73,9 +73,9 @@ class Project < ActiveRecord::Base
def issues_with_subprojects(include_subprojects=false) def issues_with_subprojects(include_subprojects=false)
conditions = nil conditions = nil
if include_subprojects && !active_children.empty? if include_subprojects
ids = [id] + active_children.collect {|c| c.id} ids = [id] + child_ids
conditions = ["#{Project.table_name}.id IN (#{ids.join(',')})"] conditions = ["#{Project.table_name}.id IN (#{ids.join(',')}) AND #{Project.visible_by}"]
end end
conditions ||= ["#{Project.table_name}.id = ?", id] conditions ||= ["#{Project.table_name}.id = ?", id]
# Quick and dirty fix for Rails 2 compatibility # Quick and dirty fix for Rails 2 compatibility
@@ -93,6 +93,7 @@ class Project < ActiveRecord::Base
end end
def self.visible_by(user=nil) def self.visible_by(user=nil)
user ||= User.current
if user && user.admin? if user && user.admin?
return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}" return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
elsif user && user.memberships.any? elsif user && user.memberships.any?
+7 -10
View File
@@ -265,7 +265,7 @@ class Query < ActiveRecord::Base
def statement def statement
# project/subprojects clause # project/subprojects clause
clause = '' project_clauses = []
if project && !@project.active_children.empty? if project && !@project.active_children.empty?
ids = [project.id] ids = [project.id]
if has_filter?("subproject_id") if has_filter?("subproject_id")
@@ -277,17 +277,16 @@ class Query < ActiveRecord::Base
# main project only # main project only
else else
# all subprojects # all subprojects
ids += project.active_children.collect{|p| p.id} ids += project.child_ids
end end
elsif Setting.display_subprojects_issues? elsif Setting.display_subprojects_issues?
ids += project.active_children.collect{|p| p.id} ids += project.child_ids
end end
clause << "#{Issue.table_name}.project_id IN (%s)" % ids.join(',') project_clauses << "#{Issue.table_name}.project_id IN (%s)" % ids.join(',')
elsif project elsif project
clause << "#{Issue.table_name}.project_id = %d" % project.id project_clauses << "#{Issue.table_name}.project_id = %d" % project.id
else
clause << Project.visible_by(User.current)
end end
project_clauses << Project.visible_by(User.current)
# filters clauses # filters clauses
filters_clauses = [] filters_clauses = []
@@ -365,8 +364,6 @@ class Query < ActiveRecord::Base
filters_clauses << sql filters_clauses << sql
end if filters and valid? end if filters and valid?
clause << ' AND ' unless clause.empty? (project_clauses + filters_clauses).join(' AND ')
clause << filters_clauses.join(' AND ') unless filters_clauses.empty?
clause
end end
end end
+1 -1
View File
@@ -21,9 +21,9 @@
<p><%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %></p> <p><%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %></p>
</div> </div>
<div class="splitcontentright"> <div class="splitcontentright">
<p><%= time_entry.text_field :comments, :size => 40 %></p>
<p><%= time_entry.select :activity_id, (@activities.collect {|p| [p.name, p.id]}) %></p> <p><%= time_entry.select :activity_id, (@activities.collect {|p| [p.name, p.id]}) %></p>
</div> </div>
<p><%= time_entry.text_field :comments, :size => 60 %></p>
<% end %> <% end %>
</fieldset> </fieldset>
<% end %> <% end %>
+2 -2
View File
@@ -12,7 +12,7 @@
<% end %> <% end %>
<h3><%= l(:label_permissions) %></h3> <h3><%= l(:label_permissions) %></h3>
<div class="box"> <div class="box" id="permissions">
<% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %> <% perms_by_module = @permissions.group_by {|p| p.project_module.to_s} %>
<% perms_by_module.keys.sort.each do |mod| %> <% perms_by_module.keys.sort.each do |mod| %>
<fieldset><legend><%= mod.blank? ? l(:label_project) : mod.humanize %></legend> <fieldset><legend><%= mod.blank? ? l(:label_project) : mod.humanize %></legend>
@@ -24,6 +24,6 @@
<% end %> <% end %>
</fieldset> </fieldset>
<% end %> <% end %>
<br /><%= check_all_links 'role_form' %> <br /><%= check_all_links 'permissions' %>
<%= hidden_field_tag 'role[permissions][]', '' %> <%= hidden_field_tag 'role[permissions][]', '' %>
</div> </div>
+2 -2
View File
@@ -9,13 +9,13 @@
<%= hidden_field_tag 'settings[bcc_recipients]', 0 %></p> <%= hidden_field_tag 'settings[bcc_recipients]', 0 %></p>
</div> </div>
<fieldset class="box"><legend><%=l(:text_select_mail_notifications)%></legend> <fieldset class="box" id="notified_events"><legend><%=l(:text_select_mail_notifications)%></legend>
<% @notifiables.each do |notifiable| %> <% @notifiables.each do |notifiable| %>
<label><%= check_box_tag 'settings[notified_events][]', notifiable, Setting.notified_events.include?(notifiable) %> <label><%= check_box_tag 'settings[notified_events][]', notifiable, Setting.notified_events.include?(notifiable) %>
<%= l_or_humanize(notifiable) %></label><br /> <%= l_or_humanize(notifiable) %></label><br />
<% end %> <% end %>
<%= hidden_field_tag 'settings[notified_events][]', '' %> <%= hidden_field_tag 'settings[notified_events][]', '' %>
<p><%= check_all_links('mail-options-form') %></p> <p><%= check_all_links('notified_events') %></p>
</fieldset> </fieldset>
<fieldset class="box"><legend><%= l(:setting_emails_footer) %></legend> <fieldset class="box"><legend><%= l(:setting_emails_footer) %></legend>
+2 -2
View File
@@ -376,13 +376,13 @@ class RedCloth < String
re = re =
case rtype case rtype
when :limit when :limit
/(^|[>\s]) /(^|[>\s\(])
(#{rcq}) (#{rcq})
(#{C}) (#{C})
(?::(\S+?))? (?::(\S+?))?
([^\s\-].*?[^\s\-]|\w) ([^\s\-].*?[^\s\-]|\w)
#{rcq} #{rcq}
(?=[[:punct:]]|\s|$)/x (?=[[:punct:]]|\s|\)|$)/x
else else
/(#{rcq}) /(#{rcq})
(#{C}) (#{C})
+2 -2
View File
@@ -27,8 +27,8 @@ module Redmine
# Get the revision of a particuliar file # Get the revision of a particuliar file
def get_rev (rev,path) def get_rev (rev,path)
cmd="git --git-dir #{target('')} show #{shell_quote rev} -- #{shell_quote path}" if rev!='latest' and (! rev.nil?) cmd="#{GIT_BIN} --git-dir #{target('')} show #{shell_quote rev} -- #{shell_quote path}" if rev!='latest' and (! rev.nil?)
cmd="git --git-dir #{target('')} log -1 master -- #{shell_quote path}" if cmd="#{GIT_BIN} --git-dir #{target('')} log -1 master -- #{shell_quote path}" if
rev=='latest' or rev.nil? rev=='latest' or rev.nil?
rev=[] rev=[]
i=0 i=0
+1 -1
View File
@@ -26,7 +26,7 @@ module Redmine
class TextileFormatter < RedCloth class TextileFormatter < RedCloth
# 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, :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]
def initialize(*args) def initialize(*args)
super super
+4 -4
View File
@@ -2,10 +2,10 @@
Copyright (C) 2006-2008 Jean-Philippe Lang */ Copyright (C) 2006-2008 Jean-Philippe Lang */
function checkAll (id, checked) { function checkAll (id, checked) {
var el = document.getElementById(id); var els = Element.descendants(id);
for (var i = 0; i < el.elements.length; i++) { for (var i = 0; i < els.length; i++) {
if (el.elements[i].disabled==false) { if (els[i].disabled==false) {
el.elements[i].checked = checked; els[i].checked = checked;
} }
} }
} }
+4
View File
@@ -223,6 +223,8 @@ height: 1%;
clear:left; clear:left;
} }
html>body .tabular p {overflow:auto;}
.tabular label{ .tabular label{
font-weight: bold; font-weight: bold;
float: left; float: left;
@@ -239,6 +241,8 @@ text-align: left;
width: 200px; width: 200px;
} }
input#time_entry_comments { width: 90%;}
#preview fieldset {margin-top: 1em; background: url(../images/draft.png)} #preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
.tabular.settings p{ padding-left: 300px; } .tabular.settings p{ padding-left: 300px; }
+17 -1
View File
@@ -71,4 +71,20 @@ issues_005:
assigned_to_id: assigned_to_id:
author_id: 2 author_id: 2
status_id: 1 status_id: 1
issues_006:
created_on: <%= 1.minute.ago.to_date.to_s(:db) %>
project_id: 5
updated_on: <%= 1.minute.ago.to_date.to_s(:db) %>
priority_id: 4
subject: Issue of a private subproject
id: 6
fixed_version_id:
category_id:
description: This is an issue of a private subproject of cookbook
tracker_id: 1
assigned_to_id:
author_id: 2
status_id: 1
start_date: <%= Date.today.to_s(:db) %>
due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
+31
View File
@@ -53,13 +53,44 @@ class IssuesControllerTest < Test::Unit::TestCase
assert_template 'index.rhtml' assert_template 'index.rhtml'
assert_not_nil assigns(:issues) assert_not_nil assigns(:issues)
assert_nil assigns(:project) assert_nil assigns(:project)
assert_tag :tag => 'a', :content => /Can't print recipes/
assert_tag :tag => 'a', :content => /Subproject issue/
# private projects hidden
assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
assert_no_tag :tag => 'a', :content => /Issue on project 2/
end end
def test_index_with_project def test_index_with_project
Setting.display_subprojects_issues = 0
get :index, :project_id => 1 get :index, :project_id => 1
assert_response :success assert_response :success
assert_template 'index.rhtml' assert_template 'index.rhtml'
assert_not_nil assigns(:issues) assert_not_nil assigns(:issues)
assert_tag :tag => 'a', :content => /Can't print recipes/
assert_no_tag :tag => 'a', :content => /Subproject issue/
end
def test_index_with_project_and_subprojects
Setting.display_subprojects_issues = 1
get :index, :project_id => 1
assert_response :success
assert_template 'index.rhtml'
assert_not_nil assigns(:issues)
assert_tag :tag => 'a', :content => /Can't print recipes/
assert_tag :tag => 'a', :content => /Subproject issue/
assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
end
def test_index_with_project_and_subprojects_should_show_private_subprojects
@request.session[:user_id] = 2
Setting.display_subprojects_issues = 1
get :index, :project_id => 1
assert_response :success
assert_template 'index.rhtml'
assert_not_nil assigns(:issues)
assert_tag :tag => 'a', :content => /Can't print recipes/
assert_tag :tag => 'a', :content => /Subproject issue/
assert_tag :tag => 'a', :content => /Issue of a private subproject/
end end
def test_index_with_project_and_filter def test_index_with_project_and_filter
+23 -2
View File
@@ -29,6 +29,7 @@ class ProjectsControllerTest < Test::Unit::TestCase
@controller = ProjectsController.new @controller = ProjectsController.new
@request = ActionController::TestRequest.new @request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new @response = ActionController::TestResponse.new
@request.session[:user_id] = nil
end end
def test_index def test_index
@@ -237,11 +238,21 @@ class ProjectsControllerTest < Test::Unit::TestCase
assert_not_nil assigns(:calendar) assert_not_nil assigns(:calendar)
end end
def test_calendar_with_subprojects def test_calendar_with_subprojects_should_not_show_private_subprojects
get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2] get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
assert_response :success assert_response :success
assert_template 'calendar' assert_template 'calendar'
assert_not_nil assigns(:calendar) assert_not_nil assigns(:calendar)
assert_no_tag :tag => 'a', :content => /#6/
end
def test_calendar_with_subprojects_should_show_private_subprojects
@request.session[:user_id] = 2
get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
assert_response :success
assert_template 'calendar'
assert_not_nil assigns(:calendar)
assert_tag :tag => 'a', :content => /#6/
end end
def test_gantt def test_gantt
@@ -251,13 +262,23 @@ class ProjectsControllerTest < Test::Unit::TestCase
assert_not_nil assigns(:events) assert_not_nil assigns(:events)
end end
def test_gantt_with_subprojects def test_gantt_with_subprojects_should_not_show_private_subprojects
get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2] get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
assert_response :success assert_response :success
assert_template 'gantt.rhtml' assert_template 'gantt.rhtml'
assert_not_nil assigns(:events) assert_not_nil assigns(:events)
assert_no_tag :tag => 'a', :content => /#6/
end end
def test_gantt_with_subprojects_should_show_private_subprojects
@request.session[:user_id] = 2
get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
assert_response :success
assert_template 'gantt.rhtml'
assert_not_nil assigns(:events)
assert_tag :tag => 'a', :content => /#6/
end
def test_gantt_export_to_pdf def test_gantt_export_to_pdf
get :gantt, :id => 1, :format => 'pdf' get :gantt, :id => 1, :format => 'pdf'
assert_response :success assert_response :success
+32
View File
@@ -0,0 +1,32 @@
# redMine - project management software
# Copyright (C) 2006-2007 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../test_helper'
class AttachmentTest < Test::Unit::TestCase
def setup
end
def test_diskfilename
assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentué.txt")[13..-1]
assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentué")[13..-1]
assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentué.ça")[13..-1]
end
end
@@ -162,6 +162,18 @@ class ApplicationHelperTest < HelperTestCase
to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') } to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
end end
def test_text_formatting
to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
'(_text within parentheses_)' => '(<em>text within parentheses</em>)'
}
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
end
def test_wiki_horizontal_rule
assert_equal '<hr />', textilizable('---')
assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
end
def test_macro_hello_world def test_macro_hello_world
text = "{{hello_world}}" text = "{{hello_world}}"
assert textilizable(text).match(/Hello world!/) assert textilizable(text).match(/Hello world!/)