Status 404 after moving the folder to another project #1106

This commit is contained in:
Karel Pičman 2020-04-23 10:13:06 +02:00
parent 0b750831d2
commit ecec07b520
23 changed files with 299 additions and 184 deletions

View File

@ -83,8 +83,6 @@ class DmsfContextMenusController < ApplicationController
def find_folder def find_folder
@folder = DmsfFolder.find params[:folder_id] if params[:folder_id].present? @folder = DmsfFolder.find params[:folder_id] if params[:folder_id].present?
rescue DmsfAccessError
render_403
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
render_404 render_404
end end

View File

@ -30,13 +30,13 @@ class DmsfController < ApplicationController
:autocomplete_for_user] :autocomplete_for_user]
before_action :find_parent, only: [:new, :create] before_action :find_parent, only: [:new, :create]
before_action :permissions before_action :permissions
# also try to lookup folder by title if this is API call # Also try to lookup folder by title if this is an API call
before_action :find_folder_by_title, only: [:show] before_action :find_folder_by_title, only: [:show]
before_action :get_query, only: [:expand_folder, :show, :trash] before_action :get_query, only: [:expand_folder, :show, :trash]
accept_api_auth :show, :create, :save, :delete accept_api_auth :show, :create, :save, :delete
helper :all # TODO: Is it needed? helper :custom_fields
helper :dmsf_folder_permissions helper :dmsf_folder_permissions
helper :queries helper :queries
include QueriesHelper include QueriesHelper
@ -48,7 +48,6 @@ class DmsfController < ApplicationController
def expand_folder def expand_folder
@idnt = params[:idnt].present? ? params[:idnt].to_i + 1 : 0 @idnt = params[:idnt].present? ? params[:idnt].to_i + 1 : 0
#@query = retrieve_query(DmsfQuery, true)
@query.dmsf_folder_id = @folder.id @query.dmsf_folder_id = @folder.id
@query.deleted = false @query.deleted = false
respond_to do |format| respond_to do |format|
@ -62,8 +61,6 @@ class DmsfController < ApplicationController
@folder_manipulation_allowed = User.current.allowed_to?(:folder_manipulation, @project) @folder_manipulation_allowed = User.current.allowed_to?(:folder_manipulation, @project)
@file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project) @file_manipulation_allowed = User.current.allowed_to?(:file_manipulation, @project)
@trash_enabled = @folder_manipulation_allowed && @file_manipulation_allowed @trash_enabled = @folder_manipulation_allowed && @file_manipulation_allowed
#use_session = !request.format.csv?
#@query = retrieve_query(DmsfQuery, use_session)
@query.dmsf_folder_id = @folder ? @folder.id : nil @query.dmsf_folder_id = @folder ? @folder.id : nil
@query.deleted = false @query.deleted = false
if (@folder && @folder.deleted?) || (params[:folder_title].present? && !@folder) if (@folder && @folder.deleted?) || (params[:folder_title].present? && !@folder)
@ -89,7 +86,6 @@ class DmsfController < ApplicationController
@folder_manipulation_allowed = User.current.allowed_to? :folder_manipulation, @project @folder_manipulation_allowed = User.current.allowed_to? :folder_manipulation, @project
@file_manipulation_allowed = User.current.allowed_to? :file_manipulation, @project @file_manipulation_allowed = User.current.allowed_to? :file_manipulation, @project
@file_delete_allowed = User.current.allowed_to? :file_delete, @project @file_delete_allowed = User.current.allowed_to? :file_delete, @project
#@query = retrieve_query(DmsfQuery, true)
@query.deleted = true @query.deleted = true
respond_to do |format| respond_to do |format|
format.html { format.html {
@ -604,9 +600,7 @@ class DmsfController < ApplicationController
end end
def find_folder def find_folder
@folder = DmsfFolder.find_by!(id: params[:folder_id], project_id: @project.id) if params[:folder_id].present? @folder = DmsfFolder.find(params[:folder_id]) if params[:folder_id].present?
rescue DmsfAccessError
render_403
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
render_404 render_404
end end

View File

@ -38,24 +38,22 @@ class DmsfFoldersCopyController < ApplicationController
def copy def copy
new_folder = @folder.copy_to(@target_project, @target_folder) new_folder = @folder.copy_to(@target_project, @target_folder)
unless new_folder.errors.empty? if new_folder.errors.empty?
flash[:notice] = l(:notice_successful_update)
redirect_to dmsf_folder_path(id: @target_project, folder_id: new_folder)
else
flash[:error] = new_folder.errors.full_messages.to_sentence flash[:error] = new_folder.errors.full_messages.to_sentence
redirect_to action: 'new', id: @folder, target_project_id: @target_project, target_folder_id: @target_folder redirect_to :back
return
end end
flash[:notice] = l(:notice_successful_update)
redirect_to dmsf_folder_path(id: @target_project, folder_id: new_folder)
end end
def move def move
@folder.project = @target_project if @folder.move_to(@target_project, @target_folder)
@folder.dmsf_folder = @target_folder
if @folder.save
flash[:notice] = l(:notice_successful_update) flash[:notice] = l(:notice_successful_update)
redirect_to dmsf_folder_path(id: @target_project, folder_id: @folder) redirect_to dmsf_folder_path(id: @target_project, folder_id: @folder)
else else
flash[:error] = @folder.errors.full_messages.to_sentence flash[:error] = @folder.errors.full_messages.to_sentence
redirect_to action: 'new', id: @folder, target_project_id: @target_project, target_folder_id: @target_folder redirect_to :back
end end
end end

View File

@ -155,7 +155,8 @@ class DmsfLinksController < ApplicationController
if params[:dmsf_link][:dmsf_file_id].present? if params[:dmsf_link][:dmsf_file_id].present?
redirect_to dmsf_file_path(@dmsf_link.target_file) redirect_to dmsf_file_path(@dmsf_link.target_file)
else else
redirect_to edit_dmsf_path(id: params[:dmsf_link][:project_id], folder_id: params[:dmsf_link][:dmsf_folder_id]) folder = @dmsf_link.target_folder.dmsf_folder if @dmsf_link.target_folder
redirect_to dmsf_folder_path(id: @project, folder_id: folder)
end end
end end
} }

