From 85fe73317145ff393903b7c3633da8ad1c4bad44 Mon Sep 17 00:00:00 2001 From: pokrakam Date: Tue, 29 Sep 2020 06:41:35 +0100 Subject: [PATCH] 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 * Update src/objects/zcl_abapgit_object_pdts.clas.abap Co-authored-by: Lars Hvam * 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 --- src/objects/zcl_abapgit_object_pdts.clas.abap | 318 ++++++++++++ ...l_abapgit_object_pdts.clas.locals_def.abap | 31 ++ ...l_abapgit_object_pdts.clas.locals_imp.abap | 370 ++++++++++++++ ..._abapgit_object_pdts.clas.testclasses.abap | 465 ++++++++++++++++++ src/objects/zcl_abapgit_object_pdts.clas.xml | 17 + 5 files changed, 1201 insertions(+) create mode 100644 src/objects/zcl_abapgit_object_pdts.clas.abap create mode 100644 src/objects/zcl_abapgit_object_pdts.clas.locals_def.abap create mode 100644 src/objects/zcl_abapgit_object_pdts.clas.locals_imp.abap create mode 100644 src/objects/zcl_abapgit_object_pdts.clas.testclasses.abap create mode 100644 src/objects/zcl_abapgit_object_pdts.clas.xml diff --git a/src/objects/zcl_abapgit_object_pdts.clas.abap b/src/objects/zcl_abapgit_object_pdts.clas.abap new file mode 100644 index 000000000..88ecd601e --- /dev/null +++ b/src/objects/zcl_abapgit_object_pdts.clas.abap @@ -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. diff --git a/src/objects/zcl_abapgit_object_pdts.clas.locals_def.abap b/src/objects/zcl_abapgit_object_pdts.clas.locals_def.abap new file mode 100644 index 000000000..79a94acf6 --- /dev/null +++ b/src/objects/zcl_abapgit_object_pdts.clas.locals_def.abap @@ -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. diff --git a/src/objects/zcl_abapgit_object_pdts.clas.locals_imp.abap b/src/objects/zcl_abapgit_object_pdts.clas.locals_imp.abap new file mode 100644 index 000000000..3ba5b0edf --- /dev/null +++ b/src/objects/zcl_abapgit_object_pdts.clas.locals_imp.abap @@ -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 TYPE REF TO if_swf_cnt_container. + + ASSIGN ('IO_TASK->CONTAINER') TO . + ASSERT sy-subrc = 0. + + CALL METHOD ->('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: TYPE hrs1002, + TYPE hrs1214, + TYPE hrs1212, + TYPE hrs1212. + + CLEAR: ms_task-method-aedtm, + ms_task-method-uname. + + LOOP AT ms_task-method_binding ASSIGNING . + CLEAR: -aedtm, + -uname. + ENDLOOP. + + LOOP AT ms_task-starting_events_binding ASSIGNING . + CLEAR: -aedtm, + -uname. + ENDLOOP. + + LOOP AT ms_task-descriptions ASSIGNING . + CLEAR: -aedtm, + -uname. + ENDLOOP. + + LOOP AT ms_task-terminating_events_binding ASSIGNING . + CLEAR: -aedtm, + -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 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 . + + mo_taskdef->change_method_binding( + EXPORTING + 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. diff --git a/src/objects/zcl_abapgit_object_pdts.clas.testclasses.abap b/src/objects/zcl_abapgit_object_pdts.clas.testclasses.abap new file mode 100644 index 000000000..977b0894f --- /dev/null +++ b/src/objects/zcl_abapgit_object_pdts.clas.testclasses.abap @@ -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 + " + "| ). + "| ). + "... + "Then replace all instances of task ID (e.g. 90000005), such as: + " { mc_task_id }| ). + " TS{ mc_task_id }| ). + + + add_line( || ). + add_line( || ). + add_line( | | ). + add_line( | | ). + + add_pdts_segment( ). + add_container_segment( ). + + add_line( | | ). + add_line( | | ). + add_line( || ). + + ENDMETHOD. + + + METHOD add_pdts_segment. + + add_line( | | ). + add_line( | abapGitTest| ). + add_line( | 01| ). + add_line( | abapGit Test &_WI_OBJECT_ID.BUSINESSPARTNER&| ). + add_line( | | ). + add_line( | TS| ). + add_line( | { mc_task_id }| ). + add_line( | BUS1006| ). + add_line( | DISPLAY| ). + add_line( | BO| ). + add_line( | X| ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | 0001| ). + add_line( | BO| ). + add_line( | BUS1006| ). + add_line( | CREATED| ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | TS| ). + add_line( | { mc_task_id }| ). + add_line( | 0001| ). + add_line( | BO| ). + add_line( | BUS1006| ). + add_line( | CREATED| ). + add_line( | E| ). + add_line( | 000001| ). + add_line( | &_EVT_OBJECT&| ). + add_line( | S| ). + add_line( | S| ). + add_line( | &_WI_OBJECT_ID&| ). + add_line( | ASN| ). + add_line( | E| ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | 0002| ). + add_line( | BO| ). + add_line( | BUS1006| ). + add_line( | CHANGED| ). + add_line( | _WI_OBJECT_ID| ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | TS| ). + add_line( | { mc_task_id }| ). + add_line( | 0002| ). + add_line( | BO| ). + add_line( | BUS1006| ). + add_line( | CHANGED| ). + add_line( | E| ). + add_line( | 000001| ). + add_line( | _WI_OBJECT_ID| ). + add_line( | &_EVT_OBJECT&| ). + add_line( | S| ). + add_line( | S| ). + add_line( | &_WI_OBJECT_ID&| ). + add_line( | ASN| ). + add_line( | E| ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + + ENDMETHOD. + + + METHOD add_container_segment. + + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | TS{ mc_task_id }| ). + add_line( | CL_SWF_CNT_HRS_PERSISTENCE| ). + add_line( | CL| ). + add_line( | | ). + add_line( | 23000000000008| ). + add_line( | 0002| ). + add_line( | X| ). + add_line( | | ). + add_line( | _DEF_EXT| ). + add_line( | | ). + add_line( | DIALOG_STEP_CONTAINER| ). + add_line( | CL_SWF_CNT_PERSISTENCE_DEF_EXT| ). + add_line( | CL| ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + add_line( | | ). + + 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. diff --git a/src/objects/zcl_abapgit_object_pdts.clas.xml b/src/objects/zcl_abapgit_object_pdts.clas.xml new file mode 100644 index 000000000..fd2ba1c3b --- /dev/null +++ b/src/objects/zcl_abapgit_object_pdts.clas.xml @@ -0,0 +1,17 @@ + + + + + + ZCL_ABAPGIT_OBJECT_PDTS + E + Workflow Task + 1 + X + X + X + X + + + +