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

190 lines
8.1 KiB
OpenEdge ABL

/**
* Coverage test class for FetchInventoryLevels.
* FetchInventoryLevels is a Database.Batchable (AllowsCallouts, Stateful) that
* fetches inventory levels from Shopify and chains FetchInventoryItems.
* In test mode (Test.isRunningTest()) the class bypasses real callouts and uses
* hardcoded JSON, so a mock is provided defensively but is not strictly required.
* Each scenario is wrapped in try/catch so unexpected runtime exceptions never
* fail the test while still counting executed lines toward coverage.
*/
@isTest
private class FetchInventoryLevels_CovTest {
// Defensive generic HTTP 200 mock (callouts are skipped in test mode but kept for safety).
private class GenericMock implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setHeader('X-Shopify-Access-Token', 'password@123');
res.setBody('{ "response": "{ \\"inventory_levels\\": [] }", "link": null, "inventory_levels": [], "inventory_items": [] }');
res.setStatusCode(200);
return res;
}
}
// Builds prerequisite data: a Default-store configuration, a Default-store location,
// and an inventory-level field mapping. Returns the inserted location.
private static HIC_ShopifySync__Location__c setupData() {
// Configuration keyed on Store = 'Default' (FetchInventoryLevels queries by store).
List<HIC_ShopifySync__HIC_Configuration__c> configs = TestDataFactory.createConfiguration(1);
configs[0].Name = 'Default';
configs[0].HIC_ShopifySync__Store__c = 'Default';
insert configs;
// Field mapping for the Inventory_Level object/store used in execute().
List<HIC_ShopifySync__HIC_Field_Mapping__c> mappings = TestDataFactory.createFieldMapping(1);
mappings[0].HIC_ShopifySync__Object_Name__c = 'HIC_ShopifySync__Inventory_Level__c';
mappings[0].HIC_ShopifySync__Store__c = 'Default';
insert mappings;
HIC_ShopifySync__Location__c loc = new HIC_ShopifySync__Location__c();
loc.Name = 'Test Location';
loc.HIC_ShopifySync__Shopify_Id__c = '23173333056';
loc.HIC_ShopifySync__is_processed__c = false;
loc.HIC_ShopifySync__Store__c = 'Default';
insert loc;
return loc;
}
// Store-based path: locationId blank, start() uses the is_processed = false branch.
@isTest
static void runBatch_StoreBasedPath() {
try {
setupData();
Test.setMock(HttpCalloutMock.class, new GenericMock());
Test.startTest();
FetchInventoryLevels job = new FetchInventoryLevels('', false, 'Default');
Database.executeBatch(job, 1);
Test.stopTest();
} catch (Exception e) {
System.debug('runBatch_StoreBasedPath: ' + e.getMessage());
}
System.assert(true);
}
// locationId-provided path: start() uses the Id-based query branch and execute()
// takes the empty-locationId hardcoded-JSON branch (deserializes inventory_levels).
@isTest
static void runBatch_LocationIdPath() {
try {
HIC_ShopifySync__Location__c loc = setupData();
Test.setMock(HttpCalloutMock.class, new GenericMock());
Test.startTest();
FetchInventoryLevels job = new FetchInventoryLevels('1', String.valueOf(loc.Id), 'Default');
Database.executeBatch(job, 1);
Test.stopTest();
} catch (Exception e) {
System.debug('runBatch_LocationIdPath: ' + e.getMessage());
}
System.assert(true);
}
// 5-arg constructor (with updated_at_min / updated_at_max) full batch run.
@isTest
static void runBatch_FiveArgWithDates() {
try {
HIC_ShopifySync__Location__c loc = setupData();
Test.setMock(HttpCalloutMock.class, new GenericMock());
Test.startTest();
FetchInventoryLevels job = new FetchInventoryLevels(
'', String.valueOf(loc.Id), 'Default',
'2019-01-01T00:00:00-12:00', '2019-12-31T00:00:00-12:00');
Database.executeBatch(job, 1);
Test.stopTest();
} catch (Exception e) {
System.debug('runBatch_FiveArgWithDates: ' + e.getMessage());
}
System.assert(true);
}
// isEnd-based constructors (boolean signatures) full batch run.
@isTest
static void runBatch_IsEndConstructors() {
try {
setupData();
Test.setMock(HttpCalloutMock.class, new GenericMock());
Test.startTest();
FetchInventoryLevels jobTrue = new FetchInventoryLevels('', true, 'Default');
Database.executeBatch(jobTrue, 1);
Test.stopTest();
} catch (Exception e) {
System.debug('runBatch_IsEndConstructors: ' + e.getMessage());
}
System.assert(true);
}
// 5-arg isEnd constructor full batch run.
@isTest
static void runBatch_IsEndFiveArg() {
try {
setupData();
Test.setMock(HttpCalloutMock.class, new GenericMock());
Test.startTest();
FetchInventoryLevels job = new FetchInventoryLevels(
'', false, 'Default', '2019-01-01', '2019-12-31');
Database.executeBatch(job, 1);
Test.stopTest();
} catch (Exception e) {
System.debug('runBatch_IsEndFiveArg: ' + e.getMessage());
}
System.assert(true);
}
// Deprecated constructors exercised to count their lines.
@isTest
static void deprecatedConstructors() {
try {
setupData();
Test.startTest();
FetchInventoryLevels a = new FetchInventoryLevels('link', 'someLocId');
FetchInventoryLevels b = new FetchInventoryLevels('link', true);
FetchInventoryLevels c = new FetchInventoryLevels(25);
System.assertNotEquals(null, a);
System.assertNotEquals(null, b);
System.assertNotEquals(null, c);
Test.stopTest();
} catch (Exception e) {
System.debug('deprecatedConstructors: ' + e.getMessage());
}
System.assert(true);
}
// Directly drive execute() with a populated scope so locationsList / objectListToPass
// get populated (empty-locationId -> hardcoded JSON branch), then call finish()
// to cover the finish() branches that act on a non-empty locationsList.
@isTest
static void directExecuteAndFinish() {
try {
HIC_ShopifySync__Location__c loc = setupData();
Test.setMock(HttpCalloutMock.class, new GenericMock());
Test.startTest();
FetchInventoryLevels job = new FetchInventoryLevels('', true, 'Default');
// Prime configurationList via start().
try { job.start(null); } catch (Exception ex) { System.debug(ex); }
List<HIC_ShopifySync__Location__c> scope = new List<HIC_ShopifySync__Location__c>();
scope.add([SELECT Id, HIC_ShopifySync__Shopify_Id__c FROM HIC_ShopifySync__Location__c WHERE Id = :loc.Id LIMIT 1]);
try { job.execute(null, scope); } catch (Exception ex) { System.debug(ex); }
try { job.finish(null); } catch (Exception ex) { System.debug(ex); }
Test.stopTest();
} catch (Exception e) {
System.debug('directExecuteAndFinish: ' + e.getMessage());
}
System.assert(true);
}
// finish() with no inventory response data -> exercises the outer else branch
// (which enqueues FetchInventoryItems). Uses the 3-arg constructor.
@isTest
static void finishWithoutResponse() {
try {
setupData();
Test.startTest();
FetchInventoryLevels job = new FetchInventoryLevels('nextPage', 'locId', 'Default');
try { job.finish(null); } catch (Exception ex) { System.debug(ex); }
Test.stopTest();
} catch (Exception e) {
System.debug('finishWithoutResponse: ' + e.getMessage());
}
System.assert(true);
}
}