SyncMadeEasy/force-app/main/default/classes/UtilityProTest.cls

1259 lines
58 KiB
OpenEdge ABL
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@isTest
global class UtilityProTest {
@testSetup
static void setup() {
HIC_ShopifySync__Object_Mapping__c objectMapping = new HIC_ShopifySync__Object_Mapping__c(
Name = 'TestObject',
HIC_ShopifySync__Resource__c = 'orders',
HIC_ShopifySync__Json_Nested__c = 'test.nested',
HIC_ShopifySync__Default__c = true,
HIC_ShopifySync__Store__c = 'Default',
HIC_ShopifySync__Preference__c = 1,
HIC_ShopifySync__sObject_Name__c = 'Account'
);
insert objectMapping;
Account testAccount = new Account(Name = 'TestValue');
insert testAccount;
// Create related data mappings
HIC_ShopifySync__Data_Mapping__c datamapping = new HIC_ShopifySync__Data_Mapping__c(
HIC_ShopifySync__Object_Mapping__c = objectMapping.Id,
HIC_ShopifySync__Key__c = 'testKey',
HIC_ShopifySync__Value_Of__c = 'TestValue',
HIC_ShopifySync__Default__c = true
);
insert datamapping;
// Create test Field Mapping records
HIC_ShopifySync__HIC_Field_Mapping__c fieldMapping1 = new HIC_ShopifySync__HIC_Field_Mapping__c(
HIC_ShopifySync__SF_Field__c = 'Name',
HIC_ShopifySync__Object_Mapping__c = objectMapping.Id,
HIC_ShopifySync__Shopify_Fields__c = 'name',
HIC_ShopifySync__Nested__c = 'nested.value',
HIC_ShopifySync__IsSFID__c = false,
HIC_ShopifySync__Default_Value__c = false
);
insert fieldMapping1;
HIC_ShopifySync__HIC_Field_Mapping__c fieldMapping2 = new HIC_ShopifySync__HIC_Field_Mapping__c(
HIC_ShopifySync__SF_Field__c = 'Industry',
HIC_ShopifySync__Object_Mapping__c = objectMapping.Id,
HIC_ShopifySync__Shopify_Fields__c = 'industry',
HIC_ShopifySync__Nested__c = null,
HIC_ShopifySync__IsSFID__c = true,
HIC_ShopifySync__Default_Value__c = false
);
insert fieldMapping2;
List<HIC_ShopifySync__HIC_Configuration__c> configList = new List<HIC_ShopifySync__HIC_Configuration__c>();
configList.add(new HIC_ShopifySync__HIC_Configuration__c(
Name = 'Default',
HIC_ShopifySync__API_Key__c = 'TestAPIKey',
HIC_ShopifySync__Private_Key_Password__c = 'TestPassword',
HIC_ShopifySync__Shopify_URL__c = 'https://testshop.myshopify.com',
HIC_ShopifySync__Chunk_Size__c = '50'
));
insert configList;
}
@isTest
static void testAddWebhookMapping_InsertNewMapping() {
// Arrange
String name = 'TestMapping';
String upsertURL = 'https://example.com/upsert';
String deleteURL = 'https://example.com/delete';
Boolean activated = true;
// Act
Test.startTest();
UtilityPro.addWebhookMapping(name, upsertURL, deleteURL, activated);
Test.stopTest();
// Assert
List<HIC_ShopifySync__WebhookURlMapping__c> result = [
SELECT Name, HIC_ShopifySync__UpsertURL__c, HIC_ShopifySync__DeleteURL__c, HIC_ShopifySync__Activated__c
FROM HIC_ShopifySync__WebhookURlMapping__c
WHERE Name = :name
];
}
@isTest
static void testAddWebhookMapping_UpdateExistingMapping() {
// Arrange
String name = 'TestMapping';
String upsertURL = 'https://example.com/upsert';
String deleteURL = 'https://example.com/delete';
Boolean activated = true;
// Insert an existing mapping
HIC_ShopifySync__WebhookURlMapping__c existingMapping = new HIC_ShopifySync__WebhookURlMapping__c(
Name = name,
HIC_ShopifySync__UpsertURL__c = 'https://old-url.com/upsert',
HIC_ShopifySync__DeleteURL__c = 'https://old-url.com/delete',
HIC_ShopifySync__Activated__c = false
);
insert existingMapping;
// Act
Test.startTest();
UtilityPro.addWebhookMapping(name, upsertURL, deleteURL, activated);
Test.stopTest();
// Assert
List<HIC_ShopifySync__WebhookURlMapping__c> result = [
SELECT Name, HIC_ShopifySync__UpsertURL__c, HIC_ShopifySync__DeleteURL__c, HIC_ShopifySync__Activated__c
FROM HIC_ShopifySync__WebhookURlMapping__c
WHERE Name = :name
];
}
@isTest
static void testAddWebhookMapping_ExceptionHandling() {
// Arrange
String name = 'ExceptionTestMapping';
String upsertURL = 'https://example.com/upsert';
String deleteURL = 'https://example.com/delete';
Boolean activated = true;
// Create a mock that throws an exception on DML
HIC_ShopifySync__WebhookURlMapping__c newMapping = new HIC_ShopifySync__WebhookURlMapping__c(
Name = name,
HIC_ShopifySync__UpsertURL__c = upsertURL,
HIC_ShopifySync__DeleteURL__c = deleteURL,
HIC_ShopifySync__Activated__c = activated
);
}
@IsTest
static void testPostAPIWebService() {
// Mock request body
String requestBody = '{"test": {"nested": [{"testKey": "TestValue"}]}}';
// Set up RestContext for testing
RestRequest req = new RestRequest();
req.requestURI = '/services/apexrest/APIWebservice';
req.httpMethod = 'POST';
req.requestBody = Blob.valueOf(requestBody);
req.addParameter('store', 'TestStore');
req.addParameter('objectname', 'TestObject');
RestContext.request = req;
RestResponse res = new RestResponse();
RestContext.response = res;
// Call the web service method
Test.startTest();
APIWebservice.postAPIWebService();
Test.stopTest();
// Verify logs or database changes
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Name = 'TestValue'];
System.assertEquals(1, accounts.size(), 'One account record should have been created.');
System.assertEquals('TestValue', accounts[0].Name, 'Account name should match the value mapped from Shopify.');
}
@IsTest
static void testPostAPIWebServiceMissingStore() {
// Mock request body
String requestBody = '{"test": {"nested": [{"testKey": "TestValue"}]}}';
// Set up RestContext for testing
RestRequest req = new RestRequest();
req.requestURI = '/services/apexrest/APIWebservice';
req.httpMethod = 'POST';
req.requestBody = Blob.valueOf(requestBody);
req.addParameter('objectname', 'TestObject'); // Store is not provided
RestContext.request = req;
RestResponse res = new RestResponse();
RestContext.response = res;
// Call the web service method
Test.startTest();
APIWebservice.postAPIWebService();
Test.stopTest();
// Verify default store handling
List<Account> accounts = [SELECT Id, Name FROM Account WHERE Name = 'TestValue'];
System.assertEquals(1, accounts.size(), 'One account record should have been created.');
System.assertEquals('TestValue', accounts[0].Name, 'Account name should match the value mapped from Shopify.');
}
@IsTest
static void testPostAPIWebServiceInvalidData() {
// Mock invalid request body
String requestBody = '{"invalid": "data"}';
// Set up RestContext for testing
RestRequest req = new RestRequest();
req.requestURI = '/services/apexrest/APIWebservice';
req.httpMethod = 'POST';
req.requestBody = Blob.valueOf(requestBody);
req.addParameter('store', 'TestStore');
req.addParameter('objectname', 'TestObject');
RestContext.request = req;
RestResponse res = new RestResponse();
RestContext.response = res;
// Call the web service method
Test.startTest();
APIWebservice.postAPIWebService();
Test.stopTest();
// Verify no records created
List<Account> accounts = [SELECT Id FROM Account];
System.assertEquals(1, accounts.size(), 'No account records should have been created for invalid data.');
}
@IsTest
static void testGenerateFieldMappingQuery() {
// Retrieve a valid Object Mapping ID
HIC_ShopifySync__Object_Mapping__c objectMapping = [
SELECT Id
FROM HIC_ShopifySync__Object_Mapping__c
LIMIT 1
];
// Call the method
Test.startTest();
String query = GenericAPIWebUtility.generateFieldMappingQuery(objectMapping.Id);
Test.stopTest();
// Assert query correctness
System.assertNotEquals(null, query, 'Query should not be null.');
System.assert(query.contains('SELECT'), 'Query should contain SELECT clause.');
System.assert(query.contains('FROM HIC_ShopifySync__HIC_Field_Mapping__c'), 'Query should contain FROM clause.');
System.assert(query.contains('WHERE'), 'Query should contain WHERE clause.');
System.assert(query.contains(objectMapping.Id), 'Query should include the correct Object Mapping ID.');
System.assert(query.contains('LIMIT 49999'), 'Query should limit results to 49999.');
}
@IsTest
static void testGenerateFieldMappingQueryInvalidId() {
// Test with an invalid Object Mapping ID
String invalidId = 'InvalidId';
Test.startTest();
String query = GenericAPIWebUtility.generateFieldMappingQuery(invalidId);
Test.stopTest();
// Assert result
System.assertNotEquals(null, query, 'Query should still be generated.');
System.assert(query.contains(invalidId), 'Query should include the invalid Object Mapping ID.');
}
@IsTest
static void testProcessFieldTypeAndMapping() {
// Create test data for field mappings
List<HIC_ShopifySync__HIC_Field_Mapping__c> fieldMappings = new List<HIC_ShopifySync__HIC_Field_Mapping__c>{
new HIC_ShopifySync__HIC_Field_Mapping__c(
HIC_ShopifySync__SF_Field__c = 'Description',
HIC_ShopifySync__Shopify_Fields__c = 'nested.value',
HIC_ShopifySync__Nested__c = 'nested',
HIC_ShopifySync__IsSFID__c = false,
HIC_ShopifySync__Default_Value__c = false
)
};
// Create a mock object map (ensure it's a Map<String, Object>)
Map<String, Object> objectMap = new Map<String, Object>{
'name' => 'Test Name',
'industry' => 'Technology',
'nested' => new Map<String, Object>{
'value' => 'Nested Value'
}
};
// Check if the 'nested' key exists and if its value is not null
if (objectMap.containsKey('nested') && objectMap.get('nested') != null && objectMap.get('nested') instanceof Map<String, Object>) {
// Safely cast to Map<String, Object> if it's a valid map
Map<String, Object> nestedObject = (Map<String, Object>) objectMap.get('nested');
System.debug('Nested Object: ' + nestedObject);
} else {
System.debug('The "nested" key is either missing or its value is null.');
}
// Define test parameters
String objectName = 'Account';
String companyTimeZone = 'GMT';
String store = 'Test Store';
// Call the method with a null check for nested fields
Test.startTest();
SObject sObjRecord = GenericAPIWebUtility.processFieldTypeAndMapping(
fieldMappings, objectName, objectMap, companyTimeZone, store
);
Test.stopTest();
}
@isTest
static void testProcessDataMapping() {
// Test case with non-null bodyMap and nested value
Map<String, Object> bodyMap1 = new Map<String, Object> {
'nested' => new List<Map<String, Object>>{
new Map<String, Object>{'key' => 'value1'},
new Map<String, Object>{'key' => 'value2'}
}
};
List<HIC_ShopifySync__Data_Mapping__c> dataMappings = [
SELECT Key__c, HIC_ShopifySync__Value_Of__c, Default__c
FROM HIC_ShopifySync__Data_Mapping__c
WHERE Key__c = 'name'
];
Test.startTest();
List<Object> result1 = GenericAPIWebUtility.processDataMapping('nested', dataMappings, bodyMap1);
Test.stopTest();
System.assertNotEquals(null, result1, 'Result should not be null');
System.assertEquals(2, result1.size(), 'Result list size should be 2');
// Additional assertions can be added as needed
}
@isTest
static void testProcessFieldMapping() {
// 1. Create test data (Account, Opportunity, and Field Mapping Object)
Account testAccount = new Account(Name = 'Test Account');
insert testAccount;
Opportunity testOpp = new Opportunity(
Name = 'Test Opportunity',
StageName = 'Prospecting',
CloseDate = Date.today(),
AccountId = testAccount.Id
);
insert testOpp;
// Create the HIC_ShopifySync__HIC_Field_Mapping__c record (field mapping object)
HIC_ShopifySync__HIC_Field_Mapping__c fieldMappingObj = new HIC_ShopifySync__HIC_Field_Mapping__c(
HIC_ShopifySync__SF_Field__c = 'AccountId', // Make sure this field exists in your org
HIC_ShopifySync__Shopify_Fields__c = testAccount.Id
);
insert fieldMappingObj;
// 2. Get the DescribeFieldResult for the 'AccountId' field of Opportunity
Schema.DescribeFieldResult fieldResult = Opportunity.AccountId.getDescribe();
// 3. Call the processFieldMapping method
SObject resultRecord = GenericAPIWebUtility.processFieldMapping(testOpp, fieldResult, 'Test Shopify Value', 'reference', fieldMappingObj);
// 4. Assertions to verify the field mapping logic worked as expected
// Assert that the relationship field (AccountId) is set correctly
Id resultAccount = (Id) resultRecord.get('AccountId'); // Assuming 'AccountId' is a field on the result record
// Account resultAccount = (Account) resultRecord.get('AccountId');
System.assertNotEquals(null, resultAccount, 'Account reference should be set');
// Assert that the custom field 'Test_Field__c' is populated with the mapped value
String mappedFieldValue = (String) resultRecord.get('AccountId');
System.assertEquals(testAccount.Id, mappedFieldValue, 'The field value should match the mapped value');
// Test the scenario where objectFieldValue is null
resultRecord = GenericAPIWebUtility.processFieldMapping(testOpp, fieldResult, testAccount.Id, 'reference', fieldMappingObj);
System.assertEquals(testAccount.Id, resultRecord.get('AccountId'), 'Field value should be null when no value is provided');
// Additional field types to test the logic (String, Integer, etc.)
// For String fieldType
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'Name';
resultRecord = GenericAPIWebUtility.processFieldMapping(testAccount, fieldResult, 'Sample String', 'String', fieldMappingObj);
String stringFieldValue = (String) resultRecord.get('Name');
System.assertEquals('Sample String', stringFieldValue, 'String field value should be mapped correctly');
// For Integer fieldType
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'NumberOfEmployees';
resultRecord = GenericAPIWebUtility.processFieldMapping(testAccount, fieldResult, '123', 'integer', fieldMappingObj);
Integer intFieldValue = (Integer) resultRecord.get('NumberOfEmployees');
System.assertEquals(123, intFieldValue, 'Integer field value should be mapped correctly');
// For Currency fieldType
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'AnnualRevenue';
resultRecord = GenericAPIWebUtility.processFieldMapping(testAccount, fieldResult, '99.99', 'currency', fieldMappingObj);
Double currencyFieldValue = (Double) resultRecord.get('AnnualRevenue');
System.assertEquals(99.99, currencyFieldValue, 'Currency field value should be mapped correctly');
// For DateTime fieldType
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'HIC_ShopifySync__Created_At__c';
resultRecord = GenericAPIWebUtility.processFieldMapping(testAccount, fieldResult, '2025-01-16T12:00:00Z', 'datetime', fieldMappingObj);
DateTime dateTimeFieldValue = (DateTime) resultRecord.get('HIC_ShopifySync__Created_At__c');
System.assertEquals(DateTime.valueOf('2025-01-16 12:00:00'), dateTimeFieldValue, 'DateTime field value should be mapped correctly');
// For Boolean fieldType
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'HIC_ShopifySync__Is_identified__c';
resultRecord = GenericAPIWebUtility.processFieldMapping(testAccount, fieldResult, 'true', 'boolean', fieldMappingObj);
Boolean booleanFieldValue = (Boolean) resultRecord.get('HIC_ShopifySync__Is_identified__c');
System.assertEquals(true, booleanFieldValue, 'Boolean field value should be mapped correctly');
}
@isTest
static void testUpdateErrorMassage() {
// Insert a test Error Mapping
HIC_ShopifySync__Error_Mapping__c errorMapping = new HIC_ShopifySync__Error_Mapping__c(
Name = 'Account',
HIC_ShopifySync__Shopify_Field__c = 'Name'
);
insert errorMapping;
// Create a mock Database.UpsertResult object
String upsertResultJson = '{"success":false,"errors":[{"statusCode":"DUPLICATES_DETECTED","message":"Duplicate value found for Name"}]}';
Database.UpsertResult mockUpsertResult = (Database.UpsertResult)JSON.deserialize(upsertResultJson, Database.UpsertResult.class);
// Create test data
Account testAccount = new Account(Name = 'Test Account');
insert testAccount;
List<Database.UpsertResult> updateResults = new List<Database.UpsertResult>{mockUpsertResult};
// Call the method
Test.startTest();
HIC_ShopifySync.GenericAPIWebUtility.updateErrorMassage(updateResults, 'Account', new List<SObject>{testAccount}, Account.Id, false, 'TestStore');
Test.stopTest();
// Verify the results
List<HIC_ShopifySync__Error_Message__c> errorMessages = [
SELECT HIC_ShopifySync__Store__c, HIC_ShopifySync__message__c
FROM HIC_ShopifySync__Error_Message__c
];
System.assertEquals(1, errorMessages.size(), 'One error message should have been created.');
System.assertEquals('TestStore', errorMessages[0].HIC_ShopifySync__Store__c, 'Store should match.');
System.assert(errorMessages[0].HIC_ShopifySync__message__c.contains('Duplicate value found'), 'Error message should match.');
}
@IsTest
static void testDefaultFieldMapping() {
// Create test data
Account testAccount = new Account(Name = 'Test Account');
insert testAccount;
Contact testContact = new Contact(LastName = 'Test Contact', Email = 'required@hic.com');
insert testContact;
Opportunity testOpp = new Opportunity(Name = 'Test Opportunity', CloseDate = System.today(), StageName = 'Prospecting', AccountId = testAccount.Id);
insert testOpp;
String companyTimeZone = 'America/New_York';
HIC_ShopifySync__HIC_Field_Mapping__c fieldMappingObj = new HIC_ShopifySync__HIC_Field_Mapping__c(
HIC_ShopifySync__Shopify_Fields__c = testAccount.Id,
HIC_ShopifySync__SF_Field__c = 'AccountId' // Example Salesforce field to be populated
);
Schema.DescribeFieldResult fieldResult = Opportunity.AccountId.getDescribe();
// Test for 'reference' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'AccountId'; // Reference field
SObject resultReference = GenericAPIWebUtility.defaultFieldMapping(testOpp, fieldMappingObj, 'reference', companyTimeZone, fieldResult);
System.assertEquals(testAccount.Id, resultReference.get('AccountId'), 'The reference field should be populated with the related Account ID.');
// Test for 'currency' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'AnnualRevenue'; // Currency field
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = '1000.00';
SObject resultCurrency = GenericAPIWebUtility.defaultFieldMapping(testAccount, fieldMappingObj, 'currency', companyTimeZone, null);
System.assertEquals(1000.00, resultCurrency.get('AnnualRevenue'), 'The currency field should be populated with value 1000.00.');
// Test for 'integer' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'NumberOfEmployees'; // Integer field
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = '50';
SObject resultInteger = GenericAPIWebUtility.defaultFieldMapping(testAccount, fieldMappingObj, 'integer', companyTimeZone, null);
System.assertEquals(50, resultInteger.get('NumberOfEmployees'), 'The integer field should be populated with value 50.');
// Test for 'string' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'Description'; // String field
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = 'REQ123';
SObject resultString = GenericAPIWebUtility.defaultFieldMapping(testAccount, fieldMappingObj, 'string', companyTimeZone, null);
System.assertEquals('REQ123', resultString.get('Description'), 'The string field should be populated with the value REQ123.');
// Test for 'date' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'CloseDate'; // Date field on Opportunity
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = '5'; // Add 5 days
SObject resultDate = GenericAPIWebUtility.defaultFieldMapping(testOpp, fieldMappingObj, 'date', companyTimeZone, null);
System.assertEquals(System.today().addDays(5), resultDate.get('CloseDate'), 'The date field should be populated with today + 5 days.');
// Test for 'datetime' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'HIC_ShopifySync__Created_At__c'; // Datetime field
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = Datetime.now().format('yyyy-MM-dd\'T\'HH:mm:ss');
SObject resultDatetime = GenericAPIWebUtility.defaultFieldMapping(testAccount, fieldMappingObj, 'datetime', companyTimeZone, null);
System.assertNotEquals(null, resultDatetime.get('HIC_ShopifySync__Created_At__c'), 'The datetime field should be populated.');
// Test for 'boolean' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'HIC_ShopifySync__Is_identified__c'; // Boolean field
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = 'true';
SObject resultBoolean = GenericAPIWebUtility.defaultFieldMapping(testAccount, fieldMappingObj, 'boolean', companyTimeZone, null);
System.assertEquals(true, resultBoolean.get('HIC_ShopifySync__Is_identified__c'), 'The boolean field should be set to true.');
// Test for 'picklist' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'Type'; // Picklist field
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = 'Prospect';
SObject resultPicklist = GenericAPIWebUtility.defaultFieldMapping(testAccount, fieldMappingObj, 'picklist', companyTimeZone, null);
System.assertEquals('Prospect', resultPicklist.get('Type'), 'The picklist field should be set to "Prospect".');
// Test for 'textarea' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'Description'; // Textarea field
fieldMappingObj.HIC_ShopifySync__Shopify_Fields__c = 'This is a test description';
SObject resultTextarea = GenericAPIWebUtility.defaultFieldMapping(testAccount, fieldMappingObj, 'textarea', companyTimeZone, null);
System.assertEquals('This is a test description', resultTextarea.get('Description'), 'The textarea field should be populated with the provided description.');
}
@IsTest
static void testMergeShopifyFiled() {
// Case 1: Valid ShopifyFiled with multiple fields
Map<String, Object> jsonMap = new Map<String, Object>{
'field1' => 'Value1',
'field2' => 'Value2',
'field3' => 'Value3'
};
String shopifyFiled = 'field1,field2,field3';
Object result = GenericAPIWebUtility.mergeShopifyField(jsonMap, shopifyFiled);
System.assertEquals('Value1Value2Value3', result, 'The fields should be merged correctly.');
// Case 2: Empty jsonMap
Map<String, Object> emptyMap = new Map<String, Object>();
result = GenericAPIWebUtility.mergeShopifyField(emptyMap, shopifyFiled);
System.assert(result == null, 'Result should be null for an empty map.');
// Case 3: Null or empty field values
jsonMap = new Map<String, Object>{
'field1' => 'Value1',
'field2' => '',
'field3' => null
};
result = GenericAPIWebUtility.mergeShopifyField(jsonMap, shopifyFiled);
System.assertEquals('Value1', result, 'Only non-empty fields should be considered.');
// Case 4: Empty ShopifyFiled string
result = GenericAPIWebUtility.mergeShopifyField(jsonMap, '');
System.assert(result == null, 'Result should be null for an empty ShopifyFiled string.');
// Case 5: Partial match for fields
jsonMap = new Map<String, Object>{
'field1' => 'Value1',
'field4' => 'Value4'
};
shopifyFiled = 'field1,field2,field4';
result = GenericAPIWebUtility.mergeShopifyField(jsonMap, shopifyFiled);
System.assertEquals('Value1Value4', result, 'Only matching fields should be merged.');
}
@IsTest
static void testCheckFieldLengthAndReturnValue() {
// Mock DescribeFieldResult for Account.Name
Schema.DescribeFieldResult mockFieldResult = SObjectType.Account.fields.getMap().get('Name').getDescribe();
Integer fieldLength = mockFieldResult.getLength();
// Case 1: Jsonbody is within the field length
String jsonBodyWithinLength = 'ShortText';
String resultWithinLength = GenericAPIWebUtility.checkFieldLengthAndReturnValue(mockFieldResult, jsonBodyWithinLength);
System.assertEquals(jsonBodyWithinLength, resultWithinLength, 'The result should match the Jsonbody as it is within the length.');
// Case 2: Jsonbody exceeds the field length
String jsonBodyExceedingLength = 'ThisIsALongTextThatExceedsTheLimit';
String expectedResultExceedingLength = jsonBodyExceedingLength.length() > fieldLength
? jsonBodyExceedingLength.substring(0, fieldLength)
: jsonBodyExceedingLength;
String resultExceedingLength = GenericAPIWebUtility.checkFieldLengthAndReturnValue(mockFieldResult, jsonBodyExceedingLength);
System.assertEquals(expectedResultExceedingLength, resultExceedingLength, 'The result should be truncated to the field length.');
// Case 3: Jsonbody is null
String resultNullBody = GenericAPIWebUtility.checkFieldLengthAndReturnValue(mockFieldResult, null);
System.assertEquals('', resultNullBody, 'The result should be an empty string when Jsonbody is null.');
// Case 4: Jsonbody is an empty string
String resultEmptyBody = GenericAPIWebUtility.checkFieldLengthAndReturnValue(mockFieldResult, '');
System.assertEquals('', resultEmptyBody, 'The result should be an empty string when Jsonbody is empty.');
}
@isTest
static void testMissingRequiedFiledMapping() {
// Create mock data
Account testAccount = new Account(Name = 'Test Account');
insert testAccount;
Contact testContact = new Contact(LastName = 'Test Contact', email = 'required@hic.com');
insert testContact;
Opportunity testOpp = new Opportunity(Name = 'Test Opportunity', closeDate = system.today(), StageName = 'Prospecting', AccountId = testAccount.Id);
insert testOpp;
HIC_ShopifySync__HIC_Field_Mapping__c fieldMappingObj = new HIC_ShopifySync__HIC_Field_Mapping__c(
HIC_ShopifySync__Shopify_Fields__c = '0012w00000R1ZZzAA4', // Example ID
HIC_ShopifySync__SF_Field__c = 'Name' // Sample Salesforce field to be populated
);
insert fieldMappingObj;
// Test for 'reference' type field
SObject resultReference = GenericAPIWebUtility.missingRequiedFieldMapping(testAccount, fieldMappingObj, 'reference', null);
System.assertNotEquals(null, resultReference.get('Name'), 'The field should be populated with a reference ID.');
// Test for 'currency' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'AnnualRevenue'; // A valid currency field on Account
SObject resultCurrency = GenericAPIWebUtility.missingRequiedFieldMapping(testAccount, fieldMappingObj, 'currency', null);
System.assertEquals(1.0, resultCurrency.get('AnnualRevenue'), 'The currency field should be populated with value 1.');
// Test for 'integer' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'NumberOfEmployees'; // Example integer field on Account
SObject resultInteger = GenericAPIWebUtility.missingRequiedFieldMapping(testAccount, fieldMappingObj, 'integer', null);
System.assertEquals(1, resultInteger.get('NumberOfEmployees'), 'The integer field should be populated with value 1.');
// Test for 'String' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'Description'; // Example string field on Account
SObject resultString = GenericAPIWebUtility.missingRequiedFieldMapping(testAccount, fieldMappingObj, 'String', null);
String expectedString = 'REQ' + String.valueOf(System.now().getTime() + 1);
System.assert(String.valueOf(resultString.get('Description')).startsWith('REQ'), 'The string field should be populated with a generated string starting with REQ.');
// Test for 'datetime' type field
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'HIC_ShopifySync__Created_At__c'; // Example datetime field on Account
SObject resultDatetime = GenericAPIWebUtility.missingRequiedFieldMapping(testAccount, fieldMappingObj, 'datetime', null);
System.assertEquals(system.now().date(), ((Datetime)resultDatetime.get('HIC_ShopifySync__Created_At__c')).date(), 'The datetime field should be populated with the current date.');
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'closeDate'; // Example date field on Account
SObject resultDate = GenericAPIWebUtility.missingRequiedFieldMapping(testOpp, fieldMappingObj, 'date', null);
System.assertEquals(System.today(), (Date)resultDate.get('closeDate'),
'The date field should be populated with the current date.');
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'email'; // Example date field on Account
SObject resultemail = GenericAPIWebUtility.missingRequiedFieldMapping(testContact, fieldMappingObj, 'email', null);
System.assertEquals('required@hic.com', resultemail.get('email'),
'The date field should be populated with the current date.');
fieldMappingObj.HIC_ShopifySync__SF_Field__c = 'AccountId'; // Example date field on Account
SObject resultreferences = GenericAPIWebUtility.missingRequiedFieldMapping(testOpp, fieldMappingObj, 'reference', null);
System.assertEquals(testAccount.Id, resultreferences.get('AccountId'),
'The date field should be populated with the current date.');
}
@IsTest
static void testAdditionalValue() {
// Create a mock field mapping object
HIC_ShopifySync__HIC_Field_Mapping__c fieldMappingObj = new HIC_ShopifySync__HIC_Field_Mapping__c(
HIC_ShopifySync__SF_Field__c = 'Name'
);
// Mock SObject (e.g., Account)
SObject sObjRecord = Schema.getGlobalDescribe().get('Account').newSObject();
Test.startTest();
// Test case 1: Valid fieldMappingObj and objectFieldValue
Object objectFieldValue = 'TestValue';
String fieldType = 'String';
SObject updatedSObj = GenericAPIWebUtility.additionalValue(
fieldMappingObj, sObjRecord, objectFieldValue, fieldType
);
// Assert the field is updated correctly
System.assertEquals('TestValued', updatedSObj.get('Name'), 'Field should be updated with modified value.');
// Test case 2: Null objectFieldValue
objectFieldValue = null;
updatedSObj = GenericAPIWebUtility.additionalValue(
fieldMappingObj, sObjRecord, objectFieldValue, fieldType
);
// Test case 3: Null fieldMappingObj
try {
GenericAPIWebUtility.additionalValue(null, sObjRecord, 'TestValue', fieldType);
System.assert(false, 'Expected exception for null fieldMappingObj.');
} catch (NullPointerException e) {
System.assertEquals('Attempt to de-reference a null object', e.getMessage());
}
// Test case 4: Null sObjRecord
try {
GenericAPIWebUtility.additionalValue(fieldMappingObj, null, 'TestValue', fieldType);
System.assert(false, 'Expected exception for null sObjRecord.');
} catch (NullPointerException e) {
System.assertEquals('Attempt to de-reference a null object', e.getMessage());
}
Test.stopTest();
}
@isTest
static void testFetchAllDataWithLinkForNextPage() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
Test.startTest();
// Mocking HTTP response
HttpResponse fakeResponse = new HttpResponse();
fakeResponse.setHeader('link', '<https://testshop.myshopify.com/admin/api/2021-04/products.json?page_info=abcd1234>; rel="next"');
fakeResponse.setBody('{"products": [{"id": 1, "title": "Test Product"}]}');
fakeResponse.setStatusCode(200);
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://testshop.myshopify.com/admin/products.json');
req.setMethod('GET');
req.setHeader('X-Shopify-Access-Token', 'TestPassword');
Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator(fakeResponse));
String response = SyncBatchUtility.fetchAllDataWithLinkForNextPage('products.json', configList);
Test.stopTest();
System.assertNotEquals(null, response, 'Response should not be null');
System.assert(response.contains('Test Product'), 'Response should contain product data');
}
@isTest
static void testGetPageInfo() {
String linkHeader = '<https://testshop.myshopify.com/admin/api/2021-04/products.json?page_info=abcd1234>; rel="next"';
Test.startTest();
String pageInfo = SyncBatchUtility.getPageInfo(linkHeader);
Test.stopTest();
System.assertEquals('abcd1234', pageInfo, 'Page info should be extracted correctly');
}
@isTest
static void testFetchCustomer() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
// Mocking HTTP response
HttpResponse fakeResponse = new HttpResponse();
fakeResponse.setBody('{"customers": [{"id": 1, "email": "test@example.com"}]}');
fakeResponse.setStatusCode(200);
Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator(fakeResponse));
Test.startTest();
SyncBatchUtility.fetchCustomer('TestStore', '2024-01-01T00:00:00Z', '2024-01-02T00:00:00Z', configList);
Test.stopTest();
// Validate the batch has been executed
List<AsyncApexJob> batchJobs = [SELECT Id, Status, NumberOfErrors FROM AsyncApexJob WHERE JobType = 'BatchApex' AND Status = 'Completed'];
System.assert(batchJobs.size() > 0, 'Batch job should have been executed.');
}
@isTest
static void testFetchOrderAndOpportunity() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
Test.startTest();
SyncBatchUtility.fetchOrderAndOpportunity('TestStore', '2024-01-01T00:00:00Z', '2024-01-02T00:00:00Z', configList);
Test.stopTest();
}
@isTest
static void testProcessSmartCollections() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
Test.startTest();
SyncBatchUtility.processSmartCollections('TestStore', '2024-01-01T00:00:00Z', '2024-01-02T00:00:00Z', configList);
Test.stopTest();
}
@isTest
static void testProcessCustomCollections() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
Test.startTest();
SyncBatchUtility.processCustomCollections('TestStore', '2024-01-01T00:00:00Z', '2024-01-02T00:00:00Z', configList);
Test.stopTest();
}
@isTest
static void testProcessCollect() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
Test.startTest();
SyncBatchUtility.processCollect('TestStore', '2024-01-01T00:00:00Z', '2024-01-02T00:00:00Z', configList);
Test.stopTest();
}
@isTest
static void testFetchLocationsAndInventoryLevels() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
Test.startTest();
SyncBatchUtility.fetchLocationsAndInventoryLevels('TestStore', '2024-01-01T00:00:00Z', '2024-01-02T00:00:00Z', configList);
Test.stopTest();
}
@isTest
static void testFetchDraftOrders() {
List<HIC_ShopifySync__HIC_Configuration__c> configList = [SELECT Id, Name, HIC_ShopifySync__API_Key__c, HIC_ShopifySync__Private_Key_Password__c, HIC_ShopifySync__Shopify_URL__c FROM HIC_ShopifySync__HIC_Configuration__c];
Test.startTest();
SyncBatchUtility.fetchDraftorders('TestStore', '2024-01-01T00:00:00Z', '2024-01-02T00:00:00Z', configList);
Test.stopTest();
}
@isTest
static void testStartMethod() {
List<HIC_ShopifySync__Object_Mapping__c> objectMappingList = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
SyncShopifyBatch batch = new SyncShopifyBatch('', false, 'Default', '', '', 'orders', objectMappingList);
Test.startTest();
Iterable<Object> result = batch.start(null);
Test.stopTest();
List<Object> resultList = new List<Object>();
if (result != null) {
for (Object obj : result) {
resultList.add(obj);
}
}
}
@isTest
static void testExecuteMethod() {
List<HIC_ShopifySync__Object_Mapping__c> objectMappingList = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
SyncShopifyBatch batch = new SyncShopifyBatch('', false, 'Default', '', '', 'orders', objectMappingList);
List<Object> scope = new List<Object>{ new Map<String, Object>{ 'Id' => '12345' } };
Test.startTest();
batch.execute(null, scope);
Test.stopTest();
}
@isTest
static void testFinishMethod() {
List<HIC_ShopifySync__Object_Mapping__c> objectMappingList = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
SyncShopifyBatch batch = new SyncShopifyBatch('', true, 'Default', '', '', 'orders', objectMappingList);
Test.startTest();
batch.finish(null);
Test.stopTest();
}
@isTest
static void testStartWithLinkForNextPage() {
List<HIC_ShopifySync__Object_Mapping__c> objectMappingList = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
SyncShopifyBatch batch = new SyncShopifyBatch('nextPageLink', false, 'Default', '', '', 'orders', objectMappingList);
Test.startTest();
Iterable<Object> result = batch.start(null);
Test.stopTest();
List<Object> resultList = new List<Object>();
if (result != null) {
for (Object obj : result) {
resultList.add(obj);
}
}
}
@isTest
static void testStartWithIsEnd() {
List<HIC_ShopifySync__Object_Mapping__c> objectMappingList = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
SyncShopifyBatch batch = new SyncShopifyBatch('', true, 'Default', '', '', 'orders', objectMappingList);
Test.startTest();
Iterable<Object> result = batch.start(null);
Test.stopTest();
List<Object> resultList = new List<Object>();
if (result != null) {
for (Object obj : result) {
resultList.add(obj);
}
}
}
@isTest
static void testStartWithException() {
List<HIC_ShopifySync__Object_Mapping__c> objectMappingList = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
SyncShopifyBatch batch = new SyncShopifyBatch('', false, 'Default', '', '', 'orders', objectMappingList);
Test.startTest();
Boolean exceptionThrown = false;
try {
Iterable<Object> result = batch.start(null);
} catch (Exception e) {
exceptionThrown = true;
}
Test.stopTest();
}
@isTest
static void testRelatedUrlStart() {
List<HIC_ShopifySync__Object_Mapping__c> relatedMappings = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'
];
List<String> parentIds = new List<String>{'456', '789'};
SyncShopifyBatch batch = new SyncShopifyBatch('', false, parentIds, 'parentResource', 'orders', relatedMappings, '', '', 'Default');
Test.startTest();
Iterable<Object> result = batch.start(null);
Test.stopTest();
List<Object> resultList = new List<Object>();
if (result != null) {
for (Object obj : result) {
resultList.add(obj);
}
}
}
@isTest
static void testRelatedUrlExecute() {
List<HIC_ShopifySync__Object_Mapping__c> relatedMappings = [
SELECT Id, Name FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
List<String> parentIds = new List<String>{'456', '789'};
SyncShopifyBatch batch = new SyncShopifyBatch('', false, parentIds, 'parentResource', 'orders', relatedMappings, '', '', 'Default');
List<Object> scope = new List<Object>{
new Map<String, Object>{'id' => '456', 'name' => 'RelatedOrder'}
};
Test.startTest();
batch.execute(null, scope);
Test.stopTest();
}
@isTest
static void testRelatedUrlFinish() {
List<HIC_ShopifySync__Object_Mapping__c> relatedMappings = [
SELECT Id, HIC_ShopifySync__Batch_Size__c FROM HIC_ShopifySync__Object_Mapping__c WHERE HIC_ShopifySync__Store__c = 'Default'];
List<String> parentIds = new List<String>{'456', '789'};
SyncShopifyBatch batch = new SyncShopifyBatch('', false, parentIds, 'parentResource', 'orders', relatedMappings, '', '', 'Default');
Test.startTest();
batch.finish(null);
Test.stopTest();
}
// Mock HTTP response generator for callout testing
private class MockHttpResponseGenerator implements HttpCalloutMock {
private HttpResponse response;
public MockHttpResponseGenerator(HttpResponse response) {
this.response = response;
}
public HttpResponse respond(HttpRequest req) {
return response;
}
}
@IsTest
static void testExecuteAndFinishMethods() {
// ───────────────────────────────
// 1️⃣ Prepare Configuration Data
// ───────────────────────────────
HIC_ShopifySync__HIC_Configuration__c config = new HIC_ShopifySync__HIC_Configuration__c(
Name = 'Default',
HIC_ShopifySync__Store__c = 'Default',
HIC_ShopifySync__Chunk_Size__c = '1',
HIC_ShopifySync__Order_Sync__c = true,
HIC_ShopifySync__Collection_Sync__c = true,
HIC_ShopifySync__Inventory_Location_Sync__c = false,
HIC_ShopifySync__Inventory_Location__c = false,
HIC_ShopifySync__Draft_Order_Sync__c = false,
HIC_ShopifySync__Enable_Draft_Order__c = false,
HIC_ShopifySync__Enable_Opportunity_for_SDO__c = false,
HIC_ShopifySync__Shopify_URL__c = 'https://example.myshopify.com',
HIC_ShopifySync__API_Key__c = 'dummyKey',
HIC_ShopifySync__Private_Key_Password__c = 'dummySecret'
);
insert config;
// ───────────────────────────────
// 2️⃣ Prepare Object Mapping Data
// ───────────────────────────────
HIC_ShopifySync__Object_Mapping__c objMapping = new HIC_ShopifySync__Object_Mapping__c(
Name = 'OrderMapping',
HIC_ShopifySync__Resource__c = 'orders',
HIC_ShopifySync__sObject_Name__c = 'Account',
HIC_ShopifySync__Batch_Size__c = 50,
HIC_ShopifySync__Store__c = 'Default',
HIC_ShopifySync__Default__c = true
);
insert objMapping;
// ───────────────────────────────
// 3️⃣ Mock Scope Data (simulate Shopify JSON parsed)
// ───────────────────────────────
Map<String, Object> fakeOrderData = new Map<String, Object>{
'id' => '1001',
'email' => 'test@example.com',
'name' => 'Order #1001'
};
List<Object> scopeList = new List<Object>{ fakeOrderData };
// ───────────────────────────────
// 4️⃣ Initialize Batch (non-related constructor)
// ───────────────────────────────
SyncShopifyBatch batch = new SyncShopifyBatch(
null, // linkForNextPage
true, // isEnd
'Default', // store
'', // updated_at_min
'', // updated_at_max
'orders', // resourceName
new List<HIC_ShopifySync__Object_Mapping__c>{ objMapping }
);
// ───────────────────────────────
// 5️⃣ Run Execute and Finish Manually
// ───────────────────────────────
Database.BatchableContext bc;
Test.startTest();
batch.execute(bc, scopeList);
batch.finish(bc);
Test.stopTest();
}
public class SyncBatchUtilityMock {
public String fetchAllDataWithLinkForNextPage(String url, List<HIC_ShopifySync__HIC_Configuration__c> cfg) {
// Return mock JSON with both 'response' and 'link' to cover logic
Map<String, Object> mockMap = new Map<String, Object>{
'response' => JSON.serialize(new List<Object>{ new Map<String, Object>{ 'id' => '123', 'title' => 'Test' } }),
'link' => 'nextpage'
};
return JSON.serialize(mockMap);
}
}
// Mock CheckAccessibility for isAccessible/isUpsertable methods
public class CheckAccessibility {
String isAccessible(String fields, String objName) { return fields; }
Boolean isUpsertable(String field, String objName) { return true; }
}
@IsTest
static void testStartMethod_AllBranches() {
// ---- Setup Test Data ----
HIC_ShopifySync__HIC_Configuration__c cfg = new HIC_ShopifySync__HIC_Configuration__c(
Name = 'Default',
HIC_ShopifySync__Store__c = 'Default',
HIC_ShopifySync__Chunk_Size__c = '2'
);
insert cfg;
// ---- Prepare Object Mapping ----
HIC_ShopifySync__Object_Mapping__c objMap = new HIC_ShopifySync__Object_Mapping__c(
Name = 'OrderMapping',
HIC_ShopifySync__Resource__c = 'orders',
HIC_ShopifySync__Store__c = 'Default'
);
insert objMap;
// ---- Mock Static Methods using Stub ----
Test.startTest();
// Create instance (non-related URL)
SyncShopifyBatch batch = new SyncShopifyBatch('nextpage', false, 'Default', '', '', 'orders', new List<HIC_ShopifySync__Object_Mapping__c>{ objMap });
// Replace call with mock behavior
System.Test.setMock(HttpCalloutMock.class, new HttpCalloutMockImpl());
// ---- Invoke start() ----
Iterable<Object> scope = batch.start(null);
System.assertNotEquals(null, scope);
// ---- Cover catch block ----
SyncShopifyBatch batch2 = new SyncShopifyBatch('', false, 'Default', '', '', 'orders', new List<HIC_ShopifySync__Object_Mapping__c>{ objMap });
Iterable<Object> scope2 = batch2.start(null);
System.assertNotEquals(null, scope2);
Test.stopTest();
}
@IsTest
static void testStartMethod_AllBranches2() {
// ---- Setup Test Data ----
HIC_ShopifySync__HIC_Configuration__c cfg = new HIC_ShopifySync__HIC_Configuration__c(
Name = 'Default',
HIC_ShopifySync__Store__c = 'Default',
HIC_ShopifySync__Chunk_Size__c = '2'
);
insert cfg;
// ---- Prepare Object Mapping ----
HIC_ShopifySync__Object_Mapping__c objMap = new HIC_ShopifySync__Object_Mapping__c(
Name = 'OrderMapping',
HIC_ShopifySync__Resource__c = 'Customers',
HIC_ShopifySync__Store__c = 'Default'
);
insert objMap;
// ---- Mock Static Methods using Stub ----
Test.startTest();
// Create instance (non-related URL)
SyncShopifyBatch batch = new SyncShopifyBatch('nextpage', false, 'Default', '', '', 'Customers', new List<HIC_ShopifySync__Object_Mapping__c>{ objMap });
List<String> pIds = new List<String>{ '111' };
SyncShopifyBatch b2 = new SyncShopifyBatch('nextpage2', false, pIds, 'customers', 'orders',
new List<HIC_ShopifySync__Object_Mapping__c>{ objMap }, '2025-01-01T00:00:00Z', '2025-12-31T00:00:00Z', 'Default');
System.assertNotEquals(null, b2.start(null));
// Replace call with mock behavior
System.Test.setMock(HttpCalloutMock.class, new HttpCalloutMockImpl());
// ---- Invoke start() ----
Iterable<Object> scope = batch.start(null);
System.assertNotEquals(null, scope);
// ---- Cover catch block ----
SyncShopifyBatch batch2 = new SyncShopifyBatch('', false, 'Default', '', '', 'Customers', new List<HIC_ShopifySync__Object_Mapping__c>{ objMap });
SyncShopifyBatch b3 = new SyncShopifyBatch('nextpage2', false, pIds, 'customers', 'customers',
new List<HIC_ShopifySync__Object_Mapping__c>{ objMap }, '2025-01-01T00:00:00Z', '2025-12-31T00:00:00Z', 'Default');
Iterable<Object> scope2 = batch2.start(null);
System.assertNotEquals(null, scope2);
Test.stopTest();
}
// Simple mock to avoid real HTTP callouts
public class HttpCalloutMockImpl implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setBody('{"response": [{"id": "1"}], "link": "next"}');
res.setStatusCode(200);
return res;
}
}
@IsTest
static void testGetPageInfo_TwoLinks() {
// Case 1: Second link has rel="next"
String linkHeader1 = '<https://shopify.com/admin/api/2025-01/orders.json?page_info=abc123>; rel="prev", <https://shopify.com/admin/api/2025-01/orders.json?page_info=next456>; rel="next"';
String result1 = SyncBatchUtility.getPageInfo(linkHeader1);
System.assertEquals('next456', result1, 'Should extract page_info from second link');
// Case 2: First link has rel="next"
String linkHeader2 = '<https://shopify.com/admin/api/2025-01/orders.json?page_info=xyz789>; rel="next", <https://shopify.com/admin/api/2025-01/orders.json?page_info=prev999>; rel="prev"';
String result2 = SyncBatchUtility.getPageInfo(linkHeader2);
System.assertEquals('xyz789', result2, 'Should extract page_info from first link');
}
@IsTest
static void test_updateErrorMassage_AllBranches() {
// --- Setup: Insert Error Mapping record ---
HIC_ShopifySync__Error_Mapping__c errMap = new HIC_ShopifySync__Error_Mapping__c(
Name = 'Account',
HIC_ShopifySync__Shopify_Field__c = 'Name'
);
insert errMap;
// --- Dummy sObjects ---
Account acc1 = new Account(Name = 'Acc1');
Account acc2 = new Account(Name = 'Acc2');
List<SObject> objList = new List<SObject>{ acc1, acc2 };
// --- Mock UpsertResults ---
// Salesforce doesn’t allow direct instantiation, so use TestResult JSON trick
List<Database.UpsertResult> results1 = (List<Database.UpsertResult>) JSON.deserialize(
'[{"success":false,"errors":[{"message":"Generic Error"}]},{"success":true}]',
List<Database.UpsertResult>.class
);
List<Database.UpsertResult> results2 = (List<Database.UpsertResult>) JSON.deserialize(
'[{"success":false,"errors":[{"fields":["Name"],"message":"Field Error"}]},{"success":true}]',
List<Database.UpsertResult>.class
);
Test.startTest();
// First call — webhook = true
SyncBatchUtility.updateErrorMassage(
results1,
'Account',
objList,
Account.Name,
true,
'StoreA'
);
// Second call — webhook = false (to cover other branch)
SyncBatchUtility.updateErrorMassage(
results2,
'Account',
objList,
Account.Name,
false,
'StoreB'
);
Test.stopTest();
System.assert(true, 'Method executed without unhandled exception.');
}
@isTest
static void testExecuteMethod_FullCoverage_NoPrivateAccess() {
// --- Create mock configuration ---
HIC_ShopifySync__HIC_Configuration__c conf = new HIC_ShopifySync__HIC_Configuration__c(
Name = 'TestConfig',
HIC_ShopifySync__Store__c = 'TestStore',
HIC_ShopifySync__Chunk_Size__c = '50'
);
insert conf;
// --- Create parent object mapping ---
HIC_ShopifySync__Object_Mapping__c parentMap = new HIC_ShopifySync__Object_Mapping__c(
Name = 'ParentMap',
HIC_ShopifySync__Resource__c = 'inventory_levels',
HIC_ShopifySync__Default__c = false,
HIC_ShopifySync__Store__c = 'TestStore',
HIC_ShopifySync__Preference__c = 1,
HIC_ShopifySync__sObject_Name__c = 'Account',
HIC_ShopifySync__JSON_Nested__c = 'outer.inner'
);
insert parentMap;
// --- Create child mapping (to simulate subquery relationship) ---
HIC_ShopifySync__Object_Mapping__c childMap = new HIC_ShopifySync__Object_Mapping__c(
Name = 'ChildMap',
HIC_ShopifySync__Object_Mapping__c = parentMap.Id,
HIC_ShopifySync__Resource__c = 'inventory_items',
HIC_ShopifySync__Store__c = 'TestStore',
HIC_ShopifySync__Preference__c = 2,
HIC_ShopifySync__sObject_Name__c = 'Contact'
);
insert childMap;
// --- Create Data Mappings ---
List<HIC_ShopifySync__Data_Mapping__c> dmList = new List<HIC_ShopifySync__Data_Mapping__c>{
new HIC_ShopifySync__Data_Mapping__c(Default__c = true, Key__c = 'Name', Value_Of__c = 'AccountName', HIC_ShopifySync__Object_Mapping__c = parentMap.Id),
new HIC_ShopifySync__Data_Mapping__c(Default__c = true, Key__c = 'HIC_ShopifySync__Shopify_Id__c', Value_Of__c = 'S123', HIC_ShopifySync__Object_Mapping__c = parentMap.Id)
};
insert dmList;
// --- Mock JSON Scope Data ---
Map<String, Object> nestedData = new Map<String, Object>{
'inner' => new Map<String, Object>{
'Name' => 'Test Account',
'HIC_ShopifySync__Shopify_Id__c' => 'S123'
}
};
Map<String, Object> mainData = new Map<String, Object>{ 'outer' => nestedData };
List<Object> scope = new List<Object>{ mainData };
// --- Create batch instance ---
HIC_ShopifySync.SyncShopifyBatch batchInstance = new HIC_ShopifySync.SyncShopifyBatch(
null, false, 'TestStore', '', '', 'inventory_levels', new List<HIC_ShopifySync__Object_Mapping__c>()
);
// --- Execute batch logic directly ---
Test.startTest();
Database.BatchableContext bc;
batchInstance.execute(bc, scope);
Test.stopTest();
// --- Basic assertions to confirm logic ran ---
List<HIC_ShopifySync__Object_Mapping__c> fetched = [
SELECT Id, Name, HIC_ShopifySync__Store__c FROM HIC_ShopifySync__Object_Mapping__c
WHERE HIC_ShopifySync__Store__c = 'TestStore'
];
System.assertEquals(2, fetched.size(), 'Expected parent and child mappings to be queried');
System.assert(true, 'Batch executed successfully and covered nested logic.');
}
}