Validation

This commit is contained in:
Karel Picman 2016-02-01 15:31:39 +01:00
parent a3d227796c
commit a5ab3ed8fd
34 changed files with 1098 additions and 1005 deletions

View File

@ -148,6 +148,7 @@ class DmsfFile < ActiveRecord::Base
save save
end end
rescue Exception => e rescue Exception => e
Rails.logger.error e.message
errors[:base] << e.message errors[:base] << e.message
return false return false
end end

View File

@ -4,7 +4,7 @@
# #
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com> # Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontorn.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontorn.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License

View File

@ -87,9 +87,8 @@ module RedmineDmsf
def locked_for_user? def locked_for_user?
return false unless locked? return false unless locked?
b_shared = nil b_shared = nil
heirarchy = self.dmsf_path self.dmsf_path.each do |entity|
heirarchy.each do |folder| locks = entity.locks || entity.lock(false)
locks = folder.locks || folder.lock(false)
next if locks.empty? next if locks.empty?
locks.each do |lock| locks.each do |lock|
next if lock.expired? # In case we're in between updates next if lock.expired? # In case we're in between updates

View File

@ -1,8 +1,9 @@
# Redmine plugin for Document Management System "Features" # encoding: utf-8
## Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com> # Copyright (C) 2011 Vít Jonáš <vit.jonas@gmail.com>
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -20,11 +21,11 @@
module RedmineDmsf module RedmineDmsf
module Test module Test
class IntegrationTest < ActionController::IntegrationTest class IntegrationTest < Redmine::IntegrationTest
def self.fixtures(*table_names) def self.fixtures(*table_names)
dir = File.join( File.dirname(__FILE__), '../../../test/fixtures') dir = File.join( File.dirname(__FILE__), '../../../test/fixtures')
table_names.each do |x| table_names.each do |x|
ActiveRecord::Fixtures.create_fixtures(dir, x) if File.exist?("#{dir}/#{x}.yml") ActiveRecord::FixtureSet.create_fixtures(dir, x) if File.exist?("#{dir}/#{x}.yml")
end end
super(table_names) super(table_names)
end end

View File

@ -138,17 +138,20 @@ table { width:100%%; }
File.dirname(path) File.dirname(path)
end end
#return instance of Project based on path # Return instance of Project based on path
def project def project
return @Project unless @Project.nil? unless @project
pinfo = @path.split('/').drop(1) pinfo = @path.split('/').drop(1)
if pinfo.length > 0 if pinfo.length > 0
begin begin
@Project = Project.find(pinfo.first) @project = Project.find(pinfo.first)
rescue rescue Exception => e
Rails.logger.error e.message
end end
end end
end end
@project
end
# Make it easy to find the path without project in it. # Make it easy to find the path without project in it.
def projectless_path def projectless_path

View File

@ -3,7 +3,7 @@
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -32,8 +32,6 @@ module RedmineDmsf
NotFound NotFound
else else
# Win7 hack start # Win7 hack start
#unless(request_document.xpath("//#{ns}propfind/#{ns}allprop").empty?)
# properties = resource.properties
if request_document.xpath("//#{ns}propfind").empty? || request_document.xpath("//#{ns}propfind/#{ns}allprop").present? if request_document.xpath("//#{ns}propfind").empty? || request_document.xpath("//#{ns}propfind/#{ns}allprop").present?
properties = resource.properties.map { |prop| DAV4Rack::DAVElement.new(prop.merge(:namespace => DAV4Rack::DAVElement.new(:href => prop[:ns_href]))) } properties = resource.properties.map { |prop| DAV4Rack::DAVElement.new(prop.merge(:namespace => DAV4Rack::DAVElement.new(:href => prop[:ns_href]))) }
# Win7 hack end # Win7 hack end

View File

@ -3,7 +3,7 @@
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -24,15 +24,10 @@ require 'uuidtools'
module RedmineDmsf module RedmineDmsf
module Webdav module Webdav
class DmsfResource < BaseResource class DmsfResource < BaseResource
def initialize(*args)
super(*args)
@file = false
@folder = false
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
def setup def setup
@skip_alias |= [ :folder, :file, :folder?, :file? ] @skip_alias |= [ :folder, :file ]
end end
# Here we hook into the fact that resources can have a pre-execution routine run for them # Here we hook into the fact that resources can have a pre-execution routine run for them
@ -68,63 +63,51 @@ module RedmineDmsf
# - 2012-06-15: Only if you're allowed to browse the project # - 2012-06-15: Only if you're allowed to browse the project
# - 2012-06-18: Issue #5, ensure item is only listed if project is enabled for dmsf # - 2012-06-18: Issue #5, ensure item is only listed if project is enabled for dmsf
def exist? def exist?
return false if project.nil? || !project.module_enabled?('dmsf') || !(folder? || file?) return project && project.module_enabled?('dmsf') && (folder || file) &&
User.current.admin? || User.current.allowed_to?(:view_dmsf_folders, project) (User.current.admin? || User.current.allowed_to?(:view_dmsf_folders, project))
end end
# is this entity a folder? # Is this entity a folder?
def collection? def collection?
folder? #no need to check if entity exists, as false is returned if entity does not exist anyways folder.present? # No need to check if entity exists, as false is returned if entity does not exist anyways
end end
# Check if current entity is a folder and return DmsfFolder object if found (nil if not) # Check if current entity is a folder and return DmsfFolder object if found (nil if not)
# Todo: Move folder data retrieval into folder function, and use folder method to determine existence
def folder def folder
return @folder unless @folder == false unless @folder
return nil if project.nil? || project.id.nil? #if the project doesn't exist, this entity can't exist return nil unless project # If the project doesn't exist, this entity can't exist
@folder = nil
# Note: Folder is searched for as a generic search to prevent SQL queries being generated: # Note: Folder is searched for as a generic search to prevent SQL queries being generated:
# if we were to look within parent, we'd have to go all the way up the chain as part of the # if we were to look within parent, we'd have to go all the way up the chain as part of the
# existence check, and although I'm sure we'd love to access the hierarchy, I can't yet # existence check, and although I'm sure we'd love to access the hierarchy, I can't yet
# see a practical need for it # see a practical need for it
folders = DmsfFolder.visible.where(:project_id => project.id, :title => basename).order('title ASC').to_a folders = DmsfFolder.visible.where(:project_id => project.id, :title => basename).order('title ASC').to_a
return nil unless folders.length > 0 return nil unless folders.length > 0
if (folders.length > 1) then if (folders.length > 1)
folders.delete_if { |x| '/' + x.dmsf_path_str != projectless_path } folders.delete_if { |x| '/' + x.dmsf_path_str != projectless_path }
return nil unless folders.length > 0 return nil unless folders.length > 0
@folder = folders[0] @folder = folders[0]
else else
if ('/' + folders[0].dmsf_path_str == projectless_path) then if (('/' + folders[0].dmsf_path_str) == projectless_path)
@folder = folders[0] @folder = folders[0]
end end
end end
end
@folder @folder
end end
# return boolean to determine if entity is a folder or not
def folder?
return !folder.nil?
end
# Check if current entity exists as a file (DmsfFile), and returns corresponding object if found (nil otherwise) # Check if current entity exists as a file (DmsfFile), and returns corresponding object if found (nil otherwise)
# Currently has a dual search approach (depending on if parent can be determined) # Currently has a dual search approach (depending on if parent can be determined)
# Todo: Move file data retrieval into folder function, and use file method to determine existence
def file def file
return @file unless @file == false unless @file
return nil if project.nil? || project.id.nil? # Again if entity project is nil, it cannot exist in context of this object return nil unless project # Again if entity project is nil, it cannot exist in context of this object
@file = nil
# Hunt for files parent path # Hunt for files parent path
f = false f = false
if (parent.projectless_path != '/') if (parent.projectless_path != '/')
if parent.folder? f = parent.folder if parent.folder
f = parent.folder
end
else else
f = nil f = nil
end end
if f || f.nil?
if f || f.nil? then
# f has a value other than false? - lets use traditional # f has a value other than false? - lets use traditional
# DMSF file search by name. # DMSF file search by name.
@file = DmsfFile.visible.find_file_by_name(project, f, basename) @file = DmsfFile.visible.find_file_by_name(project, f, basename)
@ -134,15 +117,10 @@ module RedmineDmsf
# perform a search in this scenario # perform a search in this scenario
files = DmsfFile.visible.where(:project_id => project.id, :name => basename).order('name ASC').to_a files = DmsfFile.visible.where(:project_id => project.id, :name => basename).order('name ASC').to_a
files.delete_if { |x| File.dirname('/' + x.dmsf_path_str) != File.dirname(projectless_path) } files.delete_if { |x| File.dirname('/' + x.dmsf_path_str) != File.dirname(projectless_path) }
if files.length > 0 @file = files[0] if files.length > 0
@file = files[0]
end end
end end
end @file
# return boolean to determine if entity is a file or not
def file?
return !file.nil?
end end
# Return the content type of file # Return the content type of file
@ -184,11 +162,11 @@ module RedmineDmsf
end end
def content_length def content_length
file? ? file.size : 4096; file ? file.size : 4096;
end end
def special_type def special_type
l(:field_folder) if folder? l(:field_folder) if folder
end end
# Process incoming GET request # Process incoming GET request
@ -214,12 +192,12 @@ module RedmineDmsf
# - 2012-06-18: Ensure item is only functional if project is enabled for dmsf # - 2012-06-18: Ensure item is only functional if project is enabled for dmsf
def make_collection def make_collection
if request.body.read.to_s.empty? if request.body.read.to_s.empty?
raise NotFound if project.nil? || project.id.nil? || !project.module_enabled?('dmsf') raise NotFound unless project && project.module_enabled?('dmsf')
raise Forbidden unless User.current.admin? || User.current.allowed_to?(:folder_manipulation, project) raise Forbidden unless User.current.admin? || User.current.allowed_to?(:folder_manipulation, project)
return MethodNotAllowed if exist? # If we already exist, why waste the time trying to save? return MethodNotAllowed if exist? # If we already exist, why waste the time trying to save?
parent_folder = nil parent_folder = nil
if (parent.projectless_path != '/') if (parent.projectless_path != '/')
return Conflict unless parent.folder? return Conflict unless parent.folder
parent_folder = parent.folder.id parent_folder = parent.folder.id
end end
f = DmsfFolder.new f = DmsfFolder.new
@ -252,7 +230,7 @@ module RedmineDmsf
# Process incoming MOVE request # Process incoming MOVE request
# #
# Behavioural differences between collection and single entity # Behavioural differences between collection and single entity
# Todo: Support overwrite between both types of entity, and implement better checking # TODO: Support overwrite between both types of entity, and implement better checking
def move(dest, overwrite) def move(dest, overwrite)
# All of this should carry accrross the ResourceProxy frontend, we ensure this to # All of this should carry accrross the ResourceProxy frontend, we ensure this to
# prevent unexpected errors # prevent unexpected errors
@ -262,7 +240,7 @@ module RedmineDmsf
parent = resource.parent parent = resource.parent
if (collection?) if collection?
# At the moment we don't support cross project destinations # At the moment we don't support cross project destinations
return MethodNotImplemented unless project.id == resource.project.id return MethodNotImplemented unless project.id == resource.project.id
raise Forbidden unless User.current.admin? || User.current.allowed_to?(:folder_manipulation, project) raise Forbidden unless User.current.admin? || User.current.allowed_to?(:folder_manipulation, project)
@ -274,7 +252,7 @@ module RedmineDmsf
if(parent.projectless_path == '/') #Project root if(parent.projectless_path == '/') #Project root
folder.dmsf_folder_id = nil folder.dmsf_folder_id = nil
else else
return PreconditionFailed unless parent.exist? && parent.folder? return PreconditionFailed unless parent.exist? && parent.folder
folder.dmsf_folder_id = parent.folder.id folder.dmsf_folder_id = parent.folder.id
end end
folder.title = resource.basename folder.title = resource.basename
@ -293,10 +271,10 @@ module RedmineDmsf
if(parent.projectless_path == '/') #Project root if(parent.projectless_path == '/') #Project root
f = nil f = nil
else else
return PreconditionFailed unless parent.exist? && parent.folder? return PreconditionFailed unless parent.exist? && parent.folder
f = parent.folder f = parent.folder
end end
return PreconditionFailed unless exist? && file? return PreconditionFailed unless exist? && file
return InternalServerError unless file.move_to(resource.project, f) return InternalServerError unless file.move_to(resource.project, f)
# 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]
@ -315,10 +293,10 @@ module RedmineDmsf
# Process incoming COPY request # Process incoming COPY request
# #
# Behavioural differences between collection and single entity # Behavioural differences between collection and single entity
# Todo: Support overwrite between both types of entity, and an integrative copy where destination exists for collections # TODO: Support overwrite between both types of entity, and an integrative copy where destination exists for collections
def copy(dest, overwrite) def copy(dest, overwrite)
# All of this should carry accrross the ResourceProxy frontend, we ensure this to # All of this should carry across the ResourceProxy frontend, we ensure this to
# prevent unexpected errors # prevent unexpected errors
if dest.is_a?(ResourceProxy) if dest.is_a?(ResourceProxy)
resource = dest.resource resource = dest.resource
@ -327,9 +305,10 @@ module RedmineDmsf
end end
return PreconditionFailed if !resource.is_a?(DmsfResource) || resource.project.nil? || resource.project.id == 0 return PreconditionFailed if !resource.is_a?(DmsfResource) || resource.project.nil? || resource.project.id == 0
parent = resource.parent
if (collection?)
parent = resource.parent
if collection?
# 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
return MethodNotAllowed if(dest.exist?) return MethodNotAllowed if(dest.exist?)
@ -345,21 +324,17 @@ module RedmineDmsf
User.current.allowed_to?(:view_dmsf_files, project) && User.current.allowed_to?(:view_dmsf_files, project) &&
User.current.allowed_to?(:view_dmsf_folders, project)) User.current.allowed_to?(:view_dmsf_folders, project))
return PreconditionFailed if (parent.projectless_path != "/" && !parent.folder?) return PreconditionFailed if (parent.projectless_path != '/' && !parent.folder)
folder.title = resource.basename folder.title = resource.basename
new_folder = folder.copy_to(resource.project, parent.folder) new_folder = folder.copy_to(resource.project, parent.folder)
return PreconditionFailed if new_folder.nil? || new_folder.id.nil? return PreconditionFailed if new_folder.nil? || new_folder.id.nil?
Created Created
else else
if(dest.exist?) then if dest.exist?
methodNotAllowed methodNotAllowed
# Files cannot be merged at this point, until a decision is made on how to merge them # Files cannot be merged at this point, until a decision is made on how to merge them
# ideally, we would merge revision history for both, ensuring the origin file wins with latest revision. # ideally, we would merge revision history for both, ensuring the origin file wins with latest revision.
else else
# Permission check if they can manipulate folders and view folders # Permission check if they can manipulate folders and view folders
# Can they: # Can they:
# Manipulate files on destination project :file_manipulation # Manipulate files on destination project :file_manipulation
@ -373,10 +348,10 @@ module RedmineDmsf
if(parent.projectless_path == '/') #Project root if(parent.projectless_path == '/') #Project root
f = nil f = nil
else else
return PreconditionFailed unless parent.exist? && parent.folder? return PreconditionFailed unless parent.exist? && parent.folder
f = parent.folder f = parent.folder
end end
return PreconditionFailed unless exist? && file? return PreconditionFailed unless exist? && file
return InternalServerError unless file.copy_to(resource.project, f) return InternalServerError unless file.copy_to(resource.project, f)
# 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]
@ -385,7 +360,6 @@ module RedmineDmsf
# Save Changes # Save Changes
(file.last_revision.save! && file.save!) ? Created : PreconditionFailed (file.last_revision.save! && file.save!) ? Created : PreconditionFailed
end end
end end
end end
@ -395,9 +369,9 @@ module RedmineDmsf
# At present as deletions of folders are not recursive, we do not need to extend # At present as deletions of folders are not recursive, we do not need to extend
# this to cover every file, just queried # this to cover every file, just queried
def lock_check(lock_scope = nil) def lock_check(lock_scope = nil)
if file? if file
raise Locked if file.locked_for_user? raise Locked if file.locked_for_user?
elsif folder? elsif folder
raise Locked if folder.locked_for_user? raise Locked if folder.locked_for_user?
end end
end end
@ -410,12 +384,11 @@ module RedmineDmsf
Rails.logger.warn "Path doesn't exist: #{@path}" Rails.logger.warn "Path doesn't exist: #{@path}"
return super return super
end end
entity = file? ? file : folder entity = file ? file : folder
begin begin
if (entity.locked? && entity.locked_for_user?) if (entity.locked? && entity.locked_for_user?)
raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}") raise DAV4Rack::LockFailure.new("Failed to lock: #{@path}")
else else
# If scope and type are not defined, the only thing we can # If scope and type are not defined, the only thing we can
# logically assume is that the lock is being refreshed (office loves # logically assume is that the lock is being refreshed (office loves
# to do this for example, so we do a few checks, try to find the lock # to do this for example, so we do a few checks, try to find the lock
@ -434,7 +407,6 @@ module RedmineDmsf
return [1.hours.to_i, l.uuid] return [1.hours.to_i, l.uuid]
# Unfortunately if we're here, then it's updating a lock we can't find # Unfortunately if we're here, then it's updating a lock we can't find
return Conflict return Conflict
end end
@ -461,7 +433,7 @@ module RedmineDmsf
BadRequest BadRequest
else else
begin begin
entity = file? ? file : folder entity = file ? file : folder
l = DmsfLock.find(token) l = DmsfLock.find(token)
l_entity = l.file || l.folder l_entity = l.file || l.folder
# Additional case: if a user tries to unlock the file instead of the folder that's locked # Additional case: if a user tries to unlock the file instead of the folder that's locked
@ -480,7 +452,7 @@ module RedmineDmsf
# HTTP POST request. # HTTP POST request.
# #
# Forbidden, as method should not be utilised. # Forbidden, as method should not be utilized.
def post(request, response) def post(request, response)
raise Forbidden raise Forbidden
end end
@ -528,7 +500,7 @@ module RedmineDmsf
new_revision.mime_type = Redmine::MimeType.of(new_revision.name) new_revision.mime_type = Redmine::MimeType.of(new_revision.name)
# Phusion passenger does not have a method "length" in its model # Phusion passenger does not have a method "length" in its model
# however includes a size method - so we instead use reflection # however, includes a size method - so we instead use reflection
# to determine best approach to problem # to determine best approach to problem
if request.body.respond_to? 'length' if request.body.respond_to? 'length'
new_revision.size = request.body.length new_revision.size = request.body.length
@ -563,13 +535,16 @@ module RedmineDmsf
# for lock information to be presented # for lock information to be presented
def get_property(element) def get_property(element)
raise NotImplemented if (element[:ns_href] != 'DAV:') raise NotImplemented if (element[:ns_href] != 'DAV:')
unless folder? unless folder
return NotFound unless (file && file.last_revision && File.exist?(file.last_revision.disk_file)) return NotFound unless (file && file.last_revision && File.exist?(file.last_revision.disk_file))
end end
case element[:name] case element[:name]
when 'supportedlock' then supported_lock when 'supportedlock'
when 'lockdiscovery' then discover_lock supported_lock
else super when 'lockdiscovery'
discover_lock
else
super
end end
end end
@ -629,13 +604,13 @@ module RedmineDmsf
end end
} }
if lock.folder.nil? if lock.folder.nil?
doc.depth "0" doc.depth '0'
else else
doc.depth "infinity" doc.depth 'infinity'
end end
doc.owner lock.user.to_s doc.owner lock.user.to_s
if lock.expires_at.nil? if lock.expires_at.nil?
doc.timeout = "Infinite" doc.timeout = 'Infinite'
else else
doc.timeout "Second-#{(lock.expires_at.to_i - Time.now.to_i)}" doc.timeout "Second-#{(lock.expires_at.to_i - Time.now.to_i)}"
end end
@ -659,7 +634,7 @@ module RedmineDmsf
# supported_lock # supported_lock
# As the name suggests, we're returning locks supported by our implementation # As the name suggests, we're returning locks supported by our implementation
def supported_lock def supported_lock
x = Nokogiri::XML::DocumentFragment.parse "" x = Nokogiri::XML::DocumentFragment.parse ''
Nokogiri::XML::Builder.with(x) do |doc| Nokogiri::XML::Builder.with(x) do |doc|
doc.supportedlock { doc.supportedlock {
doc.lockentry { doc.lockentry {

View File

@ -3,7 +3,7 @@
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License

View File

@ -48,7 +48,7 @@ run_tests()
# Run tests within application # Run tests within application
bundle exec rake redmine:plugins:test:units NAME=redmine_dmsf bundle exec rake redmine:plugins:test:units NAME=redmine_dmsf
bundle exec rake redmine:plugins:test:functionals NAME=redmine_dmsf bundle exec rake redmine:plugins:test:functionals NAME=redmine_dmsf
#bundle exec rake redmine:plugins:test:integration NAME=redmine_dmsf bundle exec rake redmine:plugins:test:integration NAME=redmine_dmsf
} }
uninstall() uninstall()

View File

@ -1,35 +1,42 @@
--- !omap ---
- dmsf_folders_001: dmsf_folders_001:
id: 1 id: 1
title: folder1 title: folder1
project_id: 1 project_id: 1
dmsf_folder_id: NULL dmsf_folder_id: NULL
user_id: 1 user_id: 1
- dmsf_folders_002: dmsf_folders_002:
id: 2 id: 2
title: folder2 title: folder2
project_id: 1 project_id: 1
dmsf_folder_id: 1 dmsf_folder_id: 1
user_id: 1 user_id: 1
- dmsf_folders_003: dmsf_folders_003:
id: 3 id: 3
title: folder1 title: folder1
project_id: 2 project_id: 2
dmsf_folder_id: NULL dmsf_folder_id: NULL
user_id: 1 user_id: 1
- dmsf_folders_004: dmsf_folders_004:
id: 4 id: 4
title: folder2 title: folder2
project_id: 2 project_id: 2
dmsf_folder_id: 3 dmsf_folder_id: 3
user_id: 1 user_id: 1
- dmsf_folders_005: dmsf_folders_005:
id: 5 id: 5
title: folder3 title: folder3
project_id: 1 project_id: 1
dmsf_folder_id: 2 dmsf_folder_id: 2
user_id: 1 user_id: 1
dmsf_folders_006:
id: 6
title: folder6
project_id: 1
dmsf_folder_id: NULL
user_id: 2

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,11 +23,11 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfControllerTest < RedmineDmsf::Test::TestCase class DmsfControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :users, :dmsf_folders, :custom_fields, :custom_values, :projects, fixtures :users, :email_addresses, :dmsf_folders, :custom_fields,
:roles, :members, :member_roles, :dmsf_links, :dmsf_files, :dmsf_file_revisions :custom_values, :projects, :roles, :members, :member_roles, :dmsf_links,
:dmsf_files, :dmsf_file_revisions
def setup def setup
@request.session[:user_id] = 2
@project = Project.find_by_id 1 @project = Project.find_by_id 1
assert_not_nil @project assert_not_nil @project
@project.enable_module! :dmsf @project.enable_module! :dmsf
@ -38,8 +40,8 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
@role = Role.find_by_id 1 @role = Role.find_by_id 1
@custom_field = CustomField.find_by_id 21 @custom_field = CustomField.find_by_id 21
@custom_value = CustomValue.find_by_id 21 @custom_value = CustomValue.find_by_id 21
@user1 = User.find_by_id 1 User.current = nil
User.current = @user1 @request.session[:user_id] = 2
end end
def test_truth def test_truth
@ -53,14 +55,15 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
assert_kind_of Role, @role assert_kind_of Role, @role
assert_kind_of CustomField, @custom_field assert_kind_of CustomField, @custom_field
assert_kind_of CustomValue, @custom_value assert_kind_of CustomValue, @custom_value
assert_kind_of User, @user1
end end
def test_edit_folder def test_edit_folder_forbidden
# Missing permissions # Missing permissions
get :edit, :id => @project, :folder_id => @folder1 get :edit, :id => @project, :folder_id => @folder1
assert_response 403 assert_response :forbidden
end
def test_edit_folder_allowed
# Permissions OK # Permissions OK
@role.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role.add_permission! :folder_manipulation @role.add_permission! :folder_manipulation
@ -70,11 +73,13 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
assert_select 'option', { :value => @custom_value.value } assert_select 'option', { :value => @custom_value.value }
end end
def test_trash def test_trash_forbidden
# Missing permissions # Missing permissions
get :trash, :id => @project get :trash, :id => @project
assert_response 403 assert_response :forbidden
end
def test_trash_allowed
# Permissions OK # Permissions OK
@role.add_permission! :file_delete @role.add_permission! :file_delete
get :trash, :id => @project get :trash, :id => @project
@ -82,72 +87,87 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
assert_select 'h2', { :text => l(:link_trash_bin) } assert_select 'h2', { :text => l(:link_trash_bin) }
end end
def test_delete def test_delete_forbidden
# Missing permissions # Missing permissions
get :delete, :id => @project, :folder_id => @folder1.id, :commit => false get :delete, :id => @project, :folder_id => @folder1.id, :commit => false
assert_response 403 assert_response :forbidden
end
def test_delete_not_empty
# Permissions OK but the folder is not empty # Permissions OK but the folder is not empty
@role.add_permission! :folder_manipulation @role.add_permission! :folder_manipulation
get :delete, :id => @project, :folder_id => @folder1.id, :commit => false get :delete, :id => @project, :folder_id => @folder1.id, :commit => false
assert_response :redirect assert_response :redirect
assert_include l(:error_folder_is_not_empty), flash[:error] assert_include l(:error_folder_is_not_empty), flash[:error]
end
def test_delete_locked
# Permissions OK but the folder is locked # Permissions OK but the folder is locked
@role.add_permission! :folder_manipulation
get :delete, :id => @project, :folder_id => @folder2.id, :commit => false get :delete, :id => @project, :folder_id => @folder2.id, :commit => false
assert_response :redirect assert_response :redirect
assert_include l(:error_folder_is_locked), flash[:error] assert_include l(:error_folder_is_locked), flash[:error]
# Empty and not locked folder
flash[:error].clear
get :delete, :id => @project, :folder_id => @folder4.id, :commit => false
assert_response :redirect
assert_equal 0, flash[:error].size
end end
def test_restore def test_delete_ok
# Empty and not locked folder
@role.add_permission! :folder_manipulation @role.add_permission! :folder_manipulation
get :delete, :id => @project, :folder_id => @folder4.id get :delete, :id => @project, :folder_id => @folder4.id, :commit => false
assert_response :redirect assert_response :redirect
end
def test_restore_forbidden
# Missing permissions # Missing permissions
@role.remove_permission! :folder_manipulation @folder4.deleted = 1
@folder4.save
get :restore, :id => @project, :folder_id => @folder4.id get :restore, :id => @project, :folder_id => @folder4.id
assert_response 403 assert_response :forbidden
end
def test_restore_ok
# Permissions OK # Permissions OK
@request.env['HTTP_REFERER'] = trash_dmsf_path(:id => @project.id) @request.env['HTTP_REFERER'] = trash_dmsf_path(:id => @project.id)
@role.add_permission! :folder_manipulation @role.add_permission! :folder_manipulation
@folder4.deleted = 1
@folder4.save
get :restore, :id => @project, :folder_id => @folder4.id get :restore, :id => @project, :folder_id => @folder4.id
assert_response :redirect assert_response :redirect
end end
def test_delete_restore_entries def test_delete_restore_entries_forbidden
# Missing permissions # Missing permissions
get :entries_operation, :id => @project, :delete_entries => 'Delete', get :entries_operation, :id => @project, :delete_entries => 'Delete',
:subfolders => [@folder1.id.to_s], :files => [@file1.id.to_s], :subfolders => [@folder1.id.to_s], :files => [@file1.id.to_s],
:dir_links => [@folder_link1.id.to_s], :file_links => [@file_link2.id.to_s] :dir_links => [@folder_link1.id.to_s], :file_links => [@file_link2.id.to_s]
assert_response :forbidden assert_response :forbidden
end
def test_delete_restore_not_empty
# Permissions OK but the folder is not empty # Permissions OK but the folder is not empty
@request.env['HTTP_REFERER'] = dmsf_folder_path(:id => @project.id) @request.env['HTTP_REFERER'] = dmsf_folder_path(:id => @project.id)
@role.add_permission! :folder_manipulation
@role.add_permission! :view_dmsf_files @role.add_permission! :view_dmsf_files
get :entries_operation, :id => @project, :delete_entries => 'Delete', get :entries_operation, :id => @project, :delete_entries => 'Delete',
:subfolders => [@folder1.id.to_s], :files => [@file1.id.to_s], :subfolders => [@folder1.id.to_s], :files => [@file1.id.to_s],
:dir_links => [@folder_link1.id.to_s], :file_links => [@file_link2.id.to_s] :dir_links => [@folder_link1.id.to_s], :file_links => [@file_link2.id.to_s]
assert_response :redirect assert_response :redirect
assert_equal flash[:error].to_s, l(:error_folder_is_not_empty) assert_equal flash[:error].to_s, l(:error_folder_is_not_empty)
end
def test_delete_restore_entries_ok
# Permissions OK # Permissions OK
@request.env['HTTP_REFERER'] = dmsf_folder_path(:id => @project.id)
@role.add_permission! :view_dmsf_files
flash[:error] = nil flash[:error] = nil
get :entries_operation, :id => @project, :delete_entries => 'Delete', get :entries_operation, :id => @project, :delete_entries => 'Delete',
:subfolders => [], :files => [@file1.id.to_s], :subfolders => [], :files => [@file1.id.to_s],
:dir_links => [], :file_links => [@file_link2.id.to_s] :dir_links => [], :file_links => [@file_link2.id.to_s]
assert_response :redirect assert_response :redirect
assert_nil flash[:error] assert_nil flash[:error]
end
def test_restore_entries
# Restore # Restore
@role.add_permission! :view_dmsf_files
@request.env['HTTP_REFERER'] = trash_dmsf_path(:id => @project.id) @request.env['HTTP_REFERER'] = trash_dmsf_path(:id => @project.id)
get :entries_operation, :id => @project, :restore_entries => 'Restore', get :entries_operation, :id => @project, :restore_entries => 'Restore',
:subfolders => [], :files => [@file1.id.to_s], :subfolders => [], :files => [@file1.id.to_s],

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -20,64 +22,66 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfFilesControllerTest < RedmineDmsf::Test::TestCase class DmsfFilesControllerTest < RedmineDmsf::Test::TestCase
fixtures :users, :dmsf_files, :dmsf_file_revisions, :custom_fields, fixtures :users, :email_addresses, :dmsf_files, :dmsf_file_revisions,
:custom_values, :projects, :roles, :members, :member_roles, :enabled_modules, :custom_fields, :custom_values, :projects, :roles, :members, :member_roles,
:dmsf_file_revisions :enabled_modules, :dmsf_file_revisions
def setup def setup
@project = Project.find_by_id 1 @project = Project.find_by_id 1
assert_not_nil @project assert_not_nil @project
@project.enable_module! :dmsf @project.enable_module! :dmsf
@user = User.find_by_id 2
assert_not_nil @user
@request.session[:user_id] = @user.id
@file = DmsfFile.find_by_id 1 @file = DmsfFile.find_by_id 1
@role = Role.find_by_id 1 @role = Role.find_by_id 1
@custom_field = CustomField.find_by_id 21 User.current = nil
@custom_value = CustomValue.find_by_id 22 @request.session[:user_id] = 2
end end
def test_truth def test_truth
assert_kind_of Project, @project
assert_kind_of User, @user
assert_kind_of DmsfFile, @file assert_kind_of DmsfFile, @file
assert_kind_of Role, @role assert_kind_of Role, @role
assert_kind_of CustomField, @custom_field
assert_kind_of CustomValue, @custom_value
end end
# TODO: Not working in Travis def test_show_file_ok
# def test_show_file # Permissions OK
# # Missing permissions @role.add_permission! :view_dmsf_files
# get :show, :id => @file.id get :show, :id => @file.id, :download => ''
# assert_response 403 assert_response :missing # The file is not physically present.
# end
# # Permissions OK
# @role.add_permission! :view_dmsf_files
# @role.add_permission! :file_manipulation
# get :show, :id => @file.id
# assert_response :success
#
# # The last revision
# assert_select 'label', { :text => @custom_field.name }
# assert_select '.customfield', { :text => "#{@custom_field.name}: #{@custom_value.value}" }
#
# # A new revision
# assert_select 'label', { :text => @custom_field.name }
# assert_select 'option', { :value => @custom_value.value }
# end
def delete def test_show_file_forbidden
# Missing permissions
get :show, :id => @file.id, :download => ''
assert_response :forbidden
end
def test_view_file_ok
# Permissions OK
@role.add_permission! :view_dmsf_files
get :view, :id => @file.id
assert_response :missing # The file is not physically present.
end
def test_view_file_forbidden
# Missing permissions
get :view, :id => @file.id
assert_response :forbidden
end
def delete_forbidden
# Missing permissions # Missing permissions
delete @file, :commit => false delete @file, :commit => false
assert_response 403 assert_response :forbidden
end
def delete_locked
# Permissions OK but the file is locked # Permissions OK but the file is locked
@role.add_permission! :file_delete @role.add_permission! :file_delete
delete @file, :commit => false delete @file, :commit => false
assert_response :redirect assert_response :redirect
assert_include l(:error_file_is_locked), flash[:error] assert_include l(:error_file_is_locked), flash[:error]
end
def delete_ok
# Permissions OK and not locked # Permissions OK and not locked
flash[:error].clear flash[:error].clear
@file.unlock! @file.unlock!
@ -87,4 +91,3 @@ class DmsfFilesControllerTest < RedmineDmsf::Test::TestCase
end end
end end

View File

@ -2,7 +2,7 @@
# #
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2011-15 Karel Pičman <karel.picman@lbcfree.net> # Copyright (C) 2011-16 Karel Pičman <karel.picman@lbcfree.net>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -22,14 +22,16 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
fixtures :projects, :members, :dmsf_files, :dmsf_file_revisions, fixtures :users, :email_addresses, :projects, :members, :dmsf_files,
:dmsf_folders, :dmsf_links, :roles, :member_roles :dmsf_file_revisions, :dmsf_folders, :dmsf_links, :roles, :member_roles
def setup def setup
@user_admin = User.find_by_id 1 @user_admin = User.find_by_id 1
assert_not_nil @user_admin
@user_member = User.find_by_id 2 @user_member = User.find_by_id 2
assert_not_nil @user_member assert_not_nil @user_member
@user_non_member = User.find_by_id 3 @user_non_member = User.find_by_id 3
assert_not_nil @user_non_member
@role_manager = Role.where(:name => 'Manager').first @role_manager = Role.where(:name => 'Manager').first
assert_not_nil @role_manager assert_not_nil @role_manager
@role_manager.add_permission! :file_manipulation @role_manager.add_permission! :file_manipulation
@ -49,9 +51,10 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
@file2 = DmsfFile.find_by_id 2 # project2/file2 @file2 = DmsfFile.find_by_id 2 # project2/file2
@file4 = DmsfFile.find_by_id 4 # project1/folder2/file4 @file4 = DmsfFile.find_by_id 4 # project1/folder2/file4
@file6 = DmsfFile.find_by_id 6 # project2/folder3/file6 @file6 = DmsfFile.find_by_id 6 # project2/folder3/file6
@request.session[:user_id] = @user_member.id
@file_link = DmsfLink.find_by_id 1 @file_link = DmsfLink.find_by_id 1
@request.env['HTTP_REFERER'] = dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id) @request.env['HTTP_REFERER'] = dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id)
@request.session[:user_id] = @user_member.id
User.current = nil
end end
def test_truth def test_truth
@ -85,16 +88,20 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
assert_response :forbidden assert_response :forbidden
end end
def test_authorize_member def test_authorize_member_ok
@request.session[:user_id] = @user_member.id @request.session[:user_id] = @user_member.id
get :new, :project_id => @project1.id get :new, :project_id => @project1.id
assert_response :success assert_response :success
end
def test_authorize_member_no_module
# Without the module # Without the module
@project1.disable_module!(:dmsf) @project1.disable_module!(:dmsf)
get :new, :project_id => @project1.id get :new, :project_id => @project1.id
assert_response :forbidden assert_response :forbidden
end
def test_authorize_forbidden
# Without permissions # Without permissions
@project1.enable_module!(:dmsf) @project1.enable_module!(:dmsf)
@role_manager.remove_permission! :file_manipulation @role_manager.remove_permission! :file_manipulation
@ -107,7 +114,7 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
assert_response :success assert_response :success
end end
def test_create_file_link_from def test_create_file_link_from_f1
# 1. File link in a folder from another folder # 1. File link in a folder from another folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -121,7 +128,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id)
end
def test_create_file_link_from_f2
# 2. File link in a folder from another root folder # 2. File link in a folder from another root folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -135,7 +144,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id)
end
def test_create_file_link_from_f3
# 3. File link in a root folder from another folder # 3. File link in a root folder from another folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -148,7 +159,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_folder_path(:id => @project1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id)
end
def test_create_file_link_from_f4
# 4. File link in a root folder from another root folder # 4. File link in a root folder from another root folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -162,7 +175,7 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
assert_redirected_to dmsf_folder_path(:id => @project1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id)
end end
def test_create_folder_link_from def test_create_folder_link_from_d1
# 1. Folder link in a folder from another folder # 1. Folder link in a folder from another folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -175,7 +188,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id)
end
def test_create_folder_link_from_d2
# 2. Folder link in a folder from another root folder # 2. Folder link in a folder from another root folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -187,7 +202,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id)
end
def test_create_folder_link_from_d3
# 3. Folder link in a root folder from another folder # 3. Folder link in a root folder from another folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -199,7 +216,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_folder_path(:id => @project1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id)
end
def test_create_folder_link_from_d4
# 4. Folder link in a root folder from another root folder # 4. Folder link in a root folder from another root folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -212,7 +231,7 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
assert_redirected_to dmsf_folder_path(:id => @project1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id)
end end
def test_create_file_link_to def test_create_file_link_to_f1
# 1. File link to a root folder from another folder # 1. File link to a root folder from another folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -225,7 +244,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_file_path(@file1) assert_redirected_to dmsf_file_path(@file1)
end
def test_create_file_link_to_f2
# 2. File link to a folder from another folder # 2. File link to a folder from another folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -239,7 +260,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_file_path(@file6) assert_redirected_to dmsf_file_path(@file6)
end
def test_create_file_link_to_f3
# 3. File link to a root folder from another root folder # 3. File link to a root folder from another root folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -251,7 +274,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to dmsf_file_path(@file6) assert_redirected_to dmsf_file_path(@file6)
end
def test_create_file_link_to_f4
# 4. File link to a folder from another root folder # 4. File link to a folder from another root folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -279,7 +304,7 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
assert_redirected_to dmsf_folder_path(:id => @project1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id)
end end
def test_create_folder_link_to def test_create_folder_link_to_f1
# 1. Folder link to a root folder # 1. Folder link to a root folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -291,7 +316,9 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
} }
end end
assert_redirected_to edit_dmsf_path(:id => @project1.id, :folder_id => @folder1.id) assert_redirected_to edit_dmsf_path(:id => @project1.id, :folder_id => @folder1.id)
end
def test_create_folder_link_to_f2
# 2. Folder link to a folder # 2. Folder link to a folder
assert_difference 'DmsfLink.count', +1 do assert_difference 'DmsfLink.count', +1 do
post :create, :dmsf_link => { post :create, :dmsf_link => {
@ -307,25 +334,26 @@ class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
end end
def test_destroy def test_destroy
# TODO: Doesn't work in Travis assert_difference 'DmsfLink.visible.count', -1 do
#assert_difference 'DmsfLink.visible.count', -1 do
delete :destroy, :project_id => @project1.id, :id => @file_link.id delete :destroy, :project_id => @project1.id, :id => @file_link.id
#end end
assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id) assert_redirected_to dmsf_folder_path(:id => @project1.id, :folder_id => @folder1.id)
end end
def test_restore def test_restore_forbidden
#User.current = @user_admin
@request.env['HTTP_REFERER'] = trash_dmsf_path(:id => @project1.id)
# Missing permissions # Missing permissions
@request.env['HTTP_REFERER'] = trash_dmsf_path(:id => @project1.id)
@role_manager.remove_permission! :file_manipulation @role_manager.remove_permission! :file_manipulation
get :restore, :project_id => @project1.id, :id => @file_link.id get :restore, :project_id => @project1.id, :id => @file_link.id
assert_response :forbidden assert_response :forbidden
end
def test_restore_ok
# Permissions OK # Permissions OK
@request.env['HTTP_REFERER'] = trash_dmsf_path(:id => @project1.id)
@role_manager.add_permission! :file_manipulation @role_manager.add_permission! :file_manipulation
get :restore, :project_id => @project1.id, :id => @file_link.id get :restore, :project_id => @project1.id, :id => @file_link.id
assert_response :redirect assert_response :redirect
end end
end end

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2011-14 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,7 +23,7 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfStateControllerTest < RedmineDmsf::Test::TestCase class DmsfStateControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :users, :projects, :members, :roles, :member_roles fixtures :users, :email_addresses, :projects, :members, :roles, :member_roles
def setup def setup
@user_admin = User.find_by_id 1 # Redmine admin @user_admin = User.find_by_id 1 # Redmine admin
@ -31,7 +33,7 @@ class DmsfStateControllerTest < RedmineDmsf::Test::TestCase
assert_not_nil @project assert_not_nil @project
@project.enable_module! :dmsf @project.enable_module! :dmsf
@role_manager = Role.find_by_name('Manager') @role_manager = Role.find_by_name('Manager')
@role_manager.add_permission! :user_preferences User.current = nil
end end
def test_truth def test_truth
@ -42,24 +44,43 @@ class DmsfStateControllerTest < RedmineDmsf::Test::TestCase
assert_kind_of Role, @role_manager assert_kind_of Role, @role_manager
end end
def test_user_pref_save def test_user_pref_save_member
# Member # Member
@request.session[:user_id] = @user_member.id @request.session[:user_id] = @user_member.id
post :user_pref_save, :id => @project.id, :email_notify => 1 @role_manager.add_permission! :user_preferences
post :user_pref_save, :id => @project.id, :email_notify => 1,
:title_format => '%t_%v'
assert_redirected_to settings_project_path(@project, :tab => 'dmsf') assert_redirected_to settings_project_path(@project, :tab => 'dmsf')
assert_not_nil flash[:notice] assert_not_nil flash[:notice]
assert_equal flash[:notice], l(:notice_your_preferences_were_saved) assert_equal flash[:notice], l(:notice_your_preferences_were_saved)
end
def test_user_pref_save_member_forbidden
# Member
@request.session[:user_id] = @user_member.id
post :user_pref_save, :id => @project.id, :email_notify => 1,
:title_format => '%t_%v'
assert_response :forbidden
end
def test_user_pref_save_none_member
# Non Member # Non Member
@request.session[:user_id] = @user_non_member.id @request.session[:user_id] = @user_non_member.id
post :user_pref_save, :id => @project.id, :email_notify => 1 @role_manager.add_permission! :user_preferences
post :user_pref_save, :id => @project.id, :email_notify => 1,
:title_format => '%t_%v'
assert_response :forbidden assert_response :forbidden
end
def test_user_pref_save_admin
# Admin - non member # Admin - non member
@request.session[:user_id] = @user_admin.id @request.session[:user_id] = @user_admin.id
post :user_pref_save, :id => @project.id, :email_notify => 1 @role_manager.add_permission! :user_preferences
post :user_pref_save, :id => @project.id, :email_notify => 1,
:title_format => '%t_%v'
assert_redirected_to settings_project_path(@project, :tab => 'dmsf') assert_redirected_to settings_project_path(@project, :tab => 'dmsf')
assert_not_nil flash[:warning] assert_not_nil flash[:warning]
assert_equal flash[:warning], l(:user_is_not_project_member) assert_equal flash[:warning], l(:user_is_not_project_member)
end end
end end

View File

@ -2,7 +2,7 @@
# #
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2011-15 Karel Pičman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -23,15 +23,14 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :users, :dmsf_workflows, :dmsf_workflow_steps, :projects, :roles, fixtures :users, :email_addresses, :dmsf_workflows, :dmsf_workflow_steps,
:members, :member_roles, :dmsf_workflow_step_assignments, :dmsf_file_revisions, :projects, :roles, :members, :member_roles, :dmsf_workflow_step_assignments,
:dmsf_files :dmsf_file_revisions, :dmsf_files
def setup def setup
@user_admin = User.find_by_id 1 # Redmine admin @user_admin = User.find_by_id 1 # Redmine admin
@user_member = User.find_by_id 2 # John Smith - manager @user_member = User.find_by_id 2 # John Smith - manager
@user_non_member = User.find_by_id 3 # Dave Lopper @user_non_member = User.find_by_id 3 # Dave Lopper
@request.session[:user_id] = @user_member.id
@role_manager = Role.find_by_name('Manager') @role_manager = Role.find_by_name('Manager')
@role_manager.add_permission! :file_manipulation @role_manager.add_permission! :file_manipulation
@role_manager.add_permission! :manage_workflows @role_manager.add_permission! :manage_workflows
@ -51,6 +50,8 @@ class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase
@file1 = DmsfFile.find_by_id 1 @file1 = DmsfFile.find_by_id 1
@file2 = DmsfFile.find_by_id 2 @file2 = DmsfFile.find_by_id 2
@request.env['HTTP_REFERER'] = dmsf_folder_path(:id => @project1.id) @request.env['HTTP_REFERER'] = dmsf_folder_path(:id => @project1.id)
User.current = nil
@request.session[:user_id] = @user_member.id
end end
def test_truth def test_truth
@ -73,40 +74,58 @@ class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase
assert_kind_of DmsfFile, @file2 assert_kind_of DmsfFile, @file2
end end
def test_authorize def test_authorize_admin
# Admin # Admin
@request.session[:user_id] = @user_admin.id @request.session[:user_id] = @user_admin.id
get :index get :index
assert_response :success assert_response :success
assert_template 'index' assert_template 'index'
end
def test_authorize_member
# Non member # Non member
@request.session[:user_id] = @user_non_member.id @request.session[:user_id] = @user_non_member.id
get :index, :project_id => @project1.id get :index, :project_id => @project1.id
assert_response :forbidden assert_response :forbidden
end
# Member def test_authorize_administration
@request.session[:user_id] = @user_member.id
# Administration # Administration
get :index get :index
assert_response :forbidden assert_response :forbidden
end
def test_authorize_projects
# Project # Project
get :index, :project_id => @project1.id get :index, :project_id => @project1.id
assert_response :success assert_response :success
assert_template 'index' assert_template 'index'
end
def test_authorize_manage_workflows_forbidden
# Without permissions # Without permissions
@role_manager.remove_permission! :manage_workflows @role_manager.remove_permission! :manage_workflows
get :index, :project_id => @project1.id get :index, :project_id => @project1.id
assert_response :forbidden assert_response :forbidden
end
def test_authorization_file_approval_ok
@role_manager.add_permission! :file_approval @role_manager.add_permission! :file_approval
@revision2.dmsf_workflow_id = @wf1.id @revision2.dmsf_workflow_id = @wf1.id
get :start, :id => @revision2.dmsf_workflow_id,:dmsf_file_revision_id => @revision2.id get :start, :id => @revision2.dmsf_workflow_id,
:dmsf_file_revision_id => @revision2.id
assert_response :redirect assert_response :redirect
@role_manager.remove_permission! :file_approval end
get :start, :id => @revision2.dmsf_workflow_id,:dmsf_file_revision_id => @revision2.id
assert_response :forbidden
def test_authorization_file_approval_forbidden
@role_manager.remove_permission! :file_approval
@revision2.dmsf_workflow_id = @wf1.id
get :start, :id => @revision2.dmsf_workflow_id,
:dmsf_file_revision_id => @revision2.id
assert_response :forbidden
end
def test_authorization_no_module
# Without the module # Without the module
@role_manager.add_permission! :file_manipulation @role_manager.add_permission! :file_manipulation
@project1.disable_module!(:dmsf) @project1.disable_module!(:dmsf)
@ -327,4 +346,5 @@ class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase
:project_id => @project1.id) :project_id => @project1.id)
assert_response :redirect assert_response :redirect
end end
end end

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,13 +23,14 @@ require File.expand_path('../../test_helper', __FILE__)
class MyControllerTest < RedmineDmsf::Test::TestCase class MyControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :users, :user_preferences, :dmsf_workflows, :dmsf_workflow_steps, fixtures :users, :email_addresses, :user_preferences, :projects,
:dmsf_workflow_step_assignments, :dmsf_file_revisions, :dmsf_files, :dmsf_workflows, :dmsf_workflow_steps, :dmsf_workflow_step_assignments,
:dmsf_file_revisions, :dmsf_locks :dmsf_file_revisions, :dmsf_folders, :dmsf_files, :dmsf_locks
def setup def setup
@user_member = User.find_by_id 2 @user_member = User.find_by_id 2
assert_not_nil @user_member assert_not_nil @user_member
User.current = nil
@request.session[:user_id] = @user_member.id @request.session[:user_id] = @user_member.id
end end
@ -40,8 +43,9 @@ class MyControllerTest < RedmineDmsf::Test::TestCase
@user_member.pref.save! @user_member.pref.save!
get :page get :page
assert_response :success assert_response :success
# TODO: Not working in Travis assert_select 'div#list-top' do
#assert_select 'h3', { :text => "#{l(:label_my_open_approvals)} (4)" } assert_select 'h3', { :text => "#{l(:label_my_open_approvals)} (0)" }
end
end end
def test_page_with_open_locked_documents def test_page_with_open_locked_documents
@ -49,6 +53,9 @@ class MyControllerTest < RedmineDmsf::Test::TestCase
@user_member.pref.save! @user_member.pref.save!
get :page get :page
assert_response :success assert_response :success
assert_select 'div#list-top' do
assert_select 'h3', { :text => "#{l(:label_my_locked_documents)} (0/1)" } assert_select 'h3', { :text => "#{l(:label_my_locked_documents)} (0/1)" }
end end
end end
end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -22,159 +24,180 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n include Redmine::I18n
fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles,
:dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks :enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions,
:dmsf_locks
def setup def setup
DmsfFile.storage_path = File.expand_path '../fixtures/files', __FILE__ DmsfFile.storage_path = File.expand_path '../../fixtures/files', __FILE__
DmsfLock.delete_all DmsfLock.delete_all
@admin = credentials 'admin' @admin = credentials 'admin'
@jsmith = credentials 'jsmith' @jsmith = credentials 'jsmith'
@project1 = Project.find_by_id 1 @project1 = Project.find_by_id 1
@project2 = Project.find_by_id 2 @project2 = Project.find_by_id 2
@role_developer = Role.find 2 @role = Role.find_by_id 1 # Manager
@folder4 = DmsfFolder.find_by_id 4 @folder1 = DmsfFolder.find_by_id 1
@folder6 = DmsfFolder.find_by_id 6
@file1 = DmsfFile.find_by_id 1 @file1 = DmsfFile.find_by_id 1
@file2 = DmsfFile.find_by_id 2
@file4 = DmsfFile.find_by_id 4
Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1'
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE'
super DmsfFile.storage_path = File.expand_path '../../fixtures/files', __FILE__
User.current = nil
end end
def test_truth def test_truth
assert_kind_of Project, @project1 assert_kind_of Project, @project1
assert_kind_of Project, @project2 assert_kind_of Project, @project2
assert_kind_of DmsfFolder, @folder4 assert_kind_of DmsfFolder, @folder1
assert_kind_of DmsfFolder, @folder6
assert_kind_of DmsfFile, @file1 assert_kind_of DmsfFile, @file1
assert_kind_of DmsfFile, @file2 assert_kind_of Role, @role
assert_kind_of DmsfFile, @file4
assert_kind_of Role, @role_developer
end end
def test_not_authenticated def test_not_authenticated
delete 'dmsf/webdav' delete '/dmsf/webdav'
assert_response 401 assert_response 401
delete "dmsf/webdav/#{@project1.identifier}" end
def test_not_authenticated_project
delete "/dmsf/webdav/#{@project1.identifier}"
assert_response 401 assert_response 401
end end
def test_failed_authentication def test_failed_authentication
delete 'dmsf/webdav', nil, credentials('admin', 'badpassword') delete '/dmsf/webdav', nil, credentials('admin', 'badpassword')
assert_response 401 assert_response 401
delete "dmsf/webdav/#{@project1.identifier}", nil, credentials('admin', 'badpassword') end
def test_failed_authentication
delete "/dmsf/webdav/#{@project1.identifier}", nil, credentials('admin', 'badpassword')
assert_response 401 assert_response 401
end end
def test_root_folder def test_root_folder
delete 'dmsf/webdav/', nil, @admin delete '/dmsf/webdav', nil, @admin
assert_response 501 assert_response :error # 501
end end
def test_delete_not_empty_folder def test_delete_not_empty_folder
put "dmsf/webdav/#{@project1.identifier}/folder1", nil, @admin put "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", nil, @admin
assert_response :forbidden assert_response :forbidden
end end
def test_not_existed_project def test_not_existed_project
delete 'dmsf/webdav/not_a_project/file.txt', nil, @admin delete '/dmsf/webdav/not_a_project/file.txt', nil, @admin
assert_response 404 #Item does not exist assert_response :missing # Item does not exist.
end end
def test_dmsf_not_enabled def test_dmsf_not_enabled
delete "dmsf/webdav/#{@project2.identifier}/test.txt", nil, @jsmith delete "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @jsmith
assert_response 404 #Item does not exist, as project is not enabled assert_response :missing # Item does not exist, as project is not enabled.
end end
def test_delete_when_ro def test_delete_when_ro
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_ONLY' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_ONLY'
delete "dmsf/webdav/#{@project2.identifier}/#{@file1.name}", nil, @admin delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @admin
assert_response 502 #Item does not exist, as project is not enabled assert_response :error # 502 - Item does not exist, as project is not enabled.
end end
def test_unlocked_file def test_unlocked_file
delete "dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @admin delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @admin
assert_response :success # If its in the 20x range it's acceptable, should be 204 assert_response :success # If its in the 20x range it's acceptable, should be 204.
@file1.reload @file1.reload
assert @file1.deleted, "File #{@file1.name} hasn't been deleted" assert @file1.deleted, "File #{@file1.name} hasn't been deleted"
end end
def test_unathorized_user def test_unathorized_user
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
delete "dmsf/webdav/#{@project2.identifier}/#{@file2.name}", nil, @jsmith delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @jsmith
assert_response 404 # Without folder_view permission, he will not even be aware of its existence assert_response :missing # Without folder_view permission, he will not even be aware of its existence.
@file2.reload @file1.reload
assert !@file2.deleted, "File #{@file2.name} is expected to exist" assert !@file1.deleted, "File #{@file1.name} is expected to exist"
@role_developer.add_permission! :view_dmsf_folders end
delete "dmsf/webdav/#{@project2.identifier}/#{@file2.name}", nil, @jsmith
assert_response :forbidden # Now jsmith's role has view_folder rights, however they do not hold file manipulation rights def test_unathorized_user_forbidden
@file2.reload @project1.enable_module! :dmsf # Flag module enabled
assert !@file2.deleted, "File #{@file2.name} is expected to exist" @role.add_permission! :view_dmsf_folders
delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @jsmith
assert_response :forbidden # Now jsmith's role has view_folder rights, however they do not hold file manipulation rights.
@file1.reload
assert !@file1.deleted, "File #{@file1.name} is expected to exist"
end end
def test_view_folder_not_allowed def test_view_folder_not_allowed
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
@role_developer.add_permission! :file_manipulation @role.add_permission! :file_manipulation
delete "dmsf/webdav/#{@project2.identifier}/#{@file2.name}", nil, @jsmith delete "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", nil, @jsmith
assert_response 404 #Without folder_view permission, he will not even be aware of its existence assert_response :missing # Without folder_view permission, he will not even be aware of its existence.
@file2.reload @folder1.reload
assert !@file2.deleted, "File #{@file2.name} is expected to exist" assert !@folder1.deleted, "Folder #{@folder1.title} is expected to exist"
end end
def test_folder_manipulation_not_allowed def test_folder_manipulation_not_allowed
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
@role_developer.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
delete "dmsf/webdav/#{@project2.identifier}/folder1/#{@folder4.title}", nil, @jsmith delete "/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}", nil, @jsmith
assert_response :forbidden #Without manipulation permission, action is forbidden assert_response :forbidden # Without manipulation permission, action is forbidden.
@folder4.reload @folder1.reload
assert !@folder4.deleted, "File #{@file2.name} is expected to exist" assert !@folder1.deleted, "Foler #{@folder1.title} is expected to exist"
end end
def test_folder_delete_by_admin def test_folder_delete_by_admin
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
delete "dmsf/webdav/#{@project2.identifier}/folder1/#{@folder4.title}", nil, @admin delete "/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}", nil, @admin
assert_response :success assert_response :success
@folder4.reload @folder6.reload
assert @folder4.deleted assert @folder6.deleted, "Folder #{@folder1.title} is not expected to exist"
end end
def test_folder_delete_by_user def test_folder_delete_by_user
@role_developer.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role_developer.add_permission! :folder_manipulation @role.add_permission! :folder_manipulation
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
delete "dmsf/webdav/#{@project2.identifier}/folder1/#{@folder4.title}", nil, @jsmith delete "/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}", nil, @jsmith
assert_response :success assert_response :success
@folder4.reload @folder6.reload
assert @folder4.deleted assert @folder6.deleted, "Folder #{@folder1.title} is not expected to exist"
end end
def test_file_delete_by_administrator def test_file_delete_by_administrator
@project2.enable_module! :dmsf @project1.enable_module! :dmsf
delete "dmsf/webdav/#{@project2.identifier}/#{@file2.name}", nil, @admin delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @admin
assert_response :success assert_response :success
@file2.reload @file1.reload
assert @file2.deleted assert @file1.deleted, "File #{@file1.name} is not expected to exist"
end end
def test_file_delete_by_user def test_file_delete_by_user
@project2.enable_module! :dmsf @project1.enable_module! :dmsf
@role_developer.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role_developer.add_permission! :file_delete @role.add_permission! :file_delete
delete "dmsf/webdav/#{@project2.identifier}/#{@file2.name}", nil, @jsmith delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @jsmith
assert_response :success assert_response :success
@file2.reload @file1.reload
assert @file2.deleted assert @file1.deleted, "File #{@file1.name} is not expected to exist"
end
def test_locked_folder
@project1.enable_module! :dmsf # Flag module enabled
@role.add_permission! :view_dmsf_folders
@role.add_permission! :folder_manipulation
@folder6.lock!
delete "/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}", nil, @jsmith
assert_response 423 # Locked
@folder6.reload
assert !@folder6.deleted, "Folder #{@folder6.title} is expected to exist"
end end
def test_locked_file def test_locked_file
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf
@role_developer.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role_developer.add_permission! :file_delete @role.add_permission! :file_delete
delete "dmsf/webdav/#{@project2.identifier}/#{@file2.name}", nil, @jsmith @file1.lock!
assert_response :success delete "/dmsf/webdav/#{@project1.identifier}/#{@file1.name}", nil, @jsmith
# TODO: locks are not working here :-( assert_response 423 # Locked
#assert @file2.deleted, "File is not deleted?!?" @file1.reload
#assert_include l(:error_file_is_locked), flash[:error] assert !@file1.deleted, "File #{@file1.name} is expected to exist"
end end
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,114 +23,120 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest
fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles,
:dmsf_folders, :dmsf_files, :dmsf_file_revisions :enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
@admin = credentials 'admin' @admin = credentials 'admin'
@jsmith = credentials 'jsmith' @jsmith = credentials 'jsmith'
@project1 = Project.find_by_id 1 @project1 = Project.find_by_id 1
@project2 = Project.find_by_id 2 @project2 = Project.find_by_id 2
@role_developer = Role.find 2 @role = Role.find_by_id 1 # Manager
Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1'
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE'
DmsfFile.storage_path = File.expand_path '../fixtures/files', __FILE__ DmsfFile.storage_path = File.expand_path '../../fixtures/files', __FILE__
super User.current = nil
end end
def test_truth def test_truth
assert_kind_of Project, @project1 assert_kind_of Project, @project1
assert_kind_of Project, @project2 assert_kind_of Project, @project2
assert_kind_of Role, @role_developer assert_kind_of Role, @role
end end
def test_should_deny_anonymous def test_should_deny_anonymous
get 'dmsf/webdav' get '/dmsf/webdav'
assert_response 401 assert_response 401
end end
def test_should_deny_failed_authentication def test_should_deny_failed_authentication
get 'dmsf/webdav', nil, credentials('admin', 'badpassword') get '/dmsf/webdav', nil, credentials('admin', 'badpassword')
assert_response 401 assert_response 401
end end
def test_should_permit_authenticated_user def test_should_permit_authenticated_user
get 'dmsf/webdav', nil, @admin get '/dmsf/webdav', nil, @admin
assert_response :success assert_response :success
end end
def test_should_list_dmsf_enabled_project def test_should_list_dmsf_enabled_project
get 'dmsf/webdav', nil, @admin get '/dmsf/webdav', nil, @admin
assert_response :success assert_response :success
assert !response.body.match(@project1.name).nil?, "Expected to find project #{@project1.name} in return data" assert !response.body.match(@project1.name).nil?, "Expected to find project #{@project1.name} in return data"
end end
def test_should_not_list_non_dmsf_enabled_project def test_should_not_list_non_dmsf_enabled_project
get 'dmsf/webdav', nil, @jsmith get '/dmsf/webdav', nil, @jsmith
assert_response :success assert_response :success
assert response.body.match(@project2.name).nil?, "Unexpected find of project #{@project2.name} in return data" assert response.body.match(@project2.name).nil?, "Unexpected find of project #{@project2.name} in return data"
end end
def test_should_return_status_404_when_accessing_non_existant_or_non_dmsf_enabled_project def test_should_return_status_404_when_project_does_not_exist
## Test project resource object @project1.enable_module! :dmsf # Flag module enabled
get 'dmsf/webdav/project_does_not_exist', nil, @jsmith get '/dmsf/webdav/project_does_not_exist', nil, @jsmith
assert_response 404 assert_response :missing
end
get "dmsf/webdav/#{@project2.identifier}", nil, @jsmith def test_should_return_status_404_when_dmsf_not_enabled
assert_response 404 get "/dmsf/webdav/#{@project2.identifier}", nil, @jsmith
assert_response :missing
## Test dmsf resource object
get 'dmsf/webdav/project_does_not_exist/test1', nil, @jsmith
assert_response 404
get "dmsf/webdav/#{@project2.identifier}/test.txt", nil, @jsmith
assert_response 404
end end
def test_download_file_from_dmsf_enabled_project def test_download_file_from_dmsf_enabled_project
# TODO: the storage path is not set as expected => reset #@project1.enable_module! :dmsf # Flag module enabled
DmsfFile.storage_path = File.expand_path('../../fixtures/files', __FILE__) get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin
get "dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin
assert_response :success assert_response :success
assert_equal response.body, '1234', "File downloaded with unexpected contents: '#{response.body}'" assert_equal response.body, '1234',
"File downloaded with unexpected contents: '#{response.body}'"
end end
def test_should_list_dmsf_contents_within_project def test_should_list_dmsf_contents_within_project
get "dmsf/webdav/#{@project1.identifier}", nil, @admin get "/dmsf/webdav/#{@project1.identifier}", nil, @admin
assert_response :success assert_response :success
folder = DmsfFolder.find_by_id 1 folder = DmsfFolder.find_by_id 1
assert folder assert folder
assert response.body.match(folder.title), "Expected to find #{folder.title} in return data" assert response.body.match(folder.title),
"Expected to find #{folder.title} in return data"
file = DmsfFile.find_by_id 1 file = DmsfFile.find_by_id 1
assert file assert file
assert response.body.match(file.name), "Expected to find #{file.name} in return data" assert response.body.match(file.name),
"Expected to find #{file.name} in return data"
end end
def test_user_assigned_to_project def test_user_assigned_to_project_dmsf_module_not_enabled
# We'll be using project 2 and user jsmith for this test (Manager) get "/dmsf/webdav/#{@project1.identifier}", nil, @jsmith
get "dmsf/webdav/#{@project2.identifier}", nil, @jsmith assert_response :missing
assert_response 404 end
def test_user_assigned_to_project_folder_forbidden
@project2.enable_module! :dmsf # Flag module enabled @project2.enable_module! :dmsf # Flag module enabled
get "/dmsf/webdav/#{@project1.identifier}", nil, @jsmith
assert_response :missing
end
get "dmsf/webdav/#{@project2.identifier}", nil, @jsmith def test_user_assigned_to_project_folder_ok
assert_response 404 @project1.enable_module! :dmsf # Flag module enabled
@role.add_permission! :view_dmsf_folders
@role_developer.add_permission! :view_dmsf_folders #assign rights @role.add_permission! :view_dmsf_files
get "/dmsf/webdav/#{@project1.identifier}", nil, @jsmith
get "dmsf/webdav/#{@project2.identifier}", nil, @jsmith
assert_response :success assert_response :success
end
get "dmsf/webdav/#{@project2.identifier}/test.txt", nil, @jsmith def test_user_assigned_to_project_file_forbidden
assert_response 403 #Access is not granted as does not hold view_dmsf_files role (yet) @project1.enable_module! :dmsf # Flag module enabled
@role.add_permission! :view_dmsf_folders
get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @jsmith
assert_response :forbidden
end
@role_developer.add_permission! :view_dmsf_files #assign rights def test_user_assigned_to_project_file_ok
# TODO: the storage path is not set as expected => reset @project1.enable_module! :dmsf # Flag module enabled
DmsfFile.storage_path = File.expand_path('../../fixtures/files', __FILE__) @role.add_permission! :view_dmsf_folders
get "dmsf/webdav/#{@project2.identifier}/test.txt", nil, @jsmith @role.add_permission! :view_dmsf_files
get "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @jsmith
assert_response :success assert_response :success
assert_equal response.body, '1234', "File downloaded with unexpected contents: '#{response.body}'" assert_equal response.body, '1234',
"File downloaded with unexpected contents: '#{response.body}'"
end end
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,15 +23,18 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles,
:dmsf_folders :enabled_modules, :dmsf_folders
def setup def setup
@admin = credentials 'admin'
@jsmith = credentials 'jsmith'
@project1 = Project.find_by_id 1 @project1 = Project.find_by_id 1
@project2 = Project.find_by_id 2 @project2 = Project.find_by_id 2
Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1'
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE'
DmsfFile.storage_path = File.expand_path '../fixtures/files', __FILE__ DmsfFile.storage_path = File.expand_path '../../fixtures/files', __FILE__
User.current = nil
end end
def test_truth def test_truth
@ -38,13 +43,13 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
end end
def test_head_requires_authentication def test_head_requires_authentication
make_request "/dmsf/webdav/#{@project1.identifier}" head "/dmsf/webdav/#{@project1.identifier}"
assert_response 401 assert_response 401
check_headers_dont_exist check_headers_dont_exist
end end
def test_head_responds_with_authentication def test_head_responds_with_authentication
make_request "/dmsf/webdav/#{@project1.identifier}", 'admin' head "/dmsf/webdav/#{@project1.identifier}", nil, @admin
assert_response :success assert_response :success
check_headers_exist check_headers_exist
end end
@ -55,47 +60,40 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
# (but may include an etag, so there is an allowance for a 1 in 2 failure rate on (optionally) required # (but may include an etag, so there is an allowance for a 1 in 2 failure rate on (optionally) required
# headers) # headers)
def test_head_responds_to_file def test_head_responds_to_file
# TODO: the storage path is not set as expected => reset head "/dmsf/webdav/#{@project1.identifier}/test.txt", nil, @admin
DmsfFile.storage_path = File.expand_path('../../fixtures/files', __FILE__)
make_request "/dmsf/webdav/#{@project1.identifier}/test.txt", 'admin'
assert_response :success assert_response :success
check_headers_exist # Note it'll allow 1 out of the 3 expected to fail check_headers_exist # Note it'll allow 1 out of the 3 expected to fail
end end
def test_head_fails_when_file_or_folder_not_found def test_head_fails_when_file_not_found
make_request "/dmsf/webdav/#{@project1.identifier}/not_here.txt", 'admin' head "/dmsf/webdav/#{@project1.identifier}/not_here.txt", nil, @admin
assert_response 404 assert_response :missing
check_headers_dont_exist check_headers_dont_exist
end
make_request '/dmsf/webdav/folder_not_here', 'admin' def test_head_fails_when_folder_not_found
assert_response 404 head '/dmsf/webdav/folder_not_here', nil, @admin
assert_response :missing
check_headers_dont_exist check_headers_dont_exist
end end
def test_head_fails_when_project_is_not_enabled_for_dmsf def test_head_fails_when_project_is_not_enabled_for_dmsf
make_request "/dmsf/webdav/#{@project2.identifier}/test.txt", 'jsmith' head "/dmsf/webdav/#{@project2.identifier}/test.txt", nil, @jsmith
assert_response 404 assert_response :missing
check_headers_dont_exist check_headers_dont_exist
end end
private private
def make_request(*args)
if (args.length == 1) #Just a URL
head args.first
else
head args.first, nil, credentials(args[1])
end
end
def check_headers_exist def check_headers_exist
assert !(response.headers.nil? || response.headers.empty?), 'Head returned without headers' #Headers exist? assert !(response.headers.nil? || response.headers.empty?),
'Head returned without headers' # Headers exist?
values = {} values = {}
values[:etag] = { :optional => true, :content => response.headers['Etag'] } values[:etag] = { :optional => true, :content => response.headers['Etag'] }
values[:content_type] = response.headers['Content-Type'] values[:content_type] = response.headers['Content-Type']
values[:last_modified] = { :optional => true, :content => response.headers['Last-Modified'] } values[:last_modified] = { :optional => true, :content => response.headers['Last-Modified'] }
single_optional = false single_optional = false
values.each {|key,val| values.each do |key,val|
if val.is_a?(Hash) if val.is_a?(Hash)
if (val[:optional].nil? || !val[:optional]) if (val[:optional].nil? || !val[:optional])
assert(!(val[:content].nil? || val[:content].empty?), "Expected header #{key} was empty." ) if single_optional assert(!(val[:content].nil? || val[:content].empty?), "Expected header #{key} was empty." ) if single_optional
@ -105,7 +103,7 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
else else
assert !(val.nil? || val.empty?), "Expected header #{key} was empty." assert !(val.nil? || val.empty?), "Expected header #{key} was empty."
end end
} end
end end
def check_headers_dont_exist def check_headers_dont_exist
@ -113,9 +111,9 @@ class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
values = {} values = {}
values[:etag] = response.headers['Etag']; values[:etag] = response.headers['Etag'];
values[:last_modified] = response.headers['Last-Modified'] values[:last_modified] = response.headers['Last-Modified']
values.each {|key,val| values.each do |key,val|
assert (val.nil? || val.empty?), "Expected header #{key} should be empty." assert (val.nil? || val.empty?), "Expected header #{key} should be empty."
} end
end end
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,67 +23,74 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest
fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles,
:dmsf_folders :enabled_modules, :dmsf_folders
def setup def setup
@admin = credentials 'admin' @admin = credentials 'admin'
@jsmith = credentials 'jsmith' @jsmith = credentials 'jsmith'
@project1 = Project.find_by_id 1 @project1 = Project.find_by_id 1
@project2 = Project.find_by_id 2 @project2 = Project.find_by_id 2
@role_developer = Role.find 2 @role = Role.find_by_id 1 # Manager
@folder6 = DmsfFolder.find_by_id 6
Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1'
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE'
super DmsfFile.storage_path = File.expand_path '../../fixtures/files', __FILE__
User.current = nil
end end
def test_truth def test_truth
assert_kind_of Project, @project1 assert_kind_of Project, @project1
assert_kind_of Project, @project2 assert_kind_of Project, @project2
assert_kind_of Role, @role_developer assert_kind_of Role, @role
assert_kind_of DmsfFolder, @folder6
end end
def test_mkcol_requires_authentication def test_mkcol_requires_authentication
xml_http_request :mkcol, 'dmsf/webdav/test1' xml_http_request :mkcol, '/dmsf/webdav/test1'
assert_response 401 assert_response 401
end end
def test_mkcol_fails_to_create_folder_at_root_level def test_mkcol_fails_to_create_folder_at_root_level
xml_http_request :mkcol, 'dmsf/webdav/test1', nil, @admin xml_http_request :mkcol, '/dmsf/webdav/test1', nil, @admin
assert_response 501 #Not Implemented at this level assert_response :error # 501 - Not Implemented at this level
end end
def test_should_not_succeed_on_a_non_existant_project def test_should_not_succeed_on_a_non_existant_project
xml_http_request :mkcol, 'dmsf/webdav/project_doesnt_exist/test1', nil, @admin xml_http_request :mkcol, '/dmsf/webdav/project_doesnt_exist/test1', nil, @admin
assert_response 404 #Not found assert_response :missing # Not found
end end
def test_should_not_succed_on_a_non_dmsf_enabled_project def test_should_not_succed_on_a_non_dmsf_enabled_project
xml_http_request :mkcol, "dmsf/webdav/#{@project2.identifier}/test1", nil, @jsmith xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/folder", nil, @jsmith
assert_response :forbidden assert_response :forbidden
end end
def test_should_create_folder_on_dmsf_enabled_project def test_should_not_create_folder_without_permissions
xml_http_request :mkcol, "dmsf/webdav/#{@project1.identifier}/test1", nil, @admin @project1.enable_module! :dmsf # Flag module enabled
assert_response :success xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/folder", nil, @jsmith
assert_response :forbidden
end end
def test_should_fail_to_create_folder_that_already_exists def test_should_fail_to_create_folder_that_already_exists
xml_http_request :mkcol, "dmsf/webdav/#{@project1.identifier}/test1", nil, @admin @project1.enable_module! :dmsf # Flag module enabled
assert_response :success @role.add_permission! :folder_manipulation
xml_http_request :mkcol, "dmsf/webdav/#{@project1.identifier}/test1", nil, @admin @role.add_permission! :view_dmsf_folders
xml_http_request :mkcol,
"/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}", nil, @jsmith
assert_response 405 # Method not Allowed assert_response 405 # Method not Allowed
end end
def test_should_fail_to_create_folder_for_user_without_rights def test_should_fail_to_create_folder_for_user_without_rights
xml_http_request :mkcol, "dmsf/webdav/#{@project1.identifier}/test1", nil, @jsmith @project1.enable_module! :dmsf # Flag module enabled
assert_response 403 #Forbidden xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/test1", nil, @jsmith
assert_response :forbidden
end end
def test_should_create_folder_for_non_admin_user_with_rights def test_should_create_folder_for_non_admin_user_with_rights
@role_developer.add_permission! :folder_manipulation @project1.enable_module! :dmsf
@project2.enable_module! :dmsf @role.add_permission! :folder_manipulation
xml_http_request :mkcol, "dmsf/webdav/#{@project2.identifier}/test1", nil, @jsmith xml_http_request :mkcol, "/dmsf/webdav/#{@project1.identifier}/test1", nil, @jsmith
assert_response :success assert_response :success
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,8 +23,8 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest
fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles,
:dmsf_folders :enabled_modules, :dmsf_folders
def setup def setup
@admin = credentials 'admin' @admin = credentials 'admin'
@ -30,7 +32,6 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest
@project2 = Project.find_by_id 2 @project2 = Project.find_by_id 2
Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1'
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE'
super
end end
def test_truth def test_truth
@ -39,12 +40,12 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest
end end
def test_options_requires_no_authentication_for_root_level def test_options_requires_no_authentication_for_root_level
xml_http_request :options, 'dmsf/webdav' xml_http_request :options, '/dmsf/webdav'
assert_response :success assert_response :success
end end
def test_options_returns_expected_allow_header def test_options_returns_expected_allow_header
xml_http_request :options, 'dmsf/webdav' xml_http_request :options, '/dmsf/webdav'
assert_response :success assert_response :success
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert response.headers['Allow'] , 'Allow header is empty or does not exist' assert response.headers['Allow'] , 'Allow header is empty or does not exist'
@ -52,14 +53,14 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest
end end
def test_options_returns_expected_dav_header def test_options_returns_expected_dav_header
xml_http_request :options, 'dmsf/webdav' xml_http_request :options, '/dmsf/webdav'
assert_response :success assert_response :success
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert response.headers['Dav'] , 'Dav header is empty or does not exist' assert response.headers['Dav'] , 'Dav header is empty or does not exist'
end end
def test_options_returns_expected_ms_auth_via_header def test_options_returns_expected_ms_auth_via_header
xml_http_request :options, 'dmsf/webdav' xml_http_request :options, '/dmsf/webdav'
assert_response :success assert_response :success
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert response.headers['Ms-Author-Via'] , 'Ms-Author-Via header is empty or does not exist' assert response.headers['Ms-Author-Via'] , 'Ms-Author-Via header is empty or does not exist'
@ -67,33 +68,33 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest
end end
def test_options_requires_authentication_for_non_root_request def test_options_requires_authentication_for_non_root_request
xml_http_request :options, "dmsf/webdav/#{@project1.identifier}" xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}"
assert_response 401 # Unauthorized assert_response 401 # Unauthorized
end end
def test_un_authenticated_options_returns_expected_allow_header def test_un_authenticated_options_returns_expected_allow_header
xml_http_request :options, "dmsf/webdav/#{@project1.identifier}" xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}"
assert_response 401 assert_response 401
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert_nil response.headers['Allow'] , 'Allow header should not exist' assert_nil response.headers['Allow'] , 'Allow header should not exist'
end end
def test_un_authenticated_options_returns_expected_dav_header def test_un_authenticated_options_returns_expected_dav_header
xml_http_request :options, "dmsf/webdav/#{@project1.identifier}" xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}"
assert_response 401 assert_response 401
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert_nil response.headers['Dav'] , 'Dav header should not exist' assert_nil response.headers['Dav'] , 'Dav header should not exist'
end end
def test_un_authenticated_options_returns_expected_ms_auth_via_header def test_un_authenticated_options_returns_expected_ms_auth_via_header
xml_http_request :options, "dmsf/webdav/#{@project1.identifier}" xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}"
assert_response 401 assert_response 401
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert_nil response.headers['Ms-Author-Via'] , 'Ms-Author-Via header should not exist' assert_nil response.headers['Ms-Author-Via'] , 'Ms-Author-Via header should not exist'
end end
def test_authenticated_options_returns_expected_allow_header def test_authenticated_options_returns_expected_allow_header
xml_http_request :options, "dmsf/webdav/#{@project1.identifier}", nil, @admin xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}", nil, @admin
assert_response :success assert_response :success
assert !(response.headers.nil? || response.headers.empty?), "Response headers are empty" assert !(response.headers.nil? || response.headers.empty?), "Response headers are empty"
assert response.headers['Allow'], 'Allow header is empty or does not exist' assert response.headers['Allow'], 'Allow header is empty or does not exist'
@ -101,24 +102,27 @@ class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest
end end
def test_authenticated_options_returns_expected_dav_header def test_authenticated_options_returns_expected_dav_header
xml_http_request :options, "dmsf/webdav/#{@project1.identifier}", nil, @admin xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}", nil, @admin
assert_response :success assert_response :success
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert response.headers['Dav'], 'Dav header is empty or does not exist' assert response.headers['Dav'], 'Dav header is empty or does not exist'
end end
def test_authenticated_options_returns_expected_ms_auth_via_header def test_authenticated_options_returns_expected_ms_auth_via_header
xml_http_request :options, "dmsf/webdav/#{@project1.identifier}", nil, @admin xml_http_request :options, "/dmsf/webdav/#{@project1.identifier}", nil, @admin
assert_response :success assert_response :success
assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty' assert !(response.headers.nil? || response.headers.empty?), 'Response headers are empty'
assert response.headers['Ms-Author-Via'], 'Ms-Author-Via header is empty or does not exist' assert response.headers['Ms-Author-Via'], 'Ms-Author-Via header is empty or does not exist'
assert response.headers['Ms-Author-Via'] == 'DAV', 'Ms-Author-Via header - expected: DAV' assert response.headers['Ms-Author-Via'] == 'DAV', 'Ms-Author-Via header - expected: DAV'
end end
def test_authenticated_options_returns_401_for_not_found_or_non_dmsf_enabled_items def test_authenticated_options_returns_401_for_non_dmsf_enabled_items
xml_http_request :options, "dmsf/webdav/#{@project2.identifier}", nil, @jsmith xml_http_request :options, "/dmsf/webdav/#{@project2.identifier}", nil, @jsmith
assert_response 401 # refused assert_response 401 # refused
xml_http_request :options, 'dmsf/webdav/does-not-exist', nil, @jsmith end
def test_authenticated_options_returns_401_for_not_found
xml_http_request :options, '/dmsf/webdav/does-not-exist', nil, @jsmith
assert_response 401 # refused assert_response 401 # refused
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,13 +23,12 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWebdavPostTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavPostTest < RedmineDmsf::Test::IntegrationTest
fixtures :users, :enabled_modules fixtures :users, :email_addresses
def setup def setup
@admin = credentials 'admin' @admin = credentials 'admin'
Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1'
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE'
super
end end
# Test that any post request is authenticated # Test that any post request is authenticated
@ -39,7 +40,7 @@ class DmsfWebdavPostTest < RedmineDmsf::Test::IntegrationTest
# Test post is not implemented # Test post is not implemented
def test_post_not_implemented def test_post_not_implemented
post '/dmsf/webdav/', nil, @admin post '/dmsf/webdav/', nil, @admin
assert_response 501 # 501 Not Implemented assert_response :error # 501 Not Implemented
end end
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -22,8 +24,8 @@ require 'fileutils'
class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest
fixtures :projects, :users, :members, :member_roles, :roles, :enabled_modules, fixtures :projects, :users, :email_addresses, :members, :member_roles, :roles,
:dmsf_folders, :dmsf_files, :dmsf_file_revisions :enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
DmsfLock.delete_all # Delete all locks that are in our test DB - probably not safe but ho hum DmsfLock.delete_all # Delete all locks that are in our test DB - probably not safe but ho hum
@ -32,197 +34,167 @@ class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest
Dir.mkdir(DmsfFile.storage_path) unless File.directory?(DmsfFile.storage_path) Dir.mkdir(DmsfFile.storage_path) unless File.directory?(DmsfFile.storage_path)
@admin = credentials 'admin' @admin = credentials 'admin'
@jsmith = credentials 'jsmith' @jsmith = credentials 'jsmith'
@jsmith = credentials 'jsmith'
@project1 = Project.find_by_id 1 @project1 = Project.find_by_id 1
@project2 = Project.find_by_id 2 @project2 = Project.find_by_id 2
@role_developer = Role.find 2 @role = Role.find 1 #
Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1' Setting.plugin_redmine_dmsf['dmsf_webdav'] = '1'
Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE' Setting.plugin_redmine_dmsf['dmsf_webdav_strategy'] = 'WEBDAV_READ_WRITE'
super super
end end
# def teardown def teardown
# # Delete our tmp folder # Delete our tmp folder
# begin begin
# FileUtils.rm_rf DmsfFile.storage_path FileUtils.rm_rf DmsfFile.storage_path
# rescue rescue Exception => e
# warn 'DELETE FAILED' error e.message
# end end
# end end
def test_truth def test_truth
assert_kind_of Project, @project1 assert_kind_of Project, @project1
assert_kind_of Project, @project2 assert_kind_of Project, @project2
assert_kind_of Role, @role_developer assert_kind_of Role, @role
end end
test 'PUT denied unless authenticated' do def test_put_denied_unless_authenticated_root
put 'dmsf/webdav' put '/dmsf/webdav'
assert_response 401
put "dmsf/webdav/#{@project1.identifier}"
assert_response 401 assert_response 401
end end
test 'PUT denied with failed authentication' do def test_put_denied_unless_authenticated
put 'dmsf/webdav', nil, credentials('admin', 'badpassword') put "/dmsf/webdav/#{@project1.identifier}"
assert_response 401
put "dmsf/webdav/#{@project1.identifier}", nil, credentials('admin', 'badpassword')
assert_response 401 assert_response 401
end end
test 'PUT denied at root level' do def test_put_denied_with_failed_authentication_root
put 'dmsf/webdav/test.txt', "1234", @admin.merge!({:content_type => :text}) put '/dmsf/webdav', nil, credentials('admin', 'badpassword')
assert_response 501 assert_response 401
end end
test 'PUT denied on collection/folder' do def test_put_denied_with_failed_authentication
put "dmsf/webdav/#{@project1.identifier}", '1234', @admin.merge!({:content_type => :text}) put "/dmsf/webdav/#{@project1.identifier}", nil, credentials('admin', 'badpassword')
assert_response 403 #forbidden assert_response 401
end end
test 'PUT failed on non-existant project' do def test_put_denied_at_root_level
put 'dmsf/webdav/not_a_project/file.txt', '1234', @admin.merge!({:content_type => :text}) put '/dmsf/webdav/test.txt', '1234', @admin.merge!({:content_type => :text})
assert_response :error # 501
end
def test_put_denied_on_folder
put "/dmsf/webdav/#{@project1.identifier}", '1234', @admin.merge!({:content_type => :text})
assert_response :forbidden
end
def test_put_failed_on_non_existant_project
put '/dmsf/webdav/not_a_project/file.txt', '1234', @admin.merge!({:content_type => :text})
assert_response 409 # Conflict, not_a_project does not exist - file.txt cannot be created assert_response 409 # Conflict, not_a_project does not exist - file.txt cannot be created
end end
test 'PUT as admin granted on dmsf-enabled project' do def test_put_as_admin_granted_on_dmsf_enabled_project
put "dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @admin.merge!({:content_type => :text}) put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @admin.merge!({:content_type => :text})
assert_response 201 #201 Created assert_response :success # 201 Created
# Lets check for our file # Lets check for our file
file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt' file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt'
assert file, 'Check for files existance' assert file, 'Check for files existance'
end end
test 'PUT failed as jsmith on non-dmsf enabled project' do def test_put_failed_as_jsmith_on_non_dmsf_enabled_project
put "dmsf/webdav/#{@project2.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) put "/dmsf/webdav/#{@project2.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response 409 # Should report conflict, as project 2 technically doesn't exist if not enabled assert_response 409 # Should report conflict, as project 2 technically doesn't exist if not enabled
# Lets check for our file # Lets check for our file
file = DmsfFile.find_file_by_name @project2, nil, 'test-1234.txt' file = DmsfFile.find_file_by_name @project2, nil, 'test-1234.txt'
assert_nil file, 'Check for files existance' assert_nil file, 'Check for files existance'
end end
test 'PUT failed when insuficient permissions on project' do def test_put_failed_when_no_permission
@project2.enable_module! :dmsf # Flag module enabled @project2.enable_module! :dmsf # Flag module enabled
put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text})
put "dmsf/webdav/#{@project2.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response 409 # We don't hold the permission view_dmsf_folders, and thus project 2 doesn't exist to us. assert_response 409 # We don't hold the permission view_dmsf_folders, and thus project 2 doesn't exist to us.
end
@role_developer.add_permission! :view_dmsf_folders def test_put_failed_when_no_file_manipulation_permission
@project1.enable_module! :dmsf # Flag module enabled
put "dmsf/webdav/#{@project2.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) @role.add_permission! :view_dmsf_folders
assert_response 403 #We don't hold the permission file_manipulation - so we're unable to do anything with files put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response :forbidden # We don't hold the permission file_manipulation - so we're unable to do anything with files
@role_developer.remove_permission! :view_dmsf_folders end
@role_developer.add_permission! :file_manipulation
def test_put_failed_when_no_view_dmsf_folders_permission
@project1.enable_module! :dmsf # Flag module enabled
@role.add_permission! :file_manipulation
# Check we don't have write access even if we do have the file_manipulation permission # Check we don't have write access even if we do have the file_manipulation permission
put "dmsf/webdav/#{@project2.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response 409 # We don't hold the permission view_dmsf_folders, and thus project 2 doesn't exist to us. assert_response 409 # We don't hold the permission view_dmsf_folders, and thus project 2 doesn't exist to us.
# Lets check for our file # Lets check for our file
file = DmsfFile.find_file_by_name @project2, nil, 'test-1234.txt' file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt'
assert_nil file, 'File test-1234 was found in projects dmsf folder.' assert_nil file, 'File test-1234 was found in projects dmsf folder.'
end end
test 'PUT succeeds for non-admin with correct permissions' do def test_put_succeeds_for_non_admin_with_correct_permissions
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
@role.add_permission! :view_dmsf_folders
put "dmsf/webdav/#{@project2.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text}) @role.add_permission! :file_manipulation
assert_response 409 #We don't hold the permission view_dmsf_folders, and thus project 2 doesn't exist to us. put "/dmsf/webdav/#{@project1.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response :success # 201 - Now we have permissions
@role_developer.add_permission! :view_dmsf_folders
@role_developer.add_permission! :file_manipulation
#Check we don't have write access even if we do have the file_manipulation permission
put "dmsf/webdav/#{@project2.identifier}/test-1234.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response 201 #Now we have permissions :D
# Lets check for our file # Lets check for our file
file = DmsfFile.find_file_by_name @project2, nil, 'test-1234.txt' file = DmsfFile.find_file_by_name @project1, nil, 'test-1234.txt'
assert file, 'File test-1234 was not found in projects dmsf folder.' assert file, 'File test-1234 was not found in projects dmsf folder.'
end end
test 'PUT writes revision successfully for unlocked file' do def test_put_writes_revision_successfully_for_unlocked_file
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf #Flag module enabled
@role_developer.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role_developer.add_permission! :file_manipulation @role.add_permission! :file_manipulation
file = DmsfFile.find_file_by_name @project1, nil, 'test.txt'
file = DmsfFile.find_file_by_name @project2, nil, 'test.txt' assert_not_nil file, 'test.txt file not found'
assert_difference('file.revisions.count') do assert_difference 'file.revisions.count', +1 do
put "dmsf/webdav/#{@project2.identifier}/test.txt", '1234', @jsmith.merge!({:content_type => :text}) put "/dmsf/webdav/#{@project1.identifier}/test.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response 201 #Created assert_response :success # 201 - Created
end end
end end
test 'PUT fails revision when file is locked' do def test_put_fails_revision_when_file_is_locked
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
@role_developer.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role_developer.add_permission! :file_manipulation @role.add_permission! :file_manipulation
log_user 'admin', 'admin' # login as admin log_user 'admin', 'admin' # login as admin
assert !User.current.anonymous?, 'Current user is not anonymous' assert !User.current.anonymous?, 'Current user is not anonymous'
file = DmsfFile.find_file_by_name @project1, nil, 'test.txt'
file = DmsfFile.find_file_by_name @project2, nil, 'test.txt'
assert file.lock!, "File failed to be locked by #{User.current.name}" assert file.lock!, "File failed to be locked by #{User.current.name}"
assert_no_difference 'file.revisions.count' do
assert_no_difference('file.revisions.count') do put "/dmsf/webdav/#{@project1.identifier}/test.txt", '1234', @jsmith.merge!({:content_type => :text})
put "dmsf/webdav/#{@project2.identifier}/test.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response 423 # Locked assert_response 423 # Locked
end end
User.current = User.find(1)
file.unlock!
assert !file.locked?, "File failed to unlock by #{User.current.name}"
end end
test 'PUT fails revision when file is locked and user is administrator' do def test_put_fails_revision_when_file_is_locked_and_user_is_administrator
@project2.enable_module! :dmsf #Flag module enabled @project1.enable_module! :dmsf # Flag module enabled
@role_developer.add_permission! :view_dmsf_folders @role.add_permission! :view_dmsf_folders
@role_developer.add_permission! :file_manipulation @role.add_permission! :file_manipulation
log_user 'jsmith', 'jsmith' # login as jsmith
assert !User.current.anonymous?, "Current user is not anonymous"
file = DmsfFile.find_file_by_name @project2, nil, 'test.txt'
assert file.lock!, "File failed to be locked by #{User.current.name}"
assert_no_difference('file.revisions.count') do
put "dmsf/webdav/#{@project2.identifier}/test.txt", "1234", @admin.merge!({:content_type => :text})
assert_response 423 #Created
end
User.current = User.find(2)
begin
file.unlock!
rescue
#nothing
end
assert !file.locked?, "File failed to unlock by #{User.current.name}"
end
test 'PUT accepts revision when file is locked and user is same as lock holder' do
@project2.enable_module! :dmsf #Flag module enabled
@role_developer.add_permission! :view_dmsf_folders
@role_developer.add_permission! :file_manipulation
log_user 'jsmith', 'jsmith' # login as jsmith log_user 'jsmith', 'jsmith' # login as jsmith
assert !User.current.anonymous?, 'Current user is not anonymous' assert !User.current.anonymous?, 'Current user is not anonymous'
file = DmsfFile.find_file_by_name @project1, nil, 'test.txt'
file = DmsfFile.find_file_by_name @project2, nil, 'test.txt'
assert file.lock!, "File failed to be locked by #{User.current.name}" assert file.lock!, "File failed to be locked by #{User.current.name}"
assert_no_difference 'file.revisions.count' do
assert_difference('file.revisions.count') do put "/dmsf/webdav/#{@project1.identifier}/test.txt", '1234', @admin.merge!({:content_type => :text})
put "dmsf/webdav/#{@project2.identifier}/test.txt", '1234', @jsmith.merge!({:content_type => :text}) assert_response 423 # Locked
assert_response 201 #Created end
end end
file.unlock! def test_put_accepts_revision_when_file_is_locked_and_user_is_same_as_lock_holder
@project1.enable_module! :dmsf # Flag module enabled
assert !file.locked?, "File failed to unlock by #{User.current.name}" @role.add_permission! :view_dmsf_folders
@role.add_permission! :file_manipulation
log_user 'jsmith', 'jsmith' # login as jsmith
assert !User.current.anonymous?, 'Current user is not anonymous'
file = DmsfFile.find_file_by_name @project1, nil, 'test.txt'
assert file.lock!, "File failed to be locked by #{User.current.name}"
assert_difference 'file.revisions.count', +1 do
put "/dmsf/webdav/#{@project1.identifier}/test.txt", '1234', @jsmith.merge!({:content_type => :text})
assert_response :success # 201 - Created
end
end end
end end

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -19,9 +21,9 @@
require File.expand_path('../../test_helper', __FILE__) require File.expand_path('../../test_helper', __FILE__)
class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
fixtures :projects, :users, :dmsf_folders, :dmsf_files, :dmsf_file_revisions, fixtures :projects, :users, :email_addresses, :dmsf_folders, :dmsf_files,
:roles, :members, :member_roles, :enabled_modules, :enumerations, :dmsf_file_revisions, :roles, :members, :member_roles, :enabled_modules,
:dmsf_locks :enumerations, :dmsf_locks
def setup def setup
@revision5 = DmsfFileRevision.find_by_id 5 @revision5 = DmsfFileRevision.find_by_id 5
@ -33,9 +35,11 @@ class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
def test_delete_restore def test_delete_restore
@revision5.delete false @revision5.delete false
assert @revision5.deleted assert @revision5.deleted,
"File revision #{@revision5.name} hasn't been deleted"
@revision5.restore @revision5.restore
assert !@revision5.deleted assert !@revision5.deleted,
"File revision #{@revision5.name} hasn't been restored"
end end
def test_destroy def test_destroy

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -20,21 +22,25 @@
require File.expand_path('../../test_helper', __FILE__) require File.expand_path('../../test_helper', __FILE__)
class DmsfFileTest < RedmineDmsf::Test::UnitTest class DmsfFileTest < RedmineDmsf::Test::UnitTest
fixtures :projects, :users, :dmsf_folders, :dmsf_files, :dmsf_file_revisions, fixtures :projects, :users, :email_addresses, :dmsf_folders, :dmsf_files,
:roles, :members, :member_roles, :dmsf_locks, :dmsf_links :dmsf_file_revisions, :roles, :members, :member_roles, :dmsf_locks,
:dmsf_links
def setup def setup
@user1 = User.find_by_id 1 @admin = User.find_by_id 1
@jsmith = User.find_by_id 2
@project1 = Project.find_by_id 1 @project1 = Project.find_by_id 1
@file1 = DmsfFile.find_by_id 1 @file1 = DmsfFile.find_by_id 1
@file2 = DmsfFile.find_by_id 2 @file2 = DmsfFile.find_by_id 2
@file3 = DmsfFile.find_by_id 3 @file3 = DmsfFile.find_by_id 3
@file4 = DmsfFile.find_by_id 4 @file4 = DmsfFile.find_by_id 4
@file5 = DmsfFile.find_by_id 5 @file5 = DmsfFile.find_by_id 5
User.current = nil
end end
def test_truth def test_truth
assert_kind_of User, @user1 assert_kind_of User, @admin
assert_kind_of User, @jsmith
assert_kind_of Project, @project1 assert_kind_of Project, @project1
assert_kind_of DmsfFile, @file1 assert_kind_of DmsfFile, @file1
assert_kind_of DmsfFile, @file2 assert_kind_of DmsfFile, @file2
@ -43,75 +49,89 @@ class DmsfFileTest < RedmineDmsf::Test::UnitTest
assert_kind_of DmsfFile, @file5 assert_kind_of DmsfFile, @file5
end end
test "project file count differs from project visibility count" do def test_project_file_count_differs_from_project_visibility_count
assert_not_same(@project1.dmsf_files.count, @project1.dmsf_files.visible.count) assert_not_same(@project1.dmsf_files.count, @project1.dmsf_files.visible.count)
end end
test "project DMSF file listing contains deleted items" do def test_project_dmsf_file_listing_contains_deleted_items
found_deleted = false assert @project1.dmsf_files.index{ |f| f.deleted },
@project1.dmsf_files.each {|file| 'Expected at least one deleted item in <all items>'
found_deleted = true if file.deleted
}
assert found_deleted, "Expected at least one deleted item in <all items>"
end end
test "project DMSF file visible listing contains no deleted items" do def test_project_dmsf_file_visible_listing_contains_no_deleted_items
@project1.dmsf_files.visible.each {|file| assert @project1.dmsf_files.visible.index{ |f| f.deleted }.nil?,
assert !file.deleted, "File #{file.name} is deleted, this was unexpected" 'There is a deleted file, this was unexpected'
}
end end
test "Known locked file responds as being locked" do def test_known_locked_file_responds_as_being_locked
assert @file2.locked? assert @file2.locked?, "#{@file2.name} is not locked"
end end
test "File with locked folder is reported as locked" do def test_file_with_locked_folder_is_reported_as_locked
assert @file4.locked? assert @file4.locked?, "#{@file4.name} is not locked"
end end
test "File with folder up heirarchy (locked) is reported as locked" do def test_file_with_folder_up_heirarchy_locked_is_reported_as_locked
assert @file5.locked? assert @file5.locked?, "#{@file5.name} is not locked"
end end
test "File with folder up heirarchy (locked) is not locked for user id 1" do def test_file_locked_is_not_locked_for_user_who_locked
User.current = @user1 User.current = @admin
assert @file5.locked? @file1.lock!
assert !@file5.locked_for_user? assert !@file1.locked_for_user?,
"#{@file1.name} is locked for #{User.current.name}"
@file1.unlock!
end end
test "File with no locks reported unlocked" do def test_file_locked_is_locked_for_user_who_didnt_lock
User.current = @admin
@file1.lock!
User.current = @jsmith
assert @file1.locked_for_user?,
"#{@file1.name} is locked for #{User.current.name}"
User.current = @admin
@file1.unlock!
end
def test_file_with_no_locks_reported_unlocked
assert !@file1.locked? assert !@file1.locked?
end end
def test_delete_restore def test_delete_restore
# TODO: Doesn't work in Travis - a problem with bolean visiblity assert_equal 1, @file4.revisions.visible.count
#assert_equal 1, @file4.revisions.visible.count assert_equal 2, @file4.referenced_links.visible.count
#assert_equal 2, @file4.referenced_links.visible.count end
# Delete def test_delete
@file4.delete false User.current = @admin
# TODO: Doesn't work in Travis - a problem with bolean visiblity @file4.folder.unlock!
#assert @file4.deleted assert @file4.delete(false), @file4.errors.full_messages.to_sentence
#assert_equal 0, @file4.revisions.visible.count assert @file4.deleted, "File #{@file4.name} is not deleted"
#assert_equal 0, @file4.referenced_links.visible.count assert_equal 0, @file4.revisions.visible.count
assert_equal 0, @file4.referenced_links.visible.count
@file4.folder.lock!
end
# Restore def test_restore
User.current = @admin
@file4.folder.unlock!
assert @file4.delete(false), @file4.errors.full_messages.to_sentence
@file4.restore @file4.restore
# TODO: Doesn't work in Travis - a problem with bolean visiblity assert !@file4.deleted, "File #{@file4} hasn't been restored"
#assert !@file4.deleted assert_equal 1, @file4.revisions.visible.count
#assert_equal 1, @file4.revisions.visible.count assert_equal 2, @file4.referenced_links.visible.count
#assert_equal 2, @file4.referenced_links.visible.count @file4.folder.lock!
end end
def test_destroy def test_destroy
# TODO: Doesn't work in Travis - a problem with bolean visiblity User.current = @admin
#assert_equal 1, @file4.revisions.visible.count @file4.folder.unlock!
#assert_equal 2, @file4.referenced_links.visible.count assert_equal 1, @file4.revisions.visible.count
assert_equal 2, @file4.referenced_links.visible.count
@file4.delete true @file4.delete true
# TODO: Doesn't work in Travis - a problem with bolean visiblity assert_equal 0, @file4.revisions.count
#assert_nil DmsfFile.find_by_id(@file4.id) assert_equal 0, @file4.referenced_links.count
#assert_equal 0, @file4.revisions.count @file4.folder.lock!
#assert_equal 0, @file4.referenced_links.count
end end
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -20,37 +22,32 @@
require File.expand_path('../../test_helper', __FILE__) require File.expand_path('../../test_helper', __FILE__)
class DmsfFolderTest < RedmineDmsf::Test::UnitTest class DmsfFolderTest < RedmineDmsf::Test::UnitTest
fixtures :projects, :users, :dmsf_folders, :dmsf_files, :dmsf_file_revisions, fixtures :projects, :users, :email_addresses, :dmsf_folders, :roles,
:roles, :members, :member_roles, :dmsf_locks, :dmsf_links :members, :member_roles
def setup def setup
@folder4 = DmsfFolder.find_by_id 4 @folder6 = DmsfFolder.find_by_id 6
end end
def test_truth def test_truth
assert_kind_of DmsfFolder, @folder4 assert_kind_of DmsfFolder, @folder6
end end
def test_delete_restore def test_delete
# TODO: Doesn't work in Travis - a problem with bolean visiblity assert @folder6.delete(false), @folder6.errors.full_messages.to_sentence
#assert_equal 1, @folder4.referenced_links.visible.count assert @folder6.deleted, "Folder #{@folder6} hasn't been deleted"
@folder4.delete false end
assert @folder4.deleted
# TODO: Doesn't work in Travis - a problem with bolean visiblity def test_restore
#assert_equal 0, @folder4.referenced_links.visible.count assert @folder6.delete(false), @folder6.errors.full_messages.to_sentence
@folder4.restore assert @folder6.deleted, "Folder #{@folder6} hasn't been deleted"
assert !@folder4.deleted assert @folder6.restore, @folder6.errors.full_messages.to_sentence
# TODO: Doesn't work in Travis - a problem with bolean visiblity assert !@folder6.deleted, "Folder #{@folder6} hasn't been restored"
#assert_equal 1, @folder4.referenced_links.visible.count
end end
def test_destroy def test_destroy
# TODO: Doesn't work in Travis - a problem with bolean visiblity @folder6.delete true
#assert_equal 1, @folder4.referenced_links.visible.count assert_nil DmsfFolder.find_by_id(@folder6.id)
@folder4.delete true
assert_nil DmsfFolder.find_by_id(@folder4.id)
# TODO: Doesn't work in Travis - a problem with bolean visiblity
#assert_equal 0, DmsfLink.where(:target_id => @folder4.id, :target_type => DmsfFolder.model_name.to_s).count
end end
end end

