77import org .labkey .api .collections .CaseInsensitiveHashMap ;
88import org .labkey .remoteapi .CommandException ;
99import org .labkey .remoteapi .Connection ;
10+ import org .labkey .remoteapi .query .BaseRowsCommand ;
1011import org .labkey .remoteapi .query .ContainerFilter ;
1112import org .labkey .remoteapi .query .Filter ;
13+ import org .labkey .remoteapi .query .MoveRowsCommand ;
1214import org .labkey .remoteapi .query .SelectRowsCommand ;
1315import org .labkey .remoteapi .query .SelectRowsResponse ;
1416import org .labkey .remoteapi .query .TruncateTableCommand ;
@@ -279,6 +281,42 @@ public void testListInSubfolder() throws Exception
279281 moveRowsExpectingError (subfolderList , SUBFOLDER_A_PATH , SUBFOLDER_MINOR_A_PATH , subARows .getRows (), expectedError );
280282 }
281283
284+ @ Test
285+ public void testAuditDetailsNone () throws Exception
286+ {
287+ truncateList (STRING_KEY_LIST );
288+
289+ // Arrange
290+ int totalRows = 5 ;
291+ int numRowsWithAttachmentValue = 2 ;
292+ var response = addRows (STRING_KEY_LIST , SUBFOLDER_A_PATH , totalRows , numRowsWithAttachmentValue );
293+
294+ QueryApiHelper queryApiHelper = getQueryApiHelper (SUBFOLDER_A_PATH , STRING_KEY_LIST );
295+ MoveRowsCommand command = queryApiHelper .createMoveRowsCommand (response .getRows (), SUBFOLDER_B_PATH );
296+ command .setAuditBehavior (BaseRowsCommand .AuditBehavior .NONE );
297+
298+ // Act
299+ MoveRowsResponse moveRowsResponse = queryApiHelper .moveRows (command );
300+
301+ // Assert
302+ UpdateCounts updateCount = new UpdateCounts (numRowsWithAttachmentValue , 0 , totalRows , totalRows , totalRows - numRowsWithAttachmentValue );
303+ checker ().verifyNull ("Expected a null transaction audit Id" , moveRowsResponse .getTransactionAuditId ());
304+ verifyUpdateCounts (updateCount , moveRowsResponse .getUpdateCounts ());
305+ }
306+
307+ @ Test
308+ public void testInvalidArguments () throws Exception
309+ {
310+ truncateList (AUTO_INCREMENT_LIST );
311+ var response = addRows (AUTO_INCREMENT_LIST , getProjectName (), 1 , 0 );
312+ var validId = response .getRows ().get (0 ).get (autoIncrementKeyFieldName );
313+
314+ moveRowsExpectingError (AUTO_INCREMENT_LIST , getProjectName (), SUBFOLDER_B_PATH , List .of (), "No 'rows' array supplied." );
315+ moveRowsExpectingError (AUTO_INCREMENT_LIST , getProjectName (), SUBFOLDER_B_PATH , List .of (Map .of ("InvalidKey" , validId )), "Key field value required for moving list rows." );
316+ moveRowsExpectingError (AUTO_INCREMENT_LIST , getProjectName (), null , response .getRows (), "A target container must be specified for the move operation." );
317+ moveRowsExpectingError (AUTO_INCREMENT_LIST , getProjectName (), "/Shared" , response .getRows (), "Invalid target container for the move operation: /Shared." );
318+ }
319+
282320 private void successfullyMoveRows (ListDefinition list , List <Map <String , Object >> rows ) throws Exception
283321 {
284322 var rowsSize = rows .size ();
@@ -306,12 +344,6 @@ private void successfullyMoveRows(ListDefinition list, List<Map<String, Object>>
306344 if (checker ().errorsSinceMark () > 0 )
307345 return ;
308346
309- // Attempt to move some rows from the project to a different subfolder even though they have already been moved
310- moveResponse = moveRows (list , getProjectName (), SUBFOLDER_B_PATH , firstRows );
311- verifySuccessfulMove (list , moveResponse , getProjectName (), SUBFOLDER_B_PATH , NO_UPDATE );
312- if (checker ().errorsSinceMark () > 0 )
313- return ;
314-
315347 // Now move them between subfolders
316348 moveResponse = moveRows (list , SUBFOLDER_A_PATH , SUBFOLDER_B_PATH , firstRows );
317349 expectedCounts = new UpdateCounts (firstRowAttachmentSize , firstRowsSize + 2 , firstRowsSize + firstRowsSize , firstRowsSize , firstRowsSize - firstRowAttachmentSize );
@@ -330,6 +362,13 @@ private void successfullyMoveRows(ListDefinition list, List<Map<String, Object>>
330362 moveResponse = moveRows (list , SUBFOLDER_B_PATH , SUBFOLDER_MINOR_A_PATH , secondRows );
331363 expectedCounts = new UpdateCounts (secondRowAttachmentSize , secondRowsSize + 2 , secondRowsSize * 3 , secondRowsSize , secondRowsSize - secondRowAttachmentSize );
332364 verifySuccessfulMove (list , moveResponse , SUBFOLDER_B_PATH , SUBFOLDER_MINOR_A_PATH , expectedCounts );
365+ if (checker ().errorsSinceMark () > 0 )
366+ return ;
367+
368+ // Now move all rows back to the project
369+ moveResponse = moveRows (list , PROJECT_PATH , PROJECT_PATH , rows );
370+ expectedCounts = new UpdateCounts (rowAttachmentSize , rowsSize + 4 , (rowsSize * 3 ) + secondRowsSize , rowsSize , rowsSize - rowAttachmentSize );
371+ verifySuccessfulMove (list , moveResponse , Map .of (SUBFOLDER_B_PATH , secondRowsSize , SUBFOLDER_MINOR_A_PATH , secondRowsSize ), PROJECT_PATH , expectedCounts );
333372 }
334373
335374 private int attachmentCount (List <Map <String , Object >> rows )
@@ -345,7 +384,17 @@ private void verifySuccessfulMove(
345384 UpdateCounts expectedCounts
346385 ) throws IOException , CommandException
347386 {
348- final String sourcePath = sourceContainerPath .startsWith ("/" ) ? sourceContainerPath : "/" + sourceContainerPath ;
387+ verifySuccessfulMove (list , response , Map .of (sourceContainerPath , expectedCounts .listRecords ), targetContainerPath , expectedCounts );
388+ }
389+
390+ private void verifySuccessfulMove (
391+ ListDefinition list ,
392+ MoveRowsResponse response ,
393+ Map <String , Integer > sourceContainerPathCounts ,
394+ String targetContainerPath ,
395+ UpdateCounts expectedCounts
396+ ) throws IOException , CommandException
397+ {
349398 final String targetPath = targetContainerPath .startsWith ("/" ) ? targetContainerPath : "/" + targetContainerPath ;
350399
351400 // Verify response
@@ -354,32 +403,36 @@ private void verifySuccessfulMove(
354403 checker ().verifyEquals ("Unexpected container path" , targetPath , response .getContainerPath ());
355404
356405 // Verify update counts
357- checker ().wrapAssertion (() -> Assertions .assertThat (response .getUpdateCounts ().keySet ())
358- .as ("Expect list moveRows response to contain specific update counts" )
359- .containsExactlyInAnyOrder ("fileAttachmentsMoved" , "listAuditEventsCreated" , "listAuditEventsMoved" , "listRecords" , "queryAuditEventsMoved" ));
360- checker ().verifyEquals ("Unexpected number of file attachments moved" , expectedCounts .fileAttachmentsMoved , response .getUpdateCounts ().get ("fileAttachmentsMoved" ));
361- checker ().verifyEquals ("Unexpected number of list audit events created" , expectedCounts .listAuditEventsCreated , response .getUpdateCounts ().get ("listAuditEventsCreated" ));
362- checker ().verifyEquals ("Unexpected number of list audit events moved" , expectedCounts .listAuditEventsMoved , response .getUpdateCounts ().get ("listAuditEventsMoved" ));
363- checker ().verifyEquals ("Unexpected number of list records moved" , expectedCounts .listRecords , response .getUpdateCounts ().get ("listRecords" ));
364- checker ().verifyEquals ("Unexpected number of query audit events moved" , expectedCounts .queryAuditEventsMoved , response .getUpdateCounts ().get ("queryAuditEventsMoved" ));
406+ verifyUpdateCounts (expectedCounts , response .getUpdateCounts ());
365407
366408 // Verify audit logs
367409 var decimalFormat = new DecimalFormat ("#,##0" );
368410 var hasUpdates = expectedCounts != NO_UPDATE ;
369411 var listAuditEvents = _auditLogHelper .getAuditLogsForTransactionId (getProjectName (), LIST_AUDIT_EVENT , List .of ("Comment" , "Container/Path" , "ListId" ), response .getTransactionAuditId (), ContainerFilter .CurrentAndSubfolders );
370412 checker ().verifyEquals ("Unexpected number of list audit events" , expectedCounts .listAuditEventsCreated , listAuditEvents .size ());
371- checker ().wrapAssertion (() -> {
372- var matches = auditEventMatches (listAuditEvents , targetPath , list .getListId (), String .format ("Moved %s rows from %s" , decimalFormat .format (expectedCounts .listRecords ), sourcePath ));
373- Assertions .assertThat (matches )
374- .as ("Expected one event recording move in target container" )
375- .hasSize (hasUpdates ? 1 : 0 );
376- });
377- checker ().wrapAssertion (() -> {
378- var matches = auditEventMatches (listAuditEvents , sourcePath , list .getListId (), String .format ("Moved %s rows to %s" , decimalFormat .format (expectedCounts .listRecords ), targetPath ));
379- Assertions .assertThat (matches )
380- .as ("Expected one event recording move in source container" )
381- .hasSize (hasUpdates ? 1 : 0 );
382- });
413+
414+ for (var entry : sourceContainerPathCounts .entrySet ())
415+ {
416+ String sourcePath = entry .getKey ().startsWith ("/" ) ? entry .getKey () : "/" + entry .getKey ();
417+ Integer expectedListRecordCount = entry .getValue ();
418+
419+ checker ().wrapAssertion (() -> {
420+ var comment = String .format ("Moved %s rows from %s" , decimalFormat .format (expectedListRecordCount ), sourcePath );
421+ var matches = auditEventMatches (listAuditEvents , targetPath , list .getListId (), comment );
422+ Assertions .assertThat (matches )
423+ .as (String .format ("Expected audit summary event in target container \" %s\" " , comment ))
424+ .hasSize (hasUpdates ? 1 : 0 );
425+ });
426+
427+ checker ().wrapAssertion (() -> {
428+ var comment = String .format ("Moved %s rows to %s" , decimalFormat .format (expectedListRecordCount ), targetPath );
429+ var matches = auditEventMatches (listAuditEvents , sourcePath , list .getListId (), comment );
430+ Assertions .assertThat (matches )
431+ .as (String .format ("Expected audit summary event in source container \" %s\" " , comment ))
432+ .hasSize (hasUpdates ? 1 : 0 );
433+ });
434+ }
435+
383436 checker ().wrapAssertion (() -> {
384437 var matches = auditEventMatches (listAuditEvents , targetPath , list .getListId (), "An existing list record was moved" );
385438 Assertions .assertThat (matches )
@@ -388,6 +441,18 @@ private void verifySuccessfulMove(
388441 });
389442 }
390443
444+ private void verifyUpdateCounts (UpdateCounts expectedCounts , Map <String , Object > responseCounts )
445+ {
446+ checker ().wrapAssertion (() -> Assertions .assertThat (responseCounts .keySet ())
447+ .as ("Expect list moveRows response to contain specific update counts" )
448+ .containsExactlyInAnyOrder ("fileAttachmentsMoved" , "listAuditEventsCreated" , "listAuditEventsMoved" , "listRecords" , "queryAuditEventsMoved" ));
449+ checker ().verifyEquals ("Unexpected number of file attachments moved" , expectedCounts .fileAttachmentsMoved , responseCounts .get ("fileAttachmentsMoved" ));
450+ checker ().verifyEquals ("Unexpected number of list audit events created" , expectedCounts .listAuditEventsCreated , responseCounts .get ("listAuditEventsCreated" ));
451+ checker ().verifyEquals ("Unexpected number of list audit events moved" , expectedCounts .listAuditEventsMoved , responseCounts .get ("listAuditEventsMoved" ));
452+ checker ().verifyEquals ("Unexpected number of list records moved" , expectedCounts .listRecords , responseCounts .get ("listRecords" ));
453+ checker ().verifyEquals ("Unexpected number of query audit events moved" , expectedCounts .queryAuditEventsMoved , responseCounts .get ("queryAuditEventsMoved" ));
454+ }
455+
391456 private List <Map <String , Object >> auditEventMatches (List <Map <String , Object >> events , String containerPath , Integer listId , String comment )
392457 {
393458 return events .stream ()
@@ -398,14 +463,14 @@ private List<Map<String, Object>> auditEventMatches(List<Map<String, Object>> ev
398463 .toList ();
399464 }
400465
401- private QueryApiHelper getQueryApiHelper (String containerPath , String listName )
466+ private QueryApiHelper getQueryApiHelper (String containerPath , ListDefinition list )
402467 {
403- return new QueryApiHelper (createDefaultConnection (), containerPath , LIST_SCHEMA , listName );
468+ return new QueryApiHelper (createDefaultConnection (), containerPath , LIST_SCHEMA , list . getName () );
404469 }
405470
406471 private MoveRowsResponse moveRows (ListDefinition list , String sourceContainerPath , String targetContainerPath , List <Map <String , Object >> rows ) throws Exception
407472 {
408- return getQueryApiHelper (sourceContainerPath , list . getName () )
473+ return getQueryApiHelper (sourceContainerPath , list )
409474 .moveRows (rows , targetContainerPath );
410475 }
411476
@@ -455,7 +520,7 @@ private SelectRowsResponse addRows(ListDefinition list, String containerPath, in
455520 _listHelper .insertNewRow (newRow , false );
456521 }
457522
458- return getQueryApiHelper (containerPath , list . getName () )
523+ return getQueryApiHelper (containerPath , list )
459524 .selectRows ();
460525 }
461526
0 commit comments