1

I'm having a big problem doing this.

I need to test a class that has a Callout method inside of it and I'm not being able to do so.

This is the class to test:

    global class GetClient{

    @future(callout = true)
    global static void lookForClient(String clientId){
        String controllerName = 'clients';
        String Parameters = 'clientId='+clientId;
        String method = 'GET';
        HttpResponse response = DisputeFOX_Utils.getJSON(controllerName, Parameters, method, false);
        if (response.getStatusCode() == 200 & response.getbody() != null & response.getbody() != '{}') {

            Map<String, Object> result = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            List<Object> clients = (List<Object>) result.get('clients');
            Map<String, Object> clientAttributes = (Map<String, Object>) clients[0];
            Map<String, Object> clientCustomFieldAttributes = (Map<String, Object>) clientAttributes.get('clientCustomField');
            Map<String, Object> forms = (Map<String, Object>) clientCustomFieldAttributes.get('map');

            //TODO: GUARDAR EN LOG LOS DATOS DE LA OPERACION DE CONSULTA
            Long timeStamp = long.valueOf(string.valueOf(Datetime.Now().getTime()/1000));

            List<DisputeFox_Integration_JSON__c> listToadd = new List<DisputeFox_Integration_JSON__c>();

            for(String attributeName : clientAttributes.keySet()){
                if(attributeName == 'clientCustomField'){
                    for(String formName : forms.keySet()){
                        processSubform(forms, clientId, timeStamp, formName);
                    }
                }else{
                    DisputeFox_Integration_JSON__c oDisputeFox_Integration_JSON = DisputeFOX_Utils.processKey(clientAttributes, clientId, timeStamp, attributeName);
                    listToadd.add(oDisputeFox_Integration_JSON);
                }
            }

            insert listToadd;

            List<Contact> contacts = new List<Contact>();
            Id contactID = getContactID(timeStamp, clientId, contacts);
            system.debug('contactID -------------> ' + contactID);
            system.debug('contacts  -------------> ' + contacts);

            sObject contact;
            if(contactID != null){
                System.debug('contactID -------> ' + contactID);
                contact = getContactByID(contactID);
            } else{
                contact = new Contact();
                System.debug('No contact found');
            }
            if(contact!=null){
                List<DisputeFox_Integration_ObjectMapping__c> mapping_info_all = [Select Id, DisputeFOX_FieldName__c, Salesforce_FieldName__c, DisputeFOX_FieldType__c from DisputeFox_Integration_ObjectMapping__c where API_Name__c = 'client'];

                for (DisputeFox_Integration_ObjectMapping__c dfMapping : mapping_info_all){
                    if(clientAttributes.containsKey(dfMapping.DisputeFOX_FieldName__c)){
                        Object jsonKeyValue = clientAttributes.get(dfMapping.DisputeFOX_FieldName__c);
                        contact = (Contact) DisputeFOX_Utils.switchType(dfMapping, jsonKeyValue, contact);
                    } 
                }
                    if(contactID == null){
                        insert contact;
                        system.debug('Contacto Insertado -------> ' + contact);
                         system.debug('Contacto insertado IDDDD -------> ' + contact.id);
                    } else{
                            update contact;
                            system.debug('Contacto Updateado -------> ' + contact);
                            system.debug('Contacto updateado IDDDD -------> ' + contact.id);
                        } 
            }
            else{
                // Objeto contact null

            }
        } else{
            // Wrong call
                system.debug('Response Satus: ' + response.getStatusCode());
                system.debug('Bad callout, check the Dispute Fox ID');
            }
    }

    public static void processSubform(Map<String, Object> forms, String clientId, long timeStamp, String formName){        
       Map<String, Object> formNameKey = (Map<String, Object>) forms.get(formName);
       Map<String, Object> formNameKeyMap = (Map<String, Object>) formNameKey.get('map');
       List<DisputeFox_Integration_JSON__c> listJsonToInsert = new List<DisputeFox_Integration_JSON__c>();
                            for(String jsonKey : formNameKeyMap.keySet()){
                                DisputeFox_Integration_JSON__c oDisputeFox_Integration_JSON = new DisputeFox_Integration_JSON__c();
                                oDisputeFox_Integration_JSON.DisputeFOX_clientId__c = clientId;
                                oDisputeFox_Integration_JSON.Timespan__c = timeStamp;
                                oDisputeFox_Integration_JSON.JSON_Key__c = jsonKey;
                                oDisputeFox_Integration_JSON.JSON_Value__c = (String) formNameKeyMap.get(jsonKey);
                                listJsonToInsert.add(oDisputeFox_Integration_JSON);
                            }
                                if(listJsonToInsert.size() > 0)
                                insert listJsonToInsert;
    }

    public static Id getContactID(long timeStamp, String clientId, List<Contact> contacts){
        List<DisputeFox_Integration_JSON__c> jsonKeySsn = [SELECT JSON_Value__c, JSON_Key__c from DisputeFox_Integration_JSON__c where JSON_Key__c = 'client_ssn' and Timespan__c =:timeStamp and DisputeFOX_clientId__c =: clientId limit 1];
        List<DisputeFox_Integration_JSON__c> jsonKeyId = [SELECT JSON_Value__c, JSON_Key__c from DisputeFox_Integration_JSON__c where JSON_Key__c = 'client_u_id' and Timespan__c =:timeStamp and DisputeFOX_clientId__c =: clientId limit 1];
        List<DisputeFox_Integration_JSON__c> jsonKeyClientId = [SELECT JSON_Value__c, JSON_Key__c from DisputeFox_Integration_JSON__c where JSON_Key__c = 'Client Id' and Timespan__c =:timeStamp and DisputeFOX_clientId__c =: clientId limit 1];
        List<DisputeFox_Integration_JSON__c> jsonKeyCaseNum = [SELECT JSON_Value__c, JSON_Key__c from DisputeFox_Integration_JSON__c where JSON_Key__c = 'Case Number' and Timespan__c =:timeStamp and DisputeFOX_clientId__c =: clientId limit 1];

        if(jsonKeySsn.size() > 0 || jsonKeyId.size() > 0 || jsonKeyClientId.size() > 0 || jsonKeyCaseNum.size() > 0){

            if(jsonKeySsn.size() > 0){
                    String jsonSSN = (String) jsonKeySsn[0].JSON_Value__c;
                    contacts = [SELECT Id FROM Contact WHERE SSN__c =:jsonSSN limit 1];
            }
            else if(jsonKeyId.size() > 0){
                    String jsonId = (String) jsonKeyId[0].JSON_Value__c;
                    contacts = [SELECT Id FROM Contact WHERE disputeFOX_ID__c=:jsonId limit 1];
            }
            else if(jsonKeyClientId.size() > 0){
                    String jsonClientId = (String) jsonKeyClientId[0].JSON_Value__c;
                    contacts = [SELECT Id FROM Contact WHERE Client_Id__c=:jsonClientId limit 1];
            }
            else if(jsonKeyCaseNum.size() > 0){
            String jsonCaseNum = (String) jsonKeyCaseNum[0].JSON_Value__c;
                    contacts = [SELECT Id FROM Contact WHERE Case_Id__c =:jsonCaseNum limit 1];
            }

            if(contacts!= null && contacts.size() > 0)
                    return contacts[0].id;
            else    return null;

        }else return null;
    }

    public static Contact getContactByID(Id contactID){
        return [SELECT Id, 
                AC_Charge_Date__c, 
                AC_Charge_Date_Ext__c, 
                AC_Final_Date__c,
                AC_Price__c, 
                AC_Split_Date__c, 
                AC_Split_Date_Ext__c, 
                Accept_Email_Promo__c, 
                Account_Number__c, 
                Account_Number_1__c, 
                Account_Number_2__c,
                Account_Type_1__c,
                Account_Type_2__c,
                AccountId,
                ACH_Full_Name__c,
                ACH_Name__c,
                ACH_Name_2__c,
                ACH_Type__c,
                ACH_Type_2__c,
                Added_Accounts__c,
                Affiliated_Companies__c,
                Age__c,
                Agent_Email__c,
                Agent_Name__c,
                Appointment_Date__c,
                Appointment_Hour__c,
                Authorized_Last_4_SSN__c,
                Authorized_Name__c,
                Authorized_Person_Type__c,
                Bank_Name_1__c,
                Bank_Name_2__c,
                Billing_Status__c,
                Cancellation_Reason__c,
                Cancelled_by__c,
                Case_Client__c,
                Case_Id__c,
                Case_Status__c, 
                CC_Type__c,
                CC_Type_2__c,
                Client_Id__c,
                Client_Info__c,
                Client_Status__c,
                Closed_By__c,
                Communication_Consent__c,
                Communication_Method__c,
                Contact_Time__c,
                Contract_Sent__c,
                CreatedById,
                CreatedDate,
                CT_ACH__c,
                CT_ACH_AUTH_NAME__c,
                CT_ACH_AUTH_TYPE__c,
                CT_BANK_NAME__c,
                CT_CC__c,
                CT_CC_AUTH_NAME__c,
                CT_CC_AUTH_TYPE__c,
                CT_CC_MASTERCARD__c,
                CT_CC_TYPE__c,
                CT_CC_VISA__c,
                CT_CHECKING__c,
                CT_CONTRACT_AC__c,
                CT_CONTRACT_AC_DAY__c,
                CT_CONTRACT_AC_MONTH__c,
                CT_CONTRACT_AC_YEAR__c,
                CT_CONTRACT_DATE__c,
                CT_CONTRACT_DAY__c,
                CT_CONTRACT_DOB__c,
                CT_CONTRACT_EXP_MONTH__c,
                CT_CONTRACT_EXP_YEAR__c,
                CT_CONTRACT_LIC__c,
                CT_CONTRACT_LIC_X__c,
                CT_CONTRACT_MARITAL__c,
                CT_CONTRACT_MONTH__c,
                CT_CONTRACT_PASS__c,
                CT_CONTRACT_PASS_X__c,
                CT_CONTRACT_PAY_DAY__c,
                CT_CONTRACT_PHYSICAL__c,
                CT_CONTRACT_POSTAL__c,
                CT_CONTRACT_RC__c,
                CT_CONTRACT_RC_DAY__c,
                CT_CONTRACT_START_DATE__c,
                CT_CONTRACT_TERMS__c,
                CT_CONTRACT_TOTAL__c,
                CT_CONTRACT_YEAR__c,
                CT_Fix__c,
                CT_LAST_4_ACH__c,
                CT_LAST_4_CC__c,
                CT_MONTHLY__c,
                CT_MULT__c,
                CT_PAY_DATE__c,
                CT_PAY_METHOD__c,
                CT_PAYMENT_DAY__c,
                CT_PLAN__c,
                CT_RC_END_DATE__c,
                CT_RC_START_DATE__c,
                CT_SAVINGS__c,
                Customer_Class__c,
                Damaged_Credit_Reason__c,
                Date_of_Cancellation__c,
                Db_Id__c,
                Discount_Percent__c,
                Division__c,
                DNC__c,
                Do_Not_Contact__c,
                DOB__c,
                DoNotCall,
                Email,
                EmailBouncedReason,
                Exp_Month_1__c,
                Exp_Month_2__c,
                Exp_Year_1__c,
                Exp_Year_2__c,
                Fax,
                First_Monthly_Payment_Made__c,
                FirstName,
                Full_Name__c,
                Gender__c,
                ID_Exp_Date__c,
                ID_Number__c,
                ID_Type__c,
                Inactivation_Reason__c,
                inactive_date__c,
                Income_Range__c,
                Initial_Payment_Made__c,
                Last_4_ACH__c,
                Last_4_ACH_2__c,
                Last_4_CC__c,
                Last_4_CC_2__c,
                LastModifiedById,
                LastModifiedDate,
                LastName,
                Lead_Source__c,
                Lead_Sub_Source__c,
                License_Number_1__c,
                License_Number_2__c,
                License_State_1__c,
                License_State_2__c,
                Marital_Status__c,
                Middle_Initial__c,
                Monthly_Offer__c,
                Name,
                Next_Birthday__c,
                OB_Address_Line_1__c,
                OB_Address_Line_2__c,
                OB_City__c,
                OB_Email__c,
                OB_Family_Member_Type__c,
                OB_Full_Name__c,
                OB_Last_4_SSN__c,
                OB_Phone__c,
                OB_State__c,
                OB_Zip_Code__c,
                OB2_Address_Line_1__c,
                OB2_Address_Line_2__c,
                OB2_City__c,
                OB2_Email__c,
                OB2_Family_Member_Type__c,
                OB2_Full_Name__c,
                OB2_Last_4_SSN__c,
                OB2_Phone__c,
                OB2_State__c,
                OB2_Zip_Code__c,
                Occupation__c,
                Opened_By__c,
                Payment_Day__c,
                Payment_Type_1__c,
                Payment_Type_2__c,
                Payments_Billed__c,
                Phone,
                Physical_Address_Line_1__c,
                Physical_Address_Line_2__c,
                Physical_City__c,
                Physical_State__c,
                Physical_Zip_Code__c,
                Plan_Effective_Date__c,
                Plan_Expiration_Date__c,
                Plan_Months__c,
                PN_ONE__c,
                Postal_Address_Line_1__c,
                Postal_Address_Line_2__c,
                Postal_City__c,
                Postal_State__c,
                Postal_Zip_Code__c,
                Preferred_Mail_Type__c,
                Price_Fix__c,
                Primary_Phone_Type__c,
                Product_Name__c,
                RC_End_Date__c,
                RC_Original_Price__c,
                RC_Start_Date__c,
                RC_Start_Date_Ext__c,
                Reactivation_Date__c,
                Reactivation_Reason__c,
                Reason_for_Not_Buying__c,
                Reasons_to_Buy_Service__c,
                Receive_Birthday_Emails__c,
                Recurrent_Amount__c,
                Referred_By__c,
                Regular_Inquiries__c,
                Regular_Payments_Made__c,
                Regular_Payments_Missed__c,
                Reset_Birthday_Email_System__c,
                Retainer_Charge_Date__c,
                Retainer_Fee__c,
                Routing_Number__c,
                Routing_Number_1__c,
                Routing_Number_2__c,
                Sale_Date__c,
                Savera_Code__c,
                Savera_Product_Details__c,
                Savings__c,
                Second_Last_Name__c,
                Secondary_Phone__c,
                Secondary_Phone_Type__c,
                SSN__c,
                SSN_Last_4__c,
                Start_Plan__c,
                subscription__c,
                Tertiary_Phone__c,
                Tertiary_Phone_Type__c,
                Total_AC__c,
                Total_Cash_Received_LTD__c,
                Total_Offer__c 
                from Contact WHERE ID =: contactID];
    }
} // END DE LA CLASS

