Compare commits

..

No commits in common. "v4.2.2" and "main" have entirely different histories.
v4.2.2 ... main

70 changed files with 131 additions and 747 deletions

View File

@ -1,180 +0,0 @@
# Redmine plugin for Document Management System "Features"
#
# Karel Pičman <karel.picman@kontron.com>
#
# This file is part of Redmine DMSF plugin.
#
# Redmine DMSF plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General
# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# Redmine DMSF plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with Redmine DMSF plugin. If not, see
# <https://www.gnu.org/licenses/>.
# GitHub CI script
name: "GitHub CI"
on:
push:
branches: ["master"]
pull_request:
branches: ["master"]
jobs:
plugin_tests:
strategy:
fail-fast: false
matrix:
engine: [mysql, postgresql, sqlite]
include:
- engine: mysql
# Database configuration for Redmine
database_configuration: >
test:
adapter: mysql2
database: test
username: redmine
password: redmine
encoding: utf8mb4
collation: utf8mb4_unicode_ci
# SQL commands to create a database for Redmine
sql1: CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8mb4;
sql2: CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'redmine';
sql3: GRANT ALL PRIVILEGES ON test.* TO 'redmine'@'localhost';
# SQL client command
database_command: mysql -uroot -proot -e
# SQL service
database_service: mysql
- engine: postgresql
# Database configuration for Redmine
database_configuration: >
test:
adapter: postgresql
database: test
username: redmine
password: redmine
host: localhost
# SQL commands to create a database for Redmine
sql1: CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'redmine' NOINHERIT VALID UNTIL 'infinity';
sql2: CREATE DATABASE test WITH ENCODING='UTF8' OWNER=redmine;
sql3: ALTER USER redmine CREATEDB;
# SQL client command
database_command: sudo -u postgres psql -c
# SQL service
database_service: postgresql
- engine: sqlite
# Database configuration for Redmine
database_configuration: >
test:
adapter: sqlite3
database: db/redmine.sqlite3
# No database needed here. It's just a file.
runs-on: ubuntu-latest
env:
RAILS_ENV: test
NAME: redmine_dmsf
steps:
- name: Install dependencies
# Install necessary packages
run: |
sudo apt-get update
sudo apt-get install -y litmus libreoffice subversion
- name: Clone Redmine
# Get the latest stable Redmine
run: svn export http://svn.redmine.org/redmine/branches/6.0-stable/ /opt/redmine
- name: Checkout code
uses: actions/checkout@v3
- name: Link the plugin
# Link the plugin to the redmine folder
run: |
ln -s $(pwd) /opt/redmine/plugins/redmine_dmsf
- name: Install Ruby and gems
uses: ruby/setup-ruby@v1 # The latest major version
with:
bundler-cache: true
ruby-version: '3.2'
- name: Setup database
# Create the database
run: |
echo "${{matrix.database_configuration}}" > /opt/redmine/config/database.yml
if [[ "${{matrix.database_service}}" ]]; then
sudo systemctl start ${{matrix.engine}}
fi
if [[ "${{matrix.database_command}}" ]]; then
${{matrix.database_command}} "${{matrix.sql1}}"
${{matrix.database_command}} "${{matrix.sql2}}"
${{matrix.database_command}} "${{matrix.sql3}}"
fi
- name: Install Redmine
# Install Redmine
run: |
cd /opt/redmine
echo "gem \"webrick\"" > Gemfile.local
bundle config set --local without 'rmagick development xapian'
bundle install
bundle exec rake generate_secret_token
bundle exec rake db:migrate
bundle exec rake redmine:plugins:migrate
bundle exec rake redmine:load_default_data
bundle exec rake assets:precompile
env:
REDMINE_LANG: en
- name: Configure WebDAV
# Add configuration for WebDAV to work
run: |
cp /opt/redmine/config/additional_environment.rb.example /opt/redmine/config/additional_environment.rb
echo "config.log_level = :info" >> /opt/redmine/config/additional_environment.rb
echo "# Redmine DMSF's WebDAV" >> /opt/redmine/config/additional_environment.rb
echo "require \"#{Rails.root}/plugins/redmine_dmsf/lib/redmine_dmsf/webdav/custom_middleware\"" >> /opt/redmine/config/additional_environment.rb
echo "config.middleware.insert_before ActionDispatch::Cookies, RedmineDmsf::Webdav::CustomMiddleware" >> /opt/redmine/config/additional_environment.rb
- name: Standard tests
# Run the tests
run: |
cd /opt/redmine
bundle exec rake redmine:plugins:test:units
bundle exec rake redmine:plugins:test:functionals
bundle exec rake redmine:plugins:test:integration
- name: Helpers tests
run: |
cd /opt/redmine
ruby plugins/redmine_dmsf/test/helpers/dmsf_helper_test.rb
ruby plugins/redmine_dmsf/test/helpers/dmsf_queries_helper_test.rb
- name: Rubocop
# Run the Rubocop tests
run: |
cd /opt/redmine
bundle exec rubocop -c plugins/redmine_dmsf/.rubocop.yml plugins/redmine_dmsf/
- name: Litmus
# Prepare Redmine's environment for WebDAV testing
# Run Webrick server
# Run Litmus tests (Omit 'http' tests due to 'timeout waiting for interim response' and locks due to complex bogus conditional)
# Shutdown Webrick
# Clean up Redmine's environment from WebDAV testing
run: |
cd /opt/redmine
bundle exec rake redmine:dmsf_webdav_test_on
bundle exec rails server -u webrick -e test -d
sleep 5
litmus http://localhost:3000/dmsf/webdav/dmsf_test_project admin admin
kill $(pgrep -f webrick)
bundle exec rake redmine:dmsf_webdav_test_off
env:
TESTS: "basic copymove props"
- name: Cleanup
# Rollback plugin's changes to the database
# Stop the database engine
run: |
cd /opt/redmine
bundle exec rake redmine:plugins:migrate VERSION=0
if [[ "${{matrix.database_service}}" ]]; then
sudo systemctl stop ${{matrix.engine}}
fi
- name: Archive test.log
if: always()
uses: actions/upload-artifact@v4
with:
name: "test_${{matrix.engine}}.log"
path: /opt/redmine/log/test.log

View File

@ -15,10 +15,13 @@
# You should have received a copy of the GNU General Public License along with Redmine DMSF plugin. If not, see # You should have received a copy of the GNU General Public License along with Redmine DMSF plugin. If not, see
# <https://www.gnu.org/licenses/>. # <https://www.gnu.org/licenses/>.
plugins:
- rubocop-rails
- rubocop-performance
AllCops: AllCops:
TargetRubyVersion: 3.2 TargetRubyVersion: 3.2
TargetRailsVersion: 7.1 TargetRailsVersion: 7.1
SuggestExtensions: false SuggestExtensions: false
NewCops: enable NewCops: enable
@ -26,11 +29,6 @@ AllCops:
Exclude: Exclude:
- '**/vendor/**/*' - '**/vendor/**/*'
# Enable extensions
require:
- rubocop-performance
- rubocop-rails
# Rules for DMSF # Rules for DMSF
Layout/LineLength: Layout/LineLength:
Exclude: Exclude:
@ -82,7 +80,7 @@ Naming/AccessorMethodName:
Exclude: Exclude:
- lib/dav4rack/resource.rb - lib/dav4rack/resource.rb
Naming/PredicateName: Naming/PredicatePrefix:
Exclude: Exclude:
- patches/attachable_patch.rb - patches/attachable_patch.rb

View File

@ -1,9 +1,16 @@
Changelog for Redmine DMSF Changelog for Redmine DMSF
========================== ==========================
4.2.2 *2025-07-22* 4.2.3 *2025-10-06*
------------------ ------------------
Redmine 6.1 compatibility
* Bug: #11 - DMSF json API wrong pagination handling
* Bug: #7 - Document edit via WebDAV sets workflow into undefined state
4.2.2 *2025-07-22*
------------------
Missing lock icons Missing lock icons
* Bug: #5 - Missing lock icons by locked objects * Bug: #5 - Missing lock icons by locked objects

339
README.md
View File

