@IsTest private class CLMDocGenCalloutTest { private class CLMCalloutMock 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')) { System.assert(req.getBody().contains('TemplateDocument')); System.assert(req.getBody().contains('DestinationFolder')); System.assert(req.getBody().contains('DeficiencyList')); System.assert(req.getBody().contains('&')); res.setStatusCode(200); res.setBody('{"Href":"https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/documentxmlmergetasks/TASK-123","Status":"Queued"}'); return res; } if (req.getMethod() == 'GET' && req.getEndpoint().contains('/documentxmlmergetasks/TASK-123')) { res.setStatusCode(200); res.setBody('{"Href":"https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/documentxmlmergetasks/TASK-123","Status":"Completed"}'); return res; } if (req.getMethod() == 'GET' && req.getEndpoint().contains('/documents/template-guid')) { res.setStatusCode(200); res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename="GeneratedReview.pdf"'); res.setBodyAsBlob(Blob.valueOf('pdf-bytes')); return res; } res.setStatusCode(404); res.setBody('{"Message":"Not Found"}'); return res; } } @IsTest static void generatesDocumentAndPollsTaskStatus() { Appraiser_Case__c appraiserCase = new Appraiser_Case__c( Appraiser_Field_Review_Date__c = Date.newInstance(2026, 4, 2), Letter_Sent_Date__c = Date.newInstance(2026, 4, 9), FHA_Case_Number__c = '123-4567890', Appraiser_Name__c = 'Jamie Appraiser', Appraiser_Last_Name__c = 'Appraiser', Property_Street__c = '123 Main & Main ', 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 = 'Missing comparable sale adjustment detail.', Resolution__c = 'Added supporting calculations & notes.', Reference__c = 'VC-1' ); Test.setMock(HttpCalloutMock.class, new CLMCalloutMock()); Test.startTest(); CLMDocGenCallout.CLMDocGenResponse response = CLMDocGenCallout.generateDocument( appraiserCase.Id, 'https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/documents/template-guid', 'https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/folder-guid', 'Review_AC-00001.docx', 'UAT' ); CLMDocGenCallout.CLMDocGenResponse taskStatus = CLMDocGenCallout.getTaskStatus('TASK-123', 'S1'); Test.stopTest(); System.assertEquals(true, response.success); System.assertEquals('TASK-123', response.documentId); System.assert(response.documentUrl.contains('/documentxmlmergetasks/TASK-123')); System.assertEquals(true, taskStatus.success); System.assertEquals('Task status: Completed', taskStatus.message); } @IsTest static void normalizesResourcePathsAndExtractsAccountIds() { System.assertEquals( '2371cf36-eb8a-43fe-9f28-b5bbe7644397', CLMDocGenCallout.extractAccountId('https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/folder-guid') ); System.assertEquals( '/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/folder-guid', CLMDocGenCallout.normalizeResourcePath( 'https://uatna11.springcm.com/v2/2371cf36-eb8a-43fe-9f28-b5bbe7644397/folders/folder-guid', 'UAT' ) ); System.assertEquals( '/v2/' + CLMDocGenCallout.defaultAccountId('UAT') + '/folders/folder-guid', CLMDocGenCallout.normalizeResourcePath('/folders/folder-guid', 'UAT') ); } @IsTest static void downloadsGeneratedDocumentThroughDownloadCredential() { Test.setMock(HttpCalloutMock.class, new CLMCalloutMock()); Test.startTest(); CLMDocGenCallout.DownloadedDocument downloaded = CLMDocGenCallout.downloadDocument( 'https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documents/template-guid', 'UAT' ); Test.stopTest(); System.assertEquals('GeneratedReview.pdf', downloaded.fileName); System.assertEquals('application/pdf', downloaded.contentType); System.assertNotEquals(null, downloaded.body); } @IsTest static void buildsPreviewXmlAndRequestBody() { Appraiser_Case__c appraiserCase = new Appraiser_Case__c( Appraiser_Field_Review_Date__c = Date.newInstance(2026, 4, 2), Letter_Sent_Date__c = Date.newInstance(2026, 4, 9), FHA_Case_Number__c = '123-4567890', Appraiser_Name__c = 'Jamie Appraiser', Appraiser_Last_Name__c = 'Appraiser', 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 = 'Missing comparable sale adjustment detail.', Resolution__c = 'Added supporting calculations.', Reference__c = 'VC-1' ); String dataXml = CLMDocGenCallout.buildDataXmlForCase(appraiserCase.Id); String requestBodyJson = CLMDocGenCallout.buildRequestBodyJson( appraiserCase.Id, 'https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/documents/template-guid', 'https://apiuatna11.springcm.com/v2/bccae332-c7db-4892-ab85-257df0f70fea/folders/folder-guid', 'Review_AC-000002.docx' ); System.assert(dataXml.contains('')); System.assert(dataXml.contains('123-4567890')); System.assert(dataXml.contains('VC-1')); System.assert(requestBodyJson.contains('"DataXML"')); System.assert(requestBodyJson.contains('Review_AC-000002.docx')); System.assert(requestBodyJson.contains('template-guid')); } }