Skip to content

Commit 5eed7d5

Browse files
committed
Integration tests for SaveRowsApiCommand
1 parent b59c356 commit 5eed7d5

1 file changed

Lines changed: 177 additions & 5 deletions

File tree

src/org/labkey/test/tests/JavaClientApiTest.java

Lines changed: 177 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,18 @@
3434
import org.labkey.remoteapi.query.DeleteRowsCommand;
3535
import org.labkey.remoteapi.query.Filter;
3636
import org.labkey.remoteapi.query.InsertRowsCommand;
37+
import org.labkey.remoteapi.query.SaveRowsApiResponse;
38+
import org.labkey.remoteapi.query.SaveRowsCommand;
3739
import org.labkey.remoteapi.query.SaveRowsResponse;
3840
import org.labkey.remoteapi.query.SelectRowsCommand;
3941
import org.labkey.remoteapi.query.SelectRowsResponse;
4042
import org.labkey.remoteapi.query.Sort;
4143
import org.labkey.remoteapi.query.TruncateTableCommand;
4244
import org.labkey.remoteapi.query.TruncateTableResponse;
4345
import org.labkey.remoteapi.query.UpdateRowsCommand;
46+
import org.labkey.remoteapi.query.SaveRowsApiCommand;
47+
import org.labkey.remoteapi.query.SaveRowsApiCommand.Command;
48+
import org.labkey.remoteapi.query.SaveRowsApiCommand.CommandType;
4449
import org.labkey.remoteapi.security.AddGroupMembersCommand;
4550
import org.labkey.remoteapi.security.CreateGroupCommand;
4651
import org.labkey.remoteapi.security.CreateGroupResponse;
@@ -84,16 +89,15 @@
8489
import static org.junit.Assert.fail;
8590