View File

@ -235,8 +235,12 @@ class DmsfFile < ActiveRecord::Base
errors[:base] << l(:error_file_is_locked) errors[:base] << l(:error_file_is_locked)
return false return false
end end
unless last_revision
errors[:base] << l(:error_at_least_one_revision_must_be_present)
return false
end
source = "#{project.identifier}:#{dmsf_path_str}" source = "#{project.identifier}:#{dmsf_path_str}"
self.project_id = project.id self.project = project
self.dmsf_folder = folder self.dmsf_folder = folder
new_revision = last_revision.clone new_revision = last_revision.clone
new_revision.workflow = nil new_revision.workflow = nil
@ -251,12 +255,12 @@ class DmsfFile < ActiveRecord::Base
last_revision.custom_values.each do |cv| last_revision.custom_values.each do |cv|
new_revision.custom_values << CustomValue.new({ custom_field: cv.custom_field, value: cv.value }) new_revision.custom_values << CustomValue.new({ custom_field: cv.custom_field, value: cv.value })
end end
set_last_revision(new_revision) set_last_revision new_revision
save && new_revision.save save && new_revision.save
end end
def copy_to(project, folder = nil) def copy_to(project, folder = nil)
copy_to_filename(project, folder, name) copy_to_filename project, folder, name
end end
def copy_to_filename(project, folder, filename) def copy_to_filename(project, folder, filename)

View File

@ -247,6 +247,23 @@ class DmsfFolder < ActiveRecord::Base
projects projects
end end
def move_to(target_project, target_folder)
if self.project != target_project
dmsf_files.visible.find_each do |f|
f.move_to target_project, f.dmsf_folder
end
dmsf_folders.visible.find_each do |s|
s.move_to target_project, s.dmsf_folder
end
dmsf_links.visible.find_each do |l|
l.move_to target_project, l.dmsf_folder
end
self.project = target_project
end
self.dmsf_folder = target_folder
save
end
def copy_to(project, folder) def copy_to(project, folder)
new_folder = DmsfFolder.new new_folder = DmsfFolder.new
new_folder.dmsf_folder = folder ? folder : nil new_folder.dmsf_folder = folder ? folder : nil
@ -254,7 +271,6 @@ class DmsfFolder < ActiveRecord::Base
new_folder.title = title new_folder.title = title
new_folder.description = description new_folder.description = description
new_folder.user = User.current new_folder.user = User.current
new_folder.custom_values = [] new_folder.custom_values = []
custom_values.each do |cv| custom_values.each do |cv|
v = CustomValue.new v = CustomValue.new
@ -262,36 +278,22 @@ class DmsfFolder < ActiveRecord::Base
v.value = cv.value v.value = cv.value
new_folder.custom_values << v new_folder.custom_values << v
end end
unless new_folder.save unless new_folder.save
Rails.logger.error new_folder.errors.full_messages.to_sentence Rails.logger.error new_folder.errors.full_messages.to_sentence
return new_folder return new_folder
end end
dmsf_files.visible.find_each do |f| dmsf_files.visible.find_each do |f|
f.copy_to project, new_folder f.copy_to project, new_folder
end end
dmsf_folders.visible.find_each do |s| dmsf_folders.visible.find_each do |s|
s.copy_to project, new_folder s.copy_to project, new_folder
end end
dmsf_links.visible.find_each do |l|
folder_links.visible.find_each do |l|
l.copy_to project, new_folder l.copy_to project, new_folder
end end
file_links.visible.find_each do |l|
l.copy_to project, new_folder
end
url_links.visible.find_each do |l|
l.copy_to project, new_folder
end
dmsf_folder_permissions.find_each do |p| dmsf_folder_permissions.find_each do |p|
p.copy_to new_folder p.copy_to new_folder
end end
new_folder new_folder
end end

View File

@ -79,13 +79,6 @@ class DmsfLink < ActiveRecord::Base
@target_project @target_project
end end
def folder
if !@folder && dmsf_folder_id
@folder = DmsfFolder.find_by(id: dmsf_folder_id)
end
@folder
end
def title def title
name name
end end
@ -114,6 +107,12 @@ class DmsfLink < ActiveRecord::Base
path path
end end
def move_to(target_project, target_folder)
self.project = target_project
self.dmsf_folder = target_folder
save
end
def copy_to(project, folder) def copy_to(project, folder)
link = DmsfLink.new link = DmsfLink.new
link.target_project_id = target_project_id link.target_project_id = target_project_id
@ -128,8 +127,8 @@ class DmsfLink < ActiveRecord::Base
end end
def container def container
if folder && folder.system if dmsf_folder && dmsf_folder.system
Issue.find_by(id: folder.title) Issue.find_by id: dmsf_folder.title
end end
end end

View File

