33import com .fasterxml .jackson .core .JsonProcessingException ;
44import com .fasterxml .jackson .core .type .TypeReference ;
55import com .fasterxml .jackson .databind .ObjectMapper ;
6+
67import net .glenmazza .sfclient .TestApplication ;
78import net .glenmazza .sfclient .model .AccountCreateRecord ;
9+ import net .glenmazza .sfclient .model .AccountInsertCompositeRecord ;
810import net .glenmazza .sfclient .model .AccountMultipleEntityRecord ;
911import net .glenmazza .sfclient .model .AccountQueryRecord ;
12+ import net .glenmazza .sfclient .model .AccountUpdateCompositeRecord ;
1013import net .glenmazza .sfclient .model .AccountUpdateRecord ;
1114import net .glenmazza .sfclient .model .ApexAccountRecord ;
15+ import net .glenmazza .sfclient .model .CompositeEntityRecord ;
16+ import net .glenmazza .sfclient .model .CompositeEntityRecordRequest ;
17+ import net .glenmazza .sfclient .model .CompositeEntityRecordResponse ;
1218import net .glenmazza .sfclient .model .MultipleEntityRecord ;
1319import net .glenmazza .sfclient .model .MultipleEntityRecord201Response ;
1420import net .glenmazza .sfclient .model .MultipleEntityRecord400ResponseException ;
3036
3137import java .time .LocalDate ;
3238import java .time .temporal .ChronoUnit ;
39+ import java .util .ArrayList ;
3340import java .util .HashMap ;
3441import java .util .List ;
3542import java .util .Map ;
3643
3744import static org .junit .jupiter .api .Assertions .assertEquals ;
3845import static org .junit .jupiter .api .Assertions .assertTrue ;
3946
40-
4147/**
4248 * Test cases cover the three AbstractRESTService subclasses supporting Salesforce entity calls, Apex endpoints,
4349 * and SOQLQueries.
44- *
4550 * Will need to have your test Salesforce instance configured in application-test.properties~template. Also,
4651 * the Apex REST test requires a certain Apex endpoint to be installed see the header for that
4752 * test for more info.
@@ -61,6 +66,9 @@ public class RESTServicesTest {
6166 @ Autowired
6267 private SalesforceMultipleRecordInserter smri ;
6368
69+ @ Autowired
70+ private SalesforceCompositeRequestService scrs ;
71+
6472 @ Autowired
6573 private ApexRESTCaller arc ;
6674
@@ -78,7 +86,7 @@ public static void initialize() {
7886 void testSalesforceRecordManagerInsertsGetsAndSOQLQueries () throws JsonProcessingException {
7987 // insert first Account via Class & SOQL query
8088 AccountCreateRecord acr = new AccountCreateRecord ();
81- String account1Name = "Test Account " + LocalDate .now ();
89+ String account1Name = "ACR Test Account " + LocalDate .now ();
8290 acr .setName (account1Name );
8391 acr .setSite ("Philadelphia" );
8492 acr .setNumberOfEmployees (25 );
@@ -98,7 +106,7 @@ void testSalesforceRecordManagerInsertsGetsAndSOQLQueries() throws JsonProcessin
98106
99107 // create via Map
100108 Map <String , Object > accountViaMap = new HashMap <>();
101- String account2Name = "Test Account 2 " + LocalDate .now ();
109+ String account2Name = "ACR Test Account 2 " + LocalDate .now ();
102110 accountViaMap .put ("Name" , account2Name );
103111 accountViaMap .put ("Site" , "Baltimore" );
104112 accountViaMap .put ("NumberOfEmployees" , 30 );
@@ -188,8 +196,11 @@ void testSalesforceRecordManagerUpdates() throws JsonProcessingException {
188196 srm .deleteObject ("Account" , rcr1 .getId ());
189197 }
190198
199+
200+ // Note if this test fails, may be necessary to delete Test MER Account1 and 2 that it creates
201+ // from Salesforce CRM. This test requires that neither exist in SF prior to running.
191202 @ Test
192- void testMultipleEntityRecordInsertions () throws JsonProcessingException {
203+ void testMultipleEntityRecordInsertionsAndCompositeCalls () throws JsonProcessingException {
193204 AccountMultipleEntityRecord amer = new AccountMultipleEntityRecord ("111" );
194205 amer .setName ("Test MER Account1" );
195206 amer .setSite ("Raleigh" );
@@ -212,11 +223,77 @@ void testMultipleEntityRecordInsertions() throws JsonProcessingException {
212223 MultipleEntityRecord201Response response = smri .bulkInsert ("Account" , merr );
213224 assertEquals (2 , response .getResults ().size ());
214225
215- // method also deletes objects once done comparing
216- queryAndConfirmValues (response , amer );
217- queryAndConfirmValues (response , amer2 );
218-
219- // now test exception handling: will activate by having both accounts have the same reference ID.
226+ String acct1SfId = queryAndConfirmMultipleRecordValues (response , amer );
227+ String acct2SfId = queryAndConfirmMultipleRecordValues (response , amer2 );
228+
229+ // use the Composite objects to update the values
230+ AccountUpdateCompositeRecord aucr1 = new AccountUpdateCompositeRecord (acct1SfId );
231+ aucr1 .getBody ().setNumberOfEmployees (30 );
232+ aucr1 .getBody ().setSite ("Asheville" );
233+
234+ AccountUpdateCompositeRecord aucr2 = new AccountUpdateCompositeRecord (acct2SfId );
235+ aucr2 .getBody ().setNumberOfEmployees (40 );
236+ aucr2 .getBody ().setSite ("Greensboro" );
237+
238+ // ...and add a third company, note SF ID not known yet, so just choosing a unique ref ID
239+ AccountInsertCompositeRecord aicr = new AccountInsertCompositeRecord ("mythirdcompany" );
240+ aicr .getBody ().setName ("Test MER Account3" );
241+ aicr .getBody ().setSite ("Winston-Salem" );
242+ aicr .getBody ().setNumberOfEmployees (25 );
243+
244+ CompositeEntityRecordRequest cerReq = new CompositeEntityRecordRequest (false );
245+ List <? extends CompositeEntityRecord > compList = new ArrayList <>(List .of (aucr1 , aucr2 , aicr ));
246+ cerReq .setCompositeRequest (compList );
247+
248+ CompositeEntityRecordResponse cerr = scrs .bulkProcess (cerReq );
249+
250+ queryAndConfirmCompositeValues (acct1SfId , aucr1 );
251+ queryAndConfirmCompositeValues (acct2SfId , aucr2 );
252+
253+ // test that create worked fine
254+ String acct3SfId = (String ) cerr .getCompositeResponse ().get (2 ).getSuccessResultsMap ().get ("id" );
255+
256+ AccountCreateRecord acr = srm .getObject ("Account" ,
257+ acct3SfId , AccountCreateRecord .class );
258+
259+ List <CompositeEntityRecordResponse .Result > results = cerr .getCompositeResponse ();
260+ assertEquals (201 , results .get (2 ).getHttpStatusCode ());
261+ assertEquals ("mythirdcompany" , results .get (2 ).getReferenceId ());
262+ Map <String , Object > body = results .get (2 ).getSuccessResultsMap ();
263+ assertEquals (true , body .get ("success" ));
264+ assertEquals (aicr .getBody ().getName (), acr .getName ());
265+ assertEquals (aicr .getBody ().getSite (), acr .getSite ());
266+ assertEquals (aicr .getBody ().getNumberOfEmployees (), acr .getNumberOfEmployees ());
267+ srm .deleteObject ("Account" , acct3SfId );
268+
269+ // now test composite errors, will attempt to update Acct 1 even though it doesn't exist anymore
270+ srm .deleteObject ("Account" , acct1SfId );
271+ aucr2 .getBody ().setNumberOfEmployees (50 );
272+ aucr2 .getBody ().setSite ("Durham" );
273+
274+ cerr = scrs .bulkProcess (cerReq );
275+
276+ results = cerr .getCompositeResponse ();
277+ assertEquals (400 , results .get (0 ).getHttpStatusCode ());
278+ assertEquals (acct1SfId , results .get (0 ).getReferenceId ());
279+ List <Map <String , Object >> errors = results .get (0 ).getErrorResultsList ();
280+ assertEquals ("ENTITY_IS_DELETED" , errors .get (0 ).get ("errorCode" ));
281+ assertEquals ("entity is deleted" , errors .get (0 ).get ("message" ));
282+ assertEquals (0 , ((List <?>) errors .get (0 ).get ("fields" )).size ());
283+
284+ assertEquals (200 , results .get (1 ).getHttpStatusCode ());
285+ assertEquals (acct2SfId , results .get (1 ).getReferenceId ());
286+ body = results .get (1 ).getSuccessResultsMap ();
287+ assertEquals (acct2SfId , body .get ("id" ));
288+ assertEquals (true , body .get ("success" ));
289+ assertEquals (false , body .get ("created" ));
290+
291+ // check update occurred for success case
292+ queryAndConfirmCompositeValues (acct2SfId , aucr2 );
293+
294+ srm .deleteObject ("Account" , acct2SfId );
295+
296+ // now test Multiple Entry exception handling: will activate by having both accounts have the same reference ID.
220297 amer2 .setAttributes (new MultipleEntityRecord .Attributes ("Account" , "111" ));
221298
222299 /* Error response should be:
@@ -261,7 +338,7 @@ void testMultipleEntityRecordInsertions() throws JsonProcessingException {
261338 assertEquals ("Duplicate ReferenceId provided in the request." , message );
262339 }
263340
264- private void queryAndConfirmValues (MultipleEntityRecord201Response response , AccountMultipleEntityRecord amer )
341+ private String queryAndConfirmMultipleRecordValues (MultipleEntityRecord201Response response , AccountMultipleEntityRecord amer )
265342 throws JsonProcessingException {
266343 String accountSfId = response .getResults ().stream ()
267344 .filter (r -> amer .getAttributes ().getReferenceId ().equals (r .getReferenceId ()))
@@ -275,7 +352,16 @@ private void queryAndConfirmValues(MultipleEntityRecord201Response response, Acc
275352 assertEquals (acr .getRating ().name (), amer .getRating ().name ());
276353 assertEquals (acr .getLeadDate (), amer .getLeadDate ());
277354
278- srm .deleteObject ("Account" , accountSfId );
355+ return accountSfId ;
356+ }
357+
358+ private void queryAndConfirmCompositeValues (String accountSfId , AccountUpdateCompositeRecord aucr )
359+ throws JsonProcessingException {
360+
361+ // query and check values
362+ AccountCreateRecord acr = srm .getObject ("Account" , accountSfId , AccountCreateRecord .class );
363+ assertEquals (aucr .getBody ().getSite (), acr .getSite ());
364+ assertEquals (aucr .getBody ().getNumberOfEmployees (), acr .getNumberOfEmployees ());
279365 }
280366
281367 @ Test
0 commit comments