salesforce-composite-envelo.../composite-envelope-builder/force-app/main/default/classes/DocusignCompositeEnvelopeBu...

280 lines
11 KiB
OpenEdge ABL

/**
* @description Test class for DocusignCompositeEnvelopeBuilder
* @author Paul Huliganga
* @date 2026-02-23
*/
@isTest
private class DocusignCompositeEnvelopeBuilderTest {
/**
* @description Mock HTTP callout for Docusign API
*/
private class DocusignMock implements HttpCalloutMock {
private Integer statusCode;
private String responseBody;
public DocusignMock(Integer statusCode, String responseBody) {
this.statusCode = statusCode;
this.responseBody = responseBody;
}
public HTTPResponse respond(HTTPRequest req) {
HttpResponse res = new HttpResponse();
res.setStatusCode(this.statusCode);
res.setBody(this.responseBody);
res.setStatus(this.statusCode == 201 ? 'Created' : 'Error');
return res;
}
}
/**
* @description Setup test data
*/
@testSetup
static void setup() {
// Create Custom Setting for credentials
Docusign_Configuration__c config = new Docusign_Configuration__c();
config.Account_Id__c = 'test-account-id-12345';
config.Base_URL__c = 'callout:DocusignAPI';
insert config;
}
/**
* @description Test successful envelope creation with 3 templates
*/
@isTest
static void testSuccessfulEnvelopeCreation() {
// Arrange
String envelopeId = 'envelope-12345-abcde';
String mockResponse = '{"envelopeId":"' + envelopeId + '","status":"sent"}';
Test.setMock(HttpCalloutMock.class, new DocusignMock(201, mockResponse));
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = new List<String>{'template-1', 'template-2', 'template-3'};
req.recordId = '001000000ABC123';
req.language = 'en';
req.emailSubject = 'Test Envelope';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(1, results.size(), 'Should return 1 result');
System.assertEquals(true, results[0].success, 'Should be successful');
System.assertEquals(envelopeId, results[0].envelopeId, 'Should return envelope ID');
System.assertEquals(null, results[0].errorMessage, 'Should have no error message');
}
/**
* @description Test with single template (minimum)
*/
@isTest
static void testSingleTemplate() {
// Arrange
String mockResponse = '{"envelopeId":"envelope-single","status":"sent"}';
Test.setMock(HttpCalloutMock.class, new DocusignMock(201, mockResponse));
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = new List<String>{'template-1'};
req.recordId = '001000000ABC123';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(true, results[0].success, 'Should be successful with 1 template');
}
/**
* @description Test with 14 templates (maximum)
*/
@isTest
static void testMaximumTemplates() {
// Arrange
String mockResponse = '{"envelopeId":"envelope-max","status":"sent"}';
Test.setMock(HttpCalloutMock.class, new DocusignMock(201, mockResponse));
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
List<String> templateIds = new List<String>();
for (Integer i = 1; i <= 14; i++) {
templateIds.add('template-' + i);
}
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = templateIds;
req.recordId = '001000000ABC123';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(true, results[0].success, 'Should be successful with 14 templates');
}
/**
* @description Test with duplicate template IDs (should be deduplicated)
*/
@isTest
static void testDuplicateTemplates() {
// Arrange
String mockResponse = '{"envelopeId":"envelope-dedup","status":"sent"}';
Test.setMock(HttpCalloutMock.class, new DocusignMock(201, mockResponse));
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = new List<String>{'template-1', 'template-2', 'template-1'}; // Duplicate
req.recordId = '001000000ABC123';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(true, results[0].success, 'Should handle duplicates');
}
/**
* @description Test validation failure - no template IDs
*/
@isTest
static void testValidationNoTemplates() {
// Arrange
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = new List<String>(); // Empty
req.recordId = '001000000ABC123';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(false, results[0].success, 'Should fail validation');
System.assert(results[0].errorMessage.containsIgnoreCase('template'), 'Error should mention templates');
}
/**
* @description Test validation failure - too many templates
*/
@isTest
static void testValidationTooManyTemplates() {
// Arrange
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
List<String> templateIds = new List<String>();
for (Integer i = 1; i <= 15; i++) {
templateIds.add('template-' + i);
}
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = templateIds; // 15 templates (> max of 14)
req.recordId = '001000000ABC123';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(false, results[0].success, 'Should fail validation');
System.assert(results[0].errorMessage.contains('Maximum 14'), 'Error should mention limit');
}
/**
* @description Test validation failure - no record ID
*/
@isTest
static void testValidationNoRecordId() {
// Arrange
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = new List<String>{'template-1'};
req.recordId = ''; // Blank
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(false, results[0].success, 'Should fail validation');
System.assert(results[0].errorMessage.contains('record ID'), 'Error should mention record ID');
}
/**
* @description Test API error - 400 Bad Request
*/
@isTest
static void testAPIError400() {
// Arrange
String mockResponse = '{"errorCode":"INVALID_REQUEST_PARAMETER","message":"Invalid template ID"}';
Test.setMock(HttpCalloutMock.class, new DocusignMock(400, mockResponse));
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = new List<String>{'invalid-template'};
req.recordId = '001000000ABC123';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(false, results[0].success, 'Should fail with API error');
System.assert(results[0].errorMessage.contains('400'), 'Error should include status code');
}
/**
* @description Test API error - 401 Unauthorized
*/
@isTest
static void testAPIError401() {
// Arrange
String mockResponse = '{"errorCode":"USER_AUTHENTICATION_FAILED","message":"Invalid token"}';
Test.setMock(HttpCalloutMock.class, new DocusignMock(401, mockResponse));
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'invalid-token');
DocusignEnvelopeRequest req = new DocusignEnvelopeRequest();
req.templateIds = new List<String>{'template-1'};
req.recordId = '001000000ABC123';
// Act
Test.startTest();
List<DocusignEnvelopeResult> results =
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignEnvelopeRequest>{req});
Test.stopTest();
// Assert
System.assertEquals(false, results[0].success, 'Should fail with auth error');
System.assertNotEquals(null, results[0].errorMessage, 'Should have error message');
System.assert(String.isNotBlank(results[0].errorMessage), 'Error message should not be blank');
}
}