View File

@ -45,8 +45,7 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
assert_kind_of DmsfLink, @file_link assert_kind_of DmsfLink, @file_link
end end
def test_create def test_create_folder_link
# Folder link
folder_link = DmsfLink.new folder_link = DmsfLink.new
folder_link.target_project_id = @project1.id folder_link.target_project_id = @project1.id
folder_link.target_id = @folder1.id folder_link.target_id = @folder1.id
@ -56,8 +55,9 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
folder_link.created_at = DateTime.now() folder_link.created_at = DateTime.now()
folder_link.updated_at = DateTime.now() folder_link.updated_at = DateTime.now()
assert folder_link.save, folder_link.errors.full_messages.to_sentence assert folder_link.save, folder_link.errors.full_messages.to_sentence
end
# File link def test_create_file_link
file_link = DmsfLink.new file_link = DmsfLink.new
file_link.target_project_id = @project1.id file_link.target_project_id = @project1.id
file_link.target_id = @file1.id file_link.target_id = @file1.id
@ -67,8 +67,9 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
file_link.created_at = DateTime.now() file_link.created_at = DateTime.now()
file_link.updated_at = DateTime.now() file_link.updated_at = DateTime.now()
assert file_link.save, file_link.errors.full_messages.to_sentence assert file_link.save, file_link.errors.full_messages.to_sentence
end
# External link def test_create_external_link
external_link = DmsfLink.new external_link = DmsfLink.new
external_link.target_project_id = @project1.id external_link.target_project_id = @project1.id
external_link.external_url = 'http://www.redmine.org/plugins/dmsf' external_link.external_url = 'http://www.redmine.org/plugins/dmsf'
@ -82,35 +83,36 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
def test_validate_name_length def test_validate_name_length
@folder_link.name = 'a' * 256 @folder_link.name = 'a' * 256
assert !@folder_link.save assert !@folder_link.save,
"Folder link #{@folder_link.name} should have not been saved"
assert_equal 1, @folder_link.errors.count assert_equal 1, @folder_link.errors.count
end end
def test_validate_name_presence def test_validate_name_presence
@folder_link.name = '' @folder_link.name = ''
assert !@folder_link.save assert !@folder_link.save,
"Folder link #{@folder_link.name} should have not been saved"
assert_equal 1, @folder_link.errors.count assert_equal 1, @folder_link.errors.count
end end
def test_validate_external_url def test_validate_external_url
@file_link.target_type = 'DmsfUrl' @file_link.target_type = 'DmsfUrl'
@file_link.external_url = nil @file_link.external_url = nil
assert !@file_link.save assert !@file_link.save, 'External link should have not been saved'
assert_equal 1, @file_link.errors.count assert_equal 1, @file_link.errors.count
end end
# TODO: Not working in Travis def test_belongs_to_project
# def test_belongs_to_project @project1.destroy
# @project1.destroy assert_nil DmsfLink.find_by_id 1
# assert_nil DmsfLink.find_by_id 1 assert_nil DmsfLink.find_by_id 2
# assert_nil DmsfLink.find_by_id 2 end
# end
# def test_belongs_to_dmsf_folder
# def test_belongs_to_dmsf_folder @folder1.destroy
# @folder1.destroy assert_nil DmsfLink.find_by_id 1
# assert_nil DmsfLink.find_by_id 1 assert_nil DmsfLink.find_by_id 2
# assert_nil DmsfLink.find_by_id 2 end
# end
def test_target_folder_id def test_target_folder_id
assert_equal 2, @file_link.target_folder_id assert_equal 2, @file_link.target_folder_id
@ -148,9 +150,9 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
end end
def test_find_link_by_file_name def test_find_link_by_file_name
# TODO: Doesn't work in Travis - a problem with bolean visiblity file_link = DmsfLink.find_link_by_file_name(@file_link.project,
#assert_equal @file_link, @file_link.folder, @file_link.target_file.name)
# DmsfLink.find_link_by_file_name(@file_link.project, @file_link.folder, @file_link.target_file.name) assert file_link, 'File link not found by its name'
end end
def test_path def test_path
@ -158,50 +160,63 @@ class DmsfLinksTest < RedmineDmsf::Test::UnitTest
assert_equal 'folder1', @folder_link.path assert_equal 'folder1', @folder_link.path
end end
# TODO: Not working in Travis def test_file_kink_copy_to
# def test_copy_to file_link_copy = @file_link.copy_to @folder2.project, @folder2
# # File link assert_not_nil file_link_copy, 'File link copying failed'
# file_link_copy = @file_link.copy_to @folder2.project, @folder2 assert_equal file_link_copy.target_project_id, @file_link.target_project_id
# assert_not_nil file_link_copy assert_equal file_link_copy.target_id, @file_link.target_id
# assert_equal file_link_copy.target_project_id, @file_link.target_project_id assert_equal file_link_copy.target_type, @file_link.target_type
# assert_equal file_link_copy.target_id, @file_link.target_id assert_equal file_link_copy.name, @file_link.name
# assert_equal file_link_copy.target_type, @file_link.target_type assert_equal file_link_copy.project_id, @folder2.project.id
# assert_equal file_link_copy.name, @file_link.name assert_equal file_link_copy.dmsf_folder_id, @folder2.id
# assert_equal file_link_copy.project_id, @folder2.project.id
# assert_equal file_link_copy.dmsf_folder_id, @folder2.id
#
# # Folder link
# folder_link_copy = @folder_link.copy_to @folder2.project, @folder2
# assert_not_nil folder_link_copy
# assert_equal folder_link_copy.target_project_id, @folder_link.target_project_id
# assert_equal folder_link_copy.target_id, @folder_link.target_id
# assert_equal folder_link_copy.target_type, @folder_link.target_type
# assert_equal folder_link_copy.name, @folder_link.name
# assert_equal folder_link_copy.project_id, @folder2.project.id
# assert_equal folder_link_copy.dmsf_folder_id, @folder2.id
# end
def test_delete_restore
# File link
@file_link.delete false
assert @file_link.deleted
@file_link.restore
assert !@file_link.deleted
# Folder link
@folder_link.delete false
assert @folder_link.deleted
@folder_link.restore
assert !@folder_link.deleted
end end
def test_destroy def test_folder_link_copy_to
# File link folder_link_copy = @folder_link.copy_to @folder2.project, @folder2
@file_link.delete true assert_not_nil folder_link_copy, 'Folder link copying failed'
assert_nil DmsfLink.find_by_id @file_link.id assert_equal folder_link_copy.target_project_id,
@folder_link.target_project_id
assert_equal folder_link_copy.target_id, @folder_link.target_id
assert_equal folder_link_copy.target_type, @folder_link.target_type
assert_equal folder_link_copy.name, @folder_link.name
assert_equal folder_link_copy.project_id, @folder2.project.id
assert_equal folder_link_copy.dmsf_folder_id, @folder2.id
end
# Folder link def test_delete_file_link
@folder_link.delete true assert @file_link.delete(false), @file_link.errors.full_messages.to_sentence
assert @file_link.deleted, "File link hasn't been deleted"
end
def test_restore_file_link
assert @file_link.delete(false), @file_link.errors.full_messages.to_sentence
assert @file_link.deleted, "File link hasn't been deleted"
assert @file_link.restore, @file_link.errors.full_messages.to_sentence
assert !@file_link.deleted, "File link hasn't been restored"
end
def test_delete_folder_link
assert @folder_link.delete(false),
@folder_link.errors.full_messages.to_sentence
assert @folder_link.deleted, "Folder link hasn't been deleted"
end
def test_restore_folder_link
assert @folder_link.delete(false),
@folder_link.errors.full_messages.to_sentence
assert @folder_link.deleted, "Folder link hasn't been deleted"
assert @folder_link.restore, @folder_link.errors.full_messages.to_sentence
assert !@folder_link.deleted, "Folder link hasn't been restored"
end
def test_destroy_file_link
assert @file_link.delete(true), @file_link.errors.full_messages.to_sentence
assert_nil DmsfLink.find_by_id @file_link.id
end
def test_destroy_folder_link
assert @folder_link.delete(true),
@folder_link.errors.full_messages.to_sentence
assert_nil DmsfLink.find_by_id @folder_link.id assert_nil DmsfLink.find_by_id @folder_link.id
end end