8691
/**
87-
* Test for the Java Client API library. This test is written in
88-
* Selenium because we don't yet have a way to create a list via
89-
* the API, so this test will set up a list and then use the Java
90-
* client API library to insert, read, update, and delete from that list
92+
* Tests for the Java Client API library.
9193
*/
9294
@Category({Daily.class})
9395
@BaseWebDriverTest.ClassTimeout(minutes = 4)
9496
public class JavaClientApiTest extends BaseWebDriverTest
9597
{
9698
public static final String PROJECT_NAME = JavaClientApiTest.class.getSimpleName() + " Project " + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
99+
private static final String SUB_FOLDER_NAME = "Folder " + TRICKY_CHARACTERS_FOR_PROJECT_NAMES;
100+
private static final String SUB_FOLDER_PATH = PROJECT_NAME + "/" + SUB_FOLDER_NAME;
97101
public static final String LIST_NAME = "People" + FieldDefinition.DOMAIN_TRICKY_CHARACTERS;
98102
public static final String LAST_NAME = "LastName" + FieldDefinition.TRICKY_CHARACTERS;
99103
public static final String USER_NAME = "user1@javaclientapi.test";
@@ -113,7 +117,8 @@ public static void doSetup() throws Exception
113117
@LogMethod
114118
private void setupProject() throws Exception
115119
{
116-
_containerHelper.createProject(getProjectName(), null);
120+
_containerHelper.createProject(getProjectName());
121+
_containerHelper.createSubfolder(getProjectName(), SUB_FOLDER_NAME);
117122

118123
clickProject(PROJECT_NAME);
119124
PortalHelper portalHelper = new PortalHelper(this);
@@ -602,6 +607,173 @@ public void testImpersonationConnection() throws Exception
602607
cn.stopImpersonating();
603608
}
604609

610+
@Test
611+
public void testSaveRowsApiCommand() throws Exception
612+
{
613+
// Arrange
614+
String schemaName = "lists";
615+
String playersListName = "Players " + FieldDefinition.DOMAIN_TRICKY_CHARACTERS;
616+
Connection conn = createDefaultConnection();
617+
618+
String teamsListName = "Teams " + FieldDefinition.DOMAIN_TRICKY_CHARACTERS;
619+
620+
// Create lists
621+
{
622+
CreateDomainCommand createdListCmd = new CreateDomainCommand("IntList", playersListName);
623+
createdListCmd.setOptions(Map.of("keyName", "JerseyNumber", "keyType", "Integer"));
624+
625+
Domain domain = createdListCmd.getDomainDesign();
626+
domain.setFields(List.of(
627+
new PropertyDescriptor("FirstName", "First Name", "string"),
628+
new PropertyDescriptor("LastName", "Last Name", "string"),
629+
new PropertyDescriptor("Team", null, "string")
630+
));
631+
632+
createdListCmd.execute(conn, PROJECT_NAME);
633+
634+
createdListCmd = new CreateDomainCommand("VarList", teamsListName);
635+
createdListCmd.setOptions(Map.of("keyName", "Team"));
636+
637+
domain = createdListCmd.getDomainDesign();
638+
domain.setFields(List.of(
639+
new PropertyDescriptor("City", null, "string"),
640+
new PropertyDescriptor("Team", "Team Name", "string")
641+
));
642+
643+
createdListCmd.execute(conn, SUB_FOLDER_PATH);
644+
}
645+
646+
// Add some initial data
647+
{
648+
InsertRowsCommand insertCmd = new InsertRowsCommand(schemaName, playersListName);
649+
insertCmd.addRow(Map.of("FirstName", "Alvin", "LastName", "David", "JerseyNumber", 21, "Team", "Seattle Mariners"));
650+
insertCmd.addRow(Map.of("FirstName", "Jay", "LastName", "Buhner", "JerseyNumber", 19, "Team", "New York Yankees"));
651+
insertCmd.addRow(Map.of("FirstName", "Ken", "LastName", "Phelps", "JerseyNumber", 44, "Team", "Seattle Mariners"));
652+
653+
insertCmd.execute(conn, PROJECT_NAME);
654+
655+
insertCmd = new InsertRowsCommand(schemaName, teamsListName);
656+
insertCmd.addRow(Map.of("City", "New York", "Team", "Yankees"));
657+
insertCmd.addRow(Map.of("City", "New York", "Team", "Giants"));
658+
insertCmd.addRow(Map.of("City", "Brooklyn", "Team", "Dodgers"));
659+
insertCmd.addRow(Map.of("City", "Montreal", "Team", "Expos"));
660+
insertCmd.addRow(Map.of("City", "Seattle", "Team", "Pilots"));
661+
662+
insertCmd.execute(conn, SUB_FOLDER_PATH);
663+
}
664+
665+
SaveRowsApiCommand saveCmd = new SaveRowsApiCommand();
666+
667+
// Draft Ken Griffey Jr.
668+
saveCmd.addCommand(new Command(CommandType.Insert, schemaName, playersListName, List.of(
669+
Map.of("FirstName", "Ken", "LastName", "Griffey Jr.", "JerseyNumber", 24, "Team", "Seattle Mariners")
670+
)));
671+
672+
// Trade for Jay Buhner
673+
List<Map<String, Object>> rows = List.of(
674+
Map.of("JerseyNumber", 19, "Team", "Seattle Mariners"),
675+
Map.of("JerseyNumber", 44, "Team", "New York Yankees")
676+
);
677+
Command command = new Command(CommandType.Update, schemaName, playersListName, rows)
678+
.setAuditBehavior(SaveRowsCommand.AuditBehavior.DETAILED)
679+
.setAuditUserComment("Traded Jay Buhner for Ken Phelps on July 21, 1988");
680+
saveCmd.addCommand(command);
681+
682+
// Alvin Davis retires
683+
saveCmd.addCommand(new Command(CommandType.Delete, schemaName, playersListName, List.of(Map.of("JerseyNumber", 21))));
684+
685+
// Teams move west
686+
rows = List.of(
687+
Map.of("Team", "Dodgers", "City", "Los Angeles"),
688+
Map.of("Team", "Giants", "City", "San Francisco")
689+
);
690+
command = new Command(CommandType.Update, schemaName, teamsListName, rows)
691+
.setContainerPath(SUB_FOLDER_PATH)
692+
.setSkipReselectRows(true);
693+
saveCmd.addCommand(command);
694+
695+
// Some teams are relegated to history
696+
rows = List.of(Map.of("Team", "Expos"), Map.of("Team", "Pilots"));
697+
command = new Command(CommandType.Delete, schemaName, teamsListName, rows)
698+
.setContainerPath(SUB_FOLDER_PATH)
699+
.setAuditBehavior(SaveRowsCommand.AuditBehavior.DETAILED)
700+
.setAuditUserComment("Expos and Pilots no longer play ball");
701+
saveCmd.addCommand(command);
702+
703+
// Act
704+
// Execute multiple query operations using a saveRows command
705+
SaveRowsApiResponse response = saveCmd.execute(conn, PROJECT_NAME);
706+
707+
// Assert
708+
assertEquals(200, response.getStatusCode());
709+
assertEquals(0, response.getErrorCount());
710+
assertEquals(5, response.getResults().size());
711+
712+
// Verify saveRows results per command
713+
{
714+
var result = response.getResults().get(0);
715+
assertEquals("insert", result.getCommand());
716+
assertEquals(1, result.getRowsAffected());
717+
assertEquals(0, result.getTransactionAuditId());
718+
719+
result = response.getResults().get(1);
720+
assertEquals("update", result.getCommand());
721+
assertEquals(2, result.getRowsAffected());
722+
assertTrue("Expected a transaction auditId to be provided", result.getTransactionAuditId() > 0);
723+
724+
result = response.getResults().get(2);
725+
assertEquals("delete", result.getCommand());
726+
assertEquals(1, result.getRowsAffected());
727+
assertEquals(0, result.getTransactionAuditId());
728+
729+
result = response.getResults().get(3);
730+
assertEquals("update", result.getCommand());
731+
assertEquals(2, result.getRowsAffected());
732+
assertEquals(0, result.getTransactionAuditId());
733+
734+
result = response.getResults().get(4);
735+
assertEquals("delete", result.getCommand());
736+
assertEquals(2, result.getRowsAffected());
737+
assertTrue("Expected a transaction auditId to be provided", result.getTransactionAuditId() > 0);
738+
}
739+
740+
// Verify players list after operations
741+
{
742+
var selectRowsCommand = new SelectRowsCommand(schemaName, playersListName);
743+
selectRowsCommand.addSort(new Sort("JerseyNumber", Sort.Direction.ASCENDING));
744+
745+
var resp = selectRowsCommand.execute(conn, PROJECT_NAME);
746+
assertEquals(3, resp.getRowCount());
747+
748+
var players = resp.getRows();
749+
assertEquals(19, players.get(0).get("jerseyNumber")); // verify case-insensitive
750+
assertEquals("Seattle Mariners", players.get(0).get("Team"));
751+
assertEquals(24, players.get(1).get("Jerseynumber")); // verify case-insensitive
752+
assertEquals("Seattle Mariners", players.get(1).get("Team"));
753+
assertEquals(44, players.get(2).get("JerseyNumber"));
754+
assertEquals("New York Yankees", players.get(2).get("Team"));
755+
}
756+
757+
// Verify teams list after operations
758+
{
759+
var selectRowsCommand = new SelectRowsCommand(schemaName, teamsListName);
760+
selectRowsCommand.addSort(new Sort("City", Sort.Direction.ASCENDING));
761+
762+
var resp = selectRowsCommand.execute(conn, SUB_FOLDER_PATH);
763+
assertEquals(3, resp.getRowCount());
764+
765+
var teams = resp.getRows();
766+
assertEquals("Los Angeles", teams.get(0).get("City"));
767+
assertEquals("Dodgers", teams.get(0).get("Team"));
768+
769+
assertEquals("New York", teams.get(1).get("City"));
770+
assertEquals("Yankees", teams.get(1).get("Team"));
771+
772+
assertEquals("San Francisco", teams.get(2).get("City"));
773+
assertEquals("Giants", teams.get(2).get("Team"));
774+
}
775+
}
776+
605777
@Override
606778
protected void doCleanup(boolean afterTest) throws TestTimeoutException
607779
{

0 commit comments

Comments
 (0)