From 0b40abb821739fb7706e26eafa33c69dc06ba7a3 Mon Sep 17 00:00:00 2001 From: Karel Picman Date: Thu, 9 May 2013 12:17:12 +0200 Subject: [PATCH] Approval workflows copied fron 1.5.0 devel --- app/controllers/dmsf_workflows_controller.rb | 171 ++++++++++++++++++ app/helpers/dmsf_workflows_helper.rb | 45 +++++ app/models/dmsf_workflow.rb | 110 +++++++++++ app/models/dmsf_workflow_step.rb | 37 ++++ app/models/dmsf_workflow_step_action.rb | 24 +++ app/models/dmsf_workflow_step_assignment.rb | 26 +++ app/views/dmsf_workflows/_action.html.erb | 33 ++++ app/views/dmsf_workflows/_main.html.erb | 32 ++++ app/views/dmsf_workflows/_steps.html.erb | 81 +++++++++ app/views/dmsf_workflows/action.html.erb | 1 + app/views/dmsf_workflows/action.js.erb | 3 + app/views/dmsf_workflows/add_step.html.erb | 1 + .../autocomplete_for_user.js.erb | 1 + app/views/dmsf_workflows/edit.html.erb | 1 + app/views/dmsf_workflows/index.html.erb | 1 + app/views/dmsf_workflows/log.html.erb | 1 + app/views/dmsf_workflows/new.html.erb | 12 ++ app/views/dmsf_workflows/remove_step.html.erb | 1 + .../dmsf_workflows/reorder_steps.html.erb | 1 + assets/images/ticket_go.png | Bin 0 -> 608 bytes assets/javascripts/dmsf.css | 50 +++++ assets/stylesheets/dmsf.css | 5 + config/locales/en.yml | 17 ++ config/routes.rb | 13 ++ .../20120822100401_create_dmsf_workflows.rb | 13 ++ ...120822100402_create_dmsf_workflow_steps.rb | 15 ++ ...3_create_dmsf_workflow_step_assignments.rb | 17 ++ ...00404_create_dmsf_workflow_step_actions.rb | 17 ++ init.rb | 13 ++ lib/redmine_dmsf/patches/project_patch.rb | 2 +- .../patches/project_tabs_extended.rb | 5 +- test/fixtures/dmsf_workflow_step_actions.yml | 22 +++ .../dmsf_workflow_step_assignments.yml | 6 + test/fixtures/dmsf_workflow_steps.yml | 21 +++ test/fixtures/dmsf_workflows.yml | 8 + .../dmsf_workflow_controller_test.rb | 171 ++++++++++++++++++ test/unit/dmsf_workflow_step_action_test.rb | 60 ++++++ .../dmsf_workflow_step_assignment_test.rb | 53 ++++++ test/unit/dmsf_workflow_step_test.rb | 76 ++++++++ test/unit/dmsf_workflow_test.rb | 54 ++++++ 40 files changed, 1217 insertions(+), 3 deletions(-) create mode 100644 app/controllers/dmsf_workflows_controller.rb create mode 100644 app/helpers/dmsf_workflows_helper.rb create mode 100644 app/models/dmsf_workflow.rb create mode 100644 app/models/dmsf_workflow_step.rb create mode 100644 app/models/dmsf_workflow_step_action.rb create mode 100644 app/models/dmsf_workflow_step_assignment.rb create mode 100644 app/views/dmsf_workflows/_action.html.erb create mode 100644 app/views/dmsf_workflows/_main.html.erb create mode 100644 app/views/dmsf_workflows/_steps.html.erb create mode 100644 app/views/dmsf_workflows/action.html.erb create mode 100644 app/views/dmsf_workflows/action.js.erb create mode 100644 app/views/dmsf_workflows/add_step.html.erb create mode 100644 app/views/dmsf_workflows/autocomplete_for_user.js.erb create mode 100644 app/views/dmsf_workflows/edit.html.erb create mode 100644 app/views/dmsf_workflows/index.html.erb create mode 100644 app/views/dmsf_workflows/log.html.erb create mode 100644 app/views/dmsf_workflows/new.html.erb create mode 100644 app/views/dmsf_workflows/remove_step.html.erb create mode 100644 app/views/dmsf_workflows/reorder_steps.html.erb create mode 100644 assets/images/ticket_go.png create mode 100644 assets/javascripts/dmsf.css create mode 100644 db/migrate/20120822100401_create_dmsf_workflows.rb create mode 100644 db/migrate/20120822100402_create_dmsf_workflow_steps.rb create mode 100644 db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb create mode 100644 db/migrate/20120822100404_create_dmsf_workflow_step_actions.rb create mode 100644 test/fixtures/dmsf_workflow_step_actions.yml create mode 100644 test/fixtures/dmsf_workflow_step_assignments.yml create mode 100644 test/fixtures/dmsf_workflow_steps.yml create mode 100644 test/fixtures/dmsf_workflows.yml create mode 100644 test/functional/dmsf_workflow_controller_test.rb create mode 100644 test/unit/dmsf_workflow_step_action_test.rb create mode 100644 test/unit/dmsf_workflow_step_assignment_test.rb create mode 100644 test/unit/dmsf_workflow_step_test.rb create mode 100644 test/unit/dmsf_workflow_test.rb diff --git a/app/controllers/dmsf_workflows_controller.rb b/app/controllers/dmsf_workflows_controller.rb new file mode 100644 index 00000000..34ca0555 --- /dev/null +++ b/app/controllers/dmsf_workflows_controller.rb @@ -0,0 +1,171 @@ +# Redmine plugin for Document Management System "Features" +# +# Copyright (C) 2013 Karel Picman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class DmsfWorkflowsController < ApplicationController + unloadable + layout :workflows_layout + + before_filter :find_workflow, :except => [:create, :new, :index] + before_filter :find_project + before_filter :authorize_global, :except => [:action, :new_action] + + def index + if @project + @workflow_pages, @workflows = paginate DmsfWorkflow.where(:project_id => @project.id), :per_page => 25 + else + @workflow_pages, @workflows = paginate DmsfWorkflow.where(:project_id => nil), :per_page => 25 + end + end + + def action + end + + def new_action + logger.info '>>>>>>>>>>>>>>>>>>>>>>> YES!' + end + + def log + end + + def new + @workflow = DmsfWorkflow.new + end + + def create + @workflow = DmsfWorkflow.new(:name => params[:dmsf_workflow][:name], :project_id => params[:project_id]) + if request.post? && @workflow.save + flash[:notice] = l(:notice_successful_create) + if @project + redirect_to settings_project_path(@project, :tab => 'dmsf') + else + redirect_to dmsf_workflows_path + end + else + render :action => 'new' + end + end + + def edit + end + + def update + if request.put? && @workflow.update_attributes({:name => params[:dmsf_workflow][:name]}) + flash[:notice] = l(:notice_successful_update) + if @project + redirect_to settings_project_path(@project, :tab => 'dmsf') + else + redirect_to dmsf_workflows_path + end + else + render :action => 'edit' + end + end + + def destroy + begin + @workflow.destroy + rescue + flash[:error] = l(:error_unable_delete_dmsf_workflow) + end + if @project + redirect_to settings_project_path(@project, :tab => 'dmsf') + else + redirect_to dmsf_workflows_path + end + end + + def autocomplete_for_user + respond_to do |format| + format.js + end + end + + def add_step + if request.post? + users = User.find_all_by_id(params[:user_ids]) + if params[:step] == '0' + if @workflow.steps.count > 0 + step = @workflow.steps.last + 1 + else + step = 1 + end + else + step = params[:step].to_i + end + operator = 1 ? params[:commit] == l(:dmsf_and) : 0 + users.each do |user| + @workflow.dmsf_workflow_steps << DmsfWorkflowStep.new( + :dmsf_workflow_id => @workflow.id, + :step => step, + :user_id => user.id, + :operator => operator) + end + @workflow.save + end + respond_to do |format| + format.html + end + end + + def remove_step + if request.delete? + DmsfWorkflowStep.where(:dmsf_workflow_id => @workflow.id, :step => params[:step]).each do |ws| + @workflow.dmsf_workflow_steps.delete(ws) + end + @workflow.dmsf_workflow_steps.each do |ws| + n = ws.step.to_i + if n > params[:step].to_i + ws.step = n - 1 + ws.save + end + end + end + respond_to do |format| + format.html + end + end + + def reorder_steps + if request.put? + @workflow.reorder_steps params[:step].to_i, params[:workflow_step][:move_to] + end + respond_to do |format| + format.html + end + end + + private + + def find_workflow + @workflow = DmsfWorkflow.find_by_id(params[:id]) + end + + def find_project + if @workflow + @project = @workflow.project + elsif params[:project_id].present? + @project = Project.find_by_id params[:project_id] + end + end + + def workflows_layout + find_workflow + find_project + @project ? 'base' : 'admin' + end +end diff --git a/app/helpers/dmsf_workflows_helper.rb b/app/helpers/dmsf_workflows_helper.rb new file mode 100644 index 00000000..c61c2ac5 --- /dev/null +++ b/app/helpers/dmsf_workflows_helper.rb @@ -0,0 +1,45 @@ +# Redmine plugin for Document Management System "Features" +# +# Copyright (C) 2013 Karel Picman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +module DmsfWorkflowsHelper + + def render_principals_for_new_dmsf_workflow_users(workflow) + scope = User.active.sorted.like(params[:q]) + principal_count = scope.count + principal_pages = Redmine::Pagination::Paginator.new principal_count, 100, params['page'] + principals = scope.offset(principal_pages.offset).limit(principal_pages.per_page).all + + s = content_tag('div', principals_check_box_tags('user_ids[]', principals), :id => 'principals') + + links = pagination_links_full(principal_pages, principal_count, :per_page_links => false) {|text, parameters, options| + link_to text, autocomplete_for_user_dmsf_workflow_path(workflow, parameters.merge(:q => params[:q], :format => 'js')), :remote => true + } + + s + content_tag('p', links, :class => 'pagination') + end + + def dmsf_workflow_steps_options_for_select(steps) + options = Array.new + options << [l(:dmsf_new_step), 0] + steps.each do |step| + options << [step.to_s, step] + end + options_for_select(options, 0) + end + +end diff --git a/app/models/dmsf_workflow.rb b/app/models/dmsf_workflow.rb new file mode 100644 index 00000000..cb214588 --- /dev/null +++ b/app/models/dmsf_workflow.rb @@ -0,0 +1,110 @@ +# Redmine plugin for Document Management System "Features" +# +# Copyright (C) 2013 Karel Picman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class DmsfWorkflow < ActiveRecord::Base + belongs_to :project + + has_many :dmsf_workflow_steps, :dependent => :destroy + + validates_uniqueness_of :name + validates :name, :presence => true + validates_length_of :name, :maximum => 255 + + def self.workflows(project) + project ? where(:project_id => project) : where('project_id IS NULL') + end + + def project + @project = Project.find_by_id(project_id) unless @project + @project + end + + def to_s + name + end + + def approvals(step) + wa = Array.new + dmsf_workflow_steps.each do |s| + if s.step == step + wa << s + end + end + wa.sort_by { |obj| -obj.operator } + end + + def steps + ws = Array.new + dmsf_workflow_steps.each do |s| + unless ws.include? s.step + ws << s.step + end + end + ws.sort + end + + def reorder_steps(step, move_to) + case move_to + when 'highest' + unless step == 1 + dmsf_workflow_steps.each do |ws| + if ws.step < step + ws.update_attribute('step', ws.step + 1) + elsif ws.step == step + ws.update_attribute('step', 1) + end + end + end + when 'higher' + unless step == 1 + dmsf_workflow_steps.each do |ws| + if ws.step == step - 1 + ws.update_attribute('step', step) + elsif ws.step == step + ws.update_attribute('step', step - 1) + end + end + end + when 'lower' + unless step == steps.count + dmsf_workflow_steps.each do |ws| + if ws.step == step + 1 + ws.update_attribute('step', step) + elsif ws.step == step + ws.update_attribute('step', step + 1) + end + end + end + when 'lowest' + size = steps.count + unless step == size + dmsf_workflow_steps.each do |ws| + if ws.step > step + ws.update_attribute('step', ws.step - 1) + elsif ws.step == step + ws.update_attribute('step', size) + end + end + end + end + end + + def delegates + User.all + end +end \ No newline at end of file diff --git a/app/models/dmsf_workflow_step.rb b/app/models/dmsf_workflow_step.rb new file mode 100644 index 00000000..4d33a284 --- /dev/null +++ b/app/models/dmsf_workflow_step.rb @@ -0,0 +1,37 @@ +# Redmine plugin for Document Management System "Features" +# +# Copyright (C) 2013 Karel Picman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class DmsfWorkflowStep < ActiveRecord::Base + belongs_to :workflow + + has_many :dmsf_workflow_step_assignments, :dependent => :destroy + + validates :dmsf_workflow_id, :presence => true + validates :step, :presence => true + validates :user_id, :presence => true + validates :operator, :presence => true + validates_uniqueness_of :user_id, :scope => [:dmsf_workflow_id, :step] + + def soperator + operator == 1 ? l(:dmsf_and) : l(:dmsf_or) + end + + def user + User.find(user_id) + end +end \ No newline at end of file diff --git a/app/models/dmsf_workflow_step_action.rb b/app/models/dmsf_workflow_step_action.rb new file mode 100644 index 00000000..bdc10ee1 --- /dev/null +++ b/app/models/dmsf_workflow_step_action.rb @@ -0,0 +1,24 @@ +# Redmine plugin for Document Management System "Features" +# +# Copyright (C) 2013 Karel Picman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class DmsfWorkflowStepAction < ActiveRecord::Base + belongs_to :dmsf_workflow_step_assignment + + validates :dmsf_workflow_step_assignment_id, :presence => true + validates :action, :presence => true +end \ No newline at end of file diff --git a/app/models/dmsf_workflow_step_assignment.rb b/app/models/dmsf_workflow_step_assignment.rb new file mode 100644 index 00000000..1ffc5250 --- /dev/null +++ b/app/models/dmsf_workflow_step_assignment.rb @@ -0,0 +1,26 @@ +# Redmine plugin for Document Management System "Features" +# +# Copyright (C) 2013 Karel Picman +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +class DmsfWorkflowStepAssignment < ActiveRecord::Base + belongs_to :dmsf_workflow_step + + has_many :dmsf_workflow_step_actions, :dependent => :destroy + + validates :dmsf_workflow_step_id, :presence => true + validates :dmsf_file_revision_id, :presence => true +end \ No newline at end of file diff --git a/app/views/dmsf_workflows/_action.html.erb b/app/views/dmsf_workflows/_action.html.erb new file mode 100644 index 00000000..99b49e6e --- /dev/null +++ b/app/views/dmsf_workflows/_action.html.erb @@ -0,0 +1,33 @@ +

