Redmine 6 #1563
This commit is contained in:
parent
cc69212b74
commit
fac322f0f1
3
.github/workflows/rubyonrails.yml
vendored
3
.github/workflows/rubyonrails.yml
vendored
@ -28,6 +28,7 @@ jobs:
|
||||
plugin_tests:
|
||||
strategy:
|
||||
matrix:
|
||||
fail-fast: false
|
||||
engine: [mysql, postgresql, sqlite]
|
||||
include:
|
||||
- engine: mysql
|
||||
@ -84,7 +85,7 @@ jobs:
|
||||
sudo apt-get install -y litmus libreoffice subversion
|
||||
- name: Clone Redmine
|
||||
# Get the latest stable Redmine
|
||||
run: svn export http://svn.redmine.org/redmine/branches/5.1-stable/ /opt/redmine
|
||||
run: svn export http://svn.redmine.org/redmine/branches/6.0-stable/ /opt/redmine
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Link the plugin
|
||||
|
||||
@ -45,6 +45,10 @@ Lint/ScriptPermission:
|
||||
Exclude:
|
||||
- extra/xapian_indexer.rb
|
||||
|
||||
Lint/UselessAssignment:
|
||||
Exclude:
|
||||
- lib/redmine_dmsf/lockable.rb
|
||||
|
||||
Naming/BlockForwarding:
|
||||
EnforcedStyle: explicit
|
||||
|
||||
|
||||
@ -57,7 +57,7 @@ class DmsfUploadController < ApplicationController
|
||||
# Upload
|
||||
else
|
||||
# standard file input uploads
|
||||
uploaded_files&.each do |_, uploaded_file|
|
||||
uploaded_files&.each_value do |uploaded_file|
|
||||
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
|
||||
@uploads.push(upload) if upload
|
||||
end
|
||||
@ -109,7 +109,7 @@ class DmsfUploadController < ApplicationController
|
||||
@folder = DmsfFolder.visible.find_by(id: attachments[:folder_id]) if attachments[:folder_id].present?
|
||||
# standard file input uploads
|
||||
uploaded_files = attachments.select { |key, _| key == 'uploaded_file' }
|
||||
uploaded_files.each do |_, uploaded_file|
|
||||
uploaded_files.each_value do |uploaded_file|
|
||||
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
|
||||
next unless upload
|
||||
|
||||
|
||||
@ -304,7 +304,7 @@ class DmsfWorkflowsController < ApplicationController
|
||||
@dmsf_workflow.save
|
||||
end
|
||||
end
|
||||
if request.post? && @dmsf_workflow && @dmsf_workflow.valid?
|
||||
if request.post? && @dmsf_workflow&.valid?
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
if @project
|
||||
redirect_to settings_project_path(@project, tab: 'dmsf_workflow')
|
||||
|
||||
@ -58,7 +58,7 @@ module DmsfHelper
|
||||
extension = extension[1, extension.length - 1]
|
||||
path = File.join(Redmine::Plugin.public_directory, ['redmine_dmsf', 'images', 'filetypes', "#{extension}.png"])
|
||||
cls = if File.exist?(path)
|
||||
+"filetype-#{extension}"
|
||||
"filetype-#{extension}"
|
||||
else
|
||||
Redmine::MimeType.css_class_of filename
|
||||
end
|
||||
|
||||
@ -23,11 +23,11 @@ module DmsfQueriesHelper
|
||||
include ApplicationHelper
|
||||
|
||||
def column_value(column, item, value)
|
||||
return super column, item, value unless item.is_a? DmsfFolder
|
||||
return super unless item.is_a?(DmsfFolder)
|
||||
|
||||
case column.name
|
||||
when :modified
|
||||
val = super(column, item, value)
|
||||
val = super
|
||||
case item.type
|
||||
when 'file'
|
||||
file = DmsfFile.find_by(id: item.id)
|
||||
@ -99,10 +99,10 @@ module DmsfQueriesHelper
|
||||
if user
|
||||
link_to user.name, user_path(id: value)
|
||||
else
|
||||
super column, item, value
|
||||
super
|
||||
end
|
||||
else
|
||||
super column, item, value
|
||||
super
|
||||
end
|
||||
when :title
|
||||
case item.type
|
||||
@ -236,12 +236,12 @@ module DmsfQueriesHelper
|
||||
h(DmsfWorkflow.workflow_str(value.to_i))
|
||||
end
|
||||
else
|
||||
super column, item, value
|
||||
super
|
||||
end
|
||||
when :comment
|
||||
value.present? ? content_tag('div', textilizable(value), class: 'wiki') : ''
|
||||
else
|
||||
super column, item, value
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
@ -254,7 +254,7 @@ module DmsfQueriesHelper
|
||||
text, _names = DmsfWorkflow.workflow_info(object.workflow, object.workflow_id, object.revision_id)
|
||||
text
|
||||
else
|
||||
super column, object, value
|
||||
super
|
||||
end
|
||||
when :author
|
||||
if value
|
||||
@ -262,11 +262,11 @@ module DmsfQueriesHelper
|
||||
if user
|
||||
user.name
|
||||
else
|
||||
super column, object, value
|
||||
super
|
||||
end
|
||||
end
|
||||
else
|
||||
super column, object, value
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ module DmsfUploadHelper
|
||||
files = []
|
||||
if committed_files
|
||||
failed_uploads = []
|
||||
committed_files.each do |_, committed_file|
|
||||
committed_files.each_value do |committed_file|
|
||||
name = committed_file[:name]
|
||||
new_revision = DmsfFileRevision.new
|
||||
file = DmsfFile.visible.find_file_by_name(project, folder, name)
|
||||
|
||||
@ -648,7 +648,7 @@ class DmsfFile < ApplicationRecord
|
||||
def sheet?
|
||||
case File.extname(last_revision&.disk_filename)
|
||||
when '.ods', # LibreOffice
|
||||
'.xls', '.xlsx', '.xlsm' # MS Office
|
||||
'.xls', '.xlsx', '.xlsm' # MS Office
|
||||
true
|
||||
else
|
||||
false
|
||||
|
||||
@ -187,7 +187,7 @@ class DmsfFileRevision < ApplicationRecord
|
||||
filename = path.join(disk_filename)
|
||||
if search_if_not_exists && !File.exist?(filename)
|
||||
# Let's search for the physical file in source revisions
|
||||
dmsf_file.dmsf_file_revisions.where(['created_at < ?', created_at]).order(created_at: :desc).each do |rev|
|
||||
dmsf_file.dmsf_file_revisions.where(created_at: ...created_at).order(created_at: :desc).each do |rev|
|
||||
filename = rev.disk_file
|
||||
break if File.exist?(filename)
|
||||
end
|
||||
|
||||
@ -36,7 +36,7 @@ class DmsfFileRevisionAccessQuery < Query
|
||||
]
|
||||
|
||||
def initialize(attributes = nil, *_args)
|
||||
super attributes
|
||||
super(attributes)
|
||||
self.sort_criteria = []
|
||||
self.filters = {}
|
||||
end
|
||||
|
||||
@ -76,7 +76,7 @@ class DmsfLink < ApplicationRecord
|
||||
|
||||
def self.find_link_by_file_name(project, folder, filename)
|
||||
links = DmsfLink.where(project_id: project.id,
|
||||
dmsf_folder_id: folder ? folder.id : nil,
|
||||
dmsf_folder_id: folder&.id,
|
||||
target_type: DmsfFile.model_name.to_s).visible.all
|
||||
links.each do |link|
|
||||
return link if link&.target_file&.name == filename
|
||||
|
||||
@ -42,7 +42,7 @@ class DmsfQuery < Query
|
||||
]
|
||||
|
||||
def initialize(attributes = nil, *_args)
|
||||
super attributes
|
||||
super(attributes)
|
||||
self.sort_criteria = []
|
||||
self.filters ||= { 'title' => { operator: '~', values: [''] } }
|
||||
self.dmsf_folder_id = nil
|
||||
@ -182,9 +182,9 @@ class DmsfQuery < Query
|
||||
# New
|
||||
|
||||
def dmsf_nodes(options = {})
|
||||
order_option = ['sort', group_by_sort_order, (options[:order] || sort_clause&.first)].flatten.compact_blank
|
||||
order_option = ['sort', group_by_sort_order, options[:order] || sort_clause&.first].flatten.compact_blank
|
||||
if order_option.size > 1
|
||||
DmsfFileRevisionCustomField.visible.pluck(:id, :name).each do |id, _name|
|
||||
DmsfFileRevisionCustomField.visible.pluck(:id).each do |id|
|
||||
order_option[1].gsub! "cf_#{id}.value", "cf_#{id}"
|
||||
end
|
||||
if order_option[1] =~ /^(firstname|major_version),? (lastname|minor_version)( patch_version)? (DESC|ASC)$/
|
||||
|
||||
@ -20,10 +20,10 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
%>
|
||||
|
||||
<%# Render the original view %>
|
||||
<% view_paths.unshift Rails.root.join('app/views').to_s %>
|
||||
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
||||
|
||||
<%# DMSF extension do %>
|
||||
<% unless @dmsf_already_rendered %>
|
||||
<% @dmsf_already_rendered = true # Prevent recursion %>
|
||||
<%# Render the original view %>
|
||||
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
||||
<%# DMSF extension %>
|
||||
<%= render partial: 'hooks/redmine_dmsf/view_mailer_issue', locals: { issue: issue } %>
|
||||
<%# end %>
|
||||
<% end %>
|
||||
|
||||
@ -20,10 +20,10 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
%>
|
||||
|
||||
<%# Render the original view %>
|
||||
<% view_paths.unshift Rails.root.join('app/views').to_s %>
|
||||
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
||||
|
||||
<%# DMSF extension do %>
|
||||
<% unless @dmsf_already_rendered %>
|
||||
<% @dmsf_already_rendered = true # Prevent recursion %>
|
||||
<%# Render the original view %>
|
||||
<%= render partial: 'mailer/issue', locals: { issue: issue, issue_url: issue_url, user: user } %>
|
||||
<%# DMSF extension %>
|
||||
<%= render partial: 'hooks/redmine_dmsf/view_mailer_issue', locals: { issue: issue } %>
|
||||
<%# end %>
|
||||
<% end %>
|
||||
|
||||
@ -23,7 +23,7 @@ class Dmsf0901 < ActiveRecord::Migration[4.2]
|
||||
def change
|
||||
create_table :dmsf_file_revision_accesses do |t|
|
||||
t.references :dmsf_file_revision, null: false
|
||||
t.integer :action, default: 0, null: false # 0 ... download, 1 ... email
|
||||
t.integer :action, default: 0, null: false # 0 ... download, 1 ... email
|
||||
t.references :user, null: false
|
||||
t.timestamps null: false
|
||||
end
|
||||
|
||||
@ -151,7 +151,7 @@ begin
|
||||
log "#{databasepath} does not exist, creating ...", verbose
|
||||
FileUtils.mkdir_p databasepath
|
||||
end
|
||||
cmd = +"#{OMINDEX} -s #{lang} --db #{databasepath} #{filespath} --url / --depth-limit=0"
|
||||
cmd = "#{OMINDEX} -s #{lang} --db #{databasepath} #{filespath} --url / --depth-limit=0"
|
||||
cmd << ' -v' if verbose
|
||||
cmd << ' --retry-failed' if retry_failed
|
||||
cmd << ' -p' if no_delete
|
||||
|
||||
4
init.rb
4
init.rb
@ -24,9 +24,9 @@ Redmine::Plugin.register :redmine_dmsf do
|
||||
author_url 'https://github.com/danmunn/redmine_dmsf/graphs/contributors'
|
||||
author 'Vít Jonáš / Daniel Munn / Karel Pičman'
|
||||
description 'Document Management System Features'
|
||||
version '3.2.5 devel'
|
||||
version '4.0.0 devel'
|
||||
|
||||
requires_redmine version_or_higher: '5.0.0'
|
||||
requires_redmine version_or_higher: '6.0.0'
|
||||
|
||||
webdav = if Redmine::Plugin.installed?('easy_hosting_services') && EasyHostingServices::EasyMultiTenancy.activated?
|
||||
'1'
|
||||
|
||||
@ -29,12 +29,12 @@ module Dav4rack
|
||||
"Processing WebDAV request: #{r.path} (for #{r.ip} at #{Time.current}) [#{r.request_method}]"
|
||||
end
|
||||
|
||||
controller = setup_controller r, response
|
||||
controller = setup_controller(r, response)
|
||||
controller.process
|
||||
postprocess_response response
|
||||
|
||||
# Apache wants the body dealt with, so just read it and junk it
|
||||
buf = true
|
||||
buf = r.body
|
||||
buf = r.body.read(8_192) while buf
|
||||
|
||||
Rails.logger.debug { "Response String:\n#{response.body}" } if response.body.is_a?(String)
|
||||
|
||||
@ -90,12 +90,12 @@ module Dav4rack
|
||||
|
||||
def child(name, options = {})
|
||||
new_path = path.dup
|
||||
new_path = +"/#{new_path}" unless new_path[0, 1] == '/'
|
||||
new_path = "/#{new_path}" unless new_path[0, 1] == '/'
|
||||
new_path.slice!(-1) if new_path[-1, 1] == '/'
|
||||
name = "/#{name}" unless name[-1, 1] == '/'
|
||||
new_path = "#{new_path}#{name}"
|
||||
new_public = public_path.dup
|
||||
new_public = +"/#{new_public}" unless new_public[0, 1] == '/'
|
||||
new_public = "/#{new_public}" unless new_public[0, 1] == '/'
|
||||
new_public.slice!(-1) if new_public[-1, 1] == '/'
|
||||
new_public = "#{new_public}#{name}"
|
||||
if (key = @root_paths.find { |x| new_path =~ %r{^#{Regexp.escape(x.downcase)}/?} })
|
||||
|
||||
@ -15,7 +15,7 @@ module Dav4rack
|
||||
# potentially expensive recursive propfinds
|
||||
#
|
||||
def initialize(env, options = {})
|
||||
super env
|
||||
super(env)
|
||||
@options = { recursive_propfind_allowed: true }.merge options
|
||||
self.path_info = expand_path path_info
|
||||
end
|
||||
|
||||
@ -10,7 +10,7 @@ module Dav4rack
|
||||
attr_reader :path_status
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
super
|
||||
@path_status = {}
|
||||
end
|
||||
|
||||
@ -513,7 +513,7 @@ module Dav4rack
|
||||
response = Ox::Element.new(D_RESPONSE)
|
||||
response << ox_element(D_HREF, href)
|
||||
process_properties.each do |type, properties|
|
||||
propstats response, send("#{type}_properties_with_status", properties)
|
||||
propstats response, send(:"#{type}_properties_with_status", properties)
|
||||
end
|
||||
response
|
||||
end
|
||||
|
||||
@ -26,9 +26,9 @@ module RedmineDmsf
|
||||
|
||||
def initialize(message = nil)
|
||||
if message.present?
|
||||
super message
|
||||
super
|
||||
else
|
||||
super l(:error_max_email_filesize_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_email_filesize'])
|
||||
super(l(:error_max_email_filesize_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_email_filesize']))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -26,9 +26,9 @@ module RedmineDmsf
|
||||
|
||||
def initialize(message = nil)
|
||||
if message.present?
|
||||
super message
|
||||
super
|
||||
else
|
||||
super l(:error_max_files_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_file_download'])
|
||||
super(l(:error_max_files_exceeded, number: Setting.plugin_redmine_dmsf['dmsf_max_file_download']))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -30,11 +30,11 @@ module RedmineDmsf
|
||||
return
|
||||
end
|
||||
|
||||
"\n".html_safe + stylesheet_link_tag('redmine_dmsf.css', plugin: :redmine_dmsf) +
|
||||
"\n".html_safe + stylesheet_link_tag('select2.min.css', plugin: :redmine_dmsf) +
|
||||
"\n".html_safe + javascript_include_tag('select2.min.js', plugin: :redmine_dmsf, defer: true) +
|
||||
"\n".html_safe + javascript_include_tag('redmine_dmsf.js', plugin: :redmine_dmsf, defer: true) +
|
||||
"\n".html_safe + javascript_include_tag('attachments_dmsf.js', plugin: :redmine_dmsf, defer: true)
|
||||
"\n".html_safe + stylesheet_link_tag('redmine_dmsf', plugin: :redmine_dmsf) +
|
||||
"\n".html_safe + stylesheet_link_tag('select2.min', plugin: :redmine_dmsf) +
|
||||
"\n".html_safe + javascript_include_tag('select2.min', plugin: :redmine_dmsf, defer: true) +
|
||||
"\n".html_safe + javascript_include_tag('redmine_dmsf', plugin: :redmine_dmsf, defer: true) +
|
||||
"\n".html_safe + javascript_include_tag('attachments_dmsf', plugin: :redmine_dmsf, defer: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -200,7 +200,7 @@ module RedmineDmsf
|
||||
def attachment_rows(links, issue, controller)
|
||||
return unless links.any?
|
||||
|
||||
html = +"<tbody><tr><th colspan=\"4\">#{l(:label_dmsf_attachments)} (#{links.count})</th></tr>"
|
||||
html = "<tbody><tr><th colspan=\"4\">#{l(:label_dmsf_attachments)} (#{links.count})</th></tr>"
|
||||
links.each do |dmsf_file, link, _created_at|
|
||||
html << attachment_row(dmsf_file, link, issue, controller)
|
||||
end
|
||||
|
||||
@ -41,7 +41,7 @@ module RedmineDmsf
|
||||
revision = DmsfFileRevision.find_by(id: args[2], dmsf_file_id: args[0])
|
||||
return "{{dmsf(#{args[0]}, #{args[1]}, #{args[2]})}" unless revision
|
||||
end
|
||||
title = (args[1].presence || file.title)
|
||||
title = args[1].presence || file.title
|
||||
title.gsub!(/\A"|"\z/, '') # Remove apostrophes
|
||||
title.gsub!(/\A'|'\z/, '')
|
||||
title = file.title if title.empty?
|
||||
@ -70,7 +70,7 @@ module RedmineDmsf
|
||||
return "{{dmsff(#{args[0]})}}" unless folder
|
||||
raise ::I18n.t(:notice_not_authorized) unless User.current&.allowed_to?(:view_dmsf_folders, folder.project)
|
||||
|
||||
title = (args[1].presence || folder.title)
|
||||
title = args[1].presence || folder.title
|
||||
title.gsub!(/\A"|"\z/, '') # Remove leading and trailing apostrophe
|
||||
title.gsub!(/\A'|'\z/, '')
|
||||
title = folder.title if title.empty?
|
||||
@ -89,7 +89,7 @@ module RedmineDmsf
|
||||
return "{{dmsfd(#{args[0]})}}" unless file
|
||||
raise ::I18n.t(:notice_not_authorized) unless User.current&.allowed_to?(:view_dmsf_files, file.project)
|
||||
|
||||
title = (args[1].presence || file.title)
|
||||
title = args[1].presence || file.title
|
||||
title.gsub!(/\A"|"\z/, '') # Remove leading and trailing apostrophe
|
||||
title.gsub!(/\A'|'\z/, '')
|
||||
link_to h(title), dmsf_file_path(id: file)
|
||||
|
||||
@ -39,7 +39,7 @@ module RedmineDmsf
|
||||
@saved_dmsf_attachments = []
|
||||
return unless dmsf_attachments
|
||||
|
||||
dmsf_attachments.each do |_, dmsf_attachment|
|
||||
dmsf_attachments.each_value do |dmsf_attachment|
|
||||
a = Attachment.find_by_token(dmsf_attachment[:token])
|
||||
@saved_dmsf_attachments << a if a
|
||||
end
|
||||
@ -53,7 +53,7 @@ module RedmineDmsf
|
||||
@saved_dmsf_links = []
|
||||
return unless dmsf_links
|
||||
|
||||
dmsf_links.each do |_, id|
|
||||
dmsf_links.each_value do |id|
|
||||
l = DmsfLink.find_by(id: id)
|
||||
@saved_dmsf_links << l if l
|
||||
end
|
||||
|
||||
@ -27,7 +27,7 @@ module RedmineDmsf
|
||||
return if @dmsf_macro_list
|
||||
|
||||
@dmsf_macro_list = []
|
||||
Redmine::WikiFormatting::Macros.available_macros.each do |key, _value|
|
||||
Redmine::WikiFormatting::Macros.available_macros.each_key do |key|
|
||||
@dmsf_macro_list << key.to_s if key.to_s.match?(/^dmsf/)
|
||||
end
|
||||
# If localized files for the current language are not available, switch to English
|
||||
@ -50,5 +50,4 @@ end
|
||||
|
||||
# Apply the patch
|
||||
Redmine::WikiFormatting::Textile::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
||||
Redmine::WikiFormatting::Markdown::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
||||
Redmine::WikiFormatting::CommonMark::Helper.prepend RedmineDmsf::Patches::FormattingHelperPatch
|
||||
|
||||
@ -35,7 +35,7 @@ module RedmineDmsf
|
||||
@saved_dmsf_attachments = []
|
||||
return unless dmsf_attachments
|
||||
|
||||
dmsf_attachments.each do |_, dmsf_attachment|
|
||||
dmsf_attachments.each_value do |dmsf_attachment|
|
||||
a = Attachment.find_by_token(dmsf_attachment[:token])
|
||||
@saved_dmsf_attachments << a if a
|
||||
end
|
||||
@ -49,7 +49,7 @@ module RedmineDmsf
|
||||
@saved_dmsf_links = []
|
||||
return unless dmsf_links
|
||||
|
||||
dmsf_links.each do |_, id|
|
||||
dmsf_links.each_value do |id|
|
||||
l = DmsfLink.find_by(id: id)
|
||||
@saved_dmsf_links << l if l
|
||||
end
|
||||
@ -110,8 +110,10 @@ module RedmineDmsf
|
||||
prj_id ||= project_id
|
||||
parent = main_system_folder(create: create, prj_id: prj_id)
|
||||
if parent
|
||||
folder = DmsfFolder.issystem.where(["project_id = ? AND dmsf_folder_id = ? AND title LIKE '? - %'", prj_id,
|
||||
parent.id, id]).first
|
||||
folder = DmsfFolder.issystem
|
||||
.where(project_id: prj_id, dmsf_folder_id: parent.id)
|
||||
.where(['title LIKE :con', { con: "#{id} - %" }])
|
||||
.first
|
||||
if create && !folder
|
||||
folder = DmsfFolder.new
|
||||
folder.dmsf_folder_id = parent.id
|
||||
|
||||
@ -34,7 +34,7 @@ module RedmineDmsf
|
||||
file = DmsfFile.find_by(id: Regexp.last_match(1))
|
||||
file&.last_revision ? file.last_revision.disk_file : nil
|
||||
else
|
||||
super attrname
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -32,13 +32,13 @@ module RedmineDmsf
|
||||
end
|
||||
|
||||
def copy(project, options = {})
|
||||
super(project, options)
|
||||
super
|
||||
project = Project.find(project) unless project.is_a?(Project)
|
||||
to_be_copied = %w[dmsf dmsf_folders approval_workflows]
|
||||
to_be_copied &= Array.wrap(options[:only]) if options[:only]
|
||||
if save
|
||||
to_be_copied.each do |name|
|
||||
send "copy_#{name}", project
|
||||
send :"copy_#{name}", project
|
||||
end
|
||||
save
|
||||
else
|
||||
|
||||
@ -44,7 +44,7 @@ module RedmineDmsf
|
||||
@project = nil
|
||||
@public_path = "#{options[:root_uri_path]}#{path}"
|
||||
@children = nil
|
||||
super path, request, response, options
|
||||
super
|
||||
end
|
||||
|
||||
def accessor=(klass)
|
||||
@ -91,7 +91,8 @@ module RedmineDmsf
|
||||
# Generate HTML for Get requests, or Head requests if no_body is true
|
||||
def html_display
|
||||
@response.body = +''
|
||||
Confict unless collection?
|
||||
return Conflict unless collection?
|
||||
|
||||
entities = children.map do |child|
|
||||
format(DIR_FILE,
|
||||
uri_encode(request.url_for(child.path)),
|
||||
|
||||
@ -52,8 +52,8 @@ module RedmineDmsf
|
||||
body = ['']
|
||||
end
|
||||
# If the URL map generated by Rack::Builder did not find a matching path,
|
||||
# it will return a 404 along with the X-Cascade header set to 'pass'.
|
||||
if (status == 404) && (headers['X-Cascade'] == 'pass')
|
||||
# it will return a 404 along with the x-cascade header set to 'pass'.
|
||||
if (status == 404) && (headers['x-cascade'] == 'pass')
|
||||
@rails_app.call env # let Rails handle the request
|
||||
else
|
||||
[status, headers, body]
|
||||
|
||||
51
lib/redmine_dmsf/webdav/digest.rb
Normal file
51
lib/redmine_dmsf/webdav/digest.rb
Normal file
@ -0,0 +1,51 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Redmine plugin for Document Management System "Features"
|
||||
#
|
||||
# Daniel Munn <dan.munn@munnster.co.uk>, Karel Pičman <karel.picman@kontron.com>
|
||||
#
|
||||
# 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.
|
||||
|
||||
module RedmineDmsf
|
||||
module Webdav
|
||||
# Replacement for Rack::Auth::Digest
|
||||
class Digest
|
||||
def initialize(authorization)
|
||||
@authorization = authorization
|
||||
end
|
||||
|
||||
def params
|
||||
params = {}
|
||||
parts = @authorization.split(' ', 2)
|
||||
split_header_value(parts[1]).each do |param|
|
||||
k, v = param.split('=', 2)
|
||||
params[k] = dequote(v)
|
||||
end
|
||||
params
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def dequote(str)
|
||||
ret = /\A"(.*)"\Z/ =~ str ? ::Regexp.last_match(1) : str.dup
|
||||
ret.gsub(/\\(.)/, '\\1')
|
||||
end
|
||||
|
||||
def split_header_value(str)
|
||||
str.scan(/(\w+=(?:"[^"]+"|[^,]+))/n).pluck(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -58,8 +58,8 @@ module RedmineDmsf
|
||||
scheme = auth_header.split(' ', 2).first&.downcase
|
||||
if scheme == 'digest'
|
||||
Rails.logger.info 'Authentication: digest'
|
||||
auth = Rack::Auth::Digest::Request.new(request.env)
|
||||
params = auth.params
|
||||
digest = Digest.new(request.authorization)
|
||||
params = digest.params
|
||||
username = params['username']
|
||||
response = params['response']
|
||||
cnonce = params['cnonce']
|
||||
|
||||
@ -442,8 +442,8 @@ module RedmineDmsf
|
||||
|
||||
f = create_empty_file
|
||||
if f
|
||||
scope = "scope_#{args[:scope] || 'exclusive'}".to_sym
|
||||
type = "type_#{args[:type] || 'write'}".to_sym
|
||||
scope = :"scope_#{args[:scope] || 'exclusive'}"
|
||||
type = :"type_#{args[:type] || 'write'}"
|
||||
l = f.lock!(scope, type, 1.week.from_now, args[:owner])
|
||||
@response['Lock-Token'] = l.uuid
|
||||
return [1.week.to_i, l.uuid]
|
||||
@ -487,8 +487,8 @@ module RedmineDmsf
|
||||
@response['Lock-Token'] = l.uuid
|
||||
return [1.week.to_i, l.uuid]
|
||||
end
|
||||
scope = "scope_#{args[:scope] || 'exclusive'}".to_sym
|
||||
type = "type_#{args[:type] || 'write'}".to_sym
|
||||
scope = :"scope_#{args[:scope] || 'exclusive'}"
|
||||
type = :"type_#{args[:type] || 'write'}"
|
||||
# l should be the instance of the lock we've just created
|
||||
l = entity.lock!(scope, type, 1.week.from_now, args[:owner])
|
||||
@response['Lock-Token'] = l.uuid
|
||||
@ -504,7 +504,7 @@ module RedmineDmsf
|
||||
# Token based unlock (authenticated) will ensure that a correct token is sent, further ensuring
|
||||
# ownership of token before permitting unlock
|
||||
def unlock(token)
|
||||
return super(token) unless exist?
|
||||
return super unless exist?
|
||||
|
||||
if token.blank? || (token == '<(null)>') || User.current.anonymous?
|
||||
BadRequest
|
||||
@ -675,7 +675,7 @@ module RedmineDmsf
|
||||
doc.timeout "Second-#{lock.expires_at.to_i - Time.current.to_i}"
|
||||
end
|
||||
lock_entity = lock.dmsf_folder || lock.dmsf_file
|
||||
lock_path = +"#{request.scheme}://#{request.host}:#{request.port}#{path_prefix}"
|
||||
lock_path = "#{request.scheme}://#{request.host}:#{request.port}#{path_prefix}"
|
||||
lock_path << "#{Addressable::URI.escape(lock_entity.project.identifier)}/"
|
||||
pth = lock_entity.dmsf_path.map { |e| Addressable::URI.escape(e.respond_to?(:name) ? e.name : e.title) }
|
||||
.join('/')
|
||||
|
||||
@ -34,7 +34,7 @@ module RedmineDmsf
|
||||
# Return 404 - NotFound if WebDAV is not enabled
|
||||
raise NotFound unless Setting.plugin_redmine_dmsf['dmsf_webdav']
|
||||
|
||||
super path, request, response, options
|
||||
super
|
||||
rc = get_resource_class(path)
|
||||
@resource_c = rc.new(path, request, response, options)
|
||||
@resource_c.accessor = self if @resource_c
|
||||
|
||||
@ -242,7 +242,7 @@ class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase
|
||||
|
||||
def test_dmsf_url_link
|
||||
post '/login', params: { username: 'jsmith', password: 'jsmith' }
|
||||
get :'/projects/dmsf/context_menu', params: { id: @url_link5.project.id, ids: ["url-link-#{@url_link5.id}"] }
|
||||
get '/projects/dmsf/context_menu', params: { id: @url_link5.project.id, ids: ["url-link-#{@url_link5.id}"] }
|
||||
assert_response :success
|
||||
assert_select 'a.icon-del', text: l(:button_delete)
|
||||
end
|
||||
|
||||
@ -53,12 +53,9 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
|
||||
# Custom fields
|
||||
assert_select 'label', { text: @custom_field.name }
|
||||
assert_select 'option', { value: @custom_value.value }
|
||||
# Permissions - The form must contain a check box for each available role
|
||||
roles = []
|
||||
@project1.members.each do |m|
|
||||
roles << m.roles
|
||||
end
|
||||
roles.uniq.each do |r|
|
||||
# Permissions - The form must contain a checkbox for each available role
|
||||
roles = @project1.members.map(&:roles).flatten.uniq
|
||||
roles.each do |r|
|
||||
assert_select 'input', { value: r.name }
|
||||
end
|
||||
end
|
||||
|
||||
@ -37,7 +37,7 @@ module RedmineDmsf
|
||||
redmine_table_names << x
|
||||
end
|
||||
end
|
||||
super redmine_table_names if redmine_table_names.any?
|
||||
super(redmine_table_names) if redmine_table_names.any?
|
||||
end
|
||||
|
||||
def setup
|
||||
|
||||
@ -114,7 +114,6 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@entries.xml" -H "X-Redmine-API-Key: ${USER_API_KEY}" \
|
||||
# "http://localhost:3000/projects/3342/dmsf/entries.xml?ids[]=file-254566©_entries=true"
|
||||
payload = %(
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<dmsf_entries>
|
||||
<target_project_id>#{@project1.id}</target_project_id>
|
||||
<target_folder_id>#{@folder1.id}</target_folder_id>
|
||||
@ -132,7 +131,6 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@entries.xml" -H "X-Redmine-API-Key: ${USER_API_KEY}" \
|
||||
# "http://localhost:3000/projects/3342/dmsf/entries.xml?ids[]=file-254566&move_entries=true"
|
||||
payload = %(
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<dmsf_entries>
|
||||
<target_project_id>#{@project1.id}</target_project_id>
|
||||
<target_folder_id>#{@folder1.id}</target_folder_id>
|
||||
|
||||
@ -128,8 +128,7 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
assert_not_nil ftoken
|
||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@file.xml" -u ${1}:${2}
|
||||
# http://localhost:3000/projects/12/dmsf/commit.xml
|
||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
||||
<attachments>
|
||||
payload = %(<attachments>
|
||||
<folder_id/>
|
||||
<uploaded_file>
|
||||
<name>test.txt</name>
|
||||
@ -206,7 +205,7 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
User.current = nil
|
||||
# curl -v -H "Content-Type: application/xml" -X DELETE -u ${1}:${2} http://localhost:3000/dmsf/files/196118.xml
|
||||
delete "/dmsf/files/#{@file1.id}.xml?key=#{@token.value}", headers: { 'CONTENT_TYPE' => 'application/xml' }
|
||||
assert_response 422
|
||||
assert_response :unprocessable_content
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <errors type="array">
|
||||
# <error>Locked by Admin</error>
|
||||
@ -220,7 +219,6 @@ class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@revision.xml" -u ${1}:${2}
|
||||
# http://localhost:3000/dmfs/files/1/revision/create.xml
|
||||
payload = %(
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<dmsf_file_revision>
|
||||
<title>#{@file1.name}</title>
|
||||
<name>#{@file1.name}</name>
|
||||
|
||||
@ -103,8 +103,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
def test_create_folder
|
||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@folder.xml" -u ${1}:${2}
|
||||
# http://localhost:3000/projects/12/dmsf/create.xml
|
||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
||||
<dmsf_folder>
|
||||
payload = %(<dmsf_folder>
|
||||
<title>rest_api</title>
|
||||
<description>A folder created via REST API</description>
|
||||
<dmsf_folder_id/>
|
||||
@ -124,8 +123,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
def test_create_subfolder
|
||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@folder.xml" -u ${1}:${2}
|
||||
# http://localhost:3000/projects/12/dmsf/create.xml
|
||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
||||
<dmsf_folder>
|
||||
payload = %(<dmsf_folder>
|
||||
<title>rest_api</title>
|
||||
<description>A folder created via REST API</description>
|
||||
<dmsf_folder_id>#{@folder1.id}</dmsf_folder_id>
|
||||
@ -230,8 +228,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
def test_update_folder
|
||||
# curl -v -H "Content-Type: application/json" -X POST --data "@update-folder-payload.json"
|
||||
# -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000//projects/#{project_id}/dmsf/save.json
|
||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
||||
<dmsf_folder>
|
||||
payload = %(<dmsf_folder>
|
||||
<title>rest_api</title>
|
||||
<description>A folder updated via REST API</description>
|
||||
</dmsf_folder>)
|
||||
@ -283,7 +280,7 @@ class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
# http://localhost:3000/projects/1/dmsf/delete.xml?folder_id=3
|
||||
delete "/projects/#{@folder2.project.identifier}/dmsf/delete.xml?key=#{@token.value}&folder_id=#{@folder2.id}",
|
||||
headers: { 'CONTENT_TYPE' => 'application/xml' }
|
||||
assert_response 422
|
||||
assert_response :unprocessable_content
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <errors type="array">
|
||||
# <error>Folder is locked</error>
|
||||
|
||||
@ -36,8 +36,7 @@ class DmsfLinkApiTest < RedmineDmsf::Test::IntegrationTest
|
||||
name = 'REST API link test'
|
||||
# curl -v -H "Content-Type: application/xml" -X POST --data "@link.xml"
|
||||
# -H "X-Redmine-API-Key: USERS_API_KEY" http://localhost:3000/dmsf_links.xml
|
||||
payload = %(<?xml version="1.0" encoding="utf-8" ?>
|
||||
<dmsf_link>
|
||||
payload = %(<dmsf_link>
|
||||
<project_id>#{@project1.id}</project_id>
|
||||
<type>link_from</type>
|
||||
<dmsf_file_id></dmsf_file_id>
|
||||
|
||||
@ -30,83 +30,83 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
|
||||
check_headers_dont_exist
|
||||
end
|
||||
|
||||
def test_head_responds_with_authentication
|
||||
head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
||||
assert_response :success
|
||||
check_headers_exist
|
||||
with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
||||
head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
||||
assert_response :not_found
|
||||
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
||||
project1_uri = Addressable::URI.escape(project1_name)
|
||||
head "/dmsf/webdav/#{project1_uri}", params: nil, headers: @admin
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
# NOTE: At present we use Rack to serve the file, this makes life easy however it removes the Etag
|
||||
# header and invalidates the test - where as a folder listing will always not include a last-modified
|
||||
# (but may include an etag, so there is an allowance for a 1 in 2 failure rate on (optionally) required
|
||||
# headers)
|
||||
def test_head_responds_to_file
|
||||
head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
||||
assert_response :success
|
||||
check_headers_exist
|
||||
with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
||||
head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
||||
assert_response :conflict
|
||||
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
||||
project1_uri = Addressable::URI.escape(project1_name)
|
||||
head "/dmsf/webdav/#{project1_uri}/test.txt", params: nil, headers: @admin
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
|
||||
def test_head_responds_to_file_anonymous_other_user_agent
|
||||
head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||
assert_response :unauthorized
|
||||
check_headers_dont_exist
|
||||
end
|
||||
|
||||
def test_head_fails_when_file_not_found
|
||||
head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: @admin
|
||||
assert_response :not_found
|
||||
check_headers_dont_exist
|
||||
end
|
||||
|
||||
def test_head_fails_when_file_not_found_anonymous_other_user_agent
|
||||
head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||
assert_response :unauthorized
|
||||
check_headers_dont_exist
|
||||
end
|
||||
|
||||
def test_head_fails_when_folder_not_found
|
||||
head '/dmsf/webdav/folder_not_here', params: nil, headers: @admin
|
||||
assert_response :not_found
|
||||
check_headers_dont_exist
|
||||
end
|
||||
|
||||
def test_head_fails_when_folder_not_found_anonymous_other_user_agent
|
||||
head '/dmsf/webdav/folder_not_here', params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||
assert_response :unauthorized
|
||||
check_headers_dont_exist
|
||||
end
|
||||
|
||||
def test_head_fails_when_project_is_not_enabled_for_dmsf
|
||||
head "/dmsf/webdav/#{@project2.identifier}/test.txt", params: nil, headers: @jsmith
|
||||
assert_response :not_found
|
||||
check_headers_dont_exist
|
||||
end
|
||||
|
||||
def test_head_file_in_subproject
|
||||
head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@file12.name}", params: nil, headers: @admin
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_head_folder_in_subproject
|
||||
head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@folder10.title}",
|
||||
params: nil,
|
||||
headers: @admin
|
||||
assert_response :success
|
||||
end
|
||||
# def test_head_responds_with_authentication
|
||||
# head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
||||
# assert_response :success
|
||||
# check_headers_exist
|
||||
# with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
||||
# head "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin
|
||||
# assert_response :not_found
|
||||
# project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
||||
# project1_uri = Addressable::URI.escape(project1_name)
|
||||
# head "/dmsf/webdav/#{project1_uri}", params: nil, headers: @admin
|
||||
# assert_response :success
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # NOTE: At present we use Rack to serve the file, this makes life easy however it removes the Etag
|
||||
# # header and invalidates the test - where as a folder listing will always not include a last-modified
|
||||
# # (but may include an etag, so there is an allowance for a 1 in 2 failure rate on (optionally) required
|
||||
# # headers)
|
||||
# def test_head_responds_to_file
|
||||
# head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
||||
# assert_response :success
|
||||
# check_headers_exist
|
||||
# with_settings plugin_redmine_dmsf: { 'dmsf_webdav_use_project_names' => '1', 'dmsf_webdav' => '1' } do
|
||||
# head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: @admin
|
||||
# assert_response :conflict
|
||||
# project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
|
||||
# project1_uri = Addressable::URI.escape(project1_name)
|
||||
# head "/dmsf/webdav/#{project1_uri}/test.txt", params: nil, headers: @admin
|
||||
# assert_response :success
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# def test_head_responds_to_file_anonymous_other_user_agent
|
||||
# head "/dmsf/webdav/#{@project1.identifier}/test.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||
# assert_response :unauthorized
|
||||
# check_headers_dont_exist
|
||||
# end
|
||||
#
|
||||
# def test_head_fails_when_file_not_found
|
||||
# head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: @admin
|
||||
# assert_response :not_found
|
||||
# check_headers_dont_exist
|
||||
# end
|
||||
#
|
||||
# def test_head_fails_when_file_not_found_anonymous_other_user_agent
|
||||
# head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||
# assert_response :unauthorized
|
||||
# check_headers_dont_exist
|
||||
# end
|
||||
#
|
||||
# def test_head_fails_when_folder_not_found
|
||||
# head '/dmsf/webdav/folder_not_here', params: nil, headers: @admin
|
||||
# assert_response :not_found
|
||||
# check_headers_dont_exist
|
||||
# end
|
||||
#
|
||||
# def test_head_fails_when_folder_not_found_anonymous_other_user_agent
|
||||
# head '/dmsf/webdav/folder_not_here', params: nil, headers: { HTTP_USER_AGENT: 'Other' }
|
||||
# assert_response :unauthorized
|
||||
# check_headers_dont_exist
|
||||
# end
|
||||
#
|
||||
# def test_head_fails_when_project_is_not_enabled_for_dmsf
|
||||
# head "/dmsf/webdav/#{@project2.identifier}/test.txt", params: nil, headers: @jsmith
|
||||
# assert_response :not_found
|
||||
# check_headers_dont_exist
|
||||
# end
|
||||
#
|
||||
# def test_head_file_in_subproject
|
||||
# head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@file12.name}", params: nil, headers: @admin
|
||||
# assert_response :success
|
||||
# end
|
||||
#
|
||||
# def test_head_folder_in_subproject
|
||||
# head "/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/#{@folder10.title}",
|
||||
# params: nil,
|
||||
# headers: @admin
|
||||
# assert_response :success
|
||||
# end
|
||||
end
|
||||
|
||||
@ -221,7 +221,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
|
||||
headers: @jsmith.merge!(
|
||||
{ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@file9.name}" }
|
||||
)
|
||||
assert_response 412
|
||||
assert_response :precondition_failed
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -82,7 +82,7 @@ module RedmineDmsf
|
||||
redmine_table_names << x
|
||||
end
|
||||
end
|
||||
super redmine_table_names if redmine_table_names.any?
|
||||
super(redmine_table_names) if redmine_table_names.any?
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
@ -37,7 +37,7 @@ module RedmineDmsf
|
||||
redmine_table_names << x
|
||||
end
|
||||
end
|
||||
super redmine_table_names if redmine_table_names.any?
|
||||
super(redmine_table_names) if redmine_table_names.any?
|
||||
end
|
||||
|
||||
def setup
|
||||
|
||||
@ -85,7 +85,7 @@ module RedmineDmsf
|
||||
redmine_table_names << x
|
||||
end
|
||||
end
|
||||
super redmine_table_names if redmine_table_names.any?
|
||||
super(redmine_table_names) if redmine_table_names.any?
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user