mirror of
https://github.com/meineerde/redmine.git
synced 2025-12-30 20:29:37 +00:00
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:
parent
c0db7007fa
commit
729d1176ea
@ -40,7 +40,7 @@ class Attachment < ActiveRecord::Base
|
||||
@temp_file = incoming_file
|
||||
if @temp_file.size > 0
|
||||
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.filesize = @temp_file.size
|
||||
end
|
||||
@ -100,4 +100,17 @@ private
|
||||
# Finally, replace all non alphanumeric, hyphens or periods with underscore
|
||||
@filename = just_filename.gsub(/[^\w\.\-]/,'_')
|
||||
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
|
||||
|
||||
@ -73,9 +73,9 @@ class Project < ActiveRecord::Base
|
||||
|
||||
def issues_with_subprojects(include_subprojects=false)
|
||||
conditions = nil
|
||||
if include_subprojects && !active_children.empty?
|
||||
ids = [id] + active_children.collect {|c| c.id}
|
||||
conditions = ["#{Project.table_name}.id IN (#{ids.join(',')})"]
|
||||
if include_subprojects
|
||||
ids = [id] + child_ids
|
||||
conditions = ["#{Project.table_name}.id IN (#{ids.join(',')}) AND #{Project.visible_by}"]
|
||||
end
|
||||
conditions ||= ["#{Project.table_name}.id = ?", id]
|
||||
# Quick and dirty fix for Rails 2 compatibility
|
||||
@ -93,6 +93,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def self.visible_by(user=nil)
|
||||
user ||= User.current
|
||||
if user && user.admin?
|
||||
return "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"
|
||||
elsif user && user.memberships.any?
|
||||
|
||||
@ -265,7 +265,7 @@ class Query < ActiveRecord::Base
|
||||
|
||||
def statement
|
||||
# project/subprojects clause
|
||||
clause = ''
|
||||
project_clauses = []
|
||||
if project && !@project.active_children.empty?
|
||||
ids = [project.id]
|
||||
if has_filter?("subproject_id")
|
||||
@ -277,17 +277,16 @@ class Query < ActiveRecord::Base
|
||||
# main project only
|
||||
else
|
||||
# all subprojects
|
||||
ids += project.active_children.collect{|p| p.id}
|
||||
ids += project.child_ids
|
||||
end
|
||||
elsif Setting.display_subprojects_issues?
|
||||
ids += project.active_children.collect{|p| p.id}
|
||||
ids += project.child_ids
|
||||
end
|
||||
clause << "#{Issue.table_name}.project_id IN (%s)" % ids.join(',')
|
||||
project_clauses << "#{Issue.table_name}.project_id IN (%s)" % ids.join(',')
|
||||
elsif project
|
||||
clause << "#{Issue.table_name}.project_id = %d" % project.id
|
||||
else
|
||||
clause << Project.visible_by(User.current)
|
||||
project_clauses << "#{Issue.table_name}.project_id = %d" % project.id
|
||||
end
|
||||
project_clauses << Project.visible_by(User.current)
|
||||
|
||||
# filters clauses
|
||||
filters_clauses = []
|
||||
@ -365,8 +364,6 @@ class Query < ActiveRecord::Base
|
||||
filters_clauses << sql
|
||||
end if filters and valid?
|
||||
|
||||
clause << ' AND ' unless clause.empty?
|
||||
clause << filters_clauses.join(' AND ') unless filters_clauses.empty?
|
||||
clause
|
||||
(project_clauses + filters_clauses).join(' AND ')
|
||||
end
|
||||
end
|
||||
|
||||
@ -21,9 +21,9 @@
|
||||
<p><%= time_entry.text_field :hours, :size => 6, :label => :label_spent_time %> <%= l(:field_hours) %></p>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
<p><%= time_entry.text_field :comments, :size => 60 %></p>
|
||||
<% end %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<% end %>
|
||||
|
||||
<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.keys.sort.each do |mod| %>
|
||||
<fieldset><legend><%= mod.blank? ? l(:label_project) : mod.humanize %></legend>
|
||||
@ -24,6 +24,6 @@
|
||||
<% end %>
|
||||
</fieldset>
|
||||
<% end %>
|
||||
<br /><%= check_all_links 'role_form' %>
|
||||
<br /><%= check_all_links 'permissions' %>
|
||||
<%= hidden_field_tag 'role[permissions][]', '' %>
|
||||
</div>
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
<%= hidden_field_tag 'settings[bcc_recipients]', 0 %></p>
|
||||
</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| %>
|
||||
<label><%= check_box_tag 'settings[notified_events][]', notifiable, Setting.notified_events.include?(notifiable) %>
|
||||
<%= l_or_humanize(notifiable) %></label><br />
|
||||
<% end %>
|
||||
<%= hidden_field_tag 'settings[notified_events][]', '' %>
|
||||
<p><%= check_all_links('mail-options-form') %></p>
|
||||
<p><%= check_all_links('notified_events') %></p>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="box"><legend><%= l(:setting_emails_footer) %></legend>
|
||||
|
||||
@ -376,13 +376,13 @@ class RedCloth < String
|
||||
re =
|
||||
case rtype
|
||||
when :limit
|
||||
/(^|[>\s])
|
||||
/(^|[>\s\(])
|
||||
(#{rcq})
|
||||
(#{C})
|
||||
(?::(\S+?))?
|
||||
([^\s\-].*?[^\s\-]|\w)
|
||||
#{rcq}
|
||||
(?=[[:punct:]]|\s|$)/x
|
||||
(?=[[:punct:]]|\s|\)|$)/x
|
||||
else
|
||||
/(#{rcq})
|
||||
(#{C})
|
||||
|
||||
@ -27,8 +27,8 @@ module Redmine
|
||||
|
||||
# Get the revision of a particuliar file
|
||||
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 --git-dir #{target('')} log -1 master -- #{shell_quote path}" if
|
||||
cmd="#{GIT_BIN} --git-dir #{target('')} show #{shell_quote rev} -- #{shell_quote path}" if rev!='latest' and (! rev.nil?)
|
||||
cmd="#{GIT_BIN} --git-dir #{target('')} log -1 master -- #{shell_quote path}" if
|
||||
rev=='latest' or rev.nil?
|
||||
rev=[]
|
||||
i=0
|
||||
|
||||
@ -26,7 +26,7 @@ module Redmine
|
||||
class TextileFormatter < RedCloth
|
||||
|
||||
# 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)
|
||||
super
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
Copyright (C) 2006-2008 Jean-Philippe Lang */
|
||||
|
||||
function checkAll (id, checked) {
|
||||
var el = document.getElementById(id);
|
||||
for (var i = 0; i < el.elements.length; i++) {
|
||||
if (el.elements[i].disabled==false) {
|
||||
el.elements[i].checked = checked;
|
||||
var els = Element.descendants(id);
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
if (els[i].disabled==false) {
|
||||
els[i].checked = checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,6 +223,8 @@ height: 1%;
|
||||
clear:left;
|
||||
}
|
||||
|
||||
html>body .tabular p {overflow:auto;}
|
||||
|
||||
.tabular label{
|
||||
font-weight: bold;
|
||||
float: left;
|
||||
@ -239,6 +241,8 @@ text-align: left;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
input#time_entry_comments { width: 90%;}
|
||||
|
||||
#preview fieldset {margin-top: 1em; background: url(../images/draft.png)}
|
||||
|
||||
.tabular.settings p{ padding-left: 300px; }
|
||||
|
||||
18
test/fixtures/issues.yml
vendored
18
test/fixtures/issues.yml
vendored
@ -71,4 +71,20 @@ issues_005:
|
||||
assigned_to_id:
|
||||
author_id: 2
|
||||
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) %>
|
||||
|
||||
@ -53,13 +53,44 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
assert_template 'index.rhtml'
|
||||
assert_not_nil assigns(:issues)
|
||||
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
|
||||
|
||||
def test_index_with_project
|
||||
Setting.display_subprojects_issues = 0
|
||||
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_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
|
||||
|
||||
def test_index_with_project_and_filter
|
||||
|
||||
@ -29,6 +29,7 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
@controller = ProjectsController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
@request.session[:user_id] = nil
|
||||
end
|
||||
|
||||
def test_index
|
||||
@ -237,11 +238,21 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
assert_not_nil assigns(:calendar)
|
||||
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]
|
||||
assert_response :success
|
||||
assert_template '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
|
||||
|
||||
def test_gantt
|
||||
@ -251,13 +262,23 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
assert_not_nil assigns(:events)
|
||||
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]
|
||||
assert_response :success
|
||||
assert_template 'gantt.rhtml'
|
||||
assert_not_nil assigns(:events)
|
||||
assert_no_tag :tag => 'a', :content => /#6/
|
||||
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
|
||||
get :gantt, :id => 1, :format => 'pdf'
|
||||
assert_response :success
|
||||
|
||||
32
test/unit/attachment_test.rb
Normal file
32
test/unit/attachment_test.rb
Normal 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]/, '') }
|
||||
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
|
||||
text = "{{hello_world}}"
|
||||
assert textilizable(text).match(/Hello world!/)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user