<%= l(:label_dmsf_workflow) %>

+ +<%= form_tag({:controller => 'dmsf_workflows', + :action => 'new_action', + :object_type => DmsfWorkflow, + :object_id => @workflow, + :project_id => @project}, + :remote => true, + :method => :post, + :id => 'new-action-form') do %> +


+ +

+
+ <%= text_area_tag :note, '', :placeholder => l(:message_dmsf_wokflow_note), :size => '38x2' %> +

+ +

+
+ <%= text_field_tag 'user_search', nil %> +

+ + <%= javascript_tag "observeSearchfield('user_search', 'users_for_delegate', '#{ escape_javascript autocomplete_for_user_dmsf_workflow_path(@workflow) }')" %> + +
+ <%= principals_check_box_tags 'watcher[user_ids][]', @workflow.delegates %> +
+ +

+ <%= submit_tag l(:button_add), :name => nil, :onclick => "hideModal(this);" %> + <%= submit_tag l(:button_cancel), :name => nil, :onclick => "hideModal(this);", :type => 'button' %> +

+<% end %> diff --git a/app/views/dmsf_workflows/_main.html.erb b/app/views/dmsf_workflows/_main.html.erb new file mode 100644 index 00000000..8e96b5ad --- /dev/null +++ b/app/views/dmsf_workflows/_main.html.erb @@ -0,0 +1,32 @@ +<% @workflows = DmsfWorkflow.where(:project_id => @project.id) if @project && @workflows.nil? %> + +
+<% if @project %> + <%= link_to l(:label_dmsf_workflow_new), new_dmsf_workflow_path(:project_id => @project.id), :class => 'icon icon-add' %> +<% else %> + <%= link_to l(:label_dmsf_workflow_new), new_dmsf_workflow_path, :class => 'icon icon-add' %> +<% end %> +
+ +

<%=l(:label_dmsf_workflow_plural)%>

+ + + + + + + +<% for workflow in @workflows %> + + + + +<% end %> + +
<%=l(:field_name)%>
<%= link_to(h(workflow.name), edit_dmsf_workflow_path(workflow)) %> + <%= delete_link dmsf_workflow_path(workflow) %> +
+ +<% if @workflow_pages %> +

<%= pagination_links_full @workflow_pages %>

+<% end %> \ No newline at end of file diff --git a/app/views/dmsf_workflows/_steps.html.erb b/app/views/dmsf_workflows/_steps.html.erb new file mode 100644 index 00000000..70afad2a --- /dev/null +++ b/app/views/dmsf_workflows/_steps.html.erb @@ -0,0 +1,81 @@ +<% if @workflow.project %> +

<%= link_to l(:label_dmsf_workflow_plural), settings_project_path(@project, :tab => 'dmsf') %> » <%=h @workflow %>

+<% else %> +

<%= link_to l(:label_dmsf_workflow_plural), dmsf_workflows_path %> » <%=h @workflow %>

+<% end %> + +<% if @project %> +
+ <%= link_to 'Action', action_dmsf_workflow_path(:project_id => @project.id, :id => @workflow, :step => 1), :remote => true %> +
+<% end %> + +<%= labelled_form_for @workflow do |f| %> + <%= error_messages_for 'workflow' %> +
+