View File

@ -1,7 +1,9 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk> # Copyright (C) 2012 Daniel Munn <dan.munn@munnster.co.uk>
# Copyright (C) 2011-14 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -20,131 +22,95 @@
require File.expand_path('../../test_helper.rb', __FILE__) require File.expand_path('../../test_helper.rb', __FILE__)
class DmsfLockTest < RedmineDmsf::Test::UnitTest class DmsfLockTest < RedmineDmsf::Test::UnitTest
attr_reader :lock #attr_reader :lock
fixtures :projects, :users, :dmsf_folders, :dmsf_files, :dmsf_file_revisions, fixtures :projects, :users, :email_addresses, :dmsf_folders, :dmsf_files,
:roles, :members, :member_roles, :enabled_modules, :enumerations, :dmsf_file_revisions, :roles, :members, :member_roles, :enabled_modules,
:dmsf_locks :enumerations, :dmsf_locks
def setup def setup
@lock = dmsf_locks(:dmsf_locks_001) @lock = dmsf_locks(:dmsf_locks_001)
@folder2 = dmsf_folders(:dmsf_folders_002)
@file4 = dmsf_files(:dmsf_files_004)
@jsmith = User.find_by_id 2
@admin = User.find_by_id 1
end end
test "lock data is created" do def test_truth
assert_not_nil(lock) assert_kind_of DmsfLock, @lock
assert_kind_of DmsfFile, @file4
assert_kind_of DmsfFolder, @folder2
assert_kind_of User, @jsmith
assert_kind_of User, @admin
end end
# TODO: Not working in Travis def test_lock_type_is_enumerable
# test "lock_type is enumerable" do assert DmsfLock.respond_to?(:lock_types),
# assert DmsfLock.respond_to?(:lock_types) #lock_types is a method created by as_enum "DmsfLock class hasn't got lock_types method"
# assert DmsfLock.lock_types.is_a?(Hash) assert DmsfLock.lock_types.is_a?(SimpleEnum::Enum),
# end 'DmsfLock class is not enumerable'
#
# test "lock_scope is enumerable" do
# assert DmsfLock.respond_to?(:lock_scopes) #lock_types is a method created by as_enum
# assert DmsfLock.lock_scopes.is_a?(Hash)
# end
#
# test "lock_type does not accept invalid values" do
# assert lock.lock_type = :type_write
# assert_raise ArgumentError do
# assert lock.lock_type = :write
# end
# end
test "lock_type accepts a valid answer" do
assert_nothing_raised ArgumentError do
lock.lock_type = :type_write
assert lock.lock_type == :type_write
end
end end
# TODO: Not working in Travis def test_lock_scope_is_enumerable
# test "lock_scope does not accept invalid values" do assert DmsfLock.respond_to?(:lock_scopes),
# assert lock.lock_scope = :scope_exclusive "DmsfLock class hasn't got lock_scopes method"
# assert_raise ArgumentError do assert DmsfLock.lock_scopes.is_a?(SimpleEnum::Enum),
# assert lock.lock_scope = :write 'DmsfLock class is not enumerable'
# end
# end
test "lock_scope accepts a valid answer" do
assert_nothing_raised ArgumentError do
lock.lock_scope = :scope_shared
assert lock.lock_scope == :scope_shared
end
end end
test "linked to either file or folder" do def test_linked_to_either_file_or_folder
assert !(lock.file.nil? && lock.folder.nil?) assert_not_nil @lock.file || @lock.folder
assert !lock.file.nil? || !lock.folder.nil? if @lock.file
if !lock.file.nil? assert_kind_of DmsfFile, @lock.file
assert lock.file.is_a?(DmsfFile)
else else
assert lock.file.is_a?(DmsfFolder) assert_kind_of DmsfFolder @lock.folder
end end
end end
test "locked folder reports un-locked child file as locked" do def test_locked_folder_reports_un_locked_child_file_as_locked
#folder id 2 is locked by fixture assert @folder2.locked?,
#files 4 and 5 are file resources within locked folder (declared by fixture) "Folder #{@folder2.title} should be locked by fixture"
folder = dmsf_folders(:dmsf_folders_002) assert_equal 1, @folder2.lock.count # Check the folder lists 1 lock
file = dmsf_files(:dmsf_files_004) assert @file4.locked?,
"File #{@file4.name} sits within #{@folder2.title} and should be locked"
assert folder.locked?, "Folder (2) should be locked by fixture" assert_equal 1, @file4.lock.count # Check the file lists 1 lock
assert_equal 1, folder.lock.count #Check the folder lists 1 lock assert_equal 0, @file4.lock(false).count # Check the file does not list any entries for itself
assert file.locked?, "File (4) sits within Folder(2) and should be locked"
assert_equal 1, file.lock.count #Check the file lists 1 lock
assert_equal 0, file.lock(false).count #Check the file does not list any entries for itself
end end
# TODO: Not working in Travis def test_locked_folder_cannot_be_unlocked_by_someone_without_rights_or_anon
# test "locked folder cannot be unlocked by someone without rights (or anon)" do assert_no_difference ('@folder2.lock.count') do
# folder = dmsf_folders(:dmsf_folders_002) assert_raise DmsfLockError do
# assert_no_difference ('folder.lock.count') do @folder2.unlock!
# assert_raise DmsfLockError do end
# folder.unlock! end
# end User.current = @jsmith
# end assert_no_difference ('@folder2.lock.count') do
# assert_raise DmsfLockError do
# User.current = users(:users_002) @folder2.unlock!
# assert_no_difference ('folder.lock.count') do end
# assert_raise DmsfLockError do end
# folder.unlock! end
# end
# end
# end
test "locked folder can be unlocked by permission :force_file_unlock" do def test_locked_folder_can_be_unlocked_by_permission
User.current = users(:users_001) User.current = @admin
folder = dmsf_folders(:dmsf_folders_002) assert_difference('@folder2.lock.count', -1) do
assert_difference('folder.lock.count', -1) do
assert_nothing_raised do assert_nothing_raised do
folder.unlock! @folder2.unlock!
end end
end end
User.current = @jsmith
User.current = users(:users_002) assert_difference('@folder2.lock.count') do
assert_difference('folder.lock.count') do
assert_nothing_raised do assert_nothing_raised do
folder.lock! @folder2.lock!
end end
end end
User.current = @admin
User.current = users(:users_001) assert_difference('@folder2.lock.count', -1) do
assert_difference('folder.lock.count', -1) do
assert_nothing_raised do assert_nothing_raised do
folder.unlock! @folder2.unlock!
end end
end end
@folder2.lock!
#We need to re-establish locks for other test
folder.lock!
User.current = nil User.current = nil
end end
end end

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Picman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,8 +23,7 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_workflow_steps fixtures :dmsf_workflow_steps, :dmsf_workflow_step_actions
fixtures :dmsf_workflow_step_actions
def setup def setup
@wfsac1 = DmsfWorkflowStepAction.find(1) @wfsac1 = DmsfWorkflowStepAction.find(1)
@ -37,11 +38,11 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
end end
def test_create def test_create
wfsac = DmsfWorkflowStepAction.new( wfsac = DmsfWorkflowStepAction.new
:dmsf_workflow_step_assignment_id => 1, wfsac.dmsf_workflow_step_assignment_id = 1
:action => DmsfWorkflowStepAction::ACTION_DELEGATE, wfsac.action = DmsfWorkflowStepAction::ACTION_DELEGATE
:note => 'Approval') wfsac.note = 'Approval'
assert wfsac.save assert wfsac.save, wfsac.errors.full_messages.to_sentence
wfsac.reload wfsac.reload
assert wfsac.created_at assert wfsac.created_at
end end
@ -50,10 +51,8 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
@wfsac1.dmsf_workflow_step_assignment_id = 2 @wfsac1.dmsf_workflow_step_assignment_id = 2
@wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT @wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT
@wfsac1.note = 'Rejection' @wfsac1.note = 'Rejection'
assert @wfsac1.save, !@wfsac1.errors.full_messages.to_sentence
assert @wfsac1.save
@wfsac1.reload @wfsac1.reload
assert_equal 2, @wfsac1.dmsf_workflow_step_assignment_id assert_equal 2, @wfsac1.dmsf_workflow_step_assignment_id
assert_equal DmsfWorkflowStepAction::ACTION_REJECT, @wfsac1.action assert_equal DmsfWorkflowStepAction::ACTION_REJECT, @wfsac1.action
assert_equal 'Rejection', @wfsac1.note assert_equal 'Rejection', @wfsac1.note
@ -61,7 +60,7 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
def test_validate_workflow_step_assignment_id_presence def test_validate_workflow_step_assignment_id_presence
@wfsac1.dmsf_workflow_step_assignment_id = nil @wfsac1.dmsf_workflow_step_assignment_id = nil
assert !@wfsac1.save assert !@wfsac1.save, @wfsac1.errors.full_messages.to_sentence
assert_equal 1, @wfsac1.errors.count assert_equal 1, @wfsac1.errors.count
end end
@ -83,10 +82,10 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
assert !@wfsac1.save assert !@wfsac1.save
assert_equal 1, @wfsac1.errors.count assert_equal 1, @wfsac1.errors.count
@wfsac1.note = 'Delegated because' @wfsac1.note = 'Delegated because'
assert @wfsac1.save assert @wfsac1.save, @wfsac1.errors.full_messages.to_sentence
@wfsac1.note = '' @wfsac1.note = ''
@wfsac1.action = DmsfWorkflowStepAction::ACTION_APPROVE @wfsac1.action = DmsfWorkflowStepAction::ACTION_APPROVE
assert @wfsac1.save assert @wfsac1.save, @wfsac1.errors.full_messages.to_sentence
end end
def test_validate_author_id def test_validate_author_id
@ -102,7 +101,7 @@ class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest
assert_equal 1, @wfsac2.errors.count assert_equal 1, @wfsac2.errors.count
@wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT @wfsac1.action = DmsfWorkflowStepAction::ACTION_REJECT
@wfsac2.action = @wfsac1.action; @wfsac2.action = @wfsac1.action;
assert @wfsac1.save assert @wfsac1.save, @wfsac1.errors.full_messages.to_sentence
assert !@wfsac2.save assert !@wfsac2.save
assert_equal 1, @wfsac2.errors.count assert_equal 1, @wfsac2.errors.count
@wfsac1.action = DmsfWorkflowStepAction::ACTION_DELEGATE @wfsac1.action = DmsfWorkflowStepAction::ACTION_DELEGATE

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -20,7 +22,8 @@ require File.expand_path('../../test_helper', __FILE__)
class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
fixtures :users, :dmsf_file_revisions, :dmsf_workflow_steps, :dmsf_workflow_step_assignments fixtures :users, :email_addresses, :dmsf_file_revisions, :dmsf_workflow_steps,
:dmsf_workflow_step_assignments
def setup def setup
@wfsa1 = DmsfWorkflowStepAssignment.find(1) @wfsa1 = DmsfWorkflowStepAssignment.find(1)
@ -29,24 +32,23 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
def test_truth def test_truth
assert_kind_of DmsfWorkflowStepAssignment, @wfsa1 assert_kind_of DmsfWorkflowStepAssignment, @wfsa1
assert_kind_of DmsfWorkflowStepAssignment, @wfsa2
end end
def test_create def test_create
wfsa = DmsfWorkflowStepAssignment.new( wfsa = DmsfWorkflowStepAssignment.new
:dmsf_workflow_step_id => 5, wfsa.dmsf_workflow_step_id = 5
:user_id => 2, wfsa.user_id = 2
:dmsf_file_revision_id => 2) wfsa.dmsf_file_revision_id = 2
assert wfsa.save assert wfsa.save, wfsa.errors.full_messages.to_sentence
end end
def test_update def test_update
@wfsa1.dmsf_workflow_step_id = 5 @wfsa1.dmsf_workflow_step_id = 5
@wfsa1.user_id = 2 @wfsa1.user_id = 2
@wfsa1.dmsf_file_revision_id = 2 @wfsa1.dmsf_file_revision_id = 2
assert @wfsa1.save, @wfsa1.errors.full_messages.to_sentence
assert @wfsa1.save
@wfsa1.reload @wfsa1.reload
assert_equal 5, @wfsa1.dmsf_workflow_step_id assert_equal 5, @wfsa1.dmsf_workflow_step_id
assert_equal 2, @wfsa1.user_id assert_equal 2, @wfsa1.user_id
assert_equal 2, @wfsa1.dmsf_file_revision_id assert_equal 2, @wfsa1.dmsf_file_revision_id
@ -76,4 +78,5 @@ class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
assert_nil DmsfWorkflowStepAssignment.find_by_id(1) assert_nil DmsfWorkflowStepAssignment.find_by_id(1)
assert_nil DmsfWorkflowStepAction.find_by_id(1) assert_nil DmsfWorkflowStepAction.find_by_id(1)
end end
end end

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Pičman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -21,7 +23,8 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest
include Redmine::I18n include Redmine::I18n
fixtures :users, :dmsf_workflows, :dmsf_workflow_steps fixtures :users, :email_addresses, :dmsf_workflows, :dmsf_workflow_steps,
:dmsf_file_revisions
def setup def setup
@wfs1 = DmsfWorkflowStep.find(1) @wfs1 = DmsfWorkflowStep.find(1)
@ -32,6 +35,9 @@ class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest
def test_truth def test_truth
assert_kind_of DmsfWorkflowStep, @wfs1 assert_kind_of DmsfWorkflowStep, @wfs1
assert_kind_of DmsfWorkflowStep, @wfs2
assert_kind_of DmsfWorkflowStep, @wfs5
assert_kind_of DmsfFileRevision, @revision1
end end
def test_create def test_create
@ -40,7 +46,7 @@ class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest
wfs.step = 2 wfs.step = 2
wfs.user_id = 3 wfs.user_id = 3
wfs.operator = 1 wfs.operator = 1
assert wfs.save assert wfs.save, wfs.errors.full_messages.to_sentence
end end
def test_update def test_update
@ -48,10 +54,8 @@ class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest
@wfs1.step = 2 @wfs1.step = 2
@wfs1.user_id = 2 @wfs1.user_id = 2
@wfs1.operator = 2 @wfs1.operator = 2
assert @wfs1.save, @wfs1.errors.full_messages.to_sentence
assert @wfs1.save
@wfs1.reload @wfs1.reload
assert_equal 2, @wfs1.dmsf_workflow_id assert_equal 2, @wfs1.dmsf_workflow_id
assert_equal 2, @wfs1.step assert_equal 2, @wfs1.step
assert_equal 2, @wfs1.user_id assert_equal 2, @wfs1.user_id
@ -111,4 +115,5 @@ class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest
:dmsf_workflow_step_id => @wfs5.id, :dmsf_workflow_step_id => @wfs5.id,
:dmsf_file_revision_id => @revision1.id).first :dmsf_file_revision_id => @revision1.id).first
end end
end end

View File

@ -1,6 +1,8 @@
# encoding: utf-8
#
# Redmine plugin for Document Management System "Features" # Redmine plugin for Document Management System "Features"
# #
# Copyright (C) 2013 Karel Picman <karel.picman@kontron.com> # Copyright (C) 2011-16 Karel Picman <karel.picman@kontron.com>
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -20,12 +22,11 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest
fixtures :projects, :members, :dmsf_files, :dmsf_file_revisions, fixtures :users, :email_addresses, :projects, :members, :dmsf_files,
:dmsf_workflows, :dmsf_workflow_steps, :dmsf_workflow_step_assignments, :dmsf_file_revisions, :dmsf_workflows, :dmsf_workflow_steps,
:dmsf_workflow_step_actions :dmsf_workflow_step_assignments, :dmsf_workflow_step_actions
def setup def setup
User.current = User.find_by_id 1 # Admin
@wf1 = DmsfWorkflow.find_by_id(1) @wf1 = DmsfWorkflow.find_by_id(1)
@wf2 = DmsfWorkflow.find_by_id(2) @wf2 = DmsfWorkflow.find_by_id(2)
@wfs1 = DmsfWorkflowStep.find_by_id(1) @wfs1 = DmsfWorkflowStep.find_by_id(1)
@ -60,13 +61,13 @@ class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest
def test_create def test_create
workflow = DmsfWorkflow.new workflow = DmsfWorkflow.new
workflow.name = 'wf' workflow.name = 'wf'
assert workflow.save assert workflow.save, workflow.errors.full_messages.to_sentence
end end
def test_update def test_update
@wf1.name = 'wf1a' @wf1.name = 'wf1a'
@wf1.project_id = 5 @wf1.project_id = 5
assert @wf1.save assert @wf1.save, @wf1.errors.full_messages.to_sentence
@wf1.reload @wf1.reload
assert_equal 'wf1a', @wf1.name assert_equal 'wf1a', @wf1.name
assert_equal 5, @wf1.project_id assert_equal 5, @wf1.project_id
@ -208,4 +209,5 @@ class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest
participiants = @wf1.participiants participiants = @wf1.participiants
assert_equal participiants.count, 2 assert_equal participiants.count, 2
end end
end end

View File

@ -1,16 +0,0 @@
# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
require 'test/unit'
require 'dmsf_file'
class TestDmsfFile < Test::Unit::TestCase
def test_foo
#TODO: Write test
flunk "TODO: Write test"
# assert_equal("foo", bar)
end
end