Redmine 3.4.4
This commit is contained in:
commit
64924a6376
2112 changed files with 259028 additions and 0 deletions
59
test/unit/lib/redmine/access_control_test.rb
Normal file
59
test/unit/lib/redmine/access_control_test.rb
Normal file
|
@ -0,0 +1,59 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::AccessControlTest < ActiveSupport::TestCase
|
||||
|
||||
def setup
|
||||
@access_module = Redmine::AccessControl
|
||||
end
|
||||
|
||||
def test_permissions
|
||||
perms = @access_module.permissions
|
||||
assert perms.is_a?(Array)
|
||||
assert perms.first.is_a?(Redmine::AccessControl::Permission)
|
||||
end
|
||||
|
||||
def test_module_permission
|
||||
perm = @access_module.permission(:view_issues)
|
||||
assert perm.is_a?(Redmine::AccessControl::Permission)
|
||||
assert_equal :view_issues, perm.name
|
||||
assert_equal :issue_tracking, perm.project_module
|
||||
assert perm.actions.is_a?(Array)
|
||||
assert perm.actions.include?('issues/index')
|
||||
end
|
||||
|
||||
def test_no_module_permission
|
||||
perm = @access_module.permission(:edit_project)
|
||||
assert perm.is_a?(Redmine::AccessControl::Permission)
|
||||
assert_equal :edit_project, perm.name
|
||||
assert_nil perm.project_module
|
||||
assert perm.actions.is_a?(Array)
|
||||
assert perm.actions.include?('projects/settings')
|
||||
end
|
||||
|
||||
def test_read_action_should_return_true_for_read_actions
|
||||
assert_equal true, @access_module.read_action?(:view_project)
|
||||
assert_equal true, @access_module.read_action?(:controller => 'projects', :action => 'show')
|
||||
end
|
||||
|
||||
def test_read_action_should_return_false_for_update_actions
|
||||
assert_equal false, @access_module.read_action?(:edit_project)
|
||||
assert_equal false, @access_module.read_action?(:controller => 'projects', :action => 'edit')
|
||||
end
|
||||
end
|
53
test/unit/lib/redmine/acts/positioned_with_scope_test.rb
Normal file
53
test/unit/lib/redmine/acts/positioned_with_scope_test.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Acts::PositionedWithScopeTest < ActiveSupport::TestCase
|
||||
fixtures :projects, :boards
|
||||
|
||||
def test_create_should_default_to_last_position
|
||||
b = Board.generate!(:project_id => 1)
|
||||
assert_equal 3, b.reload.position
|
||||
|
||||
b = Board.generate!(:project_id => 3)
|
||||
assert_equal 1, b.reload.position
|
||||
end
|
||||
|
||||
def test_create_should_insert_at_given_position
|
||||
b = Board.generate!(:project_id => 1, :position => 2)
|
||||
|
||||
assert_equal 2, b.reload.position
|
||||
assert_equal [1, 3, 1, 2], Board.order(:id).pluck(:position)
|
||||
end
|
||||
|
||||
def test_destroy_should_remove_position
|
||||
b = Board.generate!(:project_id => 1, :position => 2)
|
||||
b.destroy
|
||||
|
||||
assert_equal [1, 2, 1], Board.order(:id).pluck(:position)
|
||||
end
|
||||
|
||||
def test_update_should_update_positions
|
||||
b = Board.generate!(:project_id => 1)
|
||||
assert_equal 3, b.position
|
||||
|
||||
b.position = 2
|
||||
b.save!
|
||||
assert_equal [1, 3, 1, 2], Board.order(:id).pluck(:position)
|
||||
end
|
||||
end
|
55
test/unit/lib/redmine/acts/positioned_without_scope_test.rb
Normal file
55
test/unit/lib/redmine/acts/positioned_without_scope_test.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Acts::PositionedWithoutScopeTest < ActiveSupport::TestCase
|
||||
fixtures :trackers, :issue_statuses
|
||||
|
||||
def test_create_should_default_to_last_position
|
||||
t = Tracker.generate
|
||||
t.save!
|
||||
|
||||
assert_equal 4, t.reload.position
|
||||
end
|
||||
|
||||
def test_create_should_insert_at_given_position
|
||||
t = Tracker.generate
|
||||
t.position = 2
|
||||
t.save!
|
||||
|
||||
assert_equal 2, t.reload.position
|
||||
assert_equal [1, 3, 4, 2], Tracker.order(:id).pluck(:position)
|
||||
end
|
||||
|
||||
def test_destroy_should_remove_position
|
||||
t = Tracker.generate!
|
||||
Tracker.generate!
|
||||
t.destroy
|
||||
|
||||
assert_equal [1, 2, 3, 4], Tracker.order(:id).pluck(:position)
|
||||
end
|
||||
|
||||
def test_update_should_update_positions
|
||||
t = Tracker.generate!
|
||||
assert_equal 4, t.position
|
||||
|
||||
t.position = 2
|
||||
t.save!
|
||||
assert_equal [1, 3, 4, 2], Tracker.order(:id).pluck(:position)
|
||||
end
|
||||
end
|
106
test/unit/lib/redmine/ciphering_test.rb
Normal file
106
test/unit/lib/redmine/ciphering_test.rb
Normal file
|
@ -0,0 +1,106 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::CipheringTest < ActiveSupport::TestCase
|
||||
|
||||
def test_password_should_be_encrypted
|
||||
Redmine::Configuration.with 'database_cipher_key' => 'secret' do
|
||||
r = Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'svn')
|
||||
assert_equal 'foo', r.password
|
||||
assert r.read_attribute(:password).match(/\Aaes-256-cbc:.+\Z/)
|
||||
end
|
||||
end
|
||||
|
||||
def test_password_should_be_clear_with_blank_key
|
||||
Redmine::Configuration.with 'database_cipher_key' => '' do
|
||||
r = Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'svn')
|
||||
assert_equal 'foo', r.password
|
||||
assert_equal 'foo', r.read_attribute(:password)
|
||||
end
|
||||
end
|
||||
|
||||
def test_password_should_be_clear_with_nil_key
|
||||
Redmine::Configuration.with 'database_cipher_key' => nil do
|
||||
r = Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'svn')
|
||||
assert_equal 'foo', r.password
|
||||
assert_equal 'foo', r.read_attribute(:password)
|
||||
end
|
||||
end
|
||||
|
||||
def test_blank_password_should_be_clear
|
||||
Redmine::Configuration.with 'database_cipher_key' => 'secret' do
|
||||
r = Repository::Subversion.create!(:password => '', :url => 'file:///tmp', :identifier => 'svn')
|
||||
assert_equal '', r.password
|
||||
assert_equal '', r.read_attribute(:password)
|
||||
end
|
||||
end
|
||||
|
||||
def test_unciphered_password_should_be_readable
|
||||
Redmine::Configuration.with 'database_cipher_key' => nil do
|
||||
r = Repository::Subversion.create!(:password => 'clear', :url => 'file:///tmp', :identifier => 'svn')
|
||||
end
|
||||
|
||||
Redmine::Configuration.with 'database_cipher_key' => 'secret' do
|
||||
r = Repository.order('id DESC').first
|
||||
assert_equal 'clear', r.password
|
||||
end
|
||||
end
|
||||
|
||||
def test_ciphered_password_with_no_cipher_key_configured_should_be_returned_ciphered
|
||||
Redmine::Configuration.with 'database_cipher_key' => 'secret' do
|
||||
r = Repository::Subversion.create!(:password => 'clear', :url => 'file:///tmp', :identifier => 'svn')
|
||||
end
|
||||
|
||||
Redmine::Configuration.with 'database_cipher_key' => '' do
|
||||
r = Repository.order('id DESC').first
|
||||
# password can not be deciphered
|
||||
assert_nothing_raised do
|
||||
assert r.password.match(/\Aaes-256-cbc:.+\Z/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_encrypt_all
|
||||
Repository.delete_all
|
||||
Redmine::Configuration.with 'database_cipher_key' => nil do
|
||||
Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'foo')
|
||||
Repository::Subversion.create!(:password => 'bar', :url => 'file:///tmp', :identifier => 'bar')
|
||||
end
|
||||
|
||||
Redmine::Configuration.with 'database_cipher_key' => 'secret' do
|
||||
assert Repository.encrypt_all(:password)
|
||||
r = Repository.order('id DESC').first
|
||||
assert_equal 'bar', r.password
|
||||
assert r.read_attribute(:password).match(/\Aaes-256-cbc:.+\Z/)
|
||||
end
|
||||
end
|
||||
|
||||
def test_decrypt_all
|
||||
Repository.delete_all
|
||||
Redmine::Configuration.with 'database_cipher_key' => 'secret' do
|
||||
Repository::Subversion.create!(:password => 'foo', :url => 'file:///tmp', :identifier => 'foo')
|
||||
Repository::Subversion.create!(:password => 'bar', :url => 'file:///tmp', :identifier => 'bar')
|
||||
|
||||
assert Repository.decrypt_all(:password)
|
||||
r = Repository.order('id DESC').first
|
||||
assert_equal 'bar', r.password
|
||||
assert_equal 'bar', r.read_attribute(:password)
|
||||
end
|
||||
end
|
||||
end
|
104
test/unit/lib/redmine/codeset_util_test.rb
Normal file
104
test/unit/lib/redmine/codeset_util_test.rb
Normal file
|
@ -0,0 +1,104 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::CodesetUtilTest < ActiveSupport::TestCase
|
||||
|
||||
def test_to_utf8_by_setting_from_latin1
|
||||
with_settings :repositories_encodings => 'UTF-8,ISO-8859-1' do
|
||||
s1 = "Texte encod\xc3\xa9".force_encoding("UTF-8")
|
||||
s2 = "Texte encod\xe9".force_encoding("ASCII-8BIT")
|
||||
s3 = s2.dup.force_encoding("UTF-8")
|
||||
assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
|
||||
assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_utf8_by_setting_from_euc_jp
|
||||
with_settings :repositories_encodings => 'UTF-8,EUC-JP' do
|
||||
s1 = "\xe3\x83\xac\xe3\x83\x83\xe3\x83\x89\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xb3".force_encoding("UTF-8")
|
||||
s2 = "\xa5\xec\xa5\xc3\xa5\xc9\xa5\xde\xa5\xa4\xa5\xf3".force_encoding("ASCII-8BIT")
|
||||
s3 = s2.dup.force_encoding("UTF-8")
|
||||
assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
|
||||
assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_utf8_by_setting_should_be_converted_all_latin1
|
||||
with_settings :repositories_encodings => 'ISO-8859-1' do
|
||||
s1 = "\xc3\x82\xc2\x80".force_encoding("UTF-8")
|
||||
s2 = "\xC2\x80".force_encoding("ASCII-8BIT")
|
||||
s3 = s2.dup.force_encoding("UTF-8")
|
||||
assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s2)
|
||||
assert_equal s1, Redmine::CodesetUtil.to_utf8_by_setting(s3)
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_utf8_by_setting_blank_string
|
||||
assert_equal "", Redmine::CodesetUtil.to_utf8_by_setting("")
|
||||
assert_nil Redmine::CodesetUtil.to_utf8_by_setting(nil)
|
||||
end
|
||||
|
||||
def test_to_utf8_by_setting_returns_ascii_as_utf8
|
||||
s1 = "ASCII".force_encoding("UTF-8")
|
||||
s2 = s1.dup.force_encoding("ISO-8859-1")
|
||||
str1 = Redmine::CodesetUtil.to_utf8_by_setting(s1)
|
||||
str2 = Redmine::CodesetUtil.to_utf8_by_setting(s2)
|
||||
assert_equal s1, str1
|
||||
assert_equal s1, str2
|
||||
assert_equal "UTF-8", str1.encoding.to_s
|
||||
assert_equal "UTF-8", str2.encoding.to_s
|
||||
end
|
||||
|
||||
def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped
|
||||
with_settings :repositories_encodings => '' do
|
||||
# s1 = File.read("#{RAILS_ROOT}/test/fixtures/encoding/iso-8859-1.txt")
|
||||
s1 = "Texte encod\xe9 en ISO-8859-1.".force_encoding("ASCII-8BIT")
|
||||
str = Redmine::CodesetUtil.to_utf8_by_setting(s1)
|
||||
assert str.valid_encoding?
|
||||
assert_equal "UTF-8", str.encoding.to_s
|
||||
assert_equal "Texte encod? en ISO-8859-1.", str
|
||||
end
|
||||
end
|
||||
|
||||
def test_to_utf8_by_setting_invalid_utf8_sequences_should_be_stripped_ja_jis
|
||||
with_settings :repositories_encodings => 'ISO-2022-JP' do
|
||||
s1 = "test\xb5\xfetest\xb5\xfe".force_encoding("ASCII-8BIT")
|
||||
str = Redmine::CodesetUtil.to_utf8_by_setting(s1)
|
||||
assert str.valid_encoding?
|
||||
assert_equal "UTF-8", str.encoding.to_s
|
||||
assert_equal "test??test??", str
|
||||
end
|
||||
end
|
||||
|
||||
test "#replace_invalid_utf8 should replace invalid utf8" do
|
||||
s1 = "\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1\xE3\x81\xFF".force_encoding("UTF-8")
|
||||
s2 = Redmine::CodesetUtil.replace_invalid_utf8(s1)
|
||||
assert s2.valid_encoding?
|
||||
assert_equal "UTF-8", s2.encoding.to_s
|
||||
assert_equal "\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1??".force_encoding("UTF-8"), s2
|
||||
end
|
||||
|
||||
test "#to_utf8 should replace invalid non utf8" do
|
||||
s1 = "\xa4\xb3\xa4\xf3\xa4\xcb\xa4\xc1\xa4".force_encoding("EUC-JP")
|
||||
s2 = Redmine::CodesetUtil.to_utf8(s1, "EUC-JP")
|
||||
assert s2.valid_encoding?
|
||||
assert_equal "UTF-8", s2.encoding.to_s
|
||||
assert_equal "\xe3\x81\x93\xe3\x82\x93\xe3\x81\xab\xe3\x81\xa1?".force_encoding("UTF-8"), s2
|
||||
end
|
||||
end
|
61
test/unit/lib/redmine/configuration_test.rb
Normal file
61
test/unit/lib/redmine/configuration_test.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::ConfigurationTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
@conf = Redmine::Configuration
|
||||
end
|
||||
|
||||
def test_empty
|
||||
assert_kind_of Hash, load_conf('empty.yml', 'test')
|
||||
end
|
||||
|
||||
def test_default
|
||||
assert_kind_of Hash, load_conf('default.yml', 'test')
|
||||
assert_equal 'foo', @conf['somesetting']
|
||||
end
|
||||
|
||||
def test_no_default
|
||||
assert_kind_of Hash, load_conf('no_default.yml', 'test')
|
||||
assert_equal 'foo', @conf['somesetting']
|
||||
end
|
||||
|
||||
def test_overrides
|
||||
assert_kind_of Hash, load_conf('overrides.yml', 'test')
|
||||
assert_equal 'bar', @conf['somesetting']
|
||||
end
|
||||
|
||||
def test_with
|
||||
load_conf('default.yml', 'test')
|
||||
assert_equal 'foo', @conf['somesetting']
|
||||
@conf.with 'somesetting' => 'bar' do
|
||||
assert_equal 'bar', @conf['somesetting']
|
||||
end
|
||||
assert_equal 'foo', @conf['somesetting']
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_conf(file, env)
|
||||
@conf.load(
|
||||
:file => File.join(Rails.root, 'test', 'fixtures', 'configuration', file),
|
||||
:env => env
|
||||
)
|
||||
end
|
||||
end
|
31
test/unit/lib/redmine/export/csv_test.rb
Normal file
31
test/unit/lib/redmine/export/csv_test.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class CsvTest < ActiveSupport::TestCase
|
||||
|
||||
BOM = "\xEF\xBB\xBF".force_encoding('UTF-8')
|
||||
|
||||
def test_should_include_bom_when_utf8_encoded
|
||||
with_locale 'sk' do
|
||||
string = Redmine::Export::CSV.generate {|csv| csv << %w(Foo Bar)}
|
||||
assert_equal 'UTF-8', string.encoding.name
|
||||
assert string.starts_with?(BOM)
|
||||
end
|
||||
end
|
||||
end
|
104
test/unit/lib/redmine/export/pdf_test.rb
Normal file
104
test/unit/lib/redmine/export/pdf_test.rb
Normal file
|
@ -0,0 +1,104 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class PdfTest < ActiveSupport::TestCase
|
||||
fixtures :users, :projects, :roles, :members, :member_roles,
|
||||
:enabled_modules, :issues, :trackers, :attachments
|
||||
|
||||
def test_fix_text_encoding_nil
|
||||
assert_equal '', Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(nil, "UTF-8")
|
||||
assert_equal '', Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(nil, "ISO-8859-1")
|
||||
end
|
||||
|
||||
def test_rdm_pdf_iconv_cannot_convert_ja_cp932
|
||||
utf8_txt_1 = "\xe7\x8b\x80\xe6\x85\x8b"
|
||||
utf8_txt_2 = "\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80"
|
||||
utf8_txt_3 = "\xe7\x8b\x80\xe7\x8b\x80\xe6\x85\x8b\xe7\x8b\x80"
|
||||
["CP932", "SJIS"].each do |encoding|
|
||||
txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_1, encoding)
|
||||
txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_2, encoding)
|
||||
txt_3 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(utf8_txt_3, encoding)
|
||||
assert_equal "?\x91\xd4".force_encoding("ASCII-8BIT"), txt_1
|
||||
assert_equal "?\x91\xd4?".force_encoding("ASCII-8BIT"), txt_2
|
||||
assert_equal "??\x91\xd4?".force_encoding("ASCII-8BIT"), txt_3
|
||||
assert_equal "ASCII-8BIT", txt_1.encoding.to_s
|
||||
assert_equal "ASCII-8BIT", txt_2.encoding.to_s
|
||||
assert_equal "ASCII-8BIT", txt_3.encoding.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_en
|
||||
str1 = "Texte encod\xe9 en ISO-8859-1".force_encoding("UTF-8")
|
||||
str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test".force_encoding("ASCII-8BIT")
|
||||
txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, 'UTF-8')
|
||||
txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, 'UTF-8')
|
||||
assert_equal "ASCII-8BIT", txt_1.encoding.to_s
|
||||
assert_equal "ASCII-8BIT", txt_2.encoding.to_s
|
||||
assert_equal "Texte encod? en ISO-8859-1", txt_1
|
||||
assert_equal "?a?b?c?d?e test", txt_2
|
||||
end
|
||||
|
||||
def test_rdm_pdf_iconv_invalid_utf8_should_be_replaced_ja
|
||||
str1 = "Texte encod\xe9 en ISO-8859-1".force_encoding("UTF-8")
|
||||
str2 = "\xe9a\xe9b\xe9c\xe9d\xe9e test".force_encoding("ASCII-8BIT")
|
||||
encoding = ( RUBY_PLATFORM == 'java' ? "SJIS" : "CP932" )
|
||||
txt_1 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str1, encoding)
|
||||
txt_2 = Redmine::Export::PDF::RDMPdfEncoding::rdm_from_utf8(str2, encoding)
|
||||
assert_equal "ASCII-8BIT", txt_1.encoding.to_s
|
||||
assert_equal "ASCII-8BIT", txt_2.encoding.to_s
|
||||
assert_equal "Texte encod? en ISO-8859-1", txt_1
|
||||
assert_equal "?a?b?c?d?e test", txt_2
|
||||
end
|
||||
|
||||
def test_attach
|
||||
["CP932", "SJIS"].each do |encoding|
|
||||
set_fixtures_attachments_directory
|
||||
|
||||
str2 = "\x83e\x83X\x83g".force_encoding("ASCII-8BIT")
|
||||
|
||||
a1 = Attachment.find(17)
|
||||
a2 = Attachment.find(19)
|
||||
User.current = User.find(1)
|
||||
assert a1.readable?
|
||||
assert a1.visible?
|
||||
assert a2.readable?
|
||||
assert a2.visible?
|
||||
|
||||
aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8")
|
||||
assert_not_nil aa1
|
||||
assert_equal 17, aa1.id
|
||||
|
||||
aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding)
|
||||
assert_not_nil aa2
|
||||
assert_equal 19, aa2.id
|
||||
|
||||
User.current = nil
|
||||
assert a1.readable?
|
||||
assert (! a1.visible?)
|
||||
assert a2.readable?
|
||||
assert (! a2.visible?)
|
||||
aa1 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "Testfile.PNG", "UTF-8")
|
||||
assert_nil aa1
|
||||
aa2 = Redmine::Export::PDF::RDMPdfEncoding::attach(Attachment.all, "test#{str2}.png", encoding)
|
||||
assert_nil aa2
|
||||
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
end
|
||||
end
|
163
test/unit/lib/redmine/field_format/attachment_format_test.rb
Normal file
163
test/unit/lib/redmine/field_format/attachment_format_test.rb
Normal file
|
@ -0,0 +1,163 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::AttachmentFieldFormatTest < ActionView::TestCase
|
||||
include ApplicationHelper
|
||||
include Redmine::I18n
|
||||
|
||||
fixtures :users
|
||||
|
||||
def setup
|
||||
set_language_if_valid 'en'
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
def test_should_accept_a_hash_with_upload_on_create
|
||||
field = GroupCustomField.generate!(:name => "File", :field_format => 'attachment')
|
||||
group = Group.new(:name => 'Group')
|
||||
attachment = nil
|
||||
|
||||
custom_value = new_record(CustomValue) do
|
||||
attachment = new_record(Attachment) do
|
||||
group.custom_field_values = {field.id => {:file => mock_file}}
|
||||
assert group.save
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal 'a_file.png', attachment.filename
|
||||
assert_equal custom_value, attachment.container
|
||||
assert_equal field, attachment.container.custom_field
|
||||
assert_equal group, attachment.container.customized
|
||||
end
|
||||
|
||||
def test_should_accept_a_hash_with_no_upload_on_create
|
||||
field = GroupCustomField.generate!(:name => "File", :field_format => 'attachment')
|
||||
group = Group.new(:name => 'Group')
|
||||
attachment = nil
|
||||
|
||||
custom_value = new_record(CustomValue) do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
group.custom_field_values = {field.id => {}}
|
||||
assert group.save
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal '', custom_value.value
|
||||
end
|
||||
|
||||
def test_should_not_validate_with_invalid_upload_on_create
|
||||
field = GroupCustomField.generate!(:name => "File", :field_format => 'attachment')
|
||||
group = Group.new(:name => 'Group')
|
||||
|
||||
with_settings :attachment_max_size => 0 do
|
||||
assert_no_difference 'CustomValue.count' do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
group.custom_field_values = {field.id => {:file => mock_file}}
|
||||
assert_equal false, group.save
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_accept_a_hash_with_token_on_create
|
||||
field = GroupCustomField.generate!(:name => "File", :field_format => 'attachment')
|
||||
group = Group.new(:name => 'Group')
|
||||
|
||||
attachment = Attachment.create!(:file => mock_file, :author => User.find(2))
|
||||
assert_nil attachment.container
|
||||
|
||||
custom_value = new_record(CustomValue) do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
group.custom_field_values = {field.id => {:token => attachment.token}}
|
||||
assert group.save
|
||||
end
|
||||
end
|
||||
|
||||
attachment.reload
|
||||
assert_equal custom_value, attachment.container
|
||||
assert_equal field, attachment.container.custom_field
|
||||
assert_equal group, attachment.container.customized
|
||||
end
|
||||
|
||||
def test_should_not_validate_with_invalid_token_on_create
|
||||
field = GroupCustomField.generate!(:name => "File", :field_format => 'attachment')
|
||||
group = Group.new(:name => 'Group')
|
||||
|
||||
assert_no_difference 'CustomValue.count' do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
group.custom_field_values = {field.id => {:token => "123.0123456789abcdef"}}
|
||||
assert_equal false, group.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_replace_attachment_on_update
|
||||
field = GroupCustomField.generate!(:name => "File", :field_format => 'attachment')
|
||||
group = Group.new(:name => 'Group')
|
||||
attachment = nil
|
||||
custom_value = new_record(CustomValue) do
|
||||
attachment = new_record(Attachment) do
|
||||
group.custom_field_values = {field.id => {:file => mock_file}}
|
||||
assert group.save
|
||||
end
|
||||
end
|
||||
group.reload
|
||||
|
||||
assert_no_difference 'Attachment.count' do
|
||||
assert_no_difference 'CustomValue.count' do
|
||||
group.custom_field_values = {field.id => {:file => mock_file}}
|
||||
assert group.save
|
||||
end
|
||||
end
|
||||
|
||||
assert !Attachment.exists?(attachment.id)
|
||||
assert CustomValue.exists?(custom_value.id)
|
||||
|
||||
new_attachment = Attachment.order(:id => :desc).first
|
||||
custom_value.reload
|
||||
assert_equal custom_value, new_attachment.container
|
||||
end
|
||||
|
||||
def test_should_delete_attachment_on_update
|
||||
field = GroupCustomField.generate!(:name => "File", :field_format => 'attachment')
|
||||
group = Group.new(:name => 'Group')
|
||||
attachment = nil
|
||||
custom_value = new_record(CustomValue) do
|
||||
attachment = new_record(Attachment) do
|
||||
group.custom_field_values = {field.id => {:file => mock_file}}
|
||||
assert group.save
|
||||
end
|
||||
end
|
||||
group.reload
|
||||
|
||||
assert_difference 'Attachment.count', -1 do
|
||||
assert_no_difference 'CustomValue.count' do
|
||||
group.custom_field_values = {field.id => {}}
|
||||
assert group.save
|
||||
end
|
||||
end
|
||||
|
||||
assert !Attachment.exists?(attachment.id)
|
||||
assert CustomValue.exists?(custom_value.id)
|
||||
|
||||
custom_value.reload
|
||||
assert_equal '', custom_value.value
|
||||
end
|
||||
end
|
|
@ -0,0 +1,59 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class AttachmentFormatVisibilityTest < ActionView::TestCase
|
||||
fixtures :projects, :enabled_modules, :projects_trackers,
|
||||
:roles, :members, :member_roles,
|
||||
:users, :email_addresses,
|
||||
:trackers, :issue_statuses, :enumerations, :issue_categories,
|
||||
:versions, :issues
|
||||
|
||||
def setup
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
def test_attachment_should_be_visible_with_visible_custom_field
|
||||
field = IssueCustomField.generate!(:field_format => 'attachment', :visible => true)
|
||||
attachment = new_record(Attachment) do
|
||||
issue = Issue.generate
|
||||
issue.custom_field_values = {field.id => {:file => mock_file}}
|
||||
issue.save!
|
||||
end
|
||||
|
||||
assert attachment.visible?(manager = User.find(2))
|
||||
assert attachment.visible?(developer = User.find(3))
|
||||
assert attachment.visible?(non_member = User.find(7))
|
||||
assert attachment.visible?(User.anonymous)
|
||||
end
|
||||
|
||||
def test_attachment_should_be_visible_with_limited_visibility_custom_field
|
||||
field = IssueCustomField.generate!(:field_format => 'attachment', :visible => false, :role_ids => [1])
|
||||
attachment = new_record(Attachment) do
|
||||
issue = Issue.generate
|
||||
issue.custom_field_values = {field.id => {:file => mock_file}}
|
||||
issue.save!
|
||||
end
|
||||
|
||||
assert attachment.visible?(manager = User.find(2))
|
||||
assert !attachment.visible?(developer = User.find(3))
|
||||
assert !attachment.visible?(non_member = User.find(7))
|
||||
assert !attachment.visible?(User.anonymous)
|
||||
end
|
||||
end
|
63
test/unit/lib/redmine/field_format/bool_format_test.rb
Normal file
63
test/unit/lib/redmine/field_format/bool_format_test.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::BoolFieldFormatTest < ActionView::TestCase
|
||||
include ApplicationHelper
|
||||
include Redmine::I18n
|
||||
|
||||
def setup
|
||||
set_language_if_valid 'en'
|
||||
end
|
||||
|
||||
def test_check_box_style_should_render_edit_tag_as_check_box
|
||||
field = IssueCustomField.new(:field_format => 'bool', :is_required => false, :edit_tag_style => 'check_box')
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new)
|
||||
|
||||
tag = field.format.edit_tag(self, 'abc', 'xyz', value)
|
||||
assert_select_in tag, 'input[name=xyz]', 2
|
||||
assert_select_in tag, 'input[id=abc]', 1
|
||||
assert_select_in tag, 'input[type=hidden][value="0"]'
|
||||
assert_select_in tag, 'input[type=checkbox][value="1"]'
|
||||
end
|
||||
|
||||
def test_check_box_should_be_checked_when_value_is_set
|
||||
field = IssueCustomField.new(:field_format => 'bool', :is_required => false, :edit_tag_style => 'check_box')
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new, :value => '1')
|
||||
|
||||
tag = field.format.edit_tag(self, 'abc', 'xyz', value)
|
||||
assert_select_in tag, 'input[type=checkbox][value="1"][checked=checked]'
|
||||
end
|
||||
|
||||
def test_radio_style_should_render_edit_tag_as_radio_buttons
|
||||
field = IssueCustomField.new(:field_format => 'bool', :is_required => false, :edit_tag_style => 'radio')
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new)
|
||||
|
||||
tag = field.format.edit_tag(self, 'abc', 'xyz', value)
|
||||
assert_select_in tag, 'input[type=radio][name=xyz]', 3
|
||||
end
|
||||
|
||||
def test_default_style_should_render_edit_tag_as_select
|
||||
field = IssueCustomField.new(:field_format => 'bool', :is_required => false)
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new)
|
||||
|
||||
tag = field.format.edit_tag(self, 'abc', 'xyz', value)
|
||||
assert_select_in tag, 'select[name=xyz]', 1
|
||||
end
|
||||
end
|
100
test/unit/lib/redmine/field_format/enumeration_format_test.rb
Normal file
100
test/unit/lib/redmine/field_format/enumeration_format_test.rb
Normal file
|
@ -0,0 +1,100 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::EnumerationFieldFormatTest < ActionView::TestCase
|
||||
include ApplicationHelper
|
||||
|
||||
def setup
|
||||
set_language_if_valid 'en'
|
||||
@field = IssueCustomField.create!(:name => 'List', :field_format => 'enumeration', :is_required => false)
|
||||
@foo = CustomFieldEnumeration.new(:name => 'Foo')
|
||||
@bar = CustomFieldEnumeration.new(:name => 'Bar')
|
||||
@field.enumerations << @foo
|
||||
@field.enumerations << @bar
|
||||
end
|
||||
|
||||
def test_edit_tag_should_contain_possible_values
|
||||
value = CustomFieldValue.new(:custom_field => @field, :customized => Issue.new)
|
||||
|
||||
tag = @field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'select' do
|
||||
assert_select 'option', 3
|
||||
assert_select 'option[value=""]'
|
||||
assert_select 'option[value=?]', @foo.id.to_s, :text => 'Foo'
|
||||
assert_select 'option[value=?]', @bar.id.to_s, :text => 'Bar'
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_should_select_current_value
|
||||
value = CustomFieldValue.new(:custom_field => @field, :customized => Issue.new, :value => @bar.id.to_s)
|
||||
|
||||
tag = @field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'select' do
|
||||
assert_select 'option[selected=selected]', 1
|
||||
assert_select 'option[value=?][selected=selected]', @bar.id.to_s, :text => 'Bar'
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_with_multiple_should_select_current_values
|
||||
@field.multiple = true
|
||||
@field.save!
|
||||
value = CustomFieldValue.new(:custom_field => @field, :customized => Issue.new, :value => [@foo.id.to_s, @bar.id.to_s])
|
||||
|
||||
tag = @field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'select[multiple=multiple]' do
|
||||
assert_select 'option[selected=selected]', 2
|
||||
assert_select 'option[value=?][selected=selected]', @foo.id.to_s, :text => 'Foo'
|
||||
assert_select 'option[value=?][selected=selected]', @bar.id.to_s, :text => 'Bar'
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_with_check_box_style_should_contain_possible_values
|
||||
@field.edit_tag_style = 'check_box'
|
||||
@field.save!
|
||||
value = CustomFieldValue.new(:custom_field => @field, :customized => Issue.new)
|
||||
|
||||
tag = @field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'span' do
|
||||
assert_select 'input[type=radio]', 3
|
||||
assert_select 'label', :text => '(none)' do
|
||||
assert_select 'input[value=""]'
|
||||
end
|
||||
assert_select 'label', :text => 'Foo' do
|
||||
assert_select 'input[value=?]', @foo.id.to_s
|
||||
end
|
||||
assert_select 'label', :text => 'Bar' do
|
||||
assert_select 'input[value=?]', @bar.id.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_value_from_keyword_should_return_enumeration_id
|
||||
assert_equal @foo.id, @field.value_from_keyword('foo', nil)
|
||||
assert_nil @field.value_from_keyword('baz', nil)
|
||||
end
|
||||
|
||||
def test_value_from_keyword_for_multiple_custom_field_should_return_enumeration_ids
|
||||
@field.multiple = true
|
||||
@field.save!
|
||||
assert_equal [@foo.id, @bar.id], @field.value_from_keyword('foo, bar', nil)
|
||||
assert_equal [@foo.id], @field.value_from_keyword('foo, baz', nil)
|
||||
assert_equal [], @field.value_from_keyword('baz', nil)
|
||||
end
|
||||
end
|
101
test/unit/lib/redmine/field_format/field_format_test.rb
Normal file
101
test/unit/lib/redmine/field_format/field_format_test.rb
Normal file
|
@ -0,0 +1,101 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::FieldFormatTest < ActionView::TestCase
|
||||
include ApplicationHelper
|
||||
|
||||
def setup
|
||||
set_language_if_valid 'en'
|
||||
end
|
||||
|
||||
def test_string_field_with_text_formatting_disabled_should_not_format_text
|
||||
field = IssueCustomField.new(:field_format => 'string')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "*foo*")
|
||||
|
||||
assert_equal "*foo*", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal "*foo*", field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_string_field_with_text_formatting_enabled_should_format_text
|
||||
field = IssueCustomField.new(:field_format => 'string', :text_formatting => 'full')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "*foo*")
|
||||
|
||||
assert_equal "*foo*", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_include "<strong>foo</strong>", field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_text_field_with_text_formatting_disabled_should_not_format_text
|
||||
field = IssueCustomField.new(:field_format => 'text')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "*foo*\nbar")
|
||||
|
||||
assert_equal "*foo*\nbar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_include "*foo*\n<br />bar", field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_text_field_with_text_formatting_enabled_should_format_text
|
||||
field = IssueCustomField.new(:field_format => 'text', :text_formatting => 'full')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "*foo*\nbar")
|
||||
|
||||
assert_equal "*foo*\nbar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_include "<strong>foo</strong>", field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_should_validate_url_pattern_with_safe_scheme
|
||||
field = IssueCustomField.new(:field_format => 'string', :name => 'URL', :url_pattern => 'http://foo/%value%')
|
||||
assert_save field
|
||||
end
|
||||
|
||||
def test_should_not_validate_url_pattern_with_unsafe_scheme
|
||||
field = IssueCustomField.new(:field_format => 'string', :name => 'URL', :url_pattern => 'foo://foo/%value%')
|
||||
assert !field.save
|
||||
assert_include "URL is invalid", field.errors.full_messages
|
||||
end
|
||||
|
||||
def test_text_field_with_url_pattern_should_format_as_link
|
||||
field = IssueCustomField.new(:field_format => 'string', :url_pattern => 'http://foo/%value%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "bar")
|
||||
|
||||
assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/bar">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_text_field_with_url_pattern_and_value_containing_a_space_should_format_as_link
|
||||
field = IssueCustomField.new(:field_format => 'string', :url_pattern => 'http://foo/%value%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "foo bar")
|
||||
|
||||
assert_equal "foo bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/foo%20bar">foo bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_text_field_with_url_pattern_should_not_encode_url_pattern
|
||||
field = IssueCustomField.new(:field_format => 'string', :url_pattern => 'http://foo/bar#anchor')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "1")
|
||||
|
||||
assert_equal "1", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/bar#anchor">1</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_text_field_with_url_pattern_should_encode_values
|
||||
field = IssueCustomField.new(:field_format => 'string', :url_pattern => 'http://foo/%value%#anchor')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "foo bar")
|
||||
|
||||
assert_equal "foo bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/foo%20bar#anchor">foo bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
end
|
90
test/unit/lib/redmine/field_format/link_format_test.rb
Normal file
90
test/unit/lib/redmine/field_format/link_format_test.rb
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::LinkFieldFormatTest < ActionView::TestCase
|
||||
def test_link_field_should_substitute_value
|
||||
field = IssueCustomField.new(:field_format => 'link', :url_pattern => 'http://foo/%value%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "bar")
|
||||
|
||||
assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/bar">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_link_field_should_substitute_object_id_in_url
|
||||
object = Issue.new
|
||||
object.stubs(:id).returns(10)
|
||||
|
||||
field = IssueCustomField.new(:field_format => 'link', :url_pattern => 'http://foo/%id%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => object, :value => "bar")
|
||||
|
||||
assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/10">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_link_field_should_substitute_project_id_in_url
|
||||
project = Project.new
|
||||
project.stubs(:id).returns(52)
|
||||
object = Issue.new
|
||||
object.stubs(:project).returns(project)
|
||||
|
||||
field = IssueCustomField.new(:field_format => 'link', :url_pattern => 'http://foo/%project_id%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => object, :value => "bar")
|
||||
|
||||
assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/52">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_link_field_should_substitute_project_identifier_in_url
|
||||
project = Project.new
|
||||
project.stubs(:identifier).returns('foo_project-00')
|
||||
object = Issue.new
|
||||
object.stubs(:project).returns(project)
|
||||
|
||||
field = IssueCustomField.new(:field_format => 'link', :url_pattern => 'http://foo/%project_identifier%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => object, :value => "bar")
|
||||
|
||||
assert_equal "bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/foo_project-00">bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_link_field_should_substitute_regexp_groups
|
||||
field = IssueCustomField.new(:field_format => 'link', :regexp => /^(.+)-(.+)$/, :url_pattern => 'http://foo/%m2%/%m1%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "56-142")
|
||||
|
||||
assert_equal "56-142", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/142/56">56-142</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_link_field_without_url_pattern_should_link_to_value
|
||||
field = IssueCustomField.new(:field_format => 'link')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "http://foo/bar")
|
||||
|
||||
assert_equal "http://foo/bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/bar">http://foo/bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
|
||||
def test_link_field_without_url_pattern_should_link_to_value_with_http_by_default
|
||||
field = IssueCustomField.new(:field_format => 'link')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "foo.bar")
|
||||
|
||||
assert_equal "foo.bar", field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo.bar">foo.bar</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
end
|
188
test/unit/lib/redmine/field_format/list_format_test.rb
Normal file
188
test/unit/lib/redmine/field_format/list_format_test.rb
Normal file
|
@ -0,0 +1,188 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::ListFieldFormatTest < ActionView::TestCase
|
||||
include ApplicationHelper
|
||||
include Redmine::I18n
|
||||
|
||||
def setup
|
||||
set_language_if_valid 'en'
|
||||
end
|
||||
|
||||
def test_possible_existing_value_should_be_valid
|
||||
field = GroupCustomField.create!(:name => 'List', :field_format => 'list', :possible_values => ['Foo', 'Bar'])
|
||||
group = Group.new(:name => 'Group')
|
||||
group.custom_field_values = {field.id => 'Baz'}
|
||||
assert group.save(:validate => false)
|
||||
|
||||
group = Group.order('id DESC').first
|
||||
assert_equal ['Foo', 'Bar', 'Baz'], field.possible_custom_value_options(group.custom_value_for(field))
|
||||
assert group.valid?
|
||||
end
|
||||
|
||||
def test_edit_tag_should_have_id_and_name
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar'], :is_required => false)
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new)
|
||||
|
||||
tag = field.format.edit_tag(self, 'abc', 'xyz', value)
|
||||
assert_select_in tag, 'select[id=abc][name=xyz]'
|
||||
end
|
||||
|
||||
def test_edit_tag_should_contain_possible_values
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar'], :is_required => false)
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new)
|
||||
|
||||
tag = field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'select' do
|
||||
assert_select 'option', 3
|
||||
assert_select 'option[value=""]'
|
||||
assert_select 'option[value=Foo]', :text => 'Foo'
|
||||
assert_select 'option[value=Bar]', :text => 'Bar'
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_should_select_current_value
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar'], :is_required => false)
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new, :value => 'Bar')
|
||||
|
||||
tag = field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'select' do
|
||||
assert_select 'option[selected=selected]', 1
|
||||
assert_select 'option[value=Bar][selected=selected]', :text => 'Bar'
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_with_multiple_should_select_current_values
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar', 'Baz'], :is_required => false,
|
||||
:multiple => true)
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new, :value => ['Bar', 'Baz'])
|
||||
|
||||
tag = field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'select[multiple=multiple]' do
|
||||
assert_select 'option[selected=selected]', 2
|
||||
assert_select 'option[value=Bar][selected=selected]', :text => 'Bar'
|
||||
assert_select 'option[value=Baz][selected=selected]', :text => 'Baz'
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_with_check_box_style_should_contain_possible_values
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar'], :is_required => false,
|
||||
:edit_tag_style => 'check_box')
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new)
|
||||
|
||||
tag = field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'span' do
|
||||
assert_select 'input[type=radio]', 3
|
||||
assert_select 'label', :text => '(none)' do
|
||||
assert_select 'input[value=""]'
|
||||
end
|
||||
assert_select 'label', :text => 'Foo' do
|
||||
assert_select 'input[value=Foo]'
|
||||
end
|
||||
assert_select 'label', :text => 'Bar' do
|
||||
assert_select 'input[value=Bar]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_with_check_box_style_should_select_current_value
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar'], :is_required => false,
|
||||
:edit_tag_style => 'check_box')
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new, :value => 'Bar')
|
||||
|
||||
tag = field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'span' do
|
||||
assert_select 'input[type=radio][checked=checked]', 1
|
||||
assert_select 'label', :text => 'Bar' do
|
||||
assert_select 'input[value=Bar][checked=checked]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_edit_tag_with_check_box_style_and_multiple_values_should_contain_hidden_field_to_clear_value
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar'], :is_required => false,
|
||||
:edit_tag_style => 'check_box', :multiple => true)
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new)
|
||||
|
||||
tag = field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'span' do
|
||||
assert_select 'input[type=checkbox]', 2
|
||||
assert_select 'input[type=hidden]', 1
|
||||
end
|
||||
end
|
||||
|
||||
def test_field_with_url_pattern_should_link_value
|
||||
field = IssueCustomField.new(:field_format => 'list', :url_pattern => 'http://localhost/%value%')
|
||||
formatted = field.format.formatted_value(self, field, 'foo', Issue.new, true)
|
||||
assert_equal '<a href="http://localhost/foo">foo</a>', formatted
|
||||
assert formatted.html_safe?
|
||||
end
|
||||
|
||||
def test_field_with_url_pattern_and_multiple_values_should_link_values
|
||||
field = IssueCustomField.new(:field_format => 'list', :url_pattern => 'http://localhost/%value%')
|
||||
formatted = field.format.formatted_value(self, field, ['foo', 'bar'], Issue.new, true)
|
||||
assert_equal '<a href="http://localhost/bar">bar</a>, <a href="http://localhost/foo">foo</a>', formatted
|
||||
assert formatted.html_safe?
|
||||
end
|
||||
|
||||
def test_field_with_url_pattern_should_not_link_blank_value
|
||||
field = IssueCustomField.new(:field_format => 'list', :url_pattern => 'http://localhost/%value%')
|
||||
formatted = field.format.formatted_value(self, field, '', Issue.new, true)
|
||||
assert_equal '', formatted
|
||||
assert formatted.html_safe?
|
||||
end
|
||||
|
||||
def test_edit_tag_with_check_box_style_and_multiple_should_select_current_values
|
||||
field = IssueCustomField.new(:field_format => 'list', :possible_values => ['Foo', 'Bar', 'Baz'], :is_required => false,
|
||||
:multiple => true, :edit_tag_style => 'check_box')
|
||||
value = CustomFieldValue.new(:custom_field => field, :customized => Issue.new, :value => ['Bar', 'Baz'])
|
||||
|
||||
tag = field.format.edit_tag(self, 'id', 'name', value)
|
||||
assert_select_in tag, 'span' do
|
||||
assert_select 'input[type=checkbox][checked=checked]', 2
|
||||
assert_select 'label', :text => 'Bar' do
|
||||
assert_select 'input[value=Bar][checked=checked]'
|
||||
end
|
||||
assert_select 'label', :text => 'Baz' do
|
||||
assert_select 'input[value=Baz][checked=checked]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_value_from_keyword_should_return_value
|
||||
field = GroupCustomField.create!(:name => 'List', :field_format => 'list', :possible_values => ['Foo', 'Bar', 'Baz,qux'])
|
||||
|
||||
assert_equal 'Foo', field.value_from_keyword('foo', nil)
|
||||
assert_equal 'Baz,qux', field.value_from_keyword('baz,qux', nil)
|
||||
assert_nil field.value_from_keyword('invalid', nil)
|
||||
end
|
||||
|
||||
def test_value_from_keyword_for_multiple_custom_field_should_return_values
|
||||
field = GroupCustomField.create!(:name => 'List', :field_format => 'list', :possible_values => ['Foo', 'Bar', 'Baz,qux'], :multiple => true)
|
||||
|
||||
assert_equal ['Foo','Bar'], field.value_from_keyword('foo,bar', nil)
|
||||
assert_equal ['Baz,qux'], field.value_from_keyword('baz,qux', nil)
|
||||
assert_equal ['Baz,qux', 'Foo'], field.value_from_keyword('baz,qux,foo', nil)
|
||||
assert_equal ['Foo'], field.value_from_keyword('foo,invalid', nil)
|
||||
assert_equal ['Foo'], field.value_from_keyword(',foo,', nil)
|
||||
assert_equal ['Foo'], field.value_from_keyword(',foo, ,,', nil)
|
||||
assert_equal [], field.value_from_keyword('invalid', nil)
|
||||
end
|
||||
end
|
31
test/unit/lib/redmine/field_format/numeric_format_test.rb
Normal file
31
test/unit/lib/redmine/field_format/numeric_format_test.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::NumericFieldFormatTest < ActionView::TestCase
|
||||
include ApplicationHelper
|
||||
|
||||
def test_integer_field_with_url_pattern_should_format_as_link
|
||||
field = IssueCustomField.new(:field_format => 'int', :url_pattern => 'http://foo/%value%')
|
||||
custom_value = CustomValue.new(:custom_field => field, :customized => Issue.new, :value => "3")
|
||||
|
||||
assert_equal 3, field.format.formatted_custom_value(self, custom_value, false)
|
||||
assert_equal '<a href="http://foo/3">3</a>', field.format.formatted_custom_value(self, custom_value, true)
|
||||
end
|
||||
end
|
79
test/unit/lib/redmine/field_format/user_field_format_test.rb
Normal file
79
test/unit/lib/redmine/field_format/user_field_format_test.rb
Normal file
|
@ -0,0 +1,79 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::UserFieldFormatTest < ActionView::TestCase
|
||||
fixtures :projects, :roles, :users, :members, :member_roles,
|
||||
:trackers,
|
||||
:issue_statuses, :issue_categories, :issue_relations, :workflows,
|
||||
:enumerations
|
||||
|
||||
def test_user_role_should_reject_blank_values
|
||||
field = IssueCustomField.new(:name => 'Foo', :field_format => 'user', :user_role => ["1", ""])
|
||||
field.save!
|
||||
assert_equal ["1"], field.user_role
|
||||
end
|
||||
|
||||
def test_existing_values_should_be_valid
|
||||
field = IssueCustomField.create!(:name => 'Foo', :field_format => 'user', :is_for_all => true, :trackers => Tracker.all)
|
||||
project = Project.generate!
|
||||
user = User.generate!
|
||||
User.add_to_project(user, project, Role.find_by_name('Manager'))
|
||||
issue = Issue.generate!(:project_id => project.id, :tracker_id => 1, :custom_field_values => {field.id => user.id})
|
||||
|
||||
field.user_role = [Role.find_by_name('Developer').id]
|
||||
field.save!
|
||||
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_include [user.name, user.id.to_s], field.possible_custom_value_options(issue.custom_value_for(field))
|
||||
assert issue.valid?
|
||||
end
|
||||
|
||||
def test_possible_values_options_should_return_project_members
|
||||
field = IssueCustomField.new(:field_format => 'user')
|
||||
project = Project.find(1)
|
||||
|
||||
assert_equal ['Dave Lopper', 'John Smith'], field.possible_values_options(project).map(&:first)
|
||||
end
|
||||
|
||||
def test_possible_values_options_should_return_project_members_with_selected_role
|
||||
field = IssueCustomField.new(:field_format => 'user', :user_role => ["2"])
|
||||
project = Project.find(1)
|
||||
|
||||
assert_equal ['Dave Lopper'], field.possible_values_options(project).map(&:first)
|
||||
end
|
||||
|
||||
def test_value_from_keyword_should_return_user_id
|
||||
field = IssueCustomField.new(:field_format => 'user')
|
||||
project = Project.find(1)
|
||||
|
||||
assert_equal 2, field.value_from_keyword('jsmith', project)
|
||||
assert_equal 3, field.value_from_keyword('Dave Lopper', project)
|
||||
assert_nil field.value_from_keyword('Unknown User', project)
|
||||
end
|
||||
|
||||
def test_value_from_keyword_for_multiple_custom_field_should_return_enumeration_ids
|
||||
field = IssueCustomField.new(:field_format => 'user', :multiple => true)
|
||||
project = Project.find(1)
|
||||
|
||||
assert_equal [2, 3], field.value_from_keyword('jsmith, Dave Lopper', project)
|
||||
assert_equal [2], field.value_from_keyword('jsmith', project)
|
||||
assert_equal [], field.value_from_keyword('Unknown User', project)
|
||||
end
|
||||
end
|
105
test/unit/lib/redmine/field_format/version_field_format_test.rb
Normal file
105
test/unit/lib/redmine/field_format/version_field_format_test.rb
Normal file
|
@ -0,0 +1,105 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'redmine/field_format'
|
||||
|
||||
class Redmine::VersionFieldFormatTest < ActionView::TestCase
|
||||
fixtures :projects, :versions, :trackers,
|
||||
:roles, :users, :members, :member_roles,
|
||||
:issue_statuses, :issue_categories, :issue_relations, :workflows,
|
||||
:enumerations
|
||||
|
||||
def setup
|
||||
super
|
||||
User.current = nil
|
||||
end
|
||||
|
||||
def test_version_status_should_reject_blank_values
|
||||
field = IssueCustomField.new(:name => 'Foo', :field_format => 'version', :version_status => ["open", ""])
|
||||
field.save!
|
||||
assert_equal ["open"], field.version_status
|
||||
end
|
||||
|
||||
def test_existing_values_should_be_valid
|
||||
field = IssueCustomField.create!(:name => 'Foo', :field_format => 'version', :is_for_all => true, :trackers => Tracker.all)
|
||||
project = Project.generate!
|
||||
version = Version.generate!(:project => project, :status => 'open')
|
||||
issue = Issue.generate!(:project_id => project.id, :tracker_id => 1, :custom_field_values => {field.id => version.id})
|
||||
|
||||
field.version_status = ["open"]
|
||||
field.save!
|
||||
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_include [version.name, version.id.to_s], field.possible_custom_value_options(issue.custom_value_for(field))
|
||||
assert issue.valid?
|
||||
end
|
||||
|
||||
def test_possible_values_options_should_return_project_versions
|
||||
field = IssueCustomField.new(:field_format => 'version')
|
||||
project = Project.find(1)
|
||||
expected = project.shared_versions.sort.map(&:name)
|
||||
|
||||
assert_equal expected, field.possible_values_options(project).map(&:first)
|
||||
end
|
||||
|
||||
def test_possible_values_options_should_return_system_shared_versions_without_project
|
||||
field = IssueCustomField.new(:field_format => 'version')
|
||||
version = Version.generate!(:project => Project.find(1), :status => 'open', :sharing => 'system')
|
||||
|
||||
expected = Version.visible.where(:sharing => 'system').sort.map(&:name)
|
||||
assert_include version.name, expected
|
||||
assert_equal expected, field.possible_values_options.map(&:first)
|
||||
end
|
||||
|
||||
def test_possible_values_options_should_return_project_versions_with_selected_status
|
||||
field = IssueCustomField.new(:field_format => 'version', :version_status => ["open"])
|
||||
project = Project.find(1)
|
||||
expected = project.shared_versions.sort.select {|v| v.status == "open"}.map(&:name)
|
||||
|
||||
assert_equal expected, field.possible_values_options(project).map(&:first)
|
||||
end
|
||||
|
||||
def test_cast_value_should_not_raise_error_when_array_contains_value_casted_to_nil
|
||||
field = IssueCustomField.new(:field_format => 'version')
|
||||
assert_nothing_raised do
|
||||
field.cast_value([1,2, 42])
|
||||
end
|
||||
end
|
||||
|
||||
def test_query_filter_options_should_include_versions_with_any_status
|
||||
field = IssueCustomField.new(:field_format => 'version', :version_status => ["open"])
|
||||
project = Project.find(1)
|
||||
version = Version.generate!(:project => project, :status => 'locked')
|
||||
query = Query.new(:project => project)
|
||||
|
||||
full_name = "#{version.project} - #{version.name}"
|
||||
assert_not_include full_name, field.possible_values_options(project).map(&:first)
|
||||
assert_include full_name, field.query_filter_options(query)[:values].call.map(&:first)
|
||||
end
|
||||
|
||||
def test_query_filter_options_should_include_version_status_for_grouping
|
||||
field = IssueCustomField.new(:field_format => 'version', :version_status => ["open"])
|
||||
project = Project.find(1)
|
||||
version = Version.generate!(:project => project, :status => 'locked')
|
||||
query = Query.new(:project => project)
|
||||
|
||||
full_name = "#{version.project} - #{version.name}"
|
||||
assert_include [full_name, version.id.to_s, l(:version_status_locked)],
|
||||
field.query_filter_options(query)[:values].call
|
||||
end
|
||||
end
|
63
test/unit/lib/redmine/helpers/calendar_test.rb
Normal file
63
test/unit/lib/redmine/helpers/calendar_test.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class CalendarTest < ActiveSupport::TestCase
|
||||
|
||||
def test_monthly
|
||||
c = Redmine::Helpers::Calendar.new(Date.today, :fr, :month)
|
||||
assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
|
||||
|
||||
c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :month)
|
||||
assert_equal ['2007-06-25'.to_date, '2007-08-05'.to_date], [c.startdt, c.enddt]
|
||||
|
||||
c = Redmine::Helpers::Calendar.new(Date.today, :en, :month)
|
||||
assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
|
||||
end
|
||||
|
||||
def test_weekly
|
||||
c = Redmine::Helpers::Calendar.new(Date.today, :fr, :week)
|
||||
assert_equal [1, 7], [c.startdt.cwday, c.enddt.cwday]
|
||||
|
||||
c = Redmine::Helpers::Calendar.new('2007-07-14'.to_date, :fr, :week)
|
||||
assert_equal ['2007-07-09'.to_date, '2007-07-15'.to_date], [c.startdt, c.enddt]
|
||||
|
||||
c = Redmine::Helpers::Calendar.new(Date.today, :en, :week)
|
||||
assert_equal [7, 6], [c.startdt.cwday, c.enddt.cwday]
|
||||
end
|
||||
|
||||
def test_monthly_start_day
|
||||
[1, 6, 7].each do |day|
|
||||
with_settings :start_of_week => day do
|
||||
c = Redmine::Helpers::Calendar.new(Date.today, :en, :month)
|
||||
assert_equal day , c.startdt.cwday
|
||||
assert_equal (day + 5) % 7 + 1, c.enddt.cwday
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_weekly_start_day
|
||||
[1, 6, 7].each do |day|
|
||||
with_settings :start_of_week => day do
|
||||
c = Redmine::Helpers::Calendar.new(Date.today, :en, :week)
|
||||
assert_equal day, c.startdt.cwday
|
||||
assert_equal (day + 5) % 7 + 1, c.enddt.cwday
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
37
test/unit/lib/redmine/helpers/diff_test.rb
Normal file
37
test/unit/lib/redmine/helpers/diff_test.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class DiffTest < ActiveSupport::TestCase
|
||||
def test_diff
|
||||
diff = Redmine::Helpers::Diff.new("foo", "bar")
|
||||
assert_not_nil diff
|
||||
end
|
||||
|
||||
def test_dont_double_escape
|
||||
# 3 cases to test in the before: first word, last word, everything inbetween
|
||||
before = "<stuff> with html & special chars</danger>"
|
||||
# all words in after are treated equal
|
||||
after = "other stuff <script>alert('foo');</alert>"
|
||||
|
||||
computed_diff = Redmine::Helpers::Diff.new(before, after).to_html
|
||||
expected_diff = '<span class="diff_in"><stuff> with html & special chars</danger></span> <span class="diff_out">other stuff <script>alert('foo');</alert></span>'
|
||||
|
||||
assert_equal computed_diff, expected_diff
|
||||
end
|
||||
end
|
498
test/unit/lib/redmine/helpers/gantt_test.rb
Normal file
498
test/unit/lib/redmine/helpers/gantt_test.rb
Normal file
|
@ -0,0 +1,498 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Helpers::GanttHelperTest < Redmine::HelperTest
|
||||
fixtures :projects, :trackers, :issue_statuses,
|
||||
:enumerations, :users, :issue_categories
|
||||
|
||||
include ProjectsHelper
|
||||
include IssuesHelper
|
||||
include ERB::Util
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
def setup
|
||||
setup_with_controller
|
||||
User.current = User.find(1)
|
||||
end
|
||||
|
||||
def today
|
||||
@today ||= Date.today
|
||||
end
|
||||
private :today
|
||||
|
||||
def gantt_start
|
||||
@gantt.date_from
|
||||
end
|
||||
|
||||
# Creates a Gantt chart for a 4 week span
|
||||
def create_gantt(project=Project.generate!, options={})
|
||||
@project = project
|
||||
@gantt = Redmine::Helpers::Gantt.new(options)
|
||||
@gantt.project = @project
|
||||
@gantt.query = IssueQuery.new(:project => @project, :name => 'Gantt')
|
||||
@gantt.view = self
|
||||
@gantt.instance_variable_set('@date_from', options[:date_from] || (today - 14))
|
||||
@gantt.instance_variable_set('@date_to', options[:date_to] || (today + 14))
|
||||
end
|
||||
private :create_gantt
|
||||
|
||||
test "#number_of_rows with one project should return the number of rows just for that project" do
|
||||
p1, p2 = Project.generate!, Project.generate!
|
||||
i1, i2 = Issue.generate!(:project => p1), Issue.generate!(:project => p2)
|
||||
create_gantt(p1)
|
||||
assert_equal 2, @gantt.number_of_rows
|
||||
end
|
||||
|
||||
test "#number_of_rows with no project should return the total number of rows for all the projects, recursively" do
|
||||
p1, p2 = Project.generate!, Project.generate!
|
||||
create_gantt(nil)
|
||||
# fix the return value of #number_of_rows_on_project() to an arbitrary value
|
||||
# so that we really only test #number_of_rows
|
||||
@gantt.stubs(:number_of_rows_on_project).returns(7)
|
||||
# also fix #projects because we want to test #number_of_rows in isolation
|
||||
@gantt.stubs(:projects).returns(Project.all)
|
||||
# actual test
|
||||
assert_equal Project.count*7, @gantt.number_of_rows
|
||||
end
|
||||
|
||||
test "#number_of_rows should not exceed max_rows option" do
|
||||
p = Project.generate!
|
||||
5.times do
|
||||
Issue.generate!(:project => p)
|
||||
end
|
||||
create_gantt(p)
|
||||
@gantt.render
|
||||
assert_equal 6, @gantt.number_of_rows
|
||||
assert !@gantt.truncated
|
||||
create_gantt(p, :max_rows => 3)
|
||||
@gantt.render
|
||||
assert_equal 3, @gantt.number_of_rows
|
||||
assert @gantt.truncated
|
||||
end
|
||||
|
||||
test "#number_of_rows_on_project should count 0 for an empty the project" do
|
||||
create_gantt
|
||||
assert_equal 0, @gantt.number_of_rows_on_project(@project)
|
||||
end
|
||||
|
||||
test "#number_of_rows_on_project should count the number of issues without a version" do
|
||||
create_gantt
|
||||
@project.issues << Issue.generate!(:project => @project, :fixed_version => nil)
|
||||
assert_equal 2, @gantt.number_of_rows_on_project(@project)
|
||||
end
|
||||
|
||||
test "#number_of_rows_on_project should count the number of issues on versions, including cross-project" do
|
||||
create_gantt
|
||||
version = Version.generate!
|
||||
@project.versions << version
|
||||
@project.issues << Issue.generate!(:project => @project, :fixed_version => version)
|
||||
assert_equal 3, @gantt.number_of_rows_on_project(@project)
|
||||
end
|
||||
|
||||
def setup_subjects
|
||||
create_gantt
|
||||
@project.enabled_module_names = [:issue_tracking]
|
||||
@tracker = Tracker.generate!
|
||||
@project.trackers << @tracker
|
||||
@version = Version.generate!(:effective_date => (today + 7), :sharing => 'none')
|
||||
@project.versions << @version
|
||||
@issue = Issue.generate!(:fixed_version => @version,
|
||||
:subject => "gantt#line_for_project",
|
||||
:tracker => @tracker,
|
||||
:project => @project,
|
||||
:done_ratio => 30,
|
||||
:start_date => (today - 1),
|
||||
:due_date => (today + 7))
|
||||
@project.issues << @issue
|
||||
end
|
||||
private :setup_subjects
|
||||
|
||||
# TODO: more of an integration test
|
||||
test "#subjects project should be rendered" do
|
||||
setup_subjects
|
||||
@output_buffer = @gantt.subjects
|
||||
assert_select "div.project-name a", /#{@project.name}/
|
||||
assert_select 'div.project-name[style*="left:4px"]'
|
||||
end
|
||||
|
||||
test "#subjects version should be rendered" do
|
||||
setup_subjects
|
||||
@output_buffer = @gantt.subjects
|
||||
assert_select "div.version-name a", /#{@version.name}/
|
||||
assert_select 'div.version-name[style*="left:24px"]'
|
||||
end
|
||||
|
||||
test "#subjects version without assigned issues should not be rendered" do
|
||||
setup_subjects
|
||||
@version = Version.generate!(:effective_date => (today + 14),
|
||||
:sharing => 'none',
|
||||
:name => 'empty_version')
|
||||
@project.versions << @version
|
||||
@output_buffer = @gantt.subjects
|
||||
assert_select "div.version-name a", :text => /#{@version.name}/, :count => 0
|
||||
end
|
||||
|
||||
test "#subjects issue should be rendered" do
|
||||
setup_subjects
|
||||
@output_buffer = @gantt.subjects
|
||||
assert_select "div.issue-subject", /#{@issue.subject}/
|
||||
assert_select 'div.issue-subject[style*="left:44px"]'
|
||||
end
|
||||
|
||||
test "#subjects issue assigned to a shared version of another project should be rendered" do
|
||||
setup_subjects
|
||||
p = Project.generate!
|
||||
p.enabled_module_names = [:issue_tracking]
|
||||
@shared_version = Version.generate!(:sharing => 'system')
|
||||
p.versions << @shared_version
|
||||
# Reassign the issue to a shared version of another project
|
||||
@issue = Issue.generate!(:fixed_version => @shared_version,
|
||||
:subject => "gantt#assigned_to_shared_version",
|
||||
:tracker => @tracker,
|
||||
:project => @project,
|
||||
:done_ratio => 30,
|
||||
:start_date => (today - 1),
|
||||
:due_date => (today + 7))
|
||||
@project.issues << @issue
|
||||
@output_buffer = @gantt.subjects
|
||||
assert_select "div.issue-subject", /#{@issue.subject}/
|
||||
end
|
||||
|
||||
test "#subjects issue with subtasks should indent subtasks" do
|
||||
setup_subjects
|
||||
attrs = {:project => @project, :tracker => @tracker, :fixed_version => @version}
|
||||
@child1 = Issue.generate!(
|
||||
attrs.merge(:subject => 'child1',
|
||||
:parent_issue_id => @issue.id,
|
||||
:start_date => (today - 1),
|
||||
:due_date => (today + 2))
|
||||
)
|
||||
@child2 = Issue.generate!(
|
||||
attrs.merge(:subject => 'child2',
|
||||
:parent_issue_id => @issue.id,
|
||||
:start_date => today,
|
||||
:due_date => (today + 7))
|
||||
)
|
||||
@grandchild = Issue.generate!(
|
||||
attrs.merge(:subject => 'grandchild',
|
||||
:parent_issue_id => @child1.id,
|
||||
:start_date => (today - 1),
|
||||
:due_date => (today + 2))
|
||||
)
|
||||
@output_buffer = @gantt.subjects
|
||||
# parent task 44px
|
||||
assert_select 'div.issue-subject[style*="left:44px"]', /#{@issue.subject}/
|
||||
# children 64px
|
||||
assert_select 'div.issue-subject[style*="left:64px"]', /child1/
|
||||
assert_select 'div.issue-subject[style*="left:64px"]', /child2/
|
||||
# grandchild 84px
|
||||
assert_select 'div.issue-subject[style*="left:84px"]', /grandchild/, @output_buffer
|
||||
end
|
||||
|
||||
test "#lines" do
|
||||
create_gantt
|
||||
@project.enabled_module_names = [:issue_tracking]
|
||||
@tracker = Tracker.generate!
|
||||
@project.trackers << @tracker
|
||||
@version = Version.generate!(:effective_date => (today + 7))
|
||||
@project.versions << @version
|
||||
@issue = Issue.generate!(:fixed_version => @version,
|
||||
:subject => "gantt#line_for_project",
|
||||
:tracker => @tracker,
|
||||
:project => @project,
|
||||
:done_ratio => 30,
|
||||
:start_date => (today - 1),
|
||||
:due_date => (today + 7))
|
||||
@project.issues << @issue
|
||||
@output_buffer = @gantt.lines
|
||||
|
||||
assert_select "div.project.task_todo"
|
||||
assert_select "div.project.starting"
|
||||
assert_select "div.project.ending"
|
||||
assert_select "div.label.project", /#{@project.name}/
|
||||
|
||||
assert_select "div.version.task_todo"
|
||||
assert_select "div.version.starting"
|
||||
assert_select "div.version.ending"
|
||||
assert_select "div.label.version", /#{@version.name}/
|
||||
|
||||
assert_select "div.task_todo"
|
||||
assert_select "div.task.label", /#{@issue.done_ratio}/
|
||||
assert_select "div.tooltip", /#{@issue.subject}/
|
||||
end
|
||||
|
||||
test "#subject_for_project" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.subject_for_project(@project, :format => :html)
|
||||
assert_select 'a[href=?]', "/projects/#{@project.identifier}", :text => /#{@project.name}/
|
||||
end
|
||||
|
||||
test "#subject_for_project should style overdue projects" do
|
||||
create_gantt
|
||||
@project.stubs(:overdue?).returns(true)
|
||||
@output_buffer = @gantt.subject_for_project(@project, :format => :html)
|
||||
assert_select 'div span.project-overdue'
|
||||
end
|
||||
|
||||
test "#subject_for_version" do
|
||||
create_gantt
|
||||
version = Version.generate!(:name => 'Foo', :effective_date => today, :project => @project)
|
||||
@output_buffer = @gantt.subject_for_version(version, :format => :html)
|
||||
assert_select 'a[href=?]', "/versions/#{version.to_param}", :text => /Foo/
|
||||
end
|
||||
|
||||
test "#subject_for_version should style overdue versions" do
|
||||
create_gantt
|
||||
version = Version.generate!(:name => 'Foo', :effective_date => today, :project => @project)
|
||||
version.stubs(:overdue?).returns(true)
|
||||
@output_buffer = @gantt.subject_for_version(version, :format => :html)
|
||||
assert_select 'div span.version-overdue'
|
||||
end
|
||||
|
||||
test "#subject_for_version should style behind schedule versions" do
|
||||
create_gantt
|
||||
version = Version.generate!(:name => 'Foo', :effective_date => today, :project => @project)
|
||||
version.stubs(:behind_schedule?).returns(true)
|
||||
@output_buffer = @gantt.subject_for_version(version, :format => :html)
|
||||
assert_select 'div span.version-behind-schedule'
|
||||
end
|
||||
|
||||
test "#subject_for_issue" do
|
||||
create_gantt
|
||||
issue = Issue.generate!(:project => @project)
|
||||
@output_buffer = @gantt.subject_for_issue(issue, :format => :html)
|
||||
assert_select 'div', :text => /#{issue.subject}/
|
||||
assert_select 'a[href=?]', "/issues/#{issue.to_param}", :text => /#{issue.tracker.name} ##{issue.id}/
|
||||
end
|
||||
|
||||
test "#subject_for_issue should style overdue issues" do
|
||||
create_gantt
|
||||
issue = Issue.generate!(:project => @project)
|
||||
issue.stubs(:overdue?).returns(true)
|
||||
@output_buffer = @gantt.subject_for_issue(issue, :format => :html)
|
||||
assert_select 'div span.issue-overdue'
|
||||
end
|
||||
|
||||
test "#subject should add an absolute positioned div" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.subject('subject', :format => :html)
|
||||
assert_select "div[style*=absolute]", :text => 'subject'
|
||||
end
|
||||
|
||||
test "#subject should use the indent option to move the div to the right" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.subject('subject', :format => :html, :indent => 40)
|
||||
assert_select 'div[style*="left:40"]'
|
||||
end
|
||||
|
||||
test "#line_for_project" do
|
||||
create_gantt
|
||||
@project.stubs(:start_date).returns(today - 7)
|
||||
@project.stubs(:due_date).returns(today + 7)
|
||||
@output_buffer = @gantt.line_for_project(@project, :format => :html)
|
||||
assert_select "div.project.label", :text => @project.name
|
||||
end
|
||||
|
||||
test "#line_for_version" do
|
||||
create_gantt
|
||||
version = Version.generate!(:name => 'Foo', :project => @project)
|
||||
version.stubs(:start_date).returns(today - 7)
|
||||
version.stubs(:due_date).returns(today + 7)
|
||||
version.stubs(:completed_percent).returns(30)
|
||||
@output_buffer = @gantt.line_for_version(version, :format => :html)
|
||||
assert_select "div.version.label", :text => /Foo/
|
||||
assert_select "div.version.label", :text => /30%/
|
||||
end
|
||||
|
||||
test "#line_for_issue" do
|
||||
create_gantt
|
||||
issue = Issue.generate!(:project => @project, :start_date => today - 7, :due_date => today + 7, :done_ratio => 30)
|
||||
@output_buffer = @gantt.line_for_issue(issue, :format => :html)
|
||||
assert_select "div.task.label", :text => /#{issue.status.name}/
|
||||
assert_select "div.task.label", :text => /30%/
|
||||
assert_select "div.tooltip", /#{issue.subject}/
|
||||
end
|
||||
|
||||
test "#line todo line should start from the starting point on the left" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
|
||||
assert_select 'div.task_todo[style*="left:28px"]', 1
|
||||
end
|
||||
|
||||
test "#line todo line should be the total width" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
|
||||
assert_select 'div.task_todo[style*="width:58px"]', 1
|
||||
end
|
||||
|
||||
test "#line late line should start from the starting point on the left" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
|
||||
assert_select 'div.task_late[style*="left:28px"]', 1
|
||||
end
|
||||
|
||||
test "#line late line should be the total delayed width" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
|
||||
assert_select 'div.task_late[style*="width:30px"]', 1
|
||||
end
|
||||
|
||||
test "#line done line should start from the starting point on the left" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
|
||||
assert_select 'div.task_done[style*="left:28px"]', 1
|
||||
end
|
||||
|
||||
test "#line done line should be the width for the done ratio" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, false, 'line', :format => :html, :zoom => 4)
|
||||
# 15 days * 4 px * 30% - 2 px for borders = 16 px
|
||||
assert_select 'div.task_done[style*="width:16px"]', 1
|
||||
end
|
||||
|
||||
test "#line done line should be the total width for 100% done ratio" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 100, false, 'line', :format => :html, :zoom => 4)
|
||||
# 15 days * 4 px - 2 px for borders = 58 px
|
||||
assert_select 'div.task_done[style*="width:58px"]', 1
|
||||
end
|
||||
|
||||
test "#line done line should be the total width for 100% done ratio with same start and end dates" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today + 7, today + 7, 100, false, 'line', :format => :html, :zoom => 4)
|
||||
assert_select 'div.task_done[style*="width:2px"]', 1
|
||||
end
|
||||
|
||||
test "#line done line should not be the total done width if the gantt starts after start date" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 16, today - 2, 30, false, 'line', :format => :html, :zoom => 4)
|
||||
assert_select 'div.task_done[style*="left:0px"]', 1
|
||||
assert_select 'div.task_done[style*="width:8px"]', 1
|
||||
end
|
||||
|
||||
test "#line starting marker should appear at the start date" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
|
||||
assert_select "div.starting", 1
|
||||
assert_select 'div.starting[style*="left:28px"]', 1
|
||||
end
|
||||
|
||||
test "#line starting marker should not appear if the start date is before gantt start date" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(gantt_start - 2, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
|
||||
assert_select "div.starting", 0
|
||||
end
|
||||
|
||||
test "#line ending marker should appear at the end date" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(today - 7, today + 7, 30, true, 'line', :format => :html, :zoom => 4)
|
||||
assert_select "div.ending", 1
|
||||
assert_select 'div.ending[style*="left:88px"]', 1
|
||||
end
|
||||
|
||||
test "#line ending marker should not appear if the end date is before gantt start date" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(gantt_start - 30, gantt_start - 21, 30, true, 'line', :format => :html)
|
||||
assert_select "div.ending", 0
|
||||
end
|
||||
|
||||
test "#line label should appear at the far left, even if it's before gantt start date" do
|
||||
create_gantt
|
||||
@output_buffer = @gantt.line(gantt_start - 30, gantt_start - 21, 30, true, 'line', :format => :html)
|
||||
assert_select "div.label", :text => 'line'
|
||||
end
|
||||
|
||||
def test_sort_issues_no_date
|
||||
project = Project.generate!
|
||||
issue1 = Issue.generate!(:subject => "test", :project => project)
|
||||
issue2 = Issue.generate!(:subject => "test", :project => project)
|
||||
assert issue1.root_id < issue2.root_id
|
||||
child1 = Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
|
||||
:project => project)
|
||||
child2 = Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
|
||||
:project => project)
|
||||
child3 = Issue.generate!(:parent_issue_id => child1.id, :subject => 'child',
|
||||
:project => project)
|
||||
assert_equal child1.root_id, child2.root_id
|
||||
assert child1.lft < child2.lft
|
||||
assert child3.lft < child2.lft
|
||||
issues = [child3, child2, child1, issue2, issue1]
|
||||
Redmine::Helpers::Gantt.sort_issues!(issues)
|
||||
assert_equal [issue1.id, child1.id, child3.id, child2.id, issue2.id],
|
||||
issues.map{|v| v.id}
|
||||
end
|
||||
|
||||
def test_sort_issues_root_only
|
||||
project = Project.generate!
|
||||
issue1 = Issue.generate!(:subject => "test", :project => project)
|
||||
issue2 = Issue.generate!(:subject => "test", :project => project)
|
||||
issue3 = Issue.generate!(:subject => "test", :project => project,
|
||||
:start_date => (today - 1))
|
||||
issue4 = Issue.generate!(:subject => "test", :project => project,
|
||||
:start_date => (today - 2))
|
||||
issues = [issue4, issue3, issue2, issue1]
|
||||
Redmine::Helpers::Gantt.sort_issues!(issues)
|
||||
assert_equal [issue1.id, issue2.id, issue4.id, issue3.id],
|
||||
issues.map{|v| v.id}
|
||||
end
|
||||
|
||||
def test_sort_issues_tree
|
||||
project = Project.generate!
|
||||
issue1 = Issue.generate!(:subject => "test", :project => project)
|
||||
issue2 = Issue.generate!(:subject => "test", :project => project,
|
||||
:start_date => (today - 2))
|
||||
issue1_child1 =
|
||||
Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
|
||||
:project => project)
|
||||
issue1_child2 =
|
||||
Issue.generate!(:parent_issue_id => issue1.id, :subject => 'child',
|
||||
:project => project, :start_date => (today - 10))
|
||||
issue1_child1_child1 =
|
||||
Issue.generate!(:parent_issue_id => issue1_child1.id, :subject => 'child',
|
||||
:project => project, :start_date => (today - 8))
|
||||
issue1_child1_child2 =
|
||||
Issue.generate!(:parent_issue_id => issue1_child1.id, :subject => 'child',
|
||||
:project => project, :start_date => (today - 9))
|
||||
issue1_child1_child1_logic = Redmine::Helpers::Gantt.sort_issue_logic(issue1_child1_child1)
|
||||
assert_equal [[today - 10, issue1.id], [today - 9, issue1_child1.id],
|
||||
[today - 8, issue1_child1_child1.id]],
|
||||
issue1_child1_child1_logic
|
||||
issue1_child1_child2_logic = Redmine::Helpers::Gantt.sort_issue_logic(issue1_child1_child2)
|
||||
assert_equal [[today - 10, issue1.id], [today - 9, issue1_child1.id],
|
||||
[today - 9, issue1_child1_child2.id]],
|
||||
issue1_child1_child2_logic
|
||||
issues = [issue1_child1_child2, issue1_child1_child1, issue1_child2,
|
||||
issue1_child1, issue2, issue1]
|
||||
Redmine::Helpers::Gantt.sort_issues!(issues)
|
||||
assert_equal [issue1.id, issue1_child1.id, issue1_child2.id,
|
||||
issue1_child1_child2.id, issue1_child1_child1.id, issue2.id],
|
||||
issues.map{|v| v.id}
|
||||
end
|
||||
|
||||
def test_sort_versions
|
||||
project = Project.generate!
|
||||
versions = []
|
||||
versions << Version.create!(:project => project, :name => 'test1')
|
||||
versions << Version.create!(:project => project, :name => 'test2', :effective_date => '2013-10-25')
|
||||
versions << Version.create!(:project => project, :name => 'test3')
|
||||
versions << Version.create!(:project => project, :name => 'test4', :effective_date => '2013-10-02')
|
||||
|
||||
assert_equal versions.sort, Redmine::Helpers::Gantt.sort_versions!(versions.dup)
|
||||
end
|
||||
end
|
189
test/unit/lib/redmine/hook_test.rb
Normal file
189
test/unit/lib/redmine/hook_test.rb
Normal file
|
@ -0,0 +1,189 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Hook::ManagerTest < ActionView::TestCase
|
||||
fixtures :projects, :users, :members, :member_roles, :roles,
|
||||
:groups_users,
|
||||
:email_addresses,
|
||||
:trackers, :projects_trackers,
|
||||
:enabled_modules,
|
||||
:versions,
|
||||
:issue_statuses, :issue_categories, :issue_relations,
|
||||
:enumerations,
|
||||
:issues
|
||||
|
||||
# Some hooks that are manually registered in these tests
|
||||
class TestHook < Redmine::Hook::ViewListener; end
|
||||
|
||||
class TestHook1 < TestHook
|
||||
def view_layouts_base_html_head(context)
|
||||
'Test hook 1 listener.'
|
||||
end
|
||||
end
|
||||
|
||||
class TestHook2 < TestHook
|
||||
def view_layouts_base_html_head(context)
|
||||
'Test hook 2 listener.'
|
||||
end
|
||||
end
|
||||
|
||||
class TestHook3 < TestHook
|
||||
def view_layouts_base_html_head(context)
|
||||
"Context keys: #{context.keys.collect(&:to_s).sort.join(', ')}."
|
||||
end
|
||||
end
|
||||
|
||||
class TestLinkToHook < TestHook
|
||||
def view_layouts_base_html_head(context)
|
||||
link_to('Issues', :controller => 'issues')
|
||||
end
|
||||
end
|
||||
|
||||
class TestHookHelperController < ActionController::Base
|
||||
include Redmine::Hook::Helper
|
||||
end
|
||||
|
||||
class TestHookHelperView < ActionView::Base
|
||||
include Redmine::Hook::Helper
|
||||
end
|
||||
|
||||
Redmine::Hook.clear_listeners
|
||||
|
||||
def setup
|
||||
@hook_module = Redmine::Hook
|
||||
@hook_module.clear_listeners
|
||||
end
|
||||
|
||||
def teardown
|
||||
@hook_module.clear_listeners
|
||||
end
|
||||
|
||||
def test_clear_listeners
|
||||
assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
|
||||
@hook_module.add_listener(TestHook1)
|
||||
@hook_module.add_listener(TestHook2)
|
||||
assert_equal 2, @hook_module.hook_listeners(:view_layouts_base_html_head).size
|
||||
|
||||
@hook_module.clear_listeners
|
||||
assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
|
||||
end
|
||||
|
||||
def test_add_listener
|
||||
assert_equal 0, @hook_module.hook_listeners(:view_layouts_base_html_head).size
|
||||
@hook_module.add_listener(TestHook1)
|
||||
assert_equal 1, @hook_module.hook_listeners(:view_layouts_base_html_head).size
|
||||
end
|
||||
|
||||
def test_call_hook
|
||||
@hook_module.add_listener(TestHook1)
|
||||
assert_equal ['Test hook 1 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
end
|
||||
|
||||
def test_call_hook_with_context
|
||||
@hook_module.add_listener(TestHook3)
|
||||
assert_equal ['Context keys: bar, controller, foo, hook_caller, project, request.'],
|
||||
hook_helper.call_hook(:view_layouts_base_html_head, :foo => 1, :bar => 'a')
|
||||
end
|
||||
|
||||
def test_call_hook_with_multiple_listeners
|
||||
@hook_module.add_listener(TestHook1)
|
||||
@hook_module.add_listener(TestHook2)
|
||||
assert_equal ['Test hook 1 listener.', 'Test hook 2 listener.'], hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
end
|
||||
|
||||
# Context: Redmine::Hook::Helper.call_hook default_url
|
||||
def test_call_hook_default_url_options
|
||||
@hook_module.add_listener(TestLinkToHook)
|
||||
|
||||
assert_equal ['<a href="/issues">Issues</a>'], hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
end
|
||||
|
||||
def test_view_hook_should_generate_links_with_relative_url_root
|
||||
Redmine::Utils.relative_url_root = '/foo'
|
||||
@hook_module.add_listener(TestLinkToHook)
|
||||
|
||||
assert_equal ['<a href="/foo/issues">Issues</a>'], hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
ensure
|
||||
Redmine::Utils.relative_url_root = ''
|
||||
end
|
||||
|
||||
# Context: Redmine::Hook::Helper.call_hook
|
||||
def test_call_hook_with_project_added_to_context
|
||||
@hook_module.add_listener(TestHook3)
|
||||
assert_match /project/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
|
||||
end
|
||||
|
||||
def test_call_hook_from_controller_with_controller_added_to_context
|
||||
@hook_module.add_listener(TestHook3)
|
||||
assert_match /controller/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
|
||||
end
|
||||
|
||||
def test_call_hook_from_controller_with_request_added_to_context
|
||||
@hook_module.add_listener(TestHook3)
|
||||
assert_match /request/i, hook_helper.call_hook(:view_layouts_base_html_head)[0]
|
||||
end
|
||||
|
||||
def test_call_hook_from_view_with_project_added_to_context
|
||||
@hook_module.add_listener(TestHook3)
|
||||
assert_match /project/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
end
|
||||
|
||||
def test_call_hook_from_view_with_controller_added_to_context
|
||||
@hook_module.add_listener(TestHook3)
|
||||
assert_match /controller/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
end
|
||||
|
||||
def test_call_hook_from_view_with_request_added_to_context
|
||||
@hook_module.add_listener(TestHook3)
|
||||
assert_match /request/i, view_hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
end
|
||||
|
||||
def test_call_hook_from_view_should_join_responses_with_a_space
|
||||
@hook_module.add_listener(TestHook1)
|
||||
@hook_module.add_listener(TestHook2)
|
||||
assert_equal 'Test hook 1 listener. Test hook 2 listener.',
|
||||
view_hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
end
|
||||
|
||||
def test_call_hook_should_not_change_the_default_url_for_email_notifications
|
||||
issue = Issue.find(1)
|
||||
|
||||
ActionMailer::Base.deliveries.clear
|
||||
Mailer.deliver_issue_add(issue)
|
||||
mail = ActionMailer::Base.deliveries.last
|
||||
|
||||
@hook_module.add_listener(TestLinkToHook)
|
||||
hook_helper.call_hook(:view_layouts_base_html_head)
|
||||
|
||||
ActionMailer::Base.deliveries.clear
|
||||
Mailer.deliver_issue_add(issue)
|
||||
mail2 = ActionMailer::Base.deliveries.last
|
||||
|
||||
assert_equal mail_body(mail), mail_body(mail2)
|
||||
end
|
||||
|
||||
def hook_helper
|
||||
@hook_helper ||= TestHookHelperController.new
|
||||
end
|
||||
|
||||
def view_hook_helper
|
||||
@view_hook_helper ||= TestHookHelperView.new(Rails.root.to_s + '/app/views')
|
||||
end
|
||||
end
|
||||
|
261
test/unit/lib/redmine/i18n_test.rb
Normal file
261
test/unit/lib/redmine/i18n_test.rb
Normal file
|
@ -0,0 +1,261 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::I18nTest < ActiveSupport::TestCase
|
||||
include Redmine::I18n
|
||||
include ActionView::Helpers::NumberHelper
|
||||
|
||||
def setup
|
||||
User.current = nil
|
||||
end
|
||||
|
||||
def teardown
|
||||
set_language_if_valid 'en'
|
||||
end
|
||||
|
||||
def test_date_format_default
|
||||
set_language_if_valid 'en'
|
||||
today = Date.today
|
||||
with_settings :date_format => '' do
|
||||
assert_equal I18n.l(today), format_date(today)
|
||||
end
|
||||
end
|
||||
|
||||
def test_date_format
|
||||
set_language_if_valid 'en'
|
||||
today = Date.today
|
||||
with_settings :date_format => '%d %m %Y' do
|
||||
assert_equal today.strftime('%d %m %Y'), format_date(today)
|
||||
end
|
||||
end
|
||||
|
||||
def test_date_format_with_month_name_should_translate_with_current_locale
|
||||
set_language_if_valid 'es'
|
||||
date = Date.parse('2011-02-20 14:00:00')
|
||||
with_settings :date_format => '%d %B %Y' do
|
||||
assert_equal '20 Febrero 2011', format_date(date)
|
||||
end
|
||||
end
|
||||
|
||||
def test_date_and_time_for_each_language
|
||||
with_settings :date_format => '' do
|
||||
valid_languages.each do |lang|
|
||||
set_language_if_valid lang
|
||||
assert_nothing_raised do
|
||||
format_date(Date.today)
|
||||
format_time(Time.now)
|
||||
format_time(Time.now, false)
|
||||
assert_not_equal 'default', ::I18n.l(Date.today, :format => :default),
|
||||
"date.formats.default missing in #{lang}"
|
||||
assert_not_equal 'time', ::I18n.l(Time.now, :format => :time),
|
||||
"time.formats.time missing in #{lang}"
|
||||
end
|
||||
assert l('date.day_names').is_a?(Array)
|
||||
assert_equal 7, l('date.day_names').size
|
||||
|
||||
assert l('date.month_names').is_a?(Array)
|
||||
assert_equal 13, l('date.month_names').size
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_time_for_each_zone
|
||||
ActiveSupport::TimeZone.all.each do |zone|
|
||||
User.current.stubs(:time_zone).returns(zone.name)
|
||||
assert_nothing_raised do
|
||||
format_time(Time.now)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_time_format
|
||||
set_language_if_valid 'en'
|
||||
now = Time.parse('2011-02-20 15:45:22')
|
||||
with_settings :time_format => '%H:%M' do
|
||||
with_settings :date_format => '' do
|
||||
assert_equal '02/20/2011 15:45', format_time(now)
|
||||
assert_equal '15:45', format_time(now, false)
|
||||
end
|
||||
with_settings :date_format => '%Y-%m-%d' do
|
||||
assert_equal '2011-02-20 15:45', format_time(now)
|
||||
assert_equal '15:45', format_time(now, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_time_format_default
|
||||
set_language_if_valid 'en'
|
||||
now = Time.parse('2011-02-20 15:45:22')
|
||||
with_settings :time_format => '' do
|
||||
with_settings :date_format => '' do
|
||||
assert_equal '02/20/2011 03:45 PM', format_time(now)
|
||||
assert_equal '03:45 PM', format_time(now, false)
|
||||
end
|
||||
with_settings :date_format => '%Y-%m-%d' do
|
||||
assert_equal '2011-02-20 03:45 PM', format_time(now)
|
||||
assert_equal '03:45 PM', format_time(now, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_utc_time_format
|
||||
set_language_if_valid 'en'
|
||||
now = Time.now
|
||||
with_settings :date_format => '%d %m %Y', :time_format => '%H %M' do
|
||||
assert_equal now.localtime.strftime('%d %m %Y %H %M'), format_time(now.utc), "User time zone was #{User.current.time_zone}"
|
||||
assert_equal now.localtime.strftime('%H %M'), format_time(now.utc, false)
|
||||
end
|
||||
end
|
||||
|
||||
def test_number_to_human_size_for_each_language
|
||||
valid_languages.each do |lang|
|
||||
set_language_if_valid lang
|
||||
assert_nothing_raised do
|
||||
size = number_to_human_size(257024)
|
||||
assert_match /251/, size, "#{lang} failure"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_day_name
|
||||
set_language_if_valid 'fr'
|
||||
assert_equal 'dimanche', day_name(0)
|
||||
assert_equal 'jeudi', day_name(4)
|
||||
end
|
||||
|
||||
def test_day_letter
|
||||
set_language_if_valid 'fr'
|
||||
assert_equal 'd', day_letter(0)
|
||||
assert_equal 'j', day_letter(4)
|
||||
end
|
||||
|
||||
def test_number_to_currency_for_each_language
|
||||
valid_languages.each do |lang|
|
||||
set_language_if_valid lang
|
||||
assert_nothing_raised do
|
||||
number_to_currency(-1000.2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_l_hours_short
|
||||
set_language_if_valid 'en'
|
||||
assert_equal '2.00 h', l_hours_short(2.0)
|
||||
end
|
||||
|
||||
def test_number_to_currency_default
|
||||
set_language_if_valid 'bs'
|
||||
assert_equal "KM -1000,20", number_to_currency(-1000.2)
|
||||
set_language_if_valid 'de'
|
||||
euro_sign = "\xe2\x82\xac".force_encoding('UTF-8')
|
||||
assert_equal "-1000,20 #{euro_sign}", number_to_currency(-1000.2)
|
||||
end
|
||||
|
||||
def test_lu_should_not_error_when_user_language_is_an_empty_string
|
||||
user = User.new
|
||||
user.language = ''
|
||||
|
||||
assert_nothing_raised do
|
||||
lu(user, :label_issue)
|
||||
end
|
||||
end
|
||||
|
||||
def test_valid_languages
|
||||
assert valid_languages.is_a?(Array)
|
||||
assert valid_languages.first.is_a?(Symbol)
|
||||
end
|
||||
|
||||
def test_languages_options
|
||||
options = languages_options
|
||||
assert options.is_a?(Array)
|
||||
assert_equal valid_languages.size, options.size
|
||||
assert_nil options.detect {|option| !option.is_a?(Array)}
|
||||
assert_nil options.detect {|option| option.size != 2}
|
||||
assert_nil options.detect {|option| !option.first.is_a?(String) || !option.last.is_a?(String)}
|
||||
assert_include ["English", "en"], options
|
||||
ja = "Japanese (\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e)".force_encoding('UTF-8')
|
||||
assert_include [ja, "ja"], options
|
||||
end
|
||||
|
||||
def test_languages_options_should_return_strings_with_utf8_encoding
|
||||
strings = languages_options.flatten
|
||||
assert_equal ["UTF-8"], strings.map(&:encoding).uniq.map(&:name).sort
|
||||
end
|
||||
|
||||
def test_languages_options_should_ignore_locales_without_general_lang_name_key
|
||||
stubs(:valid_languages).returns([:en, :foo])
|
||||
assert_equal [["English", "en"]], languages_options(:cache => false)
|
||||
end
|
||||
|
||||
def test_locales_validness
|
||||
lang_files_count = Dir["#{Rails.root}/config/locales/*.yml"].size
|
||||
assert_equal lang_files_count, valid_languages.size
|
||||
valid_languages.each do |lang|
|
||||
assert set_language_if_valid(lang)
|
||||
end
|
||||
set_language_if_valid('en')
|
||||
end
|
||||
|
||||
def test_valid_language
|
||||
to_test = {'fr' => :fr,
|
||||
'Fr' => :fr,
|
||||
'zh' => :zh,
|
||||
'zh-tw' => :"zh-TW",
|
||||
'zh-TW' => :"zh-TW"}
|
||||
to_test.each {|lang, expected| assert_equal expected, find_language(lang)}
|
||||
end
|
||||
|
||||
def test_find_language_with_invalid_language_should_return_nil
|
||||
assert_nil find_language('zh-ZZ')
|
||||
end
|
||||
|
||||
def test_fallback
|
||||
::I18n.backend.store_translations(:en, {:untranslated => "Untranslated string"})
|
||||
::I18n.locale = 'en'
|
||||
assert_equal "Untranslated string", l(:untranslated)
|
||||
::I18n.locale = 'fr'
|
||||
assert_equal "Untranslated string", l(:untranslated)
|
||||
|
||||
::I18n.backend.store_translations(:fr, {:untranslated => "Pas de traduction"})
|
||||
::I18n.locale = 'en'
|
||||
assert_equal "Untranslated string", l(:untranslated)
|
||||
::I18n.locale = 'fr'
|
||||
assert_equal "Pas de traduction", l(:untranslated)
|
||||
end
|
||||
|
||||
def test_utf8
|
||||
set_language_if_valid 'ja'
|
||||
str_ja_yes = "\xe3\x81\xaf\xe3\x81\x84".force_encoding('UTF-8')
|
||||
i18n_ja_yes = l(:general_text_Yes)
|
||||
assert_equal str_ja_yes, i18n_ja_yes
|
||||
assert_equal "UTF-8", i18n_ja_yes.encoding.to_s
|
||||
end
|
||||
|
||||
def test_traditional_chinese_locale
|
||||
set_language_if_valid 'zh-TW'
|
||||
str_tw = "Traditional Chinese (\xe7\xb9\x81\xe9\xab\x94\xe4\xb8\xad\xe6\x96\x87)".force_encoding('UTF-8')
|
||||
assert_equal str_tw, l(:general_lang_name)
|
||||
end
|
||||
|
||||
def test_french_locale
|
||||
set_language_if_valid 'fr'
|
||||
str_fr = "French (Fran\xc3\xa7ais)".force_encoding('UTF-8')
|
||||
assert_equal str_fr, l(:general_lang_name)
|
||||
end
|
||||
end
|
27
test/unit/lib/redmine/info_test.rb
Normal file
27
test/unit/lib/redmine/info_test.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::InfoTest < ActiveSupport::TestCase
|
||||
def test_environment
|
||||
env = Redmine::Info.environment
|
||||
|
||||
assert_kind_of String, env
|
||||
assert_match 'Redmine version', env
|
||||
end
|
||||
end
|
191
test/unit/lib/redmine/menu_manager/mapper_test.rb
Normal file
191
test/unit/lib/redmine/menu_manager/mapper_test.rb
Normal file
|
@ -0,0 +1,191 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::MenuManager::MapperTest < ActiveSupport::TestCase
|
||||
test "Mapper#initialize should define a root MenuNode if menu is not present in items" do
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
node = menu_mapper.menu_items
|
||||
assert_not_nil node
|
||||
assert_equal :root, node.name
|
||||
end
|
||||
|
||||
test "Mapper#initialize should use existing MenuNode if present" do
|
||||
node = "foo" # just an arbitrary reference
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {:test_menu => node})
|
||||
assert_equal node, menu_mapper.menu_items
|
||||
end
|
||||
|
||||
def test_push_onto_root
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
|
||||
menu_mapper.exists?(:test_overview)
|
||||
end
|
||||
|
||||
def test_push_onto_parent
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
|
||||
|
||||
assert menu_mapper.exists?(:test_child)
|
||||
assert_equal :test_child, menu_mapper.find(:test_child).name
|
||||
end
|
||||
|
||||
def test_push_onto_grandparent
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview}
|
||||
menu_mapper.push :test_grandchild, { :controller => 'projects', :action => 'show'}, {:parent => :test_child}
|
||||
|
||||
assert menu_mapper.exists?(:test_grandchild)
|
||||
grandchild = menu_mapper.find(:test_grandchild)
|
||||
assert_equal :test_grandchild, grandchild.name
|
||||
assert_equal :test_child, grandchild.parent.name
|
||||
end
|
||||
|
||||
def test_push_first
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {:first => true}
|
||||
|
||||
root = menu_mapper.find(:root)
|
||||
assert_equal 5, root.children.size
|
||||
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
|
||||
assert_not_nil root.children[position]
|
||||
assert_equal name, root.children[position].name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_push_before
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {:before => :test_fourth}
|
||||
|
||||
root = menu_mapper.find(:root)
|
||||
assert_equal 5, root.children.size
|
||||
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
|
||||
assert_not_nil root.children[position]
|
||||
assert_equal name, root.children[position].name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_push_after
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {:after => :test_third}
|
||||
|
||||
root = menu_mapper.find(:root)
|
||||
assert_equal 5, root.children.size
|
||||
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
|
||||
assert_not_nil root.children[position]
|
||||
assert_equal name, root.children[position].name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_push_last
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_first, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_second, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_third, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_fifth, { :controller => 'projects', :action => 'show'}, {:last => true}
|
||||
menu_mapper.push :test_fourth, { :controller => 'projects', :action => 'show'}, {}
|
||||
|
||||
root = menu_mapper.find(:root)
|
||||
assert_equal 5, root.children.size
|
||||
{0 => :test_first, 1 => :test_second, 2 => :test_third, 3 => :test_fourth, 4 => :test_fifth}.each do |position, name|
|
||||
assert_not_nil root.children[position]
|
||||
assert_equal name, root.children[position].name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_exists_for_child_node
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
menu_mapper.push :test_child, { :controller => 'projects', :action => 'show'}, {:parent => :test_overview }
|
||||
|
||||
assert menu_mapper.exists?(:test_child)
|
||||
end
|
||||
|
||||
def test_exists_for_invalid_node
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
|
||||
assert !menu_mapper.exists?(:nothing)
|
||||
end
|
||||
|
||||
def test_find
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
|
||||
item = menu_mapper.find(:test_overview)
|
||||
assert_equal :test_overview, item.name
|
||||
assert_equal({:controller => 'projects', :action => 'show'}, item.url)
|
||||
end
|
||||
|
||||
def test_find_missing
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
|
||||
item = menu_mapper.find(:nothing)
|
||||
assert_nil item
|
||||
end
|
||||
|
||||
def test_delete
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
menu_mapper.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
assert_not_nil menu_mapper.delete(:test_overview)
|
||||
|
||||
assert_nil menu_mapper.find(:test_overview)
|
||||
end
|
||||
|
||||
def test_delete_missing
|
||||
menu_mapper = Redmine::MenuManager::Mapper.new(:test_menu, {})
|
||||
assert_nil menu_mapper.delete(:test_missing)
|
||||
end
|
||||
|
||||
test 'deleting all items' do
|
||||
# Exposed by deleting :last items
|
||||
Redmine::MenuManager.map :test_menu do |menu|
|
||||
menu.push :not_last, Redmine::Info.help_url
|
||||
menu.push :administration, { :controller => 'projects', :action => 'show'}, {:last => true}
|
||||
menu.push :help, Redmine::Info.help_url, :last => true
|
||||
end
|
||||
|
||||
assert_nothing_raised do
|
||||
Redmine::MenuManager.map :test_menu do |menu|
|
||||
menu.delete(:administration)
|
||||
menu.delete(:help)
|
||||
menu.push :test_overview, { :controller => 'projects', :action => 'show'}, {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
342
test/unit/lib/redmine/menu_manager/menu_helper_test.rb
Normal file
342
test/unit/lib/redmine/menu_manager/menu_helper_test.rb
Normal file
|
@ -0,0 +1,342 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::MenuManager::MenuHelperTest < Redmine::HelperTest
|
||||
include Redmine::MenuManager::MenuHelper
|
||||
include ERB::Util
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
fixtures :users, :members, :projects, :enabled_modules, :roles, :member_roles
|
||||
|
||||
def setup
|
||||
setup_with_controller
|
||||
# Stub the current menu item in the controller
|
||||
def current_menu_item
|
||||
:index
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_single_menu_node
|
||||
node = Redmine::MenuManager::MenuItem.new(:testing, '/test', { })
|
||||
@output_buffer = render_single_menu_node(node, 'This is a test', node.url, false)
|
||||
|
||||
assert_select("a.testing", "This is a test")
|
||||
end
|
||||
|
||||
def test_render_menu_node
|
||||
single_node = Redmine::MenuManager::MenuItem.new(:single_node, '/test', { })
|
||||
@output_buffer = render_menu_node(single_node, nil)
|
||||
|
||||
assert_select("li") do
|
||||
assert_select("a.single-node", "Single node")
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_symbol_as_url
|
||||
node = Redmine::MenuManager::MenuItem.new(:testing, :issues_path)
|
||||
@output_buffer = render_menu_node(node, nil)
|
||||
|
||||
assert_select 'a[href="/issues"]', "Testing"
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_symbol_as_url_and_project
|
||||
node = Redmine::MenuManager::MenuItem.new(:testing, :project_issues_path)
|
||||
@output_buffer = render_menu_node(node, Project.find(1))
|
||||
|
||||
assert_select 'a[href="/projects/ecookbook/issues"]', "Testing"
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_nested_items
|
||||
parent_node = Redmine::MenuManager::MenuItem.new(:parent_node, '/test', { })
|
||||
parent_node << Redmine::MenuManager::MenuItem.new(:child_one_node, '/test', { })
|
||||
parent_node << Redmine::MenuManager::MenuItem.new(:child_two_node, '/test', { })
|
||||
parent_node <<
|
||||
Redmine::MenuManager::MenuItem.new(:child_three_node, '/test', { }) <<
|
||||
Redmine::MenuManager::MenuItem.new(:child_three_inner_node, '/test', { })
|
||||
|
||||
@output_buffer = render_menu_node(parent_node, nil)
|
||||
|
||||
assert_select("li") do
|
||||
assert_select("a.parent-node", "Parent node")
|
||||
assert_select("ul") do
|
||||
assert_select("li a.child-one-node", "Child one node")
|
||||
assert_select("li a.child-two-node", "Child two node")
|
||||
assert_select("li") do
|
||||
assert_select("a.child-three-node", "Child three node")
|
||||
assert_select("ul") do
|
||||
assert_select("li a.child-three-inner-node", "Child three inner node")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_children
|
||||
User.current = User.find(2)
|
||||
|
||||
parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
|
||||
'/test',
|
||||
{
|
||||
:children => Proc.new {|p|
|
||||
children = []
|
||||
3.times do |time|
|
||||
children << Redmine::MenuManager::MenuItem.new("test_child_#{time}",
|
||||
{:controller => 'issues', :action => 'index'},
|
||||
{})
|
||||
end
|
||||
children
|
||||
}
|
||||
})
|
||||
@output_buffer = render_menu_node(parent_node, Project.find(1))
|
||||
|
||||
assert_select("li") do
|
||||
assert_select("a.parent-node", "Parent node")
|
||||
assert_select("ul") do
|
||||
assert_select("li a.test-child-0", "Test child 0")
|
||||
assert_select("li a.test-child-1", "Test child 1")
|
||||
assert_select("li a.test-child-2", "Test child 2")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_nested_items_and_children
|
||||
User.current = User.find(2)
|
||||
|
||||
parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
|
||||
{:controller => 'issues', :action => 'index'},
|
||||
{
|
||||
:children => Proc.new {|p|
|
||||
children = []
|
||||
3.times do |time|
|
||||
children << Redmine::MenuManager::MenuItem.new("test_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
|
||||
end
|
||||
children
|
||||
}
|
||||
})
|
||||
|
||||
parent_node << Redmine::MenuManager::MenuItem.new(:child_node,
|
||||
{:controller => 'issues', :action => 'index'},
|
||||
{
|
||||
:children => Proc.new {|p|
|
||||
children = []
|
||||
6.times do |time|
|
||||
children << Redmine::MenuManager::MenuItem.new("test_dynamic_child_#{time}", {:controller => 'issues', :action => 'index'}, {})
|
||||
end
|
||||
children
|
||||
}
|
||||
})
|
||||
|
||||
@output_buffer = render_menu_node(parent_node, Project.find(1))
|
||||
|
||||
assert_select("li") do
|
||||
assert_select("a.parent-node", "Parent node")
|
||||
assert_select("ul") do
|
||||
assert_select("li a.child-node", "Child node")
|
||||
assert_select("ul") do
|
||||
assert_select("li a.test-dynamic-child-0", "Test dynamic child 0")
|
||||
assert_select("li a.test-dynamic-child-1", "Test dynamic child 1")
|
||||
assert_select("li a.test-dynamic-child-2", "Test dynamic child 2")
|
||||
assert_select("li a.test-dynamic-child-3", "Test dynamic child 3")
|
||||
assert_select("li a.test-dynamic-child-4", "Test dynamic child 4")
|
||||
assert_select("li a.test-dynamic-child-5", "Test dynamic child 5")
|
||||
end
|
||||
assert_select("li a.test-child-0", "Test child 0")
|
||||
assert_select("li a.test-child-1", "Test child 1")
|
||||
assert_select("li a.test-child-2", "Test child 2")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_allowed_and_unallowed_unattached_children
|
||||
User.current = User.find(2)
|
||||
|
||||
parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
|
||||
{:controller => 'issues', :action => 'index'},
|
||||
{
|
||||
:children => Proc.new {|p|
|
||||
[
|
||||
Redmine::MenuManager::MenuItem.new("test_child_allowed", {:controller => 'issues', :action => 'index'}, {}),
|
||||
Redmine::MenuManager::MenuItem.new("test_child_unallowed", {:controller => 'issues', :action => 'unallowed'}, {}),
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
@output_buffer = render_menu_node(parent_node, Project.find(1))
|
||||
|
||||
assert_select("li") do
|
||||
assert_select("a.parent-node", "Parent node")
|
||||
assert_select("ul.menu-children.unattached") do
|
||||
assert_select("li a.test-child-allowed", "Test child allowed")
|
||||
assert_select("li a.test-child-unallowed", false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_allowed_and_unallowed_standard_children
|
||||
User.current = User.find(6)
|
||||
|
||||
Redmine::MenuManager.map :some_menu do |menu|
|
||||
menu.push(:parent_node, {:controller => 'issues', :action => 'index'}, { })
|
||||
menu.push(:test_child_allowed, {:controller => 'issues', :action => 'index'}, {:parent => :parent_node})
|
||||
menu.push(:test_child_unallowed, {:controller => 'issues', :action => 'new'}, {:parent => :parent_node})
|
||||
end
|
||||
|
||||
@output_buffer = render_menu(:some_menu, Project.find(1))
|
||||
|
||||
assert_select("li") do
|
||||
assert_select("a.parent-node", "Parent node")
|
||||
assert_select("ul.menu-children.unattached", false)
|
||||
assert_select("ul.menu-children") do
|
||||
assert_select("li a.test-child-allowed", "Test child allowed")
|
||||
assert_select("li a.test-child-unallowed", false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_empty_virtual_menu_node_with_children
|
||||
|
||||
# only empty item with no click target
|
||||
Redmine::MenuManager.map :menu1 do |menu|
|
||||
menu.push(:parent_node, nil, { })
|
||||
end
|
||||
|
||||
# parent with unallowed unattached child
|
||||
Redmine::MenuManager.map :menu2 do |menu|
|
||||
menu.push(:parent_node, nil, {:children => Proc.new {|p|
|
||||
[Redmine::MenuManager::MenuItem.new("test_child_unallowed", {:controller => 'issues', :action => 'new'}, {})]
|
||||
} })
|
||||
end
|
||||
|
||||
# parent with unallowed standard child
|
||||
Redmine::MenuManager.map :menu3 do |menu|
|
||||
menu.push(:parent_node, nil, {})
|
||||
menu.push(:test_child_unallowed, {:controller =>'issues', :action => 'new'}, {:parent => :parent_node})
|
||||
end
|
||||
|
||||
# should not be displayed to anonymous
|
||||
User.current = User.find(6)
|
||||
assert_nil render_menu(:menu1, Project.find(1))
|
||||
assert_nil render_menu(:menu2, Project.find(1))
|
||||
assert_nil render_menu(:menu3, Project.find(1))
|
||||
|
||||
# should be displayed to an admin
|
||||
User.current = User.find(1)
|
||||
@output_buffer = render_menu(:menu2, Project.find(1))
|
||||
assert_select("ul li a.parent-node", "Parent node")
|
||||
@output_buffer = render_menu(:menu3, Project.find(1))
|
||||
assert_select("ul li a.parent-node", "Parent node")
|
||||
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_children_without_an_array
|
||||
parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
|
||||
'/test',
|
||||
{
|
||||
:children => Proc.new {|p| Redmine::MenuManager::MenuItem.new("test_child", "/testing", {})}
|
||||
})
|
||||
|
||||
assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
|
||||
@output_buffer = render_menu_node(parent_node, Project.find(1))
|
||||
end
|
||||
end
|
||||
|
||||
def test_render_menu_node_with_incorrect_children
|
||||
parent_node = Redmine::MenuManager::MenuItem.new(:parent_node,
|
||||
'/test',
|
||||
{
|
||||
:children => Proc.new {|p| ["a string"] }
|
||||
})
|
||||
|
||||
assert_raises Redmine::MenuManager::MenuError, ":children must be an array of MenuItems" do
|
||||
@output_buffer = render_menu_node(parent_node, Project.find(1))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_menu_items_for_should_yield_all_items_if_passed_a_block
|
||||
menu_name = :test_menu_items_for_should_yield_all_items_if_passed_a_block
|
||||
Redmine::MenuManager.map menu_name do |menu|
|
||||
menu.push(:a_menu, '/', { })
|
||||
menu.push(:a_menu_2, '/', { })
|
||||
menu.push(:a_menu_3, '/', { })
|
||||
end
|
||||
|
||||
items_yielded = []
|
||||
menu_items_for(menu_name) do |item|
|
||||
items_yielded << item
|
||||
end
|
||||
|
||||
assert_equal 3, items_yielded.size
|
||||
end
|
||||
|
||||
def test_menu_items_for_should_return_all_items
|
||||
menu_name = :test_menu_items_for_should_return_all_items
|
||||
Redmine::MenuManager.map menu_name do |menu|
|
||||
menu.push(:a_menu, '/', { })
|
||||
menu.push(:a_menu_2, '/', { })
|
||||
menu.push(:a_menu_3, '/', { })
|
||||
end
|
||||
|
||||
items = menu_items_for(menu_name)
|
||||
assert_equal 3, items.size
|
||||
end
|
||||
|
||||
def test_menu_items_for_should_skip_unallowed_items_on_a_project
|
||||
menu_name = :test_menu_items_for_should_skip_unallowed_items_on_a_project
|
||||
Redmine::MenuManager.map menu_name do |menu|
|
||||
menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
|
||||
menu.push(:a_menu_2, {:controller => 'issues', :action => 'index' }, { })
|
||||
menu.push(:unallowed, {:controller => 'issues', :action => 'unallowed' }, { })
|
||||
end
|
||||
|
||||
User.current = User.find(2)
|
||||
|
||||
items = menu_items_for(menu_name, Project.find(1))
|
||||
assert_equal 2, items.size
|
||||
end
|
||||
|
||||
def test_menu_items_for_should_skip_items_that_fail_the_permission
|
||||
menu_name = :test_menu_items_for_should_skip_items_that_fail_the_permission
|
||||
Redmine::MenuManager.map menu_name do |menu|
|
||||
menu.push(:a_menu, :project_issues_path)
|
||||
menu.push(:unallowed, :project_issues_path, :permission => :unallowed)
|
||||
end
|
||||
|
||||
User.current = User.find(2)
|
||||
|
||||
items = menu_items_for(menu_name, Project.find(1))
|
||||
assert_equal 1, items.size
|
||||
end
|
||||
|
||||
def test_menu_items_for_should_skip_items_that_fail_the_conditions
|
||||
menu_name = :test_menu_items_for_should_skip_items_that_fail_the_conditions
|
||||
Redmine::MenuManager.map menu_name do |menu|
|
||||
menu.push(:a_menu, {:controller => 'issues', :action => 'index' }, { })
|
||||
menu.push(:unallowed,
|
||||
{:controller => 'issues', :action => 'index' },
|
||||
{ :if => Proc.new { false }})
|
||||
end
|
||||
|
||||
User.current = User.find(2)
|
||||
|
||||
items = menu_items_for(menu_name, Project.find(1))
|
||||
assert_equal 1, items.size
|
||||
end
|
||||
end
|
108
test/unit/lib/redmine/menu_manager/menu_item_test.rb
Normal file
108
test/unit/lib/redmine/menu_manager/menu_item_test.rb
Normal file
|
@ -0,0 +1,108 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
module RedmineMenuTestHelper
|
||||
# Helpers
|
||||
def get_menu_item(menu_name, item_name)
|
||||
Redmine::MenuManager.items(menu_name).find {|item| item.name == item_name.to_sym}
|
||||
end
|
||||
end
|
||||
|
||||
class Redmine::MenuManager::MenuItemTest < ActiveSupport::TestCase
|
||||
include RedmineMenuTestHelper
|
||||
|
||||
Redmine::MenuManager.map :test_menu do |menu|
|
||||
menu.push(:parent, '/test', { })
|
||||
menu.push(:child_menu, '/test', { :parent => :parent})
|
||||
menu.push(:child2_menu, '/test', { :parent => :parent})
|
||||
end
|
||||
|
||||
# context new menu item
|
||||
def test_new_menu_item_should_require_a_name
|
||||
assert_raises ArgumentError do
|
||||
Redmine::MenuManager::MenuItem.new
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_menu_item_should_require_an_url
|
||||
assert_raises ArgumentError do
|
||||
Redmine::MenuManager::MenuItem.new(:test_missing_url)
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_menu_item_with_all_required_parameters
|
||||
assert Redmine::MenuManager::MenuItem.new(:test_good_menu, '/test', {})
|
||||
end
|
||||
|
||||
def test_new_menu_item_should_require_a_proc_to_use_for_the_if_condition
|
||||
assert_raises ArgumentError do
|
||||
Redmine::MenuManager::MenuItem.new(:test_error, '/test',
|
||||
{
|
||||
:if => ['not_a_proc']
|
||||
})
|
||||
end
|
||||
|
||||
assert Redmine::MenuManager::MenuItem.new(:test_good_if, '/test',
|
||||
{
|
||||
:if => Proc.new{}
|
||||
})
|
||||
end
|
||||
|
||||
def test_new_menu_item_should_allow_a_hash_for_extra_html_options
|
||||
assert_raises ArgumentError do
|
||||
Redmine::MenuManager::MenuItem.new(:test_error, '/test',
|
||||
{
|
||||
:html => ['not_a_hash']
|
||||
})
|
||||
end
|
||||
|
||||
assert Redmine::MenuManager::MenuItem.new(:test_good_html, '/test',
|
||||
{
|
||||
:html => { :onclick => 'doSomething'}
|
||||
})
|
||||
end
|
||||
|
||||
def test_new_menu_item_should_require_a_proc_to_use_the_children_option
|
||||
assert_raises ArgumentError do
|
||||
Redmine::MenuManager::MenuItem.new(:test_error, '/test',
|
||||
{
|
||||
:children => ['not_a_proc']
|
||||
})
|
||||
end
|
||||
|
||||
assert Redmine::MenuManager::MenuItem.new(:test_good_children, '/test',
|
||||
{
|
||||
:children => Proc.new{}
|
||||
})
|
||||
end
|
||||
|
||||
def test_new_should_not_allow_setting_the_parent_item_to_the_current_item
|
||||
assert_raises ArgumentError do
|
||||
Redmine::MenuManager::MenuItem.new(:test_error, '/test', { :parent => :test_error })
|
||||
end
|
||||
end
|
||||
|
||||
def test_has_children
|
||||
parent_item = get_menu_item(:test_menu, :parent)
|
||||
assert parent_item.children.present?
|
||||
assert_equal 2, parent_item.children.size
|
||||
assert_equal get_menu_item(:test_menu, :child_menu), parent_item.children[0]
|
||||
assert_equal get_menu_item(:test_menu, :child2_menu), parent_item.children[1]
|
||||
end
|
||||
end
|
34
test/unit/lib/redmine/menu_manager_test.rb
Normal file
34
test/unit/lib/redmine/menu_manager_test.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::MenuManagerTest < ActiveSupport::TestCase
|
||||
def test_map_should_yield_a_mapper
|
||||
assert_difference 'Redmine::MenuManager.items(:project_menu).size' do
|
||||
Redmine::MenuManager.map :project_menu do |mapper|
|
||||
assert_kind_of Redmine::MenuManager::Mapper, mapper
|
||||
mapper.push :new_item, '/'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_items_should_return_menu_items
|
||||
items = Redmine::MenuManager.items(:project_menu)
|
||||
assert_kind_of Redmine::MenuManager::MenuNode, items.first
|
||||
end
|
||||
end
|
75
test/unit/lib/redmine/mime_type_test.rb
Normal file
75
test/unit/lib/redmine/mime_type_test.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::MimeTypeTest < ActiveSupport::TestCase
|
||||
|
||||
def test_of
|
||||
to_test = {'test.txt' => 'text/plain',
|
||||
'test.c' => 'text/x-c',
|
||||
}
|
||||
to_test.each do |name, expected|
|
||||
assert_equal expected, Redmine::MimeType.of(name)
|
||||
end
|
||||
end
|
||||
|
||||
def test_of_with_unknown_type
|
||||
assert_nil Redmine::MimeType.of('test.unk')
|
||||
end
|
||||
|
||||
def test_css_class_of
|
||||
to_test = {'test.txt' => 'text-plain',
|
||||
'test.c' => 'text-x-c',
|
||||
}
|
||||
to_test.each do |name, expected|
|
||||
assert_equal expected, Redmine::MimeType.css_class_of(name)
|
||||
end
|
||||
end
|
||||
|
||||
def test_css_class_of_with_unknown_type
|
||||
assert_nil Redmine::MimeType.css_class_of('test.unk')
|
||||
end
|
||||
|
||||
def test_main_mimetype_of
|
||||
to_test = {'test.txt' => 'text',
|
||||
'test.c' => 'text',
|
||||
}
|
||||
to_test.each do |name, expected|
|
||||
assert_equal expected, Redmine::MimeType.main_mimetype_of(name)
|
||||
end
|
||||
end
|
||||
|
||||
def test_main_mimetype_of_with_unknown_type
|
||||
assert_nil Redmine::MimeType.main_mimetype_of('test.unk')
|
||||
end
|
||||
|
||||
def test_is_type
|
||||
to_test = {['text', 'test.unk'] => false,
|
||||
['text', 'test.txt'] => true,
|
||||
['text', 'test.c'] => true,
|
||||
}
|
||||
to_test.each do |args, expected|
|
||||
assert_equal expected, Redmine::MimeType.is_type?(*args)
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_default_to_mime_type_gem
|
||||
assert !Redmine::MimeType::EXTENSIONS.keys.include?("zip")
|
||||
assert_equal "application/zip", Redmine::MimeType.of("file.zip")
|
||||
end
|
||||
end
|
29
test/unit/lib/redmine/notifiable_test.rb
Normal file
29
test/unit/lib/redmine/notifiable_test.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::NotifiableTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
end
|
||||
|
||||
def test_all
|
||||
%w(issue_added issue_updated issue_note_added issue_status_updated issue_assigned_to_updated issue_priority_updated news_added news_comment_added document_added file_added message_posted wiki_content_added wiki_content_updated).each do |notifiable|
|
||||
assert Redmine::Notifiable.all.collect(&:name).include?(notifiable), "missing #{notifiable}"
|
||||
end
|
||||
end
|
||||
end
|
34
test/unit/lib/redmine/pagination_helper_test.rb
Normal file
34
test/unit/lib/redmine/pagination_helper_test.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class PaginationHelperTest < ActionView::TestCase
|
||||
include Redmine::Pagination::Helper
|
||||
|
||||
def test_per_page_options_should_return_usefull_values
|
||||
with_settings :per_page_options => '10, 25, 50, 100' do
|
||||
assert_equal [], per_page_options(10, 3)
|
||||
assert_equal [], per_page_options(25, 3)
|
||||
assert_equal [10, 25], per_page_options(10, 22)
|
||||
assert_equal [10, 25], per_page_options(25, 22)
|
||||
assert_equal [10, 25, 50], per_page_options(50, 22)
|
||||
assert_equal [10, 25, 50], per_page_options(25, 26)
|
||||
assert_equal [10, 25, 50, 100], per_page_options(25, 120)
|
||||
end
|
||||
end
|
||||
end
|
94
test/unit/lib/redmine/pagination_test.rb
Normal file
94
test/unit/lib/redmine/pagination_test.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::PaginationTest < ActiveSupport::TestCase
|
||||
|
||||
def setup
|
||||
@klass = Redmine::Pagination::Paginator
|
||||
end
|
||||
|
||||
def test_count_is_zero
|
||||
p = @klass.new 0, 10, 1
|
||||
|
||||
assert_equal 0, p.offset
|
||||
assert_equal 10, p.per_page
|
||||
%w(first_page previous_page next_page last_page).each do |method|
|
||||
assert_nil p.send(method), "#{method} was not nil"
|
||||
end
|
||||
assert_equal 0, p.first_item
|
||||
assert_equal 0, p.last_item
|
||||
assert_equal [], p.linked_pages
|
||||
end
|
||||
|
||||
def test_count_is_less_than_per_page
|
||||
p = @klass.new 7, 10, 1
|
||||
|
||||
assert_equal 0, p.offset
|
||||
assert_equal 10, p.per_page
|
||||
assert_equal 1, p.first_page
|
||||
assert_nil p.previous_page
|
||||
assert_nil p.next_page
|
||||
assert_equal 1, p.last_page
|
||||
assert_equal 1, p.first_item
|
||||
assert_equal 7, p.last_item
|
||||
assert_equal [], p.linked_pages
|
||||
end
|
||||
|
||||
def test_count_is_equal_to_per_page
|
||||
p = @klass.new 10, 10, 1
|
||||
|
||||
assert_equal 0, p.offset
|
||||
assert_equal 10, p.per_page
|
||||
assert_equal 1, p.first_page
|
||||
assert_nil p.previous_page
|
||||
assert_nil p.next_page
|
||||
assert_equal 1, p.last_page
|
||||
assert_equal 1, p.first_item
|
||||
assert_equal 10, p.last_item
|
||||
assert_equal [], p.linked_pages
|
||||
end
|
||||
|
||||
def test_2_pages
|
||||
p = @klass.new 16, 10, 1
|
||||
|
||||
assert_equal 0, p.offset
|
||||
assert_equal 10, p.per_page
|
||||
assert_equal 1, p.first_page
|
||||
assert_nil p.previous_page
|
||||
assert_equal 2, p.next_page
|
||||
assert_equal 2, p.last_page
|
||||
assert_equal 1, p.first_item
|
||||
assert_equal 10, p.last_item
|
||||
assert_equal [1, 2], p.linked_pages
|
||||
end
|
||||
|
||||
def test_many_pages
|
||||
p = @klass.new 155, 10, 1
|
||||
|
||||
assert_equal 0, p.offset
|
||||
assert_equal 10, p.per_page
|
||||
assert_equal 1, p.first_page
|
||||
assert_nil p.previous_page
|
||||
assert_equal 2, p.next_page
|
||||
assert_equal 16, p.last_page
|
||||
assert_equal 1, p.first_item
|
||||
assert_equal 10, p.last_item
|
||||
assert_equal [1, 2, 3, 16], p.linked_pages
|
||||
end
|
||||
end
|
186
test/unit/lib/redmine/plugin_test.rb
Normal file
186
test/unit/lib/redmine/plugin_test.rb
Normal file
|
@ -0,0 +1,186 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::PluginTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
@klass = Redmine::Plugin
|
||||
# In case some real plugins are installed
|
||||
@klass.clear
|
||||
end
|
||||
|
||||
def teardown
|
||||
@klass.clear
|
||||
end
|
||||
|
||||
def test_register
|
||||
@klass.register :foo do
|
||||
name 'Foo plugin'
|
||||
url 'http://example.net/plugins/foo'
|
||||
author 'John Smith'
|
||||
author_url 'http://example.net/jsmith'
|
||||
description 'This is a test plugin'
|
||||
version '0.0.1'
|
||||
settings :default => {'sample_setting' => 'value', 'foo'=>'bar'}, :partial => 'foo/settings'
|
||||
end
|
||||
|
||||
assert_equal 1, @klass.all.size
|
||||
|
||||
plugin = @klass.find('foo')
|
||||
assert plugin.is_a?(Redmine::Plugin)
|
||||
assert_equal :foo, plugin.id
|
||||
assert_equal 'Foo plugin', plugin.name
|
||||
assert_equal 'http://example.net/plugins/foo', plugin.url
|
||||
assert_equal 'John Smith', plugin.author
|
||||
assert_equal 'http://example.net/jsmith', plugin.author_url
|
||||
assert_equal 'This is a test plugin', plugin.description
|
||||
assert_equal '0.0.1', plugin.version
|
||||
end
|
||||
|
||||
def test_installed
|
||||
@klass.register(:foo) {}
|
||||
assert_equal true, @klass.installed?(:foo)
|
||||
assert_equal false, @klass.installed?(:bar)
|
||||
end
|
||||
|
||||
def test_menu
|
||||
assert_difference 'Redmine::MenuManager.items(:project_menu).size' do
|
||||
@klass.register :foo do
|
||||
menu :project_menu, :foo_menu_item, '/foo', :caption => 'Foo'
|
||||
end
|
||||
end
|
||||
menu_item = Redmine::MenuManager.items(:project_menu).detect {|i| i.name == :foo_menu_item}
|
||||
assert_not_nil menu_item
|
||||
assert_equal 'Foo', menu_item.caption
|
||||
assert_equal '/foo', menu_item.url
|
||||
ensure
|
||||
Redmine::MenuManager.map(:project_menu).delete(:foo_menu_item)
|
||||
end
|
||||
|
||||
def test_delete_menu_item
|
||||
Redmine::MenuManager.map(:project_menu).push(:foo_menu_item, '/foo', :caption => 'Foo')
|
||||
assert_difference 'Redmine::MenuManager.items(:project_menu).size', -1 do
|
||||
@klass.register :foo do
|
||||
delete_menu_item :project_menu, :foo_menu_item
|
||||
end
|
||||
end
|
||||
assert_nil Redmine::MenuManager.items(:project_menu).detect {|i| i.name == :foo_menu_item}
|
||||
ensure
|
||||
Redmine::MenuManager.map(:project_menu).delete(:foo_menu_item)
|
||||
end
|
||||
|
||||
def test_directory_with_override
|
||||
@klass.register(:foo) do
|
||||
directory '/path/to/foo'
|
||||
end
|
||||
assert_equal '/path/to/foo', @klass.find('foo').directory
|
||||
end
|
||||
|
||||
def test_directory_without_override
|
||||
@klass.register(:foo) {}
|
||||
assert_equal File.join(@klass.directory, 'foo'), @klass.find('foo').directory
|
||||
end
|
||||
|
||||
def test_requires_redmine
|
||||
plugin = Redmine::Plugin.register(:foo) {}
|
||||
Redmine::VERSION.stubs(:to_a).returns([2, 1, 3, "stable", 10817])
|
||||
# Specific version without hash
|
||||
assert plugin.requires_redmine('2.1.3')
|
||||
assert plugin.requires_redmine('2.1')
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine('2.1.4')
|
||||
end
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine('2.2')
|
||||
end
|
||||
# Specific version
|
||||
assert plugin.requires_redmine(:version => '2.1.3')
|
||||
assert plugin.requires_redmine(:version => ['2.1.3', '2.2.0'])
|
||||
assert plugin.requires_redmine(:version => '2.1')
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine(:version => '2.2.0')
|
||||
end
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine(:version => ['2.1.4', '2.2.0'])
|
||||
end
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine(:version => '2.2')
|
||||
end
|
||||
# Version range
|
||||
assert plugin.requires_redmine(:version => '2.0.0'..'2.2.4')
|
||||
assert plugin.requires_redmine(:version => '2.1.3'..'2.2.4')
|
||||
assert plugin.requires_redmine(:version => '2.0.0'..'2.1.3')
|
||||
assert plugin.requires_redmine(:version => '2.0'..'2.2')
|
||||
assert plugin.requires_redmine(:version => '2.1'..'2.2')
|
||||
assert plugin.requires_redmine(:version => '2.0'..'2.1')
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine(:version => '2.1.4'..'2.2.4')
|
||||
end
|
||||
# Version or higher
|
||||
assert plugin.requires_redmine(:version_or_higher => '0.1.0')
|
||||
assert plugin.requires_redmine(:version_or_higher => '2.1.3')
|
||||
assert plugin.requires_redmine(:version_or_higher => '2.1')
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine(:version_or_higher => '2.2.0')
|
||||
end
|
||||
assert_raise Redmine::PluginRequirementError do
|
||||
plugin.requires_redmine(:version_or_higher => '2.2')
|
||||
end
|
||||
end
|
||||
|
||||
def test_requires_redmine_plugin
|
||||
test = self
|
||||
other_version = '0.5.0'
|
||||
@klass.register :other do
|
||||
name 'Other'
|
||||
version other_version
|
||||
end
|
||||
@klass.register :foo do
|
||||
test.assert requires_redmine_plugin(:other, :version_or_higher => '0.1.0')
|
||||
test.assert requires_redmine_plugin(:other, :version_or_higher => other_version)
|
||||
test.assert requires_redmine_plugin(:other, other_version)
|
||||
test.assert_raise Redmine::PluginRequirementError do
|
||||
requires_redmine_plugin(:other, :version_or_higher => '99.0.0')
|
||||
end
|
||||
test.assert requires_redmine_plugin(:other, :version => other_version)
|
||||
test.assert requires_redmine_plugin(:other, :version => [other_version, '99.0.0'])
|
||||
test.assert_raise Redmine::PluginRequirementError do
|
||||
requires_redmine_plugin(:other, :version => '99.0.0')
|
||||
end
|
||||
test.assert_raise Redmine::PluginRequirementError do
|
||||
requires_redmine_plugin(:other, :version => ['98.0.0', '99.0.0'])
|
||||
end
|
||||
# Missing plugin
|
||||
test.assert_raise Redmine::PluginNotFound do
|
||||
requires_redmine_plugin(:missing, :version_or_higher => '0.1.0')
|
||||
end
|
||||
test.assert_raise Redmine::PluginNotFound do
|
||||
requires_redmine_plugin(:missing, '0.1.0')
|
||||
end
|
||||
test.assert_raise Redmine::PluginNotFound do
|
||||
requires_redmine_plugin(:missing, :version => '0.1.0')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_settings_warns_about_possible_partial_collision
|
||||
@klass.register(:foo) { settings :partial => 'foo/settings' }
|
||||
Rails.logger.expects(:warn)
|
||||
@klass.register(:bar) { settings :partial => 'foo/settings' }
|
||||
end
|
||||
end
|
102
test/unit/lib/redmine/safe_attributes_test.rb
Normal file
102
test/unit/lib/redmine/safe_attributes_test.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::SafeAttributesTest < ActiveSupport::TestCase
|
||||
fixtures :users
|
||||
|
||||
class Base
|
||||
def attributes=(attrs)
|
||||
attrs.each do |key, value|
|
||||
send("#{key}=", value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Person < Base
|
||||
attr_accessor :firstname, :lastname, :login
|
||||
include Redmine::SafeAttributes
|
||||
safe_attributes :firstname, :lastname
|
||||
safe_attributes :login, :if => lambda {|person, user| user.admin?}
|
||||
end
|
||||
|
||||
class Book < Base
|
||||
attr_accessor :title
|
||||
include Redmine::SafeAttributes
|
||||
safe_attributes :title
|
||||
end
|
||||
|
||||
def test_safe_attribute_names
|
||||
p = Person.new
|
||||
user = User.anonymous
|
||||
assert_equal ['firstname', 'lastname'], p.safe_attribute_names(user)
|
||||
assert p.safe_attribute?('firstname', user)
|
||||
assert !p.safe_attribute?('login', user)
|
||||
|
||||
p = Person.new
|
||||
user = User.find(1)
|
||||
assert_equal ['firstname', 'lastname', 'login'], p.safe_attribute_names(user)
|
||||
assert p.safe_attribute?('firstname', user)
|
||||
assert p.safe_attribute?('login', user)
|
||||
end
|
||||
|
||||
def test_safe_attribute_names_without_user
|
||||
p = Person.new
|
||||
User.current = nil
|
||||
assert_equal ['firstname', 'lastname'], p.safe_attribute_names
|
||||
assert p.safe_attribute?('firstname')
|
||||
assert !p.safe_attribute?('login')
|
||||
|
||||
p = Person.new
|
||||
User.current = User.find(1)
|
||||
assert_equal ['firstname', 'lastname', 'login'], p.safe_attribute_names
|
||||
assert p.safe_attribute?('firstname')
|
||||
assert p.safe_attribute?('login')
|
||||
end
|
||||
|
||||
def test_set_safe_attributes
|
||||
p = Person.new
|
||||
p.send('safe_attributes=', {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}, User.anonymous)
|
||||
assert_equal 'John', p.firstname
|
||||
assert_equal 'Smith', p.lastname
|
||||
assert_nil p.login
|
||||
|
||||
p = Person.new
|
||||
User.current = User.find(1)
|
||||
p.send('safe_attributes=', {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}, User.find(1))
|
||||
assert_equal 'John', p.firstname
|
||||
assert_equal 'Smith', p.lastname
|
||||
assert_equal 'jsmith', p.login
|
||||
end
|
||||
|
||||
def test_set_safe_attributes_without_user
|
||||
p = Person.new
|
||||
User.current = nil
|
||||
p.safe_attributes = {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}
|
||||
assert_equal 'John', p.firstname
|
||||
assert_equal 'Smith', p.lastname
|
||||
assert_nil p.login
|
||||
|
||||
p = Person.new
|
||||
User.current = User.find(1)
|
||||
p.safe_attributes = {'firstname' => 'John', 'lastname' => 'Smith', 'login' => 'jsmith'}
|
||||
assert_equal 'John', p.firstname
|
||||
assert_equal 'Smith', p.lastname
|
||||
assert_equal 'jsmith', p.login
|
||||
end
|
||||
end
|
218
test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb
Normal file
218
test/unit/lib/redmine/scm/adapters/bazaar_adapter_test.rb
Normal file
|
@ -0,0 +1,218 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class BazaarAdapterTest < ActiveSupport::TestCase
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/bazaar_repository').to_s
|
||||
REPOSITORY_PATH.gsub!(/\/+/, '/')
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def setup
|
||||
@adapter = Redmine::Scm::Adapters::BazaarAdapter.new(
|
||||
File.join(REPOSITORY_PATH, "trunk")
|
||||
)
|
||||
end
|
||||
|
||||
def test_scm_version
|
||||
to_test = { "Bazaar (bzr) 2.1.2\n" => [2,1,2],
|
||||
"2.1.1\n1.7\n1.8" => [2,1,1],
|
||||
"2.0.1\r\n1.8.1\r\n1.9.1" => [2,0,1]}
|
||||
to_test.each do |s, v|
|
||||
test_scm_version_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_cat
|
||||
cat = @adapter.cat('directory/document.txt')
|
||||
assert cat =~ /Write the contents of a file as of a given revision to standard output/
|
||||
end
|
||||
|
||||
def test_cat_path_invalid
|
||||
assert_nil @adapter.cat('invalid')
|
||||
end
|
||||
|
||||
def test_cat_revision_invalid
|
||||
assert_nil @adapter.cat('doc-mkdir.txt', '12345678')
|
||||
end
|
||||
|
||||
def test_diff
|
||||
diff1 = @adapter.diff('doc-mkdir.txt', 3, 2)
|
||||
assert_equal 21, diff1.size
|
||||
buf = diff1[14].gsub(/\r\n|\r|\n/, "")
|
||||
assert_equal "-Display more information.", buf
|
||||
end
|
||||
|
||||
def test_diff_path_invalid
|
||||
assert_equal [], @adapter.diff('invalid', 1)
|
||||
end
|
||||
|
||||
def test_diff_revision_invalid
|
||||
assert_equal [], @adapter.diff(nil, 12345678)
|
||||
assert_equal [], @adapter.diff(nil, 12345678, 87654321)
|
||||
end
|
||||
|
||||
def test_annotate
|
||||
annotate = @adapter.annotate('doc-mkdir.txt')
|
||||
assert_equal 17, annotate.lines.size
|
||||
assert_equal '1', annotate.revisions[0].identifier
|
||||
assert_equal 'jsmith@', annotate.revisions[0].author
|
||||
assert_equal 'mkdir', annotate.lines[0]
|
||||
end
|
||||
|
||||
def test_annotate_path_invalid
|
||||
assert_nil @adapter.annotate('invalid')
|
||||
end
|
||||
|
||||
def test_annotate_revision_invalid
|
||||
assert_nil @adapter.annotate('doc-mkdir.txt', '12345678')
|
||||
end
|
||||
|
||||
def test_branch_conf_path
|
||||
p = "c:\\test\\test\\"
|
||||
bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
|
||||
assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
|
||||
p = "c:\\test\\test\\.bzr"
|
||||
bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
|
||||
assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
|
||||
p = "c:\\test\\test\\.bzr\\"
|
||||
bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
|
||||
assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
|
||||
p = "c:\\test\\test"
|
||||
bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
|
||||
assert_equal File.join("c:\\test\\test", ".bzr", "branch", "branch.conf"), bcp
|
||||
p = "\\\\server\\test\\test\\"
|
||||
bcp = Redmine::Scm::Adapters::BazaarAdapter.branch_conf_path(p)
|
||||
assert_equal File.join("\\\\server\\test\\test", ".bzr", "branch", "branch.conf"), bcp
|
||||
end
|
||||
|
||||
def test_append_revisions_only_true
|
||||
assert_equal true, @adapter.append_revisions_only
|
||||
end
|
||||
|
||||
def test_append_revisions_only_false
|
||||
adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
|
||||
File.join(REPOSITORY_PATH, "empty-branch")
|
||||
)
|
||||
assert_equal false, adpt.append_revisions_only
|
||||
end
|
||||
|
||||
def test_append_revisions_only_shared_repo
|
||||
adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
|
||||
REPOSITORY_PATH
|
||||
)
|
||||
assert_equal false, adpt.append_revisions_only
|
||||
end
|
||||
|
||||
def test_info_not_nil
|
||||
assert_not_nil @adapter.info
|
||||
end
|
||||
|
||||
def test_info_nil
|
||||
adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
|
||||
"/invalid/invalid/"
|
||||
)
|
||||
assert_nil adpt.info
|
||||
end
|
||||
|
||||
def test_info
|
||||
info = @adapter.info
|
||||
assert_equal 4, info.lastrev.identifier.to_i
|
||||
end
|
||||
|
||||
def test_info_emtpy
|
||||
adpt = Redmine::Scm::Adapters::BazaarAdapter.new(
|
||||
File.join(REPOSITORY_PATH, "empty-branch")
|
||||
)
|
||||
assert_equal 0, adpt.info.lastrev.identifier.to_i
|
||||
end
|
||||
|
||||
def test_entries_path_invalid
|
||||
assert_equal [], @adapter.entries('invalid')
|
||||
end
|
||||
|
||||
def test_entries_revision_invalid
|
||||
assert_nil @adapter.entries(nil, 12345678)
|
||||
end
|
||||
|
||||
def test_revisions
|
||||
revisions = @adapter.revisions(nil, 4, 2)
|
||||
assert_equal 3, revisions.size
|
||||
assert_equal 2, revisions[2].identifier
|
||||
assert_equal 'jsmith@foo.bar-20071203175224-v0eog5d5wrgdrshg', revisions[2].scmid
|
||||
assert_equal 4, revisions[0].identifier
|
||||
assert_equal 'jsmith@foo.bar-20071203175422-t40bf8li5zz0c4cg', revisions[0].scmid
|
||||
assert_equal 2, revisions[0].paths.size
|
||||
assert_equal 'D', revisions[0].paths[0][:action]
|
||||
assert_equal '/doc-deleted.txt', revisions[0].paths[0][:path]
|
||||
assert_equal 'docdeleted.txt-20071203175320-iwwj561ojuubs3gt-1', revisions[0].paths[0][:revision]
|
||||
assert_equal 'M', revisions[0].paths[1][:action]
|
||||
assert_equal '/directory/doc-ls.txt', revisions[0].paths[1][:path]
|
||||
assert_equal 'docls.txt-20071203175005-a3hyc3mn0shl7cgu-1', revisions[0].paths[1][:revision]
|
||||
end
|
||||
|
||||
def test_revisions_path_invalid
|
||||
assert_nil @adapter.revisions('invalid')
|
||||
end
|
||||
|
||||
def test_revisions_revision_invalid
|
||||
assert_nil @adapter.revisions(nil, 12345678)
|
||||
assert_nil @adapter.revisions(nil, 12345678, 87654321)
|
||||
end
|
||||
|
||||
def test_entry
|
||||
entry = @adapter.entry()
|
||||
assert_equal "", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
entry = @adapter.entry('')
|
||||
assert_equal "", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
assert_nil @adapter.entry('invalid')
|
||||
assert_nil @adapter.entry('/invalid')
|
||||
assert_nil @adapter.entry('/invalid/')
|
||||
assert_nil @adapter.entry('invalid/invalid')
|
||||
assert_nil @adapter.entry('invalid/invalid/')
|
||||
assert_nil @adapter.entry('/invalid/invalid')
|
||||
assert_nil @adapter.entry('/invalid/invalid/')
|
||||
["doc-ls.txt", "/doc-ls.txt"].each do |path|
|
||||
entry = @adapter.entry(path, 2)
|
||||
assert_equal "doc-ls.txt", entry.path
|
||||
assert_equal "file", entry.kind
|
||||
end
|
||||
["directory", "/directory", "/directory/"].each do |path|
|
||||
entry = @adapter.entry(path, 2)
|
||||
assert_equal "directory", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
end
|
||||
["directory/document.txt", "/directory/document.txt"].each do |path|
|
||||
entry = @adapter.entry(path, 2)
|
||||
assert_equal "directory/document.txt", entry.path
|
||||
assert_equal "file", entry.kind
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_scm_version_for(scm_command_version, version)
|
||||
@adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
|
||||
assert_equal version, @adapter.class.scm_command_version
|
||||
end
|
||||
else
|
||||
puts "Bazaar test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
106
test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb
Normal file
106
test/unit/lib/redmine/scm/adapters/cvs_adapter_test.rb
Normal file
|
@ -0,0 +1,106 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class CvsAdapterTest < ActiveSupport::TestCase
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/cvs_repository').to_s
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
MODULE_NAME = 'test'
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def setup
|
||||
@adapter = Redmine::Scm::Adapters::CvsAdapter.new(MODULE_NAME, REPOSITORY_PATH)
|
||||
end
|
||||
|
||||
def test_scm_version
|
||||
to_test = { "\nConcurrent Versions System (CVS) 1.12.13 (client/server)\n" => [1,12,13],
|
||||
"\r\n1.12.12\r\n1.12.11" => [1,12,12],
|
||||
"1.12.11\r\n1.12.10\r\n" => [1,12,11]}
|
||||
to_test.each do |s, v|
|
||||
test_scm_version_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_revisions_all
|
||||
cnt = 0
|
||||
@adapter.revisions('', nil, nil, :log_encoding => 'UTF-8') do |revision|
|
||||
cnt += 1
|
||||
end
|
||||
assert_equal 16, cnt
|
||||
end
|
||||
|
||||
def test_revisions_from_rev3
|
||||
rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
|
||||
cnt = 0
|
||||
@adapter.revisions('', rev3_committed_on, nil, :log_encoding => 'UTF-8') do |revision|
|
||||
cnt += 1
|
||||
end
|
||||
assert_equal 4, cnt
|
||||
end
|
||||
|
||||
def test_entries_rev3
|
||||
rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
|
||||
entries = @adapter.entries('sources', rev3_committed_on)
|
||||
assert_equal 2, entries.size
|
||||
assert_equal entries[0].name, "watchers_controller.rb"
|
||||
assert_equal entries[0].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22)
|
||||
end
|
||||
|
||||
def test_path_encoding_default_utf8
|
||||
adpt1 = Redmine::Scm::Adapters::CvsAdapter.new(
|
||||
MODULE_NAME,
|
||||
REPOSITORY_PATH
|
||||
)
|
||||
assert_equal "UTF-8", adpt1.path_encoding
|
||||
adpt2 = Redmine::Scm::Adapters::CvsAdapter.new(
|
||||
MODULE_NAME,
|
||||
REPOSITORY_PATH,
|
||||
nil,
|
||||
nil,
|
||||
""
|
||||
)
|
||||
assert_equal "UTF-8", adpt2.path_encoding
|
||||
end
|
||||
|
||||
def test_root_url_path
|
||||
to_test = {
|
||||
':pserver:cvs_user:cvs_password@123.456.789.123:9876/repo' => '/repo',
|
||||
':pserver:cvs_user:cvs_password@123.456.789.123/repo' => '/repo',
|
||||
':pserver:cvs_user:cvs_password@cvs_server:/repo' => '/repo',
|
||||
':pserver:cvs_user:cvs_password@cvs_server:9876/repo' => '/repo',
|
||||
':pserver:cvs_user:cvs_password@cvs_server/repo' => '/repo',
|
||||
':pserver:cvs_user:cvs_password@cvs_server/path/repo' => '/path/repo',
|
||||
':ext:cvsservername:/path' => '/path'
|
||||
}
|
||||
|
||||
to_test.each do |string, expected|
|
||||
assert_equal expected, Redmine::Scm::Adapters::CvsAdapter.new('foo', string).send(:root_url_path), "#{string} failed"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_scm_version_for(scm_command_version, version)
|
||||
@adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
|
||||
assert_equal version, @adapter.class.scm_command_version
|
||||
end
|
||||
else
|
||||
puts "Cvs test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
60
test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb
Normal file
60
test/unit/lib/redmine/scm/adapters/darcs_adapter_test.rb
Normal file
|
@ -0,0 +1,60 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class DarcsAdapterTest < ActiveSupport::TestCase
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/darcs_repository').to_s
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def setup
|
||||
@adapter = Redmine::Scm::Adapters::DarcsAdapter.new(REPOSITORY_PATH)
|
||||
end
|
||||
|
||||
def test_darcsversion
|
||||
to_test = { "1.0.9 (release)\n" => [1,0,9] ,
|
||||
"2.2.0 (release)\n" => [2,2,0] }
|
||||
to_test.each do |s, v|
|
||||
test_darcsversion_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_revisions
|
||||
id1 = '20080308225258-98289-761f654d669045eabee90b91b53a21ce5593cadf.gz'
|
||||
revs = @adapter.revisions('', nil, nil, {:with_path => true})
|
||||
assert_equal 6, revs.size
|
||||
assert_equal id1, revs[5].scmid
|
||||
paths = revs[5].paths
|
||||
assert_equal 5, paths.size
|
||||
assert_equal 'A', paths[0][:action]
|
||||
assert_equal '/README', paths[0][:path]
|
||||
assert_equal 'A', paths[1][:action]
|
||||
assert_equal '/images', paths[1][:path]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_darcsversion_for(darcsversion, version)
|
||||
@adapter.class.expects(:darcs_binary_version_from_command_line).returns(darcsversion)
|
||||
assert_equal version, @adapter.class.darcs_binary_version
|
||||
end
|
||||
|
||||
else
|
||||
puts "Darcs test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,68 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class FilesystemAdapterTest < ActiveSupport::TestCase
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/filesystem_repository').to_s
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def setup
|
||||
@adapter = Redmine::Scm::Adapters::FilesystemAdapter.new(REPOSITORY_PATH)
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_equal 3, @adapter.entries.size
|
||||
assert_equal ["dir", "japanese", "test"], @adapter.entries.collect(&:name)
|
||||
assert_equal ["dir", "japanese", "test"], @adapter.entries(nil).collect(&:name)
|
||||
assert_equal ["dir", "japanese", "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", "japanese", "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
|
||||
|
||||
def test_path_encoding_default_utf8
|
||||
adpt1 = Redmine::Scm::Adapters::FilesystemAdapter.new(
|
||||
REPOSITORY_PATH
|
||||
)
|
||||
assert_equal "UTF-8", adpt1.path_encoding
|
||||
adpt2 = Redmine::Scm::Adapters::FilesystemAdapter.new(
|
||||
REPOSITORY_PATH,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
""
|
||||
)
|
||||
assert_equal "UTF-8", adpt2.path_encoding
|
||||
end
|
||||
else
|
||||
puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
597
test/unit/lib/redmine/scm/adapters/git_adapter_test.rb
Normal file
597
test/unit/lib/redmine/scm/adapters/git_adapter_test.rb
Normal file
|
@ -0,0 +1,597 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class GitAdapterTest < ActiveSupport::TestCase
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
|
||||
|
||||
FELIX_HEX = "Felix Sch\xC3\xA4fer"
|
||||
CHAR_1_HEX = "\xc3\x9c"
|
||||
|
||||
## Git, Mercurial and CVS path encodings are binary.
|
||||
## Subversion supports URL encoding for path.
|
||||
## Redmine Mercurial adapter and extension use URL encoding.
|
||||
## Git accepts only binary path in command line parameter.
|
||||
## So, there is no way to use binary command line parameter in JRuby.
|
||||
JRUBY_SKIP = (RUBY_PLATFORM == 'java')
|
||||
JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
## Ruby uses ANSI api to fork a process on Windows.
|
||||
## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
|
||||
## and these are incompatible with ASCII.
|
||||
## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10
|
||||
## http://code.google.com/p/msysgit/issues/detail?id=80
|
||||
## So, Latin-1 path tests fail on Japanese Windows
|
||||
WINDOWS_PASS = (Redmine::Platform.mswin? &&
|
||||
Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10]))
|
||||
WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10"
|
||||
|
||||
def setup
|
||||
adapter_class = Redmine::Scm::Adapters::GitAdapter
|
||||
assert adapter_class
|
||||
assert adapter_class.client_command
|
||||
assert_equal true, adapter_class.client_available
|
||||
assert_equal true, adapter_class.client_version_above?([1])
|
||||
assert_equal true, adapter_class.client_version_above?([1, 0])
|
||||
|
||||
@adapter = Redmine::Scm::Adapters::GitAdapter.new(
|
||||
REPOSITORY_PATH,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
'ISO-8859-1'
|
||||
)
|
||||
assert @adapter
|
||||
@char_1 = CHAR_1_HEX.dup.force_encoding('UTF-8')
|
||||
@str_felix_hex = FELIX_HEX.dup.force_encoding('ASCII-8BIT')
|
||||
end
|
||||
|
||||
def test_scm_version
|
||||
to_test = { "git version 1.7.3.4\n" => [1,7,3,4],
|
||||
"1.6.1\n1.7\n1.8" => [1,6,1],
|
||||
"1.6.2\r\n1.8.1\r\n1.9.1" => [1,6,2]}
|
||||
to_test.each do |s, v|
|
||||
test_scm_version_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_branches
|
||||
brs = []
|
||||
@adapter.branches.each do |b|
|
||||
brs << b
|
||||
end
|
||||
assert_equal 6, brs.length
|
||||
br_issue_8857 = brs[0]
|
||||
assert_equal 'issue-8857', br_issue_8857.to_s
|
||||
assert_equal '2a682156a3b6e77a8bf9cd4590e8db757f3c6c78', br_issue_8857.revision
|
||||
assert_equal br_issue_8857.scmid, br_issue_8857.revision
|
||||
assert_equal false, br_issue_8857.is_default
|
||||
br_latin_1_path = brs[1]
|
||||
assert_equal 'latin-1-path-encoding', br_latin_1_path.to_s
|
||||
assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', br_latin_1_path.revision
|
||||
assert_equal br_latin_1_path.scmid, br_latin_1_path.revision
|
||||
assert_equal false, br_latin_1_path.is_default
|
||||
br_master = brs[2]
|
||||
assert_equal 'master', br_master.to_s
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master.revision
|
||||
assert_equal br_master.scmid, br_master.revision
|
||||
assert_equal false, br_master.is_default
|
||||
br_master_20120212 = brs[3]
|
||||
assert_equal 'master-20120212', br_master_20120212.to_s
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', br_master_20120212.revision
|
||||
assert_equal br_master_20120212.scmid, br_master_20120212.revision
|
||||
assert_equal true, br_master_20120212.is_default
|
||||
br_latin_1 = brs[-2]
|
||||
assert_equal 'test-latin-1', br_latin_1.to_s
|
||||
assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', br_latin_1.revision
|
||||
assert_equal br_latin_1.scmid, br_latin_1.revision
|
||||
assert_equal false, br_latin_1.is_default
|
||||
br_test = brs[-1]
|
||||
assert_equal 'test_branch', br_test.to_s
|
||||
assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', br_test.revision
|
||||
assert_equal br_test.scmid, br_test.revision
|
||||
assert_equal false, br_test.is_default
|
||||
end
|
||||
|
||||
def test_default_branch
|
||||
assert_equal 'master-20120212', @adapter.default_branch
|
||||
end
|
||||
|
||||
def test_tags
|
||||
assert_equal [
|
||||
"tag00.lightweight",
|
||||
"tag01.annotated",
|
||||
], @adapter.tags
|
||||
end
|
||||
|
||||
def test_revisions_master_all
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, "master",{}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 15, revs1.length
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 0].identifier
|
||||
assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
|
||||
|
||||
revs2 = []
|
||||
@adapter.revisions('', nil, "master",
|
||||
{:reverse => true}) do |rev|
|
||||
revs2 << rev
|
||||
end
|
||||
assert_equal 15, revs2.length
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
|
||||
assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
|
||||
end
|
||||
|
||||
def test_revisions_master_merged_rev
|
||||
revs1 = []
|
||||
@adapter.revisions('',
|
||||
"713f4944648826f558cf548222f813dabe7cbb04",
|
||||
"master",
|
||||
{:reverse => true}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 8, revs1.length
|
||||
assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', revs1[ 0].identifier
|
||||
assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 1].identifier
|
||||
# 4a07fe31b is not a child of 713f49446
|
||||
assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 2].identifier
|
||||
# Merged revision
|
||||
assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 3].identifier
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
|
||||
|
||||
revs2 = []
|
||||
@adapter.revisions('',
|
||||
"fba357b886984ee71185ad2065e65fc0417d9b92",
|
||||
"master",
|
||||
{:reverse => true}) do |rev|
|
||||
revs2 << rev
|
||||
end
|
||||
assert_equal 7, revs2.length
|
||||
assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs2[ 0].identifier
|
||||
# 4a07fe31b is not a child of fba357b8869
|
||||
assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs2[ 1].identifier
|
||||
# Merged revision
|
||||
assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs2[ 2].identifier
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
|
||||
end
|
||||
|
||||
def test_revisions_branch_latin_1_path_encoding_all
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, "latin-1-path-encoding",{}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 8, revs1.length
|
||||
assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[ 0].identifier
|
||||
assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
|
||||
|
||||
revs2 = []
|
||||
@adapter.revisions('', nil, "latin-1-path-encoding",
|
||||
{:reverse => true}) do |rev|
|
||||
revs2 << rev
|
||||
end
|
||||
assert_equal 8, revs2.length
|
||||
assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
|
||||
assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
|
||||
end
|
||||
|
||||
def test_revisions_branch_latin_1_path_encoding_with_rev
|
||||
revs1 = []
|
||||
@adapter.revisions('',
|
||||
'7234cb2750b63f47bff735edc50a1c0a433c2518',
|
||||
"latin-1-path-encoding",
|
||||
{:reverse => true}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 7, revs1.length
|
||||
assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 0].identifier
|
||||
assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier
|
||||
|
||||
revs2 = []
|
||||
@adapter.revisions('',
|
||||
'57ca437c0acbbcb749821fdf3726a1367056d364',
|
||||
"latin-1-path-encoding",
|
||||
{:reverse => true}) do |rev|
|
||||
revs2 << rev
|
||||
end
|
||||
assert_equal 3, revs2.length
|
||||
assert_equal '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', revs2[ 0].identifier
|
||||
assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
|
||||
end
|
||||
|
||||
def test_revisions_invalid_rev
|
||||
assert_equal [], @adapter.revisions('', '1234abcd', "master")
|
||||
assert_raise Redmine::Scm::Adapters::CommandFailed do
|
||||
revs1 = []
|
||||
@adapter.revisions('',
|
||||
'1234abcd',
|
||||
"master",
|
||||
{:reverse => true}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_revisions_includes_master_two_revs
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, nil,
|
||||
{:reverse => true,
|
||||
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
|
||||
:excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43']}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 2, revs1.length
|
||||
assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
|
||||
end
|
||||
|
||||
def test_revisions_includes_master_two_revs_from_origin
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, nil,
|
||||
{:reverse => true,
|
||||
:includes => ['899a15dba03a3b350b89c3f537e4bbe02a03cdc9'],
|
||||
:excludes => []}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 2, revs1.length
|
||||
assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[ 0].identifier
|
||||
assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 1].identifier
|
||||
end
|
||||
|
||||
def test_revisions_includes_merged_revs
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, nil,
|
||||
{:reverse => true,
|
||||
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
|
||||
:excludes => ['fba357b886984ee71185ad2065e65fc0417d9b92']}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 7, revs1.length
|
||||
assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 0].identifier
|
||||
assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 1].identifier
|
||||
assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 2].identifier
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
|
||||
end
|
||||
|
||||
def test_revisions_includes_two_heads
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, nil,
|
||||
{:reverse => true,
|
||||
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c',
|
||||
'1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127'],
|
||||
:excludes => ['4f26664364207fa8b1af9f8722647ab2d4ac5d43',
|
||||
'4fc55c43bf3d3dc2efb66145365ddc17639ce81e']}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 4, revs1.length
|
||||
assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier
|
||||
assert_equal '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', revs1[-2].identifier
|
||||
assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier
|
||||
end
|
||||
|
||||
def test_revisions_disjointed_histories_revisions
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, nil,
|
||||
{:reverse => true,
|
||||
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c',
|
||||
'92397af84d22f27389c822848ecd5b463c181583'],
|
||||
:excludes => ['95488a44bc25f7d1f97d775a31359539ff333a63',
|
||||
'4f26664364207fa8b1af9f8722647ab2d4ac5d43'] }) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 4, revs1.length
|
||||
assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', revs1[ 0].identifier
|
||||
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 1].identifier
|
||||
assert_equal 'bc201c95999c4f10d018b0aa03b541cd6a2ff0ee', revs1[-2].identifier
|
||||
assert_equal '92397af84d22f27389c822848ecd5b463c181583', revs1[-1].identifier
|
||||
end
|
||||
|
||||
def test_revisions_invalid_rev_excludes
|
||||
assert_equal [],
|
||||
@adapter.revisions('', nil, nil,
|
||||
{:reverse => true,
|
||||
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
|
||||
:excludes => ['0123abcd4567']})
|
||||
assert_raise Redmine::Scm::Adapters::CommandFailed do
|
||||
revs1 = []
|
||||
@adapter.revisions('', nil, nil,
|
||||
{:reverse => true,
|
||||
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'],
|
||||
:excludes => ['0123abcd4567']}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_getting_revisions_with_spaces_in_filename
|
||||
assert_equal 1, @adapter.revisions("filemane with spaces.txt",
|
||||
nil, "master").length
|
||||
end
|
||||
|
||||
def test_parents
|
||||
revs1 = []
|
||||
@adapter.revisions('',
|
||||
nil,
|
||||
"master",
|
||||
{:reverse => true}) do |rev|
|
||||
revs1 << rev
|
||||
end
|
||||
assert_equal 15, revs1.length
|
||||
assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
|
||||
revs1[0].identifier
|
||||
assert_nil revs1[0].parents
|
||||
assert_equal "899a15dba03a3b350b89c3f537e4bbe02a03cdc9",
|
||||
revs1[1].identifier
|
||||
assert_equal 1, revs1[1].parents.length
|
||||
assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
|
||||
revs1[1].parents[0]
|
||||
assert_equal "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
|
||||
revs1[10].identifier
|
||||
assert_equal 2, revs1[10].parents.length
|
||||
assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
|
||||
revs1[10].parents[0]
|
||||
assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da",
|
||||
revs1[10].parents[1]
|
||||
end
|
||||
|
||||
def test_getting_revisions_with_leading_and_trailing_spaces_in_filename
|
||||
assert_equal " filename with a leading space.txt ",
|
||||
@adapter.revisions(" filename with a leading space.txt ",
|
||||
nil, "master")[0].paths[0][:path]
|
||||
end
|
||||
|
||||
def test_getting_entries_with_leading_and_trailing_spaces_in_filename
|
||||
assert_equal " filename with a leading space.txt ",
|
||||
@adapter.entries('',
|
||||
'83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name
|
||||
end
|
||||
|
||||
def test_annotate
|
||||
annotate = @adapter.annotate('sources/watchers_controller.rb')
|
||||
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
|
||||
assert_equal 41, annotate.lines.size
|
||||
assert_equal "# This program is free software; you can redistribute it and/or",
|
||||
annotate.lines[4].strip
|
||||
assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
|
||||
annotate.revisions[4].identifier
|
||||
assert_equal "jsmith", annotate.revisions[4].author
|
||||
end
|
||||
|
||||
def test_annotate_moved_file
|
||||
annotate = @adapter.annotate('renamed_test.txt')
|
||||
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
|
||||
assert_equal 2, annotate.lines.size
|
||||
end
|
||||
|
||||
def test_last_rev
|
||||
last_rev = @adapter.lastrev("README",
|
||||
"4f26664364207fa8b1af9f8722647ab2d4ac5d43")
|
||||
assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid
|
||||
assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier
|
||||
assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author
|
||||
assert_equal Time.gm(2009, 6, 24, 5, 27, 38), last_rev.time
|
||||
end
|
||||
|
||||
def test_last_rev_with_spaces_in_filename
|
||||
last_rev = @adapter.lastrev("filemane with spaces.txt",
|
||||
"ed5bb786bbda2dee66a2d50faf51429dbc043a7b")
|
||||
last_rev_author = last_rev.author
|
||||
assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid
|
||||
assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier
|
||||
assert_equal "#{@str_felix_hex} <felix@fachschaften.org>",
|
||||
last_rev.author
|
||||
assert_equal Time.gm(2010, 9, 18, 19, 59, 46), last_rev.time
|
||||
end
|
||||
|
||||
def test_latin_1_path
|
||||
if WINDOWS_PASS
|
||||
puts WINDOWS_SKIP_STR
|
||||
elsif JRUBY_SKIP
|
||||
puts JRUBY_SKIP_STR
|
||||
else
|
||||
p2 = "latin-1-dir/test-#{@char_1}-2.txt"
|
||||
['4fc55c43bf3d3dc2efb66145365ddc17639ce81e', '4fc55c43bf3'].each do |r1|
|
||||
assert @adapter.diff(p2, r1)
|
||||
assert @adapter.cat(p2, r1)
|
||||
assert_equal 1, @adapter.annotate(p2, r1).lines.length
|
||||
['64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '64f1f3e89ad1cb5797'].each do |r2|
|
||||
assert @adapter.diff(p2, r1, r2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_latin_1_user_annotate
|
||||
['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', '83ca5fd546063a'].each do |r1|
|
||||
annotate = @adapter.annotate(" filename with a leading space.txt ", r1)
|
||||
assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
|
||||
assert_equal 1, annotate.lines.size
|
||||
assert_equal "And this is a file with a leading and trailing space...",
|
||||
annotate.lines[0].strip
|
||||
assert_equal "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
|
||||
annotate.revisions[0].identifier
|
||||
assert_equal @str_felix_hex, annotate.revisions[0].author
|
||||
end
|
||||
end
|
||||
|
||||
def test_entries_tag
|
||||
entries1 = @adapter.entries(nil, 'tag01.annotated',
|
||||
options = {:report_last_commit => true})
|
||||
assert entries1
|
||||
assert_equal 3, entries1.size
|
||||
assert_equal 'sources', entries1[1].name
|
||||
assert_equal 'sources', entries1[1].path
|
||||
assert_equal 'dir', entries1[1].kind
|
||||
readme = entries1[2]
|
||||
assert_equal 'README', readme.name
|
||||
assert_equal 'README', readme.path
|
||||
assert_equal 'file', readme.kind
|
||||
assert_equal 27, readme.size
|
||||
assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', readme.lastrev.identifier
|
||||
assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time
|
||||
end
|
||||
|
||||
def test_entries_branch
|
||||
entries1 = @adapter.entries(nil, 'test_branch',
|
||||
options = {:report_last_commit => true})
|
||||
assert entries1
|
||||
assert_equal 4, entries1.size
|
||||
assert_equal 'sources', entries1[1].name
|
||||
assert_equal 'sources', entries1[1].path
|
||||
assert_equal 'dir', entries1[1].kind
|
||||
readme = entries1[2]
|
||||
assert_equal 'README', readme.name
|
||||
assert_equal 'README', readme.path
|
||||
assert_equal 'file', readme.kind
|
||||
assert_equal 159, readme.size
|
||||
assert_equal '713f4944648826f558cf548222f813dabe7cbb04', readme.lastrev.identifier
|
||||
assert_equal Time.gm(2009, 6, 19, 4, 37, 23), readme.lastrev.time
|
||||
end
|
||||
|
||||
def test_entries_wrong_path_encoding
|
||||
adpt = Redmine::Scm::Adapters::GitAdapter.new(
|
||||
REPOSITORY_PATH,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
'EUC-JP'
|
||||
)
|
||||
entries1 = adpt.entries('latin-1-dir', '64f1f3e8')
|
||||
assert entries1
|
||||
assert_equal 3, entries1.size
|
||||
f1 = entries1[1]
|
||||
assert_nil f1.name
|
||||
assert_nil f1.path
|
||||
assert_equal 'file', f1.kind
|
||||
end
|
||||
|
||||
def test_entries_latin_1_files
|
||||
entries1 = @adapter.entries('latin-1-dir', '64f1f3e8')
|
||||
assert entries1
|
||||
assert_equal 3, entries1.size
|
||||
f1 = entries1[1]
|
||||
assert_equal "test-#{@char_1}-2.txt", f1.name
|
||||
assert_equal "latin-1-dir/test-#{@char_1}-2.txt", f1.path
|
||||
assert_equal 'file', f1.kind
|
||||
end
|
||||
|
||||
def test_entries_latin_1_dir
|
||||
if WINDOWS_PASS
|
||||
puts WINDOWS_SKIP_STR
|
||||
elsif JRUBY_SKIP
|
||||
puts JRUBY_SKIP_STR
|
||||
else
|
||||
entries1 = @adapter.entries("latin-1-dir/test-#{@char_1}-subdir",
|
||||
'1ca7f5ed')
|
||||
assert entries1
|
||||
assert_equal 3, entries1.size
|
||||
f1 = entries1[1]
|
||||
assert_equal "test-#{@char_1}-2.txt", f1.name
|
||||
assert_equal "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-2.txt", f1.path
|
||||
assert_equal 'file', f1.kind
|
||||
end
|
||||
end
|
||||
|
||||
def test_entry
|
||||
entry = @adapter.entry()
|
||||
assert_equal "", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
entry = @adapter.entry('')
|
||||
assert_equal "", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
assert_nil @adapter.entry('invalid')
|
||||
assert_nil @adapter.entry('/invalid')
|
||||
assert_nil @adapter.entry('/invalid/')
|
||||
assert_nil @adapter.entry('invalid/invalid')
|
||||
assert_nil @adapter.entry('invalid/invalid/')
|
||||
assert_nil @adapter.entry('/invalid/invalid')
|
||||
assert_nil @adapter.entry('/invalid/invalid/')
|
||||
["README", "/README"].each do |path|
|
||||
entry = @adapter.entry(path, '7234cb2750b63f')
|
||||
assert_equal "README", entry.path
|
||||
assert_equal "file", entry.kind
|
||||
end
|
||||
["sources", "/sources", "/sources/"].each do |path|
|
||||
entry = @adapter.entry(path, '7234cb2750b63f')
|
||||
assert_equal "sources", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
end
|
||||
["sources/watchers_controller.rb", "/sources/watchers_controller.rb"].each do |path|
|
||||
entry = @adapter.entry(path, '7234cb2750b63f')
|
||||
assert_equal "sources/watchers_controller.rb", entry.path
|
||||
assert_equal "file", entry.kind
|
||||
end
|
||||
end
|
||||
|
||||
def test_path_encoding_default_utf8
|
||||
adpt1 = Redmine::Scm::Adapters::GitAdapter.new(
|
||||
REPOSITORY_PATH
|
||||
)
|
||||
assert_equal "UTF-8", adpt1.path_encoding
|
||||
adpt2 = Redmine::Scm::Adapters::GitAdapter.new(
|
||||
REPOSITORY_PATH,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
""
|
||||
)
|
||||
assert_equal "UTF-8", adpt2.path_encoding
|
||||
end
|
||||
|
||||
def test_cat_path_invalid
|
||||
assert_nil @adapter.cat('invalid')
|
||||
end
|
||||
|
||||
def test_cat_revision_invalid
|
||||
assert @adapter.cat('README')
|
||||
assert_nil @adapter.cat('README', '1234abcd5678')
|
||||
end
|
||||
|
||||
def test_diff_path_invalid
|
||||
assert_equal [], @adapter.diff('invalid', '713f4944648826f5')
|
||||
end
|
||||
|
||||
def test_diff_revision_invalid
|
||||
assert_nil @adapter.diff(nil, '1234abcd5678')
|
||||
assert_nil @adapter.diff(nil, '713f4944648826f5', '1234abcd5678')
|
||||
assert_nil @adapter.diff(nil, '1234abcd5678', '713f4944648826f5')
|
||||
end
|
||||
|
||||
def test_annotate_path_invalid
|
||||
assert_nil @adapter.annotate('invalid')
|
||||
end
|
||||
|
||||
def test_annotate_revision_invalid
|
||||
assert @adapter.annotate('README')
|
||||
assert_nil @adapter.annotate('README', '1234abcd5678')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_scm_version_for(scm_command_version, version)
|
||||
@adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
|
||||
assert_equal version, @adapter.class.scm_command_version
|
||||
end
|
||||
|
||||
else
|
||||
puts "Git test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
485
test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb
Normal file
485
test/unit/lib/redmine/scm/adapters/mercurial_adapter_test.rb
Normal file
|
@ -0,0 +1,485 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class MercurialAdapterTest < ActiveSupport::TestCase
|
||||
HELPERS_DIR = Redmine::Scm::Adapters::MercurialAdapter::HELPERS_DIR
|
||||
TEMPLATE_NAME = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_NAME
|
||||
TEMPLATE_EXTENSION = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_EXTENSION
|
||||
HgCommandAborted = Redmine::Scm::Adapters::MercurialAdapter::HgCommandAborted
|
||||
HgCommandArgumentError = Redmine::Scm::Adapters::MercurialAdapter::HgCommandArgumentError
|
||||
|
||||
REPOSITORY_PATH = repository_path('mercurial')
|
||||
CHAR_1_HEX = "\xc3\x9c"
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def setup
|
||||
adapter_class = Redmine::Scm::Adapters::MercurialAdapter
|
||||
assert adapter_class
|
||||
assert adapter_class.client_command
|
||||
assert_equal true, adapter_class.client_available
|
||||
assert_equal true, adapter_class.client_version_above?([0, 9, 5])
|
||||
|
||||
@adapter = Redmine::Scm::Adapters::MercurialAdapter.new(
|
||||
REPOSITORY_PATH,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
'ISO-8859-1')
|
||||
@diff_c_support = true
|
||||
@char_1 = CHAR_1_HEX.dup.force_encoding('UTF-8')
|
||||
@tag_char_1 = "tag-#{CHAR_1_HEX}-00".force_encoding('UTF-8')
|
||||
@branch_char_0 = "branch-#{CHAR_1_HEX}-00".force_encoding('UTF-8')
|
||||
@branch_char_1 = "branch-#{CHAR_1_HEX}-01".force_encoding('UTF-8')
|
||||
end
|
||||
|
||||
def test_hgversion
|
||||
to_test = { "Mercurial Distributed SCM (version 0.9.5)\n" => [0,9,5],
|
||||
"Mercurial Distributed SCM (1.0)\n" => [1,0],
|
||||
"Mercurial Distributed SCM (1e4ddc9ac9f7+20080325)\n" => nil,
|
||||
"Mercurial Distributed SCM (1.0.1+20080525)\n" => [1,0,1],
|
||||
"Mercurial Distributed SCM (1916e629a29d)\n" => nil,
|
||||
"Mercurial SCM Distribuito (versione 0.9.5)\n" => [0,9,5],
|
||||
"(1.6)\n(1.7)\n(1.8)" => [1,6],
|
||||
"(1.7.1)\r\n(1.8.1)\r\n(1.9.1)" => [1,7,1]}
|
||||
|
||||
to_test.each do |s, v|
|
||||
test_hgversion_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_template_path
|
||||
to_test = {
|
||||
[1,2] => "1.0",
|
||||
[] => "1.0",
|
||||
[1,2,1] => "1.0",
|
||||
[1,7] => "1.0",
|
||||
[1,7,1] => "1.0",
|
||||
[2,0] => "1.0",
|
||||
}
|
||||
to_test.each do |v, template|
|
||||
test_template_path_for(v, template)
|
||||
end
|
||||
end
|
||||
|
||||
def test_info
|
||||
[REPOSITORY_PATH, REPOSITORY_PATH + "/",
|
||||
REPOSITORY_PATH + "//"].each do |repo|
|
||||
adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo)
|
||||
repo_path = adp.info.root_url.gsub(/\\/, "/")
|
||||
assert_equal REPOSITORY_PATH, repo_path
|
||||
assert_equal '33', adp.info.lastrev.revision
|
||||
assert_equal '2e6d546429230f377d7d19c2078abd2dd909f235',adp.info.lastrev.scmid
|
||||
end
|
||||
end
|
||||
|
||||
def test_revisions
|
||||
revisions = @adapter.revisions(nil, 2, 4)
|
||||
assert_equal 3, revisions.size
|
||||
assert_equal '2', revisions[0].revision
|
||||
assert_equal '400bb86721098697c7d17b3724c794c57636de70', revisions[0].scmid
|
||||
assert_equal '4', revisions[2].revision
|
||||
assert_equal 'def6d2f1254a56fb8fbe9ec3b5c0451674dbd8b8', revisions[2].scmid
|
||||
|
||||
revisions = @adapter.revisions(nil, 2, 4, {:limit => 2})
|
||||
assert_equal 2, revisions.size
|
||||
assert_equal '2', revisions[0].revision
|
||||
assert_equal '400bb86721098697c7d17b3724c794c57636de70', revisions[0].scmid
|
||||
end
|
||||
|
||||
def test_parents
|
||||
revs1 = @adapter.revisions(nil, 0, 0)
|
||||
assert_equal 1, revs1.size
|
||||
assert_equal [], revs1[0].parents
|
||||
revs2 = @adapter.revisions(nil, 1, 1)
|
||||
assert_equal 1, revs2.size
|
||||
assert_equal 1, revs2[0].parents.size
|
||||
assert_equal "0885933ad4f68d77c2649cd11f8311276e7ef7ce", revs2[0].parents[0]
|
||||
revs3 = @adapter.revisions(nil, 30, 30)
|
||||
assert_equal 1, revs3.size
|
||||
assert_equal 2, revs3[0].parents.size
|
||||
assert_equal "a94b0528f24fe05ebaef496ae0500bb050772e36", revs3[0].parents[0]
|
||||
assert_equal "3a330eb329586ea2adb3f83237c23310e744ebe9", revs3[0].parents[1]
|
||||
end
|
||||
|
||||
def test_diff
|
||||
if @adapter.class.client_version_above?([1, 2])
|
||||
assert_nil @adapter.diff(nil, '100000')
|
||||
end
|
||||
assert_nil @adapter.diff(nil, '100000', '200000')
|
||||
[2, '400bb8672109', '400', 400].each do |r1|
|
||||
diff1 = @adapter.diff(nil, r1)
|
||||
if @diff_c_support
|
||||
assert_equal 28, diff1.size
|
||||
buf = diff1[24].gsub(/\r\n|\r|\n/, "")
|
||||
assert_equal "+ return true unless klass.respond_to?('watched_by')", buf
|
||||
else
|
||||
assert_equal 0, diff1.size
|
||||
end
|
||||
[4, 'def6d2f1254a'].each do |r2|
|
||||
diff2 = @adapter.diff(nil, r1, r2)
|
||||
assert_equal 49, diff2.size
|
||||
buf = diff2[41].gsub(/\r\n|\r|\n/, "")
|
||||
assert_equal "+class WelcomeController < ApplicationController", buf
|
||||
diff3 = @adapter.diff('sources/watchers_controller.rb', r1, r2)
|
||||
assert_equal 20, diff3.size
|
||||
buf = diff3[12].gsub(/\r\n|\r|\n/, "")
|
||||
assert_equal "+ @watched.remove_watcher(user)", buf
|
||||
|
||||
diff4 = @adapter.diff(nil, r2, r1)
|
||||
assert_equal 49, diff4.size
|
||||
buf = diff4[41].gsub(/\r\n|\r|\n/, "")
|
||||
assert_equal "-class WelcomeController < ApplicationController", buf
|
||||
diff5 = @adapter.diff('sources/watchers_controller.rb', r2, r1)
|
||||
assert_equal 20, diff5.size
|
||||
buf = diff5[9].gsub(/\r\n|\r|\n/, "")
|
||||
assert_equal "- @watched.remove_watcher(user)", buf
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_diff_made_by_revision
|
||||
if @diff_c_support
|
||||
[24, '24', '4cddb4e45f52'].each do |r1|
|
||||
diff1 = @adapter.diff(nil, r1)
|
||||
assert_equal 5, diff1.size
|
||||
buf = diff1[4].gsub(/\r\n|\r|\n/, "")
|
||||
assert_equal '+0885933ad4f68d77c2649cd11f8311276e7ef7ce tag-init-revision', buf
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_cat
|
||||
[2, '400bb8672109', '400', 400].each do |r|
|
||||
buf = @adapter.cat('sources/welcome_controller.rb', r)
|
||||
assert buf
|
||||
lines = buf.split("\r\n")
|
||||
assert_equal 25, lines.length
|
||||
assert_equal 'class WelcomeController < ApplicationController', lines[17]
|
||||
end
|
||||
assert_nil @adapter.cat('sources/welcome_controller.rb')
|
||||
end
|
||||
|
||||
def test_annotate
|
||||
assert_equal [], @adapter.annotate("sources/welcome_controller.rb").lines
|
||||
[2, '400bb8672109', '400', 400].each do |r|
|
||||
ann = @adapter.annotate('sources/welcome_controller.rb', r)
|
||||
assert ann
|
||||
assert_equal '1', ann.revisions[17].revision
|
||||
assert_equal '9d5b5b004199', ann.revisions[17].identifier
|
||||
assert_equal 'jsmith', ann.revisions[0].author
|
||||
assert_equal 25, ann.lines.length
|
||||
assert_equal 'class WelcomeController < ApplicationController', ann.lines[17]
|
||||
end
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_nil @adapter.entries(nil, '100000')
|
||||
|
||||
assert_equal 1, @adapter.entries("sources", 3).size
|
||||
assert_equal 1, @adapter.entries("sources", 'b3a615152df8').size
|
||||
|
||||
[2, '400bb8672109', '400', 400].each do |r|
|
||||
entries1 = @adapter.entries(nil, r)
|
||||
assert entries1
|
||||
assert_equal 3, entries1.size
|
||||
assert_equal 'sources', entries1[1].name
|
||||
assert_equal 'sources', entries1[1].path
|
||||
assert_equal 'dir', entries1[1].kind
|
||||
readme = entries1[2]
|
||||
assert_equal 'README', readme.name
|
||||
assert_equal 'README', readme.path
|
||||
assert_equal 'file', readme.kind
|
||||
assert_equal 27, readme.size
|
||||
assert_equal '1', readme.lastrev.revision
|
||||
assert_equal '9d5b5b00419901478496242e0768deba1ce8c51e', readme.lastrev.identifier
|
||||
# 2007-12-14 10:24:01 +0100
|
||||
assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time
|
||||
|
||||
entries2 = @adapter.entries('sources', r)
|
||||
assert entries2
|
||||
assert_equal 2, entries2.size
|
||||
assert_equal 'watchers_controller.rb', entries2[0].name
|
||||
assert_equal 'sources/watchers_controller.rb', entries2[0].path
|
||||
assert_equal 'file', entries2[0].kind
|
||||
assert_equal 'welcome_controller.rb', entries2[1].name
|
||||
assert_equal 'sources/welcome_controller.rb', entries2[1].path
|
||||
assert_equal 'file', entries2[1].kind
|
||||
end
|
||||
end
|
||||
|
||||
def test_entries_tag
|
||||
entries1 = @adapter.entries(nil, 'tag_test.00')
|
||||
assert entries1
|
||||
assert_equal 3, entries1.size
|
||||
assert_equal 'sources', entries1[1].name
|
||||
assert_equal 'sources', entries1[1].path
|
||||
assert_equal 'dir', entries1[1].kind
|
||||
readme = entries1[2]
|
||||
assert_equal 'README', readme.name
|
||||
assert_equal 'README', readme.path
|
||||
assert_equal 'file', readme.kind
|
||||
assert_equal 21, readme.size
|
||||
assert_equal '0', readme.lastrev.revision
|
||||
assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', readme.lastrev.identifier
|
||||
# 2007-12-14 10:22:52 +0100
|
||||
assert_equal Time.gm(2007, 12, 14, 9, 22, 52), readme.lastrev.time
|
||||
end
|
||||
|
||||
def test_entries_branch
|
||||
entries1 = @adapter.entries(nil, 'test-branch-00')
|
||||
assert entries1
|
||||
assert_equal 5, entries1.size
|
||||
assert_equal 'sql_escape', entries1[2].name
|
||||
assert_equal 'sql_escape', entries1[2].path
|
||||
assert_equal 'dir', entries1[2].kind
|
||||
readme = entries1[4]
|
||||
assert_equal 'README', readme.name
|
||||
assert_equal 'README', readme.path
|
||||
assert_equal 'file', readme.kind
|
||||
assert_equal 365, readme.size
|
||||
assert_equal '8', readme.lastrev.revision
|
||||
assert_equal 'c51f5bb613cd60793c2a9fe9df29332e74bb949f', readme.lastrev.identifier
|
||||
# 2001-02-01 00:00:00 -0900
|
||||
assert_equal Time.gm(2001, 2, 1, 9, 0, 0), readme.lastrev.time
|
||||
end
|
||||
|
||||
def test_entry
|
||||
entry = @adapter.entry()
|
||||
assert_equal "", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
entry = @adapter.entry('')
|
||||
assert_equal "", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
assert_nil @adapter.entry('invalid')
|
||||
assert_nil @adapter.entry('/invalid')
|
||||
assert_nil @adapter.entry('/invalid/')
|
||||
assert_nil @adapter.entry('invalid/invalid')
|
||||
assert_nil @adapter.entry('invalid/invalid/')
|
||||
assert_nil @adapter.entry('/invalid/invalid')
|
||||
assert_nil @adapter.entry('/invalid/invalid/')
|
||||
["README", "/README"].each do |path|
|
||||
["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev|
|
||||
entry = @adapter.entry(path, rev)
|
||||
assert_equal "README", entry.path
|
||||
assert_equal "file", entry.kind
|
||||
assert_equal '0', entry.lastrev.revision
|
||||
assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', entry.lastrev.identifier
|
||||
end
|
||||
end
|
||||
["sources", "/sources", "/sources/"].each do |path|
|
||||
["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev|
|
||||
entry = @adapter.entry(path, rev)
|
||||
assert_equal "sources", entry.path
|
||||
assert_equal "dir", entry.kind
|
||||
end
|
||||
end
|
||||
["sources/watchers_controller.rb", "/sources/watchers_controller.rb"].each do |path|
|
||||
["0", "0885933ad4f6", "0885933ad4f68d77c2649cd11f8311276e7ef7ce"].each do |rev|
|
||||
entry = @adapter.entry(path, rev)
|
||||
assert_equal "sources/watchers_controller.rb", entry.path
|
||||
assert_equal "file", entry.kind
|
||||
assert_equal '0', entry.lastrev.revision
|
||||
assert_equal '0885933ad4f68d77c2649cd11f8311276e7ef7ce', entry.lastrev.identifier
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_locate_on_outdated_repository
|
||||
assert_equal 1, @adapter.entries("images", 0).size
|
||||
assert_equal 2, @adapter.entries("images").size
|
||||
assert_equal 2, @adapter.entries("images", 2).size
|
||||
end
|
||||
|
||||
def test_access_by_nodeid
|
||||
path = 'sources/welcome_controller.rb'
|
||||
assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400bb8672109')
|
||||
end
|
||||
|
||||
def test_access_by_fuzzy_nodeid
|
||||
path = 'sources/welcome_controller.rb'
|
||||
# falls back to nodeid
|
||||
assert_equal @adapter.cat(path, 2), @adapter.cat(path, '400')
|
||||
end
|
||||
|
||||
def test_tags
|
||||
assert_equal [@tag_char_1, 'tag_test.00', 'tag-init-revision'], @adapter.tags
|
||||
end
|
||||
|
||||
def test_tagmap
|
||||
tm = {
|
||||
@tag_char_1 => 'adf805632193500ad3b615cd04f58f9b0769f576',
|
||||
'tag_test.00' => '6987191f453a5f6557018d522feea2c450d5588d',
|
||||
'tag-init-revision' => '0885933ad4f68d77c2649cd11f8311276e7ef7ce',
|
||||
}
|
||||
assert_equal tm, @adapter.tagmap
|
||||
end
|
||||
|
||||
def test_branches
|
||||
brs = []
|
||||
@adapter.branches.each do |b|
|
||||
brs << b
|
||||
end
|
||||
assert_equal 7, brs.length
|
||||
assert_equal 'default', brs[0].to_s
|
||||
assert_equal '31', brs[0].revision
|
||||
assert_equal '31eeee7395c8c78e66dd54c50addd078d10b2355', brs[0].scmid
|
||||
assert_equal 'test-branch-01', brs[1].to_s
|
||||
assert_equal '30', brs[1].revision
|
||||
assert_equal 'ad4dc4f80284a4f9168b77e0b6de288e5d207ee7', brs[1].scmid
|
||||
assert_equal @branch_char_1, brs[2].to_s
|
||||
assert_equal '27', brs[2].revision
|
||||
assert_equal '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', brs[2].scmid
|
||||
assert_equal 'branch (1)[2]&,%.-3_4', brs[3].to_s
|
||||
assert_equal '25', brs[3].revision
|
||||
assert_equal 'afc61e85bde74de930e5846c8451bd55b5bafc9c', brs[3].scmid
|
||||
assert_equal @branch_char_0, brs[4].to_s
|
||||
assert_equal '23', brs[4].revision
|
||||
assert_equal 'c8d3e4887474af6a589190140508037ebaa9d9c3', brs[4].scmid
|
||||
assert_equal 'test_branch.latin-1', brs[5].to_s
|
||||
assert_equal '22', brs[5].revision
|
||||
assert_equal 'c2ffe7da686aa3d956e59f2a2854cf8980a8b768', brs[5].scmid
|
||||
assert_equal 'test-branch-00', brs[6].to_s
|
||||
assert_equal '13', brs[6].revision
|
||||
assert_equal '3a330eb329586ea2adb3f83237c23310e744ebe9', brs[6].scmid
|
||||
end
|
||||
|
||||
def test_branchmap
|
||||
bm = {
|
||||
'default' => '31eeee7395c8c78e66dd54c50addd078d10b2355',
|
||||
'test_branch.latin-1' => 'c2ffe7da686aa3d956e59f2a2854cf8980a8b768',
|
||||
'branch (1)[2]&,%.-3_4' => 'afc61e85bde74de930e5846c8451bd55b5bafc9c',
|
||||
'test-branch-00' => '3a330eb329586ea2adb3f83237c23310e744ebe9',
|
||||
"test-branch-01" => 'ad4dc4f80284a4f9168b77e0b6de288e5d207ee7',
|
||||
@branch_char_0 => 'c8d3e4887474af6a589190140508037ebaa9d9c3',
|
||||
@branch_char_1 => '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914',
|
||||
}
|
||||
assert_equal bm, @adapter.branchmap
|
||||
end
|
||||
|
||||
def test_path_space
|
||||
p = 'README (1)[2]&,%.-3_4'
|
||||
[15, '933ca60293d7'].each do |r1|
|
||||
assert @adapter.diff(p, r1)
|
||||
assert @adapter.cat(p, r1)
|
||||
assert_equal 1, @adapter.annotate(p, r1).lines.length
|
||||
[25, 'afc61e85bde7'].each do |r2|
|
||||
assert @adapter.diff(p, r1, r2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_tag_non_ascii
|
||||
p = "latin-1-dir/test-#{@char_1}-1.txt"
|
||||
assert @adapter.cat(p, @tag_char_1)
|
||||
assert_equal 1, @adapter.annotate(p, @tag_char_1).lines.length
|
||||
end
|
||||
|
||||
def test_branch_non_ascii
|
||||
p = "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-1.txt"
|
||||
assert @adapter.cat(p, @branch_char_1)
|
||||
assert_equal 1, @adapter.annotate(p, @branch_char_1).lines.length
|
||||
end
|
||||
|
||||
def test_nodes_in_branch
|
||||
[
|
||||
'default',
|
||||
@branch_char_1,
|
||||
'branch (1)[2]&,%.-3_4',
|
||||
@branch_char_0,
|
||||
'test_branch.latin-1',
|
||||
'test-branch-00',
|
||||
].each do |bra|
|
||||
nib0 = @adapter.nodes_in_branch(bra)
|
||||
assert nib0
|
||||
nib1 = @adapter.nodes_in_branch(bra, :limit => 1)
|
||||
assert_equal 1, nib1.size
|
||||
case bra
|
||||
when 'branch (1)[2]&,%.-3_4'
|
||||
if @adapter.class.client_version_above?([1, 6])
|
||||
assert_equal 3, nib0.size
|
||||
assert_equal 'afc61e85bde74de930e5846c8451bd55b5bafc9c', nib0[0]
|
||||
nib2 = @adapter.nodes_in_branch(bra, :limit => 2)
|
||||
assert_equal 2, nib2.size
|
||||
assert_equal '933ca60293d78f7c7979dd123cc0c02431683575', nib2[1]
|
||||
end
|
||||
when @branch_char_1
|
||||
if @adapter.class.client_version_above?([1, 6])
|
||||
assert_equal 2, nib0.size
|
||||
assert_equal '08ff3227303ec0dfcc818efa8e9cc652fe81859f', nib0[1]
|
||||
nib2 = @adapter.nodes_in_branch(bra, :limit => 1)
|
||||
assert_equal 1, nib2.size
|
||||
assert_equal '7bbf4c738e7145149d2e5eb1eed1d3a8ddd3b914', nib2[0]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_path_encoding_default_utf8
|
||||
adpt1 = Redmine::Scm::Adapters::MercurialAdapter.new(
|
||||
REPOSITORY_PATH
|
||||
)
|
||||
assert_equal "UTF-8", adpt1.path_encoding
|
||||
adpt2 = Redmine::Scm::Adapters::MercurialAdapter.new(
|
||||
REPOSITORY_PATH,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
""
|
||||
)
|
||||
assert_equal "UTF-8", adpt2.path_encoding
|
||||
end
|
||||
|
||||
def test_bad_early_options
|
||||
assert_nil @adapter.diff('sources/welcome_controller.rb',
|
||||
'--config=alias.rhdiff=!xterm')
|
||||
assert_raise HgCommandArgumentError do
|
||||
@adapter.entries('--debugger')
|
||||
end
|
||||
assert_raise HgCommandAborted do
|
||||
@adapter.revisions(nil, nil, nil, limit: '--repo=otherrepo')
|
||||
end
|
||||
assert_raise HgCommandAborted do
|
||||
@adapter.nodes_in_branch('default', limit: '--repository=otherrepo')
|
||||
end
|
||||
assert_raise HgCommandAborted do
|
||||
@adapter.nodes_in_branch('-Rotherrepo')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_hgversion_for(hgversion, version)
|
||||
@adapter.class.expects(:hgversion_from_command_line).returns(hgversion)
|
||||
if version
|
||||
assert_equal version, @adapter.class.hgversion
|
||||
else
|
||||
assert_nil @adapter.class.hgversion
|
||||
end
|
||||
end
|
||||
|
||||
def test_template_path_for(version, template)
|
||||
assert_equal "#{HELPERS_DIR}/#{TEMPLATE_NAME}-#{template}.#{TEMPLATE_EXTENSION}",
|
||||
@adapter.class.template_path_for(version)
|
||||
assert File.exist?(@adapter.class.template_path_for(version))
|
||||
end
|
||||
else
|
||||
puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,63 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class SubversionAdapterTest < ActiveSupport::TestCase
|
||||
|
||||
if repository_configured?('subversion')
|
||||
def setup
|
||||
@adapter = Redmine::Scm::Adapters::SubversionAdapter.new(self.class.subversion_repository_url)
|
||||
end
|
||||
|
||||
def test_client_version
|
||||
v = Redmine::Scm::Adapters::SubversionAdapter.client_version
|
||||
assert v.is_a?(Array)
|
||||
end
|
||||
|
||||
def test_scm_version
|
||||
to_test = { "svn, version 1.6.13 (r1002816)\n" => [1,6,13],
|
||||
"svn, versione 1.6.13 (r1002816)\n" => [1,6,13],
|
||||
"1.6.1\n1.7\n1.8" => [1,6,1],
|
||||
"1.6.2\r\n1.8.1\r\n1.9.1" => [1,6,2]}
|
||||
to_test.each do |s, v|
|
||||
test_scm_version_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_info_not_nil
|
||||
assert_not_nil @adapter.info
|
||||
end
|
||||
|
||||
def test_info_nil
|
||||
adpt = Redmine::Scm::Adapters::SubversionAdapter.new(
|
||||
"file:///invalid/invalid/"
|
||||
)
|
||||
assert_nil adpt.info
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_scm_version_for(scm_version, version)
|
||||
@adapter.class.expects(:scm_version_from_command_line).returns(scm_version)
|
||||
assert_equal version, @adapter.class.svn_binary_version
|
||||
end
|
||||
else
|
||||
puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
37
test/unit/lib/redmine/syntax_highlighting/coderay_test.rb
Normal file
37
test/unit/lib/redmine/syntax_highlighting/coderay_test.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::SyntaxHighlighting::CodeRayTest < ActiveSupport::TestCase
|
||||
def test_retrieve_supported_languages_should_return_array_of_symbols
|
||||
assert_kind_of Array, Redmine::SyntaxHighlighting::CodeRay.send(:retrieve_supported_languages)
|
||||
assert_kind_of Symbol, Redmine::SyntaxHighlighting::CodeRay.send(:retrieve_supported_languages).first
|
||||
end
|
||||
|
||||
def test_retrieve_supported_languages_should_return_array_of_symbols_holding_languages
|
||||
assert_includes Redmine::SyntaxHighlighting::CodeRay.send(:retrieve_supported_languages), :ruby
|
||||
end
|
||||
|
||||
def test_retrieve_supported_languages_should_return_array_of_symbols_holding_languages_aliases
|
||||
assert_includes Redmine::SyntaxHighlighting::CodeRay.send(:retrieve_supported_languages), :javascript
|
||||
end
|
||||
|
||||
def test_retrieve_supported_languages_should_return_array_of_symbols_not_holding_internal_languages
|
||||
refute_includes Redmine::SyntaxHighlighting::CodeRay.send(:retrieve_supported_languages), :default
|
||||
end
|
||||
end
|
61
test/unit/lib/redmine/themes_test.rb
Normal file
61
test/unit/lib/redmine/themes_test.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::ThemesTest < ActiveSupport::TestCase
|
||||
|
||||
def test_themes
|
||||
themes = Redmine::Themes.themes
|
||||
assert_kind_of Array, themes
|
||||
assert_kind_of Redmine::Themes::Theme, themes.first
|
||||
end
|
||||
|
||||
def test_rescan
|
||||
Redmine::Themes.themes.pop
|
||||
|
||||
assert_difference 'Redmine::Themes.themes.size' do
|
||||
Redmine::Themes.rescan
|
||||
end
|
||||
end
|
||||
|
||||
def test_theme_loaded
|
||||
theme = Redmine::Themes.themes.last
|
||||
|
||||
assert_equal theme, Redmine::Themes.theme(theme.id)
|
||||
end
|
||||
|
||||
def test_theme_loaded_without_rescan
|
||||
theme = Redmine::Themes.themes.last
|
||||
|
||||
assert_equal theme, Redmine::Themes.theme(theme.id, :rescan => false)
|
||||
end
|
||||
|
||||
def test_theme_not_loaded
|
||||
theme = Redmine::Themes.themes.pop
|
||||
|
||||
assert_equal theme, Redmine::Themes.theme(theme.id)
|
||||
end
|
||||
|
||||
def test_theme_not_loaded_without_rescan
|
||||
theme = Redmine::Themes.themes.pop
|
||||
|
||||
assert_nil Redmine::Themes.theme(theme.id, :rescan => false)
|
||||
ensure
|
||||
Redmine::Themes.rescan
|
||||
end
|
||||
end
|
352
test/unit/lib/redmine/unified_diff_test.rb
Normal file
352
test/unit/lib/redmine/unified_diff_test.rb
Normal file
|
@ -0,0 +1,352 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::UnifiedDiffTest < ActiveSupport::TestCase
|
||||
def test_subversion_diff
|
||||
diff = Redmine::UnifiedDiff.new(read_diff_fixture('subversion.diff'))
|
||||
# number of files
|
||||
assert_equal 4, diff.size
|
||||
assert diff.detect {|file| file.file_name =~ %r{^config/settings.yml}}
|
||||
end
|
||||
|
||||
def test_truncate_diff
|
||||
diff = Redmine::UnifiedDiff.new(read_diff_fixture('subversion.diff'), :max_lines => 20)
|
||||
assert_equal 2, diff.size
|
||||
end
|
||||
|
||||
def test_inline_partials
|
||||
diff = Redmine::UnifiedDiff.new(read_diff_fixture('partials.diff'))
|
||||
assert_equal 1, diff.size
|
||||
diff = diff.first
|
||||
assert_equal 43, diff.size
|
||||
|
||||
assert_equal [51, -1], diff[0].offsets
|
||||
assert_equal [51, -1], diff[1].offsets
|
||||
assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>elit</span>', diff[0].html_line
|
||||
assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>xx</span>', diff[1].html_line
|
||||
|
||||
assert_nil diff[2].offsets
|
||||
assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[2].html_line
|
||||
|
||||
assert_equal [0, -14], diff[3].offsets
|
||||
assert_equal [0, -14], diff[4].offsets
|
||||
assert_equal '<span>Ut sed</span> auctor justo', diff[3].html_line
|
||||
assert_equal '<span>xxx</span> auctor justo', diff[4].html_line
|
||||
|
||||
assert_equal [13, -19], diff[6].offsets
|
||||
assert_equal [13, -19], diff[7].offsets
|
||||
|
||||
assert_equal [24, -8], diff[9].offsets
|
||||
assert_equal [24, -8], diff[10].offsets
|
||||
|
||||
assert_equal [37, -1], diff[12].offsets
|
||||
assert_equal [37, -1], diff[13].offsets
|
||||
|
||||
assert_equal [0, -38], diff[15].offsets
|
||||
assert_equal [0, -38], diff[16].offsets
|
||||
end
|
||||
|
||||
def test_side_by_side_partials
|
||||
diff = Redmine::UnifiedDiff.new(read_diff_fixture('partials.diff'), :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
diff = diff.first
|
||||
assert_equal 32, diff.size
|
||||
|
||||
assert_equal [51, -1], diff[0].offsets
|
||||
assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>elit</span>', diff[0].html_line_left
|
||||
assert_equal 'Lorem ipsum dolor sit amet, consectetur adipiscing <span>xx</span>', diff[0].html_line_right
|
||||
|
||||
assert_nil diff[1].offsets
|
||||
assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[1].html_line_left
|
||||
assert_equal 'Praesent et sagittis dui. Vivamus ac diam diam', diff[1].html_line_right
|
||||
|
||||
assert_equal [0, -14], diff[2].offsets
|
||||
assert_equal '<span>Ut sed</span> auctor justo', diff[2].html_line_left
|
||||
assert_equal '<span>xxx</span> auctor justo', diff[2].html_line_right
|
||||
|
||||
assert_equal [13, -19], diff[4].offsets
|
||||
assert_equal [24, -8], diff[6].offsets
|
||||
assert_equal [37, -1], diff[8].offsets
|
||||
assert_equal [0, -38], diff[10].offsets
|
||||
|
||||
end
|
||||
|
||||
def test_partials_with_html_entities
|
||||
raw = <<-DIFF
|
||||
--- test.orig.txt Wed Feb 15 16:10:39 2012
|
||||
+++ test.new.txt Wed Feb 15 16:11:25 2012
|
||||
@@ -1,5 +1,5 @@
|
||||
Semicolons were mysteriously appearing in code diffs in the repository
|
||||
|
||||
-void DoSomething(std::auto_ptr<MyClass> myObj)
|
||||
+void DoSomething(const MyClass& myObj)
|
||||
|
||||
DIFF
|
||||
|
||||
diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 'void DoSomething(<span>std::auto_ptr<MyClass></span> myObj)', diff.first[2].html_line_left
|
||||
assert_equal 'void DoSomething(<span>const MyClass&</span> myObj)', diff.first[2].html_line_right
|
||||
|
||||
diff = Redmine::UnifiedDiff.new(raw, :type => 'inline')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 'void DoSomething(<span>std::auto_ptr<MyClass></span> myObj)', diff.first[2].html_line
|
||||
assert_equal 'void DoSomething(<span>const MyClass&</span> myObj)', diff.first[3].html_line
|
||||
end
|
||||
|
||||
def test_line_starting_with_dashes
|
||||
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
||||
--- old.txt Wed Nov 11 14:24:58 2009
|
||||
+++ new.txt Wed Nov 11 14:25:02 2009
|
||||
@@ -1,8 +1,4 @@
|
||||
-Lines that starts with dashes:
|
||||
-
|
||||
-------------------------
|
||||
--- file.c
|
||||
-------------------------
|
||||
+A line that starts with dashes:
|
||||
|
||||
and removed.
|
||||
|
||||
@@ -23,4 +19,4 @@
|
||||
|
||||
|
||||
|
||||
-Another chunk of change
|
||||
+Another chunk of changes
|
||||
|
||||
DIFF
|
||||
)
|
||||
assert_equal 1, diff.size
|
||||
end
|
||||
|
||||
def test_one_line_new_files
|
||||
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
||||
diff -r 000000000000 -r ea98b14f75f0 README1
|
||||
--- /dev/null
|
||||
+++ b/README1
|
||||
@@ -0,0 +1,1 @@
|
||||
+test1
|
||||
diff -r 000000000000 -r ea98b14f75f0 README2
|
||||
--- /dev/null
|
||||
+++ b/README2
|
||||
@@ -0,0 +1,1 @@
|
||||
+test2
|
||||
diff -r 000000000000 -r ea98b14f75f0 README3
|
||||
--- /dev/null
|
||||
+++ b/README3
|
||||
@@ -0,0 +1,3 @@
|
||||
+test4
|
||||
+test5
|
||||
+test6
|
||||
diff -r 000000000000 -r ea98b14f75f0 README4
|
||||
--- /dev/null
|
||||
+++ b/README4
|
||||
@@ -0,0 +1,3 @@
|
||||
+test4
|
||||
+test5
|
||||
+test6
|
||||
DIFF
|
||||
)
|
||||
assert_equal 4, diff.size
|
||||
assert_equal "README1", diff[0].file_name
|
||||
end
|
||||
|
||||
def test_both_git_diff
|
||||
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
||||
# HG changeset patch
|
||||
# User test
|
||||
# Date 1348014182 -32400
|
||||
# Node ID d1c871b8ef113df7f1c56d41e6e3bfbaff976e1f
|
||||
# Parent 180b6605936cdc7909c5f08b59746ec1a7c99b3e
|
||||
modify test1.txt
|
||||
|
||||
diff -r 180b6605936c -r d1c871b8ef11 test1.txt
|
||||
--- a/test1.txt
|
||||
+++ b/test1.txt
|
||||
@@ -1,1 +1,1 @@
|
||||
-test1
|
||||
+modify test1
|
||||
DIFF
|
||||
)
|
||||
assert_equal 1, diff.size
|
||||
assert_equal "test1.txt", diff[0].file_name
|
||||
end
|
||||
|
||||
def test_include_a_b_slash
|
||||
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
||||
--- test1.txt
|
||||
+++ b/test02.txt
|
||||
@@ -1 +0,0 @@
|
||||
-modify test1
|
||||
DIFF
|
||||
)
|
||||
assert_equal 1, diff.size
|
||||
assert_equal "b/test02.txt", diff[0].file_name
|
||||
|
||||
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
||||
--- a/test1.txt
|
||||
+++ a/test02.txt
|
||||
@@ -1 +0,0 @@
|
||||
-modify test1
|
||||
DIFF
|
||||
)
|
||||
assert_equal 1, diff.size
|
||||
assert_equal "a/test02.txt", diff[0].file_name
|
||||
|
||||
diff = Redmine::UnifiedDiff.new(<<-DIFF
|
||||
--- a/test1.txt
|
||||
+++ test02.txt
|
||||
@@ -1 +0,0 @@
|
||||
-modify test1
|
||||
DIFF
|
||||
)
|
||||
assert_equal 1, diff.size
|
||||
assert_equal "test02.txt", diff[0].file_name
|
||||
end
|
||||
|
||||
def test_utf8_ja
|
||||
ja = " text_tip_issue_end_day: "
|
||||
ja += "\xe3\x81\x93\xe3\x81\xae\xe6\x97\xa5\xe3\x81\xab\xe7\xb5\x82\xe4\xba\x86\xe3\x81\x99\xe3\x82\x8b<span>\xe3\x82\xbf\xe3\x82\xb9\xe3\x82\xaf</span>".force_encoding('UTF-8')
|
||||
with_settings :repositories_encodings => '' do
|
||||
diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ja.diff'), :type => 'inline')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 12, diff.first.size
|
||||
assert_equal ja, diff.first[4].html_line_left
|
||||
end
|
||||
end
|
||||
|
||||
def test_utf8_ru
|
||||
ru = " other: "\xd0\xbe\xd0\xba\xd0\xbe\xd0\xbb\xd0\xbe %{count} \xd1\x87\xd0\xb0\xd1\x81<span>\xd0\xb0</span>"".force_encoding('UTF-8')
|
||||
with_settings :repositories_encodings => '' do
|
||||
diff = Redmine::UnifiedDiff.new(read_diff_fixture('issue-12641-ru.diff'), :type => 'inline')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 8, diff.first.size
|
||||
assert_equal ru, diff.first[3].html_line_left
|
||||
end
|
||||
end
|
||||
|
||||
def test_offset_range_ascii_1
|
||||
raw = <<-DIFF
|
||||
--- a.txt 2013-04-05 14:19:39.000000000 +0900
|
||||
+++ b.txt 2013-04-05 14:19:51.000000000 +0900
|
||||
@@ -1,3 +1,3 @@
|
||||
aaaa
|
||||
-abc
|
||||
+abcd
|
||||
bbbb
|
||||
DIFF
|
||||
diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 3, diff.first.size
|
||||
assert_equal "abc<span></span>", diff.first[1].html_line_left
|
||||
assert_equal "abc<span>d</span>", diff.first[1].html_line_right
|
||||
end
|
||||
|
||||
def test_offset_range_ascii_2
|
||||
raw = <<-DIFF
|
||||
--- a.txt 2013-04-05 14:19:39.000000000 +0900
|
||||
+++ b.txt 2013-04-05 14:19:51.000000000 +0900
|
||||
@@ -1,3 +1,3 @@
|
||||
aaaa
|
||||
-abc
|
||||
+zabc
|
||||
bbbb
|
||||
DIFF
|
||||
diff = Redmine::UnifiedDiff.new(raw, :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 3, diff.first.size
|
||||
assert_equal "<span></span>abc", diff.first[1].html_line_left
|
||||
assert_equal "<span>z</span>abc", diff.first[1].html_line_right
|
||||
end
|
||||
|
||||
def test_offset_range_japanese_1
|
||||
ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span></span>".force_encoding('UTF-8')
|
||||
ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x9e</span>".force_encoding('UTF-8')
|
||||
with_settings :repositories_encodings => '' do
|
||||
diff = Redmine::UnifiedDiff.new(
|
||||
read_diff_fixture('issue-13644-1.diff'), :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 3, diff.first.size
|
||||
assert_equal ja1, diff.first[1].html_line_left
|
||||
assert_equal ja2, diff.first[1].html_line_right
|
||||
end
|
||||
end
|
||||
|
||||
def test_offset_range_japanese_2
|
||||
ja1 = "<span></span>\xe6\x97\xa5\xe6\x9c\xac".force_encoding('UTF-8')
|
||||
ja2 = "<span>\xe3\x81\xab\xe3\x81\xa3\xe3\x81\xbd\xe3\x82\x93</span>\xe6\x97\xa5\xe6\x9c\xac".force_encoding('UTF-8')
|
||||
with_settings :repositories_encodings => '' do
|
||||
diff = Redmine::UnifiedDiff.new(
|
||||
read_diff_fixture('issue-13644-2.diff'), :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 3, diff.first.size
|
||||
assert_equal ja1, diff.first[1].html_line_left
|
||||
assert_equal ja2, diff.first[1].html_line_right
|
||||
end
|
||||
end
|
||||
|
||||
def test_offset_range_japanese_3
|
||||
# UTF-8 The 1st byte differs.
|
||||
ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>".force_encoding('UTF-8')
|
||||
ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe5\xa8\x98</span>".force_encoding('UTF-8')
|
||||
with_settings :repositories_encodings => '' do
|
||||
diff = Redmine::UnifiedDiff.new(
|
||||
read_diff_fixture('issue-13644-3.diff'), :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 3, diff.first.size
|
||||
assert_equal ja1, diff.first[1].html_line_left
|
||||
assert_equal ja2, diff.first[1].html_line_right
|
||||
end
|
||||
end
|
||||
|
||||
def test_offset_range_japanese_4
|
||||
# UTF-8 The 2nd byte differs.
|
||||
ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>".force_encoding('UTF-8')
|
||||
ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x98</span>".force_encoding('UTF-8')
|
||||
with_settings :repositories_encodings => '' do
|
||||
diff = Redmine::UnifiedDiff.new(
|
||||
read_diff_fixture('issue-13644-4.diff'), :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 3, diff.first.size
|
||||
assert_equal ja1, diff.first[1].html_line_left
|
||||
assert_equal ja2, diff.first[1].html_line_right
|
||||
end
|
||||
end
|
||||
|
||||
def test_offset_range_japanese_5
|
||||
# UTF-8 The 2nd byte differs.
|
||||
ja1 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xa8\x98</span>ok".force_encoding('UTF-8')
|
||||
ja2 = "\xe6\x97\xa5\xe6\x9c\xac<span>\xe8\xaa\x98</span>ok".force_encoding('UTF-8')
|
||||
with_settings :repositories_encodings => '' do
|
||||
diff = Redmine::UnifiedDiff.new(
|
||||
read_diff_fixture('issue-13644-5.diff'), :type => 'sbs')
|
||||
assert_equal 1, diff.size
|
||||
assert_equal 3, diff.first.size
|
||||
assert_equal ja1, diff.first[1].html_line_left
|
||||
assert_equal ja2, diff.first[1].html_line_right
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def read_diff_fixture(filename)
|
||||
File.new(File.join(File.dirname(__FILE__), '/../../../fixtures/diffs', filename)).read
|
||||
end
|
||||
end
|
76
test/unit/lib/redmine/utils/date_calculation.rb
Normal file
76
test/unit/lib/redmine/utils/date_calculation.rb
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Utils::DateCalculationTest < ActiveSupport::TestCase
|
||||
include Redmine::Utils::DateCalculation
|
||||
|
||||
def test_working_days_without_non_working_week_days
|
||||
with_settings :non_working_week_days => [] do
|
||||
assert_working_days 18, '2012-10-09', '2012-10-27'
|
||||
assert_working_days 6, '2012-10-09', '2012-10-15'
|
||||
assert_working_days 5, '2012-10-09', '2012-10-14'
|
||||
assert_working_days 3, '2012-10-09', '2012-10-12'
|
||||
assert_working_days 3, '2012-10-14', '2012-10-17'
|
||||
assert_working_days 16, '2012-10-14', '2012-10-30'
|
||||
end
|
||||
end
|
||||
|
||||
def test_working_days_with_non_working_week_days
|
||||
with_settings :non_working_week_days => %w(6 7) do
|
||||
assert_working_days 14, '2012-10-09', '2012-10-27'
|
||||
assert_working_days 4, '2012-10-09', '2012-10-15'
|
||||
assert_working_days 4, '2012-10-09', '2012-10-14'
|
||||
assert_working_days 3, '2012-10-09', '2012-10-12'
|
||||
assert_working_days 8, '2012-10-09', '2012-10-19'
|
||||
assert_working_days 8, '2012-10-11', '2012-10-23'
|
||||
assert_working_days 2, '2012-10-14', '2012-10-17'
|
||||
assert_working_days 11, '2012-10-14', '2012-10-30'
|
||||
end
|
||||
end
|
||||
|
||||
def test_add_working_days_without_non_working_week_days
|
||||
with_settings :non_working_week_days => [] do
|
||||
assert_add_working_days '2012-10-10', '2012-10-10', 0
|
||||
assert_add_working_days '2012-10-11', '2012-10-10', 1
|
||||
assert_add_working_days '2012-10-12', '2012-10-10', 2
|
||||
assert_add_working_days '2012-10-13', '2012-10-10', 3
|
||||
assert_add_working_days '2012-10-25', '2012-10-10', 15
|
||||
end
|
||||
end
|
||||
|
||||
def test_add_working_days_with_non_working_week_days
|
||||
with_settings :non_working_week_days => %w(6 7) do
|
||||
assert_add_working_days '2012-10-10', '2012-10-10', 0
|
||||
assert_add_working_days '2012-10-11', '2012-10-10', 1
|
||||
assert_add_working_days '2012-10-12', '2012-10-10', 2
|
||||
assert_add_working_days '2012-10-15', '2012-10-10', 3
|
||||
assert_add_working_days '2012-10-31', '2012-10-10', 15
|
||||
assert_add_working_days '2012-10-19', '2012-10-09', 8
|
||||
assert_add_working_days '2012-10-23', '2012-10-11', 8
|
||||
end
|
||||
end
|
||||
|
||||
def assert_working_days(expected_days, from, to)
|
||||
assert_equal expected_days, working_days(from.to_date, to.to_date)
|
||||
end
|
||||
|
||||
def assert_add_working_days(expected_date, from, working_days)
|
||||
assert_equal expected_date.to_date, add_working_days(from.to_date, working_days)
|
||||
end
|
||||
end
|
94
test/unit/lib/redmine/views/builders/json_test.rb
Normal file
94
test/unit/lib/redmine/views/builders/json_test.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Views::Builders::JsonTest < ActiveSupport::TestCase
|
||||
|
||||
def test_hash
|
||||
assert_json_output({'person' => {'name' => 'Ryan', 'age' => 32}}) do |b|
|
||||
b.person do
|
||||
b.name 'Ryan'
|
||||
b.age 32
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_hash_hash
|
||||
assert_json_output({'person' => {'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
|
||||
b.person do
|
||||
b.name 'Ryan'
|
||||
b.birth :city => 'London', :country => 'UK'
|
||||
end
|
||||
end
|
||||
|
||||
assert_json_output({'person' => {'id' => 1, 'name' => 'Ryan', 'birth' => {'city' => 'London', 'country' => 'UK'}}}) do |b|
|
||||
b.person :id => 1 do
|
||||
b.name 'Ryan'
|
||||
b.birth :city => 'London', :country => 'UK'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_array
|
||||
assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
|
||||
b.array :books do |b|
|
||||
b.book :title => 'Book 1', :author => 'B. Smith'
|
||||
b.book :title => 'Book 2', :author => 'G. Cooper'
|
||||
end
|
||||
end
|
||||
|
||||
assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
|
||||
b.array :books do |b|
|
||||
b.book :title => 'Book 1' do
|
||||
b.author 'B. Smith'
|
||||
end
|
||||
b.book :title => 'Book 2' do
|
||||
b.author 'G. Cooper'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_array_with_content_tags
|
||||
assert_json_output({'books' => [{'value' => 'Book 1', 'author' => 'B. Smith'}, {'value' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b|
|
||||
b.array :books do |b|
|
||||
b.book 'Book 1', :author => 'B. Smith'
|
||||
b.book 'Book 2', :author => 'G. Cooper'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_nested_arrays
|
||||
assert_json_output({'books' => [{'authors' => ['B. Smith', 'G. Cooper']}]}) do |b|
|
||||
b.array :books do |books|
|
||||
books.book do |book|
|
||||
book.array :authors do |authors|
|
||||
authors.author 'B. Smith'
|
||||
authors.author 'G. Cooper'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_json_output(expected, &block)
|
||||
builder = Redmine::Views::Builders::Json.new(ActionDispatch::TestRequest.new, ActionDispatch::TestResponse.new)
|
||||
block.call(builder)
|
||||
assert_equal(expected, ActiveSupport::JSON.decode(builder.output))
|
||||
end
|
||||
end
|
67
test/unit/lib/redmine/views/builders/xml_test.rb
Normal file
67
test/unit/lib/redmine/views/builders/xml_test.rb
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Views::Builders::XmlTest < ActiveSupport::TestCase
|
||||
|
||||
def test_hash
|
||||
assert_xml_output('<person><name>Ryan</name><age>32</age></person>') do |b|
|
||||
b.person do
|
||||
b.name 'Ryan'
|
||||
b.age 32
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_array
|
||||
assert_xml_output('<books type="array"><book title="Book 1"/><book title="Book 2"/></books>') do |b|
|
||||
b.array :books do |b|
|
||||
b.book :title => 'Book 1'
|
||||
b.book :title => 'Book 2'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_array_with_content_tags
|
||||
assert_xml_output('<books type="array"><book author="B. Smith">Book 1</book><book author="G. Cooper">Book 2</book></books>') do |b|
|
||||
b.array :books do |b|
|
||||
b.book 'Book 1', :author => 'B. Smith'
|
||||
b.book 'Book 2', :author => 'G. Cooper'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_nested_arrays
|
||||
assert_xml_output('<books type="array"><book><authors type="array"><author>B. Smith</author><author>G. Cooper</author></authors></book></books>') do |b|
|
||||
b.array :books do |books|
|
||||
books.book do |book|
|
||||
book.array :authors do |authors|
|
||||
authors.author 'B. Smith'
|
||||
authors.author 'G. Cooper'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def assert_xml_output(expected, &block)
|
||||
builder = Redmine::Views::Builders::Xml.new(ActionDispatch::TestRequest.new, ActionDispatch::TestResponse.new)
|
||||
block.call(builder)
|
||||
assert_equal('<?xml version="1.0" encoding="UTF-8"?>' + expected, builder.output)
|
||||
end
|
||||
end
|
48
test/unit/lib/redmine/views/labelled_form_builder_test.rb
Normal file
48
test/unit/lib/redmine/views/labelled_form_builder_test.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::Views::LabelledFormBuilderTest < Redmine::HelperTest
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
def test_label_should_output_one_element
|
||||
set_language_if_valid 'en'
|
||||
labelled_form_for(Issue.new) do |f|
|
||||
output = f.label :subject
|
||||
assert_equal output, '<label for="issue_subject">Subject</label>'
|
||||
end
|
||||
end
|
||||
|
||||
def test_hours_field_should_display_formatted_value_if_valid
|
||||
entry = TimeEntry.new(:hours => '2.5')
|
||||
entry.validate
|
||||
|
||||
labelled_form_for(entry) do |f|
|
||||
assert_include 'value="2.50"', f.hours_field(:hours)
|
||||
end
|
||||
end
|
||||
|
||||
def test_hours_field_should_display_entered_value_if_invalid
|
||||
entry = TimeEntry.new(:hours => '2.z')
|
||||
entry.validate
|
||||
|
||||
labelled_form_for(entry) do |f|
|
||||
assert_include 'value="2.z"', f.hours_field(:hours)
|
||||
end
|
||||
end
|
||||
end
|
35
test/unit/lib/redmine/wiki_formatting/html_parser_test.rb
Normal file
35
test/unit/lib/redmine/wiki_formatting/html_parser_test.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::WikiFormatting::HtmlParserTest < ActiveSupport::TestCase
|
||||
|
||||
def setup
|
||||
@parser = Redmine::WikiFormatting::HtmlParser
|
||||
end
|
||||
|
||||
def test_convert_line_breaks
|
||||
assert_equal "A html snippet with\na new line.",
|
||||
@parser.to_text('<p>A html snippet with<br>a new line.</p>')
|
||||
end
|
||||
|
||||
def test_should_remove_style_tags_from_body
|
||||
assert_equal "Text",
|
||||
@parser.to_text('<html><body><style>body {font-size: 0.8em;}</style>Text</body></html>')
|
||||
end
|
||||
end
|
404
test/unit/lib/redmine/wiki_formatting/macros_test.rb
Normal file
404
test/unit/lib/redmine/wiki_formatting/macros_test.rb
Normal file
|
@ -0,0 +1,404 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest
|
||||
include ApplicationHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
include ERB::Util
|
||||
include Rails.application.routes.url_helpers
|
||||
extend ActionView::Helpers::SanitizeHelper::ClassMethods
|
||||
|
||||
fixtures :projects, :roles, :enabled_modules, :users,
|
||||
:repositories, :changesets,
|
||||
:trackers, :issue_statuses, :issues,
|
||||
:versions, :documents,
|
||||
:wikis, :wiki_pages, :wiki_contents,
|
||||
:boards, :messages,
|
||||
:attachments
|
||||
|
||||
def setup
|
||||
super
|
||||
@project = nil
|
||||
end
|
||||
|
||||
def teardown
|
||||
end
|
||||
|
||||
def test_macro_registration
|
||||
Redmine::WikiFormatting::Macros.register do
|
||||
macro :foo do |obj, args|
|
||||
"Foo: #{args.size} (#{args.join(',')}) (#{args.class.name})"
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo}}")
|
||||
assert_equal '<p>Foo: 0 () (Array)</p>', textilizable("{{foo()}}")
|
||||
assert_equal '<p>Foo: 1 (arg1) (Array)</p>', textilizable("{{foo(arg1)}}")
|
||||
assert_equal '<p>Foo: 2 (arg1,arg2) (Array)</p>', textilizable("{{foo(arg1, arg2)}}")
|
||||
end
|
||||
|
||||
def test_macro_registration_parse_args_set_to_false_should_disable_arguments_parsing
|
||||
Redmine::WikiFormatting::Macros.register do
|
||||
macro :bar, :parse_args => false do |obj, args|
|
||||
"Bar: (#{args}) (#{args.class.name})"
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal '<p>Bar: (args, more args) (String)</p>', textilizable("{{bar(args, more args)}}")
|
||||
assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar}}")
|
||||
assert_equal '<p>Bar: () (String)</p>', textilizable("{{bar()}}")
|
||||
end
|
||||
|
||||
def test_macro_registration_with_3_args_should_receive_text_argument
|
||||
Redmine::WikiFormatting::Macros.register do
|
||||
macro :baz do |obj, args, text|
|
||||
"Baz: (#{args.join(',')}) (#{text.class.name}) (#{text})"
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz}}")
|
||||
assert_equal "<p>Baz: () (NilClass) ()</p>", textilizable("{{baz()}}")
|
||||
assert_equal "<p>Baz: () (String) (line1\nline2)</p>", textilizable("{{baz()\nline1\nline2\n}}")
|
||||
assert_equal "<p>Baz: (arg1,arg2) (String) (line1\nline2)</p>", textilizable("{{baz(arg1, arg2)\nline1\nline2\n}}")
|
||||
end
|
||||
|
||||
def test_macro_name_with_upper_case
|
||||
Redmine::WikiFormatting::Macros.macro(:UpperCase) {|obj, args| "Upper"}
|
||||
|
||||
assert_equal "<p>Upper</p>", textilizable("{{UpperCase}}")
|
||||
end
|
||||
|
||||
def test_multiple_macros_on_the_same_line
|
||||
Redmine::WikiFormatting::Macros.macro :foo do |obj, args|
|
||||
args.any? ? "args: #{args.join(',')}" : "no args"
|
||||
end
|
||||
|
||||
assert_equal '<p>no args no args</p>', textilizable("{{foo}} {{foo}}")
|
||||
assert_equal '<p>args: a,b no args</p>', textilizable("{{foo(a,b)}} {{foo}}")
|
||||
assert_equal '<p>args: a,b args: c,d</p>', textilizable("{{foo(a,b)}} {{foo(c,d)}}")
|
||||
assert_equal '<p>no args args: c,d</p>', textilizable("{{foo}} {{foo(c,d)}}")
|
||||
end
|
||||
|
||||
def test_macro_should_receive_the_object_as_argument_when_with_object_and_attribute
|
||||
issue = Issue.find(1)
|
||||
issue.description = "{{hello_world}}"
|
||||
assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(issue, :description)
|
||||
end
|
||||
|
||||
def test_macro_should_receive_the_object_as_argument_when_called_with_object_option
|
||||
text = "{{hello_world}}"
|
||||
assert_equal '<p>Hello world! Object: Issue, Called with no argument and no block of text.</p>', textilizable(text, :object => Issue.find(1))
|
||||
end
|
||||
|
||||
def test_extract_macro_options_should_with_args
|
||||
options = extract_macro_options(["arg1", "arg2"], :foo, :size)
|
||||
assert_equal([["arg1", "arg2"], {}], options)
|
||||
end
|
||||
|
||||
def test_extract_macro_options_should_with_options
|
||||
options = extract_macro_options(["foo=bar", "size=2"], :foo, :size)
|
||||
assert_equal([[], {:foo => "bar", :size => "2"}], options)
|
||||
end
|
||||
|
||||
def test_extract_macro_options_should_with_args_and_options
|
||||
options = extract_macro_options(["arg1", "arg2", "foo=bar", "size=2"], :foo, :size)
|
||||
assert_equal([["arg1", "arg2"], {:foo => "bar", :size => "2"}], options)
|
||||
end
|
||||
|
||||
def test_extract_macro_options_should_parse_options_lazily
|
||||
options = extract_macro_options(["params=x=1&y=2"], :params)
|
||||
assert_equal([[], {:params => "x=1&y=2"}], options)
|
||||
end
|
||||
|
||||
def test_macro_exception_should_be_displayed
|
||||
Redmine::WikiFormatting::Macros.macro :exception do |obj, args|
|
||||
raise "My message"
|
||||
end
|
||||
|
||||
text = "{{exception}}"
|
||||
assert_include '<div class="flash error">Error executing the <strong>exception</strong> macro (My message)</div>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_macro_arguments_should_not_be_parsed_by_formatters
|
||||
text = '{{hello_world(http://www.redmine.org, #1)}}'
|
||||
assert_include 'Arguments: http://www.redmine.org, #1', textilizable(text)
|
||||
end
|
||||
|
||||
def test_exclamation_mark_should_not_run_macros
|
||||
text = "!{{hello_world}}"
|
||||
assert_equal '<p>{{hello_world}}</p>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_exclamation_mark_should_escape_macros
|
||||
text = "!{{hello_world(<tag>)}}"
|
||||
assert_equal '<p>{{hello_world(<tag>)}}</p>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_unknown_macros_should_not_be_replaced
|
||||
text = "{{unknown}}"
|
||||
assert_equal '<p>{{unknown}}</p>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_unknown_macros_should_parsed_as_text
|
||||
text = "{{unknown(*test*)}}"
|
||||
assert_equal '<p>{{unknown(<strong>test</strong>)}}</p>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_unknown_macros_should_be_escaped
|
||||
text = "{{unknown(<tag>)}}"
|
||||
assert_equal '<p>{{unknown(<tag>)}}</p>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_html_safe_macro_output_should_not_be_escaped
|
||||
Redmine::WikiFormatting::Macros.macro :safe_macro do |obj, args|
|
||||
"<tag>".html_safe
|
||||
end
|
||||
assert_equal '<p><tag></p>', textilizable("{{safe_macro}}")
|
||||
end
|
||||
|
||||
def test_macro_hello_world
|
||||
text = "{{hello_world}}"
|
||||
assert textilizable(text).match(/Hello world!/)
|
||||
end
|
||||
|
||||
def test_macro_hello_world_should_escape_arguments
|
||||
text = "{{hello_world(<tag>)}}"
|
||||
assert_include 'Arguments: <tag>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_macro_macro_list
|
||||
text = "{{macro_list}}"
|
||||
assert_match %r{<code>hello_world</code>}, textilizable(text)
|
||||
end
|
||||
|
||||
def test_macro_include
|
||||
@project = Project.find(1)
|
||||
# include a page of the current project wiki
|
||||
text = "{{include(Another page)}}"
|
||||
assert_include 'This is a link to a ticket', textilizable(text)
|
||||
|
||||
@project = nil
|
||||
# include a page of a specific project wiki
|
||||
text = "{{include(ecookbook:Another page)}}"
|
||||
assert_include 'This is a link to a ticket', textilizable(text)
|
||||
|
||||
text = "{{include(ecookbook:)}}"
|
||||
assert_include 'CookBook documentation', textilizable(text)
|
||||
|
||||
text = "{{include(unknowidentifier:somepage)}}"
|
||||
assert_include 'Page not found', textilizable(text)
|
||||
end
|
||||
|
||||
def test_macro_collapse
|
||||
text = "{{collapse\n*Collapsed* block of text\n}}"
|
||||
with_locale 'en' do
|
||||
result = textilizable(text)
|
||||
|
||||
assert_select_in result, 'div.collapsed-text'
|
||||
assert_select_in result, 'strong', :text => 'Collapsed'
|
||||
assert_select_in result, 'a.collapsible.collapsed', :text => 'Show'
|
||||
assert_select_in result, 'a.collapsible', :text => 'Hide'
|
||||
end
|
||||
end
|
||||
|
||||
def test_macro_collapse_with_one_arg
|
||||
text = "{{collapse(Example)\n*Collapsed* block of text\n}}"
|
||||
result = textilizable(text)
|
||||
|
||||
assert_select_in result, 'div.collapsed-text'
|
||||
assert_select_in result, 'strong', :text => 'Collapsed'
|
||||
assert_select_in result, 'a.collapsible.collapsed', :text => 'Example'
|
||||
assert_select_in result, 'a.collapsible', :text => 'Example'
|
||||
end
|
||||
|
||||
def test_macro_collapse_with_two_args
|
||||
text = "{{collapse(Show example, Hide example)\n*Collapsed* block of text\n}}"
|
||||
result = textilizable(text)
|
||||
|
||||
assert_select_in result, 'div.collapsed-text'
|
||||
assert_select_in result, 'strong', :text => 'Collapsed'
|
||||
assert_select_in result, 'a.collapsible.collapsed', :text => 'Show example'
|
||||
assert_select_in result, 'a.collapsible', :text => 'Hide example'
|
||||
end
|
||||
|
||||
def test_macro_collapse_should_not_break_toc
|
||||
set_language_if_valid 'en'
|
||||
|
||||
text = <<-RAW
|
||||
{{toc}}
|
||||
|
||||
h1. Title
|
||||
|
||||
{{collapse(Show example, Hide example)
|
||||
h2. Heading
|
||||
}}"
|
||||
RAW
|
||||
|
||||
expected_toc = '<ul class="toc"><li><strong>Table of contents</strong></li><li><a href="#Title">Title</a><ul><li><a href="#Heading">Heading</a></li></ul></li></ul>'
|
||||
|
||||
assert_include expected_toc, textilizable(text).gsub(/[\r\n]/, '')
|
||||
end
|
||||
|
||||
def test_macro_child_pages
|
||||
expected = "<p><ul class=\"pages-hierarchy\">\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
|
||||
"<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
|
||||
"</ul>\n</p>"
|
||||
|
||||
@project = Project.find(1)
|
||||
# child pages of the current wiki page
|
||||
assert_equal expected, textilizable("{{child_pages}}", :object => WikiPage.find(2).content)
|
||||
# child pages of another page
|
||||
assert_equal expected, textilizable("{{child_pages(Another_page)}}", :object => WikiPage.find(1).content)
|
||||
|
||||
@project = Project.find(2)
|
||||
assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page)}}", :object => WikiPage.find(1).content)
|
||||
end
|
||||
|
||||
def test_macro_child_pages_with_parent_option
|
||||
expected = "<p><ul class=\"pages-hierarchy\">\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Another_page\">Another page</a>\n" +
|
||||
"<ul class=\"pages-hierarchy\">\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
|
||||
"<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
|
||||
"</ul>\n</li>\n</ul>\n</p>"
|
||||
|
||||
@project = Project.find(1)
|
||||
# child pages of the current wiki page
|
||||
assert_equal expected, textilizable("{{child_pages(parent=1)}}", :object => WikiPage.find(2).content)
|
||||
# child pages of another page
|
||||
assert_equal expected, textilizable("{{child_pages(Another_page, parent=1)}}", :object => WikiPage.find(1).content)
|
||||
|
||||
@project = Project.find(2)
|
||||
assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page, parent=1)}}", :object => WikiPage.find(1).content)
|
||||
end
|
||||
|
||||
def test_macro_child_pages_with_depth_option
|
||||
expected = "<p><ul class=\"pages-hierarchy\">\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
|
||||
"</ul>\n</p>"
|
||||
|
||||
@project = Project.find(1)
|
||||
assert_equal expected, textilizable("{{child_pages(depth=1)}}", :object => WikiPage.find(2).content)
|
||||
end
|
||||
|
||||
def test_macro_child_pages_without_wiki_page_should_fail
|
||||
assert_match /can be called from wiki pages only/, textilizable("{{child_pages}}")
|
||||
end
|
||||
|
||||
def test_macro_thumbnail
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
|
||||
"/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "testfile.PNG")
|
||||
assert_equal "<p>#{link}</p>",
|
||||
textilizable("{{thumbnail(testfile.png)}}", :object => Issue.find(14))
|
||||
end
|
||||
|
||||
def test_macro_thumbnail_with_full_path
|
||||
link = link_to('<img alt="testfile.PNG" src="http://test.host/attachments/thumbnail/17" />'.html_safe,
|
||||
"http://test.host/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "testfile.PNG")
|
||||
assert_equal "<p>#{link}</p>",
|
||||
textilizable("{{thumbnail(testfile.png)}}", :object => Issue.find(14), :only_path => false)
|
||||
end
|
||||
|
||||
def test_macro_thumbnail_with_size
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17/200" />'.html_safe,
|
||||
"/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "testfile.PNG")
|
||||
assert_equal "<p>#{link}</p>",
|
||||
textilizable("{{thumbnail(testfile.png, size=200)}}", :object => Issue.find(14))
|
||||
end
|
||||
|
||||
def test_macro_thumbnail_with_title
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
|
||||
"/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "Cool image")
|
||||
assert_equal "<p>#{link}</p>",
|
||||
textilizable("{{thumbnail(testfile.png, title=Cool image)}}", :object => Issue.find(14))
|
||||
end
|
||||
|
||||
def test_macro_thumbnail_with_invalid_filename_should_fail
|
||||
assert_include 'test.png not found',
|
||||
textilizable("{{thumbnail(test.png)}}", :object => Issue.find(14))
|
||||
end
|
||||
|
||||
def test_macros_should_not_be_executed_in_pre_tags
|
||||
text = <<-RAW
|
||||
{{hello_world(foo)}}
|
||||
|
||||
<pre>
|
||||
{{hello_world(pre)}}
|
||||
!{{hello_world(pre)}}
|
||||
</pre>
|
||||
|
||||
{{hello_world(bar)}}
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>Hello world! Object: NilClass, Arguments: foo and no block of text.</p>
|
||||
|
||||
<pre>
|
||||
{{hello_world(pre)}}
|
||||
!{{hello_world(pre)}}
|
||||
</pre>
|
||||
|
||||
<p>Hello world! Object: NilClass, Arguments: bar and no block of text.</p>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
|
||||
def test_macros_should_be_escaped_in_pre_tags
|
||||
text = "<pre>{{hello_world(<tag>)}}</pre>"
|
||||
assert_equal "<pre>{{hello_world(<tag>)}}</pre>", textilizable(text)
|
||||
end
|
||||
|
||||
def test_macros_should_not_mangle_next_macros_outputs
|
||||
text = '{{macro(2)}} !{{macro(2)}} {{hello_world(foo)}}'
|
||||
assert_equal '<p>{{macro(2)}} {{macro(2)}} Hello world! Object: NilClass, Arguments: foo and no block of text.</p>', textilizable(text)
|
||||
end
|
||||
|
||||
def test_macros_with_text_should_not_mangle_following_macros
|
||||
text = <<-RAW
|
||||
{{hello_world
|
||||
Line of text
|
||||
}}
|
||||
|
||||
{{hello_world
|
||||
Another line of text
|
||||
}}
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>Hello world! Object: NilClass, Called with no argument and a 12 bytes long block of text.</p>
|
||||
<p>Hello world! Object: NilClass, Called with no argument and a 20 bytes long block of text.</p>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,93 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::WikiFormatting::MarkdownFormatterTest < ActionView::TestCase
|
||||
if Object.const_defined?(:Redcarpet)
|
||||
|
||||
def setup
|
||||
@formatter = Redmine::WikiFormatting::Markdown::Formatter
|
||||
end
|
||||
|
||||
def test_syntax_error_in_image_reference_should_not_raise_exception
|
||||
assert @formatter.new("!>[](foo.png)").to_html
|
||||
end
|
||||
|
||||
def test_empty_image_should_not_raise_exception
|
||||
assert @formatter.new("![]()").to_html
|
||||
end
|
||||
|
||||
# re-using the formatter after getting above error crashes the
|
||||
# ruby interpreter. This seems to be related to
|
||||
# https://github.com/vmg/redcarpet/issues/318
|
||||
def test_should_not_crash_redcarpet_after_syntax_error
|
||||
@formatter.new("!>[](foo.png)").to_html rescue nil
|
||||
assert @formatter.new("").to_html.present?
|
||||
end
|
||||
|
||||
def test_inline_style
|
||||
assert_equal "<p><strong>foo</strong></p>", @formatter.new("**foo**").to_html.strip
|
||||
end
|
||||
|
||||
def test_not_set_intra_emphasis
|
||||
assert_equal "<p>foo_bar_baz</p>", @formatter.new("foo_bar_baz").to_html.strip
|
||||
end
|
||||
|
||||
def test_wiki_links_should_be_preserved
|
||||
text = 'This is a wiki link: [[Foo]]'
|
||||
assert_include '[[Foo]]', @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def test_redmine_links_with_double_quotes_should_be_preserved
|
||||
text = 'This is a redmine link: version:"1.0"'
|
||||
assert_include 'version:"1.0"', @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def test_should_support_syntax_highligth
|
||||
text = <<-STR
|
||||
~~~ruby
|
||||
def foo
|
||||
end
|
||||
~~~
|
||||
STR
|
||||
assert_select_in @formatter.new(text).to_html, 'pre code.ruby.syntaxhl' do
|
||||
assert_select 'span.keyword', :text => 'def'
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_allow_invalid_language_for_code_blocks
|
||||
text = <<-STR
|
||||
~~~foo
|
||||
test
|
||||
~~~
|
||||
STR
|
||||
assert_equal "<pre>test\n</pre>", @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def test_external_links_should_have_external_css_class
|
||||
text = 'This is a [link](http://example.net/)'
|
||||
assert_equal '<p>This is a <a href="http://example.net/" class="external">link</a></p>', @formatter.new(text).to_html.strip
|
||||
end
|
||||
|
||||
def test_locals_links_should_not_have_external_css_class
|
||||
text = 'This is a [link](/issues)'
|
||||
assert_equal '<p>This is a <a href="/issues">link</a></p>', @formatter.new(text).to_html.strip
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::WikiFormatting::MarkdownHtmlParserTest < ActiveSupport::TestCase
|
||||
|
||||
def setup
|
||||
@parser = Redmine::WikiFormatting::Markdown::HtmlParser
|
||||
end
|
||||
|
||||
def test_should_convert_tags
|
||||
assert_equal 'A **simple** html snippet.',
|
||||
@parser.to_text('<p>A <b>simple</b> html snippet.</p>')
|
||||
end
|
||||
end
|
600
test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb
Normal file
600
test/unit/lib/redmine/wiki_formatting/textile_formatter_test.rb
Normal file
|
@ -0,0 +1,600 @@
|
|||
#encoding: utf-8
|
||||
#
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
require 'digest/md5'
|
||||
|
||||
class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase
|
||||
|
||||
def setup
|
||||
@formatter = Redmine::WikiFormatting::Textile::Formatter
|
||||
end
|
||||
|
||||
MODIFIERS = {
|
||||
"*" => 'strong', # bold
|
||||
"_" => 'em', # italic
|
||||
"+" => 'ins', # underline
|
||||
"-" => 'del', # deleted
|
||||
"^" => 'sup', # superscript
|
||||
"~" => 'sub' # subscript
|
||||
}
|
||||
|
||||
def test_modifiers
|
||||
assert_html_output(
|
||||
'*bold*' => '<strong>bold</strong>',
|
||||
'before *bold*' => 'before <strong>bold</strong>',
|
||||
'*bold* after' => '<strong>bold</strong> after',
|
||||
'*two words*' => '<strong>two words</strong>',
|
||||
'*two*words*' => '<strong>two*words</strong>',
|
||||
'*two * words*' => '<strong>two * words</strong>',
|
||||
'*two* *words*' => '<strong>two</strong> <strong>words</strong>',
|
||||
'*(two)* *(words)*' => '<strong>(two)</strong> <strong>(words)</strong>'
|
||||
)
|
||||
end
|
||||
|
||||
def test_modifiers_combination
|
||||
MODIFIERS.each do |m1, tag1|
|
||||
MODIFIERS.each do |m2, tag2|
|
||||
next if m1 == m2
|
||||
text = "#{m2}#{m1}Phrase modifiers#{m1}#{m2}"
|
||||
html = "<#{tag2}><#{tag1}>Phrase modifiers</#{tag1}></#{tag2}>"
|
||||
assert_html_output text => html
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_modifier_should_work_with_one_non_ascii_character
|
||||
assert_html_output "*Ä*" => "<strong>Ä</strong>"
|
||||
end
|
||||
|
||||
def test_styles
|
||||
# single style
|
||||
assert_html_output({
|
||||
'p{color:red}. text' => '<p style="color:red;">text</p>',
|
||||
'p{color:red;}. text' => '<p style="color:red;">text</p>',
|
||||
'p{color: red}. text' => '<p style="color: red;">text</p>',
|
||||
'p{color:#f00}. text' => '<p style="color:#f00;">text</p>',
|
||||
'p{color:#ff0000}. text' => '<p style="color:#ff0000;">text</p>',
|
||||
'p{border:10px}. text' => '<p style="border:10px;">text</p>',
|
||||
'p{border:10}. text' => '<p style="border:10;">text</p>',
|
||||
'p{border:10%}. text' => '<p style="border:10%;">text</p>',
|
||||
'p{border:10em}. text' => '<p style="border:10em;">text</p>',
|
||||
'p{border:1.5em}. text' => '<p style="border:1.5em;">text</p>',
|
||||
'p{border-left:1px}. text' => '<p style="border-left:1px;">text</p>',
|
||||
'p{border-right:1px}. text' => '<p style="border-right:1px;">text</p>',
|
||||
'p{border-top:1px}. text' => '<p style="border-top:1px;">text</p>',
|
||||
'p{border-bottom:1px}. text' => '<p style="border-bottom:1px;">text</p>',
|
||||
}, false)
|
||||
|
||||
# multiple styles
|
||||
assert_html_output({
|
||||
'p{color:red; border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>',
|
||||
'p{color:red ; border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>',
|
||||
'p{color:red;border-top:1px}. text' => '<p style="color:red;border-top:1px;">text</p>',
|
||||
}, false)
|
||||
|
||||
# styles with multiple values
|
||||
assert_html_output({
|
||||
'p{border:1px solid red;}. text' => '<p style="border:1px solid red;">text</p>',
|
||||
'p{border-top-left-radius: 10px 5px;}. text' => '<p style="border-top-left-radius: 10px 5px;">text</p>',
|
||||
}, false)
|
||||
end
|
||||
|
||||
def test_invalid_styles_should_be_filtered
|
||||
assert_html_output({
|
||||
'p{invalid}. text' => '<p>text</p>',
|
||||
'p{invalid:red}. text' => '<p>text</p>',
|
||||
'p{color:(red)}. text' => '<p>text</p>',
|
||||
'p{color:red;invalid:blue}. text' => '<p style="color:red;">text</p>',
|
||||
'p{invalid:blue;color:red}. text' => '<p style="color:red;">text</p>',
|
||||
'p{color:"}. text' => '<p>p{color:"}. text</p>',
|
||||
}, false)
|
||||
end
|
||||
|
||||
def test_inline_code
|
||||
assert_html_output(
|
||||
'this is @some code@' => 'this is <code>some code</code>',
|
||||
'@<Location /redmine>@' => '<code><Location /redmine></code>'
|
||||
)
|
||||
end
|
||||
|
||||
def test_lang_attribute
|
||||
assert_html_output(
|
||||
'*[fr]French*' => '<strong lang="fr">French</strong>',
|
||||
'*[fr-fr]French*' => '<strong lang="fr-fr">French</strong>',
|
||||
'*[fr_fr]French*' => '<strong lang="fr_fr">French</strong>'
|
||||
)
|
||||
end
|
||||
|
||||
def test_lang_attribute_should_ignore_invalid_value
|
||||
assert_html_output(
|
||||
'*[fr3]French*' => '<strong>[fr3]French</strong>'
|
||||
)
|
||||
end
|
||||
|
||||
def test_nested_lists
|
||||
raw = <<-RAW
|
||||
# Item 1
|
||||
# Item 2
|
||||
** Item 2a
|
||||
** Item 2b
|
||||
# Item 3
|
||||
** Item 3a
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<ol>
|
||||
<li>Item 1</li>
|
||||
<li>Item 2
|
||||
<ul>
|
||||
<li>Item 2a</li>
|
||||
<li>Item 2b</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Item 3
|
||||
<ul>
|
||||
<li>Item 3a</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_escaping
|
||||
assert_html_output(
|
||||
'this is a <script>' => 'this is a <script>'
|
||||
)
|
||||
end
|
||||
|
||||
def test_kbd
|
||||
assert_html_output({
|
||||
'<kbd>test</kbd>' => '<kbd>test</kbd>'
|
||||
}, false)
|
||||
end
|
||||
|
||||
def test_use_of_backslashes_followed_by_numbers_in_headers
|
||||
assert_html_output({
|
||||
'h1. 2009\02\09' => '<h1>2009\02\09</h1>'
|
||||
}, false)
|
||||
end
|
||||
|
||||
def test_double_dashes_should_not_strikethrough
|
||||
assert_html_output(
|
||||
'double -- dashes -- test' => 'double -- dashes -- test',
|
||||
'double -- *dashes* -- test' => 'double -- <strong>dashes</strong> -- test'
|
||||
)
|
||||
end
|
||||
|
||||
def test_abbreviations
|
||||
assert_html_output(
|
||||
'this is an abbreviation: GPL(General Public License)' => 'this is an abbreviation: <abbr title="General Public License">GPL</abbr>',
|
||||
'2 letters JP(Jean-Philippe) abbreviation' => '2 letters <abbr title="Jean-Philippe">JP</abbr> abbreviation',
|
||||
'GPL(This is a double-quoted "title")' => '<abbr title="This is a double-quoted "title"">GPL</abbr>'
|
||||
)
|
||||
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.<br />
|
||||
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+}, ''), to_html(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+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_table_with_alignment
|
||||
raw = <<-RAW
|
||||
|>. right|
|
||||
|<. left|
|
||||
|<>. justify|
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<table>
|
||||
<tr><td style="text-align:right;">right</td></tr>
|
||||
<tr><td style="text-align:left;">left</td></tr>
|
||||
<tr><td style="text-align:justify;">justify</td></tr>
|
||||
</table>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_table_with_trailing_whitespace
|
||||
raw = <<-RAW
|
||||
This is a table with trailing whitespace in one row:
|
||||
|
||||
|cell11|cell12|
|
||||
|cell21|cell22|
|
||||
|cell31|cell32|
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>This is a table with trailing whitespace in one row:</p>
|
||||
|
||||
<table>
|
||||
<tr><td>cell11</td><td>cell12</td></tr>
|
||||
<tr><td>cell21</td><td>cell22</td></tr>
|
||||
<tr><td>cell31</td><td>cell32</td></tr>
|
||||
</table>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_table_with_line_breaks
|
||||
raw = <<-RAW
|
||||
This is a table with line breaks:
|
||||
|
||||
|cell11
|
||||
continued|cell12||
|
||||
|-cell21-||cell23
|
||||
cell23 line2
|
||||
cell23 *line3*|
|
||||
|cell31|cell32
|
||||
cell32 line2|cell33|
|
||||
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>This is a table with line breaks:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>cell11<br />continued</td>
|
||||
<td>cell12</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><del>cell21</del></td>
|
||||
<td></td>
|
||||
<td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell31</td>
|
||||
<td>cell32<br/>cell32 line2</td>
|
||||
<td>cell33</td>
|
||||
</tr>
|
||||
</table>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_tables_with_lists
|
||||
raw = <<-RAW
|
||||
This is a table with lists:
|
||||
|
||||
|cell11|cell12|
|
||||
|cell21|ordered list
|
||||
# item
|
||||
# item 2|
|
||||
|cell31|unordered list
|
||||
* item
|
||||
* item 2|
|
||||
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>This is a table with lists:</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>cell11</td>
|
||||
<td>cell12</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell21</td>
|
||||
<td>ordered list<br /># item<br /># item 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>cell31</td>
|
||||
<td>unordered list<br />* item<br />* item 2</td>
|
||||
</tr>
|
||||
</table>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_textile_should_not_mangle_brackets
|
||||
assert_equal '<p>[msg1][msg2]</p>', to_html('[msg1][msg2]')
|
||||
end
|
||||
|
||||
def test_textile_should_escape_image_urls
|
||||
# this is onclick="alert('XSS');" in encoded form
|
||||
raw = '!/images/comment.png"onclick=alert('XSS');"!'
|
||||
expected = '<p><img src="/images/comment.png"onclick=&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;;&#x22;" alt="" /></p>'
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
|
||||
STR_WITHOUT_PRE = [
|
||||
# 0
|
||||
"h1. Title
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
|
||||
# 1
|
||||
"h2. Heading 2
|
||||
|
||||
Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
|
||||
|
||||
Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.",
|
||||
# 2
|
||||
"h2. Heading 2
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
|
||||
h3. Heading 3
|
||||
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.",
|
||||
# 3
|
||||
"h3. Heading 3
|
||||
|
||||
Praesent eget turpis nibh, a lacinia nulla.",
|
||||
# 4
|
||||
"h2. Heading 2
|
||||
|
||||
Ut rhoncus elementum adipiscing."]
|
||||
|
||||
TEXT_WITHOUT_PRE = STR_WITHOUT_PRE.join("\n\n").freeze
|
||||
|
||||
def test_get_section_should_return_the_requested_section_and_its_hash
|
||||
assert_section_with_hash STR_WITHOUT_PRE[1], TEXT_WITHOUT_PRE, 2
|
||||
assert_section_with_hash STR_WITHOUT_PRE[2..3].join("\n\n"), TEXT_WITHOUT_PRE, 3
|
||||
assert_section_with_hash STR_WITHOUT_PRE[3], TEXT_WITHOUT_PRE, 5
|
||||
assert_section_with_hash STR_WITHOUT_PRE[4], TEXT_WITHOUT_PRE, 6
|
||||
|
||||
assert_section_with_hash '', TEXT_WITHOUT_PRE, 0
|
||||
assert_section_with_hash '', TEXT_WITHOUT_PRE, 10
|
||||
end
|
||||
|
||||
def test_update_section_should_update_the_requested_section
|
||||
replacement = "New text"
|
||||
|
||||
assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement)
|
||||
assert_equal [STR_WITHOUT_PRE[0..1], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(3, replacement)
|
||||
assert_equal [STR_WITHOUT_PRE[0..2], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(5, replacement)
|
||||
assert_equal [STR_WITHOUT_PRE[0..3], replacement].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(6, replacement)
|
||||
|
||||
assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(0, replacement)
|
||||
assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(10, replacement)
|
||||
end
|
||||
|
||||
def test_update_section_with_hash_should_update_the_requested_section
|
||||
replacement = "New text"
|
||||
|
||||
assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"),
|
||||
@formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement, Digest::MD5.hexdigest(STR_WITHOUT_PRE[1]))
|
||||
end
|
||||
|
||||
def test_update_section_with_wrong_hash_should_raise_an_error
|
||||
assert_raise Redmine::WikiFormatting::StaleSectionError do
|
||||
@formatter.new(TEXT_WITHOUT_PRE).update_section(2, "New text", Digest::MD5.hexdigest("Old text"))
|
||||
end
|
||||
end
|
||||
|
||||
STR_WITH_PRE = [
|
||||
# 0
|
||||
"h1. Title
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
|
||||
# 1
|
||||
"h2. Heading 2
|
||||
|
||||
<pre><code class=\"ruby\">
|
||||
def foo
|
||||
end
|
||||
</code></pre>
|
||||
|
||||
<pre><code><pre><code class=\"ruby\">
|
||||
Place your code here.
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
|
||||
<pre>
|
||||
Pre Content:
|
||||
|
||||
h2. Inside pre
|
||||
|
||||
<tag> inside pre block
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
</pre>",
|
||||
# 2
|
||||
"h3. Heading 3
|
||||
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
|
||||
|
||||
def test_get_section_should_ignore_pre_content
|
||||
text = STR_WITH_PRE.join("\n\n")
|
||||
|
||||
assert_section_with_hash STR_WITH_PRE[1..2].join("\n\n"), text, 2
|
||||
assert_section_with_hash STR_WITH_PRE[2], text, 3
|
||||
end
|
||||
|
||||
def test_update_section_should_not_escape_pre_content_outside_section
|
||||
text = STR_WITH_PRE.join("\n\n")
|
||||
replacement = "New text"
|
||||
|
||||
assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"),
|
||||
@formatter.new(text).update_section(3, replacement)
|
||||
end
|
||||
|
||||
def test_get_section_should_support_lines_with_spaces_before_heading
|
||||
# the lines after Content 2 and Heading 4 contain a space
|
||||
text = <<-STR
|
||||
h1. Heading 1
|
||||
|
||||
Content 1
|
||||
|
||||
h1. Heading 2
|
||||
|
||||
Content 2
|
||||
|
||||
h1. Heading 3
|
||||
|
||||
Content 3
|
||||
|
||||
h1. Heading 4
|
||||
|
||||
Content 4
|
||||
STR
|
||||
|
||||
[1, 2, 3, 4].each do |index|
|
||||
assert_match /\Ah1. Heading #{index}.+Content #{index}/m, @formatter.new(text).get_section(index).first
|
||||
end
|
||||
end
|
||||
|
||||
def test_get_section_should_support_headings_starting_with_a_tab
|
||||
text = <<-STR
|
||||
h1.\tHeading 1
|
||||
|
||||
Content 1
|
||||
|
||||
h1. Heading 2
|
||||
|
||||
Content 2
|
||||
STR
|
||||
|
||||
assert_match /\Ah1.\tHeading 1\s+Content 1\z/, @formatter.new(text).get_section(1).first
|
||||
end
|
||||
|
||||
def test_should_not_allow_arbitrary_class_attribute_on_offtags
|
||||
%w(code pre kbd).each do |tag|
|
||||
assert_html_output({"<#{tag} class=\"foo\">test</#{tag}>" => "<#{tag}>test</#{tag}>"}, false)
|
||||
end
|
||||
|
||||
assert_html_output({"<notextile class=\"foo\">test</notextile>" => "test"}, false)
|
||||
end
|
||||
|
||||
def test_should_allow_valid_language_class_attribute_on_code_tags
|
||||
assert_html_output({"<code class=\"ruby\">test</code>" => "<code class=\"ruby syntaxhl\"><span class=\"CodeRay\">test</span></code>"}, false)
|
||||
end
|
||||
|
||||
def test_should_not_allow_valid_language_class_attribute_on_non_code_offtags
|
||||
%w(pre kbd).each do |tag|
|
||||
assert_html_output({"<#{tag} class=\"ruby\">test</#{tag}>" => "<#{tag}>test</#{tag}>"}, false)
|
||||
end
|
||||
|
||||
assert_html_output({"<notextile class=\"ruby\">test</notextile>" => "test"}, false)
|
||||
end
|
||||
|
||||
def test_should_prefix_class_attribute_on_tags
|
||||
assert_html_output({
|
||||
'!(foo)test.png!' => "<p><img src=\"test.png\" class=\"wiki-class-foo\" alt=\"\" /></p>",
|
||||
'%(foo)test%' => "<p><span class=\"wiki-class-foo\">test</span></p>",
|
||||
'p(foo). test' => "<p class=\"wiki-class-foo\">test</p>",
|
||||
'|(foo). test|' => "<table>\n\t\t<tr>\n\t\t\t<td class=\"wiki-class-foo\">test</td>\n\t\t</tr>\n\t</table>",
|
||||
}, false)
|
||||
end
|
||||
|
||||
def test_should_prefix_id_attribute_on_tags
|
||||
assert_html_output({
|
||||
'!(#foo)test.png!' => "<p><img src=\"test.png\" id=\"wiki-id-foo\" alt=\"\" /></p>",
|
||||
'%(#foo)test%' => "<p><span id=\"wiki-id-foo\">test</span></p>",
|
||||
'p(#foo). test' => "<p id=\"wiki-id-foo\">test</p>",
|
||||
'|(#foo). test|' => "<table>\n\t\t<tr>\n\t\t\t<td id=\"wiki-id-foo\">test</td>\n\t\t</tr>\n\t</table>",
|
||||
}, false)
|
||||
end
|
||||
|
||||
def test_should_not_prefix_class_and_id_attributes_already_prefixed
|
||||
assert_html_output({
|
||||
'!(wiki-class-foo#wiki-id-bar)test.png!' => "<p><img src=\"test.png\" class=\"wiki-class-foo\" id=\"wiki-id-bar\" alt=\"\" /></p>",
|
||||
}, false)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_html_output(to_test, expect_paragraph = true)
|
||||
to_test.each do |text, expected|
|
||||
assert_equal(( expect_paragraph ? "<p>#{expected}</p>" : expected ), @formatter.new(text).to_html, "Formatting the following text failed:\n===\n#{text}\n===\n")
|
||||
end
|
||||
end
|
||||
|
||||
def to_html(text)
|
||||
@formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def assert_section_with_hash(expected, text, index)
|
||||
result = @formatter.new(text).get_section(index)
|
||||
|
||||
assert_kind_of Array, result
|
||||
assert_equal 2, result.size
|
||||
assert_equal expected, result.first, "section content did not match"
|
||||
assert_equal Digest::MD5.hexdigest(expected), result.last, "section hash did not match"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::WikiFormatting::TextileHtmlParserTest < ActiveSupport::TestCase
|
||||
|
||||
def setup
|
||||
@parser = Redmine::WikiFormatting::Textile::HtmlParser
|
||||
end
|
||||
|
||||
def test_should_convert_tags
|
||||
assert_equal 'A *simple* html snippet.',
|
||||
@parser.to_text('<p>A <b>simple</b> html snippet.</p>')
|
||||
end
|
||||
end
|
83
test/unit/lib/redmine/wiki_formatting_test.rb
Normal file
83
test/unit/lib/redmine/wiki_formatting_test.rb
Normal file
|
@ -0,0 +1,83 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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.expand_path('../../../../test_helper', __FILE__)
|
||||
|
||||
class Redmine::WikiFormattingTest < ActiveSupport::TestCase
|
||||
fixtures :issues
|
||||
|
||||
def test_textile_formatter
|
||||
assert_equal Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting.formatter_for('textile')
|
||||
assert_equal Redmine::WikiFormatting::Textile::Helper, Redmine::WikiFormatting.helper_for('textile')
|
||||
end
|
||||
|
||||
def test_null_formatter
|
||||
assert_equal Redmine::WikiFormatting::NullFormatter::Formatter, Redmine::WikiFormatting.formatter_for('')
|
||||
assert_equal Redmine::WikiFormatting::NullFormatter::Helper, Redmine::WikiFormatting.helper_for('')
|
||||
end
|
||||
|
||||
def test_formats_for_select
|
||||
assert_include ['Textile', 'textile'], Redmine::WikiFormatting.formats_for_select
|
||||
end
|
||||
|
||||
def test_should_link_urls_and_email_addresses
|
||||
raw = <<-DIFF
|
||||
This is a sample *text* with a link: http://www.redmine.org
|
||||
and an email address foo@example.net
|
||||
DIFF
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>This is a sample *text* with a link: <a class="external" href="http://www.redmine.org">http://www.redmine.org</a><br />
|
||||
and an email address <a class="email" href="mailto:foo@example.net">foo@example.net</a></p>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), Redmine::WikiFormatting::NullFormatter::Formatter.new(raw).to_html.gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
|
||||
def test_should_link_email_with_slashes
|
||||
raw = 'foo/bar@example.net'
|
||||
expected = '<p><a class="email" href="mailto:foo/bar@example.net">foo/bar@example.net</a></p>'
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), Redmine::WikiFormatting::NullFormatter::Formatter.new(raw).to_html.gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
|
||||
def test_links_separated_with_line_break_should_link
|
||||
raw = <<-DIFF
|
||||
link: https://www.redmine.org
|
||||
http://www.redmine.org
|
||||
DIFF
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>link: <a class="external" href="https://www.redmine.org">https://www.redmine.org</a><br />
|
||||
<a class="external" href="http://www.redmine.org">http://www.redmine.org</a></p>
|
||||
EXPECTED
|
||||
|
||||
end
|
||||
|
||||
def test_supports_section_edit
|
||||
with_settings :text_formatting => 'textile' do
|
||||
assert_equal true, Redmine::WikiFormatting.supports_section_edit?
|
||||
end
|
||||
|
||||
with_settings :text_formatting => '' do
|
||||
assert_equal false, Redmine::WikiFormatting.supports_section_edit?
|
||||
end
|
||||
end
|
||||
|
||||
def test_cache_key_for_saved_object_should_no_be_nil
|
||||
assert_not_nil Redmine::WikiFormatting.cache_key_for('textile', 'Text', Issue.find(1), :description)
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue