Object type PDTS - Workflow Task (#3711)

* Adapt trial code from christianguenter2

* Add changed_by

* Adapt trial code from christianguenter2

* Add changed_by

* Add unit test mock class

* Update unit tests

* Unit tests %26 lint fixes

* De-Linting

* More lint fixes

* More lint experimenting

* More de-linting

* Update unit tests

* Turnaround test (WIP)

* More XML turnaround testing

* Turnaround test now working

* Clean up code

* Enable experimental mode

If we want to merge into master, it will only run for daredevil experimentalists

* Update src/objects/zcl_abapgit_object_pdts.clas.testclasses.abap

Co-authored-by: Lars Hvam <larshp@hotmail.com>

* Update src/objects/zcl_abapgit_object_pdts.clas.abap

Co-authored-by: Lars Hvam <larshp@hotmail.com>

* 702 compatibility

* More 702 compatibility

* Removed container texts and system elements

Temporary(?) measure as they are being too troublesome, changing XML on successive serializations and suchlike.

* Caught exception

* General refactoring

* Remove NOTEXT pragmas and directives

* De-linting

* Remove diff in transport class

* Refactoring WIP

* Refactoring - WIP

* Refactor serialization

* De-lint

* Update container serialization

* Refactor deserialization WIP

* Object type PDTS - Workflow Task (experimental)

* Object PDTS Alpha version

* De-lint

* Correct CI dependency issues

* Check for critical unit test setting

Co-authored-by: Lars Hvam <larshp@hotmail.com>
This commit is contained in:
pokrakam 2020-09-29 06:41:35 +01:00 committed by GitHub
parent 404a08fdb2
commit 85fe733171
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1201 additions and 0 deletions

View File

@ -0,0 +1,318 @@
CLASS zcl_abapgit_object_pdts DEFINITION
PUBLIC
INHERITING FROM zcl_abapgit_objects_super
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor IMPORTING is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CONSTANTS: c_object_type_task TYPE hr_sotype VALUE 'TS'.
DATA ms_objkey TYPE hrsobject.
DATA mv_objid TYPE hrobjid.
METHODS check_subrc_for IMPORTING iv_call TYPE clike OPTIONAL
RAISING zcx_abapgit_exception.
METHODS is_experimental RETURNING VALUE(rv_result) TYPE abap_bool.
METHODS get_container_xml
IMPORTING
ii_task TYPE REF TO lif_task_definition
RETURNING
VALUE(ri_first_element) TYPE REF TO if_ixml_element
RAISING
zcx_abapgit_exception.
METHODS extract_container IMPORTING io_xml TYPE REF TO zif_abapgit_xml_input
RETURNING VALUE(rv_result) TYPE xstring.
ENDCLASS.
CLASS zcl_abapgit_object_pdts IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
IF is_experimental( ) = abap_false.
"Alpha version, known issues:
"- Container texts not de/serialized properly (functionally OK)
"- Container handling still a bad hack, needs refactoring with lots of debugging time
"- Probably has a few more bugs, more testing needed
zcx_abapgit_exception=>raise( 'PDTS not fully implemented, enable experimental features to test it' ).
ENDIF.
ms_objkey-otype = c_object_type_task.
ms_objkey-objid = ms_item-obj_name.
mv_objid = ms_item-obj_name. "Todo: Obsolete
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA li_task TYPE REF TO lif_task_definition.
li_task = lcl_task_definition=>load( mv_objid ).
li_task->clear_origin_data( ).
io_xml->add( iv_name = 'PDTS'
ig_data = li_task->get_definition( ) ).
io_xml->add_xml( iv_name = 'CONTAINER'
ii_xml = get_container_xml( li_task ) ).
ENDMETHOD.
METHOD get_container_xml.
DATA li_xml_dom TYPE REF TO if_ixml_document.
DATA li_elements TYPE REF TO if_ixml_node_collection.
DATA li_iterator TYPE REF TO if_ixml_node_iterator.
DATA li_element TYPE REF TO if_ixml_node.
DATA li_children TYPE REF TO if_ixml_node_list.
DATA li_child_iterator TYPE REF TO if_ixml_node_iterator.
DATA li_attributes TYPE REF TO if_ixml_named_node_map.
DATA lv_name TYPE string.
"Todo: get_user_container strips out system elements, but to_xml adds them back in (hardcoded internally)
" Dirty hack further down to remove them from XML until we get this to work properly
ii_task->get_user_container( )->to_xml(
EXPORTING
include_null_values = abap_true
include_initial_values = abap_true
include_typenames = abap_true
include_change_data = abap_true
include_texts = abap_false "Todo: Get texts to work properly
include_extension_elements = abap_true
save_delta_handling_info = abap_true
use_xslt = abap_false
IMPORTING
xml_dom = li_xml_dom
EXCEPTIONS
conversion_error = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `TO_XML` ).
ri_first_element ?= li_xml_dom->get_first_child( ).
li_elements = ri_first_element->get_elements_by_tag_name( name = 'ELEMENTS' ).
li_iterator = li_elements->create_iterator( ).
DO.
li_element = li_iterator->get_next( ).
IF li_element IS NOT BOUND.
EXIT.
ENDIF.
li_children = li_element->get_children( ).
li_child_iterator = li_children->create_iterator( ).
DO.
li_element = li_child_iterator->get_next( ).
IF li_element IS NOT BOUND.
EXIT.
ENDIF.
"Remove system container elements - causing too much trouble
"Todo: This is a bad hack, but obsolete if we can fix todo above
li_attributes = li_element->get_attributes( ).
lv_name = li_attributes->get_named_item( name = 'NAME' )->get_value( ).
IF lv_name(1) = '_'.
li_element->remove_node( ).
li_child_iterator->reset( ).
CONTINUE.
ENDIF.
li_attributes->remove_named_item( name = 'CHGDTA' ).
ENDDO.
ENDDO.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_task TYPE lif_task_definition=>ty_task_data,
lv_xml_string TYPE xstring,
li_task TYPE REF TO lif_task_definition.
io_xml->read( EXPORTING iv_name = 'PDTS'
CHANGING cg_data = ls_task ).
li_task = lcl_task_definition=>create(
iv_objid = mv_objid
is_task_data = ls_task ).
li_task->create_task( ).
li_task->change_wi_text( ).
li_task->change_method( ).
lv_xml_string = extract_container( io_xml ).
li_task->import_container( lv_xml_string ).
li_task->change_start_events( ).
li_task->change_terminating_events( ).
li_task->change_text( ).
li_task->save( iv_package ).
tadir_insert( iv_package ).
ENDMETHOD.
METHOD extract_container.
DATA li_stream TYPE REF TO if_ixml_ostream.
DATA li_container_element TYPE REF TO if_ixml_element.
DATA li_document TYPE REF TO if_ixml_document.
li_document = io_xml->get_raw( ).
li_container_element = li_document->find_from_name_ns( 'CONTAINER' ).
IF li_container_element IS BOUND.
li_document = cl_ixml=>create( )->create_document( ).
li_stream = cl_ixml=>create( )->create_stream_factory( )->create_ostream_xstring( rv_result ).
li_document->append_child( li_container_element ).
cl_ixml=>create( )->create_renderer(
document = li_document
ostream = li_stream
)->render( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
CALL FUNCTION 'RH_HRSOBJECT_DELETE'
EXPORTING
act_otype = c_object_type_task
act_objid = mv_objid
no_confirmation_msg = abap_true
EXCEPTIONS
enqueue_failed = 1
object_not_deleted = 2
object_not_found = 3
OTHERS = 4. "#EC SUBRC_OK
check_subrc_for( `RH_HRSOBJECT_DELETE` ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
CALL FUNCTION 'RH_READ_OBJECT'
EXPORTING
plvar = '01'
otype = c_object_type_task
objid = mv_objid
istat = '1'
begda = sy-datum
endda = '99991231'
ointerval = 'X'
read_db = 'X'
EXCEPTIONS
not_found = 1
OTHERS = 2.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'HRSOBJECT'
iv_argument = c_object_type_task && mv_objid ).
ENDMETHOD.
METHOD zif_abapgit_object~is_active.
rv_active = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE uname
INTO rv_user
FROM hrs1201
WHERE otype = c_object_type_task AND
objid = ms_item-obj_name.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS_REMOTE'
STARTING NEW TASK 'GIT'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
EXCEPTIONS
OTHERS = 0.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~get_comparator.
RETURN.
ENDMETHOD.
METHOD zif_abapgit_object~get_deserialize_steps.
APPEND zif_abapgit_object=>gc_step_id-abap TO rt_steps.
ENDMETHOD.
METHOD check_subrc_for.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( iv_call && ' returned ' && sy-subrc ).
ENDIF.
ENDMETHOD.
METHOD is_experimental.
DATA lo_settings TYPE REF TO zcl_abapgit_settings.
DATA lo_settings_persistence TYPE REF TO zcl_abapgit_persist_settings.
lo_settings_persistence = zcl_abapgit_persist_settings=>get_instance( ).
lo_settings = lo_settings_persistence->read( ).
rv_result = lo_settings->get_experimental_features( ).
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,31 @@
INTERFACE lif_task_definition.
TYPES: BEGIN OF ty_task_data,
short_text TYPE hr_mcshort,
plvar TYPE plvar,
wi_text TYPE witext,
method TYPE hrs1201,
method_binding TYPE hrsmtbind,
starting_events TYPE hrsevtab,
starting_events_binding TYPE hrsevbind,
terminating_events TYPE hrsetmtab,
terminating_events_binding TYPE hrsevbind,
descriptions TYPE wstexts,
END OF ty_task_data.
METHODS clear_origin_data.
METHODS get_definition RETURNING VALUE(rs_result) TYPE ty_task_data.
METHODS get_container RETURNING VALUE(ri_result) TYPE REF TO if_swf_cnt_container.
METHODS get_user_container RETURNING VALUE(ri_result) TYPE REF TO if_swf_cnt_container.
METHODS import_container IMPORTING iv_xml_string TYPE xstring
RAISING zcx_abapgit_exception.
METHODS create_task RAISING zcx_abapgit_exception.
METHODS save IMPORTING iv_package TYPE devclass OPTIONAL
RAISING zcx_abapgit_exception.
METHODS change_wi_text RAISING zcx_abapgit_exception.
METHODS change_method RAISING zcx_abapgit_exception.
METHODS change_start_events RAISING zcx_abapgit_exception.
METHODS change_terminating_events RAISING zcx_abapgit_exception.
METHODS change_text RAISING zcx_abapgit_exception.
ENDINTERFACE.

View File

@ -0,0 +1,370 @@
CLASS lcl_attribute_setter DEFINITION
INHERITING FROM cl_workflow_general_task_def
CREATE PUBLIC
FINAL.
PUBLIC SECTION.
CLASS-METHODS set_objid IMPORTING iv_objid TYPE hrobject-objid
io_task TYPE REF TO cl_workflow_general_task_def.
CLASS-METHODS set_container_id IMPORTING iv_id TYPE guid_32
io_task TYPE REF TO cl_workflow_general_task_def. "#EC NEEDED
ENDCLASS.
CLASS lcl_attribute_setter IMPLEMENTATION.
METHOD set_container_id.
FIELD-SYMBOLS <lv_object> TYPE REF TO if_swf_cnt_container.
ASSIGN ('IO_TASK->CONTAINER') TO <lv_object>.
ASSERT sy-subrc = 0.
CALL METHOD <lv_object>->('SET_GUID')
EXPORTING
guid_32 = iv_id.
ENDMETHOD.
METHOD set_objid.
io_task->objid = iv_objid.
ENDMETHOD.
ENDCLASS.
CLASS lcl_task_definition DEFINITION
CREATE PUBLIC
FINAL.
PUBLIC SECTION.
INTERFACES lif_task_definition.
CLASS-METHODS load IMPORTING iv_objid TYPE hrobject-objid
RETURNING VALUE(ri_result) TYPE REF TO lif_task_definition
RAISING zcx_abapgit_exception.
CLASS-METHODS create IMPORTING iv_objid TYPE hrobject-objid
is_task_data TYPE lif_task_definition=>ty_task_data
RETURNING VALUE(ri_result) TYPE REF TO lif_task_definition
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CONSTANTS c_subty_task_description TYPE hr_s_subty VALUE '0120'.
DATA mo_taskdef TYPE REF TO cl_workflow_task_ts.
DATA ms_task TYPE lif_task_definition=>ty_task_data.
DATA: mv_objid TYPE hrobjid.
METHODS supply_instance RAISING zcx_abapgit_exception.
METHODS check_subrc_for IMPORTING iv_call TYPE clike OPTIONAL
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS lcl_task_definition IMPLEMENTATION.
METHOD load.
DATA lo_taskdef TYPE REF TO lcl_task_definition.
CREATE OBJECT lo_taskdef.
lo_taskdef->mv_objid = iv_objid.
lo_taskdef->supply_instance( ).
ri_result = lo_taskdef.
ENDMETHOD.
METHOD check_subrc_for.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( iv_call && ' returned ' && sy-subrc ).
ENDIF.
ENDMETHOD.
METHOD supply_instance.
cl_workflow_factory=>create_ts(
EXPORTING
objid = mv_objid
RECEIVING
ts_inst = mo_taskdef
EXCEPTIONS
standard_task_does_not_exist = 1
object_could_not_be_locked = 2
objid_not_given = 3
OTHERS = 4 ) ##SUBRC_OK.
check_subrc_for( 'CREATE_TS' ).
ms_task-wi_text = mo_taskdef->wi_text.
ms_task-short_text = mo_taskdef->short_text.
ms_task-plvar = mo_taskdef->plvar.
ms_task-method = mo_taskdef->method.
ms_task-method_binding = mo_taskdef->method_binding.
ms_task-starting_events = mo_taskdef->starting_events.
ms_task-starting_events_binding = mo_taskdef->starting_events_binding.
ms_task-terminating_events = mo_taskdef->terminating_events.
ms_task-terminating_events_binding = mo_taskdef->terminating_events_binding.
ms_task-descriptions = mo_taskdef->descriptions.
ENDMETHOD.
METHOD lif_task_definition~clear_origin_data.
FIELD-SYMBOLS: <ls_description> TYPE hrs1002,
<ls_method_binding> TYPE hrs1214,
<ls_starting_events_binding> TYPE hrs1212,
<ls_term_events_binding> TYPE hrs1212.
CLEAR: ms_task-method-aedtm,
ms_task-method-uname.
LOOP AT ms_task-method_binding ASSIGNING <ls_method_binding>.
CLEAR: <ls_method_binding>-aedtm,
<ls_method_binding>-uname.
ENDLOOP.
LOOP AT ms_task-starting_events_binding ASSIGNING <ls_starting_events_binding>.
CLEAR: <ls_starting_events_binding>-aedtm,
<ls_starting_events_binding>-uname.
ENDLOOP.
LOOP AT ms_task-descriptions ASSIGNING <ls_description>.
CLEAR: <ls_description>-aedtm,
<ls_description>-uname.
ENDLOOP.
LOOP AT ms_task-terminating_events_binding ASSIGNING <ls_term_events_binding>.
CLEAR: <ls_term_events_binding>-aedtm,
<ls_term_events_binding>-uname.
ENDLOOP.
ENDMETHOD.
METHOD lif_task_definition~get_definition.
rs_result = me->ms_task.
ENDMETHOD.
METHOD lif_task_definition~get_container.
ri_result = mo_taskdef->container.
ENDMETHOD.
METHOD lif_task_definition~get_user_container.
DATA: li_container TYPE REF TO if_swf_cnt_element_access_1,
lt_user_elements TYPE swfdnamtab,
lt_system_elements TYPE swfdnamtab,
lv_element TYPE swfdname.
li_container = mo_taskdef->container.
lt_user_elements = li_container->all_elements_list( ).
lt_system_elements = li_container->all_elements_list( list_system = abap_true ).
LOOP AT lt_system_elements INTO lv_element.
READ TABLE lt_user_elements WITH KEY table_line = lv_element TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
TRY.
li_container->element_remove( name = lv_element ).
CATCH cx_swf_cnt_container.
"Shouldn't happen, doesn't matter if it does
ENDTRY.
ENDIF.
ENDLOOP.
ri_result ?= li_container.
ENDMETHOD.
METHOD create.
DATA lo_task TYPE REF TO lcl_task_definition.
CREATE OBJECT lo_task TYPE lcl_task_definition.
lo_task->mv_objid = iv_objid.
lo_task->ms_task = is_task_data.
ri_result = lo_task.
ENDMETHOD.
METHOD lif_task_definition~import_container.
DATA lt_exception_list TYPE swf_cx_tab.
DATA: lo_exception TYPE REF TO cx_swf_ifs_exception.
mo_taskdef->container->import_from_xml(
EXPORTING xml_stream = iv_xml_string
IMPORTING exception_list = lt_exception_list ).
IF lt_exception_list IS NOT INITIAL.
READ TABLE lt_exception_list INDEX 1 INTO lo_exception.
zcx_abapgit_exception=>raise( iv_text = lo_exception->get_text( )
ix_previous = lo_exception ).
ENDIF.
ENDMETHOD.
METHOD lif_task_definition~create_task.
cl_workflow_factory=>create_new_ts(
EXPORTING
short_text = |{ ms_task-short_text }|
text = |{ ms_task-wi_text }|
RECEIVING
task_object = mo_taskdef
EXCEPTIONS
text_exists_already = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `CREATE_NEW_TS` ).
lcl_attribute_setter=>set_objid( iv_objid = mv_objid
io_task = mo_taskdef ).
lcl_attribute_setter=>set_container_id( iv_id = |TS{ mv_objid }|
io_task = mo_taskdef ).
ENDMETHOD.
METHOD lif_task_definition~change_start_events.
mo_taskdef->change_start_events_complete(
EXPORTING
starting_events = ms_task-starting_events
EXCEPTIONS
no_changes_allowed = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_START_EVENTS_COMPLETE` ).
mo_taskdef->change_start_evt_bind_complete(
EXPORTING
new_bindings = ms_task-starting_events_binding
EXCEPTIONS
no_changes_allowed = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_START_EVT_BIND_COMPLETE` ).
ENDMETHOD.
METHOD lif_task_definition~save.
DATA ls_hrsobject TYPE hrsobject.
ls_hrsobject-otype = 'TS'. "swfco_org_standard_task - todo: linter can't resolve this
ls_hrsobject-objid = mv_objid.
INSERT hrsobject FROM ls_hrsobject.
mo_taskdef->save_standard_task(
EXPORTING
development_class = iv_package
iv_force_gen = abap_true
EXCEPTIONS
no_changes_allowed = 1
no_client_indep_maint = 2
update_error = 3
insert_error_new_ts = 4
new_ts_could_not_be_locked = 5
save_abort_by_user = 6
OTHERS = 7 ). "#EC SUBRC_OK
check_subrc_for( `SAVE_STANDARD_TASK` ).
ENDMETHOD.
METHOD lif_task_definition~change_wi_text.
mo_taskdef->change_wi_text(
EXPORTING
new_wi_text = ms_task-wi_text
EXCEPTIONS
no_changes_allowed = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_WI_TEXT` ).
ENDMETHOD.
METHOD lif_task_definition~change_method.
FIELD-SYMBOLS <ls_method_binding> TYPE hrs1214.
mo_taskdef->change_method(
EXPORTING
new_method = ms_task-method " New Method or Settings
EXCEPTIONS
no_changes_allowed = 1
problem_method_web_enabling = 2
problem_method_phon_enabling = 3
OTHERS = 4 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_METHOD` ).
LOOP AT ms_task-method_binding ASSIGNING <ls_method_binding>.
mo_taskdef->change_method_binding(
EXPORTING
binding = <ls_method_binding>
delete = abap_false
insert = abap_true
EXCEPTIONS
no_changes_allowed = 1
desired_action_not_clear = 2
ts_cnt_element_does_not_exist = 3
binding_could_not_be_deleted = 4
OTHERS = 5 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_METHOD_BINDING` ).
ENDLOOP.
ENDMETHOD.
METHOD lif_task_definition~change_terminating_events.
mo_taskdef->change_term_events_complete(
EXPORTING
terminating_events = ms_task-terminating_events
EXCEPTIONS
no_changes_allowed = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_TEXT` ).
mo_taskdef->change_term_evt_bind_complete(
EXPORTING
new_bindings = ms_task-terminating_events_binding
EXCEPTIONS
no_changes_allowed = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_TERM_EVENTS_COMPLETE` ).
ENDMETHOD.
METHOD lif_task_definition~change_text.
mo_taskdef->change_text(
EXPORTING
subty = c_subty_task_description
new_text = ms_task-descriptions
EXCEPTIONS
no_changes_allowed = 1
OTHERS = 2 ). "#EC SUBRC_OK
check_subrc_for( `CHANGE_TEXT` ).
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,465 @@
CLASS ltd_mock DEFINITION
FINAL
CREATE PUBLIC
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PUBLIC SECTION.
CONSTANTS mc_task_id TYPE hrobjid VALUE '99999999'.
METHODS create_input_xml RETURNING VALUE(ri_result) TYPE REF TO zif_abapgit_xml_input
RAISING zcx_abapgit_exception.
METHODS get_input_xml RETURNING VALUE(rv_result) TYPE string.
PRIVATE SECTION.
DATA mv_xml TYPE string.
METHODS generate.
METHODS add_line IMPORTING iv_string TYPE string.
METHODS add_pdts_segment.
METHODS add_container_segment.
ENDCLASS.
CLASS ltd_mock IMPLEMENTATION.
METHOD add_line.
mv_xml = mv_xml && iv_string && cl_abap_char_utilities=>newline.
ENDMETHOD.
METHOD generate.
"Todo: Automate GitHub updates, sort out XML discrepancies
"
"When pasting updates from GitHub, following changes are needed:
"UTF-16, remove serializer attribute from abapGit tag, replace task ID with variable
"
"<?xml version="1.0" encoding="utf-16"?>| ).
"<abapGit version="v1.0.0">| ).
"...
"Then replace all instances of task ID (e.g. 90000005), such as:
" <OBJID>{ mc_task_id }</OBJID>| ).
" <INSTID>TS{ mc_task_id }</INSTID>| ).
add_line( |<?xml version="1.0" encoding="utf-16"?>| ).
add_line( |<abapGit version="v1.0.0">| ).
add_line( | <asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">| ).
add_line( | <asx:values>| ).
add_pdts_segment( ).
add_container_segment( ).
add_line( | </asx:values>| ).
add_line( | </asx:abap>| ).
add_line( |</abapGit>| ).
ENDMETHOD.
METHOD add_pdts_segment.
add_line( | <PDTS>| ).
add_line( | <SHORT_TEXT>abapGitTest</SHORT_TEXT>| ).
add_line( | <PLVAR>01</PLVAR>| ).
add_line( | <WI_TEXT>abapGit Test &amp;_WI_OBJECT_ID.BUSINESSPARTNER&amp;</WI_TEXT>| ).
add_line( | <METHOD>| ).
add_line( | <OTYPE>TS</OTYPE>| ).
add_line( | <OBJID>{ mc_task_id }</OBJID>| ).
add_line( | <SWOTP>BUS1006</SWOTP>| ).
add_line( | <SWMTD>DISPLAY</SWMTD>| ).
add_line( | <METHTYPE>BO</METHTYPE>| ).
add_line( | <SYNCHRON>X</SYNCHRON>| ).
add_line( | </METHOD>| ).
add_line( | <STARTING_EVENTS>| ).
add_line( | <HRSEVENTS>| ).
add_line( | <SUBTY>0001</SUBTY>| ).
add_line( | <CLSTYP>BO</CLSTYP>| ).
add_line( | <OBJTYP>BUS1006</OBJTYP>| ).
add_line( | <EVENT>CREATED</EVENT>| ).
add_line( | </HRSEVENTS>| ).
add_line( | </STARTING_EVENTS>| ).
add_line( | <STARTING_EVENTS_BINDING>| ).
add_line( | <HRS1212>| ).
add_line( | <OTYPE>TS</OTYPE>| ).
add_line( | <OBJID>{ mc_task_id }</OBJID>| ).
add_line( | <SUBTY>0001</SUBTY>| ).
add_line( | <CLSTYP>BO</CLSTYP>| ).
add_line( | <OBJTYP>BUS1006</OBJTYP>| ).
add_line( | <EVENT>CREATED</EVENT>| ).
add_line( | <DATAFLOW>E</DATAFLOW>| ).
add_line( | <TAB_INDEX>000001</TAB_INDEX>| ).
add_line( | <EXPR>&amp;_EVT_OBJECT&amp;</EXPR>| ).
add_line( | <SOURCETYPE>S</SOURCETYPE>| ).
add_line( | <TARGETTYPE>S</TARGETTYPE>| ).
add_line( | <TARGETEXPR>&amp;_WI_OBJECT_ID&amp;</TARGETEXPR>| ).
add_line( | <OPERATION>ASN</OPERATION>| ).
add_line( | <OPCLASS>E</OPCLASS>| ).
add_line( | </HRS1212>| ).
add_line( | </STARTING_EVENTS_BINDING>| ).
add_line( | <TERMINATING_EVENTS>| ).
add_line( | <HRSEVTERM>| ).
add_line( | <SUBTY>0002</SUBTY>| ).
add_line( | <CLSTYP>BO</CLSTYP>| ).
add_line( | <OBJTYP>BUS1006</OBJTYP>| ).
add_line( | <EVENT>CHANGED</EVENT>| ).
add_line( | <EV_ELEMENT>_WI_OBJECT_ID</EV_ELEMENT>| ).
add_line( | </HRSEVTERM>| ).
add_line( | </TERMINATING_EVENTS>| ).
add_line( | <TERMINATING_EVENTS_BINDING>| ).
add_line( | <HRS1212>| ).
add_line( | <OTYPE>TS</OTYPE>| ).
add_line( | <OBJID>{ mc_task_id }</OBJID>| ).
add_line( | <SUBTY>0002</SUBTY>| ).
add_line( | <CLSTYP>BO</CLSTYP>| ).
add_line( | <OBJTYP>BUS1006</OBJTYP>| ).
add_line( | <EVENT>CHANGED</EVENT>| ).
add_line( | <DATAFLOW>E</DATAFLOW>| ).
add_line( | <TAB_INDEX>000001</TAB_INDEX>| ).
add_line( | <EV_ELEMENT>_WI_OBJECT_ID</EV_ELEMENT>| ).
add_line( | <EXPR>&amp;_EVT_OBJECT&amp;</EXPR>| ).
add_line( | <SOURCETYPE>S</SOURCETYPE>| ).
add_line( | <TARGETTYPE>S</TARGETTYPE>| ).
add_line( | <TARGETEXPR>&amp;_WI_OBJECT_ID&amp;</TARGETEXPR>| ).
add_line( | <OPERATION>ASN</OPERATION>| ).
add_line( | <OPCLASS>E</OPCLASS>| ).
add_line( | </HRS1212>| ).
add_line( | </TERMINATING_EVENTS_BINDING>| ).
add_line( | </PDTS>| ).
ENDMETHOD.
METHOD add_container_segment.
add_line( | <CONTAINER>| ).
add_line( | <CONTAINER>| ).
add_line( | <PROPERTIES>| ).
add_line( | <OWN_ID>| ).
add_line( | <INSTID>TS{ mc_task_id }</INSTID>| ).
add_line( | <TYPEID>CL_SWF_CNT_HRS_PERSISTENCE</TYPEID>| ).
add_line( | <CATID>CL</CATID>| ).
add_line( | </OWN_ID>| ).
add_line( | <PROPSTRING>23000000000008</PROPSTRING>| ).
add_line( | <XMLVERSION>0002</XMLVERSION>| ).
add_line( | <INTERNAL>X</INTERNAL>| ).
add_line( | <EXDEFINITN>| ).
add_line( | <NAME>_DEF_EXT</NAME>| ).
add_line( | <POR>| ).
add_line( | <INSTID>DIALOG_STEP_CONTAINER</INSTID>| ).
add_line( | <TYPEID>CL_SWF_CNT_PERSISTENCE_DEF_EXT</TYPEID>| ).
add_line( | <CATID>CL</CATID>| ).
add_line( | </POR>| ).
add_line( | </EXDEFINITN>| ).
add_line( | </PROPERTIES>| ).
add_line( | <ELEMENTS>| ).
add_line( | <M NAME="NEWINTERNALMODE:NewInternalMode:" TYPE="::BAPIBUS1006_HEAD-NEWINTERNALMODE:C:1:0" PROPS="0C003301"/>| ).
add_line( | <N NAME="FOO:Foo:" TYPE="::CHAR10:h:10:0" PROPS="0C005241"/>| ).
add_line( | </ELEMENTS>| ).
add_line( | </CONTAINER>| ).
add_line( | </CONTAINER>| ).
ENDMETHOD.
METHOD create_input_xml.
generate( ).
CREATE OBJECT ri_result TYPE zcl_abapgit_xml_input
EXPORTING
iv_xml = mv_xml.
ENDMETHOD.
METHOD get_input_xml.
rv_result = me->mv_xml.
ENDMETHOD.
ENDCLASS.
CLASS ltc_turnaround_test DEFINITION FINAL FOR TESTING
DURATION LONG
RISK LEVEL CRITICAL.
PRIVATE SECTION.
DATA mo_mock TYPE REF TO ltd_mock.
DATA mi_output_xml TYPE REF TO zif_abapgit_xml_output.
DATA mo_cut TYPE REF TO zif_abapgit_object.
CLASS-METHODS class_setup.
CLASS-METHODS task_exists RETURNING VALUE(rv_result) TYPE abap_bool.
CLASS-METHODS check_critical_tests_enabled.
CLASS-METHODS check_task_does_not_exist.
METHODS setup.
METHODS create_task RAISING zcx_abapgit_exception.
METHODS serialize_task RETURNING VALUE(rv_result) TYPE string
RAISING zcx_abapgit_exception.
METHODS clean_xml IMPORTING iv_xml TYPE string
RETURNING VALUE(rv_result) TYPE string.
METHODS delete_task
RAISING
zcx_abapgit_exception.
METHODS output_matches_input FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltc_turnaround_test IMPLEMENTATION.
METHOD class_setup.
check_critical_tests_enabled( ).
check_task_does_not_exist( ).
ENDMETHOD.
METHOD check_critical_tests_enabled.
"Objects will be created and deleted, do not run in customer system!
"These tests may fail if you are locking the entries (e.g. the ZABAPGIT transaction is open)
IF zcl_abapgit_persist_settings=>get_instance( )->read( )->get_run_critical_tests( ) = abap_false.
cl_abap_unit_assert=>fail(
msg = 'Cancelled. You can enable these tests at the Settings page'
level = if_aunit_constants=>tolerable ).
ENDIF.
ENDMETHOD.
METHOD check_task_does_not_exist.
IF task_exists( ) = abap_true.
cl_abap_unit_assert=>fail( msg = |Test task { ltd_mock=>mc_task_id } already exists|
level = if_aunit_constants=>fatal
quit = if_aunit_constants=>class ).
ENDIF.
ENDMETHOD.
METHOD setup.
DATA ls_item TYPE zif_abapgit_definitions=>ty_item.
ls_item-obj_type = 'PDTS'.
ls_item-obj_name = ltd_mock=>mc_task_id.
TRY.
CREATE OBJECT mo_cut TYPE zcl_abapgit_object_pdts
EXPORTING
is_item = ls_item
iv_language = sy-langu.
CATCH zcx_abapgit_exception.
cl_abap_unit_assert=>fail( ).
ENDTRY.
CREATE OBJECT mo_mock.
ENDMETHOD.
METHOD output_matches_input.
DATA lv_output TYPE string.
create_task( ).
cl_abap_unit_assert=>assert_equals( act = mo_cut->changed_by( )
exp = sy-uname ).
lv_output = serialize_task( ).
lv_output = clean_xml( lv_output ).
cl_abap_unit_assert=>assert_equals( act = lv_output
exp = mo_mock->get_input_xml( ) ).
delete_task( ).
ENDMETHOD.
METHOD clean_xml.
rv_result = substring_from( val = iv_xml
sub = '<' ).
ENDMETHOD.
METHOD create_task.
DATA lo_input_xml TYPE REF TO zif_abapgit_xml_input.
DATA: lv_step TYPE zif_abapgit_definitions=>ty_deserialization_step,
li_log TYPE REF TO zif_abapgit_log. "#EC NEEDED
lo_input_xml = mo_mock->create_input_xml( ).
mo_cut->deserialize( iv_package = '$TMP'
io_xml = lo_input_xml
iv_step = lv_step
ii_log = li_log ).
cl_abap_unit_assert=>assert_true( task_exists( ) ).
cl_abap_unit_assert=>assert_true( mo_cut->exists( ) ).
ENDMETHOD.
METHOD serialize_task.
CREATE OBJECT mi_output_xml TYPE zcl_abapgit_xml_output.
mo_cut->serialize( io_xml = mi_output_xml ).
rv_result = mi_output_xml->render( ).
ENDMETHOD.
METHOD delete_task.
mo_cut->delete( iv_package = '$TMP' ).
cl_abap_unit_assert=>assert_false( task_exists( ) ).
ENDMETHOD.
METHOD task_exists.
DATA lv_dummy TYPE hr_sobjid.
SELECT SINGLE objid
INTO lv_dummy
FROM hrs1000
WHERE otype = 'TS' AND
objid = ltd_mock=>mc_task_id ##WARN_OK.
IF sy-subrc = 0.
rv_result = abap_true.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ltc_lock DEFINITION
FINAL
FOR TESTING
DURATION MEDIUM
RISK LEVEL HARMLESS.
PRIVATE SECTION.
CONSTANTS c_ts TYPE hr_sotype VALUE 'TS'.
METHODS enqueue_is_detected FOR TESTING RAISING cx_static_check.
METHODS get_any_task RETURNING VALUE(rv_taskid) TYPE hrobjid.
METHODS lock_task IMPORTING iv_taskid TYPE hrobjid.
ENDCLASS.
CLASS ltc_lock IMPLEMENTATION.
METHOD enqueue_is_detected.
DATA: lv_taskid TYPE hrobjid,
lo_cut TYPE REF TO zif_abapgit_object,
ls_item TYPE zif_abapgit_definitions=>ty_item.
lv_taskid = get_any_task( ).
lock_task( lv_taskid ).
ls_item-obj_type = 'PDTS'.
ls_item-obj_name = 'TS' && lv_taskid.
CREATE OBJECT lo_cut TYPE zcl_abapgit_object_pdts
EXPORTING
is_item = ls_item
iv_language = sy-langu.
cl_abap_unit_assert=>assert_true( lo_cut->is_locked( ) ).
CALL FUNCTION 'DEQUEUE_HRSOBJECT'
EXPORTING
objid = lv_taskid
otype = c_ts
x_objid = ' '
x_otype = ' '
_scope = '2'.
ENDMETHOD.
METHOD get_any_task.
SELECT SINGLE objid
INTO rv_taskid
FROM hrs1000
WHERE otype = c_ts ##WARN_OK. "#EC CI_NOORDER #EC CI_SGLSELECT
cl_abap_unit_assert=>assert_subrc( exp = 0
act = sy-subrc ).
ENDMETHOD.
METHOD lock_task.
CALL FUNCTION 'ENQUEUE_HRSOBJECT'
EXPORTING
objid = iv_taskid
otype = c_ts
x_objid = ' '
x_otype = ' '
_scope = '2'
_wait = ' '
EXCEPTIONS
foreign_lock = 01
system_failure = 02.
cl_abap_unit_assert=>assert_subrc( exp = 0
act = sy-subrc ).
ENDMETHOD.
ENDCLASS.
CLASS ltc_smoke_test DEFINITION FINAL FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO zif_abapgit_object.
METHODS setup.
METHODS run_simple_methods FOR TESTING RAISING cx_static_check.
ENDCLASS.
CLASS ltc_smoke_test IMPLEMENTATION.
METHOD setup.
DATA ls_item TYPE zif_abapgit_definitions=>ty_item.
ls_item-obj_type = 'PDTS'.
ls_item-obj_name = ltd_mock=>mc_task_id.
TRY.
CREATE OBJECT mo_cut TYPE zcl_abapgit_object_pdts
EXPORTING
is_item = ls_item
iv_language = sy-langu.
CATCH zcx_abapgit_exception.
cl_abap_unit_assert=>fail( ).
ENDTRY.
ENDMETHOD.
METHOD run_simple_methods.
mo_cut->get_comparator( ).
mo_cut->get_deserialize_steps( ).
mo_cut->get_metadata( ).
mo_cut->is_active( ).
ENDMETHOD.
ENDCLASS.

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<VSEOCLASS>
<CLSNAME>ZCL_ABAPGIT_OBJECT_PDTS</CLSNAME>
<LANGU>E</LANGU>
<DESCRIPT>Workflow Task</DESCRIPT>
<STATE>1</STATE>
<CLSCCINCL>X</CLSCCINCL>
<FIXPT>X</FIXPT>
<UNICODE>X</UNICODE>
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
</VSEOCLASS>
</asx:values>
</asx:abap>
</abapGit>