11import {
22 ExperimentCRUDUtils ,
3- generateFieldName ,
3+ generateDomainName ,
44 getEscapedNameExpression ,
55 hookServer ,
66 RequestOptions ,
@@ -12,6 +12,7 @@ import {
1212 checkLackDesignerOrReaderPerm ,
1313 createSource ,
1414 deleteSourceType ,
15+ generateFieldNameForImport ,
1516 getDataClassRowIdByName ,
1617 initProject ,
1718 verifyRequiredLineageInsertUpdate ,
@@ -518,7 +519,7 @@ describe('Multi Value Text Choice', () => {
518519 } ) ;
519520
520521 const dataType = 'MVTCReq Source Type' ;
521- const fieldName = generateFieldName ( ) ;
522+ const fieldName = generateFieldNameForImport ( ) ;
522523 const fieldNameInExpression = getEscapedNameExpression ( ( fieldName ) ) ;
523524 console . log ( "Selected Required MVTC dataclass name: " + dataType + ", field name: " + fieldName ) ;
524525
@@ -818,4 +819,144 @@ describe('Multi Value Text Choice', () => {
818819
819820 } ) ;
820821
821- } ) ;
822+ } ) ;
823+
824+ describe ( 'Data CRUD' , ( ) => {
825+
826+ it ( "Update using different key fields" , async ( ) => {
827+ const dataType = generateDomainName ( 3 ) + "UpdateKeyFields" ;
828+ const fieldName = generateFieldNameForImport ( ) ;
829+ console . log ( "Selected dataclass name: " + dataType + ", field name: " + fieldName ) ;
830+
831+ // create data class with one field
832+ await server . post ( 'property' , 'createDomain' , {
833+ kind : 'DataClass' ,
834+ domainDesign : { name : dataType , fields : [ { name : fieldName } ] } ,
835+ options : { name : dataType }
836+ } , { ...topFolderOptions , ...designerReaderOptions } ) . expect ( successfulResponse ) ;
837+
838+ // insert 2 rows data, provide explicit names and a rowId = -1
839+ const dataName1 = 'KeyData1' ;
840+ const dataName2 = 'KeyData2' ;
841+ const inserted = await insertDataClassData ( [
842+ { name : dataName1 , description : 'original1' , [ fieldName ] : 'val1' , rowId : - 1 } ,
843+ { name : dataName2 , description : 'original2' , [ fieldName ] : 'val2' , rowId : - 1 } ,
844+ ] , dataType , topFolderOptions ) ;
845+
846+ // verify both rows are inserted with correct name and rowId is not -1 for both rows, record the rowId and lsid for both rows
847+ expect ( inserted [ 0 ] . name ) . toBe ( dataName1 ) ;
848+ expect ( inserted [ 1 ] . name ) . toBe ( dataName2 ) ;
849+ expect ( inserted [ 0 ] . rowId ) . not . toBe ( - 1 ) ;
850+ expect ( inserted [ 1 ] . rowId ) . not . toBe ( - 1 ) ;
851+ const row1RowId = inserted [ 0 ] . rowId ;
852+ const row1Lsid = inserted [ 0 ] . lsid ;
853+ const row2RowId = inserted [ 1 ] . rowId ;
854+ const row2Lsid = inserted [ 1 ] . lsid ;
855+
856+ const findRow = ( rows : any [ ] , rowId : number ) => rows . find ( r => caseInsensitive ( r , 'RowId' ) === rowId ) ;
857+
858+ // update description and fieldName value for both rows using rowId as key, verify update is successful and data are updated correctly
859+ await ExperimentCRUDUtils . updateRows ( server , [
860+ { rowId : row1RowId , description : 'updByRowId1' , [ fieldName ] : 'rowIdVal1' } ,
861+ { rowId : row2RowId , description : 'updByRowId2' , [ fieldName ] : 'rowIdVal2' } ,
862+ ] , 'exp.data' , dataType , topFolderOptions , editorUserOptions ) ;
863+
864+ let rows = await ExperimentCRUDUtils . getRows ( server , [ row1RowId , row2RowId ] , 'exp.data' , dataType , '*' , topFolderOptions , adminOptions ) ;
865+ let row1 = findRow ( rows , row1RowId ) ;
866+ let row2 = findRow ( rows , row2RowId ) ;
867+ expect ( caseInsensitive ( row1 , 'description' ) ) . toBe ( 'updByRowId1' ) ;
868+ expect ( caseInsensitive ( row1 , fieldName ) ) . toBe ( 'rowIdVal1' ) ;
869+ expect ( caseInsensitive ( row2 , 'description' ) ) . toBe ( 'updByRowId2' ) ;
870+ expect ( caseInsensitive ( row2 , fieldName ) ) . toBe ( 'rowIdVal2' ) ;
871+
872+ // update description and fieldName value for both rows using lsid as key, verify update is successful and data are updated correctly
873+ await ExperimentCRUDUtils . updateRows ( server , [
874+ { lsid : row1Lsid , description : 'updByLsid1' , [ fieldName ] : 'lsidVal1' } ,
875+ { lsid : row2Lsid , description : 'updByLsid2' , [ fieldName ] : 'lsidVal2' } ,
876+ ] , 'exp.data' , dataType , topFolderOptions , editorUserOptions ) ;
877+
878+ rows = await ExperimentCRUDUtils . getRows ( server , [ row1RowId , row2RowId ] , 'exp.data' , dataType , '*' , topFolderOptions , adminOptions ) ;
879+ row1 = findRow ( rows , row1RowId ) ;
880+ row2 = findRow ( rows , row2RowId ) ;
881+ expect ( caseInsensitive ( row1 , 'description' ) ) . toBe ( 'updByLsid1' ) ;
882+ expect ( caseInsensitive ( row1 , fieldName ) ) . toBe ( 'lsidVal1' ) ;
883+ expect ( caseInsensitive ( row2 , 'description' ) ) . toBe ( 'updByLsid2' ) ;
884+ expect ( caseInsensitive ( row2 , fieldName ) ) . toBe ( 'lsidVal2' ) ;
885+
886+ // update description and fieldName value, one of the row use lsid as key, the other use rowId, verify update is successful and data are updated correctly
887+ await ExperimentCRUDUtils . updateRows ( server , [
888+ { lsid : row1Lsid , description : 'updMixed1' , [ fieldName ] : 'mixedVal1' } ,
889+ { rowId : row2RowId , description : 'updMixed2' , [ fieldName ] : 'mixedVal2' } ,
890+ ] , 'exp.data' , dataType , topFolderOptions , editorUserOptions ) ;
891+
892+ rows = await ExperimentCRUDUtils . getRows ( server , [ row1RowId , row2RowId ] , 'exp.data' , dataType , '*' , topFolderOptions , adminOptions ) ;
893+ row1 = findRow ( rows , row1RowId ) ;
894+ row2 = findRow ( rows , row2RowId ) ;
895+ expect ( caseInsensitive ( row1 , 'description' ) ) . toBe ( 'updMixed1' ) ;
896+ expect ( caseInsensitive ( row1 , fieldName ) ) . toBe ( 'mixedVal1' ) ;
897+ expect ( caseInsensitive ( row2 , 'description' ) ) . toBe ( 'updMixed2' ) ;
898+ expect ( caseInsensitive ( row2 , fieldName ) ) . toBe ( 'mixedVal2' ) ;
899+
900+ // update names of both rows using lsid as key, verify update is successful and names are updated correctly
901+ const newName1 = 'RenamedByLsid1' ;
902+ const newName2 = 'RenamedByLsid2' ;
903+ await ExperimentCRUDUtils . updateRows ( server , [
904+ { lsid : row1Lsid , name : newName1 } ,
905+ { lsid : row2Lsid , name : newName2 } ,
906+ ] , 'exp.data' , dataType , topFolderOptions , editorUserOptions ) ;
907+
908+ rows = await ExperimentCRUDUtils . getRows ( server , [ row1RowId , row2RowId ] , 'exp.data' , dataType , 'RowId,Name' , topFolderOptions , adminOptions ) ;
909+ row1 = findRow ( rows , row1RowId ) ;
910+ row2 = findRow ( rows , row2RowId ) ;
911+ expect ( caseInsensitive ( row1 , 'Name' ) ) . toBe ( newName1 ) ;
912+ expect ( caseInsensitive ( row2 , 'Name' ) ) . toBe ( newName2 ) ;
913+
914+ // update names of both rows using rowId as key, verify update is successful and names are updated correctly
915+ const newName3 = 'RenamedByRowId1' ;
916+ const newName4 = 'RenamedByRowId2' ;
917+ await ExperimentCRUDUtils . updateRows ( server , [
918+ { rowId : row1RowId , name : newName3 } ,
919+ { rowId : row2RowId , name : newName4 } ,
920+ ] , 'exp.data' , dataType , topFolderOptions , editorUserOptions ) ;
921+
922+ rows = await ExperimentCRUDUtils . getRows ( server , [ row1RowId , row2RowId ] , 'exp.data' , dataType , 'RowId,Name' , topFolderOptions , adminOptions ) ;
923+ row1 = findRow ( rows , row1RowId ) ;
924+ row2 = findRow ( rows , row2RowId ) ;
925+ expect ( caseInsensitive ( row1 , 'Name' ) ) . toBe ( newName3 ) ;
926+ expect ( caseInsensitive ( row2 , 'Name' ) ) . toBe ( newName4 ) ;
927+
928+ // update description and fieldName value from Import with update, the import columns contains name field, verify update is successful and data are updated correctly
929+ const importUpdateText = 'Name\tDescription\t' + fieldName + '\n' + newName3 + '\timportUpd1\timportVal1\n' + newName4 + '\timportUpd2\timportVal2' ;
930+ const updateResp = await ExperimentCRUDUtils . importData ( server , importUpdateText , dataType , 'UPDATE' , topFolderOptions , editorUserOptions ) ;
931+ expect ( updateResp . body . success ) . toBe ( true ) ;
932+
933+ rows = await ExperimentCRUDUtils . getRows ( server , [ row1RowId , row2RowId ] , 'exp.data' , dataType , '*' , topFolderOptions , adminOptions ) ;
934+ row1 = findRow ( rows , row1RowId ) ;
935+ row2 = findRow ( rows , row2RowId ) ;
936+ expect ( caseInsensitive ( row1 , 'description' ) ) . toBe ( 'importUpd1' ) ;
937+ expect ( caseInsensitive ( row1 , fieldName ) ) . toBe ( 'importVal1' ) ;
938+ expect ( caseInsensitive ( row2 , 'description' ) ) . toBe ( 'importUpd2' ) ;
939+ expect ( caseInsensitive ( row2 , fieldName ) ) . toBe ( 'importVal2' ) ;
940+
941+ // update description and fieldName value from Import with merge. at the same time create a new data. the import columns contain name field, verify update and insert is successful
942+ const newDataName = 'MergedNewData' ;
943+ const importMergeText = 'Name\tDescription\t' + fieldName + '\n' + newName3 + '\tmergeUpd1\tmergeVal1\n' + newName4 + '\tmergeUpd2\tmergeVal2\n' + newDataName + '\tmergeNew\tmergeNewVal' ;
944+ const mergeResp = await ExperimentCRUDUtils . importData ( server , importMergeText , dataType , 'MERGE' , topFolderOptions , editorUserOptions ) ;
945+ expect ( mergeResp . body . success ) . toBe ( true ) ;
946+
947+ rows = await ExperimentCRUDUtils . getRows ( server , [ row1RowId , row2RowId ] , 'exp.data' , dataType , '*' , topFolderOptions , adminOptions ) ;
948+ row1 = findRow ( rows , row1RowId ) ;
949+ row2 = findRow ( rows , row2RowId ) ;
950+ expect ( caseInsensitive ( row1 , 'description' ) ) . toBe ( 'mergeUpd1' ) ;
951+ expect ( caseInsensitive ( row1 , fieldName ) ) . toBe ( 'mergeVal1' ) ;
952+ expect ( caseInsensitive ( row2 , 'description' ) ) . toBe ( 'mergeUpd2' ) ;
953+ expect ( caseInsensitive ( row2 , fieldName ) ) . toBe ( 'mergeVal2' ) ;
954+
955+ // verify new data was created by merge
956+ const newDataRow = await getDataClassDataByName ( newDataName , dataType , '*' , topFolderOptions , adminOptions ) ;
957+ expect ( caseInsensitive ( newDataRow , 'Name' ) ) . toBe ( newDataName ) ;
958+ expect ( caseInsensitive ( newDataRow , 'description' ) ) . toBe ( 'mergeNew' ) ;
959+ expect ( caseInsensitive ( newDataRow , fieldName ) ) . toBe ( 'mergeNewVal' ) ;
960+ } ) ;
961+
962+ } ) ;
0 commit comments