<%= f.text_field :name, :required => true %><%= submit_tag l(:button_save) %>

+
+<% end %> + +
+ +
+<% if @workflow.steps.any? %> + + + + + + + + + <% @workflow.steps.each do |step| %> + + + + + + + <% end; reset_cycle %> + +
<%= l(:label_dmsf_workflow_step) %><%= l(:label_dmsf_workflow_approval_plural) %><%=l(:button_sort)%>
<%= step %> + <% @workflow.approvals(step).each_with_index do |approval, i| %> + <% if i != 0 %> + <%= approval.soperator %>  + <% end %> + <%= link_to_user approval.user %> + <% end %> + + <%= reorder_links('workflow_step', {:action => 'edit', :id => @workflow, :step => step}, :put) %> + + <%= delete_link edit_dmsf_workflow_path(@workflow, :step => step) %> +
+<% else %> +

<%= l(:label_no_data) %>

+<% end %> +
+ +
+ <%= form_for(@workflow, :url => edit_dmsf_workflow_path(@workflow), + :html => {:method => :post}) do |f| %> +
<%=l(:label_user_new)%> + +

<%= label_tag 'user_search', l(:label_user_search) %><%= text_field_tag 'user_search', nil %>

+ <%= javascript_tag "observeSearchfield('user_search', null, '#{ escape_javascript autocomplete_for_user_dmsf_workflow_path(@workflow) }')" %> + +
+ <%= render_principals_for_new_dmsf_workflow_users(@workflow) %> +
+ +

+ <%= l(:label_dmsf_workflow_step) %> + <%= select_tag 'step', + dmsf_workflow_steps_options_for_select(@workflow.steps), + :id => 'selected_step', :style => "width:100px" %> +

+

<%= submit_tag l(:dmsf_and) %> <%= submit_tag l(:dmsf_or) %>

+
+ <% end %> +
+ +
\ No newline at end of file diff --git a/app/views/dmsf_workflows/action.html.erb b/app/views/dmsf_workflows/action.html.erb new file mode 100644 index 00000000..d1a62773 --- /dev/null +++ b/app/views/dmsf_workflows/action.html.erb @@ -0,0 +1 @@ +

WorkflowController#action

diff --git a/app/views/dmsf_workflows/action.js.erb b/app/views/dmsf_workflows/action.js.erb new file mode 100644 index 00000000..107ab390 --- /dev/null +++ b/app/views/dmsf_workflows/action.js.erb @@ -0,0 +1,3 @@ +$('#ajax-modal').html('<%= escape_javascript(render :partial => 'action', :locals => {:workflow => @workflow}) %>'); +showModal('ajax-modal', '400px'); +$('#ajax-modal').addClass('new-action'); diff --git a/app/views/dmsf_workflows/add_step.html.erb b/app/views/dmsf_workflows/add_step.html.erb new file mode 100644 index 00000000..88143721 --- /dev/null +++ b/app/views/dmsf_workflows/add_step.html.erb @@ -0,0 +1 @@ +<%= render 'steps' %> \ No newline at end of file diff --git a/app/views/dmsf_workflows/autocomplete_for_user.js.erb b/app/views/dmsf_workflows/autocomplete_for_user.js.erb new file mode 100644 index 00000000..e74e6b4c --- /dev/null +++ b/app/views/dmsf_workflows/autocomplete_for_user.js.erb @@ -0,0 +1 @@ +$('#users').html('<%= escape_javascript(render_principals_for_new_dmsf_workflow_users(@workflow)) %>'); diff --git a/app/views/dmsf_workflows/edit.html.erb b/app/views/dmsf_workflows/edit.html.erb new file mode 100644 index 00000000..88143721 --- /dev/null +++ b/app/views/dmsf_workflows/edit.html.erb @@ -0,0 +1 @@ +<%= render 'steps' %> \ No newline at end of file diff --git a/app/views/dmsf_workflows/index.html.erb b/app/views/dmsf_workflows/index.html.erb new file mode 100644 index 00000000..6dce40e9 --- /dev/null +++ b/app/views/dmsf_workflows/index.html.erb @@ -0,0 +1 @@ +<%= render 'main' %> \ No newline at end of file diff --git a/app/views/dmsf_workflows/log.html.erb b/app/views/dmsf_workflows/log.html.erb new file mode 100644 index 00000000..6231320b --- /dev/null +++ b/app/views/dmsf_workflows/log.html.erb @@ -0,0 +1 @@ +

WorkflowController#log

diff --git a/app/views/dmsf_workflows/new.html.erb b/app/views/dmsf_workflows/new.html.erb new file mode 100644 index 00000000..d2f0103f --- /dev/null +++ b/app/views/dmsf_workflows/new.html.erb @@ -0,0 +1,12 @@ +

<%= link_to l(:label_dmsf_workflow_plural), dmsf_workflows_path %> » <%=l(:label_dmsf_workflow_new)%>

+ +<%= labelled_form_for @workflow do |f| %> + <%= error_messages_for 'workflow' %> +
+

<%= f.text_field :name, :required => true %>

+ <% if params[:project_id] %> +

<%= hidden_field_tag :project_id, params[:project_id] %>

