From be5cdd4cac41cb6418adc603fe658c77c96d781d Mon Sep 17 00:00:00 2001 From: Pat Patterson Date: Tue, 16 Apr 2013 22:20:50 -0700 Subject: [PATCH] Accept String or correctly typed arguments in create, update, upsert. Fixes #33 --- RemoteTKController.cls | 113 ++++++++++++++++++++----------------- TestRemoteTKController.cls | 63 +++++++++++++++------ 2 files changed, 106 insertions(+), 70 deletions(-) diff --git a/RemoteTKController.cls b/RemoteTKController.cls index c39cff5..859cd3a 100644 --- a/RemoteTKController.cls +++ b/RemoteTKController.cls @@ -37,6 +37,55 @@ public class RemoteTKController { return gen.getAsString(); } + private static String writeFields(String objtype, SObject obj, String fields) { + Map fieldMap = null; + try { + fieldMap = (Map)JSON.deserializeUntyped(fields); + } catch (JSONException je) { + return makeError(je.getMessage(), 'JSON_PARSER_ERROR'); + } + + Schema.SObjectType targetType = Schema.getGlobalDescribe().get(objtype); + + Map targetFields = targetType.getDescribe().fields.getMap(); + + try { + for (String key : fieldMap.keySet()) { + if (targetFields.get(key) == null) { + return '[{"message":"Field '+key+' does not exist on object type '+objtype+'","errorCode":"INVALID_FIELD"}]'; + } + + Object value = fieldMap.get(key); + Schema.DisplayType valueType = targetFields.get(key).getDescribe().getType(); + + if (value instanceof String && valueType != Schema.DisplayType.String) { + // Coerce an incoming String to the correct type + String svalue = (String)value; + + if (valueType == Schema.DisplayType.Date) { + obj.put(key, Date.valueOf(svalue)); + } else if (valueType == Schema.DisplayType.Percent || + valueType == Schema.DisplayType.Currency) { + obj.put(key, svalue == '' ? null : Decimal.valueOf(svalue)); + } else if (valueType == Schema.DisplayType.Double) { + obj.put(key, svalue == '' ? null : Double.valueOf(svalue)); + } else if (valueType == Schema.DisplayType.Integer) { + obj.put(key, Integer.valueOf(svalue)); + } else { + obj.put(key, svalue); + } + } else { + // Just try putting the incoming value on the object + obj.put(key, value); + } + } + } catch (SObjectException soe) { + return makeError(soe.getMessage(), 'INVALID_FIELD'); + } + + return null; + } + @remoteAction public static String describe(String objtype) { // Just enough to make the sample app work! @@ -82,39 +131,12 @@ public class RemoteTKController { } SObject obj = targetType.newSObject(); - - Map fieldMap = null; - try { - fieldMap = (Map)JSON.deserializeUntyped(fields); - } catch (JSONException je) { - return makeError(je.getMessage(), 'JSON_PARSER_ERROR'); - } - - Map targetFields = targetType.getDescribe().fields.getMap(); - - try { - for (String key : fieldMap.keySet()) { - if (targetFields.get(key) == null) { - return '[{"message":"Field '+key+' does not exist on object type '+objtype+'","errorCode":"INVALID_FIELD"}]'; - } - - if (targetFields.get(key).getDescribe().getType() == Schema.DisplayType.Date) { - obj.put(key, Date.valueOf((String)fieldMap.get(key))); - } else if (targetFields.get(key).getDescribe().getType() == Schema.DisplayType.Percent || - targetFields.get(key).getDescribe().getType() == Schema.DisplayType.Currency) { - obj.put(key, String.valueOf(fieldMap.get(key)) == '' ? null : Decimal.valueOf((String)fieldMap.get(key))); - } else if (targetFields.get(key).getDescribe().getType() == Schema.DisplayType.Double) { - obj.put(key, String.valueOf(fieldMap.get(key)) == '' ? null : Double.valueOf(fieldMap.get(key))); - } else if (targetFields.get(key).getDescribe().getType() == Schema.DisplayType.Integer) { - obj.put(key, Integer.valueOf(fieldMap.get(key))); - } else { - obj.put(key, fieldMap.get(key)); - } - } - } catch (SObjectException soe) { - return makeError(soe.getMessage(), 'INVALID_FIELD'); + + String error = writeFields(objType, obj, fields); + if (error != null) { + return error; } - + try { insert obj; } catch (DMLException dmle) { @@ -172,14 +194,9 @@ public class RemoteTKController { SObject obj = targetType.newSObject(); obj.put(externalIdField, externalId); - Map fieldMap = - (Map)JSON.deserializeUntyped(fields); - try { - for (String key : fieldMap.keySet()) { - obj.put(key, fieldMap.get(key)); - } - } catch (SObjectException soe) { - return makeError(soe.getMessage(), 'INVALID_FIELD'); + String error = writeFields(objType, obj, fields); + if (error != null) { + return error; } Schema.SObjectField sobjField = targetType.getDescribe().fields.getMap().get(externalIdField); @@ -198,21 +215,11 @@ public class RemoteTKController { SObject obj = targetType.newSObject(id); - Map fieldMap = null; - try { - fieldMap = (Map)JSON.deserializeUntyped(fields); - } catch (JSONException je) { - return makeError(je.getMessage(), 'JSON_PARSER_ERROR'); + String error = writeFields(objType, obj, fields); + if (error != null) { + return error; } - try { - for (String key : fieldMap.keySet()) { - obj.put(key, fieldMap.get(key)); - } - } catch (SObjectException soe) { - return makeError(soe.getMessage(), 'INVALID_FIELD'); - } - try { update obj; } catch (DMLException dmle) { diff --git a/TestRemoteTKController.cls b/TestRemoteTKController.cls index b8ee2cf..daade25 100644 --- a/TestRemoteTKController.cls +++ b/TestRemoteTKController.cls @@ -88,9 +88,14 @@ public class TestRemoteTKController{ 'Wrong account number in '+method+' result'); } - static private Id testCreate(String accName, String accNumber) { + static private Id testCreate(String accName, String accNumber, String fields) { // Assume we can create an account - String jsonResult = RemoteTKController.create('Account', '{"Name": "'+accName+'", "AccountNumber" : "'+accNumber+'"}'); + + // Try with data in correct types + String jsonResult = RemoteTKController.create('Account', + '{"Name": "'+accName+'", '+ + '"AccountNumber" : "'+accNumber+'",'+ + fields+'}'); System.assertNotEquals(null, jsonResult, 'RemoteTKController.create returned null'); @@ -203,22 +208,22 @@ public class TestRemoteTKController{ assertError(jsonResult, 'INVALID_SEARCH', 'RemoteTKController.search'); } - static private void testUpdate(String accName, String accNumber, Id id) { - String jsonResult = RemoteTKController.updat('Account', id, '{"Name":"'+accName+'1", "AccountNumber":"'+accNumber+'1"}'); + static private void testUpdate(String accName, String accNumber, Id id, String fields) { + String jsonResult = RemoteTKController.updat('Account', id, '{"Name":"'+accName+'", "AccountNumber":"'+accNumber+'"}'); System.assertEquals(null, jsonResult, 'Non-null result from RemoteTKController.updat'); Account account = [SELECT Id, Name, AccountNumber FROM Account WHERE Id = :id LIMIT 1]; System.assertNotEquals(null, account, 'Couldn\'t find account record after RemoteTKController.updat'); - System.assertEquals(accName+'1', account.Name, + System.assertEquals(accName, account.Name, 'Account name doesn\'t match after RemoteTKController.updat'); - System.assertEquals(accNumber+'1', account.AccountNumber, + System.assertEquals(accNumber, account.AccountNumber, 'Account number doesn\'t match after RemoteTKController.updat'); - jsonResult = RemoteTKController.updat('QXZXQZXZQXZQ', id, '{"Name":"'+accName+'1"}'); + jsonResult = RemoteTKController.updat('QXZXQZXZQXZQ', id, '{"Name":"'+accName+'"}'); assertError(jsonResult, 'NOT_FOUND', 'RemoteTKController.updat'); - jsonResult = RemoteTKController.updat('Account', id, '{"XQZXQZXQZXQZ" : "'+accName+'1"}'); + jsonResult = RemoteTKController.updat('Account', id, '{"XQZXQZXQZXQZ" : "'+accName+'"}'); assertError(jsonResult, 'INVALID_FIELD', 'RemoteTKController.updat'); jsonResult = RemoteTKController.updat('Account', id, '{"Name" "'+accName+'"}'); @@ -228,22 +233,27 @@ public class TestRemoteTKController{ assertError(jsonResult, 'STRING_TOO_LONG', 'RemoteTKController.updat'); } - static private void testUpsert(String accName, String accNumber, Id id) { - String jsonResult = RemoteTKController.upser('Account', 'Id', (String)id, '{"Name":"'+accName+'2", "AccountNumber":"'+accNumber+'2"}'); + static private void testUpsert(String accName, String accNumber, Id id, String fields) { + String jsonResult = RemoteTKController.upser('Account', + 'Id', + (String)id, + '{"Name":"'+accName+'", '+ + '"AccountNumber":"'+accNumber+'",'+ + fields+'}'); System.assertEquals(null, jsonResult, 'Non-null result from RemoteTKController.upser'); Account account = [SELECT Id, Name, AccountNumber FROM Account WHERE Id = :id LIMIT 1]; System.assertNotEquals(null, account, 'Couldn\'t find account record after RemoteTKController.upser'); - System.assertEquals(accName+'2', account.Name, + System.assertEquals(accName, account.Name, 'Account name doesn\'t match after RemoteTKController.upser'); - System.assertEquals(accNumber+'2', account.AccountNumber, + System.assertEquals(accNumber, account.AccountNumber, 'Account number doesn\'t match after RemoteTKController.upser'); - jsonResult = RemoteTKController.upser('QXZXQZXZQXZQ', 'Id', (String)id, '{"Name":"'+accName+'2"}'); + jsonResult = RemoteTKController.upser('QXZXQZXZQXZQ', 'Id', (String)id, '{"Name":"'+accName+'"}'); assertError(jsonResult, 'NOT_FOUND', 'RemoteTKController.upser'); - jsonResult = RemoteTKController.upser('Account', 'Id', (String)id, '{"XQZXQZXQZXQZ" : "'+accName+'2"}'); + jsonResult = RemoteTKController.upser('Account', 'Id', (String)id, '{"XQZXQZXQZXQZ" : "'+accName+'"}'); assertError(jsonResult, 'INVALID_FIELD', 'RemoteTKController.upser'); } @@ -266,12 +276,31 @@ public class TestRemoteTKController{ String accName = 'Test1'; String accNumber = '1234'; - Id id = testCreate(accName, accNumber); + // String field values + Id id = testCreate(accName, accNumber, '"AnnualRevenue" : "1000000",'+ + '"NumberOfEmployees" : "1000",'+ + '"Phone" : "(111) 222-3333"'); + testDelete(id); + + // Integer field values + id = testCreate(accName, accNumber, '"AnnualRevenue" : 1000000,'+ + '"NumberOfEmployees" : 1000,'+ + '"Phone" : "(111) 222-3333"'); testRetrieve(accName, accNumber, id); testQuery(accName, accNumber); testSearch(accName, accNumber, id); - testUpdate(accName, accNumber, id); - testUpsert(accName, accNumber, id); + testUpdate(accName+'1', accNumber+'1', id, '"AnnualRevenue" : "1100000",'+ + '"NumberOfEmployees" : "1100",'+ + '"Phone" : "(112) 222-3333"'); + testUpdate(accName+'2', accNumber+'2', id, '"AnnualRevenue" : "2000000",'+ + '"NumberOfEmployees" : "2000",'+ + '"Phone" : "(222) 222-3333"'); + testUpsert(accName+'3', accNumber+'3', id, '"AnnualRevenue" : 3000000,'+ + '"NumberOfEmployees" : 3000,'+ + '"Phone" : "(333) 222-3333"'); + testUpsert(accName+'4', accNumber+'4', id, '"AnnualRevenue" : 4000000,'+ + '"NumberOfEmployees" : 4000,'+ + '"Phone" : "(444) 222-3333"'); testDelete(id); } } \ No newline at end of file