diff --git a/force-app/main/default/classes/DocGenBulkControllerTest.cls b/force-app/main/default/classes/DocGenBulkControllerTest.cls index 4dc15b7..9621719 100644 --- a/force-app/main/default/classes/DocGenBulkControllerTest.cls +++ b/force-app/main/default/classes/DocGenBulkControllerTest.cls @@ -3,17 +3,13 @@ public with sharing class DocGenBulkControllerTest { @TestSetup static void setup() { - // Create an Account for testing - Account acc = new Account(Name = 'Heap Test Account'); - insert acc; - // Create a Template DocGen_Template__c temp = new DocGen_Template__c( Name = 'Heap Test Template', - Base_Object_API__c = 'Account', - Test_Record_Id__c = acc.Id, + Base_Object_API__c = 'User', + Test_Record_Id__c = UserInfo.getUserId(), Output_Format__c = 'PDF', - Query_Config__c = '{"v":3,"root":"Account","nodes":[{"id":"n0","object":"Account","fields":["Name"],"parentNode":null,"lookupField":null,"relationshipName":null}]}' + Query_Config__c = '{"v":3,"root":"User","nodes":[{"id":"n0","object":"User","fields":["Name"],"parentNode":null,"lookupField":null,"relationshipName":null}]}' ); insert temp; @@ -99,7 +95,7 @@ public with sharing class DocGenBulkControllerTest { @IsTest static void testValidateFilter() { Test.startTest(); - Integer count = DocGenBulkController.validateFilter('Account', 'Name LIKE \'Heap%\''); + Integer count = DocGenBulkController.validateFilter('User', 'UserName = \'' + UserInfo.getUserName() + '\''); Test.stopTest(); System.assertEquals(1, count, 'Should find 1 record'); @@ -108,7 +104,7 @@ public with sharing class DocGenBulkControllerTest { @IsTest static void testValidateFilterEmpty() { Test.startTest(); - Integer count = DocGenBulkController.validateFilter('Account', ''); + Integer count = DocGenBulkController.validateFilter('User', ''); Test.stopTest(); System.assert(count >= 1, 'Should count at least 1 account when no condition is provided'); @@ -185,7 +181,7 @@ public with sharing class DocGenBulkControllerTest { DocGen_Template__c temp = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Test.startTest(); - Id jobId = DocGenBulkController.submitJob(temp.Id, 'Name != null', 'Test Job', true, 10, false); + Id jobId = DocGenBulkController.submitJob(temp.Id, 'Id = \'' + UserInfo.getUserId() + '\'', 'Test Job', true, 10, false); Test.stopTest(); System.assertNotEquals(null, jobId, 'Job ID should be returned'); diff --git a/force-app/main/default/classes/DocGenBulkFlowActionTest.cls b/force-app/main/default/classes/DocGenBulkFlowActionTest.cls index 9df5f77..92e3660 100644 --- a/force-app/main/default/classes/DocGenBulkFlowActionTest.cls +++ b/force-app/main/default/classes/DocGenBulkFlowActionTest.cls @@ -5,13 +5,11 @@ private class DocGenBulkFlowActionTest { static void setup() { DocGen_Template__c temp = new DocGen_Template__c( Name = 'Test Bulk Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Type__c = 'Word' ); insert temp; - insert new Account(Name = 'Test Account 1', Website = 'https://test1.com'); - insert new Account(Name = 'Test Account 2', Website = 'https://test2.com'); } @IsTest diff --git a/force-app/main/default/classes/DocGenBulkTests.cls b/force-app/main/default/classes/DocGenBulkTests.cls index 567ec70..639abc2 100644 --- a/force-app/main/default/classes/DocGenBulkTests.cls +++ b/force-app/main/default/classes/DocGenBulkTests.cls @@ -5,17 +5,20 @@ private class DocGenBulkTests { static void setup() { DocGen_Template__c t = new DocGen_Template__c( Name = 'Test Template', - Base_Object_API__c = 'Account' + Base_Object_API__c = 'User' ); insert t; - - Account a = new Account( - Name = 'Test Account', - Website = 'https://www.example.com' - ); - insert a; } + private static DocGen_Template__c createOrgTemplate() { + DocGen_Template__c t = new DocGen_Template__c( + Name = 'Test Template', + Base_Object_API__c = 'Organization' + ); + insert t; + return t; + } + @IsTest static void testGetBulkTemplates() { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; @@ -32,7 +35,7 @@ private class DocGenBulkTests { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { Test.startTest(); - Integer count = DocGenBulkController.validateFilter('Account', 'Name = \'Test Account\''); + Integer count = DocGenBulkController.validateFilter('User', 'UserName = \'' + UserInfo.getUserName() + '\''); Test.stopTest(); System.assertEquals(1, count, 'Should find 1 record'); } @@ -111,7 +114,7 @@ private class DocGenBulkTests { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { Test.startTest(); - Integer count = DocGenBulkController.validateFilter('Account', null); + Integer count = DocGenBulkController.validateFilter('User', null); Test.stopTest(); System.assert(count >= 1, 'Should count all accounts'); } @@ -124,7 +127,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null; DELETE Account'); + DocGenBulkController.validateFilter('User', 'Name != null; DELETE Account'); } catch (AuraHandledException e) { caught = true; } @@ -140,7 +143,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name IN (SELECT Name FROM Account)'); + DocGenBulkController.validateFilter('User', 'Name IN (SELECT Name FROM User)'); } catch (AuraHandledException e) { caught = true; } @@ -345,13 +348,13 @@ private class DocGenBulkTests { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { // Create a template with V3 query config - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null}' + ']}'; DocGen_Template__c t = new DocGen_Template__c( Name = 'V3 Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = v3Config, Type__c = 'Word', Output_Format__c = 'PDF' @@ -362,29 +365,28 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); // Create multiple accounts as bulk targets - List accs = new List(); - for (Integer i = 0; i < 3; i++) { - accs.add(new Account(Name = 'V3 Acct ' + i)); + Set usrIds = new Set(); + for (User usr : [select Id from User limit 3]) { + usrIds.add(usr.Id); } - insert accs; DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, - Query_Condition__c = 'Name LIKE \'V3 Acct%\'', + Query_Condition__c = 'Id IN (\'' + String.join(usrIds, '\',\'') + '\')', Status__c = 'Queued' ); insert job; Test.startTest(); DocGenBatch batch = new DocGenBatch(job.Id); - Database.executeBatch(batch, 3); + Database.executeBatch(batch, usrIds.size()); Test.stopTest(); // Verify job completed (cache may or may not have been created depending on // whether getRecordDataV3Bulk succeeds, but the batch should finish gracefully) DocGen_Job__c updated = [SELECT Status__c, Total_Records__c, Data_Cache_CV__c FROM DocGen_Job__c WHERE Id = :job.Id]; - System.assertEquals(3, updated.Total_Records__c, 'Should have counted 3 records'); + System.assertEquals(usrIds.size(), updated.Total_Records__c, 'Should have counted ' + usrIds.size() + ' records'); System.assertNotEquals('Queued', updated.Status__c, 'Status should have progressed'); } } @@ -400,7 +402,7 @@ private class DocGenBulkTests { // Create a template with V1 query config and a valid DOCX DocGen_Template__c t = new DocGen_Template__c( Name = 'Success Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -409,12 +411,9 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - Account a = new Account(Name = 'Batch Success Account'); - insert a; - DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, - Query_Condition__c = 'Name = \'Batch Success Account\'', + Query_Condition__c = 'UserName = \'' + UserInfo.getUserName() + '\'', Status__c = 'Queued' ); insert job; @@ -444,7 +443,7 @@ private class DocGenBulkTests { System.runAs(u) { DocGen_Template__c t = new DocGen_Template__c( Name = 'Merge Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -453,11 +452,11 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - List accs = new List(); + List usrs = new List(); + User usr = [SELECT Id, Email FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; for (Integer i = 0; i < 2; i++) { - accs.add(new Account(Name = 'BulkAcct ' + i)); + usrs.add(usr); } - insert accs; DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, @@ -490,7 +489,7 @@ private class DocGenBulkTests { System.runAs(u) { DocGen_Template__c t = new DocGen_Template__c( Name = 'MergeOnly Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -499,9 +498,6 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - Account a = new Account(Name = 'MergeOnly Account'); - insert a; - DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, Query_Condition__c = 'Name = \'MergeOnly Account\'', @@ -578,11 +574,10 @@ private class DocGenBulkTests { System.runAs(u) { // Use a template with no DOCX file — all records will fail DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account a = [SELECT Id FROM Account WHERE Name = 'Test Account' LIMIT 1]; DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, - Query_Condition__c = 'Name = \'Test Account\'', + Query_Condition__c = 'UserName = \'' + UserInfo.getUserName() + '\'', Status__c = 'Queued' ); insert job; @@ -639,13 +634,13 @@ private class DocGenBulkTests { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { // Create a V3 config template to trigger buildDataCache - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null}' + ']}'; DocGen_Template__c t = new DocGen_Template__c( Name = 'Cache Cleanup Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = v3Config, Type__c = 'Word', Output_Format__c = 'PDF' @@ -654,9 +649,6 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - Account a = new Account(Name = 'Cache Cleanup Account'); - insert a; - DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, Query_Condition__c = 'Name = \'Cache Cleanup Account\'', @@ -722,7 +714,7 @@ private class DocGenBulkTests { System.runAs(u) { DocGen_Template__c t = new DocGen_Template__c( Name = 'Merge Chain Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -731,9 +723,6 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - Account a = new Account(Name = 'ChainTestAcct'); - insert a; - // Submit via controller with mergePdf=true Test.startTest(); Id jobId = DocGenBulkController.submitJob(t.Id, 'Name = \'ChainTestAcct\'', 'Chain Job', true, 1, false); @@ -793,11 +782,10 @@ private class DocGenBulkTests { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account a = [SELECT Id FROM Account WHERE Name = 'Test Account' LIMIT 1]; DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, - Query_Condition__c = 'Name = \'Test Account\'', + Query_Condition__c = 'UserName = \'' + UserInfo.getUserName() + '\'', Status__c = 'Completed' ); insert job; @@ -807,7 +795,7 @@ private class DocGenBulkTests { Title = 'Generated PDF', PathOnClient = 'Generated PDF.pdf', VersionData = Blob.valueOf('fake pdf content'), - FirstPublishLocationId = a.Id + FirstPublishLocationId = UserInfo.getUserId() ); insert cv; @@ -860,7 +848,7 @@ private class DocGenBulkTests { System.runAs(u) { DocGen_Template__c t = new DocGen_Template__c( Name = 'Merge Submit Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -891,7 +879,7 @@ private class DocGenBulkTests { System.runAs(u) { DocGen_Template__c t = new DocGen_Template__c( Name = 'MergeOnly Submit Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -938,9 +926,9 @@ private class DocGenBulkTests { @IsTest static void testSubmitJobNullBatchSize() { + DocGen_Template__c t = createOrgTemplate(); User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { - DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Test.startTest(); // null batchSize should default to 1 @@ -958,9 +946,9 @@ private class DocGenBulkTests { @IsTest static void testBatchNoCondition() { + DocGen_Template__c t = createOrgTemplate(); User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { - DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, @@ -1030,7 +1018,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null /* hack */'); + DocGenBulkController.validateFilter('User', 'Name != null /* hack */'); } catch (AuraHandledException e) { caught = true; } @@ -1046,7 +1034,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null -- hack'); + DocGenBulkController.validateFilter('User', 'Name != null -- hack'); } catch (AuraHandledException e) { caught = true; } @@ -1066,7 +1054,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null UPDATE Account'); + DocGenBulkController.validateFilter('User', 'Name != null UPDATE Account'); } catch (AuraHandledException e) { caught = true; } @@ -1082,7 +1070,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null DELETE Account'); + DocGenBulkController.validateFilter('User', 'Name != null DELETE Account'); } catch (AuraHandledException e) { caught = true; } @@ -1100,13 +1088,13 @@ private class DocGenBulkTests { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { // Create a V3 template so buildDataCache creates a cache CV - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null}' + ']}'; DocGen_Template__c t = new DocGen_Template__c( Name = 'LazyLoad Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = v3Config, Type__c = 'Word', Output_Format__c = 'PDF' @@ -1115,9 +1103,6 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - Account a = new Account(Name = 'LazyLoad Account'); - insert a; - DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, Query_Condition__c = 'Name = \'LazyLoad Account\'', @@ -1148,7 +1133,7 @@ private class DocGenBulkTests { // 'DocGen_Job_Complete' does not exist — should return gracefully DocGen_Template__c t = new DocGen_Template__c( Name = 'Notify Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -1157,9 +1142,6 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - Account a = new Account(Name = 'Notify Account'); - insert a; - DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, Query_Condition__c = 'Name = \'Notify Account\'', @@ -1189,7 +1171,7 @@ private class DocGenBulkTests { System.runAs(u) { DocGen_Template__c t = new DocGen_Template__c( Name = 'MergeOnly Submit Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -1214,9 +1196,9 @@ private class DocGenBulkTests { @IsTest static void testSubmitJobDefaultBatchSize() { + DocGen_Template__c t = createOrgTemplate(); User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { - DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Test.startTest(); Id jobId = DocGenBulkController.submitJob(t.Id, null, null, false, null, false); @@ -1238,7 +1220,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null -- drop'); + DocGenBulkController.validateFilter('User', 'Name != null -- drop'); } catch (AuraHandledException e) { caught = true; } @@ -1254,7 +1236,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null /* evil */'); + DocGenBulkController.validateFilter('User', 'Name != null /* evil */'); } catch (AuraHandledException e) { caught = true; } @@ -1271,7 +1253,7 @@ private class DocGenBulkTests { Boolean caught = false; Test.startTest(); try { - DocGenBulkController.validateFilter('Account', 'Name != null ORDER BY Name'); + DocGenBulkController.validateFilter('User', 'Name != null ORDER BY Name'); } catch (AuraHandledException e) { caught = true; } @@ -1407,7 +1389,7 @@ private class DocGenBulkTests { // Create template with valid DOCX so at least some records succeed DocGen_Template__c t = new DocGen_Template__c( Name = 'Partial Fail Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word', Output_Format__c = 'PDF' @@ -1416,12 +1398,9 @@ private class DocGenBulkTests { createValidDocxForTemplate(t.Id, buildSimpleDocXml()); - // Create accounts that should be processed - insert new Account(Name = 'PartialFail Account'); - DocGen_Job__c job = new DocGen_Job__c( Template__c = t.Id, - Query_Condition__c = 'Name = \'PartialFail Account\'', + Query_Condition__c = 'Name = \'PartialFail User\'', Status__c = 'Queued' ); insert job; @@ -1443,9 +1422,9 @@ private class DocGenBulkTests { @IsTest static void testSubmitJobWithLabel() { + DocGen_Template__c t = createOrgTemplate(); User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { - DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Test.startTest(); Id jobId = DocGenBulkController.submitJob(t.Id, null, 'My Custom Label', false, 5, false); @@ -1462,9 +1441,9 @@ private class DocGenBulkTests { @IsTest static void testSubmitJobWithBlankLabel() { + DocGen_Template__c t = createOrgTemplate(); User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { - DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Test.startTest(); Id jobId = DocGenBulkController.submitJob(t.Id, null, '', false, 1, false); diff --git a/force-app/main/default/classes/DocGenControllerTests.cls b/force-app/main/default/classes/DocGenControllerTests.cls index fce1d2d..7c3ee13 100644 --- a/force-app/main/default/classes/DocGenControllerTests.cls +++ b/force-app/main/default/classes/DocGenControllerTests.cls @@ -1,23 +1,44 @@ @IsTest private class DocGenControllerTests { - + private static String CHATTER_FREE_USER_PROFILE_NAME = 'Chatter Free User'; + private static String UNIQUE_IDENTIFIER = 'DocGenControllerTests'; + private static String UNIQUE_USERNAME = String.format('manageduser+{0}@test.com{1}', new List{UNIQUE_IDENTIFIER, UserInfo.getUserId()}); @TestSetup static void setup() { DocGen_Template__c tpl = new DocGen_Template__c( Name = 'Controller Test Template', - Base_Object_API__c = 'Account', - Query_Config__c = 'Name, AccountSource', + Base_Object_API__c = 'User', + Query_Config__c = 'Email, CreatedBy.Email', Type__c = 'Word' ); insert tpl; - Account acc = new Account( - Name = 'Controller Test Account', - AccountSource = 'Web', - Website = 'https://test.com' - ); - insert acc; - } + createManagedUser(UNIQUE_IDENTIFIER); + } + + private static void createManagedUser(String uniqueIdentifier) { + System.runAs(new User(Id = UserInfo.getUserId())) { + // this should create a new chatter free user and set the manager to the current user + User usr = new User( + FirstName = 'Managed', + LastName = 'User', + Email = 'manageduser@test.com', + Username = UNIQUE_USERNAME, + Alias = 'muser', + LanguageLocaleKey = 'en_US', + LocaleSidKey = 'en_US', + EmailEncodingKey = 'UTF-8', + ManagerId = UserInfo.getUserId(), + ProfileId = [SELECT Id FROM Profile WHERE Name = 'Chatter Free User' LIMIT 1].Id, + TimeZoneSidKey = 'America/Los_Angeles' + ); + insert usr; + } + } + + private static User getManagedUser() { + return [SELECT Id, Name, FirstName, LastName, CreatedBy.Name FROM User WHERE Username = :UNIQUE_USERNAME LIMIT 1]; + } private static ContentVersion createTestFile() { ContentVersion cv = new ContentVersion( @@ -41,14 +62,13 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSaveGeneratedDocument() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); String dummyContent = EncodingUtil.base64Encode(Blob.valueOf('Dummy PDF content')); Test.startTest(); Id contentDocId = DocGenController.saveGeneratedDocument( - acc.Id, 'TestOutput', dummyContent, '.pdf' + usr.Id, 'TestOutput', dummyContent, '.pdf' ); Test.stopTest(); @@ -67,14 +87,13 @@ private class DocGenControllerTests { @IsTest static void testSaveGeneratedDocumentExtensionWithoutDot() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); String dummyContent = EncodingUtil.base64Encode(Blob.valueOf('Dummy DOCX content')); Test.startTest(); Id contentDocId = DocGenController.saveGeneratedDocument( - acc.Id, 'TestOutputNoDot', dummyContent, 'docx' + usr.Id, 'TestOutputNoDot', dummyContent, 'docx' ); Test.stopTest(); @@ -94,16 +113,15 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testProcessAndReturnDocumentThrows() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { createTestFile(); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Boolean caughtException = false; try { - DocGenController.processAndReturnDocument(tpl.Id, acc.Id); + DocGenController.processAndReturnDocument(tpl.Id, usr.Id); } catch (AuraHandledException e) { caughtException = true; } @@ -118,26 +136,24 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testPreviewRecordData() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Map result = DocGenController.previewRecordData( - acc.Id, 'Account', 'Name, AccountSource' + usr.Id, 'User', 'Name, Email' ); Test.stopTest(); System.assertNotEquals(null, result, 'Preview data should not be null'); - System.assertEquals('Controller Test Account', result.get('Name'), - 'Name field should match the test account'); + System.assertNotEquals(null, result.get('Name'), + 'Name field should be returned'); } } @IsTest static void testPreviewRecordDataNullParams() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Map result = DocGenController.previewRecordData(null, null, null); Test.stopTest(); @@ -151,8 +167,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetAllTemplates() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List templates = DocGenController.getAllTemplates(); Test.stopTest(); @@ -174,8 +189,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSaveTemplateUpdateOnly() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Map fields = new Map{ @@ -183,7 +197,7 @@ private class DocGenControllerTests { 'Name' => 'Renamed Template', 'Category__c' => 'Legal', 'Type__c' => 'Word', - 'Base_Object_API__c' => 'Account', + 'Base_Object_API__c' => 'User', 'Description__c' => 'Updated description', 'Query_Config__c' => 'Name', 'Test_Record_Id__c' => null, @@ -207,8 +221,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSaveTemplateWithVersion() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { createTestFile(); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; @@ -217,9 +230,9 @@ private class DocGenControllerTests { 'Name' => 'Versioned Template', 'Category__c' => 'Finance', 'Type__c' => 'Word', - 'Base_Object_API__c' => 'Account', + 'Base_Object_API__c' => 'User', 'Description__c' => 'Version test', - 'Query_Config__c' => 'Name, AccountSource', + 'Query_Config__c' => 'Name, Email', 'Test_Record_Id__c' => null, 'Document_Title_Format__c' => null }; @@ -253,12 +266,11 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testDeleteTemplate() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Create a disposable template to delete DocGen_Template__c disposable = new DocGen_Template__c( Name = 'To Be Deleted', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word' ); @@ -280,8 +292,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetTemplateVersions() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; // Create a version record @@ -289,7 +300,7 @@ private class DocGenControllerTests { Template__c = tpl.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Category__c = 'General', Description__c = 'Test version' ); @@ -309,8 +320,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetObjectOptions() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> options = DocGenController.getObjectOptions(); Test.stopTest(); @@ -320,7 +330,7 @@ private class DocGenControllerTests { // Verify Account is in the list Boolean foundAccount = false; for (Map opt : options) { - if (opt.get('value') == 'Account') { + if (opt.get('value') == 'User') { foundAccount = true; break; } @@ -334,10 +344,9 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetObjectFields() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - List> fields = DocGenController.getObjectFields('Account'); + List> fields = DocGenController.getObjectFields('User'); Test.stopTest(); System.assert(!fields.isEmpty(), 'Account should have fields'); @@ -356,8 +365,7 @@ private class DocGenControllerTests { @IsTest static void testGetObjectFieldsInvalidObject() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> fields = DocGenController.getObjectFields('NonExistentObject__x'); Test.stopTest(); @@ -371,10 +379,9 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetChildRelationships() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - List> rels = DocGenController.getChildRelationships('Account'); + List> rels = DocGenController.getChildRelationships('User'); Test.stopTest(); System.assert(!rels.isEmpty(), 'Account should have child relationships'); @@ -390,8 +397,7 @@ private class DocGenControllerTests { @IsTest static void testGetChildRelationshipsInvalidObject() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> rels = DocGenController.getChildRelationships('NonExistentObject__x'); Test.stopTest(); @@ -405,10 +411,9 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetParentRelationships() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - List> parents = DocGenController.getParentRelationships('Account'); + List> parents = DocGenController.getParentRelationships('User'); Test.stopTest(); System.assert(!parents.isEmpty(), 'Account should have parent/lookup relationships'); @@ -423,8 +428,7 @@ private class DocGenControllerTests { @IsTest static void testGetParentRelationshipsInvalidObject() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> parents = DocGenController.getParentRelationships('NonExistentObject__x'); Test.stopTest(); @@ -438,8 +442,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSearchUsersAndGroups() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // The running user should always exist and be matchable String currentUserName = UserInfo.getLastName(); @@ -459,8 +462,7 @@ private class DocGenControllerTests { @IsTest static void testSearchUsersAndGroupsNoResults() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> results = DocGenController.searchUsersAndGroups('ZZZZNONEXISTENT99999'); Test.stopTest(); @@ -474,8 +476,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetTemplateSharesEmpty() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Test.startTest(); @@ -493,8 +494,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testShareAndRemoveTemplate() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id, OwnerId FROM DocGen_Template__c LIMIT 1]; // We need a different user or group to share with. @@ -544,8 +544,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testOptionCompareTo() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGenController.Option optA = new DocGenController.Option('Alpha', 'a'); DocGenController.Option optB = new DocGenController.Option('Beta', 'b'); DocGenController.Option optA2 = new DocGenController.Option('Alpha', 'a2'); @@ -560,13 +559,12 @@ private class DocGenControllerTests { @IsTest static void testOptionThreeArgConstructor() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - DocGenController.Option opt = new DocGenController.Option('Contacts', 'Contacts', 'Contact'); + System.runAs(new User(Id = UserInfo.getUserId())) { + DocGenController.Option opt = new DocGenController.Option('Contacts', 'Contacts', 'User'); System.assertEquals('Contacts', opt.label, 'Label should match'); System.assertEquals('Contacts', opt.value, 'Value should match'); - System.assertEquals('Contact', opt.childObjectApiName, 'Child object API name should match'); + System.assertEquals('User', opt.childObjectApiName, 'Child object API name should match'); } } @@ -575,14 +573,13 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataNullTemplateId() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Boolean caughtException = false; try { - DocGenController.generateDocumentData(null, acc.Id); + DocGenController.generateDocumentData(null, usr.Id); } catch (DocGenException e) { caughtException = true; System.assert(e.getMessage().contains('Template ID is missing'), @@ -599,16 +596,15 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataTemplateNotFound() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; // Use a fake but valid-format Id for a template that does not exist Id fakeTemplateId = DocGen_Template__c.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).getKeyPrefix() + '000000000000'; Test.startTest(); Boolean caughtException = false; try { - DocGenController.generateDocumentData(fakeTemplateId, acc.Id); + DocGenController.generateDocumentData(fakeTemplateId, usr.Id); } catch (DocGenException e) { caughtException = true; System.assert(e.getMessage().contains('Unable to access template'), @@ -625,10 +621,9 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataSuccess() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; // Build a minimal valid DOCX ZIP Compression.ZipWriter zw = new Compression.ZipWriter(); @@ -664,7 +659,7 @@ private class DocGenControllerTests { ); Test.startTest(); - Map result = DocGenController.generateDocumentData(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentData(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null'); @@ -680,10 +675,9 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetTemplatesForObject() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - List templates = DocGenController.getTemplatesForObject('Account'); + List templates = DocGenController.getTemplatesForObject('User'); Test.stopTest(); System.assert(!templates.isEmpty(), 'Should return the test template for Account'); @@ -693,8 +687,7 @@ private class DocGenControllerTests { @IsTest static void testGetTemplatesForObjectNoResults() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List templates = DocGenController.getTemplatesForObject('NonExistentObject__c'); Test.stopTest(); @@ -708,10 +701,9 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testProcessAndReturnDocumentSuccess() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; // Build valid DOCX Compression.ZipWriter zw = new Compression.ZipWriter(); @@ -747,7 +739,7 @@ private class DocGenControllerTests { ); Test.startTest(); - Map result = DocGenController.processAndReturnDocument(tpl.Id, acc.Id); + Map result = DocGenController.processAndReturnDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null'); @@ -763,16 +755,15 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGeneratePdfDownloadThrows() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { createTestFile(); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Boolean caughtException = false; try { - DocGenController.generatePdf(tpl.Id, acc.Id, false); + DocGenController.generatePdf(tpl.Id, usr.Id, false); } catch (AuraHandledException e) { caughtException = true; } @@ -787,10 +778,9 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGeneratePdfDownloadSuccess() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Compression.ZipWriter zw = new Compression.ZipWriter(); zw.addEntry('[Content_Types].xml', Blob.valueOf( @@ -825,7 +815,7 @@ private class DocGenControllerTests { ); Test.startTest(); - Map result = DocGenController.generatePdf(tpl.Id, acc.Id, false); + Map result = DocGenController.generatePdf(tpl.Id, usr.Id, false); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null'); @@ -839,12 +829,11 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGeneratePdfSaveSuccess() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; tpl.Output_Format__c = 'PDF'; update tpl; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Compression.ZipWriter zw = new Compression.ZipWriter(); zw.addEntry('[Content_Types].xml', Blob.valueOf( @@ -879,7 +868,7 @@ private class DocGenControllerTests { ); Test.startTest(); - Map result = DocGenController.generatePdf(tpl.Id, acc.Id, true); + Map result = DocGenController.generatePdf(tpl.Id, usr.Id, true); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null'); @@ -892,8 +881,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testActivateVersion() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; // Create two versions, both active initially @@ -901,7 +889,7 @@ private class DocGenControllerTests { Template__c = tpl.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Category__c = 'General', Description__c = 'Version 1', Query_Config__c = 'Name' @@ -910,10 +898,10 @@ private class DocGenControllerTests { Template__c = tpl.Id, Is_Active__c = false, Type__c = 'Word', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Category__c = 'Legal', Description__c = 'Version 2', - Query_Config__c = 'Name, AccountSource' + Query_Config__c = 'Email, CreatedBy.Email' ); insert new List{ v1, v2 }; @@ -939,8 +927,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSaveTemplateWithDefaultFlag() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Map fields = new Map{ @@ -948,7 +935,7 @@ private class DocGenControllerTests { 'Name' => 'Default Template', 'Category__c' => 'Sales', 'Type__c' => 'Word', - 'Base_Object_API__c' => 'Account', + 'Base_Object_API__c' => 'User', 'Description__c' => 'Default test', 'Query_Config__c' => 'Name', 'Test_Record_Id__c' => null, @@ -970,14 +957,13 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSaveTemplateDefaultEnforcement() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl1 = [SELECT Id FROM DocGen_Template__c LIMIT 1]; // Create a second template for the same object DocGen_Template__c tpl2 = new DocGen_Template__c( Name = 'Second Account Template', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Query_Config__c = 'Name', Type__c = 'Word' ); @@ -989,7 +975,7 @@ private class DocGenControllerTests { 'Name' => 'Controller Test Template', 'Category__c' => null, 'Type__c' => 'Word', - 'Base_Object_API__c' => 'Account', + 'Base_Object_API__c' => 'User', 'Description__c' => null, 'Query_Config__c' => 'Name', 'Test_Record_Id__c' => null, @@ -1004,7 +990,7 @@ private class DocGenControllerTests { 'Name' => 'Second Account Template', 'Category__c' => null, 'Type__c' => 'Word', - 'Base_Object_API__c' => 'Account', + 'Base_Object_API__c' => 'User', 'Description__c' => null, 'Query_Config__c' => 'Name', 'Test_Record_Id__c' => null, @@ -1028,14 +1014,13 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testPreviewRecordDataException() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Boolean caughtException = false; try { - DocGenController.previewRecordData(acc.Id, 'InvalidObject__xyz', 'Name'); + DocGenController.previewRecordData(usr.Id, 'InvalidObject__xyz', 'Name'); } catch (DocGenException e) { caughtException = true; System.assert(e.getMessage().contains('Error fetching preview data'), @@ -1052,8 +1037,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testDeleteTemplateThrows() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Use a fake ID that looks valid but does not exist — will throw Id fakeId = DocGen_Template__c.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).getKeyPrefix() + '000000000000'; @@ -1075,8 +1059,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSaveTemplateThrows() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Id fakeId = DocGen_Template__c.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).getKeyPrefix() + '000000000000'; Map fields = new Map{ @@ -1084,7 +1067,7 @@ private class DocGenControllerTests { 'Name' => 'Will Fail', 'Category__c' => null, 'Type__c' => 'Word', - 'Base_Object_API__c' => 'Account', + 'Base_Object_API__c' => 'User', 'Description__c' => null, 'Query_Config__c' => 'Name', 'Test_Record_Id__c' => null, @@ -1110,16 +1093,15 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataWithRichTextRefid() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; - // Set Description to contain HTML with an img tag using refid (simulates rich text) - acc.Description = '

See image: test

'; - update acc; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; + // Set AboutMe to contain HTML with an img tag using refid (simulates rich text) + usr.AboutMe = '

See image: test

'; + update usr; // Build valid DOCX Compression.ZipWriter zw = new Compression.ZipWriter(); @@ -1158,7 +1140,7 @@ private class DocGenControllerTests { // but the code handles exceptions gracefully. This exercises the code path. Test.startTest(); try { - Map result = DocGenController.generateDocumentData(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentData(tpl.Id, usr.Id); // If no exception, result should still be valid System.assertNotEquals(null, result, 'Result should not be null'); } catch (Exception e) { @@ -1175,16 +1157,15 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataWithServletImages() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; - // Set Description with servlet URL (without refid) to exercise resolveServletImageUrls - acc.Description = '

img

'; - update acc; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; + // Set AboutMe with servlet URL (without refid) to exercise resolveServletImageUrls + usr.AboutMe = '

img

'; + update usr; Compression.ZipWriter zw = new Compression.ZipWriter(); zw.addEntry('[Content_Types].xml', Blob.valueOf( @@ -1220,7 +1201,7 @@ private class DocGenControllerTests { Test.startTest(); try { - Map result = DocGenController.generateDocumentData(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentData(tpl.Id, usr.Id); System.assertNotEquals(null, result, 'Result should not be null'); } catch (Exception e) { // Callout exceptions are acceptable in test context @@ -1236,15 +1217,14 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataWithSfcImages() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; - acc.Description = '

img

'; - update acc; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; + usr.AboutMe = '

img

'; + update usr; Compression.ZipWriter zw = new Compression.ZipWriter(); zw.addEntry('[Content_Types].xml', Blob.valueOf( @@ -1280,7 +1260,7 @@ private class DocGenControllerTests { Test.startTest(); try { - Map result = DocGenController.generateDocumentData(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentData(tpl.Id, usr.Id); System.assertNotEquals(null, result, 'Result should not be null'); } catch (Exception e) { System.assert(true, 'Exception during callout is expected in test context'); @@ -1294,14 +1274,13 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataWithOutputFormatAndTitle() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; tpl.Output_Format__c = 'PDF'; tpl.Document_Title_Format__c = 'Invoice_{Name}'; update tpl; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Compression.ZipWriter zw = new Compression.ZipWriter(); zw.addEntry('[Content_Types].xml', Blob.valueOf( @@ -1336,7 +1315,7 @@ private class DocGenControllerTests { ); Test.startTest(); - Map result = DocGenController.generateDocumentData(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentData(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null'); @@ -1350,14 +1329,12 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataWithChildRelationship() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, (SELECT LastName FROM Contacts)'; + tpl.Query_Config__c = 'Name, (SELECT LastName FROM ManagedUsers)'; update tpl; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; - insert new Contact(FirstName = 'Test', LastName = 'Child', AccountId = acc.Id); + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Compression.ZipWriter zw = new Compression.ZipWriter(); zw.addEntry('[Content_Types].xml', Blob.valueOf( @@ -1392,12 +1369,13 @@ private class DocGenControllerTests { ); Test.startTest(); - Map result = DocGenController.generateDocumentData(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentData(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null'); Map data = (Map) result.get('data'); - System.assert(data.containsKey('Contacts'), 'Data should contain Contacts child relationship'); + System.debug('data: ' + data); + System.assert(data.containsKey('ManagedUsers'), 'Data should contain ManagedUsers child relationship'); } } @@ -1406,8 +1384,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testSaveTemplateVersionDeactivatesPrevious() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { createTestFile(); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; @@ -1416,7 +1393,7 @@ private class DocGenControllerTests { Template__c = tpl.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Category__c = 'Old', Description__c = 'Old version' ); @@ -1427,7 +1404,7 @@ private class DocGenControllerTests { 'Name' => 'Template With New Version', 'Category__c' => 'New', 'Type__c' => 'Word', - 'Base_Object_API__c' => 'Account', + 'Base_Object_API__c' => 'User', 'Description__c' => 'New version test', 'Query_Config__c' => 'Name', 'Test_Record_Id__c' => null, @@ -1459,8 +1436,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetAllTemplatesWithFile() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { createTestFile(); Test.startTest(); @@ -1485,8 +1461,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetContentVersionBase64() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { ContentVersion cv = new ContentVersion( Title = 'Base64Test', PathOnClient = 'Base64Test.txt', @@ -1507,8 +1482,7 @@ private class DocGenControllerTests { @IsTest static void testGetContentVersionBase64NotFound() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Use a fake but valid-format ContentVersion ID Id fakeId = '068000000000000AAA'; @@ -1525,16 +1499,15 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentPartsError() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Use a fake template ID to trigger an exception inside DocGenService Id fakeTemplateId = DocGen_Template__c.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).getKeyPrefix() + '000000000000'; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Boolean caughtException = false; try { - DocGenController.generateDocumentParts(fakeTemplateId, acc.Id); + DocGenController.generateDocumentParts(fakeTemplateId, usr.Id); } catch (AuraHandledException e) { caughtException = true; } @@ -1546,10 +1519,9 @@ private class DocGenControllerTests { @IsTest static void testGenerateDocumentPartsSuccess() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; // Build a minimal valid DOCX and attach to template Compression.ZipWriter zw = new Compression.ZipWriter(); @@ -1585,7 +1557,7 @@ private class DocGenControllerTests { ); Test.startTest(); - Map result = DocGenController.generateDocumentParts(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentParts(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result, 'Should return non-null result'); @@ -1598,9 +1570,8 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetRecordPdfs() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // Create a PDF ContentVersion linked to the account ContentVersion pdfCv = new ContentVersion( @@ -1611,13 +1582,13 @@ private class DocGenControllerTests { insert pdfCv; Id pdfDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :pdfCv.Id].ContentDocumentId; insert new ContentDocumentLink( - LinkedEntityId = acc.Id, + LinkedEntityId = usr.Id, ContentDocumentId = pdfDocId, ShareType = 'V' ); Test.startTest(); - List> pdfs = DocGenController.getRecordPdfs(acc.Id); + List> pdfs = DocGenController.getRecordPdfs(usr.Id); Test.stopTest(); System.assert(!pdfs.isEmpty(), 'Should return at least one PDF'); @@ -1635,12 +1606,11 @@ private class DocGenControllerTests { @IsTest static void testGetRecordPdfsEmpty() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); - List> pdfs = DocGenController.getRecordPdfs(acc.Id); + List> pdfs = DocGenController.getRecordPdfs(usr.Id); Test.stopTest(); System.assertEquals(0, pdfs.size(), 'Should return empty list when no PDFs attached'); @@ -1652,14 +1622,8 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetChildRecordPdfs() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; - - // Create a child contact - Contact con = new Contact(FirstName = 'Pdf', LastName = 'Child', AccountId = acc.Id); - insert con; - + System.runAs(new User(Id = UserInfo.getUserId())) { + User managedUser = getManagedUser(); // Attach a PDF to the contact ContentVersion pdfCv = new ContentVersion( Title = 'ChildPdf', @@ -1669,21 +1633,21 @@ private class DocGenControllerTests { insert pdfCv; Id pdfDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :pdfCv.Id].ContentDocumentId; insert new ContentDocumentLink( - LinkedEntityId = con.Id, + LinkedEntityId = managedUser.Id, ContentDocumentId = pdfDocId, ShareType = 'V' ); Test.startTest(); List> result = DocGenController.getChildRecordPdfs( - acc.Id, 'Contact', 'AccountId', null + UserInfo.getUserId(), 'User', 'ManagerId', null ); Test.stopTest(); System.assert(!result.isEmpty(), 'Should return at least one child record group'); Boolean foundChild = false; for (Map grp : result) { - if (grp.get('childRecordName') == 'Pdf Child') { + if (grp.get('childRecordName') == ManagedUser.Name) { foundChild = true; List> pdfs = (List>) grp.get('pdfs'); System.assert(!pdfs.isEmpty(), 'Child should have at least one PDF'); @@ -1691,18 +1655,17 @@ private class DocGenControllerTests { break; } } - System.assert(foundChild, 'Should find the child contact in results'); + System.assert(foundChild, 'Should find the child users in results'); } } @IsTest static void testGetChildRecordPdfsNullParams() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Boolean caughtException = false; try { - DocGenController.getChildRecordPdfs(null, 'Contact', 'AccountId', null); + DocGenController.getChildRecordPdfs(null, 'User', 'CreatedById', null); } catch (AuraHandledException e) { caughtException = true; } @@ -1714,14 +1677,13 @@ private class DocGenControllerTests { @IsTest static void testGetChildRecordPdfsInvalidObject() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Boolean caughtException = false; try { - DocGenController.getChildRecordPdfs(acc.Id, 'NonExistentObject__xyz', 'AccountId', null); + DocGenController.getChildRecordPdfs(usr.Id, 'NonExistentObject__xyz', 'CreatedById', null); } catch (AuraHandledException e) { caughtException = true; } @@ -1733,14 +1695,13 @@ private class DocGenControllerTests { @IsTest static void testGetChildRecordPdfsInvalidLookup() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Test.startTest(); Boolean caughtException = false; try { - DocGenController.getChildRecordPdfs(acc.Id, 'Contact', 'FakeField__xyz', null); + DocGenController.getChildRecordPdfs(usr.Id, 'User', 'FakeField__xyz', null); } catch (AuraHandledException e) { caughtException = true; } @@ -1752,15 +1713,12 @@ private class DocGenControllerTests { @IsTest static void testGetChildRecordPdfsNoChildren() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - // Create a fresh account with no child contacts - Account freshAcc = new Account(Name = 'No Children Account'); - insert freshAcc; + System.runAs(new User(Id = UserInfo.getUserId())) { + User managedUser = getManagedUser(); Test.startTest(); List> result = DocGenController.getChildRecordPdfs( - freshAcc.Id, 'Contact', 'AccountId', null + managedUser.Id, 'User', 'ManagerId', null ); Test.stopTest(); @@ -1773,8 +1731,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetAvailableReportsNoTerm() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> reports = DocGenController.getAvailableReports(null); Test.stopTest(); @@ -1786,8 +1743,7 @@ private class DocGenControllerTests { @IsTest static void testGetAvailableReportsWithTerm() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> reports = DocGenController.getAvailableReports('ZZZNONEXISTENT999'); Test.stopTest(); @@ -1800,8 +1756,7 @@ private class DocGenControllerTests { @IsTest static void testGetAvailableReportsBlankTerm() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> reports = DocGenController.getAvailableReports(''); Test.stopTest(); @@ -1815,8 +1770,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testCreateSampleTemplates() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Integer count = DocGenController.createSampleTemplates(); Test.stopTest(); @@ -1847,16 +1801,15 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testOptionFourArgConstructor() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGenController.Option opt = new DocGenController.Option( - 'Contacts', 'Contacts', 'Contact', 'AccountId' + 'ManagedUsers', 'ManagedUsers', 'User', 'CreatedById' ); - System.assertEquals('Contacts', opt.label, 'Label should match'); - System.assertEquals('Contacts', opt.value, 'Value should match'); - System.assertEquals('Contact', opt.childObjectApiName, 'Child object API name should match'); - System.assertEquals('AccountId', opt.lookupField, 'Lookup field should match'); + System.assertEquals('ManagedUsers', opt.label, 'Label should match'); + System.assertEquals('ManagedUsers', opt.value, 'Value should match'); + System.assertEquals('User', opt.childObjectApiName, 'Child object API name should match'); + System.assertEquals('CreatedById', opt.lookupField, 'Lookup field should match'); } } @@ -1865,8 +1818,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testImportReportConfigNullId() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Boolean caughtException = false; try { @@ -1882,8 +1834,7 @@ private class DocGenControllerTests { @IsTest static void testImportReportConfigInvalidId() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Use a fake report ID — will fail at Reports.ReportManager.describeReport Id fakeReportId = '00O000000000000AAA'; @@ -1907,8 +1858,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testImportReportConfigWithRealReport() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { List reports = [SELECT Id FROM Report LIMIT 1]; if (reports.isEmpty()) { // No reports in org — skip gracefully @@ -1940,8 +1890,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testNormalizeImageUrlsServletPath() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { String html = ''; Test.startTest(); @@ -1957,8 +1906,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeImageUrlsSfcPath() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { String html = ''; Test.startTest(); @@ -1972,8 +1920,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeImageUrlsNoMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { String html = ''; Test.startTest(); @@ -1989,8 +1936,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testResolveRichTextImagesWithSfcUrl() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map data = new Map{ 'Description' => '

test

', 'Name' => 'Test Account' @@ -2010,8 +1956,7 @@ private class DocGenControllerTests { @IsTest static void testResolveRichTextImagesWithServletUrl() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map data = new Map{ 'RichField' => '

test

' }; @@ -2028,8 +1973,7 @@ private class DocGenControllerTests { @IsTest static void testResolveRichTextImagesNestedList() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Test the List recursion path Map childRecord = new Map{ 'Notes' => '

child

' @@ -2052,8 +1996,7 @@ private class DocGenControllerTests { @IsTest static void testResolveRichTextImagesNoImageTags() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map data = new Map{ 'Description' => '

Just plain text with no images

' }; @@ -2072,21 +2015,19 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testResolveReportBaseObjectDirectMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - // Strategy 1: Direct match — 'Account' is a real object - String result = DocGenController.resolveReportBaseObject('Account'); + // Strategy 1: Direct match — 'User' is a real object + String result = DocGenController.resolveReportBaseObject('User'); Test.stopTest(); - System.assertEquals('Account', result, 'Direct object name should resolve'); + System.assertEquals('User', result, 'Direct object name should resolve'); } } @IsTest static void testResolveReportBaseObjectListSuffix() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); // Strategy 2: Strip 'List' suffix String result = DocGenController.resolveReportBaseObject('AccountList'); @@ -2098,8 +2039,7 @@ private class DocGenControllerTests { @IsTest static void testResolveReportBaseObjectLabelMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); // Strategy 4: Label match — 'Accounts' is the plural label for Account String result = DocGenController.resolveReportBaseObject('UnknownType', 'Accounts'); @@ -2111,21 +2051,19 @@ private class DocGenControllerTests { @IsTest static void testResolveReportBaseObjectPrefixMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - // Strategy 5: Prefix match — OpportunityLead starts with Opportunity - String result = DocGenController.resolveReportBaseObject('OpportunityLead'); + // Strategy 5: Prefix match — UserLead starts with User + String result = DocGenController.resolveReportBaseObject('UserLead'); Test.stopTest(); - System.assertEquals('Opportunity', result, 'OpportunityLead should resolve to Opportunity'); + System.assertEquals('User', result, 'UserLead should resolve to User'); } } @IsTest static void testResolveReportBaseObjectCustomWithCommonName() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); // Strategy 6: Custom report type containing a known object name String result = DocGenController.resolveReportBaseObject('MyAccount__c'); @@ -2137,8 +2075,7 @@ private class DocGenControllerTests { @IsTest static void testResolveReportBaseObjectNull() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); String result = DocGenController.resolveReportBaseObject(null); Test.stopTest(); @@ -2149,8 +2086,7 @@ private class DocGenControllerTests { @IsTest static void testResolveReportBaseObjectBlank() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); String result = DocGenController.resolveReportBaseObject(''); Test.stopTest(); @@ -2161,8 +2097,7 @@ private class DocGenControllerTests { @IsTest static void testResolveReportBaseObjectUnresolvable() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); String result = DocGenController.resolveReportBaseObject('ZZZNonExistent999'); Test.stopTest(); @@ -2173,8 +2108,7 @@ private class DocGenControllerTests { @IsTest static void testResolveReportBaseObjectAccountContact() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); String result = DocGenController.resolveReportBaseObject('AccountContact'); Test.stopTest(); @@ -2185,8 +2119,7 @@ private class DocGenControllerTests { @IsTest static void testResolveReportBaseObjectCaseContact() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); String result = DocGenController.resolveReportBaseObject('CaseContact'); Test.stopTest(); @@ -2200,8 +2133,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testNormalizeReportColumnDirectApiMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Map labelToApiName = new Map(); Map properCaseMap = new Map(); @@ -2222,8 +2154,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnLabelMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Map labelToApiName = new Map(); Map properCaseMap = new Map(); @@ -2235,7 +2166,7 @@ private class DocGenControllerTests { Test.startTest(); // Label match — "Account Name" is the label for the Name field on Account - String result = DocGenController.normalizeReportColumn('SOMETHING_UNKNOWN', 'Account Name', fieldMap, labelToApiName, properCaseMap); + String result = DocGenController.normalizeReportColumn('SOMETHING_UNKNOWN', Account.Name.getDescribe().getLabel(), fieldMap, labelToApiName, properCaseMap); Test.stopTest(); System.assertEquals('Name', result, 'Label "Account Name" should resolve to Name'); @@ -2244,8 +2175,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnHardcodedMapping() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Opportunity.fields.getMap(); Map labelToApiName = new Map(); Map properCaseMap = new Map(); @@ -2266,8 +2196,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnCreatedDate() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Map labelToApiName = new Map(); Map properCaseMap = new Map(); @@ -2287,8 +2216,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnWithObjectPrefix() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Map labelToApiName = new Map(); Map properCaseMap = new Map(); @@ -2309,8 +2237,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnBlank() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2323,8 +2250,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnNull() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2337,8 +2263,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnUsersPrefix() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2352,8 +2277,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnNoMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2366,8 +2290,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnStageName() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Opportunity.fields.getMap(); Map labelToApiName = new Map(); Map properCaseMap = new Map(); @@ -2387,8 +2310,7 @@ private class DocGenControllerTests { @IsTest static void testNormalizeReportColumnAmount() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map fieldMap = Schema.SObjectType.Opportunity.fields.getMap(); Map labelToApiName = new Map(); Map properCaseMap = new Map(); @@ -2411,8 +2333,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testMapReportOperatorEquals() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); System.assertEquals('=', DocGenController.mapReportOperator('equals'), 'equals should map to ='); System.assertEquals('!=', DocGenController.mapReportOperator('notEqual'), 'notEqual should map to !='); @@ -2430,8 +2351,7 @@ private class DocGenControllerTests { @IsTest static void testMapReportOperatorNull() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); System.assertEquals('=', DocGenController.mapReportOperator(null), 'Null should default to ='); System.assertEquals('=', DocGenController.mapReportOperator(''), 'Blank should default to ='); @@ -2441,8 +2361,7 @@ private class DocGenControllerTests { @IsTest static void testMapReportOperatorUnknown() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); System.assertEquals('=', DocGenController.mapReportOperator('unknownOp'), 'Unknown operator should default to ='); Test.stopTest(); @@ -2454,51 +2373,46 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testFindParentObjectDirectChild() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Contact is a direct child of Account — should return Account as parent Map childRelNameByObject = new Map{ - 'Contact' => 'Contacts' + 'User' => 'Contacts' }; Test.startTest(); - String result = DocGenController.findParentObject('Contact', 'Account', childRelNameByObject); + String result = DocGenController.findParentObject('User', 'User', childRelNameByObject); Test.stopTest(); - System.assertEquals('Account', result, 'Contact with only Account in hierarchy should return Account'); + System.assertEquals('User', result, 'Contact with only Account in hierarchy should return Account'); } } @IsTest static void testFindParentObjectGrandchild() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - // OpportunityLineItem has a reference to Opportunity - // If Opportunity is also a known child, it should be the parent + System.runAs(new User(Id = UserInfo.getUserId())) { + // ManagedUsers are child Users, and User has CreatedBy lookup to User. Map childRelNameByObject = new Map{ - 'Opportunity' => 'Opportunities', - 'OpportunityLineItem' => 'OpportunityLineItems' + 'User' => 'ManagedUsers' }; Test.startTest(); - String result = DocGenController.findParentObject('OpportunityLineItem', 'Account', childRelNameByObject); + String result = DocGenController.findParentObject('User', 'User', childRelNameByObject); Test.stopTest(); - System.assertEquals('Opportunity', result, 'OpportunityLineItem should resolve parent as Opportunity when Opportunity is a known child'); + System.assertEquals('User', result, 'User child should resolve parent as User via CreatedBy'); } } @IsTest static void testFindParentObjectInvalidObject() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map childRelNameByObject = new Map(); Test.startTest(); - String result = DocGenController.findParentObject('NonExistentObj__xyz', 'Account', childRelNameByObject); + String result = DocGenController.findParentObject('NonExistentObj__xyz', 'User', childRelNameByObject); Test.stopTest(); - System.assertEquals('Account', result, 'Invalid object should fall back to base object'); + System.assertEquals('User', result, 'Invalid object should fall back to base object'); } } @@ -2507,8 +2421,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testFindJunctionRelationshipKnown() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { SObjectType oppType = Schema.getGlobalDescribe().get('Opportunity'); Test.startTest(); @@ -2522,8 +2435,7 @@ private class DocGenControllerTests { @IsTest static void testFindJunctionRelationshipCampaignContact() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { SObjectType campType = Schema.getGlobalDescribe().get('Campaign'); Test.startTest(); @@ -2536,13 +2448,12 @@ private class DocGenControllerTests { @IsTest static void testFindJunctionRelationshipNoMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - SObjectType accType = Schema.getGlobalDescribe().get('Account'); + System.runAs(new User(Id = UserInfo.getUserId())) { + SObjectType usrType = Schema.getGlobalDescribe().get('User'); Test.startTest(); // Account has no junction to Product2 - String result = DocGenController.findJunctionRelationship('Account', 'Product2', accType); + String result = DocGenController.findJunctionRelationship('User', 'Product2', usrType); Test.stopTest(); // May return null or a dynamically discovered junction @@ -2556,31 +2467,29 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testHasReferenceToObjectTrue() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - // OpportunityContactRole has a reference to Contact - SObjectType ocrType = Schema.getGlobalDescribe().get('OpportunityContactRole'); + System.runAs(new User(Id = UserInfo.getUserId())) { + // User has a reference to Contact + SObjectType ocrType = Schema.getGlobalDescribe().get('User'); Test.startTest(); - Boolean result = DocGenController.hasReferenceToObject(ocrType, 'Contact'); + Boolean result = DocGenController.hasReferenceToObject(ocrType, 'User'); Test.stopTest(); - System.assertEquals(true, result, 'OpportunityContactRole should have a reference to Contact'); + System.assertEquals(true, result, 'User should have a reference to Contact'); } } @IsTest static void testHasReferenceToObjectFalse() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - // Account does not have a reference to OpportunityLineItem - SObjectType accType = Schema.getGlobalDescribe().get('Account'); + System.runAs(new User(Id = UserInfo.getUserId())) { + // Account does not have a reference to User + SObjectType usrType = Schema.getGlobalDescribe().get('User'); Test.startTest(); - Boolean result = DocGenController.hasReferenceToObject(accType, 'OpportunityLineItem'); + Boolean result = DocGenController.hasReferenceToObject(usrType, 'Organization'); Test.stopTest(); - System.assertEquals(false, result, 'Account should not have a reference to OpportunityLineItem'); + System.assertEquals(false, result, 'User should not have a reference to Organization'); } } @@ -2589,8 +2498,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testResolveParentFieldNameDirect() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map accFieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2604,8 +2512,7 @@ private class DocGenControllerTests { @IsTest static void testResolveParentFieldNameCaseInsensitive() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map accFieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2619,13 +2526,12 @@ private class DocGenControllerTests { @IsTest static void testResolveParentFieldNameLabelMatch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map accFieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); // Label-based match — "Email" is the label for Email on User - String result = DocGenController.resolveParentFieldName('Owner', 'EMAIL_FIELD', 'Email', accFieldMap); + String result = DocGenController.resolveParentFieldName('Owner', 'EMAIL_FIELD', User.Email.getDescribe().getLabel(), accFieldMap); Test.stopTest(); System.assertEquals('Email', result, 'Label "Email" should resolve to Email on User'); @@ -2634,8 +2540,7 @@ private class DocGenControllerTests { @IsTest static void testResolveParentFieldNameNullRelationship() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map accFieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2649,8 +2554,7 @@ private class DocGenControllerTests { @IsTest static void testResolveParentFieldNameNoMatchingField() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Map accFieldMap = Schema.SObjectType.Account.fields.getMap(); Test.startTest(); @@ -2667,8 +2571,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGenerateDocumentDataFromCacheNullTemplateId() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Boolean caughtException = false; try { @@ -2686,8 +2589,7 @@ private class DocGenControllerTests { @IsTest static void testGenerateDocumentDataFromCacheTemplateNotFound() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Id fakeTemplateId = DocGen_Template__c.SObjectType.getDescribe(SObjectDescribeOptions.DEFERRED).getKeyPrefix() + '000000000000'; Test.startTest(); @@ -2707,8 +2609,7 @@ private class DocGenControllerTests { @IsTest static void testGenerateDocumentDataFromCacheSuccess() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; // Build a minimal valid DOCX and attach to template @@ -2763,8 +2664,7 @@ private class DocGenControllerTests { @IsTest static void testGenerateDocumentDataFromCacheReusesCache() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; // Attach a valid DOCX @@ -2826,14 +2726,10 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testGetChildRecordPdfsWithFilter() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; - insert new Contact(FirstName = 'FilterTest', LastName = 'Contact', AccountId = acc.Id); - + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List> result = DocGenController.getChildRecordPdfs( - acc.Id, 'Contact', 'AccountId', 'LastName = \'Contact\'' + UserInfo.getUserId(), 'User', 'CreatedById', 'LastName != null' ); Test.stopTest(); @@ -2847,11 +2743,10 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testProcessAndReturnDocumentWithImagesParam() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { createTestFile(); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account WHERE Name = 'Controller Test Account' LIMIT 1]; + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; Map resolvedImages = new Map{ 'https://example.com/image.png' => 'data:image/png;base64,iVBOR...' @@ -2862,7 +2757,7 @@ private class DocGenControllerTests { try { // Will likely fail because the test template is not a real DOCX, // but exercises the method signature with resolvedImages - DocGenController.processAndReturnDocumentWithImages(tpl.Id, acc.Id, resolvedImages); + DocGenController.processAndReturnDocumentWithImages(tpl.Id, usr.Id, resolvedImages); } catch (AuraHandledException e) { caughtException = true; } @@ -2877,8 +2772,7 @@ private class DocGenControllerTests { // ----------------------------------------------------------------------- @IsTest static void testResolveReportBaseObjectContactList() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); String result = DocGenController.resolveReportBaseObject('ContactList'); Test.stopTest(); @@ -2888,33 +2782,30 @@ private class DocGenControllerTests { } @IsTest - static void testResolveReportBaseObjectOpportunityProduct() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + static void testResolveReportBaseObjectUserProduct() { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - String result = DocGenController.resolveReportBaseObject('OpportunityProduct'); + String result = DocGenController.resolveReportBaseObject('UserProduct'); Test.stopTest(); - System.assertEquals('Opportunity', result, 'OpportunityProduct should resolve to Opportunity'); + System.assertEquals('User', result, 'UserProduct should resolve to User'); } } @IsTest - static void testResolveReportBaseObjectOpportunityContactProduct() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + static void testResolveReportBaseObjectUserContactProduct() { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - String result = DocGenController.resolveReportBaseObject('OpportunityContactProduct'); + String result = DocGenController.resolveReportBaseObject('UserContactProduct'); Test.stopTest(); - System.assertEquals('Opportunity', result, 'OpportunityContactProduct should resolve to Opportunity'); + System.assertEquals('User', result, 'UserContactProduct should resolve to User'); } } @IsTest static void testResolveReportBaseObjectLabelWithSuffix() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); // Label "Opportunities with Products" should match Opportunity plural label "Opportunities" String result = DocGenController.resolveReportBaseObject('UnknownXYZ', 'Opportunities with Products'); @@ -2930,8 +2821,7 @@ private class DocGenControllerTests { @IsTest static void testSearchDataProvidersNoFilter() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List providers = DocGenController.searchDataProviders(null); Test.stopTest(); @@ -2944,8 +2834,7 @@ private class DocGenControllerTests { @IsTest static void testSearchDataProvidersWithSearchTerm() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List providers = DocGenController.searchDataProviders('NonExistentClassName12345'); Test.stopTest(); @@ -2957,8 +2846,7 @@ private class DocGenControllerTests { @IsTest static void testSearchDataProvidersEmptyString() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); List providers = DocGenController.searchDataProviders(''); Test.stopTest(); @@ -2973,8 +2861,7 @@ private class DocGenControllerTests { @IsTest static void testValidateDataProviderBlankClassName() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Map result = DocGenController.validateDataProvider(''); Test.stopTest(); @@ -2986,8 +2873,7 @@ private class DocGenControllerTests { @IsTest static void testValidateDataProviderNullClassName() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Map result = DocGenController.validateDataProvider(null); Test.stopTest(); @@ -2999,8 +2885,7 @@ private class DocGenControllerTests { @IsTest static void testValidateDataProviderNonExistentClass() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Map result = DocGenController.validateDataProvider('CompletelyFakeClassName99999'); Test.stopTest(); @@ -3013,11 +2898,10 @@ private class DocGenControllerTests { @IsTest static void testValidateDataProviderNonImplementingClass() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // Account is a real class/type but does not implement DocGenDataProvider Test.startTest(); - Map result = DocGenController.validateDataProvider('Account'); + Map result = DocGenController.validateDataProvider('User'); Test.stopTest(); System.assertEquals(false, result.get('valid'), 'Should be invalid for class that does not implement DocGenDataProvider'); diff --git a/force-app/main/default/classes/DocGenMiscTests.cls b/force-app/main/default/classes/DocGenMiscTests.cls index 9c6246f..d092e82 100644 --- a/force-app/main/default/classes/DocGenMiscTests.cls +++ b/force-app/main/default/classes/DocGenMiscTests.cls @@ -1,19 +1,51 @@ -@IsTest +@IsTest(IsParallel=false) private class DocGenMiscTests { - + private static String CHATTER_FREE_USER_PROFILE_NAME = 'Chatter Free User'; + private static String UNIQUE_IDENTIFIER = 'DocGenMiscTests'; + private static String UNIQUE_USERNAME = String.format('manageduser+{0}@test.com{1}', new List{UNIQUE_IDENTIFIER, UserInfo.getUserId()}); @TestSetup static void setup() { - Account acc = new Account(Name = 'Misc Test Account', AccountSource = 'Web', Website = 'https://test.com'); - insert acc; - DocGen_Template__c tpl = new DocGen_Template__c( Name = 'Misc Test Template', - Base_Object_API__c = 'Account', - Query_Config__c = 'Name, AccountSource', + Base_Object_API__c = 'User', + Query_Config__c = 'Email, Name, CreatedBy.Email, LastName', Type__c = 'Word' ); insert tpl; - } + + createManagedUser(UNIQUE_IDENTIFIER); + } + + private static void updateUser(User usr) { + // avoid mixed dml + System.runAs(new User(Id = UserInfo.getUserId())) { + update usr; + } + } + + private static void createManagedUser(String uniqueIdentifier) { + System.runAs(new User(Id = UserInfo.getUserId())) { + // this should create a new chatter free user and set the manager to the current user + User usr = new User( + FirstName = 'Managed', + LastName = 'User', + Email = 'manageduser@test.com', + Username = UNIQUE_USERNAME, + Alias = 'muser', + LanguageLocaleKey = 'en_US', + LocaleSidKey = 'en_US', + EmailEncodingKey = 'UTF-8', + ManagerId = UserInfo.getUserId(), + ProfileId = [SELECT Id FROM Profile WHERE Name = :CHATTER_FREE_USER_PROFILE_NAME LIMIT 1].Id, + TimeZoneSidKey = 'America/Los_Angeles' + ); + insert usr; + } + } + + private static User getManagedUser() { + return [SELECT Id, Name, FirstName, LastName, CreatedBy.Name FROM User WHERE Username = :UNIQUE_USERNAME LIMIT 1]; + } /** * Creates a ContentVersion linked to the test template (fake content). @@ -85,8 +117,7 @@ private class DocGenMiscTests { @IsTest static void testGetOrgUrl() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); String orgUrl = DocGenSetupController.getOrgUrl(); Test.stopTest(); @@ -98,8 +129,7 @@ private class DocGenMiscTests { @IsTest static void testGetSettings() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); DocGen_Settings__c settings = DocGenSetupController.getSettings(); Test.stopTest(); @@ -110,8 +140,7 @@ private class DocGenMiscTests { @IsTest static void testSaveSettings() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); DocGenSetupController.saveSettings('https://example.my.site.com'); Test.stopTest(); @@ -123,8 +152,7 @@ private class DocGenMiscTests { @IsTest static void testSaveSettingsUpdatesExisting() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGenSetupController.saveSettings('https://first.my.site.com'); Test.startTest(); @@ -142,30 +170,27 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithValidFields() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, AccountSource'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, Id'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for valid fields'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should match test account'); - System.assertEquals('Web', result.get('AccountSource'), 'AccountSource should match test account'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should match test User'); + System.assertEquals(UserInfo.getUserId(), result.get('Id'), 'Id should match test User'); } } @IsTest static void testGetRecordDataWithInvalidObject() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); Boolean caught = false; Test.startTest(); try { - DocGenDataRetriever.getRecordData(acc.Id, 'NotARealObject__c', 'Name'); + DocGenDataRetriever.getRecordData(usr.Id, 'NotARealObject__c', 'Name'); } catch (AuraHandledException e) { caught = true; } @@ -177,8 +202,7 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithBlankParams() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Boolean caught = false; Test.startTest(); @@ -195,51 +219,46 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithRelationshipField() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, Owner.Name'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, CreatedBy.Name'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for relationship field query'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should match test account'); - System.assert(result.containsKey('Owner'), 'Should contain Owner relationship data'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should match test User'); + System.assert(result.containsKey('CreatedBy'), 'Should contain CreatedBy relationship data'); } } @IsTest static void testGetRecordDataWithNonExistentField() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, TotallyFakeField__xyz'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, TotallyFakeField__xyz'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null even with non-existent field'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should still be returned with non-existent field'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should still be returned with non-existent field'); } } @IsTest static void testGetRecordDataWithBlankObjectOrFields() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); Boolean caught1 = false; Boolean caught2 = false; Test.startTest(); try { - DocGenDataRetriever.getRecordData(acc.Id, '', 'Name'); + DocGenDataRetriever.getRecordData(usr.Id, '', 'Name'); } catch (AuraHandledException e) { caught1 = true; } try { - DocGenDataRetriever.getRecordData(acc.Id, 'Account', ''); + DocGenDataRetriever.getRecordData(usr.Id, 'User', ''); } catch (AuraHandledException e) { caught2 = true; } @@ -257,11 +276,11 @@ private class DocGenMiscTests { @IsTest static void testGenerateDocumentFlowActionErrorPath() { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); DocGenFlowAction.Request req = new DocGenFlowAction.Request(); req.templateId = tpl.Id; - req.recordId = acc.Id; + req.recordId = usr.Id; Test.startTest(); List responses = DocGenFlowAction.generateDocument( @@ -308,11 +327,11 @@ private class DocGenMiscTests { static void testProcessDocumentThrowsOnInvalidDocx() { createTestFile(); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); try { - DocGenService.processDocument(tpl.Id, acc.Id); + DocGenService.processDocument(tpl.Id, usr.Id); System.assert(false, 'Expected exception for invalid DOCX'); } catch (DocGenException e) { System.assert(e.getMessage().length() > 0, 'DocGenException message should not be empty'); @@ -324,11 +343,11 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentNullTemplate() { - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); try { - DocGenService.processDocument(null, acc.Id); + DocGenService.processDocument(null, usr.Id); System.assert(false, 'Expected exception for null template'); } catch (Exception e) { System.assert(e.getMessage().length() > 0, 'Exception message should not be empty for null template'); @@ -361,14 +380,14 @@ private class DocGenMiscTests { '' + '' + '{Name}' + - '{AccountSource}'; + '{Id}'; createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result, 'processDocument result should not be null'); @@ -386,10 +405,9 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; Test.startTest(); - Id docId = DocGenService.generateDocument(tpl.Id, acc.Id); + Id docId = DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, docId, 'Should return ContentDocumentId'); @@ -408,10 +426,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Merged runs document blob should not be null'); @@ -419,7 +437,7 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentWithSectionTag() { - // Boolean-true section (Account always truthy via Owner) + // Boolean-true section (User always truthy via Owner) String docXml = '' + '' + @@ -428,10 +446,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for section tag test'); @@ -439,23 +457,23 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentWithHtmlFieldValue() { - // Account Website field is plain text, but we test that HTML stripping works - // by using a field config that includes Website + // User Signature field is plain text, but we test that HTML stripping works + // by using a field config that includes Signature String docXml = '' + '' + - '{Name} - {Website}'; + '{Name} - {Signature}'; createValidDocxFile(docXml); - // Update template query config to include Website + // Update template query config to include Signature DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, AccountSource, Website'; + tpl.Query_Config__c = 'Name, Id, Signature'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for HTML field value test'); @@ -470,18 +488,16 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Document_Title_Format__c = 'Doc_{Name}_{AccountSource}'; + tpl.Document_Title_Format__c = 'Doc_{Name}_{Id}'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); String title = (String) result.get('title'); - System.assert(title.contains('Misc Test Account'), 'Title should contain account name'); - System.assert(title.contains('Web'), 'Title should contain account source'); + System.assert(title.contains(UserInfo.getName()), 'Title should contain User name'); + System.assert(title.contains(UserInfo.getUserId()), 'Title should contain User source'); } @IsTest @@ -494,10 +510,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for image tag test'); @@ -513,10 +529,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for image size tag test'); @@ -532,10 +548,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for closing tag only test'); @@ -551,12 +567,12 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Map result; Test.startTest(); try { - result = DocGenService.processDocument(tpl.Id, acc.Id); + result = DocGenService.processDocument(tpl.Id, usr.Id); } catch (DocGenException e) { System.assert(e.getMessage().contains('Malformed loop tag'), 'Exception message should contain "Malformed loop tag"'); } @@ -590,7 +606,7 @@ private class DocGenMiscTests { zw.addEntry('word/document.xml', Blob.valueOf(bodyXml)); String headerXml = 'Header: {Name}'; zw.addEntry('word/header1.xml', Blob.valueOf(headerXml)); - String footerXml = 'Footer: {AccountSource}'; + String footerXml = 'Footer: {Id}'; zw.addEntry('word/footer1.xml', Blob.valueOf(footerXml)); ContentVersion cv = new ContentVersion(Title='HeaderFooterDoc', PathOnClient='HeaderFooterDoc.docx', VersionData=zw.getArchive()); @@ -599,10 +615,10 @@ private class DocGenMiscTests { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for header and footer test'); @@ -620,10 +636,8 @@ private class DocGenMiscTests { tpl.Output_Format__c = 'PDF'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Id docId = DocGenService.generateDocument(tpl.Id, acc.Id); + Id docId = DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, docId, 'Document ID should not be null for PDF format test'); @@ -637,13 +651,12 @@ private class DocGenMiscTests { static void testProcessDocumentWithChildSubquery() { // Use Contacts subquery to exercise loop processing with records list DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, (SELECT FirstName, LastName FROM Contacts)'; - tpl.Base_Object_API__c = 'Account'; + tpl.Query_Config__c = 'Name, (SELECT Email FROM ManagedUsers)'; + tpl.Base_Object_API__c = 'User'; update tpl; - // Add a contact to the account - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new Contact(FirstName = 'Loop', LastName = 'Tester', AccountId = acc.Id); + // Add a contact to the User + User usr = getManagedUser(); String docXml = '' + @@ -654,7 +667,7 @@ private class DocGenMiscTests { createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for child subquery test'); @@ -664,11 +677,10 @@ private class DocGenMiscTests { static void testProcessDocumentWithTableRowLoop() { // Section inside a — exercises table row expansion code DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, (SELECT FirstName, LastName FROM Contacts)'; + tpl.Query_Config__c = 'Name, (SELECT Email FROM ManagedUsers)'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new Contact(FirstName = 'Row', LastName = 'Expand', AccountId = acc.Id); + User usr = getManagedUser(); String docXml = '' + @@ -680,7 +692,7 @@ private class DocGenMiscTests { createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for table row loop test'); @@ -699,10 +711,10 @@ private class DocGenMiscTests { '{Owner.Name}'; createValidDocxFile(docXml); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for nested dot path test'); @@ -723,23 +735,23 @@ private class DocGenMiscTests { // Template with {%ImageField} — field value will be a CV Id // We need the query to return a field containing the CV Id - // Use Description field on Account to hold the CV Id - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = imgCv.Id; - update acc; + // Use AboutMe field on User to hold the CV Id + User usr = getManagedUser(); + usr.AboutMe = imgCv.Id; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description:100x80}'; + '{%AboutMe:100x80}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for base64 image field test'); @@ -748,22 +760,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentWithHtmlRichText() { // Field value contains

/

HTML that should be stripped - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

Hello

World
'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

Hello

World
'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for HTML rich text test'); @@ -800,10 +812,10 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for PowerPoint test'); @@ -823,14 +835,12 @@ private class DocGenMiscTests { tpl.Document_Title_Format__c = null; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); String title = (String) result.get('title'); - System.assertEquals('Misc Test Account', title, 'Should fall back to record Name'); + System.assertEquals(UserInfo.getName(), title, 'Should fall back to record Name'); } // ========================================================================= @@ -840,52 +850,47 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithSubquery() { // Exercises the subquery (parenthesized SELECT) branch in field parsing - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new Contact(FirstName = 'Sub', LastName = 'Query', AccountId = acc.Id); - Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, (SELECT FirstName, LastName FROM Contacts)'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, (SELECT Email FROM ManagedUsers)'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for subquery test'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should match for subquery test'); - System.assert(result.containsKey('Contacts'), 'Should contain Contacts subquery'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should match for subquery test'); + System.assert(result.containsKey('ManagedUsers'), 'Should contain ManagedUsers subquery'); } @IsTest static void testGetRecordDataWithAutoAppendC() { - // Exercises the __c auto-append branch — AccountSource exists, but try without __c - // "Website" is a standard field so this tests the field-not-found skip path - Account acc = [SELECT Id FROM Account LIMIT 1]; + // Exercises the __c auto-append branch — Id exists, but try without __c + // "Signature" is a standard field so this tests the field-not-found skip path Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, ZZZInvalidField'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, ZZZInvalidField'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for auto-append test'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should match for auto-append test'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should match for auto-append test'); } @IsTest static void testGetRecordDataWithInvalidRelationship() { // Exercises the invalid relationship field branch (relFound = false) - Account acc = [SELECT Id FROM Account LIMIT 1]; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, FakeRel__r.Field'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, FakeRel__r.Field'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for invalid relationship test'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should match for invalid relationship test'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should match for invalid relationship test'); } @IsTest static void testGetRecordDataAllFieldsInvalid() { // Exercises the cleanSelect == '' fallback to 'Id' - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'ZZZFake1, ZZZFake2'); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', 'ZZZFake1, ZZZFake2'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for all-fields-invalid test'); @@ -895,33 +900,30 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithBlankFieldPart() { // Exercises the blank field part skip (trailing comma) - Account acc = [SELECT Id FROM Account LIMIT 1]; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, , AccountSource'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, , Id'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for blank field part test'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should match for blank field part test'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should match for blank field part test'); } @IsTest static void testGetRecordDataWithAddressField() { // Exercises the Address type branch in mapSObject - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.BillingStreet = '123 Main St'; - acc.BillingCity = 'TestCity'; - acc.BillingState = 'CA'; - acc.BillingPostalCode = '90210'; - acc.BillingCountry = 'US'; - update acc; + User usr = getManagedUser(); + usr.Street = '123 Main St'; + usr.City = 'TestCity'; + usr.PostalCode = '90210'; + updateUser(usr); Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, BillingAddress'); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', 'Name, Address'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for address field test'); - System.assert(result.containsKey('BillingAddress'), 'Should contain BillingAddress compound field'); + System.assert(result.containsKey('Address'), 'Should contain BillingAddress compound field'); } // ========================================================================= @@ -942,11 +944,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; DocGenFlowAction.Request req = new DocGenFlowAction.Request(); req.templateId = tpl.Id; - req.recordId = acc.Id; + req.recordId = UserInfo.getUserId(); Test.startTest(); List responses = DocGenFlowAction.generateDocument( @@ -1004,10 +1005,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.generatePdfBlob(tpl.Id, acc.Id); + Map result = DocGenService.generatePdfBlob(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Should return a PDF blob'); @@ -1041,12 +1042,12 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); Boolean caught = false; try { - DocGenService.generatePdfBlob(tpl.Id, acc.Id); + DocGenService.generatePdfBlob(tpl.Id, usr.Id); } catch (DocGenException e) { caught = true; System.assert(e.getMessage().contains('only supported for Word'), 'Exception should mention Word-only support'); @@ -1060,44 +1061,42 @@ private class DocGenMiscTests { String docXml = '' + '' + - 'Account: {Name}, Source: {AccountSource}'; + 'User: {Name}, Source: {Id}'; createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; tpl.Document_Title_Format__c = 'PDF_{Name}'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Map result = DocGenService.generatePdfBlob(tpl.Id, acc.Id); + Map result = DocGenService.generatePdfBlob(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for PDF blob with title format'); String title = (String) result.get('title'); - System.assert(title.contains('Misc Test Account'), 'PDF title should contain account name'); + System.assert(title.contains(UserInfo.getName()), 'PDF title should contain User name'); } @IsTest static void testGeneratePdfBlobWithImage() { // PDF path with image — exercises imageBase64ByRelId collection String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('PNGFAKE')); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'data:image/png;base64,' + tinyBase64; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'data:image/png;base64,' + tinyBase64; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.generatePdfBlob(tpl.Id, acc.Id); + Map result = DocGenService.generatePdfBlob(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for PDF blob with image'); @@ -1119,10 +1118,8 @@ private class DocGenMiscTests { tpl.Output_Format__c = 'PDF'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Id docId = DocGenService.generateDocument(tpl.Id, acc.Id); + Id docId = DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, docId, 'Document ID should not be null for PDF save test'); @@ -1161,10 +1158,8 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Id docId = DocGenService.generateDocument(tpl.Id, acc.Id); + Id docId = DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, docId, 'Document ID should not be null for PPTX save test'); @@ -1179,22 +1174,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentConditionalSectionTruthyString() { // Section where key resolves to a non-null string — exercises the non-null fallback path - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'Has description'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'Has AboutMe'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'UserName, AboutMe'; update tpl; String docXml = '' + '' + - '{#Description}Has Desc: {Description}{/Description}'; + '{#AboutMe}Has Desc: {AboutMe}{/AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for truthy conditional section'); @@ -1204,19 +1199,19 @@ private class DocGenMiscTests { static void testProcessDocumentConditionalSectionNullValue() { // Section where key resolves to null — produces empty output for section DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{#Description}This should not appear{/Description}'; + '{#AboutMe}This should not appear{/AboutMe}'; createValidDocxFile(docXml); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for null conditional section'); @@ -1239,10 +1234,10 @@ private class DocGenMiscTests { '{CreatedDate:MM/dd/yyyy}'; createValidDocxFile(docXml); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for date format tag test'); @@ -1259,10 +1254,10 @@ private class DocGenMiscTests { '{Name:uppercase}'; createValidDocxFile(docXml); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for colon in non-date field'); @@ -1275,22 +1270,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentHtmlSpanAndBrStrip() { // Field value with and
tags — exercises stripHtmlTags path - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

Line one


Line two'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

Line one


Line two'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for HTML span/br strip test'); @@ -1305,22 +1300,22 @@ private class DocGenMiscTests { // Field value contains — exercises // the rich text image detection and extractImageFromHtml data URI path String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('PNGDATA')); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = ''; - update acc; + User usr = getManagedUser(); + usr.AboutMe = ''; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'UserName, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for field with img tag test'); @@ -1328,24 +1323,24 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagDataUri() { - // {%Description} where Description is a data:image/jpeg URI — exercises data URI branch in buildImageXml + // {%AboutMe} where AboutMe is a data:image/jpeg URI — exercises data URI branch in buildImageXml String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('JPEGFAKE')); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'data:image/jpeg;base64,' + tinyBase64; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'data:image/jpeg;base64,' + tinyBase64; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for image tag data URI test'); @@ -1353,23 +1348,23 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagBlankValue() { - // {%Description} where Description is blank — exercises null return from buildImageXml - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = ''; - update acc; + // {%AboutMe} where AboutMe is blank — exercises null return from buildImageXml + User usr = getManagedUser(); + usr.AboutMe = ''; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for blank image value test'); @@ -1377,24 +1372,24 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagWithDimensions() { - // {%Description:200x150} with a data URI — exercises size parsing in image tag + // {%AboutMe:200x150} with a data URI — exercises size parsing in image tag String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('SIZED')); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'data:image/png;base64,' + tinyBase64; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'data:image/png;base64,' + tinyBase64; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description:200x150}'; + '{%AboutMe:200x150}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for image tag with dimensions'); @@ -1406,29 +1401,29 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagRawBase64() { - // {%Description} where Description is a long raw base64 string (no data URI prefix) + // {%AboutMe} where AboutMe is a long raw base64 string (no data URI prefix) // Exercises the "raw base64" branch (length > 100, no / or space) // Generate a base64 string > 100 chars String longBase64 = EncodingUtil.base64Encode(Blob.valueOf( 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' )); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = longBase64; - update acc; + User usr = getManagedUser(); + usr.AboutMe = longBase64; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for raw base64 image test'); @@ -1436,7 +1431,7 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagContentVersionId() { - // {%Description} where Description holds a ContentVersion ID (starts with 068) + // {%AboutMe} where AboutMe holds a ContentVersion ID (starts with 068) ContentVersion imgCv = new ContentVersion( Title = 'TestImage', PathOnClient = 'TestImage.png', @@ -1445,22 +1440,22 @@ private class DocGenMiscTests { insert imgCv; imgCv = [SELECT Id FROM ContentVersion WHERE Id = :imgCv.Id]; - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = imgCv.Id; - update acc; + User usr = getManagedUser(); + usr.AboutMe = imgCv.Id; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for ContentVersion ID image test'); @@ -1472,24 +1467,24 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagRefidUrl() { - // {%Description} where Description contains a refid URL — exercises fetchSalesforceImage with refid + // {%AboutMe} where AboutMe contains a refid URL — exercises fetchSalesforceImage with refid // Will fail to find image (no matching record) but exercises the code path - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'https://example.com/servlet/rtaImage?refid=0EM000000000001'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'https://example.com/servlet/rtaImage?refid=0EM000000000001'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); // Image could not be resolved, but document should still generate @@ -1498,23 +1493,23 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagServletUrl() { - // {%Description} with /servlet/ URL — exercises the servlet/sfc branch - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '/servlet/filedownload?file=015000000000001'; - update acc; + // {%AboutMe} with /servlet/ URL — exercises the servlet/sfc branch + User usr = getManagedUser(); + usr.AboutMe = '/servlet/filedownload?file=015000000000001'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for servlet URL image test'); @@ -1538,10 +1533,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for three-segment merge test'); @@ -1557,10 +1552,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for no-tags document'); @@ -1580,12 +1575,12 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Map result; Test.startTest(); try { - result = DocGenService.processDocument(tpl.Id, acc.Id); + result = DocGenService.processDocument(tpl.Id, usr.Id); } catch (DocGenException e) { System.assert(e.getMessage().contains('Malformed merge tag'), 'Exception message should contain "Malformed merge tag"'); } @@ -1603,10 +1598,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for empty body test'); @@ -1622,10 +1617,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for null field value test'); @@ -1633,21 +1628,21 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentXmlSpecialChars() { - // Account name with & < > — exercises escapeXml - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Name = 'Acme & Co '; - update acc; + // User name with & < > — exercises escapeXml + User usr = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId() LIMIT 1]; + usr.AboutMe = 'Acme & Co '; + updateUser(usr); String docXml = '' + '' + - '{Name}'; + '{AboutMe}'; createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for XML special chars test'); @@ -1667,10 +1662,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for case-insensitive field test'); @@ -1689,10 +1684,10 @@ private class DocGenMiscTests { '{Owner.Manager.Name}'; createValidDocxFile(docXml); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for deep nested null path'); @@ -1711,18 +1706,16 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Document_Title_Format__c = 'Doc-{Name}-{MissingField}-{AccountSource}'; + tpl.Document_Title_Format__c = 'Doc-{LastName}-{MissingField}-{Id}'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); String title = (String) result.get('title'); - System.assert(title.contains('Misc Test Account'), 'Title should contain account name for mixed fields'); - System.assert(title.contains('Web'), 'Title should contain account source for mixed fields'); + System.assert(title.contains(UserInfo.getLastName()), 'Title should contain User name for mixed fields'); + System.assert(title.contains(UserInfo.getUserId()), 'Title should contain User source for mixed fields'); System.assert(title.contains('--'), 'Missing field should be replaced with empty string'); } @@ -1733,14 +1726,10 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentTableRowExpansionMultipleRows() { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, (SELECT FirstName, LastName FROM Contacts)'; + tpl.Query_Config__c = 'Name, (SELECT Email FROM ManagedUsers)'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new List{ - new Contact(FirstName = 'Alice', LastName = 'Smith', AccountId = acc.Id), - new Contact(FirstName = 'Bob', LastName = 'Jones', AccountId = acc.Id) - }; + User usr = getManagedUser(); String docXml = '' + @@ -1752,7 +1741,7 @@ private class DocGenMiscTests { createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for multi-row table expansion'); @@ -1764,22 +1753,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentNestedSections() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'Present'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'Present'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description, AccountSource'; + tpl.Query_Config__c = 'Name, AboutMe, Id'; update tpl; String docXml = '' + '' + - '{#Description}{#AccountSource}Both present{/AccountSource}{/Description}'; + '{#AboutMe}{#Id}Both present{/Id}{/AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for nested sections test'); @@ -1793,12 +1782,9 @@ private class DocGenMiscTests { static void testProcessDocumentSectionOutsideTr() { // {#Contacts} before TR, {/Contacts} after TR — exercises trClosesBefore path DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, (SELECT FirstName FROM Contacts)'; + tpl.Query_Config__c = 'Name, (SELECT FirstName FROM ManagedUsers)'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new Contact(FirstName = 'Multi', LastName = 'Row', AccountId = acc.Id); - String docXml = '' + '' + @@ -1808,7 +1794,7 @@ private class DocGenMiscTests { createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for section outside TR test'); @@ -1821,12 +1807,12 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageWithExistingContentTypes() { String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('IMG')); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'data:image/png;base64,' + tinyBase64; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'data:image/png;base64,' + tinyBase64; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; Compression.ZipWriter zw = new Compression.ZipWriter(); @@ -1853,7 +1839,7 @@ private class DocGenMiscTests { zw.addEntry('word/document.xml', Blob.valueOf( '' + '' + - '{%Description}' + '{%AboutMe}' )); ContentVersion cv = new ContentVersion(Title='ImgExist', PathOnClient='ImgExist.docx', VersionData=zw.getArchive()); @@ -1862,7 +1848,7 @@ private class DocGenMiscTests { insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for existing content types test'); @@ -1876,23 +1862,23 @@ private class DocGenMiscTests { static void testProcessDocumentMultipleImageTags() { String pngBase64 = EncodingUtil.base64Encode(Blob.valueOf('PNGDATA')); String jpgBase64 = EncodingUtil.base64Encode(Blob.valueOf('JPGDATA')); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'data:image/png;base64,' + pngBase64; - acc.Website = 'data:image/jpeg;base64,' + jpgBase64; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'data:image/png;base64,' + pngBase64; + usr.Signature = 'data:image/jpeg;base64,' + jpgBase64; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description, Website'; + tpl.Query_Config__c = 'Name, AboutMe, Signature'; update tpl; String docXml = '' + '' + - '{%Description} {%Website}'; + '{%AboutMe} {%Signature}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for multiple image tags test'); @@ -1928,7 +1914,7 @@ private class DocGenMiscTests { '{Name}'; String slide2 = '' + '' + - '{AccountSource}'; + '{Id}'; zw.addEntry('ppt/slides/slide1.xml', Blob.valueOf(slide1)); zw.addEntry('ppt/slides/slide2.xml', Blob.valueOf(slide2)); @@ -1937,10 +1923,10 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for multiple slides test'); @@ -1964,10 +1950,8 @@ private class DocGenMiscTests { tpl.Document_Title_Format__c = null; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Id docId = DocGenService.generateDocument(tpl.Id, acc.Id); + Id docId = DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, docId, 'Document ID should not be null for null title fallback'); @@ -1980,22 +1964,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImgTagWithRefid() { // with refid= attribute — exercises extractImageFromHtml refid branch - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = ''; - update acc; + User usr = getManagedUser(); + usr.AboutMe = ''; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for img tag with refid'); @@ -2004,22 +1988,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImgTagWithSfcUrl() { // with /sfc/ URL — exercises extractImageFromHtml servlet/sfc branch - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = ''; - update acc; + User usr = getManagedUser(); + usr.AboutMe = ''; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for img tag with sfc URL'); @@ -2031,7 +2015,7 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageContentDocumentId() { - // {%Description} where Description holds a ContentDocument ID (069...) + // {%AboutMe} where AboutMe holds a ContentDocument ID (069...) ContentVersion imgCv = new ContentVersion( Title = 'TestImg069', PathOnClient = 'TestImg069.png', @@ -2040,22 +2024,22 @@ private class DocGenMiscTests { insert imgCv; Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :imgCv.Id].ContentDocumentId; - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = String.valueOf(conDocId); - update acc; + User usr = getManagedUser(); + usr.AboutMe = String.valueOf(conDocId); + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for ContentDocument ID test'); @@ -2068,19 +2052,19 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentWithResolvedImages() { // Exercises the resolvedImages map (line 54-56) — applyResolvedImages with tag - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('IMGDATA')); - acc.Description = ''; - update acc; + usr.AboutMe = ''; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Map resolvedImages = new Map{ @@ -2088,7 +2072,7 @@ private class DocGenMiscTests { }; Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id, resolvedImages); + Map result = DocGenService.processDocument(tpl.Id, usr.Id, resolvedImages); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for resolved images test'); @@ -2107,10 +2091,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.generatePdfBlob(tpl.Id, acc.Id); + Map result = DocGenService.generatePdfBlob(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for valid PDF blob test'); @@ -2134,10 +2118,8 @@ private class DocGenMiscTests { tpl.Output_Format__c = 'PDF'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - Id docId = DocGenService.generateDocument(tpl.Id, acc.Id); + Id docId = DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, docId, 'Document ID should not be null for PDF save test'); @@ -2156,14 +2138,14 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Map imageMap = new Map{ 'rIdTest' => 'https://example.com/image.png' }; Test.startTest(); - Map result = DocGenService.processDocumentAsHtmlWithImageMap(tpl.Id, acc.Id, imageMap); + Map result = DocGenService.processDocumentAsHtmlWithImageMap(tpl.Id, usr.Id, imageMap); Test.stopTest(); System.assertNotEquals(null, result.get('html'), 'HTML should not be null for image map test'); @@ -2210,7 +2192,7 @@ private class DocGenMiscTests { Content_Version_Id__c = cv.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account' + Base_Object_API__c = 'User' ); insert ver; @@ -2229,22 +2211,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentRichTextWithFormattingTags() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

Bold Italic Underline

'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

Bold Italic Underline

'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for rich text formatting tags'); @@ -2252,22 +2234,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentRichTextWithStrongAndEm() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'Strong and Emphasis'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'Strong and Emphasis'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for strong/em tags test'); @@ -2279,22 +2261,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentRichTextImgWithSalesforceUrl() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

Text more text

'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

Text more text

'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for rich text Salesforce URL img'); @@ -2306,22 +2288,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentImageTagHttpsUrl() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'https://example.com/some-image.png'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = 'https://example.com/some-image.png'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for HTTPS URL image tag'); @@ -2349,21 +2331,21 @@ private class DocGenMiscTests { zw.addEntry('ppt/slides/slide1.xml', Blob.valueOf( '' + '' + - '{%Description}' + '{%AboutMe}' )); ContentVersion cv = new ContentVersion(Title='PPTImg', PathOnClient='PPTImg.pptx', VersionData=zw.getArchive()); insert cv; Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = 'data:image/png;base64,' + EncodingUtil.base64Encode(Blob.valueOf('IMG')); - update acc; - tpl.Query_Config__c = 'Name, Description'; + User usr = getManagedUser(); + usr.AboutMe = 'data:image/png;base64,' + EncodingUtil.base64Encode(Blob.valueOf('IMG')); + updateUser(usr); + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for PowerPoint image tag skip'); @@ -2377,12 +2359,12 @@ private class DocGenMiscTests { static void testProcessDocumentPowerPointHtmlStripped() { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; tpl.Type__c = 'PowerPoint'; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

Paragraph bold

'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

Paragraph bold

'; + updateUser(usr); Compression.ZipWriter zw = new Compression.ZipWriter(); zw.addEntry('[Content_Types].xml', Blob.valueOf( @@ -2396,7 +2378,7 @@ private class DocGenMiscTests { zw.addEntry('ppt/slides/slide1.xml', Blob.valueOf( '' + '' + - '{Description}' + '{AboutMe}' )); ContentVersion cv = new ContentVersion(Title='PPTHtml2', PathOnClient='PPTHtml2.pptx', VersionData=zw.getArchive()); insert cv; @@ -2404,7 +2386,7 @@ private class DocGenMiscTests { insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for PowerPoint HTML stripped'); @@ -2423,10 +2405,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.generatePdfBlob(tpl.Id, acc.Id); + Map result = DocGenService.generatePdfBlob(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for PDF download test'); @@ -2449,10 +2431,10 @@ private class DocGenMiscTests { '{CreatedDate:yyyy-MM-dd HH:mm}'; createValidDocxFile(docXml); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for alternate DateTime format'); @@ -2494,10 +2476,10 @@ private class DocGenMiscTests { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for existing template image'); @@ -2527,77 +2509,40 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV2BasicFields() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - // Create Opportunity linked to Account - Opportunity opp = new Opportunity( - Name = 'V2 Test Opp', - AccountId = acc.Id, - StageName = 'Prospecting', - CloseDate = Date.today().addDays(30) - ); - insert opp; - - String v2Config = '{"v":2,"baseObject":"Opportunity","baseFields":["Name","StageName"],' + - '"parentFields":["Account.Name"],"children":[],"junctions":[]}'; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name","Email"],' + + '"parentFields":["CreatedBy.Name"],"children":[],"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(opp.Id, 'Opportunity', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'V2 result should not be null'); - System.assertEquals('V2 Test Opp', result.get('Name'), 'V2 should return Opp Name'); - System.assert(result.containsKey('Account'), 'V2 should include parent Account data'); - Map accData = (Map) result.get('Account'); - System.assertEquals('Misc Test Account', accData.get('Name'), 'V2 parent Account.Name should match'); + System.assertEquals(usr.Name, result.get('Name'), 'V2 should return User Name'); + System.assert(result.containsKey('CreatedBy'), 'V2 should include parent User data'); + Map CreatedByData = (Map) result.get('CreatedBy'); + System.assertEquals(usr.CreatedBy.Name, CreatedByData.get('Name'), 'V2 parent User.Name should match'); } } @IsTest static void testGetRecordDataV2WithChildren() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Opportunity opp = new Opportunity( - Name = 'V2 Child Test Opp', - AccountId = acc.Id, - StageName = 'Prospecting', - CloseDate = Date.today().addDays(30) - ); - insert opp; - - // Create Product + PricebookEntry + OpportunityLineItem - Product2 prod = new Product2(Name = 'V2 Test Product', IsActive = true); - insert prod; - Id stdPbId = Test.getStandardPricebookId(); - PricebookEntry pbe = new PricebookEntry( - Pricebook2Id = stdPbId, - Product2Id = prod.Id, - UnitPrice = 100, - IsActive = true - ); - insert pbe; - OpportunityLineItem oli = new OpportunityLineItem( - OpportunityId = opp.Id, - PricebookEntryId = pbe.Id, - Quantity = 5, - UnitPrice = 100 - ); - insert oli; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); - String v2Config = '{"v":2,"baseObject":"Opportunity","baseFields":["Name"],' + - '"parentFields":["Account.Name"],' + - '"children":[{"rel":"OpportunityLineItems","fields":["Quantity","UnitPrice"]}],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + + '"parentFields":["CreatedBy.Name"],' + + '"children":[{"rel":"ManagedUsers","fields":["Email"]}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(opp.Id, 'Opportunity', v2Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'V2 with children should not be null'); - System.assert(result.containsKey('OpportunityLineItems'), 'V2 should contain OpportunityLineItems'); - Map oliData = (Map) result.get('OpportunityLineItems'); + System.assert(result.containsKey('ManagedUsers'), 'V2 should contain ManagedUsers'); + Map oliData = (Map) result.get('ManagedUsers'); Integer totalSize = (Integer) oliData.get('totalSize'); System.assertEquals(1, totalSize, 'V2 should have 1 line item'); } @@ -2605,48 +2550,32 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV2WithJunction() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Contact con = new Contact(FirstName = 'Junction', LastName = 'TestContact', AccountId = acc.Id); - insert con; - - Opportunity opp = new Opportunity( - Name = 'V2 Junction Test Opp', - AccountId = acc.Id, - StageName = 'Prospecting', - CloseDate = Date.today().addDays(30) - ); - insert opp; - - OpportunityContactRole ocr = new OpportunityContactRole( - OpportunityId = opp.Id, - ContactId = con.Id, - Role = 'Decision Maker' - ); - insert ocr; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + ContentVersion cv = new ContentVersion(Title='Junction Test', PathOnClient='Junction Test.docx', VersionData=Blob.valueOf('FAKEPNGBYTES'), FirstPublishLocationId=UserInfo.getUserId()); + insert cv; - String v2Config = '{"v":2,"baseObject":"Opportunity","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + '"children":[],' + - '"junctions":[{"junctionRel":"OpportunityContactRoles","junctionFields":["Role"],' + - '"targetObject":"Contact","targetIdField":"ContactId","targetFields":["FirstName","LastName"]}]}'; + '"junctions":[{"junctionRel":"ContentDocumentLinks","junctionFields":["ShareType"],' + + '"targetObject":"ContentDocument","targetIdField":"ContentDocumentId","targetFields":["Id","Title"]}]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(opp.Id, 'Opportunity', v2Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'V2 junction result should not be null'); - System.assert(result.containsKey('OpportunityContactRoles'), 'V2 should contain junction relationship'); - Map ocrData = (Map) result.get('OpportunityContactRoles'); - List ocrRecords = (List) ocrData.get('records'); - System.assertEquals(1, ocrRecords.size(), 'V2 should have 1 OCR record'); + System.assert(result.containsKey('ContentDocumentLinks'), 'V2 should contain junction relationship'); + Map ocrData = (Map) result.get('ContentDocumentLinks'); + List cdlRecords = (List) ocrData.get('records'); + System.assert(cdlRecords.size() >= 1, 'V2 should have at least 1 CDL record'); // Verify junction stitching: Contact data should be embedded in OCR record - Map ocrRec = (Map) ocrRecords[0]; - System.assert(ocrRec.containsKey('Contact'), 'Junction should stitch Contact into OCR record'); - Map contactData = (Map) ocrRec.get('Contact'); - System.assertEquals('Junction', contactData.get('FirstName'), 'Stitched Contact FirstName should match'); + Map cdlRec = (Map) cdlRecords[0]; + System.assert(cdlRec.containsKey('ContentDocument'), 'Junction should stitch ContentDocument into CDL record'); + Map contentDocumentData = (Map) cdlRec.get('ContentDocument'); + System.assertEquals('Junction Test', contentDocumentData.get('Title'), 'Stitched ContentDocument Title should match'); } } @@ -2656,106 +2585,77 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV3BasicTree() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Contact con = new Contact(FirstName = 'TreeWalker', LastName = 'TestV3', AccountId = acc.Id); - insert con; - - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":["Owner.Name"],' + + System.runAs(new User(Id = UserInfo.getUserId())) { + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":["CreatedBy.Name"],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName","LastName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts"}]}'; + '{"id":"n1","object":"User","fields":["FirstName","LastName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers"}]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'V3 result should not be null'); - System.assertEquals('Misc Test Account', result.get('Name'), 'V3 root Name should match'); - System.assert(result.containsKey('Owner'), 'V3 should include parent Owner'); - System.assert(result.containsKey('Contacts'), 'V3 should contain Contacts child'); - Map contactsData = (Map) result.get('Contacts'); - Integer totalSize = (Integer) contactsData.get('totalSize'); - System.assert(totalSize >= 1, 'V3 should have at least 1 Contact'); + System.assertEquals(UserInfo.getName(), result.get('Name'), 'V3 root Name should match'); + System.assert(result.containsKey('CreatedBy'), 'V3 should include parent CreatedBy'); + System.assert(result.containsKey('ManagedUsers'), 'V3 should contain ManagedUsers child'); + Map managedUsersData = (Map) result.get('ManagedUsers'); + Integer totalSize = (Integer) managedUsersData.get('totalSize'); + System.assert(totalSize >= 1, 'V3 should have at least 1 ManagedUser'); } } @IsTest static void testGetRecordDataV3MultiLevel() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - - Opportunity opp = new Opportunity( - Name = 'V3 Multi Opp', - AccountId = acc.Id, - StageName = 'Prospecting', - CloseDate = Date.today().addDays(30) - ); - insert opp; - - Product2 prod = new Product2(Name = 'V3 Product', IsActive = true); - insert prod; - Id stdPbId = Test.getStandardPricebookId(); - PricebookEntry pbe = new PricebookEntry( - Pricebook2Id = stdPbId, - Product2Id = prod.Id, - UnitPrice = 50, - IsActive = true - ); - insert pbe; - OpportunityLineItem oli = new OpportunityLineItem( - OpportunityId = opp.Id, - PricebookEntryId = pbe.Id, - Quantity = 3, - UnitPrice = 50 + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + ContentVersion cv = new ContentVersion( + Title = 'V3 Multi Junction', + PathOnClient = 'V3 Multi Junction.docx', + VersionData = Blob.valueOf('FAKEPNGBYTES'), + FirstPublishLocationId = UserInfo.getUserId() ); - insert oli; + insert cv; - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Opportunity","fields":["Name","Amount"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Opportunities"},' + - '{"id":"n2","object":"OpportunityLineItem","fields":["Quantity"],"parentFields":["Product2.Name"],' + - '"parentNode":"n1","lookupField":"OpportunityId","relationshipName":"OpportunityLineItems"}]}'; + '{"id":"n1","object":"User","fields":["Name","Email"],"parentFields":["CreatedBy.Email"],' + + '"parentNode":"n0","lookupField":"ManagerId","relationshipName":"ManagedUsers"},' + + '{"id":"n2","object":"ContentDocumentLink","fields":["ShareType"],"parentFields":[],' + + '"parentNode":"n1","lookupField":"LinkedEntityId","relationshipName":"ContentDocumentLinks",' + + '"junction":{"targetObject":"ContentDocument","targetIdField":"ContentDocumentId","targetFields":["Id","Title"]}}]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'V3 multi-level should not be null'); - System.assert(result.containsKey('Opportunities'), 'V3 should contain Opportunities'); - Map oppData = (Map) result.get('Opportunities'); - List oppRecords = (List) oppData.get('records'); - System.assertEquals(1, oppRecords.size(), 'V3 should have 1 Opportunity'); - - Map oppRec = (Map) oppRecords[0]; - System.assert(oppRec.containsKey('OpportunityLineItems'), 'V3 Opp should contain OLI children'); - Map oliData = (Map) oppRec.get('OpportunityLineItems'); - List oliRecords = (List) oliData.get('records'); - System.assertEquals(1, oliRecords.size(), 'V3 should have 1 OLI'); - - // Verify parent field on OLI (Product2.Name) - Map oliRec = (Map) oliRecords[0]; - System.assert(oliRec.containsKey('Product2'), 'V3 OLI should have Product2 parent'); - Map prodData = (Map) oliRec.get('Product2'); - System.assertEquals('V3 Product', prodData.get('Name'), 'V3 Product2.Name should match'); + System.assert(result.containsKey('ManagedUsers'), 'V3 should contain ManagedUsers'); + Map managedUsersData = (Map) result.get('ManagedUsers'); + List managedUserRecords = (List) managedUsersData.get('records'); + System.assert(managedUserRecords.size() >= 1, 'V3 should have at least 1 managed user'); + + Map managedUserRecord = (Map) managedUserRecords[0]; + System.assert(managedUserRecord.containsKey('ContentDocumentLinks'), + 'V3 managed user should contain ContentDocumentLinks children'); + Map cdlContainer = (Map) managedUserRecord.get('ContentDocumentLinks'); + List cdlRecords = (List) cdlContainer.get('records'); + System.assertEquals(0, cdlRecords.size(), 'V3 should have 0 ContentDocumentLink'); + } } @IsTest static void testGetRecordDataV3NoNodesThrows() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); Boolean caught = false; Test.startTest(); try { - DocGenDataRetriever.getRecordData(acc.Id, 'Account', '{"v":3,"root":"Account","nodes":[]}'); + DocGenDataRetriever.getRecordData(usr.Id, 'User', '{"v":3,"root":"User","nodes":[]}'); } catch (AuraHandledException e) { caught = true; } @@ -2767,55 +2667,38 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV3WithJunction() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Contact con = new Contact(FirstName = 'V3Junction', LastName = 'Test', AccountId = acc.Id); - insert con; - - Opportunity opp = new Opportunity( - Name = 'V3 Junction Opp', - AccountId = acc.Id, - StageName = 'Prospecting', - CloseDate = Date.today().addDays(30) - ); - insert opp; - - OpportunityContactRole ocr = new OpportunityContactRole( - OpportunityId = opp.Id, - ContactId = con.Id, - Role = 'Influencer' + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + ContentVersion cv = new ContentVersion( + Title = 'V3 Junction Test', + PathOnClient = 'V3 Junction Test.docx', + VersionData = Blob.valueOf('FAKEPNGBYTES'), + FirstPublishLocationId = UserInfo.getUserId() ); - insert ocr; + insert cv; - // V3 config with junction node: OCR as child of Opportunity with junction to Contact - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + // V3 config with junction node: ContentDocumentLink child with ContentDocument junction + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Opportunity","fields":["Name"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Opportunities"},' + - '{"id":"n2","object":"OpportunityContactRole","fields":["Role"],"parentFields":[],' + - '"parentNode":"n1","lookupField":"OpportunityId","relationshipName":"OpportunityContactRoles",' + - '"junction":{"targetObject":"Contact","targetIdField":"ContactId","targetFields":["FirstName","LastName"]}}]}'; + '{"id":"n1","object":"ContentDocumentLink","fields":["ShareType"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"LinkedEntityId","relationshipName":"ContentDocumentLinks",' + + '"junction":{"targetObject":"ContentDocument","targetIdField":"ContentDocumentId","targetFields":["Id","Title"]}}]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'V3 junction result should not be null'); - Map oppsData = (Map) result.get('Opportunities'); - List opps = (List) oppsData.get('records'); - Map oppRec = (Map) opps[0]; - System.assert(oppRec.containsKey('OpportunityContactRoles'), 'V3 should have OCR on Opp'); - - Map ocrContainer = (Map) oppRec.get('OpportunityContactRoles'); - List ocrRecords = (List) ocrContainer.get('records'); - System.assertEquals(1, ocrRecords.size(), 'V3 should have 1 OCR'); - - Map ocrRec = (Map) ocrRecords[0]; - System.assert(ocrRec.containsKey('Contact'), 'V3 junction should stitch Contact'); - Map contactData = (Map) ocrRec.get('Contact'); - System.assertEquals('V3Junction', contactData.get('FirstName'), 'V3 junction stitched FirstName'); + System.assert(result.containsKey('ContentDocumentLinks'), 'V3 should include ContentDocumentLinks'); + Map cdlContainer = (Map) result.get('ContentDocumentLinks'); + List cdlRecords = (List) cdlContainer.get('records'); + System.assert(cdlRecords.size() >= 1, 'V3 should have at least 1 ContentDocumentLink'); + + Map cdlRecord = (Map) cdlRecords[0]; + System.assert(cdlRecord.containsKey('ContentDocument'), 'V3 junction should stitch ContentDocument'); + Map contentDocumentData = (Map) cdlRecord.get('ContentDocument'); + System.assertEquals('V3 Junction Test', contentDocumentData.get('Title'), 'V3 junction stitched ContentDocument title'); } } @@ -2825,52 +2708,39 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV3Bulk() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - - // Create a second account for bulk testing - Account acc2 = new Account(Name = 'Bulk Test Account 2'); - insert acc2; - - Contact con1 = new Contact(FirstName = 'BulkA', LastName = 'Test', AccountId = acc.Id); - Contact con2 = new Contact(FirstName = 'BulkB', LastName = 'Test', AccountId = acc2.Id); - insert new List{ con1, con2 }; - + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); Map config = (Map) JSON.deserializeUntyped( - '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName","LastName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts"}]}' + '{"id":"n1","object":"User","fields":["FirstName","LastName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers"}]}' ); - Set recordIds = new Set{ acc.Id, acc2.Id }; + Set recordIds = new Set{ UserInfo.getUserId(), usr.Id }; Test.startTest(); Map> results = DocGenDataRetriever.getRecordDataV3Bulk(recordIds, config); Test.stopTest(); - System.assertEquals(2, results.size(), 'Bulk should return 2 accounts'); - System.assert(results.containsKey(acc.Id), 'Bulk should contain first account'); - System.assert(results.containsKey(acc2.Id), 'Bulk should contain second account'); + System.assertEquals(2, results.size(), 'Bulk should return 2 Users'); + System.assert(results.containsKey(UserInfo.getUserId()), 'Bulk should contain first User'); - // Verify children were stitched for each account - Map acc1Data = results.get(acc.Id); - System.assert(acc1Data.containsKey('Contacts'), 'Bulk acc1 should have Contacts'); + // Verify children were stitched for each User + Map userData = results.get(UserInfo.getUserId()); + System.assert(userData.containsKey('ManagedUsers'), 'Bulk user should have ManagedUsers'); - Map acc2Data = results.get(acc2.Id); - System.assert(acc2Data.containsKey('Contacts'), 'Bulk acc2 should have Contacts'); - Map acc2Contacts = (Map) acc2Data.get('Contacts'); - List acc2ContactRecords = (List) acc2Contacts.get('records'); - System.assertEquals(1, acc2ContactRecords.size(), 'Bulk acc2 should have 1 Contact'); + Map managedUsersData = results.get(usr.Id); + System.assert(managedUsersData.containsKey('ManagedUsers'), 'Bulk managedUsers should have ManagedUsers'); + Map managedUsers = (Map) managedUsersData.get('ManagedUsers'); + List managedUsersRecords = (List) managedUsers.get('records'); } } @IsTest static void testGetRecordDataV3BulkEmpty() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Map> results = DocGenDataRetriever.getRecordDataV3Bulk( new Set(), @@ -2884,53 +2754,41 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV3BulkWithJunction() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Contact con = new Contact(FirstName = 'BulkJunction', LastName = 'Test', AccountId = acc.Id); - insert con; - - Opportunity opp = new Opportunity( - Name = 'Bulk Junction Opp', - AccountId = acc.Id, - StageName = 'Prospecting', - CloseDate = Date.today().addDays(30) + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + ContentVersion cv = new ContentVersion( + Title = 'Bulk Junction Test', + PathOnClient = 'Bulk Junction Test.docx', + VersionData = Blob.valueOf('FAKEPNGBYTES'), + FirstPublishLocationId = UserInfo.getUserId() ); - insert opp; - - OpportunityContactRole ocr = new OpportunityContactRole( - OpportunityId = opp.Id, - ContactId = con.Id, - Role = 'Evaluator' - ); - insert ocr; + insert cv; Map config = (Map) JSON.deserializeUntyped( - '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Opportunity","fields":["Name"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Opportunities"},' + - '{"id":"n2","object":"OpportunityContactRole","fields":["Role"],"parentFields":[],' + - '"parentNode":"n1","lookupField":"OpportunityId","relationshipName":"OpportunityContactRoles",' + - '"junction":{"targetObject":"Contact","targetIdField":"ContactId","targetFields":["FirstName"]}}]}' + '{"id":"n1","object":"ContentDocumentLink","fields":["ShareType"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"LinkedEntityId","relationshipName":"ContentDocumentLinks",' + + '"junction":{"targetObject":"ContentDocument","targetIdField":"ContentDocumentId","targetFields":["Id","Title"]}}]}' ); Test.startTest(); Map> results = DocGenDataRetriever.getRecordDataV3Bulk( - new Set{ acc.Id }, config + new Set{ UserInfo.getUserId(), usr.Id }, config ); Test.stopTest(); - System.assertEquals(1, results.size(), 'Bulk junction should return 1 account'); - Map accData = results.get(acc.Id); - Map oppsContainer = (Map) accData.get('Opportunities'); - List opps = (List) oppsContainer.get('records'); - Map oppRec = (Map) opps[0]; - Map ocrContainer = (Map) oppRec.get('OpportunityContactRoles'); - List ocrs = (List) ocrContainer.get('records'); - Map ocrRec = (Map) ocrs[0]; - System.assert(ocrRec.containsKey('Contact'), 'Bulk junction should stitch Contact'); + System.assert(results.size() >= 1, 'Bulk junction should return at least one User'); + Map userData = results.get(UserInfo.getUserId()); + System.assert(userData.containsKey('ContentDocumentLinks'), 'Bulk should contain ContentDocumentLinks'); + Map cdlContainer = (Map) userData.get('ContentDocumentLinks'); + List cdlRecords = (List) cdlContainer.get('records'); + System.assert(cdlRecords.size() >= 1, 'Bulk junction should return at least one ContentDocumentLink'); + Map cdlRecord = (Map) cdlRecords[0]; + System.assert(cdlRecord.containsKey('ContentDocument'), 'Bulk junction should stitch ContentDocument'); + Map contentDocumentData = (Map) cdlRecord.get('ContentDocument'); + System.assertEquals('Bulk Junction Test', contentDocumentData.get('Title'), 'Bulk junction should stitch ContentDocument Title'); } } @@ -2940,8 +2798,7 @@ private class DocGenMiscTests { @IsTest static void testGetConfigVersion() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); // V1: plain string System.assertEquals(1, DocGenDataRetriever.getConfigVersion('Name, Industry'), 'Plain string should be V1'); @@ -2949,13 +2806,13 @@ private class DocGenMiscTests { System.assertEquals(1, DocGenDataRetriever.getConfigVersion(null), 'Null should be V1'); // V2: JSON without explicit version - System.assertEquals(2, DocGenDataRetriever.getConfigVersion('{"baseObject":"Account","baseFields":["Name"]}'), 'JSON without v field should be V2'); + System.assertEquals(2, DocGenDataRetriever.getConfigVersion('{"baseObject":"User","baseFields":["Name"]}'), 'JSON without v field should be V2'); // V2: JSON with v:2 - System.assertEquals(2, DocGenDataRetriever.getConfigVersion('{"v":2,"baseObject":"Opportunity"}'), 'JSON with v:2 should be V2'); + System.assertEquals(2, DocGenDataRetriever.getConfigVersion('{"v":2,"baseObject":"User"}'), 'JSON with v:2 should be V2'); // V3: JSON with v:3 - System.assertEquals(3, DocGenDataRetriever.getConfigVersion('{"v":3,"root":"Account","nodes":[]}'), 'JSON with v:3 should be V3'); + System.assertEquals(3, DocGenDataRetriever.getConfigVersion('{"v":3,"root":"User","nodes":[]}'), 'JSON with v:3 should be V3'); // Malformed JSON falls back to V1 System.assertEquals(1, DocGenDataRetriever.getConfigVersion('{not valid json'), 'Malformed JSON should fall back to V1'); @@ -2969,155 +2826,146 @@ private class DocGenMiscTests { @IsTest static void testSanitizeClauseViaV2WhereClause() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Contact con = new Contact(FirstName = 'ClauseTest', LastName = 'Safe', AccountId = acc.Id); - insert con; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // V2 config with valid WHERE and ORDER BY and LIMIT on children - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":"Contacts","fields":["FirstName","LastName"],' + - '"where":"LastName = \'Safe\'","orderBy":"FirstName","limit":"10"}],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName","LastName"],' + + '"where":"Id = \'' + usr.Id + '\'","orderBy":"FirstName","limit":"10"}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'V2 with clauses should not be null'); - Map contactsData = (Map) result.get('Contacts'); - List records = (List) contactsData.get('records'); - System.assertEquals(1, records.size(), 'WHERE clause should filter to 1 contact'); + Map usersData = (Map) result.get('ManagedUsers'); + List records = (List) usersData.get('records'); + System.assertEquals(1, records.size(), 'WHERE clause should filter to 1 user'); } } @IsTest static void testSanitizeClauseRejectsSemicolon() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); Boolean caught = false; // V2 config with injection attempt via semicolon in WHERE - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":"Contacts","fields":["FirstName"],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName"],' + '"where":"LastName = \'x\'; DELETE Contact"}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'Root data should still be returned'); - System.assert(!result.containsKey('Contacts'), 'Invalid child relationship should be skipped'); + System.assert(!result.containsKey('ManagedUsers'), 'Invalid child relationship should be skipped'); } } @IsTest static void testSanitizeClauseRejectsComment() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":"Contacts","fields":["FirstName"],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName"],' + '"where":"LastName = \'x\' -- comment"}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for comment rejection test'); - System.assert(!result.containsKey('Contacts'), 'Comment in WHERE should skip child'); + System.assert(!result.containsKey('ManagedUsers'), 'Comment in WHERE should skip child'); } } @IsTest static void testSanitizeClauseRejectsBlockComment() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":"Contacts","fields":["FirstName"],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName"],' + '"where":"LastName = \'x\' /* block */"}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for block comment rejection'); - System.assert(!result.containsKey('Contacts'), 'Block comment in WHERE should skip child'); + System.assert(!result.containsKey('ManagedUsers'), 'Block comment in WHERE should skip child'); } } @IsTest static void testSanitizeClauseRejectsNonNumericLimit() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":"Contacts","fields":["FirstName"],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName"],' + '"limit":"abc"}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for non-numeric LIMIT test'); - System.assert(!result.containsKey('Contacts'), 'Non-numeric LIMIT should skip child'); + System.assert(!result.containsKey('ManagedUsers'), 'Non-numeric LIMIT should skip child'); } } @IsTest static void testSanitizeClauseRejectsDMLKeyword() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":"Contacts","fields":["FirstName"],' + - '"where":"DELETE FROM Contact"}],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName"],' + + '"where":"DELETE FROM User"}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for DML keyword rejection'); - System.assert(!result.containsKey('Contacts'), 'DML keyword in WHERE should skip child'); + System.assert(!result.containsKey('ManagedUsers'), 'DML keyword in WHERE should skip child'); } } @IsTest static void testSanitizeClauseRejectsSelectInWhere() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":"Contacts","fields":["FirstName"],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName"],' + '"where":"Id IN (SELECT Id FROM User)"}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for SELECT injection rejection'); - System.assert(!result.containsKey('Contacts'), 'SELECT in WHERE clause should skip child'); + System.assert(!result.containsKey('ManagedUsers'), 'SELECT in WHERE clause should skip child'); } } @@ -3127,26 +2975,23 @@ private class DocGenMiscTests { @IsTest static void testMapSObjectWithAddress() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.BillingStreet = '123 Test St'; - acc.BillingCity = 'TestCity'; - acc.BillingState = 'CA'; - acc.BillingPostalCode = '90210'; - acc.BillingCountry = 'US'; - update acc; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + usr.Street = '123 Test St'; + usr.City = 'TestCity'; + usr.PostalCode = '90210'; + updateUser(usr); Test.startTest(); Map result = DocGenDataRetriever.getRecordData( - acc.Id, 'Account', - 'Name, BillingAddress' + usr.Id, 'User', + 'Name, Address' ); Test.stopTest(); System.assertNotEquals(null, result, 'mapSObject with Address should not be null'); - System.assert(result.containsKey('BillingAddress'), 'Should contain BillingAddress compound field'); - Map addrMap = (Map) result.get('BillingAddress'); + System.assert(result.containsKey('Address'), 'Should contain Address compound field'); + Map addrMap = (Map) result.get('Address'); System.assertEquals('123 Test St', addrMap.get('street'), 'Address street should match'); System.assertEquals('TestCity', addrMap.get('city'), 'Address city should match'); } @@ -3154,25 +2999,20 @@ private class DocGenMiscTests { @IsTest static void testMapSObjectWithSubquery() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Contact con = new Contact(FirstName = 'MapSObj', LastName = 'Child', AccountId = acc.Id); - insert con; - + System.runAs(new User(Id = UserInfo.getUserId())) { // V1 style with subquery tests mapSObject's List branch Test.startTest(); Map result = DocGenDataRetriever.getRecordData( - acc.Id, 'Account', - 'Name, (SELECT FirstName, LastName FROM Contacts)' + UserInfo.getUserId(), 'User', + 'Name, (SELECT Email FROM ManagedUsers)' ); Test.stopTest(); System.assertNotEquals(null, result, 'V1 subquery result should not be null'); - System.assert(result.containsKey('Contacts'), 'Should contain Contacts from subquery'); - Map contactsMap = (Map) result.get('Contacts'); - Integer totalSize = (Integer) contactsMap.get('totalSize'); - System.assert(totalSize >= 1, 'Should have at least 1 contact'); + System.assert(result.containsKey('ManagedUsers'), 'Should contain ManagedUsers from subquery'); + Map managedUsersMap = (Map) result.get('ManagedUsers'); + Integer totalSize = (Integer) managedUsersMap.get('totalSize'); + System.assert(totalSize >= 1, 'Should have at least 1 ManagedUser'); } } @@ -3182,22 +3022,21 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV2SkipsInvalidChildren() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // Child with null rel should be skipped; child with empty fields should be skipped - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + '"parentFields":[],' + - '"children":[{"rel":null,"fields":["FirstName"]},{"rel":"Contacts","fields":[]}],' + + '"children":[{"rel":null,"fields":["FirstName"]},{"rel":"ManagedUsers","fields":[]}],' + '"junctions":[]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'V2 with invalid children should still return data'); - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should still be present'); + System.assertEquals(usr.Name, result.get('Name'), 'Name should still be present'); } } @@ -3207,27 +3046,22 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV3WithClauses() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Contact con1 = new Contact(FirstName = 'Alpha', LastName = 'Clause', AccountId = acc.Id); - Contact con2 = new Contact(FirstName = 'Beta', LastName = 'Clause', AccountId = acc.Id); - Contact con3 = new Contact(FirstName = 'Gamma', LastName = 'Other', AccountId = acc.Id); - insert new List{ con1, con2, con3 }; - - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName","LastName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts",' + + '{"id":"n1","object":"User","fields":["FirstName","LastName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers",' + '"where":"LastName = \'Clause\'","orderBy":"FirstName ASC","limit":"2"}]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for V3 with clauses'); - Map contactsData = (Map) result.get('Contacts'); + Map contactsData = (Map) result.get('ManagedUsers'); List records = (List) contactsData.get('records'); System.assert(records.size() <= 2, 'LIMIT 2 should cap results at 2'); // All returned records should have LastName = 'Clause' @@ -3244,52 +3078,25 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV1Grandchildren() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - Opportunity opp = new Opportunity( - Name = 'Grandchild Opp', - AccountId = acc.Id, - StageName = 'Prospecting', - CloseDate = Date.today().addDays(30) - ); - insert opp; - - Product2 prod = new Product2(Name = 'GC Product', IsActive = true); - insert prod; - Id stdPbId = Test.getStandardPricebookId(); - PricebookEntry pbe = new PricebookEntry( - Pricebook2Id = stdPbId, - Product2Id = prod.Id, - UnitPrice = 75, - IsActive = true - ); - insert pbe; - OpportunityLineItem oli = new OpportunityLineItem( - OpportunityId = opp.Id, - PricebookEntryId = pbe.Id, - Quantity = 2, - UnitPrice = 75 - ); - insert oli; - + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // V1 config with nested subquery (grandchild) - String v1Config = 'Name, (SELECT Name, (SELECT Quantity FROM OpportunityLineItems) FROM Opportunities)'; + String v1Config = 'Name, (SELECT Name, (SELECT Email FROM ManagedUsers) FROM ManagedUsers)'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v1Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v1Config); Test.stopTest(); System.assertNotEquals(null, result, 'V1 grandchild result should not be null'); - System.assert(result.containsKey('Opportunities'), 'Should contain Opportunities'); - Map oppContainer = (Map) result.get('Opportunities'); - List oppRecords = (List) oppContainer.get('records'); - System.assert(oppRecords.size() >= 1, 'Should have at least 1 Opportunity'); + System.assert(result.containsKey('ManagedUsers'), 'Should contain ManagedUsers'); + Map userContainer = (Map) result.get('ManagedUsers'); + List userRecords = (List) userContainer.get('records'); + System.assert(userRecords.size() >= 1, 'Should have at least 1 User'); // Verify grandchild stitching - Map oppRec = (Map) oppRecords[0]; - System.assert(oppRec.containsKey('OpportunityLineItems'), - 'Grandchild OpportunityLineItems should be stitched into Opportunity'); + Map userRec = (Map) userRecords[0]; + System.assert(userRec.containsKey('ManagedUsers'), + 'Grandchild ManagedUsers should be stitched into User'); } } @@ -3379,7 +3186,7 @@ private class DocGenMiscTests { // Child data wrapped in {records: [...]} format (V1 query style) Map data = new Map{ 'Name' => 'Test', - 'Contacts' => new Map{ + 'ManagedUsers' => new Map{ 'records' => new List{ new Map{ 'Score' => 10 }, new Map{ 'Score' => 20 } @@ -3387,7 +3194,7 @@ private class DocGenMiscTests { } }; - String xml = '{SUM:Contacts.Score}'; + String xml = '{SUM:ManagedUsers.Score}'; Test.startTest(); String result = DocGenService.processXmlForTest(xml, data); Test.stopTest(); @@ -3553,14 +3360,14 @@ private class DocGenMiscTests { static void testExcelSharedStringsProcessing() { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; tpl.Type__c = 'Excel'; - tpl.Query_Config__c = 'Name, AccountSource'; + tpl.Query_Config__c = 'Email, CreatedBy.Email'; update tpl; String sharedStringsXml = '' + '' + '{Name}' + - '{AccountSource}' + + '{Id}' + 'Static Text' + ''; @@ -3595,10 +3402,10 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Excel document should be generated'); @@ -3716,10 +3523,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - String html = DocGenService.renderPreviewHtml(tpl.Id, acc.Id); + String html = DocGenService.renderPreviewHtml(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, html, 'Should return HTML'); @@ -3751,12 +3558,12 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); Boolean caught = false; try { - DocGenService.renderPreviewHtml(tpl.Id, acc.Id); + DocGenService.renderPreviewHtml(tpl.Id, usr.Id); } catch (DocGenException e) { caught = true; System.assert(e.getMessage().contains('only supported for Word'), 'Preview should mention Word-only support'); @@ -3778,10 +3585,9 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; Test.startTest(); - Map result = DocGenService.generateDocumentParts(tpl.Id, acc.Id); + Map result = DocGenService.generateDocumentParts(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, result.get('allXmlParts'), 'Should return XML parts'); @@ -3925,31 +3731,26 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV3WithWhereOrderByLimit() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new List{ - new Contact(FirstName = 'Alpha', LastName = 'V3W', AccountId = acc.Id), - new Contact(FirstName = 'Beta', LastName = 'V3W', AccountId = acc.Id) - }; - - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName","LastName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts",' + - '"where":"LastName = \'V3W\'","orderBy":"FirstName ASC","limit":"10"}' + + '{"id":"n1","object":"User","fields":["FirstName","LastName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers",' + + '"where":"LastName = \'' + usr.LastName + '\'","orderBy":"FirstName ASC","limit":"10"}' + ']}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'Should return data'); - System.assert(result.containsKey('Contacts'), 'Should contain Contacts relationship'); - Map contactsMap = (Map) result.get('Contacts'); + System.assert(result.containsKey('ManagedUsers'), 'Should contain ManagedUsers relationship'); + Map contactsMap = (Map) result.get('ManagedUsers'); List records = (List) contactsMap.get('records'); - System.assertEquals(2, records.size(), 'Should return 2 contacts matching WHERE clause'); + System.assert(records.size() >= 1, 'Should return at least 1 ManagedUser matching WHERE clause'); } } @@ -3959,22 +3760,21 @@ private class DocGenMiscTests { @IsTest static void testSanitizeClauseRejectsInjection() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // V3 config with dangerous WHERE clause containing semicolon - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts",' + + '{"id":"n1","object":"User","fields":["FirstName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers",' + '"where":"LastName = \'test\'; DROP TABLE"}' + ']}'; Test.startTest(); // The sanitizeClause should reject the semicolon and the child query will fail gracefully - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v3Config); Test.stopTest(); // The root query should still succeed; child with bad WHERE is skipped @@ -3984,22 +3784,20 @@ private class DocGenMiscTests { @IsTest static void testSanitizeClauseLimitMustBeNumeric() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new Contact(FirstName = 'Lim', LastName = 'Test', AccountId = acc.Id); + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // V3 config with non-numeric LIMIT — should throw and skip child - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts",' + + '{"id":"n1","object":"User","fields":["FirstName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers",' + '"limit":"abc"}' + ']}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'Root data should still be returned'); @@ -4008,21 +3806,20 @@ private class DocGenMiscTests { @IsTest static void testSanitizeClauseRejectsComments() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // V3 config with comment injection in WHERE - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts",' + + '{"id":"n1","object":"User","fields":["FirstName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers",' + '"where":"LastName = \'test\' /* comment */"}' + ']}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'Root data should still be returned'); @@ -4031,21 +3828,20 @@ private class DocGenMiscTests { @IsTest static void testSanitizeClauseRejectsDMLKeywords() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); // V3 config with DML keyword in WHERE - String v3Config = '{"v":3,"root":"Account","nodes":[' + - '{"id":"n0","object":"Account","fields":["Name"],"parentFields":[],' + + String v3Config = '{"v":3,"root":"User","nodes":[' + + '{"id":"n0","object":"User","fields":["Name"],"parentFields":[],' + '"parentNode":null,"lookupField":null,"relationshipName":null},' + - '{"id":"n1","object":"Contact","fields":["FirstName"],"parentFields":[],' + - '"parentNode":"n0","lookupField":"AccountId","relationshipName":"Contacts",' + + '{"id":"n1","object":"User","fields":["FirstName"],"parentFields":[],' + + '"parentNode":"n0","lookupField":"CreatedById","relationshipName":"ManagedUsers",' + '"where":"LastName = \'test\' INSERT something"}' + ']}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v3Config); + Map result = DocGenDataRetriever.getRecordData(usr.Id, 'User', v3Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for DML keyword in V3 WHERE'); @@ -4058,14 +3854,13 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithNullFieldsConfig() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); Boolean caught = false; Test.startTest(); try { - DocGenDataRetriever.getRecordData(acc.Id, 'Account', null); + DocGenDataRetriever.getRecordData(usr.Id, 'User', null); } catch (AuraHandledException e) { caught = true; } @@ -4077,14 +3872,13 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithBlankConfig() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); Boolean caught = false; Test.startTest(); try { - DocGenDataRetriever.getRecordData(acc.Id, 'Account', ' '); + DocGenDataRetriever.getRecordData(usr.Id, 'User', ' '); } catch (AuraHandledException e) { caught = true; } @@ -4096,13 +3890,12 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithNullRecordId() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Boolean caught = false; Test.startTest(); try { - DocGenDataRetriever.getRecordData(null, 'Account', 'Name'); + DocGenDataRetriever.getRecordData(null, 'User', 'Name'); } catch (AuraHandledException e) { caught = true; } @@ -4118,8 +3911,7 @@ private class DocGenMiscTests { @IsTest static void testGetConfigVersionV1Blank() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Integer v = DocGenDataRetriever.getConfigVersion(null); Integer v2 = DocGenDataRetriever.getConfigVersion(''); @@ -4134,11 +3926,10 @@ private class DocGenMiscTests { @IsTest static void testGetConfigVersionV2() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { // JSON without version field defaults to V2 Test.startTest(); - Integer v = DocGenDataRetriever.getConfigVersion('{"baseObject":"Account","baseFields":["Name"]}'); + Integer v = DocGenDataRetriever.getConfigVersion('{"baseObject":"User","baseFields":["Name"]}'); Test.stopTest(); System.assertEquals(2, v, 'JSON without v field should be V2'); @@ -4147,10 +3938,9 @@ private class DocGenMiscTests { @IsTest static void testGetConfigVersionV3() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - Integer v = DocGenDataRetriever.getConfigVersion('{"v":3,"root":"Account","nodes":[]}'); + Integer v = DocGenDataRetriever.getConfigVersion('{"v":3,"root":"User","nodes":[]}'); Test.stopTest(); System.assertEquals(3, v, 'JSON with v:3 should be V3'); @@ -4159,8 +3949,7 @@ private class DocGenMiscTests { @IsTest static void testGetConfigVersionMalformedJson() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); Integer v = DocGenDataRetriever.getConfigVersion('{malformed json'); Test.stopTest(); @@ -4175,21 +3964,17 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataWithLocationField() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - // Account doesn't have geolocation, but Location type is covered + System.runAs(new User(Id = UserInfo.getUserId())) { + // User doesn't have geolocation, but Location type is covered // by the Address field test. Test null value handling instead. - acc.Description = null; - update acc; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', 'Name, Description'); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', 'Name, AboutMe'); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for location field test'); - // Description is null — should not be in the map (or null) - System.assertEquals('Misc Test Account', result.get('Name'), 'Name should match for location field test'); + // AboutMe is null — should not be in the map (or null) + System.assertEquals(UserInfo.getName(), result.get('Name'), 'Name should match for location field test'); } } @@ -4199,24 +3984,19 @@ private class DocGenMiscTests { @IsTest static void testGetRecordDataV2WithChildClauses() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; - insert new List{ - new Contact(FirstName = 'V2A', LastName = 'Test', AccountId = acc.Id), - new Contact(FirstName = 'V2B', LastName = 'Test', AccountId = acc.Id) - }; - - String v2Config = '{"v":2,"baseObject":"Account","baseFields":["Name"],' + - '"children":[{"rel":"Contacts","fields":["FirstName","LastName"],' + - '"where":"LastName = \'Test\'","orderBy":"FirstName ASC","limit":"5"}]}'; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); + + String v2Config = '{"v":2,"baseObject":"User","baseFields":["Name"],' + + '"children":[{"rel":"ManagedUsers","fields":["FirstName","LastName"],' + + '"where":"LastName = \'' + usr.LastName + '\'","orderBy":"FirstName ASC","limit":"5"}]}'; Test.startTest(); - Map result = DocGenDataRetriever.getRecordData(acc.Id, 'Account', v2Config); + Map result = DocGenDataRetriever.getRecordData(UserInfo.getUserId(), 'User', v2Config); Test.stopTest(); System.assertNotEquals(null, result, 'Result should not be null for V2 child clauses test'); - System.assert(result.containsKey('Contacts'), 'Should contain Contacts'); + System.assert(result.containsKey('ManagedUsers'), 'Should contain ManagedUsers'); } } @@ -4226,8 +4006,8 @@ private class DocGenMiscTests { @IsTest static void testSaveSettingsPermissionDenied() { - // Create a standard user profile user without admin access - Profile p = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1]; + // Create a user without admin access (permission set DocGen_Admin_Access is not assigned) + Profile p = [SELECT Id FROM Profile WHERE Name = :CHATTER_FREE_USER_PROFILE_NAME LIMIT 1]; User stdUser = new User( Alias = 'dgntst', Email = 'docgentest@example.com', @@ -4261,8 +4041,7 @@ private class DocGenMiscTests { @IsTest static void testSaveSettingsWithNullUrl() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); DocGenSetupController.saveSettings(null); Test.stopTest(); @@ -4278,15 +4057,14 @@ private class DocGenMiscTests { @IsTest static void testMergeTemplateForSignatureThrows() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Boolean caught = false; Test.startTest(); try { - DocGenService.mergeTemplateForSignature(tpl.Id, acc.Id); + DocGenService.mergeTemplateForSignature(tpl.Id, usr.Id); } catch (DocGenException e) { caught = true; System.assert(e.getMessage().contains('Signatures have been removed'), 'Should mention signatures removed'); @@ -4310,15 +4088,14 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; Map preloadedData = new Map{ - 'Name' => 'Cached Account Name', - 'AccountSource' => 'Web' + 'Name' => UserInfo.getName(), + 'LastName' => UserInfo.getLastName() }; Test.startTest(); - Id docId = DocGenService.generateDocumentFromData(tpl.Id, acc.Id, preloadedData); + Id docId = DocGenService.generateDocumentFromData(tpl.Id, UserInfo.getUserId(), preloadedData); Test.stopTest(); System.assertNotEquals(null, docId, 'Should return ContentDocumentId from pre-cached data'); @@ -4337,10 +4114,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - String html = DocGenService.generateHtmlForRecord(tpl.Id, acc.Id, null); + String html = DocGenService.generateHtmlForRecord(tpl.Id, usr.Id, null); Test.stopTest(); System.assertNotEquals(null, html, 'Should return HTML string'); @@ -4356,14 +4133,13 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; Map preloaded = new Map{ 'Name' => 'Preloaded Name' }; Test.startTest(); - String html = DocGenService.generateHtmlForRecord(tpl.Id, acc.Id, preloaded); + String html = DocGenService.generateHtmlForRecord(tpl.Id, UserInfo.getUserId(), preloaded); Test.stopTest(); System.assertNotEquals(null, html, 'Should return HTML with preloaded data'); @@ -4398,12 +4174,12 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Boolean caught = false; Test.startTest(); try { - DocGenService.processDocumentAsHtmlWithImageMap(tpl.Id, acc.Id, new Map()); + DocGenService.processDocumentAsHtmlWithImageMap(tpl.Id, usr.Id, new Map()); } catch (DocGenException e) { caught = true; System.assert(e.getMessage().contains('only supported for Word'), 'HTML image map should mention Word-only support'); @@ -4455,18 +4231,16 @@ private class DocGenMiscTests { Content_Version_Id__c = cv.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account' + Base_Object_API__c = 'User' ); insert ver; // extractAndSaveTemplateImages saves pre-decomposed XML CVs and image CVs DocGenService.extractAndSaveTemplateImages(tpl.Id, ver.Id); - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); // generateDocument with PDF output should use tryMergeFromPreDecomposed - Id docId = DocGenService.generateDocument(tpl.Id, acc.Id); + Id docId = DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, docId, 'Pre-decomposed path should generate a PDF'); @@ -4493,7 +4267,7 @@ private class DocGenMiscTests { )); zw.addEntry('word/document.xml', Blob.valueOf( '' + - '{Name}' + '{UserName}' )); zw.addEntry('word/_rels/document.xml.rels', Blob.valueOf( '' + @@ -4512,16 +4286,16 @@ private class DocGenMiscTests { Content_Version_Id__c = cv.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account' + Base_Object_API__c = 'User' ); insert ver; DocGenService.extractAndSaveTemplateImages(tpl.Id, ver.Id); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.generatePdfBlob(tpl.Id, acc.Id); + Map result = DocGenService.generatePdfBlob(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'PDF with template images should generate'); @@ -4533,8 +4307,7 @@ private class DocGenMiscTests { @IsTest static void testExtractAndSaveTemplateImagesNullTemplate() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); try { DocGenService.extractAndSaveTemplateImages(null, null); @@ -4578,7 +4351,7 @@ private class DocGenMiscTests { Content_Version_Id__c = cv.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account' + Base_Object_API__c = 'User' ); insert ver; @@ -4597,19 +4370,19 @@ private class DocGenMiscTests { @IsTest static void testApplyResolvedImagesAmpEncoded() { - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('AMPIMG')); - acc.Description = ''; - update acc; + usr.AboutMe = ''; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Map resolvedImages = new Map{ @@ -4617,7 +4390,7 @@ private class DocGenMiscTests { }; Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id, resolvedImages); + Map result = DocGenService.processDocument(tpl.Id, usr.Id, resolvedImages); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for amp-encoded resolved images'); @@ -4693,22 +4466,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentRichTextMultiParagraph() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

First paragraph

Second bold paragraph

Third with italic and underline

'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

First paragraph

Second bold paragraph

Third with italic and underline

'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for rich text multi-paragraph'); @@ -4728,22 +4501,22 @@ private class DocGenMiscTests { insert imgCv; imgCv = [SELECT Id FROM ContentVersion WHERE Id = :imgCv.Id]; - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = imgCv.Id; - update acc; + User usr = getManagedUser(); + usr.AboutMe = imgCv.Id; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{%Description}'; + '{%AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.generateDocumentParts(tpl.Id, acc.Id); + Map result = DocGenService.generateDocumentParts(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('allXmlParts'), 'XML parts should not be null for image CV ID parts'); @@ -4793,10 +4566,10 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Excel with self-closing cell should generate'); @@ -4809,22 +4582,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentRichTextImgDataUriWithDims() { String tinyBase64 = EncodingUtil.base64Encode(Blob.valueOf('RICHIMG')); - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

Text after

'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

Text after

'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for rich text img with data URI dims'); @@ -4836,22 +4609,22 @@ private class DocGenMiscTests { @IsTest static void testGeneratePdfBlobWithAbsoluteImageUrl() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = ''; - update acc; + User usr = getManagedUser(); + usr.AboutMe = ''; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.generatePdfBlob(tpl.Id, acc.Id); + Map result = DocGenService.generatePdfBlob(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'PDF with absolute URL image should generate'); @@ -4867,7 +4640,7 @@ private class DocGenMiscTests { 'Name' => 'SkipPrefix' }; - String xml = '{!Account.Name}'; + String xml = '{!User.Name}'; Test.startTest(); String result = DocGenService.processXmlForTest(xml, data); Test.stopTest(); @@ -4910,14 +4683,13 @@ private class DocGenMiscTests { tpl.Output_Format__c = 'PDF'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Map preloadedData = new Map{ - 'Name' => 'PDF Cached Name' + 'Name' => UserInfo.getName(), + 'LastName' => UserInfo.getLastName() }; Test.startTest(); - Id docId = DocGenService.generateDocumentFromData(tpl.Id, acc.Id, preloadedData); + Id docId = DocGenService.generateDocumentFromData(tpl.Id, UserInfo.getUserId(), preloadedData); Test.stopTest(); System.assertNotEquals(null, docId, 'Should return ContentDocumentId for PDF from cached data'); @@ -4932,7 +4704,7 @@ private class DocGenMiscTests { @IsTest static void testAggregateCountRecordsMap() { Map data = new Map{ - 'Contacts' => new Map{ + 'ManagedUsers' => new Map{ 'records' => new List{ new Map{ 'Name' => 'A' }, new Map{ 'Name' => 'B' } @@ -4940,7 +4712,7 @@ private class DocGenMiscTests { } }; - String xml = '{COUNT:Contacts}'; + String xml = '{COUNT:ManagedUsers}'; Test.startTest(); String result = DocGenService.processXmlForTest(xml, data); Test.stopTest(); @@ -4981,10 +4753,10 @@ private class DocGenMiscTests { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.generateDocumentParts(tpl.Id, acc.Id); + Map result = DocGenService.generateDocumentParts(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('allXmlParts'), 'XML parts should not be null for passthrough media'); @@ -5009,10 +4781,8 @@ private class DocGenMiscTests { tpl.Output_Format__c = 'PDF'; update tpl; - Account acc = [SELECT Id FROM Account LIMIT 1]; - Test.startTest(); - DocGenService.generateDocument(tpl.Id, acc.Id); + DocGenService.generateDocument(tpl.Id, UserInfo.getUserId()); Test.stopTest(); System.assertNotEquals(null, DocGenService.lastRenderedHtml, 'lastRenderedHtml should be populated after PDF generation'); @@ -5026,12 +4796,12 @@ private class DocGenMiscTests { static void testExcelMultipleWorksheets() { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; tpl.Type__c = 'Excel'; - tpl.Query_Config__c = 'Name, AccountSource'; + tpl.Query_Config__c = 'Email, CreatedBy.Email'; update tpl; String sharedStringsXml = '' + - '{Name}{AccountSource}'; + '{Name}{Id}'; String sheet1Xml = '' + @@ -5062,10 +4832,10 @@ private class DocGenMiscTests { Id conDocId = [SELECT ContentDocumentId FROM ContentVersion WHERE Id = :cv.Id].ContentDocumentId; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Excel with multiple sheets should generate'); @@ -5077,22 +4847,22 @@ private class DocGenMiscTests { @IsTest static void testProcessDocumentRichTextEmptyParagraphs() { - Account acc = [SELECT Id FROM Account LIMIT 1]; - acc.Description = '

Content

'; - update acc; + User usr = getManagedUser(); + usr.AboutMe = '

Content

'; + updateUser(usr); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - tpl.Query_Config__c = 'Name, Description'; + tpl.Query_Config__c = 'Name, AboutMe'; update tpl; String docXml = '' + '' + - '{Description}'; + '{AboutMe}'; createValidDocxFile(docXml); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for rich text empty paragraphs'); @@ -5149,10 +4919,10 @@ private class DocGenMiscTests { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; insert new ContentDocumentLink(LinkedEntityId=tpl.Id, ContentDocumentId=conDocId, ShareType='V'); - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = getManagedUser(); Test.startTest(); - Map result = DocGenService.processDocument(tpl.Id, acc.Id); + Map result = DocGenService.processDocument(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('blob'), 'Blob should not be null for non-image rels test'); @@ -5164,8 +4934,7 @@ private class DocGenMiscTests { @IsTest static void testFlowActionSaveToRecord() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { String docXml = '' + '' + @@ -5173,7 +4942,6 @@ private class DocGenMiscTests { ContentVersion cv = createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; // Create active version so generateDocument can find the template file insert new DocGen_Template_Version__c( @@ -5184,7 +4952,7 @@ private class DocGenMiscTests { DocGenFlowAction.Request req = new DocGenFlowAction.Request(); req.templateId = tpl.Id; - req.recordId = acc.Id; + req.recordId = UserInfo.getUserId(); req.saveToRecord = false; // Service already links via FirstPublishLocationId Test.startTest(); @@ -5203,7 +4971,7 @@ private class DocGenMiscTests { List links = [ SELECT Id FROM ContentDocumentLink WHERE ContentDocumentId = :responses[0].contentDocumentId - AND LinkedEntityId = :acc.Id + AND LinkedEntityId = :UserInfo.getUserId() ]; System.assertEquals(1, links.size(), 'Generated file should be linked to the source record'); } @@ -5215,13 +4983,12 @@ private class DocGenMiscTests { @IsTest static void testFlowActionNullTemplateId() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { - Account acc = [SELECT Id FROM Account LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + User usr = getManagedUser(); DocGenFlowAction.Request req = new DocGenFlowAction.Request(); req.templateId = null; - req.recordId = acc.Id; + req.recordId = usr.Id; Test.startTest(); List responses = DocGenFlowAction.generateDocument( @@ -5243,8 +5010,7 @@ private class DocGenMiscTests { @IsTest static void testFlowActionWithDocumentTitle() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { String docXml = '' + '' + @@ -5252,11 +5018,10 @@ private class DocGenMiscTests { createValidDocxFile(docXml); DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; DocGenFlowAction.Request req = new DocGenFlowAction.Request(); req.templateId = tpl.Id; - req.recordId = acc.Id; + req.recordId = UserInfo.getUserId(); req.saveToRecord = false; req.documentTitle = 'Custom Title'; @@ -5267,7 +5032,7 @@ private class DocGenMiscTests { Test.stopTest(); System.assertEquals(1, responses.size(), 'Should return exactly one response for documentTitle test'); - System.assertEquals(true, responses[0].success, 'Success should be true with documentTitle override'); + System.assertEquals(true, responses[0].success, 'Success should be true with documentTitle override, ' + responses[0].errorMessage); } } @@ -5277,8 +5042,7 @@ private class DocGenMiscTests { @IsTest static void testFlowActionResponseAllFields() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGenFlowAction.Response res = new DocGenFlowAction.Response(); res.contentDocumentId = null; res.contentVersionId = null; @@ -5298,8 +5062,7 @@ private class DocGenMiscTests { @IsTest static void testFlowActionRequestFields() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { DocGenFlowAction.Request req = new DocGenFlowAction.Request(); req.templateId = null; req.recordId = null; diff --git a/force-app/main/default/classes/DocGenSharingTests.cls b/force-app/main/default/classes/DocGenSharingTests.cls index 15cd51d..4e43ecc 100644 --- a/force-app/main/default/classes/DocGenSharingTests.cls +++ b/force-app/main/default/classes/DocGenSharingTests.cls @@ -1,45 +1,56 @@ @IsTest private class DocGenSharingTests { - + private static String UNIQUE_IDENTIFIER = 'DocGenSharingTests'; + private static final String TEST_GROUP_NAME = String.format('DocGenShareGroup_{0}', new List{UserInfo.getUserId()}); @TestSetup static void setup() { - DocGen_Template__c t = new DocGen_Template__c( + DocGen_Template__c templateRecord = new DocGen_Template__c( Name = 'Sharing Template', - Base_Object_API__c = 'Account' + Base_Object_API__c = 'User' ); - insert t; - - Profile p = [SELECT Id FROM Profile WHERE Name='Standard User' LIMIT 1]; - User u = new User(Alias = 'standt', Email='standarduser@testorg.com', - EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', - LocaleSidKey='en_US', ProfileId = p.Id, - TimeZoneSidKey='America/Los_Angeles', UserName='standarduser' + DateTime.now().getTime() + '@testorg.com'); - insert u; + insert templateRecord; + + // avoid mixed dml + System.runAs(new User(Id = UserInfo.getUserId())) { + Group shareGroup = new Group( + Name = TEST_GROUP_NAME, + DeveloperName = String.format('DocGenShareGroup_{0}', new List{String.valueOf(DateTime.now().getTime())}), + Type = 'Regular' + ); + insert shareGroup; + + GroupMember groupMembership = new GroupMember( + GroupId = shareGroup.Id, + UserOrGroupId = UserInfo.getUserId() + ); + insert groupMembership; + } } @IsTest static void testSharingOperations() { - User runAsUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(runAsUser) { - DocGen_Template__c t = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - User u = [SELECT Id FROM User WHERE LastName='Testing' LIMIT 1]; + System.runAs(new User(Id = UserInfo.getUserId())) { + DocGen_Template__c templateRecord = [SELECT Id FROM DocGen_Template__c LIMIT 1]; + Group shareGroup = [SELECT Id FROM Group WHERE Name = :TEST_GROUP_NAME LIMIT 1]; Test.startTest(); // Share - DocGenController.shareTemplate(t.Id, u.Id, 'Read'); + DocGenController.shareTemplate(templateRecord.Id, shareGroup.Id, 'Read'); // Verify Share exists via actual SOQL to guarantee valid ID type - DocGen_Template__Share shareRef = [SELECT Id FROM DocGen_Template__Share WHERE ParentId = :t.Id AND UserOrGroupId = :u.Id LIMIT 1]; + DocGen_Template__Share shareRef = [SELECT Id FROM DocGen_Template__Share WHERE ParentId = :templateRecord.Id AND UserOrGroupId = :shareGroup.Id LIMIT 1]; System.assertNotEquals(null, shareRef, 'Share record should exist in DB'); // Remove Share DocGenController.removeShare(shareRef.Id); - List> shares = DocGenController.getTemplateShares(t.Id); + List> shares = DocGenController.getTemplateShares(templateRecord.Id); Boolean found = false; - for (Map s : shares) { - if (s.get('UserOrGroupId') == u.Id) { found = true; } + for (Map shareRecord : shares) { + if (shareRecord.get('UserOrGroupId') == shareGroup.Id) { + found = true; break; + } } System.assert(!found, 'Share should be removed'); @@ -49,10 +60,9 @@ private class DocGenSharingTests { @IsTest static void testSearch() { - User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; - System.runAs(u) { + System.runAs(new User(Id = UserInfo.getUserId())) { Test.startTest(); - List> results = DocGenController.searchUsersAndGroups('Testing'); + List> results = DocGenController.searchUsersAndGroups(UserInfo.getLastName()); Test.stopTest(); System.assert(results.size() > 0, 'Should find user'); } diff --git a/force-app/main/default/classes/DocGenTests.cls b/force-app/main/default/classes/DocGenTests.cls index d1401ca..b62c1fb 100644 --- a/force-app/main/default/classes/DocGenTests.cls +++ b/force-app/main/default/classes/DocGenTests.cls @@ -6,16 +6,12 @@ private class DocGenTests { // Create Template DocGen_Template__c tpl = new DocGen_Template__c( Name = 'Test Template', - Base_Object_API__c = 'Account', - Query_Config__c = 'Name, AccountSource', + Base_Object_API__c = 'User', + Query_Config__c = 'Email, CreatedBy.Email', Type__c = 'Word' ); insert tpl; - // Create Account - Account acc = new Account(Name = 'Test Account', AccountSource = 'Web', Website = 'https://www.example.com'); - insert acc; - // Create ContentVersion (File) ContentVersion cv = new ContentVersion( Title = 'TestDoc', @@ -42,16 +38,16 @@ private class DocGenTests { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { DocGen_Template__c tpl = [SELECT Id FROM DocGen_Template__c LIMIT 1]; - Account acc = [SELECT Id FROM Account LIMIT 1]; + User usr = u; Test.startTest(); - Map result = DocGenController.generateDocumentData(tpl.Id, acc.Id); + Map result = DocGenController.generateDocumentData(tpl.Id, usr.Id); Test.stopTest(); System.assertNotEquals(null, result.get('data'), 'Data should not be null'); System.assertNotEquals(null, result.get('templateFile'), 'File should not be null'); Map data = (Map) result.get('data'); - System.assertEquals('Test Account', data.get('Name'), 'Account Name should match test data'); + System.assertEquals(UserInfo.getUserEmail(), data.get('Email'), 'User Email should match test data'); } } @@ -59,7 +55,7 @@ private class DocGenTests { static void testGetTemplates() { User u = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; System.runAs(u) { - List tpls = DocGenController.getTemplatesForObject('Account'); + List tpls = DocGenController.getTemplatesForObject('User'); System.assertEquals(1, tpls.size(), 'Should return 1 template for Account'); } } @@ -77,7 +73,7 @@ private class DocGenTests { Content_Version_Id__c = cv1.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Category__c = 'General', Description__c = 'V1 Description' ); @@ -106,7 +102,7 @@ private class DocGenTests { Content_Version_Id__c = cv2.Id, Is_Active__c = true, Type__c = 'Word', - Base_Object_API__c = 'Account', + Base_Object_API__c = 'User', Category__c = 'General', Description__c = 'V2 Description' );