This is the test class I've written:

@isTest
private class GetClientTest {
     @isTest static void testCallout() {
        // Set mock callout class 
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());

        // Call method to test.
        // This causes a fake response to be sent
        // from the class that implements HttpCalloutMock. 
        HttpResponse res = DisputeFOX_Utils.getJSON('clients', 'clientId=8839e6ee-1f25-4e6a-8e04-f083841db9e6', 'GET', false);

        // Verify response received contains fake values
        String contentType = res.getHeader('Content-Type');
        System.assert(contentType == 'application/json');
        String actualValue = res.getBody();
        String expectedValue = '{"clients":}';
        System.assertEquals(actualValue, expectedValue);
        System.assertEquals(200, res.getStatusCode());
    }

    @isTest static void testLookForClient() {

        Test.startTest();
        testCallout();
        GetClient.lookForClient('8839e6ee-1f25-4e6a-8e04-f083841db9e6');
        Test.stopTest();

    }

and the method I'm running is the second one:

@isTest static void testLookForClient()

But when I run this I get a crazy JSON error

System.JSONException: Unexpected character ('"' (code 34)): was expecting comma to separate OBJECT entries at [line:1, column:857]

Any idea on how to do this ?

Update:

This is the JSON I'm using:

{
    "clients": [
        {
            "client_u_id": "cbfb020e-e50b-43ee-b912-c82d2f4dc45c",
            "company_id": xx,
            "client_first_name": "Demo",
            "client_middle_name": "W",
            "client_last_name": "xxxa",
            "client_dob": "06/05/1991",
            "client_ssn": "123456",
            "client_email": "xxxxx",
            "client_phone_2": "+xxxxxxx7",
            "client_fax": "",
            "client_current_street": "xxxxxt",
            "client_current_city": "xxxxxx",
            "client_current_state": "Victoria",
            "client_current_zip": "xxxx",
            "client_previous_street": "xxxxxue",
            "client_previous_city": "New York",
            "client_previous_state": "New York",
            "client_previous_zip": "1xxx",
            "client_status": 1,
            "client_modified_date": "xx 17:57:18",
            "client_create_date": "03/26/2020 18:51:02",
            "client_password": "xxxxxx",
            "customerUserName": "elbaxxxxr.com",
            "loginStatus": false,
            "client_enum_id": 2,
            "client_folder_secondary_status_id": 0,
            "client_processing_issue_id": -1,
            "client_assignedto_id": 70,
            "client_folder_statusid": 0,
            "lead_source": 0,
            "idiq_process_status": 0,
            "email_opt_out_in": 1,
            "sms_opt_out_in": 1,
            "currentDateTime": 0,
            "clientCustomField": {
                "map": {
                    "Status": {
                        "map": {}
                    },
                    "Aditional Personal Information": {
                        "map": {
                            "Postal City": "",
                            "Document ID Type": "",
                            "Client Id": "123254",
                            "Postal Zipcode": "",
                            "Income Range": "",
                            "Full Name": "",
                            "Document ID Expiration Date": "",
                            "Gender": "\"\"",
                            "Authorized Person Name": "",
                            "Marital Status": "",
                            "Ocupation Profile": "",
                            "Salesforce ID": "xxxxx363D",
                            "Name": "",
                            "Authorized Person SSN Last 4": "",
                            "Case Number": "LCS-JD-23455",
                            "Postal Address 1": "",
                            "Postal Country": "",
                            "Postal Address 2": "",
                            "Physical Address 1": "",
                            "Physical Address 2": "",
                            "Country": "",
                            "Second Last Name": "",
                            "Authorized Person Type": "",
                            "Postal State": ""
                        }
                    },
                    "Customer insertion form": {
                        "map": {
                            "CVV Code": "962",
                            "Credit Card Number": "xxx11111111111",
                            "Current Address": "889 xxx",
                            "Email": "exxxxom",
                            "State": "Victoria",
                            "Expiration Year": "2022",
                            "Expiration Month": "8",
                            "First Name": "Demo",
                            "ZIP CODE": "3xx8",
                            "What are your hobbies": "",
                            "City": "Docklands",
                            "Last Name": "Elba"
                        }
                    }
                }
            },
            "beforLeadChangeClient": 0,
            "affiliate_id": -1,
            "client_workflow_statusid": 0,
            "client_sales_representative_id": 0,
            "client_customer_statusid": 0,
            "Customer_FolderId": -1,
            "Customer_Secondary_FolderId": 0,
            "Customer_WorkflowId": 30,
            "customer_statusid": 0,
            "monitoring_agency": "1",
            "credit_monitoring_username": "",
            "credit_monitoring_password": "",
            "secret_key": "",
            "agreementId": 35,
            "isClientAgreementSigned": 1,
            "interestRetting": 0,
            "isPortalAccess": 1
        }
    ]
}
  • What is the actual JSON? Is it indeed valid per one of the many online formatters? I think the code or data that would be needed to resolve this question is not currently included. – David Reed May 21 at 18:36
  • Sorry, I edited the question and added the Json. – Ignacio de la Torre May 21 at 18:57
0

If you're using it exactly as written, your JSON isn't valid.

{
    "clients": [
        {
            "client_u_id": "cbfb020e-e50b-43ee-b912-c82d2f4dc45c",
            "company_id": xx,

xx isn't a valid value. In that value, the JSON parser expects:

'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['

If you create a valid payload, your error may resolve itself.

| improve this answer | |
  • No bro, I'm not using the EXACT JSON and the JSON is indeed VALID, thanks anyways – Ignacio de la Torre May 21 at 19:51
  • 1
    I'm not your bro and you can take your attitude and go pound sand. I wish you luck solving your issue. – Mark Pond May 21 at 19:54
  • What is wrong with you ?? I was being nice saying bro, but yeah, I guess you are not. – Ignacio de la Torre May 21 at 19:58
  • 1
    Okay, my apologies, let's start over. Your error message is a result of improperly structured JSON, the parser expected to find a comma delimiting an array of objects and instead found a quote character. I placed your example JSON in a validator and it is invalid as written. – Mark Pond May 21 at 20:03
  • No worries Mark, I apologies as well if I sounded rude or something, and thanks a lot for the help. I will check it out again and post here if it worked or not. Thanks a bunch for your time – Ignacio de la Torre May 22 at 12:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.