+ <% end %> +
+ <%= submit_tag l(:button_create) %> +<% end %> \ No newline at end of file diff --git a/app/views/dmsf_workflows/remove_step.html.erb b/app/views/dmsf_workflows/remove_step.html.erb new file mode 100644 index 00000000..88143721 --- /dev/null +++ b/app/views/dmsf_workflows/remove_step.html.erb @@ -0,0 +1 @@ +<%= render 'steps' %> \ No newline at end of file diff --git a/app/views/dmsf_workflows/reorder_steps.html.erb b/app/views/dmsf_workflows/reorder_steps.html.erb new file mode 100644 index 00000000..88143721 --- /dev/null +++ b/app/views/dmsf_workflows/reorder_steps.html.erb @@ -0,0 +1 @@ +<%= render 'steps' %> \ No newline at end of file diff --git a/assets/images/ticket_go.png b/assets/images/ticket_go.png new file mode 100644 index 0000000000000000000000000000000000000000..2aaec3813b6df67f837ebd1a7ba3a605f9d564b0 GIT binary patch literal 608 zcmV-m0-ybfP)}|w#Zm@lU_^)(A(3I!A`K`h1kK?MJb1tVf9AaxsVe_-(g6D9rAqDxsumT8dWVWd zB|&`x&fvwM5`#0;c0P@E1H4e)a_ zt<{3%UCJ>bm?9*G5En#byA%+-!OXlvl270*sNl^e`%fGxC1z-i>hlotsLx}>QlDw!er0*7gGd#(JV|z7n40#xL{UV~_c>Ua z#RkEOaO}`2n(ErfnQc1y>zol=G4yav(>wh>*w)3`KsW0{kEy+K4+)m*&0Tm6_}~dB ziyQNtslUXQjnm_EZ|&LMR7Dy9F+^o4s#@<5PrV>F`Wzz`uYs?tGq@l~a5(SSOmdt% zewi(oPmg^bHpMwGWMB28Vo(=j;}4kHD#Qy%YZ{Q?@f!HHF~{NRIws~v7?~aZXoc43 zZ_CvAq|qB|vB6@*ax&ALy4cvk`?*mDr(aK6;lg5{CegocV@q#p<$S}{%$w=KaT{n~ u>{DB8z`p?+yQ38!$}(~A<;#64JNchU$$I%CY#&Gf0000 RedmineDmsf::Webdav::ResourceProxy, :controller_class => RedmineDmsf::Webdav::Controller ), :at => "/dmsf/webdav" + + # Approval workflow + resources :dmsf_workflows do + member do + get 'autocomplete_for_user' + get 'action' + post 'new_action' + end + end + + match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'add_step', :id => /\d+/, :via => :post + match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'remove_step', :id => /\d+/, :via => :delete + match 'dmsf_workflows/:id/edit', :controller => 'dmsf_workflows', :action => 'reorder_steps', :id => /\d+/, :via => :put end diff --git a/db/migrate/20120822100401_create_dmsf_workflows.rb b/db/migrate/20120822100401_create_dmsf_workflows.rb new file mode 100644 index 00000000..c6f20b9a --- /dev/null +++ b/db/migrate/20120822100401_create_dmsf_workflows.rb @@ -0,0 +1,13 @@ +class CreateDmsfWorkflows < ActiveRecord::Migration + def self.up + create_table :dmsf_workflows do |t| + t.string :name, :null => false + t.references :project + end + add_index :dmsf_workflows, [:name], :unique => true + end + + def self.down + drop_table :dmsf_workflows + end +end diff --git a/db/migrate/20120822100402_create_dmsf_workflow_steps.rb b/db/migrate/20120822100402_create_dmsf_workflow_steps.rb new file mode 100644 index 00000000..10c1f313 --- /dev/null +++ b/db/migrate/20120822100402_create_dmsf_workflow_steps.rb @@ -0,0 +1,15 @@ +class CreateDmsfWorkflowSteps < ActiveRecord::Migration + def self.up + create_table :dmsf_workflow_steps do |t| + t.references :dmsf_workflow, :null => false + t.integer :step, :null => false + t.references :user, :null => false + t.integer :operator, :null => false + end + add_index :dmsf_workflow_steps, :dmsf_workflow_id + end + + def self.down + drop_table :dmsf_workflow_steps + end +end diff --git a/db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb b/db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb new file mode 100644 index 00000000..c62f2b69 --- /dev/null +++ b/db/migrate/20120822100403_create_dmsf_workflow_step_assignments.rb @@ -0,0 +1,17 @@ +class CreateDmsfWorkflowStepAssignments < ActiveRecord::Migration + def self.up + create_table :dmsf_workflow_step_assignments do |t| + t.references :dmsf_workflow_step, :null => false + t.references :user, :null => false + t.references :dmsf_file_revision, :null => false + end + add_index :dmsf_workflow_step_assignments, + [:dmsf_workflow_step_id, :dmsf_file_revision_id], + # The default index name exceeds the index name limit + {:name => 'index_dmsf_wrkfl_step_assigns_on_wrkfl_step_id_and_frev_id'} + end + + def self.down + drop_table :dmsf_workflow_step_assignments + end +end \ No newline at end of file diff --git a/db/migrate/20120822100404_create_dmsf_workflow_step_actions.rb b/db/migrate/20120822100404_create_dmsf_workflow_step_actions.rb new file mode 100644 index 00000000..77663ab7 --- /dev/null +++ b/db/migrate/20120822100404_create_dmsf_workflow_step_actions.rb @@ -0,0 +1,17 @@ +class CreateDmsfWorkflowStepActions < ActiveRecord::Migration + def self.up + create_table :dmsf_workflow_step_actions do |t| + t.references :dmsf_workflow_step_assignment, :null => false + t.integer :action, :null => false + t.text :note + t.timestamp :created_at + end + add_index :dmsf_workflow_step_actions, + :dmsf_workflow_step_assignment_id, + # The default index name exceeds the index name limit + {:name => 'index_dmsf_workflow_step_actions_on_workflow_step_assignment_id'} + end + def self.down + drop_table :dmsf_workflow_step_actions + end +end diff --git a/init.rb b/init.rb index 54c5dbe2..1e78d64a 100644 --- a/init.rb +++ b/init.rb @@ -58,6 +58,19 @@ Redmine::Plugin.register :redmine_dmsf do permission :file_approval, {:dmsf_files => [:delete_revision, :notify_activate, :notify_deactivate], :dmsf => [:notify_activate, :notify_deactivate]} permission :force_file_unlock, {} + permission :approval_workflows, {:dmsf_workflows => [:new, :create, :destroy, :edit, :add_step, :remove_step, :reorder_steps, :update]} + end + + # Administration menu extension + Redmine::MenuManager.map :admin_menu do |menu| + menu.push :approvalworkflows, {:controller => 'dmsf_workflows', :action => 'index'}, :caption => :label_dmsf_workflow_plural + end + + # Adds javascript and stylesheet tags for project tree view + class DmsfViewListener < Redmine::Hook::ViewListener + def view_layouts_base_html_head(context) + stylesheet_link_tag('dmsf', :plugin => :redmine_dmsf) + end end Redmine::WikiFormatting::Macros.register do diff --git a/lib/redmine_dmsf/patches/project_patch.rb b/lib/redmine_dmsf/patches/project_patch.rb index 844c6847..010d49f5 100644 --- a/lib/redmine_dmsf/patches/project_patch.rb +++ b/lib/redmine_dmsf/patches/project_patch.rb @@ -33,7 +33,7 @@ module RedmineDmsf has_many :dmsf_files, :class_name => "DmsfFile", :foreign_key => "project_id", :conditions => { :dmsf_folder_id => nil } #Fix: should only be root folders not, all folders has_many :dmsf_folders, :class_name => "DmsfFolder", :foreign_key => "project_id", :conditions => {:dmsf_folder_id => nil}, :dependent => :destroy - + has_many :dmsf_workflows, :dependent => :destroy end end diff --git a/lib/redmine_dmsf/patches/project_tabs_extended.rb b/lib/redmine_dmsf/patches/project_tabs_extended.rb index 0626fd6e..7b10c642 100644 --- a/lib/redmine_dmsf/patches/project_tabs_extended.rb +++ b/lib/redmine_dmsf/patches/project_tabs_extended.rb @@ -39,8 +39,9 @@ module RedmineDmsf def project_settings_tabs_with_dmsf tabs = project_settings_tabs_without_dmsf - if @project.module_enabled?("dmsf") - tabs.push({:name => 'dmsf', :controller => :dmsf_state, :action => :user_pref_save, :partial => 'dmsf_state/user_pref', :label => :dmsf}) + if @project.module_enabled? 'dmsf' + #tabs.push({:name => 'dmsf', :controller => :dmsf_state, :action => :user_pref_save, :partial => 'dmsf_state/user_pref', :label => :dmsf}) + tabs << {:name => 'dmsf', :controller => 'dmsf_workflows', :action => 'index', :partial => 'dmsf_workflows/main', :label => 'label_dmsf'} end return tabs end diff --git a/test/fixtures/dmsf_workflow_step_actions.yml b/test/fixtures/dmsf_workflow_step_actions.yml new file mode 100644 index 00000000..f3058e6d --- /dev/null +++ b/test/fixtures/dmsf_workflow_step_actions.yml @@ -0,0 +1,22 @@ + +--- +wfsac1: + id: 1 + dmsf_workflow_step_assignment_id: 1 + action: 1 + note: 'Approval' + created_at: '2013-05-03 10:45:35' + +wfsac2: + id: 2 + dmsf_workflow_step_assignment_id: 1 + action: 2 + note: 'Rejection' + created_at: '2013-05-03 10:45:36' + +wfsac3: + id: 3 + dmsf_workflow_step_assignment_id: 1 + action: 3 + note: 'Delegation' + created_at: '2013-05-03 10:45:37' \ No newline at end of file diff --git a/test/fixtures/dmsf_workflow_step_assignments.yml b/test/fixtures/dmsf_workflow_step_assignments.yml new file mode 100644 index 00000000..0401354f --- /dev/null +++ b/test/fixtures/dmsf_workflow_step_assignments.yml @@ -0,0 +1,6 @@ +--- +wfsa1: + id: 1 + dmsf_workflow_step_id: 1 + user_id: 1 + dmsf_file_revision_id: 2 \ No newline at end of file diff --git a/test/fixtures/dmsf_workflow_steps.yml b/test/fixtures/dmsf_workflow_steps.yml new file mode 100644 index 00000000..c315cb90 --- /dev/null +++ b/test/fixtures/dmsf_workflow_steps.yml @@ -0,0 +1,21 @@ +--- +wfs1: + id: 1 + dmsf_workflow_id: 1 + step: 1 + user_id: 1 + operator: 1 + +wfs2: + id: 2 + dmsf_workflow_id: 1 + step: 2 + user_id: 2 + operator: 1 + +wfs3: + id: 3 + dmsf_workflow_id: 1 + step: 3 + user_id: 1 + operator: 1 diff --git a/test/fixtures/dmsf_workflows.yml b/test/fixtures/dmsf_workflows.yml new file mode 100644 index 00000000..f8d8ddeb --- /dev/null +++ b/test/fixtures/dmsf_workflows.yml @@ -0,0 +1,8 @@ +--- +wf1: + id: 1 + name: wf1 + +wf2: + id: 2 + name: wf2 \ No newline at end of file diff --git a/test/functional/dmsf_workflow_controller_test.rb b/test/functional/dmsf_workflow_controller_test.rb new file mode 100644 index 00000000..aa05e62d --- /dev/null +++ b/test/functional/dmsf_workflow_controller_test.rb @@ -0,0 +1,171 @@ +require File.expand_path('../../test_helper', __FILE__) + +class DmsfWorkflowsControllerTest < RedmineDmsf::Test::TestCase + fixtures :users, :dmsf_workflows, :dmsf_workflow_steps, :projects, :roles, + :members, :member_roles + + def setup + User.current = nil + + @manager_role = Role.find_by_name('Manager') + @project = Project.find(5) + end + + def test_index_admin + @request.session[:user_id] = 1 # admin + get :index + assert_response :success + assert_template 'index' + end + + def test_index_user + @request.session[:user_id] = 2 # non admin + get :index + assert_response :forbidden + end + + def test_index_member + old_controller = @controller + @controller = ProjectsController.new + + @request.session[:user_id] = 2 + get :settings, :id => @project.id + assert_response :success + assert_template 'settings' + + @controller = old_controller + end + + def test_new_admin + @request.session[:user_id] = 1 # admin + get :new + assert_response :success + assert_template 'new' + end + + def test_new_member_no_permission + @project.enable_module!(:dmsf) + @manager_role.remove_permission! :approval_workflows + @request.session[:user_id] = 2 + get :new, {:project_id => @project.id} + assert_response :forbidden + end + + def test_new_member_no_module + @project.disable_module!(:dmsf) + @manager_role.add_permission! :approval_workflows + @request.session[:user_id] = 2 + get :new, {:project_id => @project.id} + assert_response :forbidden + end + + def test_new_member + @manager_role.add_permission! :approval_workflows + @request.session[:user_id] = 2 + @project.enable_module!(:dmsf) + get :new, {:project_id => @project.id} + assert_response :success + assert_template 'new' + end + + def test_new_no_member + @manager_role.add_permission! :approval_workflows + @request.session[:user_id] = 3 + @project.enable_module!(:dmsf) + get :new, {:project_id => @project.id} + assert_response :forbidden + end + + def test_edit + @request.session[:user_id] = 1 # admin + get :edit, :id => 1 + assert_response :success + assert_template 'edit' + end + + def test_create + @request.session[:user_id] = 1 # admin + assert_difference 'DmsfWorkflow.count', +1 do + post :create, :dmsf_workflow => {:name => 'wf3'} + end + workflow = DmsfWorkflow.first(:order => 'id DESC') + assert_redirected_to dmsf_workflows_path + assert_equal 'wf3', workflow.name + end + + def test_update + @request.session[:user_id] = 1 # admin + put :update, :id => 1, :dmsf_workflow => {:name => 'wf1a'} + workflow = DmsfWorkflow.find(1) + assert_equal 'wf1a', workflow.name + end + + def test_destroy + @request.session[:user_id] = 1 # admin + assert_difference 'DmsfWorkflow.count', -1 do + delete :destroy, :id => 1 + end + assert_redirected_to dmsf_workflows_path + assert_nil DmsfWorkflow.find_by_id(1) + end + + def test_add_step + @request.session[:user_id] = 1 # admin + assert_difference 'DmsfWorkflowStep.count', +1 do + post :add_step, :commit => 'OR', :step => 1, :id => 1, :user_ids =>[3] + end + assert_response :success + ws = DmsfWorkflowStep.first(:order => 'id DESC') + assert_equal 1, ws.dmsf_workflow_id + assert_equal 1, ws.step + assert_equal 3, ws.user_id + assert_equal 0, ws.operator + end + + def test_remove_step + @request.session[:user_id] = 1 # admin + n = DmsfWorkflowStep.where(:dmsf_workflow_id => 1, :step => 1).count + assert_difference 'DmsfWorkflowStep.count', -n do + delete :remove_step, :step => 1, :id => 1 + end + assert_response :success + ws = DmsfWorkflowStep.where(:dmsf_workflow_id => 1).first(:order => 'id ASC') + assert_equal 1, ws.step + end + + def test_reorder_steps_to_lower + @request.session[:user_id] = 1 # admin + put :reorder_steps, :step => 1, :id => 1, :workflow_step => {:move_to => 'lower'} + assert_response :success + assert_equal 2, DmsfWorkflowStep.find(1).step + assert_equal 1, DmsfWorkflowStep.find(2).step + assert_equal 3, DmsfWorkflowStep.find(3).step + end + + def test_reorder_steps_to_lowest + @request.session[:user_id] = 1 # admin + put :reorder_steps, :step => 1, :id => 1, :workflow_step => {:move_to => 'lowest'} + assert_response :success + assert_equal 3, DmsfWorkflowStep.find(1).step + assert_equal 1, DmsfWorkflowStep.find(2).step + assert_equal 2, DmsfWorkflowStep.find(3).step + end + + def test_reorder_steps_to_higher + @request.session[:user_id] = 1 # admin + put :reorder_steps, :step => 2, :id => 1, :workflow_step => {:move_to => 'higher'} + assert_response :success + assert_equal 2, DmsfWorkflowStep.find(1).step + assert_equal 1, DmsfWorkflowStep.find(2).step + assert_equal 3, DmsfWorkflowStep.find(3).step + end + + def test_reorder_steps_to_highest + @request.session[:user_id] = 1 # admin + put :reorder_steps, :step => 3, :id => 1, :workflow_step => {:move_to => 'highest'} + assert_response :success + assert_equal 2, DmsfWorkflowStep.find(1).step + assert_equal 3, DmsfWorkflowStep.find(2).step + assert_equal 1, DmsfWorkflowStep.find(3).step + end +end diff --git a/test/unit/dmsf_workflow_step_action_test.rb b/test/unit/dmsf_workflow_step_action_test.rb new file mode 100644 index 00000000..e1749116 --- /dev/null +++ b/test/unit/dmsf_workflow_step_action_test.rb @@ -0,0 +1,60 @@ +require File.expand_path('../../test_helper', __FILE__) + +class DmsfWorkflowStepActionTest < RedmineDmsf::Test::UnitTest + + + fixtures :dmsf_workflow_steps + fixtures :dmsf_workflow_step_actions + + def setup + @wfsac1 = DmsfWorkflowStepAction.find(1) + @wfsac2 = DmsfWorkflowStepAction.find(2) + @wfsac3 = DmsfWorkflowStepAction.find(3) + end + + def test_truth + assert_kind_of DmsfWorkflowStepAction, @wfsac1 + assert_kind_of DmsfWorkflowStepAction, @wfsac2 + assert_kind_of DmsfWorkflowStepAction, @wfsac3 + end + + def test_create + wfsac = DmsfWorkflowStepAction.new( + :dmsf_workflow_step_assignment_id => 1, + :action => 1, + :note => 'Approvement') + assert wfsac.save + wfsac.reload + assert wfsac.created_at + end + + def test_update + @wfsac1.dmsf_workflow_step_assignment_id = 2 + @wfsac1.action = 2 + @wfsac1.note = 'Rejection' + + assert @wfsac1.save + @wfsac1.reload + + assert_equal 2, @wfsac1.dmsf_workflow_step_assignment_id + assert_equal 2, @wfsac1.action + assert_equal 'Rejection', @wfsac1.note + end + + def test_validate_workflow_step_assignment_id_presence + @wfsac1.dmsf_workflow_step_assignment_id = nil + assert !@wfsac1.save + assert_equal 1, @wfsac1.errors.count + end + + def test_validate_action_presence + @wfsac1.action = nil + assert !@wfsac1.save + assert_equal 1, @wfsac1.errors.count + end + + def test_destroy + @wfsac1.destroy + assert_nil DmsfWorkflowStepAction.find_by_id(1) + end +end diff --git a/test/unit/dmsf_workflow_step_assignment_test.rb b/test/unit/dmsf_workflow_step_assignment_test.rb new file mode 100644 index 00000000..96189bcc --- /dev/null +++ b/test/unit/dmsf_workflow_step_assignment_test.rb @@ -0,0 +1,53 @@ +require File.expand_path('../../test_helper', __FILE__) + +class WorkflowStepAssignmentTest < RedmineDmsf::Test::UnitTest + + fixtures :users, :dmsf_file_revisions, :dmsf_workflow_steps, :dmsf_workflow_step_assignments + + def setup + @wfsa1 = DmsfWorkflowStepAssignment.find(1) + end + + def test_truth + assert_kind_of DmsfWorkflowStepAssignment, @wfsa1 + end + + def test_create + wfsa = DmsfWorkflowStepAssignment.new( + :dmsf_workflow_step_id => 2, + :user_id => 2, + :dmsf_file_revision_id => 2) + assert wfsa.save + end + + def test_update + @wfsa1.dmsf_workflow_step_id = 2 + @wfsa1.user_id = 2 + @wfsa1.dmsf_file_revision_id = 2 + + assert @wfsa1.save + @wfsa1.reload + + assert_equal 2, @wfsa1.dmsf_workflow_step_id + assert_equal 2, @wfsa1.user_id + assert_equal 2, @wfsa1.dmsf_file_revision_id + end + + def test_validate_workflow_step_id_presence + @wfsa1.dmsf_workflow_step_id = nil + assert !@wfsa1.save + assert_equal 1, @wfsa1.errors.count + end + + def test_validate_workflow_entity_id_presence + @wfsa1.dmsf_file_revision_id = nil + assert !@wfsa1.save + assert_equal 1, @wfsa1.errors.count + end + + def test_destroy + @wfsa1.destroy + assert_nil DmsfWorkflowStepAssignment.find_by_id(1) + assert_nil DmsfWorkflowStepAction.find_by_id(1) + end +end diff --git a/test/unit/dmsf_workflow_step_test.rb b/test/unit/dmsf_workflow_step_test.rb new file mode 100644 index 00000000..e9cf676f --- /dev/null +++ b/test/unit/dmsf_workflow_step_test.rb @@ -0,0 +1,76 @@ +require File.expand_path('../../test_helper', __FILE__) + +class DmsfWorkflowStepTest < RedmineDmsf::Test::UnitTest + + fixtures :users, :dmsf_workflows, :dmsf_workflow_steps + + def setup + @wfs1 = DmsfWorkflowStep.find(1) + @wfs2 = DmsfWorkflowStep.find(2) + end + + def test_truth + assert_kind_of DmsfWorkflowStep, @wfs1 + end + + def test_create + wfs = DmsfWorkflowStep.new( + :dmsf_workflow_id => 1, + :step => 2, + :user_id => 1, + :operator => 1) + assert wfs.save + end + + def test_update + @wfs1.dmsf_workflow_id = 2 + @wfs1.step = 2 + @wfs1.user_id = 2 + @wfs1.operator = 2 + + assert @wfs1.save + @wfs1.reload + + assert_equal 2, @wfs1.dmsf_workflow_id + assert_equal 2, @wfs1.step + assert_equal 2, @wfs1.user_id + assert_equal 2, @wfs1.operator + end + + def test_validate_workflow_id_presence + @wfs1.dmsf_workflow_id = nil + assert !@wfs1.save + assert_equal 1, @wfs1.errors.count + end + + def test_validate_step_presence + @wfs1.step = nil + assert !@wfs1.save + assert_equal 1, @wfs1.errors.count + end + + def test_validate_user_id_presence + @wfs1.user_id = nil + assert !@wfs1.save + assert_equal 1, @wfs1.errors.count + end + + def test_validate_operator_presence + @wfs1.operator = nil + assert !@wfs1.save + assert_equal 1, @wfs1.errors.count + end + + def test_validate_user_id_uniqueness + @wfs2.user_id = @wfs1.user_id + @wfs2.dmsf_workflow_id = @wfs1.dmsf_workflow_id + @wfs2.step = @wfs1.step + assert !@wfs2.save + assert_equal 1, @wfs2.errors.count + end + + def test_destroy + @wfs2.destroy + assert_nil DmsfWorkflowStep.find_by_id(2) + end +end diff --git a/test/unit/dmsf_workflow_test.rb b/test/unit/dmsf_workflow_test.rb new file mode 100644 index 00000000..f67e8b73 --- /dev/null +++ b/test/unit/dmsf_workflow_test.rb @@ -0,0 +1,54 @@ +require File.expand_path('../../test_helper', __FILE__) + +class DmsfWorkflowTest < RedmineDmsf::Test::UnitTest + + fixtures :projects, :dmsf_workflows, :dmsf_workflow_steps + + def setup + @wf1 = DmsfWorkflow.find(1) + @wf2 = DmsfWorkflow.find(2) + @wfs1 = DmsfWorkflowStep.find(1) + end + + def test_truth + assert_kind_of DmsfWorkflow, @wf1 + end + + def test_create + workflow = DmsfWorkflow.new(:name => 'wf') + assert workflow.save + end + + def test_update + @wf1.name = 'wf1a' + @wf1.project_id = 5 + assert @wf1.save + @wf1.reload + assert_equal 'wf1a', @wf1.name + assert_equal 5, @wf1.project_id + end + + def test_validate_name_length + @wf1.name = 'a' * 256 + assert !@wf1.save + assert_equal 1, @wf1.errors.count + end + + def test_validate_name_presence + @wf1.name = '' + assert !@wf1.save + assert_equal 1, @wf1.errors.count + end + + def test_validate_name_uniqueness + @wf2.name = @wf1.name + assert !@wf2.save + assert_equal 1, @wf2.errors.count + end + + def test_destroy + @wf1.destroy + assert_nil DmsfWorkflow.find_by_id(1) + assert_nil DmsfWorkflowStep.find_by_id(@wfs1.id) + end +end