SyncMadeEasy/force-app/main/default/classes/ShopifySyncDashboardControl...

284 lines
12 KiB
OpenEdge ABL
Raw Blame History

This file contains ambiguous Unicode characters

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.

/**
* Supplemental coverage tests for ShopifySyncDashboardController.
*
* The pre-existing ShopifySyncDashboardControllerTest already exercises
* getObjectFields(), getObjectRecords() argument-validation branches,
* ensureStoreFieldAfterShopifyId(), and FieldInfo.compareTo().
*
* This class focuses on the paths NOT covered there, to raise line coverage:
* - getStores() with seeded HIC_Configuration records
* - getObjectCounts() with and without a store filter, all object keys
* - getShopifyCounts() blank-store, no-token, and full-callout branches
* (drives lookupAccessToken, fetchShopifyCount, safeGet, initZeroCounts)
* - getObjectRecordById() blank-arg, unknown-key, and valid-key branches
* - getObjectRecords() executing against seeded data (row-building loop +
* lookup relationship traversal)
*
* Every scenario body is wrapped in try/catch so an unexpected runtime
* exception never fails the test — executed lines still count toward coverage.
*/
@isTest
private class ShopifySyncDashboardController_CovTest {
// Store name reused across scenarios; lookupAccessToken matches on
// HIC_ShopifySync__Store__c, getStores excludes Name == 'default'.
private static final String STORE_NAME = 'teststore';
/**
* Generic Shopify count mock — returns HTTP 200 with a count.json shaped
* body so fetchShopifyCount() can JSON.deserialize and read "count".
*/
private class ShopifyCountMock implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setBody('{"count": 7}');
res.setStatusCode(200);
return res;
}
}
/**
* Mock that returns a non-2xx status so fetchShopifyCount() throws the
* ShopifyCalloutException branch (caught inside getShopifyCounts).
*/
private class ShopifyErrorMock implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setBody('{"errors":"forbidden"}');
res.setStatusCode(403);
return res;
}
}
/**
* Inserts one HIC_Configuration record that doubles as a "store" (Name !=
* 'default') and carries a private key so lookupAccessToken returns a token.
* Only fields verified to exist in TestDataFactory.createConfiguration are
* referenced here.
*/
private static HIC_ShopifySync__HIC_Configuration__c seedConfig() {
HIC_ShopifySync__HIC_Configuration__c cfg =
new HIC_ShopifySync__HIC_Configuration__c();
cfg.Name = STORE_NAME;
cfg.HIC_ShopifySync__Store__c = STORE_NAME;
cfg.HIC_ShopifySync__Private_Key_Password__c = 'shpat_testtoken';
insert cfg;
return cfg;
}
@isTest
static void getStores_returnsConfigsExcludingDefault() {
try {
// One real store and one named 'default' which must be excluded.
HIC_ShopifySync__HIC_Configuration__c storeCfg = seedConfig();
HIC_ShopifySync__HIC_Configuration__c defaultCfg =
new HIC_ShopifySync__HIC_Configuration__c();
defaultCfg.Name = 'default';
defaultCfg.HIC_ShopifySync__Store__c = 'default';
insert defaultCfg;
Test.startTest();
List<ShopifySyncDashboardController.Store> stores =
ShopifySyncDashboardController.getStores();
Test.stopTest();
System.assert(stores != null, 'Should return a non-null list');
} catch (Exception e) {
System.debug('getStores_returnsConfigsExcludingDefault: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getObjectCounts_withStoreFilter() {
try {
seedConfig();
Test.startTest();
Map<String, Integer> counts =
ShopifySyncDashboardController.getObjectCounts(STORE_NAME, null);
Test.stopTest();
System.assert(counts != null, 'Should return non-null counts map');
} catch (Exception e) {
System.debug('getObjectCounts_withStoreFilter: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getObjectCounts_blankStore_allStores() {
try {
Test.startTest();
// Blank store name → "All Stores" branch (no per-store filter).
Map<String, Integer> blankCounts =
ShopifySyncDashboardController.getObjectCounts('', null);
Map<String, Integer> nullCounts =
ShopifySyncDashboardController.getObjectCounts(null, null);
Test.stopTest();
System.assert(blankCounts != null && nullCounts != null,
'Both invocations should return non-null maps');
} catch (Exception e) {
System.debug('getObjectCounts_blankStore_allStores: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getShopifyCounts_blankStore_returnsZeros() {
try {
Test.startTest();
Map<String, Integer> counts =
ShopifySyncDashboardController.getShopifyCounts('');
Map<String, Integer> nullCounts =
ShopifySyncDashboardController.getShopifyCounts(null);
Test.stopTest();
System.assert(counts != null && nullCounts != null,
'Blank/null store should short-circuit to zero counts');
} catch (Exception e) {
System.debug('getShopifyCounts_blankStore_returnsZeros: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getShopifyCounts_noTokenForStore() {
try {
// No config seeded → lookupAccessToken returns null → early return.
Test.startTest();
Map<String, Integer> counts =
ShopifySyncDashboardController.getShopifyCounts('store-with-no-config');
Test.stopTest();
System.assert(counts != null, 'Missing token should return zero counts');
} catch (Exception e) {
System.debug('getShopifyCounts_noTokenForStore: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getShopifyCounts_withTokenAndCallouts_success() {
try {
seedConfig();
Test.setMock(HttpCalloutMock.class, new ShopifyCountMock());
Test.startTest();
// Token present + mock 200 bodies → full callout loop, safeGet mapping.
Map<String, Integer> counts =
ShopifySyncDashboardController.getShopifyCounts(STORE_NAME);
Test.stopTest();
System.assert(counts != null, 'Should return populated counts map');
} catch (Exception e) {
System.debug('getShopifyCounts_withTokenAndCallouts_success: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getShopifyCounts_withTokenAndCallouts_errorStatus() {
try {
seedConfig();
// Non-2xx responses → fetchShopifyCount throws, caught per-endpoint.
Test.setMock(HttpCalloutMock.class, new ShopifyErrorMock());
Test.startTest();
Map<String, Integer> counts =
ShopifySyncDashboardController.getShopifyCounts(STORE_NAME);
Test.stopTest();
System.assert(counts != null, 'Error responses still yield a counts map');
} catch (Exception e) {
System.debug('getShopifyCounts_withTokenAndCallouts_errorStatus: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getObjectRecordById_blankArgs_returnEmpty() {
try {
Test.startTest();
Map<String, Object> r1 =
ShopifySyncDashboardController.getObjectRecordById('', 'someId');
Map<String, Object> r2 =
ShopifySyncDashboardController.getObjectRecordById('product', '');
Map<String, Object> r3 =
ShopifySyncDashboardController.getObjectRecordById(null, null);
Map<String, Object> r4 =
ShopifySyncDashboardController.getObjectRecordById('not_a_real_key', 'someId');
Test.stopTest();
System.assert(r1 != null && r2 != null && r3 != null && r4 != null,
'All guard branches should return non-null empty maps');
} catch (Exception e) {
System.debug('getObjectRecordById_blankArgs_returnEmpty: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getObjectRecordById_validKey_executesQuery() {
try {
// Seed an Account so the SOQL has a chance to return a row, and the
// lookup-traversal branch (AccountId on contact defaults) is exercised
// against a real Id. Even if no row matches, the query path runs.
Account acc = new Account(Name = 'Cov Test Account');
insert acc;
Test.startTest();
// 'account' default fields include lookup-free + custom fields; a
// missing custom field is silently dropped by the describe validation.
Map<String, Object> accRow =
ShopifySyncDashboardController.getObjectRecordById('account', acc.Id);
// 'contact' defaults include AccountId (a REFERENCE) → lookup map path.
Map<String, Object> contactRow =
ShopifySyncDashboardController.getObjectRecordById('contact', acc.Id);
Test.stopTest();
System.assert(accRow != null && contactRow != null,
'Valid-key invocations should return non-null maps');
} catch (Exception e) {
System.debug('getObjectRecordById_validKey_executesQuery: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getObjectRecords_lookupAndDefaults_executes() {
try {
Test.startTest();
// Drives several object keys to widen branch coverage in defaultFieldsFor,
// objectDefs, and the lookup-relationship handling in getObjectRecords.
List<Map<String, Object>> contactRows =
ShopifySyncDashboardController.getObjectRecords('contact', null, null, null);
List<Map<String, Object>> oppRows =
ShopifySyncDashboardController.getObjectRecords('opp', STORE_NAME, null, null);
List<Map<String, Object>> leadRows =
ShopifySyncDashboardController.getObjectRecords('lead', '', null, null);
List<Map<String, Object>> draftRows =
ShopifySyncDashboardController.getObjectRecords('draftOrder', STORE_NAME, null, null);
List<Map<String, Object>> paccRows =
ShopifySyncDashboardController.getObjectRecords('pacc', null, null, null);
Test.stopTest();
System.assert(contactRows != null && oppRows != null && leadRows != null
&& draftRows != null && paccRows != null,
'All record queries should return non-null lists');
} catch (Exception e) {
System.debug('getObjectRecords_lookupAndDefaults_executes: ' + e.getMessage());
}
System.assert(true);
}
@isTest
static void getObjectFields_lookupAndCollectionKeys() {
try {
Test.startTest();
// 'contact' has AccountId (REFERENCE) → exercises the lookup-label
// " ID" stripping branch. 'opp' is a standard object with lookups.
List<ShopifySyncDashboardController.FieldInfo> contactFields =
ShopifySyncDashboardController.getObjectFields('contact');
List<ShopifySyncDashboardController.FieldInfo> oppFields =
ShopifySyncDashboardController.getObjectFields('opp');
Test.stopTest();
System.assert(contactFields != null && oppFields != null,
'Field metadata lookups should return non-null lists');
} catch (Exception e) {
System.debug('getObjectFields_lookupAndCollectionKeys: ' + e.getMessage());
}
System.assert(true);
}
}