Redmine 3.4.4
This commit is contained in:
commit
64924a6376
2112 changed files with 259028 additions and 0 deletions
|
@ -0,0 +1,194 @@
|
|||
# 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 AttachmentFieldFormatTest < Redmine::IntegrationTest
|
||||
fixtures :projects,
|
||||
:users, :email_addresses,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:enabled_modules,
|
||||
:issue_statuses,
|
||||
:issues,
|
||||
:enumerations,
|
||||
:custom_fields,
|
||||
:custom_values,
|
||||
:custom_fields_trackers,
|
||||
:attachments
|
||||
|
||||
def setup
|
||||
set_tmp_attachments_directory
|
||||
@field = IssueCustomField.generate!(:name => "File", :field_format => "attachment")
|
||||
log_user "jsmith", "jsmith"
|
||||
end
|
||||
|
||||
def test_new_should_include_inputs
|
||||
get '/projects/ecookbook/issues/new'
|
||||
assert_response :success
|
||||
|
||||
assert_select '[name^=?]', "issue[custom_field_values][#{@field.id}]", 2
|
||||
assert_select 'input[name=?][type=hidden][value=""]', "issue[custom_field_values][#{@field.id}][blank]"
|
||||
end
|
||||
|
||||
def test_create_with_attachment
|
||||
issue = new_record(Issue) do
|
||||
assert_difference 'Attachment.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Subject",
|
||||
:custom_field_values => {
|
||||
@field.id => {
|
||||
'blank' => '',
|
||||
'1' => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
|
||||
custom_value = issue.custom_value_for(@field)
|
||||
assert custom_value
|
||||
assert custom_value.value.present?
|
||||
|
||||
attachment = Attachment.find_by_id(custom_value.value)
|
||||
assert attachment
|
||||
assert_equal custom_value, attachment.container
|
||||
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
|
||||
# link to the attachment
|
||||
link = css_select(".cf_#{@field.id} .value a")
|
||||
assert_equal 1, link.size
|
||||
assert_equal "testfile.txt", link.text
|
||||
|
||||
# preview the attachment
|
||||
get link.attr('href')
|
||||
assert_response :success
|
||||
assert_template :file
|
||||
end
|
||||
|
||||
def test_create_without_attachment
|
||||
issue = new_record(Issue) do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Subject",
|
||||
:custom_field_values => {
|
||||
@field.id => {:blank => ''}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
|
||||
custom_value = issue.custom_value_for(@field)
|
||||
assert custom_value
|
||||
assert custom_value.value.blank?
|
||||
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
|
||||
# no links to the attachment
|
||||
assert_select ".cf_#{@field.id} .value a", 0
|
||||
end
|
||||
|
||||
def test_failure_on_create_should_preserve_attachment
|
||||
attachment = new_record(Attachment) do
|
||||
assert_no_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "",
|
||||
:custom_field_values => {
|
||||
@field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response :success
|
||||
assert_select_error /Subject cannot be blank/
|
||||
end
|
||||
end
|
||||
|
||||
assert_nil attachment.container_id
|
||||
assert_select 'input[name=?][value=?][type=hidden]', "issue[custom_field_values][#{@field.id}][p0][token]", attachment.token
|
||||
assert_select 'input[name=?][value=?]', "issue[custom_field_values][#{@field.id}][p0][filename]", 'testfile.txt'
|
||||
|
||||
issue = new_record(Issue) do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Subject",
|
||||
:custom_field_values => {
|
||||
@field.id => {:token => attachment.token}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
|
||||
custom_value = issue.custom_value_for(@field)
|
||||
assert custom_value
|
||||
assert_equal attachment.id.to_s, custom_value.value
|
||||
assert_equal custom_value, attachment.reload.container
|
||||
end
|
||||
|
||||
def test_create_with_valid_extension
|
||||
@field.extensions_allowed = "txt, log"
|
||||
@field.save!
|
||||
|
||||
attachment = new_record(Attachment) do
|
||||
assert_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Blank",
|
||||
:custom_field_values => {
|
||||
@field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_create_with_invalid_extension_should_fail
|
||||
@field.extensions_allowed = "png, jpeg"
|
||||
@field.save!
|
||||
|
||||
attachment = new_record(Attachment) do
|
||||
assert_no_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Blank",
|
||||
:custom_field_values => {
|
||||
@field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
124
test/integration/lib/redmine/hook_test.rb
Normal file
124
test/integration/lib/redmine/hook_test.rb
Normal file
|
@ -0,0 +1,124 @@
|
|||
# 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 HookTest < Redmine::IntegrationTest
|
||||
fixtures :users, :roles, :projects, :members, :member_roles
|
||||
|
||||
# Hooks that are manually registered later
|
||||
class ProjectBasedTemplate < Redmine::Hook::ViewListener
|
||||
def view_layouts_base_html_head(context)
|
||||
# Adds a project stylesheet
|
||||
stylesheet_link_tag(context[:project].identifier) if context[:project]
|
||||
end
|
||||
end
|
||||
|
||||
class SidebarContent < Redmine::Hook::ViewListener
|
||||
def view_layouts_base_sidebar(context)
|
||||
content_tag('p', 'Sidebar hook')
|
||||
end
|
||||
end
|
||||
|
||||
Redmine::Hook.clear_listeners
|
||||
|
||||
class ContentForInsideHook < Redmine::Hook::ViewListener
|
||||
render_on :view_welcome_index_left, :inline => <<-VIEW
|
||||
<% content_for :header_tags do %>
|
||||
<%= javascript_include_tag 'test_plugin.js', :plugin => 'test_plugin' %>
|
||||
<%= stylesheet_link_tag 'test_plugin.css', :plugin => 'test_plugin' %>
|
||||
<% end %>
|
||||
|
||||
<p>ContentForInsideHook content</p>
|
||||
VIEW
|
||||
end
|
||||
|
||||
class SingleRenderOn < Redmine::Hook::ViewListener
|
||||
render_on :view_welcome_index_left, :inline => 'SingleRenderOn 1'
|
||||
end
|
||||
|
||||
class MultipleRenderOn < Redmine::Hook::ViewListener
|
||||
render_on :view_welcome_index_left, {:inline => 'MultipleRenderOn 1'}, {:inline => 'MultipleRenderOn 2'}
|
||||
end
|
||||
|
||||
# Hooks that stores the call context
|
||||
class ContextTestHook < Redmine::Hook::ViewListener
|
||||
cattr_accessor :context
|
||||
|
||||
def controller_account_success_authentication_after(context)
|
||||
self.class.context = context
|
||||
end
|
||||
end
|
||||
|
||||
def setup
|
||||
Redmine::Hook.clear_listeners
|
||||
end
|
||||
|
||||
def teardown
|
||||
Redmine::Hook.clear_listeners
|
||||
end
|
||||
|
||||
def test_html_head_hook_response
|
||||
Redmine::Hook.add_listener(ProjectBasedTemplate)
|
||||
|
||||
get '/projects/ecookbook'
|
||||
assert_select 'head link[href=?]', '/stylesheets/ecookbook.css'
|
||||
end
|
||||
|
||||
def test_empty_sidebar_should_be_hidden
|
||||
get '/'
|
||||
assert_select 'div#main.nosidebar'
|
||||
end
|
||||
|
||||
def test_sidebar_with_hook_content_should_not_be_hidden
|
||||
Redmine::Hook.add_listener(SidebarContent)
|
||||
|
||||
get '/'
|
||||
assert_select 'div#sidebar p', :text => 'Sidebar hook'
|
||||
assert_select 'div#main'
|
||||
assert_select 'div#main.nosidebar', 0
|
||||
end
|
||||
|
||||
def test_hook_with_content_for_should_append_content
|
||||
Redmine::Hook.add_listener(ContentForInsideHook)
|
||||
|
||||
get '/'
|
||||
assert_response :success
|
||||
assert_select 'p', :text => 'ContentForInsideHook content'
|
||||
assert_select 'head' do
|
||||
assert_select 'script[src="/plugin_assets/test_plugin/javascripts/test_plugin.js"]'
|
||||
assert_select 'link[href="/plugin_assets/test_plugin/stylesheets/test_plugin.css"]'
|
||||
end
|
||||
end
|
||||
|
||||
def test_controller_hook_context_should_include_request
|
||||
Redmine::Hook.add_listener(ContextTestHook)
|
||||
post '/login', :params => {:username => 'admin', :password => 'admin'}
|
||||
assert_not_nil ContextTestHook.context
|
||||
context = ContextTestHook.context
|
||||
assert_kind_of ActionDispatch::Request, context[:request]
|
||||
assert_kind_of Hash, context[:request].params
|
||||
assert_kind_of AccountController, context[:hook_caller]
|
||||
end
|
||||
|
||||
def test_multiple_hooks
|
||||
Redmine::Hook.add_listener(SingleRenderOn)
|
||||
Redmine::Hook.add_listener(MultipleRenderOn)
|
||||
get '/'
|
||||
assert_equal 1, response.body.scan("SingleRenderOn 1 MultipleRenderOn 1 MultipleRenderOn 2").size
|
||||
end
|
||||
end
|
80
test/integration/lib/redmine/menu_manager_test.rb
Normal file
80
test/integration/lib/redmine/menu_manager_test.rb
Normal file
|
@ -0,0 +1,80 @@
|
|||
# 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 MenuManagerTest < Redmine::IntegrationTest
|
||||
include Redmine::I18n
|
||||
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules
|
||||
|
||||
def test_project_menu_with_specific_locale
|
||||
get '/projects/ecookbook/issues',
|
||||
:headers => {'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'}
|
||||
|
||||
assert_select 'div#main-menu' do
|
||||
assert_select 'li a.activity[href=?]', '/projects/ecookbook/activity', :text => ll('fr', :label_activity)
|
||||
assert_select 'li a.issues.selected[href=?]', '/projects/ecookbook/issues', :text => ll('fr', :label_issue_plural)
|
||||
end
|
||||
end
|
||||
|
||||
def test_project_menu_with_additional_menu_items
|
||||
Setting.default_language = 'en'
|
||||
assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
|
||||
Redmine::MenuManager.map :project_menu do |menu|
|
||||
menu.push :foo, { :controller => 'projects', :action => 'show' }, :caption => 'Foo'
|
||||
menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
|
||||
menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
|
||||
end
|
||||
|
||||
get '/projects/ecookbook'
|
||||
|
||||
assert_select 'div#main-menu ul' do
|
||||
assert_select 'li:last-child a.foo[href=?]', '/projects/ecookbook', :text => 'Foo'
|
||||
assert_select 'li:nth-child(2) a.bar[href=?]', '/projects/ecookbook', :text => 'Bar'
|
||||
assert_select 'li:nth-child(3) a.hello[href=?]', '/projects/ecookbook', :text => 'ECOOKBOOK'
|
||||
assert_select 'li:nth-child(4) a', :text => 'Activity'
|
||||
end
|
||||
|
||||
# Remove the menu items
|
||||
Redmine::MenuManager.map :project_menu do |menu|
|
||||
menu.delete :foo
|
||||
menu.delete :bar
|
||||
menu.delete :hello
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_main_menu_should_select_projects_tab_on_project_list
|
||||
get '/projects'
|
||||
assert_select '#main-menu' do
|
||||
assert_select 'a.projects'
|
||||
assert_select 'a.projects.selected'
|
||||
end
|
||||
end
|
||||
|
||||
def test_main_menu_should_not_show_up_on_account
|
||||
get '/login'
|
||||
assert_select '#main-menu', 0
|
||||
end
|
||||
end
|
102
test/integration/lib/redmine/themes_test.rb
Normal file
102
test/integration/lib/redmine/themes_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 ThemesTest < Redmine::IntegrationTest
|
||||
|
||||
def setup
|
||||
Redmine::Themes.rescan
|
||||
@theme = Redmine::Themes.themes.last
|
||||
Setting.ui_theme = @theme.id
|
||||
end
|
||||
|
||||
def teardown
|
||||
Setting.ui_theme = ''
|
||||
end
|
||||
|
||||
def test_application_css
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "link[rel=stylesheet][href^=?]", "/themes/#{@theme.dir}/stylesheets/application.css"
|
||||
end
|
||||
|
||||
def test_without_theme_js
|
||||
# simulate a state theme.js does not exists
|
||||
@theme.javascripts.clear
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "script[src^=?]", "/themes/#{@theme.dir}/javascripts/theme.js", 0
|
||||
end
|
||||
|
||||
def test_with_theme_js
|
||||
# Simulates a theme.js
|
||||
@theme.javascripts << 'theme'
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "script[src^=?]", "/themes/#{@theme.dir}/javascripts/theme.js", 1
|
||||
ensure
|
||||
@theme.javascripts.delete 'theme'
|
||||
end
|
||||
|
||||
def test_use_default_favicon_if_theme_provides_none
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'link[rel="shortcut icon"][href^="/favicon.ico"]'
|
||||
end
|
||||
|
||||
def test_use_theme_favicon_if_theme_provides_one
|
||||
# Simulate a theme favicon
|
||||
@theme.favicons << 'a.ico'
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'link[rel="shortcut icon"][href^=?]', "/themes/#{@theme.dir}/favicon/a.ico"
|
||||
ensure
|
||||
@theme.favicons.delete 'a.ico'
|
||||
end
|
||||
|
||||
def test_use_only_one_theme_favicon_if_theme_provides_many
|
||||
@theme.favicons.concat %w{b.ico a.png}
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'link[rel="shortcut icon"]', 1
|
||||
assert_select 'link[rel="shortcut icon"][href^=?]', "/themes/#{@theme.dir}/favicon/b.ico"
|
||||
ensure
|
||||
@theme.favicons.delete("b.ico")
|
||||
@theme.favicons.delete("a.png")
|
||||
end
|
||||
|
||||
def test_with_sub_uri
|
||||
Redmine::Utils.relative_url_root = '/foo'
|
||||
@theme.javascripts << 'theme'
|
||||
@theme.favicons << 'a.ico'
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "link[rel=stylesheet][href^=?]", "/foo/themes/#{@theme.dir}/stylesheets/application.css"
|
||||
assert_select "script[src^=?]", "/foo/themes/#{@theme.dir}/javascripts/theme.js"
|
||||
assert_select 'link[rel="shortcut icon"][href^=?]', "/foo/themes/#{@theme.dir}/favicon/a.ico"
|
||||
ensure
|
||||
Redmine::Utils.relative_url_root = ''
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue