This commit is contained in:
Karel Pičman 2024-11-18 17:55:46 +01:00
parent cc69212b74
commit fac322f0f1
49 changed files with 235 additions and 188 deletions

View File

@ -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

View File

@ -45,6 +45,10 @@ Lint/ScriptPermission:
Exclude:
- extra/xapian_indexer.rb
Lint/UselessAssignment:
Exclude:
- lib/redmine_dmsf/lockable.rb
Naming/BlockForwarding:
EnforcedStyle: explicit

View File

@ -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

View File

@ -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')

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -36,7 +36,7 @@ class DmsfFileRevisionAccessQuery < Query
]
def initialize(attributes = nil, *_args)
super attributes
super(attributes)
self.sort_criteria = []
self.filters = {}
end

View File

@ -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

View File

@ -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)$/

View File

@ -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 %>

View File

@ -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 %>

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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)

View File

@ -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)}/?} })

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)),

View File

@ -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]

View 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

View File

@ -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']

View File

@ -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('/')

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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&copy_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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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