Merged trunk r1773.
git-svn-id: http://redmine.rubyforge.org/svn/branches/work@1774 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 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 ActivityTest < Test::Unit::TestCase
|
||||
fixtures :projects, :versions, :users, :roles, :members, :issues, :journals, :journal_details,
|
||||
:trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
end
|
||||
|
||||
def test_activity_without_subprojects
|
||||
events = find_events(User.anonymous, :project => @project)
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
assert !events.include?(Issue.find(4))
|
||||
# subproject issue
|
||||
assert !events.include?(Issue.find(5))
|
||||
end
|
||||
|
||||
def test_activity_with_subprojects
|
||||
events = find_events(User.anonymous, :project => @project, :with_subprojects => 1)
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
# subproject issue
|
||||
assert events.include?(Issue.find(5))
|
||||
end
|
||||
|
||||
def test_global_activity_anonymous
|
||||
events = find_events(User.anonymous)
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
assert events.include?(Message.find(5))
|
||||
# Issue of a private project
|
||||
assert !events.include?(Issue.find(4))
|
||||
end
|
||||
|
||||
def test_global_activity_logged_user
|
||||
events = find_events(User.find(2)) # manager
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
# Issue of a private project the user belongs to
|
||||
assert events.include?(Issue.find(4))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_events(user, options={})
|
||||
Redmine::Activity::Fetcher.new(user, options).events(Date.today - 30, Date.today + 1)
|
||||
end
|
||||
end
|
||||
@@ -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
|
||||
@@ -39,6 +39,17 @@ class ChangesetTest < Test::Unit::TestCase
|
||||
assert fixed.closed?
|
||||
assert_equal 90, fixed.done_ratio
|
||||
end
|
||||
|
||||
def test_ref_keywords_any_line_start
|
||||
Setting.commit_ref_keywords = '*'
|
||||
|
||||
c = Changeset.new(:repository => Project.find(1).repository,
|
||||
:committed_on => Time.now,
|
||||
:comments => '#1 is the reason of this commit')
|
||||
c.scan_comment_for_issue_ids
|
||||
|
||||
assert_equal [1], c.issue_ids.sort
|
||||
end
|
||||
|
||||
def test_previous
|
||||
changeset = Changeset.find_by_revision('3')
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 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 DefaultDataTest < Test::Unit::TestCase
|
||||
fixtures :roles
|
||||
|
||||
def test_no_data
|
||||
assert !Redmine::DefaultData::Loader::no_data?
|
||||
Role.delete_all("builtin = 0")
|
||||
Tracker.delete_all
|
||||
IssueStatus.delete_all
|
||||
Enumeration.delete_all
|
||||
assert Redmine::DefaultData::Loader::no_data?
|
||||
end
|
||||
|
||||
def test_load
|
||||
GLoc.valid_languages.each do |lang|
|
||||
begin
|
||||
Role.delete_all("builtin = 0")
|
||||
Tracker.delete_all
|
||||
IssueStatus.delete_all
|
||||
Enumeration.delete_all
|
||||
assert Redmine::DefaultData::Loader::load(lang)
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
assert false, ":#{lang} default data is invalid (#{e.message})."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 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 EnumerationTest < Test::Unit::TestCase
|
||||
fixtures :enumerations, :issues
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
def test_objects_count
|
||||
# low priority
|
||||
assert_equal 5, Enumeration.find(4).objects_count
|
||||
# urgent
|
||||
assert_equal 0, Enumeration.find(7).objects_count
|
||||
end
|
||||
|
||||
def test_in_use
|
||||
# low priority
|
||||
assert Enumeration.find(4).in_use?
|
||||
# urgent
|
||||
assert !Enumeration.find(7).in_use?
|
||||
end
|
||||
|
||||
def test_destroy_with_reassign
|
||||
Enumeration.find(4).destroy(Enumeration.find(6))
|
||||
assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
|
||||
assert_equal 5, Enumeration.find(6).objects_count
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
|
||||
class FilesystemAdapterTest < Test::Unit::TestCase
|
||||
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def setup
|
||||
@adapter = Redmine::Scm::Adapters::FilesystemAdapter.new(REPOSITORY_PATH)
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_equal 2, @adapter.entries.size
|
||||
assert_equal ["dir", "test"], @adapter.entries.collect(&:name)
|
||||
assert_equal ["dir", "test"], @adapter.entries(nil).collect(&:name)
|
||||
assert_equal ["dir", "test"], @adapter.entries("/").collect(&:name)
|
||||
["dir", "/dir", "/dir/", "dir/"].each do |path|
|
||||
assert_equal ["subdir", "dirfile"], @adapter.entries(path).collect(&:name)
|
||||
end
|
||||
# If y try to use "..", the path is ignored
|
||||
["/../","dir/../", "..", "../", "/..", "dir/.."].each do |path|
|
||||
assert_equal ["dir", "test"], @adapter.entries(path).collect(&:name), ".. must be ignored in path argument"
|
||||
end
|
||||
end
|
||||
|
||||
def test_cat
|
||||
assert_equal "TEST CAT\n", @adapter.cat("test")
|
||||
assert_equal "TEST CAT\n", @adapter.cat("/test")
|
||||
# Revision number is ignored
|
||||
assert_equal "TEST CAT\n", @adapter.cat("/test", 1)
|
||||
end
|
||||
|
||||
else
|
||||
puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
|
||||
def test_fake; assert true end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -20,7 +20,11 @@ require File.dirname(__FILE__) + '/../../test_helper'
|
||||
class ApplicationHelperTest < HelperTestCase
|
||||
include ApplicationHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues, :documents, :versions, :wikis, :wiki_pages, :wiki_contents, :roles, :enabled_modules
|
||||
fixtures :projects, :roles, :enabled_modules,
|
||||
:repositories, :changesets,
|
||||
:trackers, :issue_statuses, :issues, :versions, :documents,
|
||||
:wikis, :wiki_pages, :wiki_contents,
|
||||
:boards, :messages
|
||||
|
||||
def setup
|
||||
super
|
||||
@@ -31,10 +35,14 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
|
||||
'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
|
||||
'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
|
||||
'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
|
||||
'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
|
||||
'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
|
||||
'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
|
||||
'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&t=z&s=">http://foo.bar/page?p=1&t=z&s=</a>',
|
||||
'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>'
|
||||
'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
|
||||
'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
|
||||
'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
|
||||
}
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
end
|
||||
@@ -58,7 +66,10 @@ class ApplicationHelperTest < HelperTestCase
|
||||
to_test = {
|
||||
'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
|
||||
'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
|
||||
'"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>'
|
||||
'"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
|
||||
"This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
|
||||
# no multiline link text
|
||||
"This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />\nand another on a second line\":test"
|
||||
}
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
end
|
||||
@@ -76,7 +87,10 @@ class ApplicationHelperTest < HelperTestCase
|
||||
version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
|
||||
:class => 'version')
|
||||
|
||||
source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => 'some/file'}
|
||||
message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
|
||||
|
||||
source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
|
||||
source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
|
||||
|
||||
to_test = {
|
||||
# tickets
|
||||
@@ -92,10 +106,20 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'version:"1.0"' => version_link,
|
||||
# source
|
||||
'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
|
||||
'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
|
||||
'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
|
||||
'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
|
||||
'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
|
||||
'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
|
||||
'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
|
||||
'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
|
||||
'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
|
||||
'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
|
||||
'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
|
||||
'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
|
||||
# message
|
||||
'message#4' => link_to('Post 2', message_url, :class => 'message'),
|
||||
'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5'), :class => 'message'),
|
||||
# escaping
|
||||
'!#3.' => '#3.',
|
||||
'!r1' => 'r1',
|
||||
@@ -106,7 +130,9 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'!version:"1.0"' => 'version:"1.0"',
|
||||
'!source:/some/file' => 'source:/some/file',
|
||||
# invalid expressions
|
||||
'source:' => 'source:'
|
||||
'source:' => 'source:',
|
||||
# url hash
|
||||
"http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
|
||||
}
|
||||
@project = Project.find(1)
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
@@ -116,6 +142,9 @@ class ApplicationHelperTest < HelperTestCase
|
||||
to_test = {
|
||||
'[[CookBook documentation]]' => '<a href="/wiki/ecookbook/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
|
||||
'[[Another page|Page]]' => '<a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a>',
|
||||
# link with anchor
|
||||
'[[CookBook documentation#One-section]]' => '<a href="/wiki/ecookbook/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
|
||||
'[[Another page#anchor|Page]]' => '<a href="/wiki/ecookbook/Another_page#anchor" class="wiki-page">Page</a>',
|
||||
# page that doesn't exist
|
||||
'[[Unknown page]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">Unknown page</a>',
|
||||
'[[Unknown page|404]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">404</a>',
|
||||
@@ -125,6 +154,8 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'[[onlinestore:Start page]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Start page</a>',
|
||||
'[[onlinestore:Start page|Text]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Text</a>',
|
||||
'[[onlinestore:Unknown page]]' => '<a href="/wiki/onlinestore/Unknown_page" class="wiki-page new">Unknown page</a>',
|
||||
# striked through link
|
||||
'-[[Another page|Page]]-' => '<del><a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a></del>',
|
||||
# escaping
|
||||
'![[Another page|Page]]' => '[[Another page|Page]]',
|
||||
}
|
||||
@@ -141,17 +172,22 @@ class ApplicationHelperTest < HelperTestCase
|
||||
"<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
|
||||
"<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
|
||||
"<pre><div>content</div></pre>" => "<pre><div>content</div></pre>",
|
||||
"HTML comment: <!-- no comments -->" => "<p>HTML comment: <!-- no comments --></p>",
|
||||
"<!-- opening comment" => "<p><!-- opening comment</p>"
|
||||
}
|
||||
to_test.each { |text, result| assert_equal result, textilizable(text) }
|
||||
end
|
||||
|
||||
def test_allowed_html_tags
|
||||
to_test = {
|
||||
"<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
|
||||
"<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
|
||||
}
|
||||
to_test.each { |text, result| assert_equal result, textilizable(text) }
|
||||
end
|
||||
|
||||
def test_wiki_links_in_tables
|
||||
to_test = {"|Cell 11|Cell 12|Cell 13|\n|Cell 21|Cell 22||\n|Cell 31||Cell 33|" =>
|
||||
'<tr><td>Cell 11</td><td>Cell 12</td><td>Cell 13</td></tr>' +
|
||||
'<tr><td>Cell 21</td><td>Cell 22</td></tr>' +
|
||||
'<tr><td>Cell 31</td><td>Cell 33</td></tr>',
|
||||
|
||||
"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
|
||||
to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
|
||||
'<tr><td><a href="/wiki/ecookbook/Page" class="wiki-page new">Link title</a></td>' +
|
||||
'<td><a href="/wiki/ecookbook/Other_Page" class="wiki-page new">Other title</a></td>' +
|
||||
'</tr><tr><td>Cell 21</td><td><a href="/wiki/ecookbook/Last_page" class="wiki-page new">Last page</a></td></tr>'
|
||||
@@ -160,6 +196,108 @@ 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_table_of_content
|
||||
raw = <<-RAW
|
||||
{{toc}}
|
||||
|
||||
h1. Title
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
|
||||
h2. Subtitle
|
||||
|
||||
Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
|
||||
|
||||
h2. Subtitle with %{color:red}red text%
|
||||
|
||||
h1. Another title
|
||||
|
||||
RAW
|
||||
|
||||
expected = '<ul class="toc">' +
|
||||
'<li class="heading1"><a href="#Title">Title</a></li>' +
|
||||
'<li class="heading2"><a href="#Subtitle">Subtitle</a></li>' +
|
||||
'<li class="heading2"><a href="#Subtitle-with-red-text">Subtitle with red text</a></li>' +
|
||||
'<li class="heading1"><a href="#Another-title">Another title</a></li>' +
|
||||
'</ul>'
|
||||
|
||||
assert textilizable(raw).gsub("\n", "").include?(expected)
|
||||
end
|
||||
|
||||
def test_blockquote
|
||||
# orig raw text
|
||||
raw = <<-RAW
|
||||
John said:
|
||||
> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
> Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
|
||||
> * Donec odio lorem,
|
||||
> * sagittis ac,
|
||||
> * malesuada in,
|
||||
> * adipiscing eu, dolor.
|
||||
>
|
||||
> >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
|
||||
> Proin a tellus. Nam vel neque.
|
||||
|
||||
He's right.
|
||||
RAW
|
||||
|
||||
# expected html
|
||||
expected = <<-EXPECTED
|
||||
<p>John said:</p>
|
||||
<blockquote>
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
|
||||
<ul>
|
||||
<li>Donec odio lorem,</li>
|
||||
<li>sagittis ac,</li>
|
||||
<li>malesuada in,</li>
|
||||
<li>adipiscing eu, dolor.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
|
||||
</blockquote>
|
||||
<p>Proin a tellus. Nam vel neque.</p>
|
||||
</blockquote>
|
||||
<p>He's right.</p>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_table
|
||||
raw = <<-RAW
|
||||
This is a table with empty cells:
|
||||
|
||||
|cell11|cell12||
|
||||
|cell21||cell23|
|
||||
|cell31|cell32|cell33|
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>This is a table with empty cells:</p>
|
||||
|
||||
<table>
|
||||
<tr><td>cell11</td><td>cell12</td><td></td></tr>
|
||||
<tr><td>cell21</td><td></td><td>cell23</td></tr>
|
||||
<tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
|
||||
</table>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_macro_hello_world
|
||||
text = "{{hello_world}}"
|
||||
assert textilizable(text).match(/Hello world!/)
|
||||
|
||||
@@ -18,7 +18,13 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class IssueTest < Test::Unit::TestCase
|
||||
fixtures :projects, :users, :members, :trackers, :projects_trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :time_entries
|
||||
fixtures :projects, :users, :members,
|
||||
:trackers, :projects_trackers,
|
||||
:issue_statuses, :issue_categories,
|
||||
:enumerations,
|
||||
:issues,
|
||||
:custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
|
||||
:time_entries
|
||||
|
||||
def test_create
|
||||
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'test_create', :description => 'IssueTest#test_create', :estimated_hours => '1:30')
|
||||
@@ -27,6 +33,76 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert_equal 1.5, issue.estimated_hours
|
||||
end
|
||||
|
||||
def test_create_with_required_custom_field
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
field.update_attribute(:is_required, true)
|
||||
|
||||
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => 'test_create', :description => 'IssueTest#test_create_with_required_custom_field')
|
||||
assert issue.available_custom_fields.include?(field)
|
||||
# No value for the custom field
|
||||
assert !issue.save
|
||||
assert_equal 'activerecord_error_invalid', issue.errors.on(:custom_values)
|
||||
# Blank value
|
||||
issue.custom_field_values = { field.id => '' }
|
||||
assert !issue.save
|
||||
assert_equal 'activerecord_error_invalid', issue.errors.on(:custom_values)
|
||||
# Invalid value
|
||||
issue.custom_field_values = { field.id => 'SQLServer' }
|
||||
assert !issue.save
|
||||
assert_equal 'activerecord_error_invalid', issue.errors.on(:custom_values)
|
||||
# Valid value
|
||||
issue.custom_field_values = { field.id => 'PostgreSQL' }
|
||||
assert issue.save
|
||||
issue.reload
|
||||
assert_equal 'PostgreSQL', issue.custom_value_for(field).value
|
||||
end
|
||||
|
||||
def test_update_issue_with_required_custom_field
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
field.update_attribute(:is_required, true)
|
||||
|
||||
issue = Issue.find(1)
|
||||
assert_nil issue.custom_value_for(field)
|
||||
assert issue.available_custom_fields.include?(field)
|
||||
# No change to custom values, issue can be saved
|
||||
assert issue.save
|
||||
# Blank value
|
||||
issue.custom_field_values = { field.id => '' }
|
||||
assert !issue.save
|
||||
# Valid value
|
||||
issue.custom_field_values = { field.id => 'PostgreSQL' }
|
||||
assert issue.save
|
||||
issue.reload
|
||||
assert_equal 'PostgreSQL', issue.custom_value_for(field).value
|
||||
end
|
||||
|
||||
def test_should_not_update_attributes_if_custom_fields_validation_fails
|
||||
issue = Issue.find(1)
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
assert issue.available_custom_fields.include?(field)
|
||||
|
||||
issue.custom_field_values = { field.id => 'Invalid' }
|
||||
issue.subject = 'Should be not be saved'
|
||||
assert !issue.save
|
||||
|
||||
issue.reload
|
||||
assert_equal "Can't print recipes", issue.subject
|
||||
end
|
||||
|
||||
def test_should_not_recreate_custom_values_objects_on_update
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
|
||||
issue = Issue.find(1)
|
||||
issue.custom_field_values = { field.id => 'PostgreSQL' }
|
||||
assert issue.save
|
||||
custom_value = issue.custom_value_for(field)
|
||||
issue.reload
|
||||
issue.custom_field_values = { field.id => 'MySQL' }
|
||||
assert issue.save
|
||||
issue.reload
|
||||
assert_equal custom_value.id, issue.custom_value_for(field).id
|
||||
end
|
||||
|
||||
def test_category_based_assignment
|
||||
issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
|
||||
assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
|
||||
@@ -42,7 +118,7 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert_equal orig.custom_values.first.value, issue.custom_values.first.value
|
||||
end
|
||||
|
||||
def test_close_duplicates
|
||||
def test_should_close_duplicates
|
||||
# Create 3 issues
|
||||
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
||||
assert issue1.save
|
||||
@@ -52,12 +128,12 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert issue3.save
|
||||
|
||||
# 2 is a dupe of 1
|
||||
IssueRelation.create(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
# And 3 is a dupe of 2
|
||||
IssueRelation.create(:issue_from => issue2, :issue_to => issue3, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
IssueRelation.create(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
# And 3 is a dupe of 1 (circular duplicates)
|
||||
IssueRelation.create(:issue_from => issue1, :issue_to => issue3, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
|
||||
IssueRelation.create(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
|
||||
assert issue1.reload.duplicates.include?(issue2)
|
||||
|
||||
# Closing issue 1
|
||||
@@ -69,17 +145,46 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert issue3.reload.closed?
|
||||
end
|
||||
|
||||
def test_move_to_another_project
|
||||
def test_should_not_close_duplicated_issue
|
||||
# Create 3 issues
|
||||
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
||||
assert issue1.save
|
||||
issue2 = issue1.clone
|
||||
assert issue2.save
|
||||
|
||||
# 2 is a dupe of 1
|
||||
IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
# 2 is a dup of 1 but 1 is not a duplicate of 2
|
||||
assert !issue2.reload.duplicates.include?(issue1)
|
||||
|
||||
# Closing issue 2
|
||||
issue2.init_journal(User.find(:first), "Closing issue2")
|
||||
issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
|
||||
assert issue2.save
|
||||
# 1 should not be also closed
|
||||
assert !issue1.reload.closed?
|
||||
end
|
||||
|
||||
def test_move_to_another_project_with_same_category
|
||||
issue = Issue.find(1)
|
||||
assert issue.move_to(Project.find(2))
|
||||
issue.reload
|
||||
assert_equal 2, issue.project_id
|
||||
# Category removed
|
||||
assert_nil issue.category
|
||||
# Category changes
|
||||
assert_equal 4, issue.category_id
|
||||
# Make sure time entries were move to the target project
|
||||
assert_equal 2, issue.time_entries.first.project_id
|
||||
end
|
||||
|
||||
def test_move_to_another_project_without_same_category
|
||||
issue = Issue.find(2)
|
||||
assert issue.move_to(Project.find(2))
|
||||
issue.reload
|
||||
assert_equal 2, issue.project_id
|
||||
# Category cleared
|
||||
assert_nil issue.category_id
|
||||
end
|
||||
|
||||
def test_issue_destroy
|
||||
Issue.find(1).destroy
|
||||
assert_nil Issue.find_by_id(1)
|
||||
|
||||
@@ -18,40 +18,111 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class MailHandlerTest < Test::Unit::TestCase
|
||||
fixtures :users, :projects, :enabled_modules, :roles, :members, :issues, :trackers, :enumerations
|
||||
fixtures :users, :projects,
|
||||
:enabled_modules,
|
||||
:roles,
|
||||
:members,
|
||||
:issues,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:enumerations,
|
||||
:issue_categories
|
||||
|
||||
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
|
||||
|
||||
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures'
|
||||
CHARSET = "utf-8"
|
||||
|
||||
include ActionMailer::Quoting
|
||||
|
||||
def setup
|
||||
ActionMailer::Base.delivery_method = :test
|
||||
ActionMailer::Base.perform_deliveries = true
|
||||
ActionMailer::Base.deliveries = []
|
||||
|
||||
@expected = TMail::Mail.new
|
||||
@expected.set_content_type "text", "plain", { "charset" => CHARSET }
|
||||
@expected.mime_version = '1.0'
|
||||
ActionMailer::Base.deliveries.clear
|
||||
end
|
||||
|
||||
def test_add_note_to_issue
|
||||
raw = read_fixture("add_note_to_issue.txt").join
|
||||
MailHandler.receive(raw)
|
||||
def test_add_issue
|
||||
# This email contains: 'Project: onlinestore'
|
||||
issue = submit_email('ticket_on_given_project.eml')
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'New ticket on a given project', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
||||
end
|
||||
|
||||
issue = Issue.find(2)
|
||||
journal = issue.journals.find(:first, :order => "created_on DESC")
|
||||
assert journal
|
||||
assert_equal User.find_by_mail("jsmith@somenet.foo"), journal.user
|
||||
assert_equal "Note added by mail", journal.notes
|
||||
def test_add_issue_with_status
|
||||
# This email contains: 'Project: onlinestore' and 'Status: Resolved'
|
||||
issue = submit_email('ticket_on_given_project.eml')
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal IssueStatus.find_by_name("Resolved"), issue.status
|
||||
end
|
||||
|
||||
def test_add_issue_with_attributes_override
|
||||
issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority')
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'New ticket on a given project', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal 'Feature request', issue.tracker.to_s
|
||||
assert_equal 'Stock management', issue.category.to_s
|
||||
assert_equal 'Urgent', issue.priority.to_s
|
||||
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
||||
end
|
||||
|
||||
def test_add_issue_with_partial_attributes_override
|
||||
issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker'])
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'New ticket on a given project', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal 'Feature request', issue.tracker.to_s
|
||||
assert_nil issue.category
|
||||
assert_equal 'High', issue.priority.to_s
|
||||
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
||||
end
|
||||
|
||||
def test_add_issue_with_attachment_to_specific_project
|
||||
issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'Ticket created by email with attachment', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal 'This is a new ticket with attachments', issue.description
|
||||
# Attachment properties
|
||||
assert_equal 1, issue.attachments.size
|
||||
assert_equal 'Paella.jpg', issue.attachments.first.filename
|
||||
assert_equal 'image/jpeg', issue.attachments.first.content_type
|
||||
assert_equal 10790, issue.attachments.first.filesize
|
||||
end
|
||||
|
||||
def test_add_issue_note
|
||||
journal = submit_email('ticket_reply.eml')
|
||||
assert journal.is_a?(Journal)
|
||||
assert_equal User.find_by_login('jsmith'), journal.user
|
||||
assert_equal Issue.find(2), journal.journalized
|
||||
assert_match /This is reply/, journal.notes
|
||||
end
|
||||
|
||||
def test_add_issue_note_with_status_change
|
||||
# This email contains: 'Status: Resolved'
|
||||
journal = submit_email('ticket_reply_with_status.eml')
|
||||
assert journal.is_a?(Journal)
|
||||
issue = Issue.find(journal.issue.id)
|
||||
assert_equal User.find_by_login('jsmith'), journal.user
|
||||
assert_equal Issue.find(2), journal.journalized
|
||||
assert_match /This is reply/, journal.notes
|
||||
assert_equal IssueStatus.find_by_name("Resolved"), issue.status
|
||||
end
|
||||
|
||||
private
|
||||
def read_fixture(action)
|
||||
IO.readlines("#{FIXTURES_PATH}/mail_handler/#{action}")
|
||||
end
|
||||
|
||||
def encode(subject)
|
||||
quoted_printable(subject, CHARSET)
|
||||
end
|
||||
|
||||
def submit_email(filename, options={})
|
||||
raw = IO.read(File.join(FIXTURES_PATH, filename))
|
||||
MailHandler.receive(raw, options)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ class MailerTest < Test::Unit::TestCase
|
||||
# link to a referenced ticket
|
||||
assert mail.body.include?('<a href="https://mydomain.foo/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
|
||||
# link to a changeset
|
||||
assert mail.body.include?('<a href="https://mydomain.foo/repositories/revision/ecookbook?rev=2" class="changeset" title="This commit fixes #1, #2 and references #1 & #3">r2</a>')
|
||||
assert mail.body.include?('<a href="https://mydomain.foo/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 & #3">r2</a>')
|
||||
end
|
||||
|
||||
# test mailer methods for each language
|
||||
@@ -116,4 +116,13 @@ class MailerTest < Test::Unit::TestCase
|
||||
assert Mailer.deliver_register(token)
|
||||
end
|
||||
end
|
||||
|
||||
def test_reminders
|
||||
ActionMailer::Base.deliveries.clear
|
||||
Mailer.reminders(:days => 42)
|
||||
assert_equal 1, ActionMailer::Base.deliveries.size
|
||||
mail = ActionMailer::Base.deliveries.last
|
||||
assert mail.bcc.include?('dlopper@somenet.foo')
|
||||
assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
begin
|
||||
require 'mocha'
|
||||
|
||||
class MercurialAdapterTest < Test::Unit::TestCase
|
||||
|
||||
TEMPLATES_DIR = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATES_DIR
|
||||
TEMPLATE_NAME = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_NAME
|
||||
TEMPLATE_EXTENSION = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_EXTENSION
|
||||
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/mercurial_repository'
|
||||
|
||||
def test_hgversion
|
||||
to_test = { "0.9.5" => [0,9,5],
|
||||
"1.0" => [1,0],
|
||||
"1e4ddc9ac9f7+20080325" => nil,
|
||||
"1.0.1+20080525" => [1,0,1],
|
||||
"1916e629a29d" => nil}
|
||||
|
||||
to_test.each do |s, v|
|
||||
test_hgversion_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_template_path
|
||||
to_test = { [0,9,5] => "0.9.5",
|
||||
[1,0] => "1.0",
|
||||
[] => "1.0",
|
||||
[1,0,1] => "1.0"}
|
||||
|
||||
to_test.each do |v, template|
|
||||
test_template_path_for(v, template)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_hgversion_for(hgversion, version)
|
||||
Redmine::Scm::Adapters::MercurialAdapter.expects(:hgversion_from_command_line).returns(hgversion)
|
||||
adapter = Redmine::Scm::Adapters::MercurialAdapter
|
||||
assert_equal version, adapter.hgversion
|
||||
end
|
||||
|
||||
def test_template_path_for(version, template)
|
||||
adapter = Redmine::Scm::Adapters::MercurialAdapter
|
||||
assert_equal "#{TEMPLATES_DIR}/#{TEMPLATE_NAME}-#{template}.#{TEMPLATE_EXTENSION}", adapter.template_path_for(version)
|
||||
assert File.exist?(adapter.template_path_for(version))
|
||||
end
|
||||
end
|
||||
|
||||
rescue LoadError
|
||||
def test_fake; assert(false, "Requires mocha to run those tests") end
|
||||
end
|
||||
@@ -101,7 +101,7 @@ class ProjectTest < Test::Unit::TestCase
|
||||
assert sub.save
|
||||
assert_equal @ecookbook.id, sub.parent.id
|
||||
@ecookbook.reload
|
||||
assert_equal 3, @ecookbook.children.size
|
||||
assert_equal 4, @ecookbook.children.size
|
||||
end
|
||||
|
||||
def test_subproject_invalid
|
||||
@@ -118,6 +118,7 @@ class ProjectTest < Test::Unit::TestCase
|
||||
|
||||
def test_rolled_up_trackers
|
||||
parent = Project.find(1)
|
||||
parent.trackers = Tracker.find([1,2])
|
||||
child = parent.children.find(3)
|
||||
|
||||
assert_equal [1, 2], parent.tracker_ids
|
||||
|
||||
@@ -20,15 +20,109 @@ require File.dirname(__FILE__) + '/../test_helper'
|
||||
class QueryTest < Test::Unit::TestCase
|
||||
fixtures :projects, :users, :members, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries
|
||||
|
||||
def test_custom_fields_for_all_projects_should_be_available_in_global_queries
|
||||
query = Query.new(:project => nil, :name => '_')
|
||||
assert query.available_filters.has_key?('cf_1')
|
||||
assert !query.available_filters.has_key?('cf_3')
|
||||
end
|
||||
|
||||
def find_issues_with_query(query)
|
||||
Issue.find :all,
|
||||
:include => [ :assigned_to, :status, :tracker, :project, :priority ],
|
||||
:conditions => query.statement
|
||||
end
|
||||
|
||||
def test_query_with_multiple_custom_fields
|
||||
query = Query.find(1)
|
||||
assert query.valid?
|
||||
assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
|
||||
issues = Issue.find :all,:include => [ :assigned_to, :status, :tracker, :project, :priority ], :conditions => query.statement
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal 1, issues.length
|
||||
assert_equal Issue.find(3), issues.first
|
||||
end
|
||||
|
||||
def test_operator_none
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('fixed_version_id', '!*', [''])
|
||||
query.add_filter('cf_1', '!*', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
|
||||
assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_none_for_integer
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('estimated_hours', '!*', [''])
|
||||
issues = find_issues_with_query(query)
|
||||
assert !issues.empty?
|
||||
assert issues.all? {|i| !i.estimated_hours}
|
||||
end
|
||||
|
||||
def test_operator_all
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('fixed_version_id', '*', [''])
|
||||
query.add_filter('cf_1', '*', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
|
||||
assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_greater_than
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('done_ratio', '>=', ['40'])
|
||||
assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_in_more_than
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', '>t+', ['15'])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date >=")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_in_less_than
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', '<t+', ['15'])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_today
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 't', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_this_week_on_date
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'w', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_this_week_on_datetime
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('created_on', 'w', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.created_on BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_contains
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('subject', '~', ['string'])
|
||||
assert query.statement.include?("#{Issue.table_name}.subject LIKE '%string%'")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_does_not_contains
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('subject', '!~', ['string'])
|
||||
assert query.statement.include?("#{Issue.table_name}.subject NOT LIKE '%string%'")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_default_columns
|
||||
q = Query.new
|
||||
assert !q.columns.empty?
|
||||
@@ -42,6 +136,11 @@ class QueryTest < Test::Unit::TestCase
|
||||
assert q.has_column?(c)
|
||||
end
|
||||
|
||||
def test_label_for
|
||||
q = Query.new
|
||||
assert_equal 'assigned_to', q.label_for('assigned_to_id')
|
||||
end
|
||||
|
||||
def test_editable_by
|
||||
admin = User.find(1)
|
||||
manager = User.find(2)
|
||||
|
||||
@@ -22,7 +22,7 @@ class RepositoryCvsTest < Test::Unit::TestCase
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository'
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if RUBY_PLATFORM =~ /mswin/
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
# CVS module
|
||||
MODULE_NAME = 'test'
|
||||
|
||||
|
||||
@@ -48,6 +48,13 @@ class RepositoryDarcsTest < Test::Unit::TestCase
|
||||
@repository.fetch_changesets
|
||||
assert_equal 6, @repository.changesets.count
|
||||
end
|
||||
|
||||
def test_cat
|
||||
@repository.fetch_changesets
|
||||
cat = @repository.cat("sources/welcome_controller.rb", 2)
|
||||
assert_not_nil cat
|
||||
assert cat.include?('class WelcomeController < ApplicationController')
|
||||
end
|
||||
else
|
||||
puts "Darcs test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# 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 RepositoryFilesystemTest < Test::Unit::TestCase
|
||||
fixtures :projects
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
|
||||
assert @repository = Repository::Filesystem.create(:project => @project, :url => REPOSITORY_PATH)
|
||||
end
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def test_fetch_changesets
|
||||
@repository.fetch_changesets
|
||||
@repository.reload
|
||||
|
||||
assert_equal 0, @repository.changesets.count
|
||||
assert_equal 0, @repository.changes.count
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_equal 2, @repository.entries("", 2).size
|
||||
assert_equal 2, @repository.entries("dir", 3).size
|
||||
end
|
||||
|
||||
def test_cat
|
||||
assert_equal "TEST CAT\n", @repository.scm.cat("test")
|
||||
end
|
||||
|
||||
else
|
||||
puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
||||
@@ -22,7 +22,7 @@ class RepositoryGitTest < Test::Unit::TestCase
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if RUBY_PLATFORM =~ /mswin/
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
|
||||
@@ -48,6 +48,26 @@ class RepositoryMercurialTest < Test::Unit::TestCase
|
||||
@repository.fetch_changesets
|
||||
assert_equal 6, @repository.changesets.count
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_equal 2, @repository.entries("sources", 2).size
|
||||
assert_equal 1, @repository.entries("sources", 3).size
|
||||
end
|
||||
|
||||
def test_locate_on_outdated_repository
|
||||
# Change the working dir state
|
||||
%x{hg -R #{REPOSITORY_PATH} up -r 0}
|
||||
assert_equal 1, @repository.entries("images", 0).size
|
||||
assert_equal 2, @repository.entries("images").size
|
||||
assert_equal 2, @repository.entries("images", 2).size
|
||||
end
|
||||
|
||||
|
||||
def test_cat
|
||||
assert @repository.scm.cat("sources/welcome_controller.rb", 2)
|
||||
assert_nil @repository.scm.cat("sources/welcome_controller.rb")
|
||||
end
|
||||
|
||||
else
|
||||
puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
|
||||
@@ -45,6 +45,26 @@ class RepositoryTest < Test::Unit::TestCase
|
||||
assert_equal repository, project.repository
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
changesets = Changeset.count(:all, :conditions => "repository_id = 10")
|
||||
changes = Change.count(:all, :conditions => "repository_id = 10", :include => :changeset)
|
||||
assert_difference 'Changeset.count', -changesets do
|
||||
assert_difference 'Change.count', -changes do
|
||||
Repository.find(10).destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_create_with_disabled_scm
|
||||
# disable Subversion
|
||||
Setting.enabled_scm = ['Darcs', 'Git']
|
||||
repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost")
|
||||
assert !repository.save
|
||||
assert_equal :activerecord_error_invalid, repository.errors.on(:type)
|
||||
# re-enable Subversion for following tests
|
||||
Setting.delete_all
|
||||
end
|
||||
|
||||
def test_scan_changesets_for_issue_ids
|
||||
# choosing a status to apply to fix issues
|
||||
Setting.commit_fix_status_id = IssueStatus.find(:first, :conditions => ["is_closed = ?", true]).id
|
||||
|
||||
@@ -26,7 +26,7 @@ class RoleTest < Test::Unit::TestCase
|
||||
|
||||
target = Role.new(:name => 'Target')
|
||||
assert target.save
|
||||
assert target.workflows.copy(source)
|
||||
target.workflows.copy(source)
|
||||
target.reload
|
||||
assert_equal 90, target.workflows.size
|
||||
end
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 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 SearchTest < Test::Unit::TestCase
|
||||
fixtures :users,
|
||||
:members,
|
||||
:projects,
|
||||
:roles,
|
||||
:enabled_modules,
|
||||
:issues,
|
||||
:trackers,
|
||||
:journals,
|
||||
:journal_details,
|
||||
:repositories,
|
||||
:changesets
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
@issue_keyword = '%unable to print recipes%'
|
||||
@issue = Issue.find(1)
|
||||
@changeset_keyword = '%very first commit%'
|
||||
@changeset = Changeset.find(100)
|
||||
end
|
||||
|
||||
def test_search_by_anonymous
|
||||
User.current = nil
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
|
||||
# Removes the :view_changesets permission from Anonymous role
|
||||
remove_permission Role.anonymous, :view_changesets
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert !r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_by_user
|
||||
User.current = User.find_by_login('rhill')
|
||||
assert User.current.memberships.empty?
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
|
||||
# Removes the :view_changesets permission from Non member role
|
||||
remove_permission Role.non_member, :view_changesets
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert !r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_by_allowed_member
|
||||
User.current = User.find_by_login('jsmith')
|
||||
assert User.current.projects.include?(@project)
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_by_unallowed_member
|
||||
# Removes the :view_changesets permission from user's and non member role
|
||||
remove_permission Role.find(1), :view_changesets
|
||||
remove_permission Role.non_member, :view_changesets
|
||||
|
||||
User.current = User.find_by_login('jsmith')
|
||||
assert User.current.projects.include?(@project)
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_issue_with_multiple_hits_in_journals
|
||||
i = Issue.find(1)
|
||||
assert_equal 2, i.journals.count(:all, :conditions => "notes LIKE '%notes%'")
|
||||
|
||||
r = Issue.search('%notes%').first
|
||||
assert_equal 1, r.size
|
||||
assert_equal i, r.first
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def remove_permission(role, permission)
|
||||
role.permissions = role.permissions - [ permission ]
|
||||
role.save
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 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 'mkmf'
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class SubversionAdapterTest < Test::Unit::TestCase
|
||||
|
||||
if find_executable0('svn')
|
||||
def test_client_version
|
||||
v = Redmine::Scm::Adapters::SubversionAdapter.client_version
|
||||
assert v.is_a?(Array)
|
||||
end
|
||||
else
|
||||
puts "Subversion binary NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
||||
@@ -26,7 +26,7 @@ class TrackerTest < Test::Unit::TestCase
|
||||
|
||||
target = Tracker.new(:name => 'Target')
|
||||
assert target.save
|
||||
assert target.workflows.copy(source)
|
||||
target.workflows.copy(source)
|
||||
target.reload
|
||||
assert_equal 89, target.workflows.size
|
||||
end
|
||||
|
||||
@@ -57,6 +57,12 @@ class UserTest < Test::Unit::TestCase
|
||||
assert_equal "john", @admin.login
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
User.find(2).destroy
|
||||
assert_nil User.find_by_id(2)
|
||||
assert Member.find_all_by_principal_type_and_principal_id('User', 2).empty?
|
||||
end
|
||||
|
||||
def test_validate
|
||||
@admin.login = ""
|
||||
assert !@admin.save
|
||||
|
||||
@@ -48,6 +48,50 @@ class WikiPageTest < Test::Unit::TestCase
|
||||
assert page.new_record?
|
||||
end
|
||||
|
||||
def test_parent_title
|
||||
page = WikiPage.find_by_title('Another_page')
|
||||
assert_nil page.parent_title
|
||||
|
||||
page = WikiPage.find_by_title('Page_with_an_inline_image')
|
||||
assert_equal 'CookBook documentation', page.parent_title
|
||||
end
|
||||
|
||||
def test_assign_parent
|
||||
page = WikiPage.find_by_title('Another_page')
|
||||
page.parent_title = 'CookBook documentation'
|
||||
assert page.save
|
||||
page.reload
|
||||
assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent
|
||||
end
|
||||
|
||||
def test_unassign_parent
|
||||
page = WikiPage.find_by_title('Page_with_an_inline_image')
|
||||
page.parent_title = ''
|
||||
assert page.save
|
||||
page.reload
|
||||
assert_nil page.parent
|
||||
end
|
||||
|
||||
def test_parent_validation
|
||||
page = WikiPage.find_by_title('CookBook_documentation')
|
||||
|
||||
# A page that doesn't exist
|
||||
page.parent_title = 'Unknown title'
|
||||
assert !page.save
|
||||
assert_equal :activerecord_error_invalid, page.errors.on(:parent_title)
|
||||
# A child page
|
||||
page.parent_title = 'Page_with_an_inline_image'
|
||||
assert !page.save
|
||||
assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title)
|
||||
# The page itself
|
||||
page.parent_title = 'CookBook_documentation'
|
||||
assert !page.save
|
||||
assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title)
|
||||
|
||||
page.parent_title = 'Another_page'
|
||||
assert page.save
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
page = WikiPage.find(1)
|
||||
page.destroy
|
||||
|
||||
Reference in New Issue
Block a user