import { session_types } from "../" ; import { NewObjectOptions } from "../" ; import { AdtLock } from "../" ; import { ADTClient } from "../AdtClient" ; import { hasPackageOptions , isGroupType , NewPackageOptions , RenameRefactoringProposal , TransportsOfUser } from "../api" ; import { ObjectValidateOptions } from "./../api" ; import { hasAbapGit , runTest } from "./login" ; const doRunTest = ( f ) => runTest ( f ) ( ) ; function enableWrite ( time1 ) { const time2 = new Date ( ) ; const diff = time2 . getTime ( ) - time1 . getTime ( ) ; return diff > 1000 || process . env . ADT_ENABLE_ALL === "YES" ; } async function deleteObj ( object , c , rethrow = false ) { let result ; try { c . stateful = session_types . stateful ; const handle = await c . lock ( object ) ; result = await c . deleteObject ( object , handle . LOCK_HANDLE ) ; } catch ( e ) { if ( rethrow ) throw e ; } await c . dropSession ( ) ; return result ; } async function createObj ( options , newobject , c ) { if ( isGroupType ( options . objtype ) ) return ; const baseValidateOptions = { ... options , objname : options . name , packagename : options . parentName } as ObjectValidateOptions ; const validateOptions = hasPackageOptions ( options ) ? { ... baseValidateOptions , swcomp : options . swcomp , transportLayer : options . transportLayer , packagetype : options . description } : baseValidateOptions ; const vresult = await c . validateNewObject ( validateOptions ) ; expect ( vresult ) . toBeDefined ( ) ; expect ( vresult . success ) . toBeTruthy ( ) ; await c . statelessClone . createObject ( options ) ; return await c . objectStructure ( newobject ) ; } const delay = ( ms ) => new Promise ( resolve => setTimeout ( resolve , ms ) ) ; test ( "createTransport" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const transp = await c . createTransport ( "/sap/bc/adt/oo/classes/zapidummytestcreation/source/main" , "creation test" , "ZAPIDUMMY" ) ; expect ( transp ) . toMatch ( new RegExp ( `${ process . env . ADT_SYSTEMID }K9[\d]*` ) ) ; } ) ; } ) ; test ( "Create and delete" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const options = { description : "test object for ADT API" , name : "Y_ADTNPM_FOOBAR" , objtype : "FUGR/F" , parentName : "$TMP" , parentPath : "/sap/bc/adt/packages/$TMP" } ; const newobject = "/sap/bc/adt/functions/groups/y_adtnpm_foobar" ; await deleteObj ( newobject , c ) ; await c . login ( ) ; await c . createObject ( options ) ; await c . createObject ( { description : "test FM" , name : "Y_ADTNPM_FOOBARFM" , objtype : "FUGR/FF" , parentName : "Y_ADTNPM_FOOBAR" , parentPath : newobject } ) ; await deleteObj ( newobject , c , true ) ; } ) ; } ) ; test ( "write_program" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const name = "zadttest_temporary" ; const path = "/sap/bc/adt/programs/programs/" + name ; const main = path + "/source/main" ; const source = `Report ${ name }.\nwrite:/ 'Hello,World!'.` ; try { await deleteObj ( path , c ) ; } catch ( _ ) { } try { await c . createObject ( { description : "temporary test program" , name , objtype : "PROG/P" , parentName : "$TMP" , parentPath : "/sap/bc/adt/packages/$TMP" } ) ; c . stateful = session_types . stateful ; const handle = await c . lock ( path ) ; await c . setObjectSource ( main , source , handle . LOCK_HANDLE ) ; const newsource = await c . getObjectSource ( main ) ; expect ( newsource ) . toMatch ( /Hello,World!/m ) ; await c . deleteObject ( path , handle . LOCK_HANDLE ) ; await c . unLock ( path , handle . LOCK_HANDLE ) ; } finally { c . dropSession ( ) ; } } ) ; } ) ; test ( "save with transport" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const path = "/sap/bc/adt/oo/classes/zapidummyfoobar/includes/implementations" ; const contents = "" ; c . stateful = session_types . stateful ; const handle = await c . lock ( "/sap/bc/adt/oo/classes/zapidummyfoobar" ) ; await c . setObjectSource ( path , contents , handle . LOCK_HANDLE , process . env . ADT_TRANS ) ; await c . unLock ( "/sap/bc/adt/oo/classes/zapidummyfoobar" , handle . LOCK_HANDLE ) ; } ) ; } ) ; test ( "Create and delete interface" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const newobject = "/sap/bc/adt/oo/interfaces/YIF_ADTNPM_FOOBAR" ; await c . createObject ( "INTF/OI" , "YIF_ADTNPM_FOOBAR" , "$TMP" , "test object for ADT API" , "/sap/bc/adt/packages/$TMP" ) ; try { c . stateful = session_types . stateful ; const handle = await c . lock ( newobject ) ; expect ( handle . LOCK_HANDLE ) . not . toBe ( "" ) ; await c . deleteObject ( newobject , handle . LOCK_HANDLE ) ; } catch ( e ) { fail ( "Deletion error" ) ; } } ) ; } ) ; test ( "Create inactive and try to activate" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const options = { description : "test inactive object for ADT API" , name : "zadttestinactive" , objtype : "PROG/P" , parentName : "$TMP" , parentPath : "/sap/bc/adt/packages/$TMP" } ; const newobject = "/sap/bc/adt/programs/programs/zadttestinactive" ; const contents = "REPORT zadttestinactive.\nfsdf.\nWRITE:/ 'Hello, World!'" ; let handle ; try { c . stateful = session_types . stateful ; handle = await c . lock ( newobject ) ; await c . deleteObject ( newobject , handle . LOCK_HANDLE ) ; } catch ( e ) { } await c . dropSession ( ) ; handle = undefined ; try { await c . statelessClone . createObject ( options ) ; c . stateful = session_types . stateful ; handle = await c . lock ( newobject ) ; expect ( handle . LOCK_HANDLE ) . not . toBe ( "" ) ; await c . setObjectSource ( newobject + "/source/main" , contents , handle . LOCK_HANDLE ) ; await c . unLock ( newobject , handle . LOCK_HANDLE ) ; const result = await c . activate ( "zadttestinactive" , "/sap/bc/adt/programs/programs/zadttestinactive" ) ; expect ( result ) . toBeDefined ( ) ; expect ( result . success ) . toBe ( false ) ; handle = await c . lock ( newobject ) ; await c . deleteObject ( newobject , handle . LOCK_HANDLE ) ; } catch ( e ) { throw e ; } } ) ; } ) ; test ( "pretty printer settings" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const settings = await c . prettyPrinterSetting ( ) ; expect ( settings ) . toBeDefined ( ) ; expect ( settings [ "abapformatter:indentation" ] ) . toBe ( true ) ; const newStyle = settings [ "abapformatter:style" ] === "toUpper" ? "toLower" : "toUpper" ; await c . setPrettyPrinterSetting ( settings [ "abapformatter:indentation" ] , newStyle ) ; const changed = await c . prettyPrinterSetting ( ) ; await c . setPrettyPrinterSetting ( settings [ "abapformatter:indentation" ] , settings [ "abapformatter:style" ] ) ; expect ( changed ) . toBeDefined ( ) ; expect ( changed [ "abapformatter:style" ] ) . toBe ( newStyle ) ; } ) ; } ) ; test ( "Create CDS objects" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const options = { description : "test CDS AC creation" , name : "zadttestcdsaccon" , objtype : "DCLS/DL" , parentName : "$TMP" , parentPath : "/sap/bc/adt/packages/$TMP" } ; const acconobj = `/sap/bc/adt/acm/dcl/sources/zadttestcdsaccon` ; const metaobj = `/sap/bc/adt/ddic/ddlx/sources/zadttestcdsmeta` ; const ddefobj = `/sap/bc/adt/ddic/ddl/sources/ZADT_TEST_DD` ; await deleteObj ( acconobj , c ) ; await deleteObj ( metaobj , c ) ; await deleteObj ( ddefobj , c ) ; try { const result = await createObj ( options , acconobj , c ) ; expect ( result ) . toBeDefined ( ) ; expect ( result ! . objectUrl ) . toBeDefined ( ) ; options . name = "zadttestcdsmeta" ; options . objtype = "DDLX/EX" ; const res2 = await createObj ( options , acconobj , c ) ; expect ( res2 ) . toBeDefined ( ) ; expect ( res2 ! . objectUrl ) . toBeDefined ( ) ; options . name = "ZADT_TEST_DD" ; options . objtype = "DDLS/DF" ; const res3 = await createObj ( options , acconobj , c ) ; expect ( res3 ) . toBeDefined ( ) ; expect ( res3 ! . objectUrl ) . toBeDefined ( ) ; await deleteObj ( acconobj , c ) ; await deleteObj ( metaobj , c ) ; await deleteObj ( ddefobj , c ) ; } catch ( e ) { throw e ; } finally { await c . dropSession ( ) ; await deleteObj ( acconobj , c ) ; await deleteObj ( metaobj , c ) ; await deleteObj ( ddefobj , c ) ; } } ) ; } ) ; test ( "Create and delete a package" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; const TMPPACKAGE = "$ADTAPIDUMMYPACKAGE" ; const TMPPACKAGEURL = `/sap/bc/adt/packages/${ TMPPACKAGE }` ; await doRunTest ( async ( c ) => { const options = { description : "test Package creation" , name : TMPPACKAGE , objtype : "DEVC/K" , parentName : "$TMP" , parentPath : "/sap/bc/adt/packages/$TMP" , transportLayer : "" , swcomp : "LOCAL" , packagetype : "development" } ; await deleteObj ( TMPPACKAGEURL , c ) ; try { const result = await createObj ( options , TMPPACKAGEURL , c ) ; expect ( result ) . toBeDefined ( ) ; expect ( result ! . objectUrl ) . toBeDefined ( ) ; await deleteObj ( TMPPACKAGEURL , c , true ) ; } catch ( e ) { throw e ; } finally { await c . dropSession ( ) ; await deleteObj ( TMPPACKAGEURL , c ) ; } } ) ; } ) ; test ( "Release a transport" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; jest . setTimeout ( 8000 ) ; await doRunTest ( async ( c ) => { const transp = await c . createTransport ( "/sap/bc/adt/oo/classes/zapidummytestcreation/source/main" , "release test" , "ZAPIDUMMY" ) ; expect ( transp ) . toBeDefined ( ) ; const result = await c . statelessClone . transportRelease ( transp ) ; expect ( result . length ) . toBeGreaterThan ( 0 ) ; expect ( result [ 0 ] [ "chkrun:status" ] ) . toBe ( "released" ) ; } ) ; } ) ; const findTrans = ( transports , target ) => { for ( const s of transports . workbench ) for ( const t of s . modifiable ) if ( t [ "tm:number" ] === target ) return t ; } ; test ( "Delete a transport" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const transp = await c . createTransport ( "/sap/bc/adt/oo/classes/zapidummytestcreation/source/main" , "transport delete test" , "ZAPIDUMMY" ) ; expect ( transp ) . toBeDefined ( ) ; let result = await c . userTransports ( process . env . ADT_USER ! ) ; expect ( findTrans ( result , transp ) ) . toBeDefined ( ) ; await c . statelessClone . transportDelete ( transp ) ; result = await c . userTransports ( process . env . ADT_USER ! ) ; expect ( findTrans ( result , transp ) ) . toBeUndefined ( ) ; } ) ; } ) ; test ( "Transport user changes" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const transp = await c . createTransport ( "/sap/bc/adt/oo/classes/zapidummytestcreation/source/main" , "transport user change" , "ZAPIDUMMY" ) ; expect ( transp ) . toBeDefined ( ) ; const resp = await c . transportSetOwner ( transp , "DDIC" ) ; expect ( resp [ "tm:targetuser" ] ) . toBe ( "DDIC" ) ; try { await c . statelessClone . transportDelete ( transp ) ; fail ( "Allowed to delete a transport after owner change" ) ; } catch ( e ) { } } ) ; } ) ; test ( "Create transports" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const transp = await c . createTransport ( "/sap/bc/adt/oo/classes/zapidummytestcreation/source/main" , "transport user add" , "ZAPIDUMMY" ) ; expect ( transp ) . toBeDefined ( ) ; try { const resp = await c . transportAddUser ( transp , "DDIC" ) ; expect ( resp [ "tm:number" ] . length ) . toBe ( 10 ) ; expect ( resp [ "tm:targetuser" ] ) . toBe ( "DDIC" ) ; expect ( resp [ "tm:number" ] ) . not . toBe ( transp ) ; } finally { await c . statelessClone . transportDelete ( transp ) ; } } ) ; } ) ; test ( "Create a test classes" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; await doRunTest ( async ( c ) => { const clas = "ZADTFOOBARTESTTCINCL" ; const clasurl = "/sap/bc/adt/oo/classes/" + clas . toLowerCase ( ) ; try { c . stateful = session_types . stateful ; const lock = await c . lock ( clasurl ) ; await c . deleteObject ( clasurl , lock . LOCK_HANDLE ) ; await c . dropSession ( ) ; } catch ( e ) { } await c . createObject ( "CLAS/OC" , clas , "$TMP" , "test with test classes include" , "/sap/bc/adt/packages/$TMP" ) ; try { c . stateful = session_types . stateful ; const lock = await c . lock ( clasurl ) ; await c . createTestInclude ( clas , lock . LOCK_HANDLE ) ; await c . dropSession ( ) ; const source = await c . getObjectSource ( clasurl + "/includes/testclasses" ) ; expect ( source ) . toBeDefined ( ) ; } finally { await c . dropSession ( ) ; c . stateful = session_types . stateful ; const lock = await c . lock ( clasurl ) ; await c . deleteObject ( clasurl , lock . LOCK_HANDLE ) ; await c . dropSession ( ) ; } } ) ; } ) ; test ( "create and pull AbapGit Repo" , async ( ) => { if ( ! enableWrite ( new Date ( ) ) ) return ; const PACKAGEURL = "https://github.com/marcellourbani/adt_api_dummy_test_repository.git" ; const PACKAGENAME = "$ADTAPI_TEST_GIT_REPO_DUMMY" ; const OBJECT = "/sap/bc/adt/programs/programs/zadtapi_test_git_program_dummy" ; jest . setTimeout ( 25000 ) ; await doRunTest ( async ( c ) => { if ( await hasAbapGit ( c ) ) { const getRepo = async ( ) => { const repos = await c . gitRepos ( ) ; for ( const repo of repos . filter ( r => r . sapPackage === PACKAGENAME ) ) return repo ; } ; const cleanup = async ( ) => { await deleteObj ( OBJECT , c ) ; await deleteObj ( `/sap/bc/adt/packages/${ PACKAGENAME }` , c ) ; const repo = await getRepo ( ) ; if ( repo ) await c . gitUnlinkRepo ( repo . key ) ; } ; await cleanup ( ) ; const options = { description : "test Package creation" , name : PACKAGENAME , objtype : "DEVC/K" , parentName : "$TMP" , parentPath : "/sap/bc/adt/packages/$TMP" , transportLayer : "" , swcomp : "LOCAL" , packagetype : "development" } ; try { await createObj ( options , `/sap/bc/adt/packages/${ PACKAGENAME }` , c ) ; const objects = await c . gitCreateRepo ( PACKAGENAME , PACKAGEURL ) ; expect ( objects ) . toBeDefined ( ) ; await deleteObj ( OBJECT , c ) ; const repo = await getRepo ( ) ; if ( repo ) { const pulledObjects = await c . gitPullRepo ( repo . key ) ; expect ( pulledObjects ) . toBeDefined ( ) ; const source = await c . getObjectSource ( `${ OBJECT }/source/main` ) ; expect ( source ) . toBeDefined ( ) ; } else fail ( "new repository doesn't exits" ) ; } finally { await cleanup ( ) ; } } } ) ; } ) ; test ( "rename" , runTest ( async ( c ) => { jest . setTimeout ( 8000 ) ; const uri = "/sap/bc/adt/oo/classes/zapiadt_testcase_class1/source/main" ; const renameEvaluate = await c . renameEvaluate ( uri , 22 , 11 , 11 ) ; expect ( renameEvaluate ) . toBeDefined ( ) ; expect ( renameEvaluate [ "oldName" ] ) . toBe ( "lv_test" ) ; renameEvaluate [ "newName" ] = "lv_test3" ; const renamePreview = Object . assign ( { } , renameEvaluate ) ; renamePreview [ "affectedObjects" ] . forEach ( obj => obj [ "textReplaceDeltas" ] . forEach ( replaceRelta => { replaceRelta [ "contentNew" ] = "lv_test3" ; replaceRelta [ "contentOld" ] = "lv_test" ; return replaceRelta ; } ) ) ; const info = await c . transportInfo ( renameEvaluate . affectedObjects [ 0 ] . parentUri , "ZAPIDUMMY" ) ; const preview = await c . renamePreview ( renamePreview , info . LOCKS ?. HEADER . TRKORR ) ; expect ( preview ) . toBeDefined ( ) ; if ( ! enableWrite ( new Date ( ) ) ) return ; const execute = await c . renameExecute ( preview ) ; expect ( execute ) . toBeDefined ( ) ; } ) ) ;