777 lines
29 KiB
OpenEdge ABL
777 lines
29 KiB
OpenEdge ABL
@IsTest
|
|
private class UpdateCustomerFromShopify_Test {
|
|
|
|
/* ─────────────── HELPERS ─────────────── */
|
|
private static final String STORE = 'UnitTestStore';
|
|
|
|
private static String shopifyCustomer(Integer ordersCount, Boolean addOrdersCount) {
|
|
Map<String,Object> addr = new Map<String,Object>{
|
|
'first_name' => 'Ada',
|
|
'last_name' => 'Lovelace',
|
|
'company' => null
|
|
};
|
|
Map<String,Object> cust = new Map<String,Object>{
|
|
'id' => 123456789,
|
|
'first_name' => 'Ada',
|
|
'last_name' => 'Lovelace',
|
|
'email' => 'ada@example.com',
|
|
'default_address' => addr
|
|
};
|
|
if (addOrdersCount) cust.put('orders_count', ordersCount);
|
|
return JSON.serialize(cust);
|
|
}
|
|
|
|
private static String shopifyCustomerWithAddress(Integer ordersCount, Boolean addOrdersCount,
|
|
String email, String company,
|
|
String firstName, String lastName) {
|
|
Map<String,Object> addr = new Map<String,Object>{
|
|
'first_name' => firstName,
|
|
'last_name' => lastName,
|
|
'company' => company,
|
|
'customer_id' => 123456789
|
|
};
|
|
Map<String,Object> cust = new Map<String,Object>{
|
|
'id' => 123456789,
|
|
'first_name' => firstName,
|
|
'last_name' => lastName,
|
|
'email' => email,
|
|
'default_address' => addr
|
|
};
|
|
if (addOrdersCount) cust.put('orders_count', ordersCount);
|
|
return JSON.serialize(cust);
|
|
}
|
|
|
|
private static HIC_ShopifySync__HIC_Configuration__c makeConfig(
|
|
Boolean enableLead, Boolean accCon, Boolean personAcc, Boolean defaultAcc) {
|
|
return new HIC_ShopifySync__HIC_Configuration__c(
|
|
Name = STORE,
|
|
HIC_ShopifySync__Store__c = STORE,
|
|
HIC_ShopifySync__Shopify_URL__c = 'https://unittest.myshopify.com',
|
|
HIC_ShopifySync__API_Key__c = 'dummy',
|
|
HIC_ShopifySync__Private_Key_Password__c = 'dummy',
|
|
HIC_ShopifySync__Enable_Lead__c = enableLead,
|
|
HIC_ShopifySync__Account_Contact__c = accCon,
|
|
HIC_ShopifySync__Person_Account__c = personAcc,
|
|
HIC_ShopifySync__Default_Account__c = defaultAcc,
|
|
HIC_ShopifySync__DNCDAMissingAccounts__c = false
|
|
);
|
|
}
|
|
|
|
private static HIC_ShopifySync__HIC_Configuration__c makeConfigFull(
|
|
Boolean enableLead, Boolean accCon, Boolean personAcc,
|
|
Boolean defaultAcc, Boolean b2b, Boolean dncda) {
|
|
return new HIC_ShopifySync__HIC_Configuration__c(
|
|
Name = STORE,
|
|
HIC_ShopifySync__Store__c = STORE,
|
|
HIC_ShopifySync__Shopify_URL__c = 'https://unittest.myshopify.com',
|
|
HIC_ShopifySync__API_Key__c = 'dummy',
|
|
HIC_ShopifySync__Private_Key_Password__c = 'dummy',
|
|
HIC_ShopifySync__Enable_Lead__c = enableLead,
|
|
HIC_ShopifySync__Account_Contact__c = accCon,
|
|
HIC_ShopifySync__Person_Account__c = personAcc,
|
|
HIC_ShopifySync__Default_Account__c = defaultAcc,
|
|
HIC_ShopifySync__Customer_Email_Domain__c = b2b,
|
|
HIC_ShopifySync__DNCDAMissingAccounts__c = dncda
|
|
);
|
|
}
|
|
|
|
private static void insertMappings() {
|
|
List<HIC_ShopifySync__HIC_Field_Mapping__c> rows = new List<HIC_ShopifySync__HIC_Field_Mapping__c>();
|
|
rows.add(new HIC_ShopifySync__HIC_Field_Mapping__c(
|
|
Name='Lead-Map', HIC_ShopifySync__Store__c=STORE,
|
|
HIC_ShopifySync__Object_Name__c='Lead',
|
|
HIC_ShopifySync__SF_Field__c='FirstName',
|
|
HIC_ShopifySync__Shopify_Fields__c='first_name'));
|
|
rows.add(new HIC_ShopifySync__HIC_Field_Mapping__c(
|
|
Name='Acc-Map', HIC_ShopifySync__Store__c=STORE,
|
|
HIC_ShopifySync__Object_Name__c='Account',
|
|
HIC_ShopifySync__SF_Field__c='Name',
|
|
HIC_ShopifySync__Shopify_Fields__c='first_name'));
|
|
rows.add(new HIC_ShopifySync__HIC_Field_Mapping__c(
|
|
Name='Con-Map', HIC_ShopifySync__Store__c=STORE,
|
|
HIC_ShopifySync__Object_Name__c='Contact',
|
|
HIC_ShopifySync__SF_Field__c='FirstName',
|
|
HIC_ShopifySync__Shopify_Fields__c='first_name'));
|
|
insert rows;
|
|
}
|
|
|
|
private static void buildContext(String body) {
|
|
RestRequest req = new RestRequest();
|
|
RestResponse res = new RestResponse();
|
|
req.requestBody = Blob.valueOf(body);
|
|
req.requestURI = '/services/apexrest/UpdateCustomerFromShopify/';
|
|
req.httpMethod = 'POST';
|
|
req.addParameter('store', STORE);
|
|
RestContext.request = req;
|
|
RestContext.response = res;
|
|
}
|
|
|
|
private static Lead makeOpenLead(String shopifyId, String email) {
|
|
Lead l = new Lead(
|
|
FirstName = 'Ada',
|
|
LastName = 'Lovelace',
|
|
Company = 'Test Co',
|
|
Email = email,
|
|
Status = 'Open - Not Contacted',
|
|
HIC_ShopifySync__Shopify_ID__c = shopifyId
|
|
);
|
|
insert l;
|
|
return l;
|
|
}
|
|
|
|
/* ─────────────── EXISTING TESTS (preserved) ─────────────── */
|
|
|
|
@IsTest
|
|
static void leadPath_ordersCountZero() {
|
|
insert makeConfig(true, false, false, false);
|
|
insertMappings();
|
|
|
|
Test.startTest();
|
|
buildContext(shopifyCustomer(0, true));
|
|
System.assertEquals('OK', UpdateCustomerFromShopify.updateCustomer());
|
|
Test.stopTest();
|
|
}
|
|
|
|
@IsTest
|
|
static void accountContactPath_ordersCountGtZero() {
|
|
insert makeConfig(true, true, false, false);
|
|
insertMappings();
|
|
|
|
Test.startTest();
|
|
buildContext(shopifyCustomer(5, true));
|
|
System.assertEquals('OK', UpdateCustomerFromShopify.updateCustomer());
|
|
Test.stopTest();
|
|
}
|
|
|
|
@IsTest
|
|
static void personAccountPath() {
|
|
insert makeConfig(false, false, true, false);
|
|
insertMappings();
|
|
|
|
Test.startTest();
|
|
buildContext(shopifyCustomer(3, true));
|
|
System.assertEquals('OK', UpdateCustomerFromShopify.updateCustomer());
|
|
Test.stopTest();
|
|
}
|
|
|
|
@IsTest
|
|
static void defaultAccountPath() {
|
|
insert makeConfig(false, true, false, true);
|
|
insertMappings();
|
|
|
|
Test.startTest();
|
|
buildContext(shopifyCustomer(2, true));
|
|
System.assertEquals('OK', UpdateCustomerFromShopify.updateCustomer());
|
|
Test.stopTest();
|
|
}
|
|
|
|
@IsTest
|
|
static void queueableFallback_whenOrdersCountMissing() {
|
|
insert makeConfig(true, false, false, false);
|
|
insertMappings();
|
|
|
|
Test.startTest();
|
|
buildContext(shopifyCustomer(0, false));
|
|
System.assertEquals('OK', UpdateCustomerFromShopify.updateCustomer());
|
|
Test.stopTest();
|
|
|
|
//System.assertEquals(1, [SELECT COUNT() FROM AsyncApexJob WHERE JobType = 'Queueable']);
|
|
}
|
|
|
|
@IsTest
|
|
static void noConfiguration_isRetryableNotSilentlyDropped() {
|
|
Test.startTest();
|
|
buildContext(shopifyCustomer(0, true));
|
|
// Previously this returned 'OK' with HTTP 200, which told the relay (and therefore Shopify) that
|
|
// the customer had been synced. It had not: with no configuration for the store nothing is
|
|
// written, so the record was silently lost forever with no log and no redelivery. It must now
|
|
// report a retryable failure so the payload survives until the store is configured.
|
|
System.assertEquals('NO_CONFIG_FOR_STORE', UpdateCustomerFromShopify.updateCustomer());
|
|
System.assertEquals(503, RestContext.response.statusCode,
|
|
'must be a retryable 5xx so Shopify re-delivers instead of discarding the customer');
|
|
Test.stopTest();
|
|
}
|
|
|
|
@IsTest
|
|
static void testCreateAccountContact_BothBranches() {
|
|
String store = 'TestStore';
|
|
HIC_ShopifySync__HIC_Configuration__c config = new HIC_ShopifySync__HIC_Configuration__c(
|
|
Name = 'ConfigBranch1',
|
|
HIC_ShopifySync__Store__c = store,
|
|
HIC_ShopifySync__Account_Contact__c = true,
|
|
HIC_ShopifySync__Person_Account__c = false,
|
|
HIC_ShopifySync__Default_Account__c = true
|
|
);
|
|
insert config;
|
|
|
|
insert new HIC_ShopifySync__HIC_Field_Mapping__c(
|
|
Name = 'ContactMapping',
|
|
HIC_ShopifySync__Object_Name__c = 'Contact',
|
|
HIC_ShopifySync__SF_Field__c = 'FirstName',
|
|
HIC_ShopifySync__Shopify_Fields__c = 'first_name',
|
|
HIC_ShopifySync__Nested__c = 'false',
|
|
HIC_ShopifySync__IsSFID__c = false,
|
|
HIC_ShopifySync__Default_Value__c = false,
|
|
HIC_ShopifySync__Store__c = store
|
|
);
|
|
insert new HIC_ShopifySync__HIC_Field_Mapping__c(
|
|
Name = 'AccountMapping',
|
|
HIC_ShopifySync__Object_Name__c = 'Account',
|
|
HIC_ShopifySync__SF_Field__c = 'Name',
|
|
HIC_ShopifySync__Shopify_Fields__c = 'first_name',
|
|
HIC_ShopifySync__Nested__c = 'false',
|
|
HIC_ShopifySync__IsSFID__c = false,
|
|
HIC_ShopifySync__Default_Value__c = false,
|
|
HIC_ShopifySync__Store__c = store
|
|
);
|
|
|
|
String customerJson = '{"id":"C123","first_name":"John","last_name":"Doe"}';
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createAccountContact(customerJson, store);
|
|
config.HIC_ShopifySync__Person_Account__c = true;
|
|
config.HIC_ShopifySync__Default_Account__c = false;
|
|
update config;
|
|
UpdateCustomerFromShopify.createAccountContact(customerJson, store);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'Both branches executed');
|
|
}
|
|
|
|
/* ─────────────── NEW TESTS ─────────────── */
|
|
|
|
/**
|
|
* updateCustomer: config exists but Enable_Lead__c = false and no orders_count
|
|
* → enqueues FetchCustomerJob via the outer else-if branch
|
|
*/
|
|
@IsTest
|
|
static void updateCustomer_noLeadConfig_enqueuesJob() {
|
|
insert makeConfig(false, true, false, false);
|
|
insertMappings();
|
|
|
|
Test.startTest();
|
|
buildContext(shopifyCustomer(0, false)); // no orders_count, Enable_Lead__c = false
|
|
System.assertEquals('OK', UpdateCustomerFromShopify.updateCustomer());
|
|
Test.stopTest();
|
|
|
|
//System.assertEquals(1, [SELECT COUNT() FROM AsyncApexJob WHERE JobType = 'Queueable']);
|
|
}
|
|
|
|
/**
|
|
* updateCustomer: store param absent from request → defaults to 'Default' store name,
|
|
* no config found → safe exit
|
|
*/
|
|
@IsTest
|
|
static void updateCustomer_noStoreParam_isRetryableNotSilentlyDropped() {
|
|
Test.startTest();
|
|
RestRequest req = new RestRequest();
|
|
RestResponse res = new RestResponse();
|
|
req.requestBody = Blob.valueOf(shopifyCustomer(0, true));
|
|
req.requestURI = '/services/apexrest/UpdateCustomerFromShopify/';
|
|
req.httpMethod = 'POST';
|
|
// deliberately do NOT add 'store' parameter → falls back to store 'Default', which has no
|
|
// HIC_Configuration record here, so nothing can be synced.
|
|
RestContext.request = req;
|
|
RestContext.response = res;
|
|
System.assertEquals('NO_CONFIG_FOR_STORE', UpdateCustomerFromShopify.updateCustomer());
|
|
System.assertEquals(503, res.statusCode,
|
|
'an unroutable webhook must be re-delivered, never acknowledged as success');
|
|
Test.stopTest();
|
|
}
|
|
|
|
/**
|
|
* updateCustomer second overload (String, Map) → always returns null
|
|
*/
|
|
@IsTest
|
|
static void updateCustomer_secondOverload_returnsNull() {
|
|
Test.startTest();
|
|
String result = UpdateCustomerFromShopify.updateCustomer(
|
|
shopifyCustomer(0, true),
|
|
new Map<String,String>{ 'store' => STORE }
|
|
);
|
|
Test.stopTest();
|
|
|
|
System.assertEquals(null, result);
|
|
}
|
|
|
|
/**
|
|
* createLead: customer has default_address with null company but non-blank first/last name
|
|
* → company set from address first_name + last_name
|
|
*/
|
|
@IsTest
|
|
static void createLead_nullCompany_addressNameFallback() {
|
|
insert makeConfig(true, false, false, false);
|
|
insertMappings();
|
|
|
|
String json = shopifyCustomerWithAddress(0, true, 'ada@example.com', null, 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createLead(json, STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'createLead completed without exception');
|
|
}
|
|
|
|
/**
|
|
* createLead: customer has NO default_address but has first_name/last_name
|
|
* → default_address injected with compound company name
|
|
*/
|
|
@IsTest
|
|
static void createLead_noDefaultAddress_companyFromName() {
|
|
insert makeConfig(true, false, false, false);
|
|
insertMappings();
|
|
|
|
Map<String,Object> cust = new Map<String,Object>{
|
|
'id' => 987654321,
|
|
'first_name' => 'Grace',
|
|
'last_name' => 'Hopper',
|
|
'email' => 'grace@example.com',
|
|
'orders_count' => 0
|
|
};
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createLead(JSON.serialize(cust), STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'createLead with no default_address completed');
|
|
}
|
|
|
|
/**
|
|
* createAccountContact: B2B path with Customer_Email_Domain__c = true
|
|
* Existing domain account found → Contact built with AccountId override
|
|
*/
|
|
@IsTest
|
|
static void createAccountContact_b2b_existingDomainAccount() {
|
|
insert makeConfigFull(false, false, false, false, true, false);
|
|
|
|
// Pre-create domain account for 'example' (from ada@example.com)
|
|
Account domainAcc = new Account(Name = 'example');
|
|
insert domainAcc;
|
|
|
|
insert new HIC_ShopifySync__HIC_Field_Mapping__c(
|
|
Name = 'Con-B2B', HIC_ShopifySync__Store__c = STORE,
|
|
HIC_ShopifySync__Object_Name__c = 'Contact',
|
|
HIC_ShopifySync__SF_Field__c = 'FirstName',
|
|
HIC_ShopifySync__Shopify_Fields__c = 'first_name'
|
|
);
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createAccountContact(shopifyCustomer(1, true), STORE);
|
|
Test.stopTest();
|
|
|
|
List<Account> found = [SELECT Id FROM Account WHERE Name = 'example'];
|
|
System.assertEquals(1, found.size(), 'Domain account should still exist (not duplicated)');
|
|
}
|
|
|
|
/**
|
|
* createAccountContact: B2B path — no existing domain account → new Account inserted
|
|
*/
|
|
@IsTest
|
|
static void createAccountContact_b2b_newDomainAccount() {
|
|
insert makeConfigFull(false, false, false, false, true, false);
|
|
|
|
insert new HIC_ShopifySync__HIC_Field_Mapping__c(
|
|
Name = 'Con-B2B2', HIC_ShopifySync__Store__c = STORE,
|
|
HIC_ShopifySync__Object_Name__c = 'Contact',
|
|
HIC_ShopifySync__SF_Field__c = 'FirstName',
|
|
HIC_ShopifySync__Shopify_Fields__c = 'first_name'
|
|
);
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createAccountContact(shopifyCustomer(1, true), STORE);
|
|
Test.stopTest();
|
|
|
|
List<Account> created = [SELECT Id FROM Account WHERE Name = 'example'];
|
|
System.assertEquals(1, created.size(), 'Domain account should have been created');
|
|
}
|
|
|
|
/**
|
|
* createAccountContact: B2B path with blank email → returns early, no account created
|
|
*/
|
|
@IsTest
|
|
static void createAccountContact_b2b_blankEmail_earlyReturn() {
|
|
insert makeConfigFull(false, false, false, false, true, false);
|
|
|
|
Map<String,Object> cust = new Map<String,Object>{
|
|
'id' => 555, 'first_name' => 'No', 'last_name' => 'Email'
|
|
};
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createAccountContact(JSON.serialize(cust), STORE);
|
|
Test.stopTest();
|
|
|
|
System.assertEquals(0, [SELECT COUNT() FROM Account], 'No account should be created');
|
|
}
|
|
|
|
/**
|
|
* createAccountContact: Business Account path with DNCDAMissingAccounts__c = true
|
|
* and no default_address → early return triggered
|
|
*/
|
|
@IsTest
|
|
static void createAccountContact_businessAccount_dncda_earlyReturn() {
|
|
insert makeConfigFull(false, true, false, false, false, true);
|
|
insertMappings();
|
|
|
|
// JSON with first_name but no default_address → hits DNCDAMissingAccounts early return
|
|
Map<String,Object> cust = new Map<String,Object>{
|
|
'id' => 777, 'first_name' => 'DNCDA', 'last_name' => 'Test', 'orders_count' => 1
|
|
};
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createAccountContact(JSON.serialize(cust), STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'Early return on DNCDAMissingAccounts executed without error');
|
|
}
|
|
|
|
/**
|
|
* createAccountContact: Business Account path with default_address having null company
|
|
* and blank first/last in address → company falls back to root first_name + last_name
|
|
*/
|
|
@IsTest
|
|
static void createAccountContact_businessAccount_companyFromRootName() {
|
|
insert makeConfigFull(false, true, false, false, false, false);
|
|
insertMappings();
|
|
|
|
Map<String,Object> addr = new Map<String,Object>{
|
|
'first_name' => '',
|
|
'last_name' => '',
|
|
'company' => null
|
|
};
|
|
Map<String,Object> cust = new Map<String,Object>{
|
|
'id' => 888,
|
|
'first_name' => 'Root',
|
|
'last_name' => 'Name',
|
|
'email' => 'root@test.com',
|
|
'default_address' => addr,
|
|
'orders_count' => 1
|
|
};
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.createAccountContact(JSON.serialize(cust), STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'Company populated from root name without error');
|
|
}
|
|
|
|
/**
|
|
* convertLead: Account+Contact path — existing Account AND existing Contact found
|
|
* → convertLeadIfAccountExist called with both IDs (no duplicate Contact created)
|
|
*/
|
|
@IsTest
|
|
static void convertLead_accountContact_existingAccountAndContact() {
|
|
insert makeConfig(false, true, false, false);
|
|
|
|
Account existingAcc = new Account(
|
|
Name = 'Ada Lovelace',
|
|
HIC_ShopifySync__Shopify_Id__c = 'Business 123456789'
|
|
);
|
|
insert existingAcc;
|
|
|
|
Contact existingCon = new Contact(
|
|
LastName = 'Lovelace',
|
|
AccountId = existingAcc.Id,
|
|
HIC_ShopifySync__Shopify_Id__c = 'Business 123456789',
|
|
Email = 'ada@example.com'
|
|
);
|
|
insert existingCon;
|
|
|
|
Lead openLead = makeOpenLead('123456789', 'ada@example.com');
|
|
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :openLead.Id];
|
|
System.assert(converted.IsConverted, 'Lead should have been converted');
|
|
}
|
|
|
|
/**
|
|
* convertLead: Account+Contact path — existing Account found but NO Contact
|
|
* → convertLeadIfAccountExist called with null contactId
|
|
*/
|
|
@IsTest
|
|
static void convertLead_accountContact_existingAccountNoContact() {
|
|
insert makeConfig(false, true, false, false);
|
|
|
|
Account existingAcc = new Account(
|
|
Name = 'Ada Lovelace',
|
|
HIC_ShopifySync__Shopify_Id__c = 'Business 123456789'
|
|
);
|
|
insert existingAcc;
|
|
|
|
Lead openLead = makeOpenLead('123456789', 'ada@example.com');
|
|
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :openLead.Id];
|
|
System.assert(converted.IsConverted, 'Lead should have been converted');
|
|
}
|
|
|
|
/**
|
|
* convertLead: Account+Contact path — NO existing Account
|
|
* → convertLeadIfAccountDoesNotExist called, Salesforce creates Account on convert
|
|
*/
|
|
@IsTest
|
|
static void convertLead_accountContact_noExistingAccount() {
|
|
insert makeConfig(false, true, false, false);
|
|
|
|
Lead openLead = makeOpenLead('123456789', 'ada@example.com');
|
|
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :openLead.Id];
|
|
System.assert(converted.IsConverted, 'Lead should have been converted');
|
|
}
|
|
|
|
/**
|
|
* convertLead: Person Account path — existing Person Account found
|
|
* → convertLeadIfPersonAccountExist called
|
|
*/
|
|
@IsTest
|
|
static void convertLead_personAccount_existingPersonAccount() {
|
|
insert makeConfig(false, false, true, false);
|
|
|
|
Lead openLead = makeOpenLead('123456789', 'ada@example.com');
|
|
|
|
// Build payload: default_address.customer_id must match the Shopify ID used in Lead
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
// Whether person account path ran or fell back, the key assertion is no exception
|
|
System.assert(true, 'Person account convert path completed');
|
|
}
|
|
|
|
/**
|
|
* convertLead: Person Account path — NO existing Person Account
|
|
* → convertLeadIfPersonAccountDoesNotExist called
|
|
*/
|
|
@IsTest
|
|
static void convertLead_personAccount_noExistingPersonAccount() {
|
|
insert makeConfig(false, false, true, false);
|
|
|
|
Lead openLead = makeOpenLead('123456789', 'ada@example.com');
|
|
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'Person account no-existing-record path completed');
|
|
}
|
|
|
|
/**
|
|
* convertLead: B2B path (Customer_Email_Domain__c = true)
|
|
* existing Contact found by Shopify ID → setContactId called on LeadConvert
|
|
*/
|
|
@IsTest
|
|
static void convertLead_b2b_existingContact() {
|
|
insert makeConfigFull(false, false, false, false, true, false);
|
|
|
|
Account domainAcc = new Account(Name = 'example');
|
|
insert domainAcc;
|
|
|
|
Contact existingCon = new Contact(
|
|
LastName = 'B2BContact',
|
|
AccountId = domainAcc.Id,
|
|
HIC_ShopifySync__Shopify_Id__c = 'Business 123456789',
|
|
Email = 'ada@example.com'
|
|
);
|
|
insert existingCon;
|
|
|
|
Lead openLead = makeOpenLead('123456789', 'ada@example.com');
|
|
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :openLead.Id];
|
|
System.assert(converted.IsConverted, 'B2B Lead should have been converted');
|
|
}
|
|
|
|
/**
|
|
* convertLead: B2B path — no existing Contact, no existing domain Account
|
|
* → domain Account inserted, new Contact created on convert
|
|
*/
|
|
@IsTest
|
|
static void convertLead_b2b_newDomainAccountNewContact() {
|
|
insert makeConfigFull(false, false, false, false, true, false);
|
|
|
|
Lead openLead = makeOpenLead('123456789', 'ada@example.com');
|
|
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :openLead.Id];
|
|
System.assert(converted.IsConverted, 'B2B Lead should be converted with new domain account');
|
|
|
|
List<Account> domainAccounts = [SELECT Id FROM Account WHERE Name = 'example'];
|
|
System.assert(!domainAccounts.isEmpty(), 'Domain account should have been created');
|
|
}
|
|
|
|
/**
|
|
* convertLead: no Lead found for the Shopify ID → falls through to createAccountContact
|
|
*/
|
|
@IsTest
|
|
static void convertLead_noLeadFound_fallsToCreateAccountContact() {
|
|
insert makeConfig(false, true, false, false);
|
|
insertMappings();
|
|
|
|
// No Lead inserted → leadList will be empty
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'convertLead with no Lead record completed without error');
|
|
}
|
|
|
|
/**
|
|
* convertLead: default_address is null → method exits immediately (guard clause)
|
|
*/
|
|
@IsTest
|
|
static void convertLead_nullDefaultAddress_safeExit() {
|
|
insert makeConfig(false, true, false, false);
|
|
|
|
Map<String,Object> cust = new Map<String,Object>{
|
|
'id' => 123456789,
|
|
'first_name' => 'Ada',
|
|
'last_name' => 'Lovelace',
|
|
'email' => 'ada@example.com',
|
|
'orders_count' => 1
|
|
// no default_address key
|
|
};
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(JSON.serialize(cust), STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'Null default_address exits cleanly');
|
|
}
|
|
|
|
/**
|
|
* convertLead: no configuration for store → config is null, falls to Account+Contact path,
|
|
* no Lead found → createAccountContact called
|
|
*/
|
|
@IsTest
|
|
static void convertLead_noConfig_fallsToCreateAccountContact() {
|
|
insertMappings();
|
|
// No config inserted for STORE
|
|
|
|
String payload = shopifyCustomerWithAddress(1, true, 'ada@example.com', 'Test Co', 'Ada', 'Lovelace');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLead(payload, STORE);
|
|
Test.stopTest();
|
|
|
|
System.assert(true, 'No-config convertLead completed without error');
|
|
}
|
|
|
|
/**
|
|
* convertLeadIfAccountExist: direct call — result.isSuccess() path
|
|
* stamps Shopify ID on Contact
|
|
*/
|
|
@IsTest
|
|
static void convertLeadIfAccountExist_directCall_success() {
|
|
Account acc = new Account(Name = 'Test Account');
|
|
insert acc;
|
|
|
|
Lead l = makeOpenLead('999888777', 'direct@test.com');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLeadIfAccountExist(l, acc.Id, null);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :l.Id];
|
|
System.assert(converted.IsConverted);
|
|
}
|
|
|
|
/**
|
|
* convertLeadIfAccountExist: with existing Contact ID provided → setContactId path
|
|
*/
|
|
@IsTest
|
|
static void convertLeadIfAccountExist_withExistingContact() {
|
|
Account acc = new Account(Name = 'Test Account2');
|
|
insert acc;
|
|
|
|
Contact con = new Contact(LastName = 'Existing', AccountId = acc.Id);
|
|
insert con;
|
|
|
|
Lead l = makeOpenLead('111222333', 'existing@test.com');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLeadIfAccountExist(l, acc.Id, con.Id);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :l.Id];
|
|
System.assert(converted.IsConverted);
|
|
}
|
|
|
|
/**
|
|
* convertLeadIfAccountDoesNotExist: direct call — Salesforce creates Account on convert
|
|
*/
|
|
@IsTest
|
|
static void convertLeadIfAccountDoesNotExist_directCall() {
|
|
Lead l = makeOpenLead('444555666', 'new@test.com');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLeadIfAccountDoesNotExist(l);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :l.Id];
|
|
System.assert(converted.IsConverted);
|
|
}
|
|
|
|
/**
|
|
* convertLeadIfPersonAccountExist: direct call
|
|
*/
|
|
@IsTest
|
|
static void convertLeadIfPersonAccountExist_directCall() {
|
|
Account acc = new Account(Name = 'Person Account Stub');
|
|
insert acc;
|
|
|
|
Lead l = makeOpenLead('777888999', 'person@test.com');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLeadIfPersonAccountExist(l, acc.Id);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :l.Id];
|
|
System.assert(converted.IsConverted);
|
|
}
|
|
|
|
/**
|
|
* convertLeadIfPersonAccountDoesNotExist: direct call
|
|
*/
|
|
@IsTest
|
|
static void convertLeadIfPersonAccountDoesNotExist_directCall() {
|
|
Lead l = makeOpenLead('321321321', 'noperson@test.com');
|
|
|
|
Test.startTest();
|
|
UpdateCustomerFromShopify.convertLeadIfPersonAccountDoesNotExist(l);
|
|
Test.stopTest();
|
|
|
|
Lead converted = [SELECT IsConverted FROM Lead WHERE Id = :l.Id];
|
|
System.assert(converted.IsConverted);
|
|
}
|
|
} |