@IsTest private class CLMAdminServiceTest { private class FolderBrowseMock implements HttpCalloutMock { public HttpResponse respond(HttpRequest req) { HttpResponse res = new HttpResponse(); res.setHeader('Content-Type', 'application/json'); if (req.getMethod() == 'POST' && req.getEndpoint().contains('/documentxmlmergetasks')) { res.setStatusCode(200); res.setBody('{"Href":"https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documentxmlmergetasks/TASK-555","Status":"Queued","Result":{"Href":"https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documents/generated-555"}}'); return res; } if (req.getEndpoint().endsWith('/folders/root-folder')) { res.setStatusCode(200); res.setBody('{"Name":"Templates Root","Href":"https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/root-folder","Type":"Folder","Parent":{"Href":"https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/root-parent"}}'); return res; } if (req.getEndpoint().endsWith('/folders/root-folder/folders')) { res.setStatusCode(200); res.setBody('{"Results":[{"Name":"Residential","Href":"https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/residential","Parent":{"Href":"https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/root-folder"}}]}'); return res; } if (req.getEndpoint().endsWith('/folders/root-folder/documents')) { res.setStatusCode(200); res.setBody('{"Results":[{"Name":"Appraiser Review Letter Template","Href":"https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/documents/template-1"}]}'); return res; } if (req.getMethod() == 'GET' && req.getEndpoint().contains('/documentxmlmergetasks')) { res.setStatusCode(200); res.setBody('{"Href":"https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documentxmlmergetasks/TASK-555","Status":"Completed","Result":{"Href":"https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documents/generated-555"}}'); return res; } if (req.getMethod() == 'GET' && req.getEndpoint().contains('/documents/generated-555')) { res.setStatusCode(200); res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'); res.setHeader('Content-Disposition', 'attachment; filename="Review_AC-000001.docx"'); res.setBodyAsBlob(Blob.valueOf('docx-binary')); return res; } res.setStatusCode(404); res.setBody('{"Message":"Not Found"}'); return res; } } @IsTest static void parsesFolderContents() { Test.setMock(HttpCalloutMock.class, new FolderBrowseMock()); Test.startTest(); CLMAdminService.FolderContents contents = CLMAdminService.getFolderContents( 'https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/root-folder', 'DTC_CLM_Demo' ); String body = CLMAdminService.probeResource('/documentxmlmergetasks/TASK-555', 'DTC_IAM_Enterprise'); Test.stopTest(); System.assertEquals('Templates Root', contents.folder.name); System.assertEquals('https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/root-parent', contents.folder.parentHref); System.assertEquals(1, contents.folders.size()); System.assertEquals('Residential', contents.folders[0].name); System.assertEquals(1, contents.documents.size()); System.assertEquals('Appraiser Review Letter Template', contents.documents[0].name); System.assert(body.contains('Completed')); } @IsTest static void returnsAccountSettingsFromMetadata() { Test.startTest(); List accounts = CLMAdminService.listAccountSettings(); CLMAdminService.AccountSettings settings = CLMAdminService.getAccountSettings('DTC_CLM_Demo'); Test.stopTest(); Set accountCodes = new Set(); for (CLMAdminService.AccountSettings account : accounts) { accountCodes.add(account.accountCode); } System.assert(accountCodes.contains('DTC_CLM_Demo')); System.assert(accountCodes.contains('DTC_IAM_Enterprise')); System.assert(accountCodes.contains('DTC_HUD_Demo')); System.assertNotEquals(null, settings); System.assertEquals('DTC_CLM_Demo', settings.accountCode); System.assertEquals('DTC CLM Demo', settings.accountDisplayName); System.assertEquals('UAT', settings.environment); System.assert(settings.destinationRootFolderHref.contains('/folders/')); System.assert(settings.defaultTemplateDocumentHref.contains('/documents/')); System.assertEquals('Review', settings.defaultDocumentNamePrefix); } @IsTest static void returnsLetterSettingsFromMetadata() { Test.startTest(); List letters = CLMAdminService.listLetterSettings('DTC_CLM_Demo'); CLMAdminService.LetterSettings settings = CLMAdminService.getLetterSettings('DTC_CLM_Demo', 'APPRAISER_REVIEW'); Test.stopTest(); System.assert(!letters.isEmpty()); System.assertEquals('APPRAISER_REVIEW', settings.letterCode); System.assertEquals('Appraiser Review Letter', settings.letterDisplayName); System.assertEquals(true, settings.isDefault); System.assertEquals('Review', settings.defaultDocumentNamePrefix); } @IsTest static void buildsDocGenPreviewForSelectedLetter() { Appraiser_Case__c appraiserCase = new Appraiser_Case__c( Appraiser_Field_Review_Date__c = Date.today(), Letter_Sent_Date__c = Date.newInstance(2026, 4, 9), FHA_Case_Number__c = '123-4567890', Appraiser_Name__c = 'Jamie Carter', Appraiser_Last_Name__c = 'Carter', Appraiser_Street__c = '12 Park Ave', Appraiser_City__c = 'New York', Appraiser_State_Province__c = 'NY', Appraiser_Postal_Code__c = '10016', Appraiser_Country__c = 'USA', Property_Street__c = '245 Lexington Ave', Property_City__c = 'New York', Property_State_Province__c = 'NY', Property_Postal_Code__c = '10016', Property_Country__c = 'USA' ); insert appraiserCase; insert new Appraiser_Case_Deficiency__c( Appraiser_Case__c = appraiserCase.Id, Deficiency_Number__c = 1, Description__c = 'Test deficiency', Resolution__c = 'Test resolution', Reference__c = 'VC-1' ); Test.startTest(); CLMAdminService.DocGenPreview preview = CLMAdminService.getDocGenPreview( appraiserCase.Id, 'DTC_CLM_Demo', 'NOD_LETTER' ); Test.stopTest(); System.assertEquals('DTC_CLM_Demo', preview.accountCode); System.assertEquals('NOD_LETTER', preview.letterCode); System.assertEquals('NOD Letter', preview.letterDisplayName); Appraiser_Case__c refreshedCase = [ SELECT Name FROM Appraiser_Case__c WHERE Id = :appraiserCase.Id LIMIT 1 ]; System.assertEquals('NOD_' + refreshedCase.Name + '.docx', preview.destinationDocName); System.assert(preview.mergeTaskEndpointUrl.endsWith('/documentxmlmergetasks')); System.assert(preview.payloadJson.contains('FHACaseNumber')); System.assert(preview.dataXml.contains('\n <')); System.assert(preview.dataXml.contains('VC-1')); System.assert(preview.requestBodyJson.contains('"DestinationDocumentName"')); } @IsTest static void persistsCaseTrackingOnGenerate() { Appraiser_Case__c appraiserCase = new Appraiser_Case__c( Appraiser_Field_Review_Date__c = Date.today(), Property_Street__c = '123 Main St', Property_City__c = 'Denver', Property_State_Province__c = 'CO', Property_Postal_Code__c = '80202' ); insert appraiserCase; insert new Appraiser_Case_Deficiency__c( Appraiser_Case__c = appraiserCase.Id, Deficiency_Number__c = 1, Description__c = 'Test deficiency', Resolution__c = 'Test resolution', Reference__c = 'VC-1' ); Test.setMock(HttpCalloutMock.class, new FolderBrowseMock()); Test.startTest(); CLMDocGenCallout.CLMDocGenResponse generateResponse = CLMAdminService.generateDocument( appraiserCase.Id, 'https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documents/template-1', 'https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/folders/root-folder', 'Review_AC-000001.docx', 'DTC_CLM_Demo' ); CLMAdminService.CaseContext context = CLMAdminService.getCaseContext(appraiserCase.Id); Test.stopTest(); System.assertEquals(true, generateResponse.success); System.assertEquals('Queued', context.lastDocGenStatus); System.assertEquals('DTC_CLM_Demo', context.lastClmAccountCode); System.assertEquals('TASK-555', context.lastDocGenTaskId); System.assert(context.lastDocGenTaskUrl.contains('/documentxmlmergetasks/TASK-555')); System.assert(context.generatedDocumentUrl.contains('/documents/generated-555')); System.assertNotEquals(null, context.lastDocGenRequestedAt); System.assertEquals(null, context.lastDocGenCompletedAt); System.assertEquals(1, context.deficiencies.size()); System.assertEquals('123 Main St, Denver, CO 80202', context.propertyAddress); System.assertEquals('VC-1', context.deficiencies[0].reference); } @IsTest static void persistsCaseTrackingOnStatusRefresh() { Appraiser_Case__c appraiserCase = new Appraiser_Case__c( Appraiser_Field_Review_Date__c = Date.today(), Property_Street__c = '123 Main St', Property_City__c = 'Denver', Property_State_Province__c = 'CO', Property_Postal_Code__c = '80202', Last_DocGen_Task_Id__c = 'TASK-555' ); insert appraiserCase; insert new Appraiser_Case_Deficiency__c( Appraiser_Case__c = appraiserCase.Id, Deficiency_Number__c = 1, Description__c = 'Test deficiency', Resolution__c = 'Test resolution', Reference__c = 'VC-1' ); Test.setMock(HttpCalloutMock.class, new FolderBrowseMock()); Test.startTest(); CLMDocGenCallout.CLMDocGenResponse statusResponse = CLMAdminService.getTaskStatus(appraiserCase.Id, 'TASK-555', 'DTC_CLM_Demo'); CLMAdminService.CaseContext context = CLMAdminService.getCaseContext(appraiserCase.Id); Test.stopTest(); System.assertEquals(true, statusResponse.success); System.assertEquals('Completed', context.lastDocGenStatus); System.assertEquals('DTC_CLM_Demo', context.lastClmAccountCode); System.assertEquals('TASK-555', context.lastDocGenTaskId); System.assert(context.lastDocGenTaskUrl.contains('/documentxmlmergetasks/TASK-555')); System.assert(context.generatedDocumentUrl.contains('/documents/generated-555')); System.assertNotEquals(null, context.lastDocGenCompletedAt); System.assertEquals(1, context.deficiencies.size()); } @IsTest static void attachesGeneratedDocumentToCaseAsSalesforceFile() { Appraiser_Case__c appraiserCase = new Appraiser_Case__c( Appraiser_Field_Review_Date__c = Date.today(), Property_Street__c = '245 Lexington Ave', Property_City__c = 'New York', Property_State_Province__c = 'NY', Property_Postal_Code__c = '10016', Generated_Document_Url__c = 'https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documents/generated-555', Generated_Document_Id__c = 'generated-555' ); insert appraiserCase; Test.setMock(HttpCalloutMock.class, new FolderBrowseMock()); Test.startTest(); CLMAdminService.FileAttachmentResult result = CLMAdminService.attachGeneratedDocumentToCase(appraiserCase.Id, 'DTC_CLM_Demo'); Test.stopTest(); Appraiser_Case__c refreshedCase = [ SELECT Last_CLM_Account_Code__c, Attached_File_Content_Document_Id__c, Attached_File_Url__c FROM Appraiser_Case__c WHERE Id = :appraiserCase.Id LIMIT 1 ]; List links = [ SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE LinkedEntityId = :appraiserCase.Id ]; System.assertEquals(true, result.success); System.assertNotEquals(null, result.contentDocumentId); System.assert(result.fileUrl.contains('/lightning/r/ContentDocument/')); System.assertEquals('DTC_CLM_Demo', refreshedCase.Last_CLM_Account_Code__c); System.assertEquals(result.contentDocumentId, refreshedCase.Attached_File_Content_Document_Id__c); System.assertEquals(result.fileUrl, refreshedCase.Attached_File_Url__c); System.assertEquals(1, links.size()); System.assertEquals(result.contentDocumentId, links[0].ContentDocumentId); } }