diff --git a/lib/redmine_dmsf/webdav/base_resource.rb b/lib/redmine_dmsf/webdav/base_resource.rb index 96769133..a8f2b125 100644 --- a/lib/redmine_dmsf/webdav/base_resource.rb +++ b/lib/redmine_dmsf/webdav/base_resource.rb @@ -31,9 +31,7 @@ module RedmineDmsf attr_reader :public_path def initialize(path, request, response, options) - if Setting.plugin_redmine_dmsf['dmsf_webdav'].blank? - raise NotFound - end + raise NotFound if Setting.plugin_redmine_dmsf['dmsf_webdav'].blank? @project = nil @public_path = "#{options[:root_uri_path]}#{path}" @children = nil @@ -122,13 +120,17 @@ module RedmineDmsf def project unless @project i = 1 + project_names = Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] while true pinfo = @path.split('/').drop(i) if pinfo.length > 0 - if Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] - if pinfo.first =~ /(\d+)$/ + if project_names + if pinfo.first =~ / (\d+)$/ prj = Project.visible.find_by(id: $1) - Rails.logger.error("No project found on path '#{@path}'") unless prj + if prj + # Check again whether it's really the project and not a folder with a number as a suffix + prj = nil unless pinfo.first =~ /^#{prj.name}/ + end end else begin @@ -140,7 +142,10 @@ module RedmineDmsf end end end - break unless prj + unless prj + @projectless_path = '/' + @path.split('/').drop(i).join('/') + break + end i = i + 1 @project = prj prj = nil @@ -151,8 +156,8 @@ module RedmineDmsf # Make it easy to find the path without project in it. def projectless_path - # TODO: - '/' + @path.split('/').drop(2).join('/') + project # Initialization + @projectless_path end def path_prefix diff --git a/lib/redmine_dmsf/webdav/dmsf_resource.rb b/lib/redmine_dmsf/webdav/dmsf_resource.rb index 9acf0737..281ff29a 100644 --- a/lib/redmine_dmsf/webdav/dmsf_resource.rb +++ b/lib/redmine_dmsf/webdav/dmsf_resource.rb @@ -107,18 +107,23 @@ module RedmineDmsf def subproject unless @subproject - @subproject = Project.visible.where(parent_id: parent_project.id, name: basename).first if parent_project + if Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] + if basename =~ / (\d+)$/ + @subproject = Project.visible.where(id: $1, parent_id: parent_project.id).first + if @subproject + # Check again whether it's really the project and not a folder with a number as a suffix + @subproject = nil unless basename =~ /^#{@subproject.name}/ + end + end + else + @subproject = Project.visible.where(parent_id: parent_project.id, identifier: basename).first if parent_project + end end @subproject end def parent_project - unless @parent_project - if /\/(.+)\/#{project.identifier}\/?$/.match(@path) - @parent_project = Project.visible.where(identifier: $1).first - end - end - @parent_project + project&.parent end # Return the content type of file @@ -282,6 +287,11 @@ module RedmineDmsf if dest.exist? return overwrite ? NotImplemented : PreconditionFailed else + # Change the title + return MethodNotAllowed unless folder # Moving sub-project not enabled + folder.title = resource.basename + return PreconditionFailed unless folder.save + # Move to a new destination folder.move_to(resource.project, parent.folder) ? Created : PreconditionFailed end else @@ -452,6 +462,11 @@ module RedmineDmsf end lock_check(args[:scope]) entity = file ? file : folder + unless entity + e = DAV4Rack::LockFailure.new + e.add_failure @path, MethodNotAllowed + raise e + end begin if entity.locked? && entity.locked_for_user? raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}") @@ -704,7 +719,8 @@ module RedmineDmsf File.new disk_file end -private + private + def reuse_version_for_locked_file(file) locks = file.lock locks.each do |lock| diff --git a/lib/redmine_dmsf/webdav/resource_proxy.rb b/lib/redmine_dmsf/webdav/resource_proxy.rb index 7ef67aa8..9f131e4f 100644 --- a/lib/redmine_dmsf/webdav/resource_proxy.rb +++ b/lib/redmine_dmsf/webdav/resource_proxy.rb @@ -39,7 +39,7 @@ module RedmineDmsf unless Setting.plugin_redmine_dmsf['dmsf_webdav'] raise NotFound end - super(*args) + super *args pinfo = path.split('/').drop(1) if pinfo.length == 0 # If this is the base_path, we're at root @resource_c = IndexResource.new(*args) @@ -110,12 +110,12 @@ module RedmineDmsf end def get(request, response) - @resource_c.get(request, response) + @resource_c.get request, response end def put(request, response) raise BadGateway if @read_only - @resource_c.put(request, response) + @resource_c.put request, response end def delete @@ -125,12 +125,12 @@ module RedmineDmsf def copy(dest, overwrite, depth) raise BadGateway if @read_only - @resource_c.copy(dest, overwrite, depth) + @resource_c.copy dest, overwrite, depth end def move(dest, overwrite = false) raise BadGateway if @read_only - @resource_c.move(dest, overwrite) + @resource_c.move dest, overwrite end def make_collection @@ -144,16 +144,16 @@ module RedmineDmsf def lock(args) raise BadGateway if @read_only - @resource_c.lock(args) + @resource_c.lock args end def lock_check(lock_scope = nil) - @resource_c.lock_check(lock_scope) + @resource_c.lock_check lock_scope end def unlock(token) raise BadGateway if @read_only - @resource_c.unlock(token) + @resource_c.unlock token end def name @@ -169,7 +169,7 @@ module RedmineDmsf end def get_property(element) - @resource_c.get_property(element) + @resource_c.get_property element end def properties @@ -177,7 +177,7 @@ module RedmineDmsf end def propstats(response, stats) - @resource_c.propstats(response, stats) + @resource_c.propstats response, stats end end end diff --git a/test/integration/webdav/dmsf_webdav_delete_test.rb b/test/integration/webdav/dmsf_webdav_delete_test.rb index 46bb9aaa..21d6b987 100644 --- a/test/integration/webdav/dmsf_webdav_delete_test.rb +++ b/test/integration/webdav/dmsf_webdav_delete_test.rb @@ -67,7 +67,7 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = @dmsf_webdav_use_project_names Setting.plugin_redmine_dmsf['dmsf_storage_directory'] = @dmsf_storage_directory end - + def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 @@ -191,7 +191,7 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest delete "/dmsf/webdav/#{p1name_uri}/#{@folder6.title}", params: nil, headers: @jsmith assert_response :success @folder6.reload - assert @folder6.deleted?, "Folder #{@folder1.title} is not expected to exist" + assert @folder6.deleted?, "Folder #{@folder6.title} is not expected to exist" end def test_file_delete_by_administrator @@ -259,18 +259,20 @@ class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest assert_nil DmsfFile.visible.find_by(id: @file1.id) end - def test_file_delete_in_subproject - @role.add_permission! :view_dmsf_folders - @role.add_permission! :file_delete + def test_delete_file_in_subproject delete "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@file12.name}", params: nil, headers: @admin assert_response :success end - def test_folder_delete_in_subproject - @role.add_permission! :view_dmsf_folders - @role.add_permission! :folder_delete - delete "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: nil, headers: @admin + def test_delete_folder_in_subproject + delete "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: nil, + headers: @admin assert_response :success end + def test_delete_subproject + delete "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}", params: nil, headers: @admin + assert_response :method_not_allowed + end + end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_get_test.rb b/test/integration/webdav/dmsf_webdav_get_test.rb index bc57cd81..3f89fd7e 100644 --- a/test/integration/webdav/dmsf_webdav_get_test.rb +++ b/test/integration/webdav/dmsf_webdav_get_test.rb @@ -32,6 +32,10 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest @jsmith = credentials 'jsmith' @project1 = Project.find 1 @project2 = Project.find 2 + @project3 = Project.find 3 + @file1 = DmsfFile.find 1 + @folder10 = DmsfFolder.find 10 + @file12 = DmsfFile.find 12 @role = Role.find_by(name: 'Manager') @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] Setting.plugin_redmine_dmsf['dmsf_webdav'] = true @@ -61,6 +65,10 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 + assert_kind_of Project, @project3 + assert_kind_of DmsfFile, @file1 + assert_kind_of DmsfFile, @file12 + assert_kind_of DmsfFolder, @folder10 assert_kind_of Role, @role end @@ -168,4 +176,16 @@ class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest assert_response :success end + def test_get_file_in_subproject + @project3.enable_module! :dmsf # Flag module enabled + get "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@file12.name}", params: nil, headers: @admin + assert_response :success + end + + def test_get_folder_in_subproject + @project3.enable_module! :dmsf # Flag module enabled + get "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: nil, headers: @admin + assert_response :success + end + end diff --git a/test/integration/webdav/dmsf_webdav_head_test.rb b/test/integration/webdav/dmsf_webdav_head_test.rb index 8a6bea2d..ced177ca 100644 --- a/test/integration/webdav/dmsf_webdav_head_test.rb +++ b/test/integration/webdav/dmsf_webdav_head_test.rb @@ -31,8 +31,11 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest @admin = credentials 'admin' @jsmith = credentials 'jsmith' @project1 = Project.find 1 - @project1.enable_module!('dmsf') + @project1.enable_module! 'dmsf' @project2 = Project.find 2 + @project3 = Project.find 3 + @folder10 = DmsfFolder.find 10 + @file12 = DmsfFile.find 12 @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] Setting.plugin_redmine_dmsf['dmsf_webdav'] = true @dmsf_webdav_strategy = Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] @@ -63,6 +66,9 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 + assert_kind_of Project, @project3 + assert_kind_of DmsfFolder, @folder10 + assert_kind_of DmsfFile, @file12 end def test_head_requires_authentication @@ -134,6 +140,18 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest check_headers_dont_exist end + def test_head_file_in_subproject + @project3.enable_module! :dmsf # Flag module enabled + head "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@file12.name}", params: nil, headers: @admin + assert_response :success + end + + def test_head_folder_in_subproject + @project3.enable_module! :dmsf # Flag module enabled + head "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: nil, headers: @admin + assert_response :success + end + private def check_headers_exist diff --git a/test/integration/webdav/dmsf_webdav_lock_test.rb b/test/integration/webdav/dmsf_webdav_lock_test.rb index c5bc9436..94639081 100644 --- a/test/integration/webdav/dmsf_webdav_lock_test.rb +++ b/test/integration/webdav/dmsf_webdav_lock_test.rb @@ -23,7 +23,7 @@ require File.expand_path('../../../test_helper', __FILE__) require 'fileutils' -class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest +class DmsfWebdavLockTest < RedmineDmsf::Test::IntegrationTest fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles, :enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions @@ -33,7 +33,12 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest @jsmith = credentials 'jsmith' @admin_user = User.find_by(login: 'admin') @project1 = Project.find 1 + @project1.enable_module! 'dmsf' + @project3 = Project.find 3 + @project3.enable_module! 'dmsf' @file1 = DmsfFile.find 1 + @file12 = DmsfFile.find 12 + @folder10 = DmsfFolder.find 10 # Fix permissions for jsmith's role @role = Role.find_by(name: 'Manager') @role.add_permission! :view_dmsf_folders @@ -42,6 +47,12 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav'] = true @dmsf_webdav_strategy = Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + @xml = %{ + + + + jsmith + } end def teardown @@ -51,26 +62,23 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest def test_truth assert_kind_of Project, @project1 + assert_kind_of Project, @project3 assert_kind_of DmsfFile, @file1 + assert_kind_of DmsfFile, @file12 + assert_kind_of DmsfFolder, @folder10 assert_kind_of Role, @role assert_kind_of User, @admin_user end - + def test_lock_file_already_locked_by_other log_user 'admin', 'admin' # login as admin User.current = @admin_user assert @file1.lock!, "File failed to be locked by #{User.current}" - process :lock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: - %{ - - - - jsmith - }, + process :lock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: @xml, headers: @jsmith.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite' }) assert_response :locked end - + def test_lock_file create_time = Time.utc(2000, 1, 2, 3, 4, 5) refresh_time = Time.utc(2000, 1, 2, 6, 7, 8) @@ -79,13 +87,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest # Time travel, will make the usec part of the time 0 travel_to create_time do # Lock file - xml = %{ - - - - jsmith - } - process :lock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: xml, + process :lock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: @xml, headers: @jsmith.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite' }) assert_response :success # Verify the response @@ -136,4 +138,23 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest end end + def test_lock_file_in_subproject + process :lock, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@file12.name}", params: @xml, + headers: @admin.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite' }) + assert_response :success + end + + def test_lock_folder_in_subproject + process :lock, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: @xml, + headers: @admin.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite' }) + assert_response :success + end + + def test_lock_subproject + process :lock, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}", params: @xml, + headers: @admin.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite' }) + assert_response :multi_status + assert_match 'HTTP/1.1 405 Method Not Allowed', response.body + end + end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_mkcol_test.rb b/test/integration/webdav/dmsf_webdav_mkcol_test.rb index 4de62f08..640bdff3 100644 --- a/test/integration/webdav/dmsf_webdav_mkcol_test.rb +++ b/test/integration/webdav/dmsf_webdav_mkcol_test.rb @@ -31,8 +31,13 @@ class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest @admin = credentials 'admin' @jsmith = credentials 'jsmith' @project1 = Project.find 1 + @project1.enable_module! :dmsf @project2 = Project.find 2 + @project3 = Project.find 3 + @project3.enable_module! :dmsf @role = Role.find_by(name: 'Manager') + @role.add_permission! :folder_manipulation + @role.add_permission! :view_dmsf_folders @folder6 = DmsfFolder.find 6 @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] Setting.plugin_redmine_dmsf['dmsf_webdav'] = true @@ -62,6 +67,7 @@ class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 + assert_kind_of Project, @project3 assert_kind_of Role, @role assert_kind_of DmsfFolder, @folder6 end @@ -82,36 +88,26 @@ class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest end def test_should_not_succed_on_a_non_dmsf_enabled_project + @project1.disable_module! :dmsf process :mkcol, "/dmsf/webdav/#{@project1.identifier}/folder", params: nil, headers: @jsmith - assert_response :forbidden + assert_response :not_found end def test_should_not_create_folder_without_permissions - @project1.enable_module! :dmsf # Flag module enabled + @role.remove_permission! :folder_manipulation process :mkcol, "/dmsf/webdav/#{@project1.identifier}/folder", params: nil, headers: @jsmith assert_response :forbidden end def test_should_fail_to_create_folder_that_already_exists - @project1.enable_module! :dmsf # Flag module enabled - @role.add_permission! :folder_manipulation - @role.add_permission! :view_dmsf_folders process :mkcol, "/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}", params: nil, headers: @jsmith assert_response :method_not_allowed end - def test_should_fail_to_create_folder_for_user_without_rights - @project1.enable_module! :dmsf # Flag module enabled - process :mkcol, "/dmsf/webdav/#{@project1.identifier}/test1", params: nil, headers: @jsmith - assert_response :forbidden - end - def test_should_create_folder_for_non_admin_user_with_rights - @project1.enable_module! :dmsf - @role.add_permission! :folder_manipulation process :mkcol, "/dmsf/webdav/#{@project1.identifier}/test1", params: nil, headers: @jsmith - assert_response :success # Created + assert_response :success Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true project1_uri = Addressable::URI.escape(RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)) process :mkcol, "/dmsf/webdav/#{@project1.identifier}/test2", params: nil, headers: @jsmith @@ -119,5 +115,11 @@ class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest process :mkcol, "/dmsf/webdav/#{project1_uri}/test3", params: nil, headers: @jsmith assert_response :success # Created end - + + def test_create_folder_in_subproject + process :mkcol, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/test1", params: nil, + headers: @admin + assert_response :success + end + end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_move_test.rb b/test/integration/webdav/dmsf_webdav_move_test.rb index 37782cad..dc05886a 100644 --- a/test/integration/webdav/dmsf_webdav_move_test.rb +++ b/test/integration/webdav/dmsf_webdav_move_test.rb @@ -40,9 +40,13 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest @project1.enable_module! :dmsf @project2 = Project.find 2 @project2.enable_module! :dmsf + @project3 = Project.find 3 + @project3.enable_module! :dmsf @file1 = DmsfFile.find 1 @file10 = DmsfFile.find 10 + @file12 = DmsfFile.find 12 @folder1 = DmsfFolder.find 1 + @folder10 = DmsfFolder.find 10 @role = Role.find 1 @role.add_permission! :view_dmsf_folders @role.add_permission! :folder_manipulation @@ -53,7 +57,6 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' @dmsf_webdav_use_project_names = Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = false - super end def teardown @@ -72,10 +75,13 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 + assert_kind_of Project, @project3 assert_kind_of Role, @role assert_kind_of DmsfFile, @file1 assert_kind_of DmsfFile, @file10 + assert_kind_of DmsfFile, @file12 assert_kind_of DmsfFolder, @folder1 + assert_kind_of DmsfFolder, @folder10 assert_kind_of User, @jsmith_user assert_kind_of User, @admin_user end @@ -227,7 +233,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest process :move, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, headers: @jsmith.merge!({ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{new_name}"}) - assert_response :not_implemented # NotImplemented + assert_response :not_implemented end end end @@ -347,5 +353,30 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest assert_response :success # Created end end - + + def test_move_file_in_subproject + assert_difference '@file12.dmsf_file_revisions.count', +1 do + process :move, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@file12.name}", params: nil, + headers: @admin.merge!({ + destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/new_file_name" }) + assert_response :created + end + end + + def test_move_folder_in_subproject + process :move, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: nil, + headers: @admin.merge!({ + destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/new_folder_name" }) + assert_response :created + @folder10.reload + assert_equal 'new_folder_name', @folder10.title + end + + def test_move_subproject + process :move, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}", params: nil, + headers: @admin.merge!({ + destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/new_project_name" }) + assert_response :method_not_allowed + end + end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_options_test.rb b/test/integration/webdav/dmsf_webdav_options_test.rb index 9efa51b0..140c9109 100644 --- a/test/integration/webdav/dmsf_webdav_options_test.rb +++ b/test/integration/webdav/dmsf_webdav_options_test.rb @@ -32,6 +32,8 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest @jsmith = credentials 'jsmith' @project1 = Project.find 1 @project2 = Project.find 2 + @project3 = Project.find 3 + @project3.enable_module! :dmsf @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] Setting.plugin_redmine_dmsf['dmsf_webdav'] = true @dmsf_webdav_strategy = Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] @@ -45,10 +47,11 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = @dmsf_webdav_strategy Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = @dmsf_webdav_use_project_names end - + def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 + assert_kind_of Project, @project3 end def test_options_requires_no_authentication_for_root_level @@ -177,4 +180,9 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest assert_response :not_found end + def test_options_for_subproject + process :options, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}", params: nil, headers: @admin + assert_response :success + end + end diff --git a/test/integration/webdav/dmsf_webdav_propfind_test.rb b/test/integration/webdav/dmsf_webdav_propfind_test.rb index cfe3631a..426ebcd2 100644 --- a/test/integration/webdav/dmsf_webdav_propfind_test.rb +++ b/test/integration/webdav/dmsf_webdav_propfind_test.rb @@ -30,16 +30,20 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest def setup @admin = credentials 'admin' - @jsmith = credentials 'jsmith' # Not a member of project1 - @project1 = Project.find 1 # DMSF enabled - @project2 = Project.find 2 # DMSF disabled - # Folders in project1 + @jsmith = credentials 'jsmith' + @project1 = Project.find 1 + @project1.enable_module! :dmsf + @project2 = Project.find 2 + @project2.enable_module! :dmsf + @project3 = Project.find 3 + @project3.enable_module! :dmsf @folder1 = DmsfFolder.find 1 @folder6 = DmsfFolder.find 6 - # Files in project1 + @folder10 = DmsfFolder.find 10 @file1 = DmsfFile.find 1 @file9 = DmsfFile.find 9 @file10 = DmsfFile.find 10 + @file12 = DmsfFile.find 12 @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] Setting.plugin_redmine_dmsf['dmsf_webdav'] = true @dmsf_webdav_strategy = Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] @@ -61,6 +65,14 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 + assert_kind_of Project, @project3 + assert_kind_of DmsfFolder, @folder1 + assert_kind_of DmsfFolder, @folder6 + assert_kind_of DmsfFolder, @folder10 + assert_kind_of DmsfFile, @file1 + assert_kind_of DmsfFile, @file9 + assert_kind_of DmsfFile, @file10 + assert_kind_of DmsfFile, @file12 end def test_propfind_denied_for_anonymous @@ -168,8 +180,7 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest end def test_propfind_depth1_on_root_for_admin - @project1.name = 'Online Cookbook' - @project1.save! + Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] = true project1_new_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) project1_new_uri = Addressable::URI.escape(project1_new_name) process :propfind, "/dmsf/webdav/#{project1_new_uri}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '1'}) @@ -178,4 +189,12 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest assert response.body.include?("#{project1_new_name}") end + def test_propfind_for_subproject + process :propfind, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}", params: nil, + headers: @admin.merge!({ HTTP_DEPTH: '1'}) + assert_response :multi_status + assert response.body.include?("http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/") + assert response.body.include?("#{@project3.identifier}") + end + end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_put_test.rb b/test/integration/webdav/dmsf_webdav_put_test.rb index 7993c03c..6e43cdd4 100644 --- a/test/integration/webdav/dmsf_webdav_put_test.rb +++ b/test/integration/webdav/dmsf_webdav_put_test.rb @@ -37,6 +37,8 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest @jsmith_user = User.find_by(login: 'jsmith') @project1 = Project.find 1 @project2 = Project.find 2 + @project3 = Project.find 3 + @project3.enable_module! :dmsf @role = Role.find_by(name: 'Manager') @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] Setting.plugin_redmine_dmsf['dmsf_webdav'] = true @@ -62,6 +64,7 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest def test_truth assert_kind_of Project, @project1 assert_kind_of Project, @project2 + assert_kind_of Project, @project3 assert_kind_of Role, @role assert_kind_of User, @jsmith_user end @@ -344,5 +347,12 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest end Setting.plugin_redmine_dmsf['dmsf_webdav_disable_versioning'] = original end + + def test_put_into_subproject + put "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/test-1234.txt", params: '1234', + headers: @admin.merge!({ content_type: :text }) + assert_response :created + assert DmsfFile.find_by(project_id: @project3.id, dmsf_folder: nil, name: 'test-1234.txt') + end end \ No newline at end of file diff --git a/test/integration/webdav/dmsf_webdav_unlock_test.rb b/test/integration/webdav/dmsf_webdav_unlock_test.rb new file mode 100644 index 00000000..b980bdae --- /dev/null +++ b/test/integration/webdav/dmsf_webdav_unlock_test.rb @@ -0,0 +1,143 @@ +# encoding: utf-8 +# frozen_string_literal: true +# +# Redmine plugin for Document Management System "Features" +# +# Copyright © 2012 Daniel Munn +# Copyright © 2011-20 Karel Pičman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.expand_path('../../../test_helper', __FILE__) +require 'fileutils' + +class DmsfWebdavUnlockTest < RedmineDmsf::Test::IntegrationTest + + fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles, + :enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions + + def setup + @admin = credentials 'admin' + @jsmith = credentials 'jsmith' + @admin_user = User.find_by(login: 'admin') + @jsmith_user = User.find_by(login: 'jsmith') + @project1 = Project.find 1 + @project1.enable_module! 'dmsf' + @project3 = Project.find 3 + @project3.enable_module! 'dmsf' + @file1 = DmsfFile.find 1 + @file12 = DmsfFile.find 12 + @folder1 = DmsfFolder.find 1 + @folder10 = DmsfFolder.find 10 + # Fix permissions for jsmith's role + @role = Role.find_by(name: 'Manager') + @role.add_permission! :view_dmsf_folders + @role.add_permission! :folder_manipulation + @role.add_permission! :view_dmsf_files + @role.add_permission! :file_manipulation + @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] + Setting.plugin_redmine_dmsf['dmsf_webdav'] = true + @dmsf_webdav_strategy = Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] + Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' + end + + def teardown + Setting.plugin_redmine_dmsf['dmsf_webdav'] = @dmsf_webdav + Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = @dmsf_webdav_strategy + end + + def test_truth + assert_kind_of Project, @project1 + assert_kind_of Project, @project3 + assert_kind_of DmsfFile, @file1 + assert_kind_of DmsfFile, @file12 + assert_kind_of DmsfFolder, @folder1 + assert_kind_of DmsfFolder, @folder10 + assert_kind_of Role, @role + assert_kind_of User, @admin_user + assert_kind_of User, @jsmith_user + end + + def test_unlock_file + log_user 'jsmith', 'jsmith' # login as jsmith + User.current = @jsmith_user + l = @file1.lock! + assert l, "File failed to be locked by #{User.current}" + process :unlock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, + headers: @jsmith.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite', HTTP_LOCK_TOKEN: l.uuid }) + assert_response :success + end + + def test_unlock_file_locked_by_someone_else + log_user 'jsmith', 'jsmith' # login as jsmith + User.current = @admin_user + l = @file1.lock! + assert l, "File failed to be locked by #{User.current}" + process :unlock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, + headers: @jsmith.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite', HTTP_LOCK_TOKEN: l.uuid }) + assert_response :forbidden + end + + def test_unlock_file_with_invalid_token + log_user 'jsmith', 'jsmith' # login as jsmith + User.current = @jsmith_user + l = @file1.lock! + assert l, "File failed to be locked by #{User.current}" + process :unlock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, + headers: @jsmith.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite', HTTP_LOCK_TOKEN: 'invalid_token' }) + assert_response :bad_request + end + + def test_unlock_file_not_locked + log_user 'jsmith', 'jsmith' # login as jsmith + User.current = @jsmith_user + l = @file1.lock! + @file1.unlock! + process :unlock, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, + headers: @jsmith.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite', HTTP_LOCK_TOKEN: l.uuid }) + assert_response :bad_request + end + + def test_unlock_folder + log_user 'jsmith', 'jsmith' # login as jsmith + User.current = @jsmith_user + l = @folder1.lock! + assert l, "Folder failed to be locked by #{User.current}" + process :unlock, "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", params: nil, + headers: @jsmith.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite', HTTP_LOCK_TOKEN: l.uuid }) + assert_response :success + end + + def test_unlock_file_in_subproject + log_user 'admin', 'admin' # login as admin + User.current = @admin_user + l = @file12.lock! + assert l, "File failed to be locked by #{User.current}" + process :unlock, "/dmsf/webdav/#{@project1.identifier}/#{@project1.identifier}/#{@file12.name}", params: nil, + headers: @admin.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite', HTTP_LOCK_TOKEN: l.uuid }) + assert_response :success + end + + def test_unlock_folder_in_subproject + log_user 'admin', 'admin' # login as admin + User.current = @admin_user + l = @folder10.lock! + assert l, "Folder failed to be locked by #{User.current}" + process :unlock, "/dmsf/webdav/#{@project1.identifier}/#{@project3.identifier}/#{@folder10.title}", params: nil, + headers: @admin.merge!({ HTTP_DEPTH: 'infinity', HTTP_TIMEOUT: 'Infinite', HTTP_LOCK_TOKEN: l.uuid }) + assert_response :success + end + +end \ No newline at end of file