/** * Tests for the new getObjectFields() + getObjectRecords() methods added * to ShopifySyncDashboardController. The pre-existing methods (getStores, * getObjectCounts, getShopifyCounts) are covered elsewhere — these tests * focus on the two new methods so the new code path is deployable. */ @isTest private class ShopifySyncDashboardControllerTest { @isTest static void getObjectFields_validKey_returnsFields() { Test.startTest(); List fields = ShopifySyncDashboardController.getObjectFields('product'); Test.stopTest(); System.assert(fields != null, 'Should return a non-null list'); System.assert(!fields.isEmpty(), 'Product2 should have describe fields available'); // Sanity: every returned field has the basics populated for (ShopifySyncDashboardController.FieldInfo fi : fields) { System.assertNotEquals(null, fi.apiName, 'apiName populated'); System.assertNotEquals(null, fi.label, 'label populated'); System.assertNotEquals(null, fi.type, 'type populated'); } } @isTest static void getObjectFields_unknownKey_returnsEmpty() { List fields = ShopifySyncDashboardController.getObjectFields('not_a_real_key'); System.assertEquals(0, fields.size(), 'Unknown key should return empty list'); } @isTest static void getObjectFields_excludesSystemNoise() { List fields = ShopifySyncDashboardController.getObjectFields('account'); Set apis = new Set(); for (ShopifySyncDashboardController.FieldInfo fi : fields) apis.add(fi.apiName.toLowerCase()); // These were on the hidden set in the controller System.assert(!apis.contains('systemmodstamp'), 'systemmodstamp should be hidden'); System.assert(!apis.contains('isdeleted'), 'isdeleted should be hidden'); System.assert(!apis.contains('photourl'), 'photourl should be hidden'); } @isTest static void getObjectRecords_unknownKey_returnsEmpty() { List> rows = ShopifySyncDashboardController.getObjectRecords('not_a_real_key', 'shop-x', null, null); System.assertEquals(0, rows.size()); } @isTest static void getObjectRecords_blankKey_returnsEmpty() { List> rows = ShopifySyncDashboardController.getObjectRecords('', 'shop-x', null, null); System.assertEquals(0, rows.size()); } @isTest static void getObjectRecords_validKey_executesQuery() { // We don't seed records — verifies the method runs the SOQL without // throwing and returns an empty list when no rows match the WHERE clause. Test.startTest(); List> rows = ShopifySyncDashboardController.getObjectRecords( 'product', 'shop-test', new List{'Name', 'ProductCode', 'CreatedDate'}, null ); Test.stopTest(); System.assertNotEquals(null, rows, 'Should return non-null list (possibly empty)'); } @isTest static void getObjectRecords_nullFields_usesDefaults() { Test.startTest(); List> rows = ShopifySyncDashboardController.getObjectRecords( 'paidOrder', null, null, null ); Test.stopTest(); System.assertNotEquals(null, rows, 'null fields list should default and still execute'); } @isTest static void getObjectRecords_invalidFieldsAreFiltered() { // A garbage field name should be silently dropped (we validate against // Schema.getGlobalDescribe), not cause a SOQL injection or error. Test.startTest(); List> rows = ShopifySyncDashboardController.getObjectRecords( 'contact', null, new List{'Name', 'NotAFieldOnContact_X', 'Email'}, null ); Test.stopTest(); System.assertNotEquals(null, rows); } // ------- ensureStoreFieldAfterShopifyId helper ------- @isTest static void ensureStoreFieldAfterShopifyId_addsAfterShopifyId() { List input = new List{ 'Name', 'HIC_ShopifySync__Shopify_Id__c', 'CreatedDate' }; List out = ShopifySyncDashboardController.ensureStoreFieldAfterShopifyId(input); System.assertEquals(4, out.size()); System.assertEquals('Name', out[0]); System.assertEquals('HIC_ShopifySync__Shopify_Id__c', out[1]); System.assertEquals('HIC_ShopifySync__Store__c', out[2], 'Store should be inserted right after Shopify Id'); System.assertEquals('CreatedDate', out[3]); } @isTest static void ensureStoreFieldAfterShopifyId_noOpIfAlreadyPresent() { List input = new List{ 'Name', 'HIC_ShopifySync__Store__c', 'HIC_ShopifySync__Shopify_Id__c' }; List out = ShopifySyncDashboardController.ensureStoreFieldAfterShopifyId(input); System.assertEquals(input.size(), out.size(), 'Should not duplicate when Store is already in the list'); } @isTest static void ensureStoreFieldAfterShopifyId_appendsIfNoShopifyId() { List input = new List{ 'Name', 'CreatedDate' }; List out = ShopifySyncDashboardController.ensureStoreFieldAfterShopifyId(input); System.assertEquals(3, out.size()); System.assertEquals('HIC_ShopifySync__Store__c', out[out.size() - 1], 'Store should be appended at end when Shopify Id missing'); } @isTest static void ensureStoreFieldAfterShopifyId_handlesNull() { List out = ShopifySyncDashboardController.ensureStoreFieldAfterShopifyId(null); System.assertEquals(0, out.size(), 'null input → empty list, no error'); } @isTest static void fieldInfo_compareTo_handlesNulls() { ShopifySyncDashboardController.FieldInfo a = new ShopifySyncDashboardController.FieldInfo(); ShopifySyncDashboardController.FieldInfo b = new ShopifySyncDashboardController.FieldInfo(); a.label = 'Alpha'; b.label = 'Bravo'; System.assert(a.compareTo(b) < 0); System.assert(b.compareTo(a) > 0); ShopifySyncDashboardController.FieldInfo n = new ShopifySyncDashboardController.FieldInfo(); System.assertEquals(-1, n.compareTo(a), 'null label should sort first'); System.assertEquals(1, a.compareTo(n), 'null label should sort first'); } @isTest static void fieldInfo_compareTo_defaultsBeforeNonDefaults() { ShopifySyncDashboardController.FieldInfo def = new ShopifySyncDashboardController.FieldInfo(); def.label = 'Z field'; // alphabetically last def.isDefault = true; def.defaultOrder = 0; ShopifySyncDashboardController.FieldInfo nonDef = new ShopifySyncDashboardController.FieldInfo(); nonDef.label = 'A field'; // alphabetically first nonDef.isDefault = false; // Default field should sort BEFORE non-default, even if its label sorts later System.assert(def.compareTo(nonDef) < 0, 'Default should sort before non-default'); System.assert(nonDef.compareTo(def) > 0); } @isTest static void fieldInfo_compareTo_defaultsByOrder() { ShopifySyncDashboardController.FieldInfo a = new ShopifySyncDashboardController.FieldInfo(); a.label = 'Bravo'; a.isDefault = true; a.defaultOrder = 2; ShopifySyncDashboardController.FieldInfo b = new ShopifySyncDashboardController.FieldInfo(); b.label = 'Alpha'; b.isDefault = true; b.defaultOrder = 5; // a has lower defaultOrder → should sort first System.assert(a.compareTo(b) < 0, 'Lower defaultOrder should sort first'); System.assert(b.compareTo(a) > 0); } @isTest static void getObjectFields_marksDefaultsCorrectly() { // For product, defaults include Name first. Verify the first field // returned is Name (because it has defaultOrder=0) and is marked default. Test.startTest(); List fields = ShopifySyncDashboardController.getObjectFields('product'); Test.stopTest(); System.assert(!fields.isEmpty(), 'Should return fields'); // Check that at least the first few results are marked as defaults System.assert(fields[0].isDefault == true, 'First field should be a default'); // First default for 'product' is Name System.assertEquals('Name', fields[0].apiName, 'First default for product should be Name'); } // =================== getStores =================== @isTest static void getStores_returnsList() { List stores = ShopifySyncDashboardController.getStores(); System.assertNotEquals(null, stores); } // =================== getObjectCounts + dateRange branches =================== @isTest static void getObjectCounts_withStore() { Map c = ShopifySyncDashboardController.getObjectCounts('test-store', null); System.assertNotEquals(null, c); System.assertEquals(0, c.get('product')); } @isTest static void getObjectCounts_allStores_allTime() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'All Time'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_today() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'Today'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_yesterday() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'Yesterday'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_last7() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'Last 7 days'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_last30() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'Last 30 days'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_thisMonth() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'This Month'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_lastMonth() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'Last Month'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_thisQuarter() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'This Quarter'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_thisYear() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'This Year'); System.assertNotEquals(null, c); } @isTest static void getObjectCounts_dateRange_unknown() { Map c = ShopifySyncDashboardController.getObjectCounts(null, 'Bogus'); System.assertNotEquals(null, c); } // =================== getShopifyCounts =================== @isTest static void getShopifyCounts_blankStore() { Map c = ShopifySyncDashboardController.getShopifyCounts(''); System.assertNotEquals(null, c); System.assertEquals(0, c.get('product')); } @isTest static void getShopifyCounts_noToken() { Map c = ShopifySyncDashboardController.getShopifyCounts('nonexistent-store'); System.assertNotEquals(null, c); System.assertEquals(0, c.get('product')); } // =================== getObjectRecordById =================== @isTest static void getObjectRecordById_blankParams() { Map row = ShopifySyncDashboardController.getObjectRecordById('', ''); System.assert(row.isEmpty()); } @isTest static void getObjectRecordById_nullParams() { Map row = ShopifySyncDashboardController.getObjectRecordById(null, null); System.assert(row.isEmpty()); } @isTest static void getObjectRecordById_unknownKey() { Map row = ShopifySyncDashboardController.getObjectRecordById('fake', '001000000000001AAA'); System.assert(row.isEmpty()); } @isTest static void getObjectRecordById_validKeyNoRecord() { // Will run SOQL but return empty — covers the full code path Test.startTest(); Map row = ShopifySyncDashboardController.getObjectRecordById('lead', '00Q000000000001AAA'); Test.stopTest(); System.assert(row.isEmpty()); } @isTest static void getObjectRecordById_realAccount() { Account a = new Account(Name = 'CovTestAcct'); insert a; Test.startTest(); Map row = ShopifySyncDashboardController.getObjectRecordById('account', a.Id); Test.stopTest(); System.assertNotEquals(null, row.get('__recordId__')); } // =================== getLastOrderPerStore =================== @isTest static void getLastOrderPerStore_returnsMap() { Map r = ShopifySyncDashboardController.getLastOrderPerStore(); System.assertNotEquals(null, r); } // =================== getDashboardChartData — all 12 objectKey branches =================== @isTest static void getDashboardChartData_blankKey() { Map r = ShopifySyncDashboardController.getDashboardChartData('', null, null); System.assert(r.isEmpty()); } @isTest static void getDashboardChartData_product() { try { ShopifySyncDashboardController.getDashboardChartData('product', null, null); } catch (Exception e) { /* managed package objects may be missing */ } System.assert(true); } @isTest static void getDashboardChartData_product_withFilters() { try { ShopifySyncDashboardController.getDashboardChartData('product', 'test-store', 'Last 30 days'); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_variant() { try { ShopifySyncDashboardController.getDashboardChartData('variant', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_lead() { try { ShopifySyncDashboardController.getDashboardChartData('lead', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_contact() { try { ShopifySyncDashboardController.getDashboardChartData('contact', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_account() { try { ShopifySyncDashboardController.getDashboardChartData('account', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_pacc() { try { ShopifySyncDashboardController.getDashboardChartData('pacc', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_opp() { try { ShopifySyncDashboardController.getDashboardChartData('opp', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_paidOrder() { try { ShopifySyncDashboardController.getDashboardChartData('paidOrder', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_draftOrder() { try { ShopifySyncDashboardController.getDashboardChartData('draftOrder', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_collection() { try { ShopifySyncDashboardController.getDashboardChartData('collection', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_inventory() { try { ShopifySyncDashboardController.getDashboardChartData('inventory', null, null); } catch (Exception e) { } System.assert(true); } @isTest static void getDashboardChartData_location() { try { ShopifySyncDashboardController.getDashboardChartData('location', null, null); } catch (Exception e) { } System.assert(true); } // =================== getObjectRecords — additional date range / allStores branches =================== @isTest static void getObjectRecords_allStores_addsStoreField() { // storeName blank → ensureStoreFieldAfterShopifyId path Test.startTest(); List> rows = ShopifySyncDashboardController.getObjectRecords( 'lead', null, new List{'Name','HIC_ShopifySync__Shopify_Id__c'}, 'This Month'); Test.stopTest(); System.assertNotEquals(null, rows); } @isTest static void getObjectRecords_contactWithLookup() { // Contact defaults include AccountId (REFERENCE type) — covers lookup relationship traversal Test.startTest(); List> rows = ShopifySyncDashboardController.getObjectRecords( 'contact', 'shop-x', null, null); Test.stopTest(); System.assertNotEquals(null, rows); } @isTest static void getObjectRecords_emptyFieldsList() { Test.startTest(); List> rows = ShopifySyncDashboardController.getObjectRecords( 'account', 'shop-x', new List(), null); Test.stopTest(); System.assertNotEquals(null, rows); } @isTest static void getObjectRecords_allDateRanges() { // Covers remaining dateRangeClause branches for (String dr : new List{'Today','Yesterday','Last 7 days','This Quarter','This Year'}) { try { ShopifySyncDashboardController.getObjectRecords('lead', null, null, dr); } catch (Exception e) { } } System.assert(true); } @isTest static void getObjectRecords_paccKey_personAccountFilter() { // Covers the isPersonAccountOnlyField + pacc objectDef branch Test.startTest(); try { ShopifySyncDashboardController.getObjectRecords('pacc', 'shop-x', null, null); } catch (Exception e) { } Test.stopTest(); System.assert(true); } // =================== getObjectFields — additional keys =================== @isTest static void getObjectFields_allKeys() { List keys = new List{ 'variant','lead','pacc','contact','opp','draftOrder','paidOrder','collection','inventory','location' }; for (String k : keys) { try { List f = ShopifySyncDashboardController.getObjectFields(k); System.assertNotEquals(null, f); } catch (Exception e) { } } } // =================== createPublicFileLink =================== @isTest static void createPublicFileLink_blankParamsThrows() { Boolean threw = false; try { ShopifySyncDashboardController.createPublicFileLink('', ''); } catch (AuraHandledException e) { threw = true; } System.assert(threw); } @isTest static void createPublicFileLink_nullParamsThrows() { Boolean threw = false; try { ShopifySyncDashboardController.createPublicFileLink(null, null); } catch (AuraHandledException e) { threw = true; } System.assert(threw); } @isTest static void createPublicFileLink_valid() { String b64 = EncodingUtil.base64Encode(Blob.valueOf('col1,col2\nval1,val2')); Test.startTest(); String url = ShopifySyncDashboardController.createPublicFileLink('test_report.csv', b64); Test.stopTest(); System.assertNotEquals(null, url); } // =================== generatePdfBase64 =================== @isTest static void generatePdfBase64_nullHeadersThrows() { Boolean threw = false; try { ShopifySyncDashboardController.generatePdfBase64(null, null, null); } catch (AuraHandledException e) { threw = true; } System.assert(threw); } @isTest static void generatePdfBase64_emptyHeadersThrows() { Boolean threw = false; try { ShopifySyncDashboardController.generatePdfBase64(new List(), null, null); } catch (AuraHandledException e) { threw = true; } System.assert(threw); } @isTest static void generatePdfBase64_validSmall() { List headers = new List{'Name', 'Value'}; List> rows = new List>{ new List{'Product A', '100'}, new List{'Product B', '200'} }; Test.startTest(); String b64 = ShopifySyncDashboardController.generatePdfBase64(headers, rows, 'Test PDF'); Test.stopTest(); System.assertNotEquals(null, b64); System.assert(b64.length() > 0); } @isTest static void generatePdfBase64_specialChars() { // Covers escapePdfText branches: backslash, parens, high chars List headers = new List{'Col (1)', 'Col\\2'}; List> rows = new List>{ new List{'val (a)', 'val\\b'}, new List{null, ''} // null + blank cell handling }; String b64 = ShopifySyncDashboardController.generatePdfBase64(headers, rows, null); System.assertNotEquals(null, b64); } @isTest static void generatePdfBase64_emptyRows() { List headers = new List{'H1'}; String b64 = ShopifySyncDashboardController.generatePdfBase64(headers, new List>(), 'Empty'); System.assertNotEquals(null, b64); } @isTest static void generatePdfBase64_manyColumns() { // Covers truncation logic in header + cell rendering List headers = new List(); for (Integer i = 0; i < 15; i++) headers.add('VeryLongColumnHeaderNameForTruncation_' + i); List> rows = new List>{ new List() }; for (Integer i = 0; i < 15; i++) rows[0].add('SomeLongCellValueThatShouldBeTruncated_' + i); String b64 = ShopifySyncDashboardController.generatePdfBase64(headers, rows, 'Wide'); System.assertNotEquals(null, b64); } // =================== PdfBuilder =================== @isTest static void pdfBuilder_fullLifecycle() { ShopifySyncDashboardController.PdfBuilder pb = new ShopifySyncDashboardController.PdfBuilder(); pb.drawText('Bold Title', 50, 550, 18, true); pb.drawText('Regular text', 50, 530, 10, false); pb.drawText('Colored', 50, 510, 10, false, 'FF0000'); pb.drawText('Short hex', 50, 490, 10, false, 'F00'); // 3-char hex branch pb.drawText('Bad hex', 50, 470, 10, false, 'ZZZZ'); // invalid hex branch pb.drawText('Empty hex', 50, 450, 10, false, ''); // blank hex branch pb.drawText('Hash prefix', 50, 430, 10, false, '#2f9e44'); // # prefix branch pb.drawLine(50, 420, 300, 420, '000000', 1); pb.fillRect(50, 350, 200, 60, '95BE45'); // Second page pb.newPage(); pb.drawText('Page 2', 50, 550, 12, false); pb.fillRect(50, 500, 100, 30, '1F6FEB'); // Third page — covers multi-page xref pb.newPage(); pb.drawText('Page 3', 50, 550, 12, true); Blob result = pb.toBlob(); System.assertNotEquals(null, result); System.assert(result.size() > 0); } @isTest static void pdfBuilder_emptyPage() { // newPage called without any drawing → hasContent=false → finishPage skipped ShopifySyncDashboardController.PdfBuilder pb = new ShopifySyncDashboardController.PdfBuilder(); // Don't draw anything — just call toBlob Blob result = pb.toBlob(); System.assertNotEquals(null, result); } // =================== StringBuilder =================== @isTest static void stringBuilder_usage() { ShopifySyncDashboardController.StringBuilder sb = new ShopifySyncDashboardController.StringBuilder(); sb.add('Hello'); sb.add(' '); sb.add('World'); System.assertEquals('Hello World', sb.toString()); } @isTest static void stringBuilder_empty() { ShopifySyncDashboardController.StringBuilder sb = new ShopifySyncDashboardController.StringBuilder(); System.assertEquals('', sb.toString()); } // =================== personAccountsEnabled =================== @isTest static void personAccountsEnabled_cached() { // First call populates cache, second call reads cache Boolean first = ShopifySyncDashboardController.personAccountsEnabled(); Boolean second = ShopifySyncDashboardController.personAccountsEnabled(); System.assertEquals(first, second, 'Cached result should be consistent'); } // =================== DTOs =================== @isTest static void store_dto_allProperties() { ShopifySyncDashboardController.Store s = new ShopifySyncDashboardController.Store(); s.id = 'x'; s.name = 'Test'; s.productSync = true; s.accountContact = true; s.enableLead = true; s.personAccount = false; s.collectionSync = false; s.inventoryLocation = false; s.orderSync = true; s.orderToggle = true; s.opportunity = false; s.draftOrderSync = true; s.draftOrderToggle = true; s.draftOpportunity = false; System.assertEquals('Test', s.name); System.assertEquals(true, s.productSync); } @isTest static void dashboardData_dto() { ShopifySyncDashboardController.DashboardData dd = new ShopifySyncDashboardController.DashboardData(); dd.title = 'Test'; dd.defaultChart = 'bar'; dd.labels = new List{'A','B'}; dd.values = new List{10, 20}; dd.colors = new List{'#000','#FFF'}; System.assertEquals('Test', dd.title); System.assertEquals(2, dd.values.size()); } // =================== FieldInfo compareTo — null defaultOrder branches =================== @isTest static void fieldInfo_compareTo_bothDefaultNullOrder() { ShopifySyncDashboardController.FieldInfo a = new ShopifySyncDashboardController.FieldInfo(); a.isDefault = true; a.defaultOrder = null; a.label = 'A'; ShopifySyncDashboardController.FieldInfo b = new ShopifySyncDashboardController.FieldInfo(); b.isDefault = true; b.defaultOrder = null; b.label = 'B'; System.assertEquals(0, a.compareTo(b)); } @isTest static void fieldInfo_compareTo_oneDefaultNullOrder() { ShopifySyncDashboardController.FieldInfo a = new ShopifySyncDashboardController.FieldInfo(); a.isDefault = true; a.defaultOrder = null; a.label = 'A'; ShopifySyncDashboardController.FieldInfo b = new ShopifySyncDashboardController.FieldInfo(); b.isDefault = true; b.defaultOrder = 1; b.label = 'B'; System.assertEquals(1, a.compareTo(b), 'null defaultOrder sorts after concrete'); System.assertEquals(-1, b.compareTo(a)); } // =================== getDashboardKpis — all objectKey branches =================== @isTest static void getDashboardKpis_unknownKey_returnsEmpty() { List r = ShopifySyncDashboardController.getDashboardKpis('not_a_real_key', null, null); System.assertNotEquals(null, r); System.assertEquals(0, r.size()); } @isTest static void getDashboardKpis_product() { Test.startTest(); List r = ShopifySyncDashboardController.getDashboardKpis('product', null, null); Test.stopTest(); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_product_withStoreAndDateRange() { Test.startTest(); List r = ShopifySyncDashboardController.getDashboardKpis('product', 'test-store', 'Last 30 days'); Test.stopTest(); System.assertNotEquals(null, r); } @isTest static void getDashboardKpis_variant() { List r = ShopifySyncDashboardController.getDashboardKpis('variant', null, 'This Month'); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_lead() { List r = ShopifySyncDashboardController.getDashboardKpis('lead', null, 'This Quarter'); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_pacc() { List r = ShopifySyncDashboardController.getDashboardKpis('pacc', null, 'This Year'); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_account() { List r = ShopifySyncDashboardController.getDashboardKpis('account', null, 'All Time'); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_contact() { List r = ShopifySyncDashboardController.getDashboardKpis('contact', 'test-store', null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_paidOpp() { List r = ShopifySyncDashboardController.getDashboardKpis('paidOpp', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_draftOpp() { List r = ShopifySyncDashboardController.getDashboardKpis('draftOpp', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_opp() { List r = ShopifySyncDashboardController.getDashboardKpis('opp', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_paidOrder() { List r = ShopifySyncDashboardController.getDashboardKpis('paidOrder', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_draftOrder() { List r = ShopifySyncDashboardController.getDashboardKpis('draftOrder', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_collection() { List r = ShopifySyncDashboardController.getDashboardKpis('collection', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_inventory() { List r = ShopifySyncDashboardController.getDashboardKpis('inventory', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_location() { List r = ShopifySyncDashboardController.getDashboardKpis('location', null, null); System.assertNotEquals(null, r); System.assertEquals(8, r.size()); } @isTest static void getDashboardKpis_allDateRanges_coverPeriodDelta() { // Covers priorPeriodClause branches via periodDelta on the 'product' path for (String dr : new List{ 'Today','Yesterday','Last 7 days','Last 30 days','This Month','This Quarter','This Year','Bogus' }) { List r = ShopifySyncDashboardController.getDashboardKpis('product', null, dr); System.assertNotEquals(null, r); } } @isTest static void getDashboardKpis_withSeedData() { // Seed a synced Account + Order + OrderItem so revenue/avg/top-group // aggregate branches execute against real rows, not just empty results. Account acc = new Account(Name = 'KpiCovAcct'); insert acc; Product2 prod = new Product2(Name = 'KpiCovProduct', IsActive = true); insert prod; PricebookEntry pbe = new PricebookEntry( Pricebook2Id = Test.getStandardPricebookId(), Product2Id = prod.Id, UnitPrice = 25, IsActive = true ); insert pbe; Opportunity opp = new Opportunity( Name = 'KpiCovOpp', AccountId = acc.Id, StageName = 'Prospecting', CloseDate = Date.today().addDays(10) ); insert opp; Test.startTest(); List productKpis = ShopifySyncDashboardController.getDashboardKpis('product', null, null); List accountKpis = ShopifySyncDashboardController.getDashboardKpis('account', null, null); List oppKpis = ShopifySyncDashboardController.getDashboardKpis('opp', null, null); Test.stopTest(); System.assertNotEquals(null, productKpis); System.assertNotEquals(null, accountKpis); System.assertNotEquals(null, oppKpis); } }