Index: openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql,v diff -u -r1.3 -r1.4 --- openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql 16 Jan 2003 15:07:36 -0000 1.3 +++ openacs-4/packages/workflow/sql/postgresql/workflow-tables-create.sql 20 Jan 2003 15:44:59 -0000 1.4 @@ -345,10 +345,7 @@ create table workflow_cases ( case_id integer constraint workflow_cases_pk - primary key - constraint workflow_cases_case_id_fk - references acs_objects(object_id) - on delete cascade, + primary key, workflow_id integer constraint workflow_cases_workflow_id_nn not null Index: openacs-4/packages/workflow/tcl/action-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/action-procs.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/action-procs.tcl 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/action-procs.tcl 20 Jan 2003 15:45:00 -0000 1.3 @@ -16,7 +16,8 @@ # ##### -ad_proc -public workflow::action::add { +ad_proc -public workflow::action::new { + -initial_action:boolean {-workflow_id:required} {-sort_order {}} {-short_name:required} @@ -29,7 +30,7 @@ } { This procedure is normally not invoked from application code. Instead a procedure for a certain workflow implementation, such as for example - workflow::fsm::action::add (for Finite State Machine workflows), is used. + workflow::fsm::action::new (for Finite State Machine workflows), is used. @param workflow_id The id of the FSM workflow to add the action to @param short_name Short name of the action for use in source code. @@ -46,10 +47,15 @@ treated by the workflow (i.e. a bug in the Bug Tracker) will be allowed to take this action. + @param initial_action Use this switch to indicate that this is the initial + action that will fire whenever a case of the workflow + is created. The initial action is used to determine + the initial state of the worklow as well as any + procedures that should be executed when the case created. @return The id of the created action - @see workflow::fsm::action::add + @see workflow::fsm::action::new @author Peter Marklund } { @@ -76,6 +82,11 @@ foreach privilege $privileges { db_dml insert_privilege {} } + + # Record if this is an initial action + if { $initial_action_p } { + db_dml insert_initial_action {} + } } return $action_id @@ -124,14 +135,95 @@ return [db_string select_action_id {} -default {}] } +ad_proc -public workflow::action::get { + {-action_id:required} +} { + Return information about an action with a given id. + @author Peter Marklund + @return An array list with workflow_id, sort_order, short_name, pretty_name, + pretty_past_tense, assigned_role, and always_enabled_p column + values for an action. +} { + db_1row action_info {} -column_array action_info + + return [array get action_info] +} + + ##### # # workflow::action::fsm # ##### +##### +# +# workflow::fsm::action namespace +# +##### + +ad_proc -public workflow::action::fsm::new { + -initial_action:boolean + {-workflow_id:required} + {-short_name:required} + {-pretty_name:required} + {-pretty_past_tense {}} + {-allowed_roles {}} + {-assigned_role {}} + {-privileges {}} + {-always_enabled_p f} + {-enabled_states {}} + {-new_state {}} +} { + Add an action to a certain FSM (Finite State Machine) workflow. This procedure + invokes the generic workflow::action::new procedures and does additional inserts + for FSM specific information. See the parameter + documentation for the proc workflow::action::new. + + @param enabled_states The short names of states in which the + action is enabled. + @param new_state The name of the state that a workflow case moves to + when the action is taken. Optional. + + @see workflow::action::new + + @author Peter Marklund +} { + + db_transaction { + # Generic workflow data: + set action_id [workflow::action::new -initial_action=$initial_action_p \ + -workflow_id $workflow_id \ + -short_name $short_name \ + -pretty_name $pretty_name \ + -pretty_past_tense $pretty_past_tense \ + -allowed_roles $allowed_roles \ + -assigned_role $assigned_role \ + -privileges $privileges \ + -always_enabled_p $always_enabled_p] + + # FSM specific data: + + # Record whether the action changes state + if { ![empty_string_p $new_state] } { + set new_state_id [workflow::state::fsm::get_id -workflow_id $workflow_id \ + -short_name $new_state] + } else { + set new_state_id [db_null] + } + db_dml insert_fsm_action {} + + # Record in which states the action is enabled + foreach state_short_name $enabled_states { + set enabled_state_id [workflow::state::fsm::get_id -workflow_id $workflow_id \ + -short_name $state_short_name] + db_dml insert_enabled_state {} + } + } +} + ad_proc -public workflow::action::fsm::get_new_state { {-action_id:required} } { Index: openacs-4/packages/workflow/tcl/action-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/action-procs.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/action-procs.xql 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/action-procs.xql 20 Jan 2003 15:45:00 -0000 1.3 @@ -1,7 +1,7 @@ - + insert into workflow_action_allowed_roles select :action_id, @@ -12,14 +12,32 @@ - + insert into workflow_action_privileges (action_id, privilege) values (:action_id, :privilege) + + + insert into workflow_actions + (action_id, workflow_id, sort_order, short_name, pretty_name, pretty_past_tense, + assigned_role, always_enabled_p) + values (:action_id, :workflow_id, :sort_order, :short_name, :pretty_name, :pretty_past_tense, + :assigned_role_id, :always_enabled_p) + + + + + + insert into workflow_initial_action + (workflow_id, action_id) + values (:workflow_id, :action_id) + + + select assigned_role @@ -53,20 +71,37 @@ - + - insert into workflow_actions - select :action_id, - :workflow_id, - :sort_order, - :short_name, - :pretty_name, - :pretty_past_tense, - :assigned_role_id, - :always_enabled_p + select workflow_id, + sort_order, + short_name, + pretty_name, + pretty_past_tense, + assigned_role, + always_enabled_p + from workflow_actions + where action_id = :action_id + + + insert into workflow_fsm_actions + (action_id, new_state) + values + (:action_id, :new_state_id) + + + + + + insert into workflow_fsm_action_enabled_in_states + (action_id, state_id) + values (:action_id, :enabled_state_id) + + + select new_state Index: openacs-4/packages/workflow/tcl/case-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/case-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/workflow/tcl/case-procs.tcl 14 Jan 2003 15:09:16 -0000 1.1 +++ openacs-4/packages/workflow/tcl/case-procs.tcl 20 Jan 2003 15:45:00 -0000 1.2 @@ -10,6 +10,7 @@ namespace eval workflow::case {} namespace eval workflow::case::fsm {} namespace eval workflow::case::action {} +namespace eval workflow::case::role {} namespace eval workflow::case::action::fsm {} ##### @@ -18,16 +19,19 @@ # ##### -ad_proc -public workflow::case::insert { +ad_proc -private workflow::case::insert { {-workflow_id:required} {-object_id:required} } { - Start a new case for this workflow and object + Internal procedure that creates a new workflow case in the + database. Should not be used by applications. - @param case_object_id The object_id which the case is about + @param object_id The object_id which the case is about @param workflow_short_name The short_name of the workflow. @return The case_id of the case. Returns the empty string if no case could be found. + @see + @author Lars Pind (lars@collaboraid.biz) } { set case_id [db_nextval "workflow_cases_seq"] @@ -50,10 +54,11 @@ {-comment_format:required} {-user_id} } { - Start a new case for this workflow and object + Start a new case for this workflow and object. - @param case_object_id The object_id which the case is about + @param object_id The object_id which the case is about @param workflow_short_name The short_name of the workflow. + @param comment_format html, plain or pre @return The case_id of the case. Returns the empty string if no case could be found. @author Lars Pind (lars@collaboraid.biz) @@ -69,7 +74,7 @@ # Execute the initial action workflow::case::action::execute \ -case_id $case_id \ - -action_id [get_initial_action -workflow_id $workflow_id] \ + -action_id [workflow::action::get_initial_action -workflow_id $workflow_id] \ -comment $comment \ -comment_format $comment_format \ -user_id $user_id \ @@ -79,14 +84,14 @@ return $case_id } -ad_proc -public workflow::case::get_case_id { - {-case_object_id:required} +ad_proc -public workflow::case::get_id { + {-object_id:required} {-workflow_short_name:required} } { Gets the case_id from the object_id which the case is about, along with the short_name of the workflow. - @param case_object_id The object_id which the case is about + @param object_id The object_id which the case is about @param workflow_short_name The short_name of the workflow. @return The case_id of the case. Returns the empty string if no case could be found. @@ -137,12 +142,17 @@ Get the currently enabled actions, based on the state of the case @param case_id The ID of the case. - @return A list of action_id's of the actions which are currently enabled - + @return A list of id:s of the actions which are currently + enabled + @author Lars Pind (lars@collaboraid.biz) } { - set action_ids [db_list select_enabled_actions {}] - return $action_ids + set action_list [list] + db_foreach select_enabled_actions {} { + lappend action_list $action_id + } + + return $action_list } ad_proc -public workflow::case::get_user_actions { @@ -153,26 +163,27 @@ to execute. @param case_id The ID of the case. - @return A list of action_id's of the actions which are currently enabled + @return A list of id:s of the actions + which are currently enabled @author Lars Pind (lars@collaboraid.biz) } { if { ![exists_and_not_null user_id] } { set user_id [ad_conn user_id] } - set action_ids [list] + set action_list [list] foreach action_id [get_enabled_actions -case_id $case_id] { if { [workflow::case::action::permission_p -case_id $case_id -action_id $action_id -user_id $user_id] } { - lappend action_ids $action_id + lappend action_list $action_id } } - return $action_ids + return $action_list } -ad_proc -public workflow::case::assign_roles { +ad_proc -private workflow::case::assign_roles { {-case_id:required} } { Find out which roles are assigned to currently enabled actions. @@ -315,8 +326,8 @@ set user_id [ad_conn user_id] } - set object_id [get_object_id -case_id $case_id] - set user_role_ids [get_user_roles -case_id $case_id -user_id $user_id] + set object_id [workflow::case::get_object_id -case_id $case_id] + set user_role_ids [workflow::case::get_user_roles -case_id $case_id -user_id $user_id] set permission_p 0 @@ -407,8 +418,12 @@ @param case_id The ID of the case. @param action_id The ID of the action @param comment Comment for the case activity log - @param comment_format Format of the comment, according to OpenACS standard text formatting (HM!) + @param comment_format Format of the comment (plain, text or html), according to + OpenACS standard text formatting (HM!) @param user_id User_id + @param no_check Use this switch to bypass a check of whether the action is + enabled and the user is allowed to perform it. This + switch should normally not be used. @author Lars Pind (lars@collaboraid.biz) } { @@ -457,7 +472,7 @@ {-case_id:required} {-action_id:required} } { - The new state which the workflow will be in after this action. + Get the new state which the workflow will be in after a certain action. @param case_id The ID of the case. @param action_id The ID of the action @@ -471,4 +486,3 @@ } return $new_state } - Index: openacs-4/packages/workflow/tcl/case-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/case-procs.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/workflow/tcl/case-procs.xql 14 Jan 2003 15:09:16 -0000 1.1 +++ openacs-4/packages/workflow/tcl/case-procs.xql 20 Jan 2003 15:45:00 -0000 1.2 @@ -21,12 +21,12 @@ - + select case_id from workflow_cases c, workflows w - where c.object_id = :case_object_id + where c.object_id = :object_id and w.workflow_id = c.workflow_id and w.short_name = :workflow_short_name @@ -60,7 +60,7 @@ workflow_fsm_action_enabled_in_states waeis where c.case_id = :case_id and cfsm.case_id = c.case_id - and waeis.state_id = cfsm.state_id + and waeis.state_id = cfsm.current_state union @@ -70,7 +70,7 @@ where c.case_id = :case_id and a.workflow_id = c.workflow_id and a.always_enabled_p = 't' - ) + ) enabled_actions @@ -131,13 +131,14 @@ select 1 from workflow_actions a where a.action_id = :action_id - and a.always_enabled_p = 't' or + and (a.always_enabled_p = 't' or exists (select 1 - from workflow_actions_enabled_in_states waeis, - workflow_cases_fsm c_fsm, + from workflow_fsm_action_enabled_in_states waeis, + workflow_case_fsm c_fsm where waeis.action_id = a.action_id and c_fsm.case_id = :case_id and waeis.state_id = c_fsm.current_state) + ) Index: openacs-4/packages/workflow/tcl/fsm-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/Attic/fsm-procs.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/fsm-procs.tcl 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/fsm-procs.tcl 20 Jan 2003 15:45:00 -0000 1.3 @@ -9,8 +9,7 @@ } namespace eval workflow::fsm {} -namespace eval workflow::fsm::state {} -namespace eval workflow::fsm::action {} +namespace eval workflow::state::fsm {} ##### # @@ -33,11 +32,11 @@ ##### # -# workflow::fsm::state namespace +# workflow::state::fsm namespace # ##### -ad_proc -public workflow::fsm::state::add { +ad_proc -public workflow::state::fsm::new { {-workflow_id:required} {-short_name:required} {-pretty_name:required} @@ -60,78 +59,29 @@ db_dml do_insert {} } -ad_proc -public workflow::fsm::state::get_id { - {-workflow_id:required} - {-short_name:required} +ad_proc -public workflow::state::fsm::get { + {-state_id:required} } { - Return the id of the state with given short name + Return workflow_id, sort_order, short_name, and pretty_name for a certain + FSM workflow state. - @param workflow_id The id of the workflow the state belongs to. - @param short_name The name of the state to return the id for. - @author Peter Marklund } { - return [db_string select_id {}] + db_1row state_info {} -column_array state_info + + return [array get state_info] } -##### -# -# workflow::fsm::action namespace -# -##### - -ad_proc -public workflow::fsm::action::add { +ad_proc -public workflow::state::fsm::get_id { {-workflow_id:required} {-short_name:required} - {-pretty_name:required} - {-pretty_past_tense {}} - {-allowed_roles {}} - {-assigned_role {}} - {-privileges {}} - {-enabled_states {}} - {-new_state {}} } { - Add an action to a certain FSM (Finite State Machine) workflow. This procedure - invokes the generic workflow::action::add procedures and does additional inserts - for FSM specific information. See the parameter - documentation for the proc workflow::action::add. + Return the id of the state with given short name - @param enabled_states The short names of states in which the - action is enabled. - @param new_state The name of the state that a workflow case moves to - when the action is taken. Optional. + @param workflow_id The id of the workflow the state belongs to. + @param short_name The name of the state to return the id for. - @see workflow::action::add - @author Peter Marklund -} { - - db_transaction { - # Generic workflow data: - set action_id [workflow::action::add -workflow_id $workflow_id \ - -short_name $short_name \ - -pretty_name $pretty_name \ - -pretty_past_tense $pretty_past_tense \ - -allowed_roles $allowed_roles \ - -assigned_role $assigned_role \ - -privileges $privileges] - - # FSM specific data: - - # Record whether the action changes state - if { ![empty_string_p $new_state] } { - set new_state_id [workflow::fsm::state::get_id -workflow_id $workflow_id \ - -short_name $new_state] - } else { - set new_state_id [db_null] - } - db_dml insert_fsm_action {} - - # Record in which states the action is enabled - foreach state_short_name $enabled_states { - set enabled_state_id [workflow::fsm::state::get_id -workflow_id $workflow_id \ - -short_name $state_short_name] - db_dml insert_enabled_state {} - } - } +} { + return [db_string select_id {}] } Index: openacs-4/packages/workflow/tcl/fsm-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/Attic/fsm-procs.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/fsm-procs.xql 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/fsm-procs.xql 20 Jan 2003 15:45:00 -0000 1.3 @@ -1,38 +1,32 @@ - + insert into workflow_fsm_states (state_id, workflow_id, sort_order, short_name, pretty_name) values (:state_id, :workflow_id, :sort_order, :short_name, :pretty_name) - + - select state_id + select workflow_id, + sort_order, + short_name, + pretty_name from workflow_fsm_states - where short_name = :short_name - and workflow_id = :workflow_id + where state_id = :state_id - + - insert into workflow_fsm_actions - (action_id, new_state) - values - (:action_id, :new_state_id) + select state_id + from workflow_fsm_states + where short_name = :short_name + and workflow_id = :workflow_id - - - insert into workflow_fsm_action_enabled_in_states - (action_id, state_id) - values (:action_id, :enabled_state_id) - - - Index: openacs-4/packages/workflow/tcl/install-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/install-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/workflow/tcl/install-procs.tcl 14 Jan 2003 15:09:16 -0000 1.1 +++ openacs-4/packages/workflow/tcl/install-procs.tcl 20 Jan 2003 15:45:00 -0000 1.2 @@ -1,32 +1,58 @@ +ad_library { + Procedures for initializing service contracts etc. for the + workflow package. Should only be executed once upon installation. + + @creation-date 13 January 2003 + @author Lars Pind (lars@collaboraid.biz) + @author Peter Marklund (peter@collaboraid.biz) + @cvs-id $Id$ +} - # Array-list with list of lists style +namespace eval workflow::install {} - set operations { - GetObjectType { - {operation_desc "Get the object type for which this operation is valid."} - {inputspec {}} - {outputspec {object_type:string}} - {nargs 0} - {iscachable_p "t"} - } - GetPrettyName { - {operation_desc "Get the pretty name. May contain #...#, so should be localized."} - {inputspec {}} - {outputspec {pretty_name:string}} - {nargs 0} - {iscachable_p "t"} - } - GetAssignees { - {operation_desc "Get the assignees as a Tcl list of party_ids, of the default assignees for this case, object, role"} - {inputspec {case_id:integer,object_id:integer,role_id:integer}} - {outputspec {party_ids:[integer]}} - {nargs 3} - {iscachable_p "f"} - } +# Array-list with list of lists style + +set operations { + GetObjectType { + {operation_desc "Get the object type for which this operation is valid."} + {inputspec {}} + {outputspec {object_type:string}} + {nargs 0} + {iscachable_p "t"} } - + GetPrettyName { + {operation_desc "Get the pretty name. May contain #...#, so should be localized."} + {inputspec {}} + {outputspec {pretty_name:string}} + {nargs 0} + {iscachable_p "t"} + } + GetAssignees { + {operation_desc "Get the assignees as a Tcl list of party_ids, of the default assignees for this case, object, role"} + {inputspec {case_id:integer,object_id:integer,role_id:integer}} + {outputspec {party_ids:[integer]}} + {nargs 3} + {iscachable_p "f"} + } +} +namespace eval acs_sc::contract {} +namespace eval acs_sc::contract::define {} +proc acs_sc::contract::new { contract_name {operations {}} } { + puts "New Contract: $contract_name" + if { ![string equal $operations ""] } { + puts "Operations:" + namespace eval ::acs_sc::contract::define variable contract_name $contract_name + namespace eval ::acs_sc::contract::define $operations + } +} + +proc acs_sc::contract::define::operation { operation_name } { + variable contract_name + puts "Operation: ${contract_name}.${operation_name}" +} + ##### # # Style one: Lists of lists of lists with potentially unclear semantics @@ -178,22 +204,5 @@ } } -namespace eval acs_sc::contract {} -namespace eval acs_sc::contract::define {} +#create_service_contracts -proc acs_sc::contract::new { contract_name {operations {}} } { - puts "New Contract: $contract_name" - if { ![string equal $operations ""] } { - puts "Operations:" - namespace eval ::acs_sc::contract::define variable contract_name $contract_name - namespace eval ::acs_sc::contract::define $operations - } -} - -proc acs_sc::contract::define::operation { operation_name } { - variable contract_name - puts "Operation: ${contract_name}.${operation_name}" -} - -create_service_contracts - Index: openacs-4/packages/workflow/tcl/role-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/role-procs.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/role-procs.tcl 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/role-procs.tcl 20 Jan 2003 15:45:00 -0000 1.3 @@ -15,7 +15,7 @@ # ##### -ad_proc -public workflow::role::add { +ad_proc -public workflow::role::new { {-workflow_id:required} {-short_name:required} {-pretty_name:required} Index: openacs-4/packages/workflow/tcl/role-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/role-procs.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/role-procs.xql 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/role-procs.xql 20 Jan 2003 15:45:00 -0000 1.3 @@ -1,7 +1,7 @@ - + insert into workflow_roles (role_id, workflow_id, short_name, pretty_name) Index: openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/workflow-procs-postgresql.xql 20 Jan 2003 15:45:00 -0000 1.3 @@ -2,7 +2,7 @@ postgresql7.2 - + select workflow__new (:short_name, :pretty_name, Index: openacs-4/packages/workflow/tcl/workflow-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/workflow-procs.tcl,v diff -u -r1.2 -r1.3 --- openacs-4/packages/workflow/tcl/workflow-procs.tcl 14 Jan 2003 15:09:16 -0000 1.2 +++ openacs-4/packages/workflow/tcl/workflow-procs.tcl 20 Jan 2003 15:45:00 -0000 1.3 @@ -20,13 +20,14 @@ return "workflow" } -ad_proc -public workflow::add { +ad_proc -public workflow::new { {-short_name:required} {-pretty_name:required} {-object_id:required} {-object_type "acs_object"} } { - Creates a new workflow. + Creates a new workflow. For each workflow you must create an initial action + (using the workflow::action::new proc) to be fired when a workflow case is opened. @param short_name For referring to the workflow from Tcl code. Use Tcl variable syntax. @param pretty_name A human readable name for the workflow for use in the UI. @@ -49,11 +50,14 @@ set creation_ip "" } - # It makes sense that the workflow inherits permissions from the object (typically package type or package instance) - # that sets the scope of the workflow + # It makes sense that the workflow inherits permissions from the object + # (typically package type or package instance) that sets the scope of the workflow set context_id $object_id - return [db_string do_insert {}] + # Insert the workflow + set workflow_id [db_string do_insert {}] + + return $workflow_id } ad_proc -public workflow::delete { Index: openacs-4/packages/workflow/tcl/workflow-procs.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/workflow-procs.xql,v diff -u -r1.1 -r1.2 --- openacs-4/packages/workflow/tcl/workflow-procs.xql 14 Jan 2003 15:09:16 -0000 1.1 +++ openacs-4/packages/workflow/tcl/workflow-procs.xql 20 Jan 2003 15:45:00 -0000 1.2 @@ -17,5 +17,5 @@ where workflow_id = :workflow_id - + Index: openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl,v diff -u -r1.1 -r1.2 --- openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl 14 Jan 2003 15:09:27 -0000 1.1 +++ openacs-4/packages/workflow/tcl/test/workflow-test-procs.tcl 20 Jan 2003 15:45:00 -0000 1.2 @@ -9,22 +9,86 @@ namespace eval workflow::test {} -ad_proc workflow::test::bug_workflow_name {} { +ad_proc workflow::test::workflow_name {} { The short name used for the Bug Tracker Bug test workflow. It is assumed this short name will not be present in the system. } { return "bug_test" } -ad_proc workflow::test::bug_workflow_object_id {} { +ad_proc workflow::test::workflow_object_id {} { } { return [db_string main_site_package_id {select object_id from site_nodes where parent_id is null}] } +ad_proc workflow::test::workflow_id {} { + Get the id of the Bug Tracker bug workflow +} { + return [workflow::get_id -object_id [workflow::test::workflow_object_id] \ + -short_name [workflow::test::workflow_name]] +} + +ad_proc workflow::test::admin_owner_id {} { + Return the id of the site-wide-admin (the only person + guaranteed to be on the system). +} { + set admin_email [ad_admin_owner] + + return [db_string admin_owner_id "select party_id from parties where email = :admin_email"] +} + +ad_proc workflow::test::action_short_names { action_id_list } { + + Return the short names of the actions with given id:s +} { + set short_name_list [list] + foreach action_id $action_id_list { + array set action_info [workflow::action::get -action_id $action_id] + + lappend short_name_list $action_info(short_name) + } + + return $short_name_list +} + +ad_proc workflow::test::assert_case_state { + {-workflow_id:required} + {-case_id:required} + {-expect_current_state:required} + {-expect_enabled_actions:required} + {-expect_user_actions:required} + {-expect_user_roles:required} + +} { + Make assertions about what the current state should be and + what actions are enabled etc. +} { + + set user_roles \ + [workflow::case::get_user_roles -case_id $case_id \ + -user_id [workflow::test::admin_owner_id]] + set enabled_actions [workflow::test::action_short_names \ + [workflow::case::get_enabled_actions -case_id $case_id]] + array set state_info \ + [workflow::state::fsm::get -state_id [workflow::case::fsm::get_current_state -case_id $case_id]] + set user_actions [workflow::test::action_short_names \ + [workflow::case::get_user_actions -case_id $case_id \ + -user_id [workflow::test::admin_owner_id]]] + + aa_true "current state should be $expect_current_state" \ + [string equal $state_info(short_name) $expect_current_state] + aa_true "checking enabled actions ($enabled_actions) in $expect_current_state state, expecting ($expect_enabled_actions)" \ + [util_sets_equal_p $enabled_actions $expect_enabled_actions] + aa_true "checking user actions ($user_actions) in $expect_current_state state, expecting ($expect_user_actions)" \ + [util_sets_equal_p $user_actions $expect_user_actions] + aa_true "user not assigned to any roles yet" \ + [empty_string_p $user_roles] +} + ad_proc workflow::test::workflow_setup {} { Create a test workflow for the Bug Tracker Bug use case. @@ -35,12 +99,12 @@ # ##### - set main_site_package_id [workflow::test::bug_workflow_object_id] + set main_site_package_id [workflow::test::workflow_object_id] # Cannot use bt_bug as we cannot assume Bug Tracker to be installed # TODO: test side_effects? # -side_effects { bug-tracker.FormatLogTitle } - set workflow_id [workflow::add \ - -short_name [workflow::test::bug_workflow_name] \ + set workflow_id [workflow::new \ + -short_name [workflow::test::workflow_name] \ -pretty_name "Bug Test" \ -object_id $main_site_package_id \ -object_type "acs_object"] @@ -53,7 +117,7 @@ # TODO: add assignment rules? # -assignment_rules { workflow.CreationUser } - workflow::role::add -workflow_id $workflow_id \ + workflow::role::new -workflow_id $workflow_id \ -short_name "submitter" \ -pretty_name "Submitter" @@ -62,7 +126,7 @@ # bug-tracker.ComponentMaintainer # bug-tracker.ProjectMaintainer # } - workflow::role::add -workflow_id $workflow_id \ + workflow::role::new -workflow_id $workflow_id \ -short_name "assignee" \ -pretty_name "Assignee" @@ -72,15 +136,15 @@ # ##### - workflow::fsm::state::add -workflow_id $workflow_id \ + workflow::state::fsm::new -workflow_id $workflow_id \ -short_name "open" \ -pretty_name "Open" - workflow::fsm::state::add -workflow_id $workflow_id \ + workflow::state::fsm::new -workflow_id $workflow_id \ -short_name "resolved" \ -pretty_name "Resolved" - workflow::fsm::state::add -workflow_id $workflow_id \ + workflow::state::fsm::new -workflow_id $workflow_id \ -short_name "closed" \ -pretty_name "Closed" @@ -90,23 +154,32 @@ # ##### - workflow::fsm::action::add -workflow_id $workflow_id \ + workflow::action::fsm::new -initial_action \ + -workflow_id $workflow_id \ + -short_name "open" \ + -pretty_name "Open" \ + -pretty_past_tense "Opened" \ + -new_state "open" + + workflow::action::fsm::new -workflow_id $workflow_id \ -short_name "comment" \ -pretty_name "Comment" \ -pretty_past_tense "Commented" \ -allowed_roles { submitter assignee } \ - -privileges { read } + -privileges { read } \ + -always_enabled_p t - workflow::fsm::action::add -workflow_id $workflow_id \ + workflow::action::fsm::new -workflow_id $workflow_id \ -short_name "edit" \ -pretty_name "Edit" \ -pretty_past_tense "Edited" \ -allowed_roles { submitter assignee } \ - -privileges { write } + -privileges { write } \ + -always_enabled_p t # TODO add side effects? # -side_effects { bug-tracker.CaptureResolutionCode } - workflow::fsm::action::add -workflow_id $workflow_id \ + workflow::action::fsm::new -workflow_id $workflow_id \ -short_name "resolve" \ -pretty_name "Resolve" \ -pretty_past_tense "Resolved" \ @@ -115,7 +188,7 @@ -new_state "resolved" \ -privileges { write } - workflow::fsm::action::add -workflow_id $workflow_id \ + workflow::action::fsm::new -workflow_id $workflow_id \ -short_name "close" \ -pretty_name "Close" \ -pretty_past_tense "Closed" \ @@ -124,41 +197,114 @@ -new_state "closed" \ -privileges { write } - workflow::fsm::action::add -workflow_id $workflow_id \ + workflow::action::fsm::new -workflow_id $workflow_id \ -short_name "reopen" \ -pretty_name "Reopen" \ -pretty_past_tense "Closed" \ -allowed_roles { submitter } \ -enabled_states { resolved closed } \ -new_state "open" \ -privileges { write } + + return $workflow_id } ad_proc workflow::test::workflow_teardown {} { - Delete the Bug Tracker Bug test workflow. + Delete the Bug Tracker Bug test workflow. } { - set workflow_id [workflow::get_id -object_id [workflow::test::bug_workflow_object_id] \ - -short_name [workflow::test::bug_workflow_name]] + set workflow_id [workflow::get_id -object_id [workflow::test::workflow_object_id] \ + -short_name [workflow::test::workflow_name]] - workflow::delete -workflow_id $workflow_id + workflow::delete -workflow_id $workflow_id } + +ad_proc workflow::test::case_setup {} { + Create a case of the Bug Tracker bug test workflow. + + @author Peter Marklund +} { + set workflow_id [workflow::test::workflow_id] + + set case_id [workflow::case::new -workflow_id $workflow_id \ + -object_id [workflow::test::workflow_object_id] \ + -comment "Test workflow case" \ + -comment_format "plain" \ + -user_id [workflow::test::admin_owner_id]] + + return $case_id +} + aa_register_case bugtracker_workflow_create { - Test creation and teardown of an FSM workflow. + Test creation and teardown of an FSM workflow case. @author Peter Marklund - @creation-date 10 January 2003 + @creation-date 16 January 2003 } { + # Setup # Make sure to run the teardown proc even if there is an error - #set error_p [catch workflow::test::workflow_setup error] - workflow::test::workflow_setup + # Cannot get this to work as it seems the catch will return true + # if any catch did so in the executed code. + # set error_p [catch workflow::test::workflow_setup error] + set workflow_id [workflow::test::workflow_setup] - # Any assertions here? + # Create the workflow case in open state + set object_id [workflow::test::workflow_object_id] + set case_id [workflow::test::case_setup] - workflow::test::workflow_teardown + set retrieved_case_id \ + [workflow::case::get_id -object_id $object_id \ + -workflow_short_name [workflow::test::workflow_name]] + set retrieved_object_id \ + [workflow::case::get_object_id -case_id $case_id] + aa_true "case_id of a created workflow case should be retrievable" \ + [string equal $case_id $retrieved_case_id] + aa_true "object_id of a created workflow case should be retrievable" \ + [string equal $object_id $retrieved_object_id] - # Any assertions here? + set expect_enabled_actions [list comment edit resolve] + workflow::test::assert_case_state -workflow_id $workflow_id \ + -case_id $case_id \ + -expect_current_state open \ + -expect_enabled_actions $expect_enabled_actions \ + -expect_user_actions $expect_enabled_actions \ + -expect_user_roles {} + # Resolve the bug + workflow::case::action::execute -case_id $case_id \ + -action_id [workflow::action::get_id -workflow_id $workflow_id \ + -short_name "resolve"] \ + -comment "Resolving Bug" \ + -comment_format plain \ + -user_id [workflow::test::admin_owner_id] + + set expect_enabled_actions [list comment edit resolve reopen close] + workflow::test::assert_case_state -workflow_id $workflow_id \ + -case_id $case_id \ + -expect_current_state resolved \ + -expect_enabled_actions $expect_enabled_actions \ + -expect_user_actions $expect_enabled_actions \ + -expect_user_roles {} + + # Close the bug + workflow::case::action::execute -case_id $case_id \ + -action_id [workflow::action::get_id -workflow_id $workflow_id \ + -short_name "close"] \ + -comment "Closing Bug" \ + -comment_format plain \ + -user_id [workflow::test::admin_owner_id] + + set expect_enabled_actions [list comment edit reopen] + workflow::test::assert_case_state -workflow_id $workflow_id \ + -case_id $case_id \ + -expect_current_state closed \ + -expect_enabled_actions $expect_enabled_actions \ + -expect_user_actions $expect_enabled_actions \ + -expect_user_roles {} + + # Teardown + workflow::test::workflow_teardown + # Report any errors from the setup proc #global errorInfo #aa_false "error during setup: $error - $errorInfo" $error_p