@ -189,9 +189,13 @@ class DmsfQuery < Query
joins('LEFT JOIN users ON dmsf_folders.user_id = users.id'). joins('LEFT JOIN users ON dmsf_folders.user_id = users.id').
visible(!deleted) visible(!deleted)
if deleted if deleted
scope.where(dmsf_folders: { project_id: project.id, deleted: deleted }) scope.where dmsf_folders: { project_id: project.id, deleted: deleted }
else else
scope.where(dmsf_folders: { project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted }) if dmsf_folder_id
scope.where dmsf_folders: { dmsf_folder_id: dmsf_folder_id, deleted: deleted }
else
scope.where dmsf_folders: { project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
end
end end
end end
@ -204,7 +208,7 @@ class DmsfQuery < Query
select(%{ select(%{
dmsf_links.id AS id, dmsf_links.id AS id,
COALESCE(dmsf_folders.project_id, dmsf_links.project_id) AS project_id, COALESCE(dmsf_folders.project_id, dmsf_links.project_id) AS project_id,
CAST(NULL AS #{ActiveRecord::Base.connection.type_to_sql(:decimal)}) AS revision_id, dmsf_links.target_id AS revision_id,
dmsf_links.name AS title, dmsf_links.name AS title,
dmsf_folders.title AS filename, dmsf_folders.title AS filename,
CAST(NULL AS #{ActiveRecord::Base.connection.type_to_sql(:decimal)}) AS size, CAST(NULL AS #{ActiveRecord::Base.connection.type_to_sql(:decimal)}) AS size,
@ -222,10 +226,13 @@ class DmsfQuery < Query
joins('LEFT JOIN dmsf_folders ON dmsf_links.target_id = dmsf_folders.id'). joins('LEFT JOIN dmsf_folders ON dmsf_links.target_id = dmsf_folders.id').
joins('LEFT JOIN users ON users.id = COALESCE(dmsf_folders.user_id, dmsf_links.user_id)') joins('LEFT JOIN users ON users.id = COALESCE(dmsf_folders.user_id, dmsf_links.user_id)')
if deleted if deleted
scope.where(dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, deleted: deleted }) scope.where dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, deleted: deleted }
else else
scope.where(dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, dmsf_folder_id: dmsf_folder_id, if dmsf_folder_id
deleted: deleted }) scope.where dmsf_links: { target_type: 'DmsfFolder', dmsf_folder_id: dmsf_folder_id, deleted: deleted }
else
scope.where dmsf_links: { target_type: 'DmsfFolder', project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
end
end end
end end
@ -257,9 +264,14 @@ class DmsfQuery < Query
joins('LEFT JOIN users ON dmsf_file_revisions.user_id = users.id '). joins('LEFT JOIN users ON dmsf_file_revisions.user_id = users.id ').
where('dmsf_file_revisions.created_at = (SELECT MAX(r.created_at) FROM dmsf_file_revisions r WHERE r.dmsf_file_id = dmsf_file_revisions.dmsf_file_id)') where('dmsf_file_revisions.created_at = (SELECT MAX(r.created_at) FROM dmsf_file_revisions r WHERE r.dmsf_file_id = dmsf_file_revisions.dmsf_file_id)')
if deleted if deleted
scope.where(dmsf_files: { project_id: project.id, deleted: deleted }) scope.where dmsf_files: { project_id: project.id, deleted: deleted }
else else
scope.where(dmsf_files: { project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted }) # Consider files belonging to the folder but with wrong project (#1106)
if dmsf_folder_id
scope.where dmsf_files: { dmsf_folder_id: dmsf_folder_id, deleted: deleted }
else
scope.where dmsf_files: { project_id: project.id, dmsf_folder_id: nil, deleted: deleted }
end
end end
end end
@ -272,7 +284,7 @@ class DmsfQuery < Query
select(%{ select(%{
dmsf_links.id AS id, dmsf_links.id AS id,
dmsf_files.project_id AS project_id, dmsf_files.project_id AS project_id,
dmsf_file_revisions.id AS revision_id, dmsf_files.id AS revision_id,
dmsf_links.name AS title, dmsf_links.name AS title,
dmsf_file_revisions.name AS filename, dmsf_file_revisions.name AS filename,
dmsf_file_revisions.size AS size, dmsf_file_revisions.size AS size,
@ -292,9 +304,13 @@ class DmsfQuery < Query
joins('LEFT JOIN users ON dmsf_file_revisions.user_id = users.id '). joins('LEFT JOIN users ON dmsf_file_revisions.user_id = users.id ').
where('dmsf_file_revisions.created_at = (SELECT MAX(r.created_at) FROM dmsf_file_revisions r WHERE r.dmsf_file_id = dmsf_file_revisions.dmsf_file_id)') where('dmsf_file_revisions.created_at = (SELECT MAX(r.created_at) FROM dmsf_file_revisions r WHERE r.dmsf_file_id = dmsf_file_revisions.dmsf_file_id)')
if deleted if deleted
scope.where(project_id: project.id, deleted: deleted) scope.where project_id: project.id, deleted: deleted
else else
scope.where(project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted) if dmsf_folder_id
scope.where dmsf_folder_id: dmsf_folder_id, deleted: deleted
else
scope.where project_id: project.id, dmsf_folder_id: nil, deleted: deleted
end
end end
end end
@ -324,9 +340,13 @@ class DmsfQuery < Query
1 AS sort #{cf_columns}}). 1 AS sort #{cf_columns}}).
joins('LEFT JOIN users ON dmsf_links.user_id = users.id ') joins('LEFT JOIN users ON dmsf_links.user_id = users.id ')
if deleted if deleted
scope.where(target_type: 'DmsfUrl', project_id: project.id, deleted: deleted) scope.where target_type: 'DmsfUrl', project_id: project.id, deleted: deleted
else else
scope.where(target_type: 'DmsfUrl', project_id: project.id, dmsf_folder_id: dmsf_folder_id, deleted: deleted) if dmsf_folder_id
scope.where target_type: 'DmsfUrl', dmsf_folder_id: dmsf_folder_id, deleted: deleted
else
scope.where target_type: 'DmsfUrl', project_id: project.id, dmsf_folder_id: nil, deleted: deleted
end
end end
end end

View File

@ -47,11 +47,6 @@
class: 'icon icon-email-add') %> class: 'icon icon-email-add') %>
<% end %> <% end %>
<% end %> <% end %>
<%= link_to(l(:label_link_to),
new_dmsf_link_path(project_id: @project.id, dmsf_folder_id: @folder.id, type: 'link_to'),
title: l(:title_create_link), class: 'icon icon-link') %>
<%= link_to("#{l(:button_copy)}/#{l(:button_move)}", copy_folder_path(id: @folder),
title: l(:title_copy), class: 'icon icon-copy') %>
<% unless @folder.locked? %> <% unless @folder.locked? %>
<%= link_to(l(:button_delete), delete_dmsf_path(id: @project, folder_id: @folder), <%= link_to(l(:button_delete), delete_dmsf_path(id: @project, folder_id: @folder),
data: { confirm: l(:text_are_you_sure) }, data: { confirm: l(:text_are_you_sure) },

View File

@ -25,7 +25,7 @@
<% html_title l(:dmsf) %> <% html_title l(:dmsf) %>
<div class="contextual"> <div class="contextual">
<% if @file_manipulation_allowed && !@locked_for_user && !@system_folder %> <% if @file_manipulation_allowed && !@locked_for_user && !@system_folder %>
<%= link_to l(:label_attachment_new), multi_dmsf_upload_path(id: @project, dmsf_folder_id: @folder), <%= link_to l(:label_attachment_new), multi_dmsf_upload_path(id: @project, folder_id: @folder),
class: 'icon icon-add' %> class: 'icon icon-add' %>
<% end %> <% end %>
<% if defined?(EasyExtensions) %> <% if defined?(EasyExtensions) %>

View File

@ -22,36 +22,40 @@
<li> <li>
<%= context_menu_link l(:button_edit), edit_dmsf_path(id: project, folder_id: dmsf_folder), <%= context_menu_link l(:button_edit), edit_dmsf_path(id: project, folder_id: dmsf_folder),
class: 'icon icon-edit', class: 'icon icon-edit', disabled: !allowed || locked %>
disabled: !allowed || locked %> </li>
<li>
<%= context_menu_link "#{l(:button_copy)}/#{l(:button_move)}", copy_folder_path(id: dmsf_folder),
class: 'icon icon-copy', disabled: !allowed || locked %>
</li>
<li>
<%= context_menu_link l(:label_link_to),
new_dmsf_link_path(project_id: project.id, dmsf_folder_id: dmsf_folder.id, type: 'link_to'),
class: 'icon icon-link', disabled: !allowed || locked %>
</li> </li>
<li> <li>
<% if locked %> <% if locked %>
<%= context_menu_link l(:button_unlock), unlock_dmsf_path(id: project, folder_id: dmsf_folder), <%= context_menu_link l(:button_unlock), unlock_dmsf_path(id: project, folder_id: dmsf_folder),
class: 'icon icon-unlock', class: 'icon icon-unlock', disabled: !allowed || !unlockable %>
disabled: !allowed || !unlockable %>
<% else %> <% else %>
<%= context_menu_link l(:button_lock), lock_dmsf_path(id: project, folder_id: dmsf_folder), <%= context_menu_link l(:button_lock), lock_dmsf_path(id: project, folder_id: dmsf_folder),
class: 'icon icon-lock', class: 'icon icon-lock', disabled: !allowed %>
disabled: !allowed %>
<% end %> <% end %>
</li> </li>
<li> <li>
<% if dmsf_folder.notification %> <% if dmsf_folder.notification %>
<%= context_menu_link l(:label_notifications_off), notify_deactivate_dmsf_path(id: project, folder_id: dmsf_folder), <%= context_menu_link l(:label_notifications_off), notify_deactivate_dmsf_path(id: project, folder_id: dmsf_folder),
class: 'icon icon-email', class: 'icon icon-email', disabled: !allowed || locked || !dmsf_folder.notification? %>
disabled: !allowed || locked || !dmsf_folder.notification? %>
<% else %> <% else %>
<%= context_menu_link l(:label_notifications_on), notify_activate_dmsf_path(id: project, folder_id: dmsf_folder), <%= context_menu_link l(:label_notifications_on), notify_activate_dmsf_path(id: project, folder_id: dmsf_folder),
class: 'icon icon-email-add', class: 'icon icon-email-add', disabled: !allowed || locked || dmsf_folder.notification? %>
disabled: !allowed || locked || dmsf_folder.notification? %>
<% end %> <% end %>
</li> </li>
<li> <li>
<%= context_menu_link l(:button_delete), <%= context_menu_link l(:button_delete),
dmsf_link ? dmsf_link_path(dmsf_link) : delete_dmsf_path(id: project, folder_id: dmsf_folder), dmsf_link ? dmsf_link_path(dmsf_link) : delete_dmsf_path(id: project, folder_id: dmsf_folder),
data: { confirm: l(:text_are_you_sure) }, method: :delete, class: 'icon icon-del', id: 'dmsf-cm-delete', data: { confirm: l(:text_are_you_sure) }, method: :delete, class: 'icon icon-del', id: 'dmsf-cm-delete',
disabled: !allowed || locked || !dmsf_folder.empty? %> disabled: !allowed || locked || (dmsf_link ? false : !dmsf_folder.empty?) %>
</li> </li>
<li> <li>
<%= context_menu_link l(:button_download), entries_operations_dmsf_path(id: project, folder_id: folder, <%= context_menu_link l(:button_download), entries_operations_dmsf_path(id: project, folder_id: folder,

View File

@ -32,8 +32,8 @@
<div class="box tabular"> <div class="box tabular">
<% if (@type == 'link_from') && !@container %> <% if (@type == 'link_from') && !@container %>
<p> <p>
<%= radio_button_tag(:external_link, 'false', true) %> <%= l(:label_internal) %><br/> <%= radio_button_tag :external_link, 'false', true %> <%= l(:label_internal) %><br/>
<%= radio_button_tag(:external_link, 'true', false) %> <%= l(:label_external) %> <%= radio_button_tag :external_link, 'true', false %> <%= l(:label_external) %>
</p> </p>
<% end %> <% end %>
<div id="dmsf_link_internal"> <div id="dmsf_link_internal">
@ -44,9 +44,9 @@
<% else %> <% else %>
<label for="dmsf_link[target_project_id]"><%= l(:label_target_project) %></label> <label for="dmsf_link[target_project_id]"><%= l(:label_target_project) %></label>
<% end %> <% end %>
<%= select_tag('dmsf_link[target_project_id]', <%= select_tag 'dmsf_link[target_project_id]',
project_tree_options_for_select(DmsfFile.allowed_target_projects_on_copy, project_tree_options_for_select(DmsfFile.allowed_target_projects_on_copy,
selected: @dmsf_link.target_project)) %> selected: @dmsf_link.target_project) %>
<%= late_javascript_tag do %> <%= late_javascript_tag do %>
$('#dmsf_link_target_project_id').change(function(){ $('#dmsf_link_target_project_id').change(function(){
$.ajax({ $.ajax({
@ -60,7 +60,7 @@
<% end %> <% end %>
<p> <p>
<% if @type == 'link_from' %> <% if @type == 'link_from' %>
<%= label_tag('dmsf_link[target_folder_id]', l(:label_source_folder)) %> <%= label_tag 'dmsf_link[target_folder_id]', l(:label_source_folder) %>
<% else %> <% else %>
<label for="dmsf_link_target_folder_id"> <label for="dmsf_link_target_folder_id">
<%= l(:label_target_folder) %> <%= ' #' if @fast_links %> <%= l(:label_target_folder) %> <%= ' #' if @fast_links %>
@ -71,9 +71,8 @@
<% end %> <% end %>
<% end %> <% end %>
<% if !@fast_links || (@type != 'link_to') %> <% if !@fast_links || (@type != 'link_to') %>
<%= select_tag('dmsf_link[target_folder_id]', <%= select_tag 'dmsf_link[target_folder_id]',
folder_tree_options_for_select(DmsfFolder.directory_tree(@dmsf_link.target_project), folder_tree_options_for_select(DmsfFolder.directory_tree(@dmsf_link.target_project)) %>
selected: @target_folder_id)) %>
<%= late_javascript_tag do %> <%= late_javascript_tag do %>
$('#dmsf_link_target_folder_id').change(function(){ $('#dmsf_link_target_folder_id').change(function(){
$.ajax({ $.ajax({
@ -87,10 +86,9 @@
</p> </p>
<% if @type == 'link_from' %> <% if @type == 'link_from' %>
<p> <p>
<%= label_tag('dmsf_link[target_file_id]', l(:field_target_file)) %> <%= label_tag 'dmsf_link[target_file_id]', l(:field_target_file) %>
<% files = files_for_select(@dmsf_link.target_project.id, @target_folder_id) %> <% files = files_for_select(@dmsf_link.target_project.id, @target_folder_id) %>
<%= select_tag('dmsf_link[target_file_id]', <%= select_tag 'dmsf_link[target_file_id]', options_for_select(DmsfFolder.file_list(files)), required: modal %>
options_for_select(DmsfFolder.file_list(files)), required: modal) %>
</p> </p>
<% end %> <% end %>
</div> </div>

View File

@ -72,6 +72,7 @@ if Redmine::Plugin.installed? :redmine_dmsf
get '/projects/:id/dmsf/upload/multi_upload', controller: 'dmsf_upload', action: 'multi_upload', as: 'multi_dmsf_upload' get '/projects/:id/dmsf/upload/multi_upload', controller: 'dmsf_upload', action: 'multi_upload', as: 'multi_dmsf_upload'
post '/projects/:id/dmsf/upload/files', controller: 'dmsf_upload', action: 'upload_files' post '/projects/:id/dmsf/upload/files', controller: 'dmsf_upload', action: 'upload_files'
get '/projects/:id/dmsf/upload/files', controller: 'dmsf_upload', action: 'upload_files'
post '/projects/:id/dmsf/upload/file', controller: 'dmsf_upload', action: 'upload_file' post '/projects/:id/dmsf/upload/file', controller: 'dmsf_upload', action: 'upload_file'
post '/projects/:id/dmsf/upload', controller: 'dmsf_upload', action: 'upload' post '/projects/:id/dmsf/upload', controller: 'dmsf_upload', action: 'upload'
post '/projects/:id/dmsf/upload/commit', controller: 'dmsf_upload', action: 'commit_files' post '/projects/:id/dmsf/upload/commit', controller: 'dmsf_upload', action: 'commit_files'

View File

@ -0,0 +1,28 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features"
#
# Copyright © 2011-20 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.
class AddIndexesOnDmsfFolderId < ActiveRecord::Migration[5.2]
def change
add_index :dmsf_files, :dmsf_folder_id
add_index :dmsf_links, :dmsf_folder_id
end
end

View File

@ -76,7 +76,7 @@ module RedmineDmsf
else else
tag = "<span class=\"dmsf_expander\" onclick=\"dmsfToggle('#{item.id}','#{item.id}span','#{escape_javascript(expand_folder_dmsf_path)}')\"></span>".html_safe + tag = "<span class=\"dmsf_expander\" onclick=\"dmsfToggle('#{item.id}','#{item.id}span','#{escape_javascript(expand_folder_dmsf_path)}')\"></span>".html_safe +
link_to(h(value), link_to(h(value),
dmsf_folder_path(id: item.project_id, folder_id: item.id), dmsf_folder_path(id: item.project, folder_id: item.id),
class: 'icon icon-folder', class: 'icon icon-folder',
title: h(value)) title: h(value))
end end
@ -86,8 +86,9 @@ module RedmineDmsf
tag = content_tag('span', value, class: 'icon icon-folder') tag = content_tag('span', value, class: 'icon icon-folder')
else else
tag = "<span class=\"dmsf_expander\"></span>".html_safe + tag = "<span class=\"dmsf_expander\"></span>".html_safe +
# For links we use revision_id containing dmsf_folder.id in fact
link_to(h(value), link_to(h(value),
dmsf_folder_path(id: item.project_id, folder_id: item.id), dmsf_folder_path(id: item.project, folder_id: item.revision_id),
class: 'icon icon-folder', class: 'icon icon-folder',
title: h(value)) title: h(value))
end end
@ -96,7 +97,8 @@ module RedmineDmsf
if item.deleted && (item.deleted > 0) if item.deleted && (item.deleted > 0)
tag = content_tag('span', value, class: "icon icon-file #{DmsfHelper.filetype_css(item.filename)}") tag = content_tag('span', value, class: "icon icon-file #{DmsfHelper.filetype_css(item.filename)}")
else else
file_view_url = url_for({ controller: :dmsf_files, action: 'view', id: item.id }) # For links we use revision_id containing dmsf_file.id in fact
file_view_url = url_for({ controller: :dmsf_files, action: 'view', id: (item.type == 'file') ? item.id : item.revision_id })
content_type = Redmine::MimeType.of(value) content_type = Redmine::MimeType.of(value)
content_type = 'application/octet-stream' if content_type.blank? content_type = 'application/octet-stream' if content_type.blank?
tag = "<span class=\"dmsf_expander\"></span>".html_safe + tag = "<span class=\"dmsf_expander\"></span>".html_safe +

View File

@ -31,7 +31,7 @@ module RedmineDmsf
def initialize(path, request, response, options) def initialize(path, request, response, options)
@folder = nil @folder = nil
@file = nil @file = nil
super(path, request, response, options) super path, request, response, options
end end
# Here we make sure our folder and file methods are not aliased - it should shave a few cycles off of processing # Here we make sure our folder and file methods are not aliased - it should shave a few cycles off of processing
@ -227,64 +227,52 @@ module RedmineDmsf
resource = dest.is_a?(ResourceProxy) ? dest.resource : dest resource = dest.is_a?(ResourceProxy) ? dest.resource : dest
return PreconditionFailed if !resource.is_a?(DmsfResource) || resource.project.nil? return PreconditionFailed if !resource.is_a?(DmsfResource) || resource.project.nil?
parent = resource.parent parent = resource.parent
raise Forbidden unless (!parent.exist? || !parent.folder || DmsfFolder.permissions?(parent.folder, false)) if !parent.exist? || (!User.current.admin? && (!DmsfFolder.permissions?(folder, false) ||
!DmsfFolder.permissions?(parent.folder, false)))
raise Forbidden
end
if collection? if collection?
if dest.exist? if dest.exist?
return overwrite ? NotImplemented : PreconditionFailed return overwrite ? NotImplemented : PreconditionFailed
end end
if !User.current.admin? && (!User.current.allowed_to?(:folder_manipulation, project) ||
# At the moment we don't support cross project destinations !User.current.allowed_to?(:folder_manipulation, resource.project))
return NotImplemented unless (project.id == resource.project.id) raise Forbidden
raise Forbidden unless User.current.admin? || User.current.allowed_to?(:folder_manipulation, project) end
raise Forbidden unless DmsfFolder.permissions?(folder, false)
# Current object is a folder, so now we need to figure out information about Destination # Current object is a folder, so now we need to figure out information about Destination
if dest.exist? if dest.exist?
return overwrite ? NotImplemented : PreconditionFailed return overwrite ? NotImplemented : PreconditionFailed
else else
if parent.projectless_path == '/' # Project root folder.move_to(resource.project, parent.folder) ? Created : PreconditionFailed
folder.dmsf_folder_id = nil
else
return PreconditionFailed unless parent.exist? && parent.folder
folder.dmsf_folder_id = parent.folder.id
end
folder.title = resource.basename
folder.save ? Created : PreconditionFailed
end end
else else
raise Forbidden unless User.current.admin? || if !User.current.admin? && (!User.current.allowed_to?(:file_manipulation, project) ||
User.current.allowed_to?(:folder_manipulation, project) || !User.current.allowed_to?(:file_manipulation, resource.project))
User.current.allowed_to?(:folder_manipulation, resource.project) raise Forbidden
end
if dest.exist? if dest.exist?
return PreconditionFailed unless overwrite return PreconditionFailed unless overwrite
if (project == resource.project) && file.name.match(/.\.tmp$/i) if (project == resource.project) && file.name.match(/.\.tmp$/i)
# Renaming a *.tmp file to an existing file in the same project, probably Office that is saving a file. # Renaming a *.tmp file to an existing file in the same project, probably Office that is saving a file.
Rails.logger.info "WebDAV MOVE: #{file.name} -> #{resource.basename} (exists), possible MSOffice rename from .tmp when saving" Rails.logger.info "WebDAV MOVE: #{file.name} -> #{resource.basename} (exists), possible MSOffice rename from .tmp when saving"
if resource.file.last_revision.size == 0 || reuse_version_for_locked_file(resource.file) if resource.file.last_revision.size == 0 || reuse_version_for_locked_file(resource.file)
# Last revision in the destination has zero size so reuse that revision # Last revision in the destination has zero size so reuse that revision
new_revision = resource.file.last_revision new_revision = resource.file.last_revision
else else
# Create a new revison by cloning the last revision in the destination # Create a new revison by cloning the last revision in the destination
new_revision = resource.file.last_revision.clone new_revision = resource.file.last_revision.clone
new_revision.increase_version(1) new_revision.increase_version 1
end end
# The file on disk must be renamed from .tmp to the correct filetype or else Xapian won't know how to index. # The file on disk must be renamed from .tmp to the correct filetype or else Xapian won't know how to index.
# Copy file.last_revision.disk_file to new_revision.disk_file # Copy file.last_revision.disk_file to new_revision.disk_file
new_revision.size = file.last_revision.size new_revision.size = file.last_revision.size
new_revision.disk_filename = new_revision.new_storage_filename new_revision.disk_filename = new_revision.new_storage_filename
Rails.logger.info "WebDAV MOVE: Copy file #{file.last_revision.disk_filename} -> #{new_revision.disk_filename}" Rails.logger.info "WebDAV MOVE: Copy file #{file.last_revision.disk_filename} -> #{new_revision.disk_filename}"
File.open(file.last_revision.disk_file, 'rb') do |f| File.open(file.last_revision.disk_file, 'rb') do |f|
new_revision.copy_file_content(f) new_revision.copy_file_content f
end end
# Save # Save
new_revision.save && resource.file.save new_revision.save && resource.file.save
# Delete (and destroy) the file that should have been renamed and return what should have been returned in case of a copy # Delete (and destroy) the file that should have been renamed and return what should have been returned in case of a copy
file.delete(true) ? Created : PreconditionFailed file.delete(true) ? Created : PreconditionFailed
else else
@ -300,11 +288,10 @@ module RedmineDmsf
f = parent.folder f = parent.folder
end end
return PreconditionFailed unless exist? && file return PreconditionFailed unless exist? && file
if (project == resource.project) && resource.basename.match(/.\.tmp$/i) if (project == resource.project) && resource.basename.match(/.\.tmp$/i)
Rails.logger.info "WebDAV MOVE: #{file.name} -> #{resource.basename}, possible MSOffice rename to .tmp when saving." Rails.logger.info "WebDAV MOVE: #{file.name} -> #{resource.basename}, possible MSOffice rename to .tmp when saving."
# Renaming the file to X.tmp, might be Office that is saving a file. Keep the original file. # Renaming the file to X.tmp, might be Office that is saving a file. Keep the original file.
file.copy_to_filename(resource.project, f, resource.basename) file.copy_to_filename resource.project, f, resource.basename
Created Created
else else
if (project == resource.project) && (file.last_revision.size == 0) if (project == resource.project) && (file.last_revision.size == 0)
@ -313,14 +300,12 @@ module RedmineDmsf
else else
return InternalServerError unless file.move_to(resource.project, f) return InternalServerError unless file.move_to(resource.project, f)
end end
# Update Revision and names of file [We can link to old physical resource, as it's not changed] # Update Revision and names of file [We can link to old physical resource, as it's not changed]
if file.last_revision if file.last_revision
file.last_revision.name = resource.basename file.last_revision.name = resource.basename
file.last_revision.title = DmsfFileRevision.filename_to_title(resource.basename) file.last_revision.title = DmsfFileRevision.filename_to_title(resource.basename)
end end
file.name = resource.basename file.name = resource.basename
# Save Changes # Save Changes
(file.last_revision.save && file.save) ? Created : PreconditionFailed (file.last_revision.save && file.save) ? Created : PreconditionFailed
end end

View File

@ -190,3 +190,25 @@ dmsf_file_revisions_009:
dmsf_workflow_assigned_by_user_id: NULL dmsf_workflow_assigned_by_user_id: NULL
dmsf_workflow_started_by_user_id: NULL dmsf_workflow_started_by_user_id: NULL
created_at: 2017-04-18 14:52:27 +02:00 created_at: 2017-04-18 14:52:27 +02:00
dmsf_file_revisions_010:
id: 10
dmsf_file_id: 5
source_dmsf_file_revision_id: NULL
name: "test.txt"
disk_filename: "test.txt"
size: 4
mime_type: text/plain
title: "Test File"
description: 'Some file :-)'
workflow: 1 # DmsfWorkflow::STATE_WAITING_FOR_APPROVAL
minor_version: 0
major_version: 1
comment: NULL
deleted: 0
deleted_by_user_id: NULL
user_id: 1
dmsf_workflow_assigned_by_user_id: 1
dmsf_workflow_started_by_user_id: 1
digest: '81dc9bdb52d04dc20036dbd8313ed055'
created_at: 2017-04-18 14:52:27 +02:00

View File

@ -253,9 +253,10 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
def test_show_folder_doesnt_correspond_the_project def test_show_folder_doesnt_correspond_the_project
@role.add_permission! :view_dmsf_files @role.add_permission! :view_dmsf_files
@role.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
# project1 X project2.folder3 # Despite the fact that project != @folder3.project
assert @project != @folder3.project
get :show, params: { id: @project.id, folder_id: @folder3.id } get :show, params: { id: @project.id, folder_id: @folder3.id }
assert_response :not_found assert_response :success
end end
def test_new_forbidden def test_new_forbidden

View File

@ -170,6 +170,12 @@ class DmsfFoldersCopyControllerTest < RedmineDmsf::Test::TestCase
assert_nil flash[:error] assert_nil flash[:error]
end end
def test_move_to_another_project
post :move, params: { id: @folder1.id, target_project_id: @project2.id, target_folder_id: 'Documents' }
assert_response :redirect
assert_nil flash[:error]
end
def test_move_the_same_target def test_move_the_same_target
post :move, params: { id: @folder1.id, target_project_id: @folder1.project.id, target_folder_id: @folder1.dmsf_folder } post :move, params: { id: @folder1.id, target_project_id: @folder1.project.id, target_folder_id: @folder1.dmsf_folder }
assert_equal flash[:error], l(:error_target_folder_same) assert_equal flash[:error], l(:error_target_folder_same)

View File

@ -322,7 +322,7 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
type: 'link_to' type: 'link_to'
}} }}
end end
assert_redirected_to edit_dmsf_path(id: @project1.id, folder_id: @folder1.id) assert_redirected_to dmsf_folder_path(id: @project1, folder_id: @folder1.dmsf_folder)
end end
def test_create_folder_link_to_f2 def test_create_folder_link_to_f2
@ -337,7 +337,7 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
type: 'link_to' type: 'link_to'
}} }}
end end
assert_redirected_to edit_dmsf_path(id: @project1.id, folder_id: @folder1.id) assert_redirected_to dmsf_folder_path(id: @project1, folder_id: @folder1.dmsf_folder)
end end
def test_destroy def test_destroy

View File

@ -37,13 +37,16 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
@jsmith_user = User.find_by(login: 'jsmith') @jsmith_user = User.find_by(login: 'jsmith')
@admin_user = User.find_by(login: 'admin') @admin_user = User.find_by(login: 'admin')
@project1 = Project.find 1 @project1 = Project.find 1
@project1.enable_module! :dmsf
@project2 = Project.find 2
@project2.enable_module! :dmsf
@file1 = DmsfFile.find 1 @file1 = DmsfFile.find 1
@file10 = DmsfFile.find 10 @file10 = DmsfFile.find 10
@folder1 = DmsfFolder.find 1 @folder1 = DmsfFolder.find 1
# Fix permissions for jsmith's role @role = Role.find 1
@role = Role.find 1 #
@role.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role.add_permission! :folder_manipulation @role.add_permission! :folder_manipulation
@role.add_permission! :file_manipulation
@dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav'] @dmsf_webdav = Setting.plugin_redmine_dmsf['dmsf_webdav']
Setting.plugin_redmine_dmsf['dmsf_webdav'] = true Setting.plugin_redmine_dmsf['dmsf_webdav'] = true
@dmsf_webdav_strategy = Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] @dmsf_webdav_strategy = Setting.plugin_redmine_dmsf['dmsf_webdav_strategy']
@ -68,6 +71,7 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
def test_truth def test_truth
assert_kind_of Project, @project1 assert_kind_of Project, @project1
assert_kind_of Project, @project2
assert_kind_of Role, @role assert_kind_of Role, @role
assert_kind_of DmsfFile, @file1 assert_kind_of DmsfFile, @file1
assert_kind_of DmsfFile, @file10 assert_kind_of DmsfFile, @file10
@ -85,8 +89,8 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
end end
end end
def test_move_to_new_filename_without_folder_manipulation_permission def test_move_to_new_filename_without_file_manipulation_permission
@role.remove_permission! :folder_manipulation @role.remove_permission! :file_manipulation
new_name = "#{@file1.name}.moved" new_name = "#{@file1.name}.moved"
assert_no_difference '@file1.dmsf_file_revisions.count' do assert_no_difference '@file1.dmsf_file_revisions.count' do
process :move, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, process :move, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil,
@ -95,8 +99,8 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
end end
end end
def test_move_to_new_filename_without_folder_manipulation_permission_as_admin def test_move_to_new_filename_without_file_manipulation_permission_as_admin
@role.remove_permission! :folder_manipulation @role.remove_permission! :file_manipulation
new_name = "#{@file1.name}.moved" new_name = "#{@file1.name}.moved"
assert_difference '@file1.dmsf_file_revisions.count', +1 do assert_difference '@file1.dmsf_file_revisions.count', +1 do
process :move, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil, process :move, "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", params: nil,
@ -107,6 +111,37 @@ class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
end end
end end
def test_without_folder_manipulation_permission
@role.remove_permission! :folder_manipulation
new_name = "#{@folder1.title}.moved"
process :move, "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", params: nil,
headers: @jsmith.merge!({ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{new_name}" })
assert_response :forbidden
end
def test_without_folder_manipulation_permission_as_admin
@role.remove_permission! :folder_manipulation
new_name = "#{@folder1.title}.moved"
process :move, "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", params: nil,
headers: @admin.merge!({ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{new_name}" })
assert_response :created
end
def test_move_folder_to_another_project
process :move, "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", params: nil,
headers: @admin.merge!({ destination: "http://www.example.com/dmsf/webdav/#{@project2.identifier}/#{@folder1.title}" })
assert_response :created
@folder1.dmsf_folders.each do |d|
assert_equal @project2, d.project
end
@folder1.dmsf_files.each do |f|
assert_equal @project2, f.project
end
@folder1.dmsf_links.each do |l|
assert_equal @project2, l.project
end
end
def test_move_non_existent_file def test_move_non_existent_file
process :move, "/dmsf/webdav/#{@project1.identifier}/not_a_file.txt", params: nil, process :move, "/dmsf/webdav/#{@project1.identifier}/not_a_file.txt", params: nil,
headers: @jsmith.merge!({ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/moved_file.txt" }) headers: @jsmith.merge!({ destination: "http://www.example.com/dmsf/webdav/#{@project1.identifier}/moved_file.txt" })

View File

@ -27,8 +27,10 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest
:dmsf_folder_permissions :dmsf_folder_permissions
def setup def setup
@project = Project.find 1 @project1 = Project.find 1
@project.enable_module! :dmsf @project1.enable_module! :dmsf
@project2 = Project.find 2
@project2.enable_module! :dmsf
@folder1 = DmsfFolder.find 1 @folder1 = DmsfFolder.find 1
@folder2 = DmsfFolder.find 2 @folder2 = DmsfFolder.find 2
@folder4 = DmsfFolder.find 4 @folder4 = DmsfFolder.find 4
@ -51,7 +53,8 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest
assert_kind_of DmsfFolder, @folder5 assert_kind_of DmsfFolder, @folder5
assert_kind_of DmsfFolder, @folder6 assert_kind_of DmsfFolder, @folder6
assert_kind_of DmsfFolder, @folder7 assert_kind_of DmsfFolder, @folder7
assert_kind_of Project, @project assert_kind_of Project, @project1
assert_kind_of Project, @project2
assert_kind_of User, @manager assert_kind_of User, @manager
assert_kind_of User, @developer assert_kind_of User, @developer
assert_kind_of Role, @manager_role assert_kind_of Role, @manager_role
@ -69,7 +72,7 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest
assert_equal 4, DmsfFolder.visible.where(project_id: 1).all.size assert_equal 4, DmsfFolder.visible.where(project_id: 1).all.size
# Anonymous user # Anonymous user
User.current = User.anonymous User.current = User.anonymous
@project.add_default_member User.anonymous @project1.add_default_member User.anonymous
assert_equal 5, DmsfFolder.visible.where(project_id: 1).all.size assert_equal 5, DmsfFolder.visible.where(project_id: 1).all.size
end end
@ -145,7 +148,7 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest
end end
def test_directory_tree def test_directory_tree
tree = DmsfFolder.directory_tree(@project) tree = DmsfFolder.directory_tree(@project1)
assert tree assert tree
# [["Documents", nil], # [["Documents", nil],
# ["...folder7", 7], # ["...folder7", 7],
@ -157,7 +160,7 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest
end end
def test_directory_tree_id def test_directory_tree_id
tree = DmsfFolder.directory_tree(@project.id) tree = DmsfFolder.directory_tree(@project1.id)
assert tree assert tree
# [["Documents", nil], # [["Documents", nil],
# ["...folder7", 7], # ["...folder7", 7],
@ -193,4 +196,23 @@ class DmsfFolderTest < RedmineDmsf::Test::UnitTest
assert_equal 1, users.size assert_equal 1, users.size
end end
def test_move_to
assert @folder1.move_to(@project2, nil)
assert_equal @project2, @folder1.project
@folder1.dmsf_folders.each do |d|
assert_equal @project2, d.project
end
@folder1.dmsf_files.each do |f|
assert_equal @project2, f.project
end
@folder1.dmsf_links.each do |l|
assert_equal @project2, l.project
end
end
def test_copy_to
assert @folder1.copy_to(@project2, nil)
assert DmsfFolder.find_by_title(@project2, nil, @folder1.title)
end
end end

View File

@ -163,8 +163,8 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
end end
def test_folder def test_folder
assert_equal @folder1, @file_link.folder assert_equal @folder1, @file_link.dmsf_folder
assert_nil @folder_link.folder assert_nil @folder_link.dmsf_folder
end end
def test_title def test_title
@ -174,7 +174,7 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
def test_find_link_by_file_name def test_find_link_by_file_name
file_link = DmsfLink.find_link_by_file_name(@file_link.project, file_link = DmsfLink.find_link_by_file_name(@file_link.project,
@file_link.folder, @file_link.target_file.name) @file_link.dmsf_folder, @file_link.target_file.name)
assert file_link, 'File link not found by its name' assert file_link, 'File link not found by its name'
end end