@ -1,339 +0,0 @@
# Redmine DMSF Plugin 4.2.2
[![GitHub CI](https://github.com/picman/redmine_dmsf/actions/workflows/rubyonrails.yml/badge.svg?branch=master)](https://github.com/picman/redmine_dmsf/actions/workflows/rubyonrails.yml)
[![Support Ukraine Badge](https://bit.ly/support-ukraine-now)](https://github.com/support-ukraine/support-ukraine)
Redmine DMSF is Document Management System Features plugin for Redmine issue tracking system; It is aimed to replace current Redmine's Documents module.
Redmine DMSF now comes bundled with WebDAV functionality: if switched on within plugin settings this will be accessible from _/dmsf/webdav_.
WebDAV functionality is provided through Dav4Rack library.
The development has been supported by [Kontron](https://www.kontron.com) and has been released as open source thanks to their generosity.
Project home: <https://github.com/picman/redmine_dmsf>
Redmine Document Management System "Features" plugin is distributed under GNU General Public License v3 (GPL).
33Redmine is a flexible project management web application, released under the terms of the GNU General Public License v2 (GPL) at <https://www.redmine.org/>
Further information about the GPL license can be found at
<https://www.gnu.org/licenses/gpl-3.0.html>
## Features
* Directory structure
* Document versioning / revision history
* Document locking
* Multi (drag/drop depending on browser) upload/download
* Direct document or document link sending via email
* Configurable document approval workflow
* Document access auditing
* Integration with Redmine's activity feed
* Wiki macros for a quick content linking
* Full read/write WebDAV functionality
* Optional document content full-text search
* Documents and folders' symbolic links
* Trash bin
* Documents attachable to issues
* Office documents are displayed inline
* Editing of office documents
* REST API
* DMS Document revision as a custom field type
* Compatible with Redmine 6
## Dependencies
* Redmine 6.0 or higher
### Full-text search (optional)
#### Indexing
If you want to use full-text search features, you must setup file content indexing.
It is necessary to index DMSF files with omindex before searching attempts to receive some output:
1. Change the configuration part of redmine_dmsf/extra/xapian_indexer.rb file according to your environment.
(The path to the index database set in xapian_indexer.rb must corresponds to the path set in the plugin's settings.)
2. Run `ruby redmine_dmsf/extra/xapian_indexer.rb -v`
This command should be run on regular basis (e.g. from cron)
Example of cron job (once per hour at 8th minute):
8 * * * * root /usr/bin/ruby redmine_dmsf/extra/xapian_indexer.rb
See redmine_dmsf/extra/xapian_indexer.rb for help.
#### Searching
If you want to use fulltext search abilities, install xapian packages. In case of using of Bitnami
stack or Ruby installed via RVM it might be necessary to install Xapian bindings from sources. See https://xapian.org
for details.
To index some files with omega you may have to install some other packages like
xpdf, antiword, ...
From Omega documentation:
* HTML (.html, .htm, .shtml, .shtm, .xhtml, .xhtm)
* PHP (.php) - our HTML parser knows to ignore PHP code
* text files (.txt, .text)
* SVG (.svg)
* CSV (Comma-Separated Values) files (.csv)
* PDF (.pdf) if pdftotext is available (comes with poppler or xpdf)
* PostScript (.ps, .eps, .ai) if ps2pdf (from ghostscript) and pdftotext (comes with poppler or xpdf) are available
* OpenOffice/StarOffice documents (.sxc, .stc, .sxd, .std, .sxi, .sti, .sxm, .sxw, .sxg, .stw) if unzip is available
* OpenDocument format documents (.odt, .ods, .odp, .odg, .odc, .odf, .odb, .odi, .odm, .ott, .ots, .otp, .otg, .otc, .otf, .oti, .oth) if unzip is available
* MS Word documents (.dot) if antiword is available (.doc files are left to libmagic, as they may actually be RTF (AbiWord saves RTF when asked to save as .doc, and Microsoft Word quietly loads RTF files with a .doc extension), or plain-text).
* MS Excel documents (.xls, .xlb, .xlt, .xlr, .xla) if xls2csv is available (comes with catdoc)
* MS Powerpoint documents (.ppt, .pps) if catppt is available (comes with catdoc)
* MS Office 2007 documents (.docx, .docm, .dotx, .dotm, .xlsx, .xlsm, .xltx, .xltm, .pptx, .pptm, .potx, .potm, .ppsx, .ppsm) if unzip is available
* Wordperfect documents (.wpd) if wpd2text is available (comes with libwpd)
* MS Works documents (.wps, .wpt) if wps2text is available (comes with libwps)
* MS Outlook message (.msg) if perl with Email::Outlook::Message and HTML::Parser modules is available
* MS Publisher documents (.pub) if pub2xhtml is available (comes with libmspub)
* AbiWord documents (.abw)
* Compressed AbiWord documents (.zabw)
* Rich Text Format documents (.rtf) if unrtf is available
* Perl POD documentation (.pl, .pm, .pod) if pod2text is available
* reStructured text (.rst, .rest) if rst2html is available (comes with docutils)
* Markdown (.md, .markdown) if markdown is available
* TeX DVI files (.dvi) if catdvi is available
* DjVu files (.djv, .djvu) if djvutxt is available
* XPS files (.xps) if unzip is available
* Debian packages (.deb, .udeb) if dpkg-deb is available
* RPM packages (.rpm) if rpm is available
* Atom feeds (.atom)
* MAFF (.maff) if unzip is available
* MHTML (.mhtml, .mht) if perl with MIME::Tools is available
* MIME email messages (.eml) and USENET articles if perl with MIME::Tools and HTML::Parser is available
* vCard files (.vcf, .vcard) if perl with Text::vCard is available
You can use following commands to install some of the required indexing tools:
On Debian use:
```
sudo apt-get install xapian-omega ruby-xapian libxapian-dev poppler-utils antiword unzip catdoc libwpd-tools \
libwps-tools gzip unrtf catdvi djview djview3 uuid uuid-dev xz-utils libemail-outlook-message-perl
```
On Ubuntu use:
```
sudo apt-get install xapian-omega ruby-xapian libxapian-dev poppler-utils antiword unzip catdoc libwpd-tools \
libwps-tools gzip unrtf catdvi djview djview3 uuid uuid-dev xz-utils libemail-outlook-message-perl
```
On CentOS use:
```
sudo yum install xapian-core xapian-bindings-ruby libxapian-dev poppler-utils antiword unzip catdoc libwpd-tools \
libwps-tools gzip unrtf catdvi djview djview3 uuid uuid-dev xz libemail-outlook-message-perl
```
## Inline displaying of office documents (optional)
If LibreOffice binary `libreoffice` is present in the server, office documents (.odt, .ods,...) are displayed inline.
The command must be runable by the web app's user. Test it in advance, e.g:
`sudo -u www-data libreoffice --convert-to pdf my_document.odt`
`libreoffice` package is available in the most of Linux distributions, e.g. on Debain based systems:
```
sudo apt install libreoffice liblibreoffice-java
```
## Usage
DMSF is designed to act as project module, so it must be checked as an enabled module within the project settings.
Search will now automatically search DMSF content when a Redmine search is performed, additionally a "Documents" and "Folders" check box will be visible, allowing you to search DMSF content exclusively.
## Linking DMSF object from Wiki entries (macros)
You can link DMSF object from Wikis using a macro tag `{{ }}`. List of available macros with their description is
available from the wiki's toolbar.
## Hooks
You can implement these hooks in your plugin and extend DMSF functionality in certain events.
E.g.
class DmsfUploadControllerHooks < Redmine::Hook::Listener
def dmsf_upload_controller_after_commit(context={})
context[:controller].flash[:info] = 'Okay'
end
end
**dmsf_upload_controller_after_commit**
Called after all uploaded files are committed.
parameters: *files*
**dmsf_helper_upload_after_commit**
Called after an individual file is committed. The controller is not available.
Parameters: *file*
**dmsf_workflow_controller_before_approval**
Called before an approval. If the hook returns false, the approval is not recorded.
parameters: *revision*, *step_action*
**dmsf_files_controller_before_view**
Allows a preview of the file by an external plugin. If the hook returns true, the file is not sent by DMSF. It is
expected that the file is sent by the hook.
parameters: *file*
## Setup / Upgrade
You can either clone the master branch or download the latest zipped version. Before installing ensure that the Redmine
instance is stopped.
git clone git@github.com:picman/redmine_dmsf.git
wget https://github.com/picman/redmine_dmsf/archive/master.zip
1. In case of upgrade **BACKUP YOUR DATABASE, ORIGINAL PLUGIN AND THE FOLDER WITH DOCUMENTS** first!!!
2. Put redmine_dmsf plugin directory into plugins. The plugins sub-directory must be named just **redmine_dmsf**. In case
of need rename _redmine_dmsf-x.y.z_ to *redmine_dmsf*.
3. **Go to the redmine directory**
`cd redmine`
4. Install dependencies:
`bundle install`
4.1 In production environment
bundle config set --local without 'development test'
bundle install
4.2 Without Xapian fulltext search (on Windows)
bundle config set --local without 'xapian'
bundle install
5. Initialize/Update database:
`RAILS_ENV=production bundle exec rake redmine:plugins:migrate NAME=redmine_dmsf`
6. Install assets
`RAILS_ENV="production" bundle exec rake assets:precompile`
7. The access rights must be set for web server, e.g.:
`chown -R www-data:www-data plugins/redmine_dmsf`
8. Restart the web server, e.g.:
`systemctl restart apache2`
9. You should configure the plugin via Redmine interface: Administration -> Plugins -> DMSF -> Configure. (You should check and then save the plugin's configuration after each upgrade.)
10. Don't forget to grant permissions for DMSF in Administration -> Roles and permissions
11. Assign DMSF permissions to appropriate roles.
12. There are a few rake tasks:
I) To convert documents from the standard Redmine document module
Available options:
* project - id or identifier of a project (default to all projects)
* dry_run - perform just a check without any conversion
* issues - Convert also files attached to issues
Example:
rake redmine:dmsf_convert_documents project=test RAILS_ENV="production"
(If you don't run the rake task as the web server user, don't forget to change the ownership of the imported files, e.g.
chown -R www-data:www-data /redmine/files/dmsf
afterwards)
II) To alert all users who are expected to do an approval in the current approval steps
Example:
rake redmine:dmsf_alert_approvals RAILS_ENV="production"
III) To create missing checksums for all document revisions
Available options:
* dry_run - test, no changes to the database
* forceSHA256 - replace old MD5 with SHA256
Example:
bundle exec rake redmine:dmsf_create_digests RAILS_ENV="production"
bundle exec rake redmine:dmsf_create_digests forceSHA256=1 RAILS_ENV="production"
bundle exec rake redmine:dmsf_create_digests dry_run=1 RAILS_ENV="production"
IV) To maintain DMSF
* Remove all files with no database record from the document directory
* Remove all links project_id = -1 (added links to an issue which hasn't been created)
Available options:
* dry_run - No physical deletion but to list of all unused files only
Example:
rake redmine:dmsf_maintenance RAILS_ENV="production"
rake redmine:dmsf_maintenance dry_run=1 RAILS_ENV="production"
### WebDAV
In order to enable WebDAV module, it is necessary to put the following code into yor `config/additional_environment.rb`
```ruby
# Redmine DMSF's WebDAV
require Rails.root.join('plugins', 'redmine_dmsf', 'lib', 'redmine_dmsf', 'webdav', 'custom_middleware').to_s
config.middleware.insert_before ActionDispatch::Cookies, RedmineDmsf::Webdav::CustomMiddleware
```
### Installation in a sub-uri
In order to documents and folders are available via WebDAV in case that the Redmine is configured to be run in a sub-uri
it's necessary to add the following configuration option into your `config/additional_environment.rb`:
```ruby
config.relative_url_root = '/redmine'
```
## Uninstalling DMSF
Before uninstalling the DMSF plugin, please ensure that the Redmine instance is stopped.
1. `cd [redmine-install-dir]`
2. `rake redmine:plugins:migrate NAME=redmine_dmsf VERSION=0 RAILS_ENV=production`
3. `rm plugins/redmine_dmsf -Rf`
After these steps re-start your instance of Redmine.
## Contributing
If you've added something, why not share it. Fork the repository (github.com/picman/redmine_dmsf),
make the changes and send a pull request to the maintainers.
Changes with tests, and full documentation are preferred.
## Additional Documentation
[CHANGELOG.md](CHANGELOG.md) - Project changelog
---
Special thanks to <a href="https://jetbrains.com"><img src="jetbrains-variant-3.svg" alt="JetBrains logo" width="59" height="68"></a> for providing an excellent IDE.

View File

@ -133,7 +133,7 @@ module DmsfQueriesHelper
end end
tag += content_tag('div', item.filename, class: 'dmsf-filename') tag += content_tag('div', item.filename, class: 'dmsf-filename')
if item.project.watched_by?(User.current) if item.project.watched_by?(User.current)
tag += link_to(sprite_icon('fav', nil, icon_only: true, size: '12'), tag += link_to(sprite_icon('unwatch', nil, icon_only: true, size: '12'),
watch_path(object_type: 'project', object_id: item.project.id), watch_path(object_type: 'project', object_id: item.project.id),
title: l(:button_unwatch), title: l(:button_unwatch),
method: 'delete', method: 'delete',
@ -167,7 +167,7 @@ module DmsfQueriesHelper
end end
tag += content_tag('div', item.filename, class: 'dmsf-filename', title: l(:title_filename_for_download)) tag += content_tag('div', item.filename, class: 'dmsf-filename', title: l(:title_filename_for_download))
if !item&.deleted? && item.watched_by?(User.current) if !item&.deleted? && item.watched_by?(User.current)
tag += link_to(sprite_icon('fav', nil, icon_only: true, size: '12'), tag += link_to(sprite_icon('unwatch', nil, icon_only: true, size: '12'),
watch_path(object_type: 'dmsf_folder', object_id: item.id), watch_path(object_type: 'dmsf_folder', object_id: item.id),
title: l(:button_unwatch), title: l(:button_unwatch),
method: 'delete', method: 'delete',
@ -218,7 +218,7 @@ module DmsfQueriesHelper
filename = revision ? revision.formatted_name(member) : item.filename filename = revision ? revision.formatted_name(member) : item.filename
tag += content_tag('div', filename, class: 'dmsf-filename', title: l(:title_filename_for_download)) tag += content_tag('div', filename, class: 'dmsf-filename', title: l(:title_filename_for_download))
if (item.type == 'file') && !item&.deleted? && revision.dmsf_file&.watched_by?(User.current) if (item.type == 'file') && !item&.deleted? && revision.dmsf_file&.watched_by?(User.current)
tag += link_to(sprite_icon('fav', nil, icon_only: true, size: '12'), tag += link_to(sprite_icon('unwatch', nil, icon_only: true, size: '12'),
watch_path(object_type: 'dmsf_file', object_id: item.id), watch_path(object_type: 'dmsf_file', object_id: item.id),
title: l(:button_unwatch), title: l(:button_unwatch),
method: 'delete', method: 'delete',

View File

@ -265,6 +265,15 @@ class DmsfFileRevision < ApplicationRecord
wf.assign(id) if wf && id wf.assign(id) if wf && id
end end
def reset_workflow
self.workflow = nil
self.dmsf_workflow_id = nil
self.dmsf_workflow_assigned_by_user_id = nil
self.dmsf_workflow_assigned_at = nil
self.dmsf_workflow_started_by_user_id = nil
self.dmsf_workflow_started_at = nil
end
def increase_version(version_to_increase) def increase_version(version_to_increase)
# Patch version # Patch version
self.patch_version = case version_to_increase self.patch_version = case version_to_increase

View File

@ -22,10 +22,10 @@ class DmsfFileExtensionValidator < ActiveModel::EachValidator
include Redmine::I18n include Redmine::I18n
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
return true unless attribute.to_s == 'name' return unless attribute.to_s == 'name'
extension = File.extname(value) extension = File.extname(value)
return true if Attachment.valid_extension?(extension) return if Attachment.valid_extension?(extension)
record.errors.add(:base, l(:error_attachment_extension_not_allowed, extension: extension)) record.errors.add(:base, l(:error_attachment_extension_not_allowed, extension: extension))
end end

View File

@ -25,10 +25,9 @@ class DmsfFolderParentValidator < ActiveModel::EachValidator
while folder while folder
if folder == record if folder == record
record.errors.add attribute, :invalid record.errors.add attribute, :invalid
return false return
end end
folder = folder.dmsf_folder folder = folder.dmsf_folder
end end
true
end end
end end

View File

@ -22,14 +22,11 @@ class DmsfMaxFileSizeValidator < ActiveModel::EachValidator
include Redmine::I18n include Redmine::I18n
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
if value && (value > Setting.attachment_max_size.to_i.kilobytes) return unless value && (value > Setting.attachment_max_size.to_i.kilobytes)
record.errors.add attribute,
l(:error_attachment_too_big, max_size: ActiveSupport::NumberHelper.number_to_human_size( record.errors.add attribute,
Setting.attachment_max_size.to_i.kilobytes l(:error_attachment_too_big, max_size: ActiveSupport::NumberHelper.number_to_human_size(
)) Setting.attachment_max_size.to_i.kilobytes
false ))
else
true
end
end end
end end

View File

@ -1,6 +1,6 @@
api.dmsf do api.dmsf do
api.array :dmsf_nodes, api_meta(total_count: @query.dmsf_nodes(offset: @offset, limit: @limit).count) do api.array :dmsf_nodes, api_meta(total_count: @query.dmsf_nodes().count, limit: @limit, offset: @offset) do
@query.dmsf_nodes(offset: @offset, limit: @limit).each do |node| @query.dmsf_nodes(offset: @offset, limit: @limit).each do |node|
api.node do api.node do
api.id node.id api.id node.id

View File

@ -19,7 +19,8 @@
<% watched = object.watched_by?(User.current) %> <% watched = object.watched_by?(User.current) %>
<% css = [watcher_css([object]), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ') %> <% css = [watcher_css([object]), watched ? 'icon icon-fav' : 'icon icon-fav-off'].join(' ') %>
<% text = sprite_icon('fav', watched ? l(:button_unwatch) : l(:button_watch)) %> <% icon = watched ? 'unwatch' : 'watch' %>
<% text = watched ? l(:button_unwatch) : l(:button_watch) %>
<% url = watch_path(object_type: object.class.to_s.underscore, object_id: object.id) %> <% url = watch_path(object_type: object.class.to_s.underscore, object_id: object.id) %>
<% method = watched ? 'delete' : 'post' %> <% method = watched ? 'delete' : 'post' %>
<%= context_menu_link text, url, method: method, class: css, disabled: !User.current.logged? %> <%= context_menu_link sprite_icon(icon, text), url, method: method, class: css, disabled: !User.current.logged? %>

View File

@ -27,9 +27,9 @@ Redmine::Plugin.register :redmine_dmsf do
author_url 'https://github.com/picman/redmine_dmsf/graphs/contributors' author_url 'https://github.com/picman/redmine_dmsf/graphs/contributors'
author 'Vít Jonáš / Daniel Munn / Karel Pičman' author 'Vít Jonáš / Daniel Munn / Karel Pičman'
description 'Document Management System Features' description 'Document Management System Features'
version '4.2.2' version '4.2.3'
requires_redmine version_or_higher: '6.0.0' requires_redmine version_or_higher: '6.1.0'
settings partial: 'settings/dmsf_settings', settings partial: 'settings/dmsf_settings',
default: { default: {

View File

@ -105,7 +105,9 @@ module Dav4rack
# path must be valid UTF-8 and will be url encoded by this method # path must be valid UTF-8 and will be url encoded by this method
def url_for(rel_path, collection: false) def url_for(rel_path, collection: false)
path = path_for rel_path, collection: collection path = path_for rel_path, collection: collection
"#{scheme}://#{host}:#{port}#{path}" # do not include the port when it's the standard http(s) port
skip_port = (port == 80 && scheme == 'http') || (port == 443 && scheme == 'https')
"#{scheme}://#{host}#{":#{port}" unless skip_port}#{path}"
end end
# returns an url encoded, absolute path for the given relative path # returns an url encoded, absolute path for the given relative path

View File

@ -34,7 +34,7 @@ module RedmineDmsf
html = +'' html = +''
container = context[:container] container = context[:container]
# Radio buttons # Radio buttons
if allowed_to_attach_documents(container) if allowed_to_attach_documents?(container)
html << '<p>' html << '<p>'
classes = +'inline' classes = +'inline'
html << "<label class=\"#{classes}\">" html << "<label class=\"#{classes}\">"
@ -64,7 +64,7 @@ module RedmineDmsf
end end
end end
# Upload form # Upload form
html << attach_documents_form(context, label: false) if allowed_to_attach_documents(container) html << attach_documents_form(context, label: false) if allowed_to_attach_documents?(container)
html html
end end
@ -94,7 +94,7 @@ module RedmineDmsf
def view_issues_edit_notes_bottom_style(context = {}) def view_issues_edit_notes_bottom_style(context = {})
if User.current.pref.dmsf_attachments_upload_choice == 'Attachments' || if User.current.pref.dmsf_attachments_upload_choice == 'Attachments' ||
!allowed_to_attach_documents(context[:container]) !allowed_to_attach_documents?(context[:container])
'' ''
else else
'display: none' 'display: none'
@ -103,7 +103,7 @@ module RedmineDmsf
private private
def allowed_to_attach_documents(container) def allowed_to_attach_documents?(container)
return false unless container.respond_to?(:project) && container.respond_to?(:saved_dmsf_attachments) && return false unless container.respond_to?(:project) && container.respond_to?(:saved_dmsf_attachments) &&
RedmineDmsf.dmsf_act_as_attachable? RedmineDmsf.dmsf_act_as_attachable?
@ -147,7 +147,7 @@ module RedmineDmsf
# Add Dmsf upload form # Add Dmsf upload form
container = context[:container] container = context[:container]
return unless allowed_to_attach_documents(container) return unless allowed_to_attach_documents?(container)
html = +'<p' html = +'<p'
html << ' style="display: none;"' if User.current.pref.dmsf_attachments_upload_choice == 'Attachments' html << ' style="display: none;"' if User.current.pref.dmsf_attachments_upload_choice == 'Attachments'

View File

@ -117,6 +117,7 @@ module RedmineDmsf
file = DmsfFile.visible.find_by(id: args[0]) file = DmsfFile.visible.find_by(id: args[0])
return "{{dmsfversion(#{args[0]})}}" unless file return "{{dmsfversion(#{args[0]})}}" unless file
unless User.current&.allowed_to?(:view_dmsf_files, file.project, { id: file.id }) unless User.current&.allowed_to?(:view_dmsf_files, file.project, { id: file.id })
raise ::I18n.t(:notice_not_authorized) raise ::I18n.t(:notice_not_authorized)
end end
@ -127,7 +128,7 @@ module RedmineDmsf
revision = DmsfFileRevision.find_by(id: args[1], dmsf_file_id: args[0]) revision = DmsfFileRevision.find_by(id: args[1], dmsf_file_id: args[0])
return "{{dmsfversion(#{args[0]}, #{args[1]})}}" unless revision return "{{dmsfversion(#{args[0]}, #{args[1]})}}" unless revision
end end
textilizable revision.version revision.version
end end
# dmsflastupdate - text referring to the document's last update date # dmsflastupdate - text referring to the document's last update date

View File

@ -562,6 +562,7 @@ module RedmineDmsf
else else
if last_revision if last_revision
new_revision = last_revision.dup new_revision = last_revision.dup
new_revision.reset_workflow
new_revision.source_revision = last_revision new_revision.source_revision = last_revision
else else
new_revision = DmsfFileRevision.new new_revision = DmsfFileRevision.new

View File

@ -23,8 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase class DmsfContextMenusControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_links, :dmsf_locks
def setup def setup
super super
@file_link2 = DmsfLink.find 2 @file_link2 = DmsfLink.find 2

View File

@ -25,9 +25,6 @@ class DmsfControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
include DmsfHelper include DmsfHelper
fixtures :custom_fields, :custom_values, :dmsf_links, :dmsf_folder_permissions, :dmsf_locks,
:dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@link2 = DmsfLink.find 2 @link2 = DmsfLink.find 2

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# DmsfFiles controller # DmsfFiles controller
class DmsfFilesControllerTest < RedmineDmsf::Test::TestCase class DmsfFilesControllerTest < RedmineDmsf::Test::TestCase
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks
def teardown def teardown
super super
DmsfFile.clear_previews DmsfFile.clear_previews

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Folder permissions controller # Folder permissions controller
class DmsfFolderPermissionsControllerTest < RedmineDmsf::Test::TestCase class DmsfFolderPermissionsControllerTest < RedmineDmsf::Test::TestCase
fixtures :dmsf_folder_permissions, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
post '/login', params: { username: 'jsmith', password: 'jsmith' } post '/login', params: { username: 'jsmith', password: 'jsmith' }

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Help controller # Help controller
class DmsfHelpControllerTest < RedmineDmsf::Test::TestCase class DmsfHelpControllerTest < RedmineDmsf::Test::TestCase
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_wiki_syntax def test_wiki_syntax
post '/login', params: { username: 'jsmith', password: 'jsmith' } post '/login', params: { username: 'jsmith', password: 'jsmith' }
get '/dmsf/help/wiki_syntax' get '/dmsf/help/wiki_syntax'

View File

@ -23,8 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase class DmsfLinksControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_links, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@file_link = DmsfLink.find 1 @file_link = DmsfLink.find 1

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Public URL controller # Public URL controller
class DmsfPublicUrlsControllerTest < RedmineDmsf::Test::TestCase class DmsfPublicUrlsControllerTest < RedmineDmsf::Test::TestCase
fixtures :dmsf_public_urls, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_show_valid_url def test_show_valid_url
get '/dmsf_public_urls', params: { token: 'd8d33e21914a433b280fdc94450ee212' } get '/dmsf_public_urls', params: { token: 'd8d33e21914a433b280fdc94450ee212' }
assert_response :success assert_response :success

View File

@ -23,8 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfStateControllerTest < RedmineDmsf::Test::TestCase class DmsfStateControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :queries
def setup def setup
super super
@query401 = Query.find 401 @query401 = Query.find 401

View File

@ -23,9 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_workflows, :dmsf_workflow_steps, :dmsf_workflow_step_assignments,
:dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks
def setup def setup
super super
@wfs1 = DmsfWorkflowStep.find 1 # step 1 @wfs1 = DmsfWorkflowStep.find 1 # step 1

View File

@ -21,10 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Issues controller # Issues controller
class IssuesControllerTest < RedmineDmsf::Test::TestCase class IssuesControllerTest < RedmineDmsf::Test::TestCase
fixtures :user_preferences, :issues, :versions, :trackers, :projects_trackers, :issue_statuses,
:enabled_modules, :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :enumerations,
:issue_categories
def setup def setup
super super
@issue1 = Issue.find 1 @issue1 = Issue.find 1

View File

@ -23,9 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class MyControllerTest < RedmineDmsf::Test::TestCase class MyControllerTest < RedmineDmsf::Test::TestCase
include Redmine::I18n include Redmine::I18n
fixtures :user_preferences, :dmsf_workflows, :dmsf_workflow_steps, :dmsf_workflow_step_assignments,
:dmsf_workflow_step_actions, :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks
def test_page_with_open_approvals_one_approval def test_page_with_open_approvals_one_approval
post '/login', params: { username: 'jsmith', password: 'jsmith' } post '/login', params: { username: 'jsmith', password: 'jsmith' }
DmsfFileRevision.where(id: 5).delete_all DmsfFileRevision.where(id: 5).delete_all

View File

@ -21,22 +21,15 @@ module RedmineDmsf
module Test module Test
# Helper test # Helper test
class HelperTest < ActiveSupport::TestCase class HelperTest < ActiveSupport::TestCase
fixtures :users, :email_addresses, :projects, :roles, :members, :member_roles def initialize(name)
super
# Allow us to override the fixtures method to implement fixtures for our plugin. # Load all plugin's fixtures
# Ultimately it allows for better integration without blowing redmine fixtures up,
# and allowing us to suppliment redmine fixtures if we need to.
def self.fixtures(*table_names)
dir = File.join(File.dirname(__FILE__), 'fixtures') dir = File.join(File.dirname(__FILE__), 'fixtures')
redmine_table_names = [] ext = '.yml'
table_names.each do |x| Dir.glob("#{dir}/**/*#{ext}").each do |file|
if File.exist?(File.join(dir, "#{x}.yml")) fixture = File.basename(file, ext)
ActiveRecord::FixtureSet.create_fixtures(dir, x) ActiveRecord::FixtureSet.create_fixtures dir, fixture
else
redmine_table_names << x
end
end end
super(redmine_table_names) if redmine_table_names.any?
end end
def setup def setup

View File

@ -23,8 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfHelperTest < RedmineDmsf::Test::HelperTest class DmsfHelperTest < RedmineDmsf::Test::HelperTest
include DmsfHelper include DmsfHelper
fixtures :dmsf_folders
def setup def setup
super super
@folder1 = DmsfFolder.find 1 @folder1 = DmsfFolder.find 1

View File

@ -25,8 +25,6 @@ class DmsfQueriesHelperTest < RedmineDmsf::Test::HelperTest
include ActionView::Helpers::NumberHelper include ActionView::Helpers::NumberHelper
include ActionView::Helpers::TagHelper include ActionView::Helpers::TagHelper
fixtures :dmsf_folders
def setup def setup
@folder1 = DmsfFolder.find 1 @folder1 = DmsfFolder.find 1
super super

View File

@ -23,8 +23,6 @@ require File.expand_path('../../../test_helper', __FILE__)
class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks, :dmsf_links
def setup def setup
super super
Setting.rest_api_enabled = '1' Setting.rest_api_enabled = '1'

View File

@ -23,8 +23,6 @@ require File.expand_path('../../../test_helper', __FILE__)
class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest class DmsfFileApiTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_files, :dmsf_file_revisions, :dmsf_locks, :custom_fields
def setup def setup
super super
Setting.rest_api_enabled = '1' Setting.rest_api_enabled = '1'

View File

@ -23,9 +23,6 @@ require File.expand_path('../../../test_helper', __FILE__)
class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest class DmsfFolderApiTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks, :dmsf_links, :custom_fields,
:custom_values
def setup def setup
super super
Setting.rest_api_enabled = '1' Setting.rest_api_enabled = '1'

View File

@ -23,8 +23,6 @@ require File.expand_path('../../../test_helper', __FILE__)
class DmsfLinkApiTest < RedmineDmsf::Test::IntegrationTest class DmsfLinkApiTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_files, :dmsf_file_revisions, :dmsf_links
def setup def setup
super super
Setting.rest_api_enabled = '1' Setting.rest_api_enabled = '1'

View File

@ -21,8 +21,6 @@ require File.expand_path('../../../test_helper', __FILE__)
# Custom middleware test # Custom middleware test
class DmsfWebdavCustomMiddlewareTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavCustomMiddlewareTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files
def test_options_for_root_path def test_options_for_root_path
process :options, '/' process :options, '/'
assert_response :method_not_allowed assert_response :method_not_allowed

View File

@ -23,8 +23,6 @@ require File.expand_path('../../../test_helper', __FILE__)
class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavDeleteTest < RedmineDmsf::Test::IntegrationTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks
def test_not_authenticated def test_not_authenticated
delete '/dmsf/webdav' delete '/dmsf/webdav'
assert_response :unauthorized assert_response :unauthorized

View File

@ -21,8 +21,6 @@ require File.expand_path('../../../test_helper', __FILE__)
# WebDAV GET test # WebDAV GET test
class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavGetTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_should_deny_anonymous def test_should_deny_anonymous
get '/dmsf/webdav' get '/dmsf/webdav'
assert_response :unauthorized assert_response :unauthorized

View File

@ -21,8 +21,6 @@ require File.expand_path('../../../test_helper', __FILE__)
# WebDAV HEAD tests # WebDAV HEAD tests
class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavHeadTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_head_requires_authentication def test_head_requires_authentication
head "/dmsf/webdav/#{@project1.identifier}" head "/dmsf/webdav/#{@project1.identifier}"
assert_response :unauthorized assert_response :unauthorized

View File

@ -22,8 +22,6 @@ require 'fileutils'
# WebDAV LOCK test # WebDAV LOCK test
class DmsfWebdavLockTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavLockTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks
def setup def setup
super super
@xml = %(<?xml version="1.0" encoding="utf-8" ?> @xml = %(<?xml version="1.0" encoding="utf-8" ?>

View File

@ -21,8 +21,6 @@ require File.expand_path('../../../test_helper', __FILE__)
# WebDAV MKCOL tests # WebDAV MKCOL tests
class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavMkcolTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders
def test_mkcol_requires_authentication def test_mkcol_requires_authentication
process :mkcol, '/dmsf/webdav/test1' process :mkcol, '/dmsf/webdav/test1'
assert_response :unauthorized assert_response :unauthorized

View File

@ -22,8 +22,6 @@ require 'fileutils'
# WebDAV MOVE tests # WebDAV MOVE tests
class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavMoveTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_move_denied_for_anonymous def test_move_denied_for_anonymous
new_name = "#{@file1.name}.moved" new_name = "#{@file1.name}.moved"
assert_no_difference '@file1.dmsf_file_revisions.count' do assert_no_difference '@file1.dmsf_file_revisions.count' do

View File

@ -21,8 +21,6 @@ require File.expand_path('../../../test_helper', __FILE__)
# WebDAV OPTIONS tests # WebDAV OPTIONS tests
class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavOptionsTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders
def test_options_requires_no_authentication_for_root_level def test_options_requires_no_authentication_for_root_level
process :options, '/dmsf/webdav' process :options, '/dmsf/webdav'
assert_response :success assert_response :success

View File

@ -21,7 +21,6 @@ require File.expand_path('../../../test_helper', __FILE__)
# WebDAV POST tests # WebDAV POST tests
class DmsfWebdavPostTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavPostTest < RedmineDmsf::Test::IntegrationTest
# Test that any post request is authenticated
def test_post_request_authenticated def test_post_request_authenticated
post '/dmsf/webdav/' post '/dmsf/webdav/'
assert_response :unauthorized assert_response :unauthorized

View File

@ -22,8 +22,6 @@ require 'uri'
# WebDAV PROPFIND tests # WebDAV PROPFIND tests
class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_propfind_denied_for_anonymous def test_propfind_denied_for_anonymous
process :propfind, '/dmsf/webdav/', params: nil, headers: @anonymous.merge!({ HTTP_DEPTH: '0' }) process :propfind, '/dmsf/webdav/', params: nil, headers: @anonymous.merge!({ HTTP_DEPTH: '0' })
assert_response :unauthorized assert_response :unauthorized
@ -32,21 +30,21 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
def test_propfind_depth0_on_root_for_user def test_propfind_depth0_on_root_for_user
process :propfind, '/dmsf/webdav/', params: nil, headers: @jsmith.merge!({ HTTP_DEPTH: '0' }) process :propfind, '/dmsf/webdav/', params: nil, headers: @jsmith.merge!({ HTTP_DEPTH: '0' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?('<d:href>http://www.example.com:80/dmsf/webdav/</d:href>') assert response.body.include?('<d:href>http://www.example.com/dmsf/webdav/</d:href>')
assert response.body.include?('<d:displayname>/</d:displayname>') assert response.body.include?('<d:displayname>/</d:displayname>')
end end
def test_propfind_depth1_on_root_for_user def test_propfind_depth1_on_root_for_user
process :propfind, '/dmsf/webdav/', params: nil, headers: @someone.merge!({ HTTP_DEPTH: '1' }) process :propfind, '/dmsf/webdav/', params: nil, headers: @someone.merge!({ HTTP_DEPTH: '1' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?('<d:href>http://www.example.com:80/dmsf/webdav/</d:href>') assert response.body.include?('<d:href>http://www.example.com/dmsf/webdav/</d:href>')
assert response.body.include?('<d:displayname>/</d:displayname>') assert response.body.include?('<d:displayname>/</d:displayname>')
end end
def test_propfind_depth0_on_root_for_admin def test_propfind_depth0_on_root_for_admin
process :propfind, '/dmsf/webdav/', params: nil, headers: @admin.merge!({ HTTP_DEPTH: '0' }) process :propfind, '/dmsf/webdav/', params: nil, headers: @admin.merge!({ HTTP_DEPTH: '0' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?('<d:href>http://www.example.com:80/dmsf/webdav/</d:href>') assert response.body.include?('<d:href>http://www.example.com/dmsf/webdav/</d:href>')
assert response.body.include?('<d:displayname>/</d:displayname>') assert response.body.include?('<d:displayname>/</d:displayname>')
end end
@ -56,17 +54,17 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
'dmsf_webdav_authentication' => 'Basic' } do 'dmsf_webdav_authentication' => 'Basic' } do
process :propfind, '/dmsf/webdav/', params: nil, headers: @admin.merge!({ HTTP_DEPTH: '1' }) process :propfind, '/dmsf/webdav/', params: nil, headers: @admin.merge!({ HTTP_DEPTH: '1' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?('<d:href>http://www.example.com:80/dmsf/webdav/</d:href>') assert response.body.include?('<d:href>http://www.example.com/dmsf/webdav/</d:href>')
assert response.body.include?('<d:displayname>/</d:displayname>') assert response.body.include?('<d:displayname>/</d:displayname>')
# project.identifier should not match when using project names # project.identifier should not match when using project names
assert_not response.body.include?( assert_not response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/</d:href>"
) )
assert_not response.body.include?("<d:displayname>#{@project1.identifier}</d:displayname>") assert_not response.body.include?("<d:displayname>#{@project1.identifier}</d:displayname>")
# but the project name should match # but the project name should match
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
project1_uri = Addressable::URI.escape(project1_name) project1_uri = Addressable::URI.escape(project1_name)
assert response.body.include?("<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/</d:href>") assert response.body.include?("<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/</d:href>")
assert response.body.include?("<d:displayname>#{project1_name}</d:displayname>") assert response.body.include?("<d:displayname>#{project1_name}</d:displayname>")
end end
end end
@ -96,7 +94,7 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
def test_propfind_depth0_on_project1_for_admin def test_propfind_depth0_on_project1_for_admin
process :propfind, "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '0' }) process :propfind, "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '0' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?("<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/</d:href>") assert response.body.include?("<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/</d:href>")
assert response.body.include?( assert response.body.include?(
"<d:displayname>#{RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)}</d:displayname>" "<d:displayname>#{RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)}</d:displayname>"
) )
@ -115,7 +113,7 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
project1_uri = Addressable::URI.escape(project1_name) project1_uri = Addressable::URI.escape(project1_name)
process :propfind, "/dmsf/webdav/#{project1_uri}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '0' }) process :propfind, "/dmsf/webdav/#{project1_uri}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '0' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?("<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/</d:href>") assert response.body.include?("<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/</d:href>")
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
assert response.body.include?("<d:displayname>#{project1_name}</d:displayname>") assert response.body.include?("<d:displayname>#{project1_name}</d:displayname>")
end end
@ -125,30 +123,30 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
process :propfind, "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '1' }) process :propfind, "/dmsf/webdav/#{@project1.identifier}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '1' })
assert_response :multi_status assert_response :multi_status
# Project # Project
assert response.body.include?("<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/</d:href>") assert response.body.include?("<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/</d:href>")
assert response.body.include?( assert response.body.include?(
"<d:displayname>#{RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)}</d:displayname>" "<d:displayname>#{RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)}</d:displayname>"
) )
# Folders # Folders
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}/</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@folder1.title}/</d:href>"
) )
assert response.body.include?("<d:displayname>#{@folder1.title}</d:displayname>") assert response.body.include?("<d:displayname>#{@folder1.title}</d:displayname>")
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}/</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@folder6.title}/</d:href>"
) )
assert response.body.include?("<d:displayname>#{@folder6.title}</d:displayname>") assert response.body.include?("<d:displayname>#{@folder6.title}</d:displayname>")
# Files # Files
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file1.name}</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@file1.name}</d:href>"
) )
assert response.body.include?("<d:displayname>#{@file1.name}</d:displayname>") assert response.body.include?("<d:displayname>#{@file1.name}</d:displayname>")
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file9.name}</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@file9.name}</d:href>"
) )
assert response.body.include?("<d:displayname>#{@file9.name}</d:displayname>") assert response.body.include?("<d:displayname>#{@file9.name}</d:displayname>")
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@file10.name}</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@file10.name}</d:href>"
) )
assert response.body.include?("<d:displayname>#{@file10.name}</d:displayname>") assert response.body.include?("<d:displayname>#{@file10.name}</d:displayname>")
end end
@ -167,29 +165,29 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
# Project # Project
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
project1_uri = Addressable::URI.escape(project1_name) project1_uri = Addressable::URI.escape(project1_name)
assert response.body.include?("<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/</d:href>") assert response.body.include?("<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/</d:href>")
# Folders # Folders
project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1) project1_name = RedmineDmsf::Webdav::ProjectResource.create_project_name(@project1)
project1_uri = Addressable::URI.escape(project1_name) project1_uri = Addressable::URI.escape(project1_name)
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/#{@folder1.title}/</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/#{@folder1.title}/</d:href>"
) )
assert response.body.include?("<d:displayname>#{@folder1.title}</d:displayname>") assert response.body.include?("<d:displayname>#{@folder1.title}</d:displayname>")
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/#{@folder6.title}/</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/#{@folder6.title}/</d:href>"
) )
assert response.body.include?("<d:displayname>#{@folder6.title}</d:displayname>") assert response.body.include?("<d:displayname>#{@folder6.title}</d:displayname>")
# Files # Files
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/#{@file1.name}</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/#{@file1.name}</d:href>"
) )
assert response.body.include?("<d:displayname>#{@file1.name}</d:displayname>") assert response.body.include?("<d:displayname>#{@file1.name}</d:displayname>")
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/#{@file9.name}</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/#{@file9.name}</d:href>"
) )
assert response.body.include?("<d:displayname>#{@file9.name}</d:displayname>") assert response.body.include?("<d:displayname>#{@file9.name}</d:displayname>")
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{project1_uri}/#{@file10.name}</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{project1_uri}/#{@file10.name}</d:href>"
) )
assert response.body.include?("<d:displayname>#{@file10.name}</d:displayname>") assert response.body.include?("<d:displayname>#{@file10.name}</d:displayname>")
end end
@ -203,7 +201,7 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
project1_new_uri = ERB::Util.url_encode(project1_new_name) project1_new_uri = ERB::Util.url_encode(project1_new_name)
process :propfind, "/dmsf/webdav/#{project1_new_uri}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '1' }) process :propfind, "/dmsf/webdav/#{project1_new_uri}", params: nil, headers: @admin.merge!({ HTTP_DEPTH: '1' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?("<d:href>http://www.example.com:80/dmsf/webdav/#{project1_new_uri}/</d:href>") assert response.body.include?("<d:href>http://www.example.com/dmsf/webdav/#{project1_new_uri}/</d:href>")
assert response.body.include?("<d:displayname>#{project1_new_name}</d:displayname>") assert response.body.include?("<d:displayname>#{project1_new_name}</d:displayname>")
end end
end end
@ -214,7 +212,7 @@ class DmsfWebdavPropfindTest < RedmineDmsf::Test::IntegrationTest
headers: @admin.merge!({ HTTP_DEPTH: '1' }) headers: @admin.merge!({ HTTP_DEPTH: '1' })
assert_response :multi_status assert_response :multi_status
assert response.body.include?( assert response.body.include?(
"<d:href>http://www.example.com:80/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/</d:href>" "<d:href>http://www.example.com/dmsf/webdav/#{@project1.identifier}/#{@project5.identifier}/</d:href>"
) )
assert response.body.include?( assert response.body.include?(
"<d:displayname>#{RedmineDmsf::Webdav::ProjectResource.create_project_name(@project5)}</d:displayname>" "<d:displayname>#{RedmineDmsf::Webdav::ProjectResource.create_project_name(@project5)}</d:displayname>"

View File

@ -22,8 +22,6 @@ require 'fileutils'
# WebDAV PUT tests # WebDAV PUT tests
class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavPutTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :custom_fields, :custom_values
def setup def setup
super super
@cv22 = CustomValue.find(22) @cv22 = CustomValue.find(22)

View File

@ -22,8 +22,6 @@ require 'fileutils'
# WebDAV UNLOCK tests # WebDAV UNLOCK tests
class DmsfWebdavUnlockTest < RedmineDmsf::Test::IntegrationTest class DmsfWebdavUnlockTest < RedmineDmsf::Test::IntegrationTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :dmsf_locks
def test_unlock_file def test_unlock_file
log_user 'admin', 'admin' log_user 'admin', 'admin'
l = @file2.locks.first l = @file2.locks.first

View File

@ -21,7 +21,16 @@ module RedmineDmsf
module Test module Test
# Integration test # Integration test
class IntegrationTest < Redmine::IntegrationTest class IntegrationTest < Redmine::IntegrationTest
fixtures :users, :email_addresses, :projects, :roles, :members, :member_roles def initialize(name)
super
# Load all plugin's fixtures
dir = File.join(File.dirname(__FILE__), 'fixtures')
ext = '.yml'
Dir.glob("#{dir}/**/*#{ext}").each do |file|
fixture = File.basename(file, ext)
ActiveRecord::FixtureSet.create_fixtures dir, fixture
end
end
def setup def setup
@admin = credentials('admin', 'admin') @admin = credentials('admin', 'admin')
@ -71,19 +80,6 @@ module RedmineDmsf
Rails.logger.error e.message Rails.logger.error e.message
end end
def self.fixtures(*table_names)
dir = File.join(File.dirname(__FILE__), 'fixtures')
redmine_table_names = []
table_names.each do |x|
if File.exist?(File.join(dir, "#{x}.yml"))
ActiveRecord::FixtureSet.create_fixtures(dir, x)
else
redmine_table_names << x
end
end
super(redmine_table_names) if redmine_table_names.any?
end
protected protected
def check_headers_exist def check_headers_exist

View File

@ -21,22 +21,15 @@ module RedmineDmsf
module Test module Test
# Test case # Test case
class TestCase < ActionDispatch::IntegrationTest class TestCase < ActionDispatch::IntegrationTest
fixtures :users, :email_addresses, :projects, :roles, :members, :member_roles def initialize(name)
super
# Allow us to override the fixtures method to implement fixtures for our plugin. # Load all plugin's fixtures
# Ultimately it allows for better integration without blowing redmine fixtures up,
# and allowing us to suppliment redmine fixtures if we need to.
def self.fixtures(*table_names)
dir = File.join(File.dirname(__FILE__), 'fixtures') dir = File.join(File.dirname(__FILE__), 'fixtures')
redmine_table_names = [] ext = '.yml'
table_names.each do |x| Dir.glob("#{dir}/**/*#{ext}").each do |file|
if File.exist?(File.join(dir, "#{x}.yml")) fixture = File.basename(file, ext)
ActiveRecord::FixtureSet.create_fixtures(dir, x) ActiveRecord::FixtureSet.create_fixtures dir, fixture
else
redmine_table_names << x
end
end end
super(redmine_table_names) if redmine_table_names.any?
end end
def setup def setup

View File

@ -21,7 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# File revision tests # File revision tests
class CustomFieldDmsfFileFormatTest < RedmineDmsf::Test::UnitTest class CustomFieldDmsfFileFormatTest < RedmineDmsf::Test::UnitTest
fixtures :custom_fields, :projects, :issues, :trackers
def setup def setup
super super
User.current = @jsmith User.current = @jsmith

View File

@ -23,8 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_locks, :dmsf_workflows, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@revision1 = DmsfFileRevision.find 1 @revision1 = DmsfFileRevision.find 1
@ -316,4 +314,27 @@ class DmsfFileRevisionTest < RedmineDmsf::Test::UnitTest
assert h.is_a?(Hash) assert h.is_a?(Hash)
assert_nil h['90'] assert_nil h['90']
end end
def test_set_workflow
@revision2.set_workflow @wf1.id, 'assign'
assert_equal DmsfWorkflow::STATE_ASSIGNED, @revision2.workflow
assert_equal User.current, @revision2.dmsf_workflow_assigned_by_user
assert @revision2.dmsf_workflow_assigned_at
@revision2.set_workflow @wf1.id, 'start'
assert_equal DmsfWorkflow::STATE_WAITING_FOR_APPROVAL, @revision2.workflow
assert_equal User.current, @revision2.dmsf_workflow_started_by_user
assert @revision2.dmsf_workflow_started_at
end
def test_reset_workflow
@revision2.set_workflow @wf1.id, 'assign'
@revision2.set_workflow @wf1.id, 'start'
@revision2.reset_workflow
assert_nil @revision2.workflow
assert_nil @revision2.dmsf_workflow_id
assert_nil @revision2.dmsf_workflow_assigned_by_user_id
assert_nil @revision2.dmsf_workflow_assigned_at
assert_nil @revision2.dmsf_workflow_started_by_user_id
assert_nil @revision2.dmsf_workflow_started_at
end
end end

View File

@ -21,9 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# File tests # File tests
class DmsfFileTest < RedmineDmsf::Test::UnitTest class DmsfFileTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_locks, :issues, :dmsf_links, :dmsf_workflows, :dmsf_workflow_steps,
:dmsf_workflow_step_assignments, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@issue1 = Issue.find 1 @issue1 = Issue.find 1

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Folder permissions tests # Folder permissions tests
class DmsfFolderPermissionTest < RedmineDmsf::Test::UnitTest class DmsfFolderPermissionTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_folder_permissions, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@permission1 = DmsfFolderPermission.find 1 @permission1 = DmsfFolderPermission.find 1

View File

@ -21,9 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Folder tests # Folder tests
class DmsfFolderTest < RedmineDmsf::Test::UnitTest class DmsfFolderTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_folder_permissions, :dmsf_locks, :dmsf_folders, :dmsf_files, :dmsf_file_revisions,
:dmsf_links
def setup def setup
super super
@link2 = DmsfLink.find 2 @link2 = DmsfLink.find 2

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Link tests # Link tests
class DmsfLinksTest < RedmineDmsf::Test::UnitTest class DmsfLinksTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_links, :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :custom_fields, :custom_values
def test_create_folder_link def test_create_folder_link
folder_link = DmsfLink.new folder_link = DmsfLink.new
folder_link.target_project_id = @project1.id folder_link.target_project_id = @project1.id

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper.rb', __FILE__)
# Lock tests # Lock tests
class DmsfLockTest < RedmineDmsf::Test::UnitTest class DmsfLockTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_locks, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@lock = DmsfLock.find 1 @lock = DmsfLock.find 1

View File

@ -23,8 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfMailerTest < RedmineDmsf::Test::UnitTest class DmsfMailerTest < RedmineDmsf::Test::UnitTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_workflows, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@file1.notify_activate @file1.notify_activate

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Public URL tests # Public URL tests
class DmsfPublicUrlsTest < RedmineDmsf::Test::UnitTest class DmsfPublicUrlsTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_public_urls, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@dmsf_public_url1 = DmsfPublicUrl.find 1 @dmsf_public_url1 = DmsfPublicUrl.find 1

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Query tests # Query tests
class DmsfQueryTest < RedmineDmsf::Test::UnitTest class DmsfQueryTest < RedmineDmsf::Test::UnitTest
fixtures :queries, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@query401 = Query.find 401 @query401 = Query.find 401

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Upload tests # Upload tests
class DmsfUploadTest < RedmineDmsf::Test::UnitTest class DmsfUploadTest < RedmineDmsf::Test::UnitTest
fixtures :projects
def setup def setup
super super
@uploaded = { @uploaded = {

View File

@ -23,9 +23,6 @@ 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, :dmsf_workflow_step_actions, :dmsf_folders, :dmsf_files,
:dmsf_file_revisions
def setup def setup
@wfsac1 = DmsfWorkflowStepAction.find 1 @wfsac1 = DmsfWorkflowStepAction.find 1
@wfsac2 = DmsfWorkflowStepAction.find 2 @wfsac2 = DmsfWorkflowStepAction.find 2

View File

@ -21,9 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Workflow step assignment tests # Workflow step assignment tests
class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_workflow_steps, :dmsf_workflow_step_assignments, :dmsf_folders, :dmsf_files,
:dmsf_file_revisions
def setup def setup
@wfsa1 = DmsfWorkflowStepAssignment.find 1 @wfsa1 = DmsfWorkflowStepAssignment.find 1
@wfsa2 = DmsfWorkflowStepAssignment.find 2 @wfsa2 = DmsfWorkflowStepAssignment.find 2

View File

@ -23,8 +23,6 @@ require File.expand_path('../../test_helper', __FILE__)
class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest
include Redmine::I18n include Redmine::I18n
fixtures :dmsf_workflows, :dmsf_workflow_steps, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
@wfs1 = DmsfWorkflowStep.find 1 @wfs1 = DmsfWorkflowStep.find 1
@wfs2 = DmsfWorkflowStep.find 2 @wfs2 = DmsfWorkflowStep.find 2

View File

@ -21,9 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Workflow tests # Workflow tests
class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_file_revisions, :dmsf_workflows, :dmsf_workflow_steps, :dmsf_workflow_step_assignments,
:dmsf_workflow_step_actions, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
super super
@wf1 = DmsfWorkflow.find 1 @wf1 = DmsfWorkflow.find 1

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# Issue tests # Issue tests
class IssuePatchTest < RedmineDmsf::Test::UnitTest class IssuePatchTest < RedmineDmsf::Test::UnitTest
fixtures :issues, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def setup def setup
@issue1 = Issue.find 1 @issue1 = Issue.find 1
end end

View File

@ -21,8 +21,6 @@ require File.expand_path('../../../../test_helper', __FILE__)
# Macros tests # Macros tests
class DmsfMacrosTest < RedmineDmsf::Test::HelperTest class DmsfMacrosTest < RedmineDmsf::Test::HelperTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
# Mock view context for macros # Mock view context for macros
class DmsfView class DmsfView
include ApplicationHelper include ApplicationHelper

View File

@ -22,7 +22,6 @@ require File.expand_path('../../../../../lib/redmine_dmsf/dmsf_zip', __FILE__)
# Plugin tests # Plugin tests
class DmsfZipTest < RedmineDmsf::Test::HelperTest class DmsfZipTest < RedmineDmsf::Test::HelperTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions, :attachments
def setup def setup
@zip = RedmineDmsf::DmsfZip::Zip.new @zip = RedmineDmsf::DmsfZip::Zip.new

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# project tests # project tests
class ProjectPatchTest < RedmineDmsf::Test::UnitTest class ProjectPatchTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_links, :dmsf_workflows, :dmsf_locks, :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_project_has_dmsf_files def test_project_has_dmsf_files
assert @project1.respond_to?(:dmsf_files) assert @project1.respond_to?(:dmsf_files)
end end

View File

@ -21,10 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# User tests # User tests
class UserPatchTest < RedmineDmsf::Test::UnitTest class UserPatchTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_links, :dmsf_locks, :dmsf_workflows, :dmsf_workflow_steps,
:dmsf_workflow_step_assignments, :dmsf_workflow_step_actions, :dmsf_folders,
:dmsf_files, :dmsf_file_revisions, :custom_fields, :custom_values
def test_remove_dmsf_references def test_remove_dmsf_references
id = @jsmith.id id = @jsmith.id
@jsmith.destroy @jsmith.destroy

View File

@ -21,8 +21,6 @@ require File.expand_path('../../test_helper', __FILE__)
# User preference tests # User preference tests
class UserPreferencePatchTest < RedmineDmsf::Test::UnitTest class UserPreferencePatchTest < RedmineDmsf::Test::UnitTest
fixtures :dmsf_folders, :dmsf_files, :dmsf_file_revisions
def test_user_preference_has_dmsf_attachments_upload_choice def test_user_preference_has_dmsf_attachments_upload_choice
assert @jsmith.pref.respond_to?(:dmsf_attachments_upload_choice) assert @jsmith.pref.respond_to?(:dmsf_attachments_upload_choice)
end end

View File

@ -21,7 +21,16 @@ module RedmineDmsf
module Test module Test
# Unit test # Unit test
class UnitTest < ActiveSupport::TestCase class UnitTest < ActiveSupport::TestCase
fixtures :users, :email_addresses, :projects, :roles, :members, :member_roles def initialize(name)
super
# Load all plugin's fixtures
dir = File.join(File.dirname(__FILE__), 'fixtures')
ext = '.yml'
Dir.glob("#{dir}/**/*#{ext}").each do |file|
fixture = File.basename(file, ext)
ActiveRecord::FixtureSet.create_fixtures dir, fixture
end
end
def setup def setup
@admin = User.find_by(login: 'admin') @admin = User.find_by(login: 'admin')
@ -71,22 +80,6 @@ module RedmineDmsf
Rails.logger.error e.message Rails.logger.error e.message
end end
# Allow us to override the fixtures method to implement fixtures for our plugin.
# Ultimately it allows for better integration without blowing redmine fixtures up,
# and allowing us to suppliment redmine fixtures if we need to.
def self.fixtures(*table_names)
dir = File.join(File.dirname(__FILE__), 'fixtures')
redmine_table_names = []
table_names.each do |x|
if File.exist?(File.join(dir, "#{x}.yml"))
ActiveRecord::FixtureSet.create_fixtures(dir, x)
else
redmine_table_names << x
end
end
super(redmine_table_names) if redmine_table_names.any?
end
protected protected
def last_email def last_email