313 lines
12 KiB
OpenEdge ABL
313 lines
12 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');
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
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<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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');
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = new List<String>{'template-1'};
|
|
req.recordId = '001000000ABC123';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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);
|
|
}
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = templateIds;
|
|
req.recordId = '001000000ABC123';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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');
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = new List<String>{'template-1', 'template-2', 'template-1'}; // Duplicate
|
|
req.recordId = '001000000ABC123';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{req});
|
|
Test.stopTest();
|
|
|
|
// Assert
|
|
System.assertEquals(true, results[0].success, 'Should handle duplicates');
|
|
}
|
|
|
|
// Custom fields test removed - not supported in InvocableVariable (Phase 2 enhancement)
|
|
|
|
/**
|
|
* @description Test validation failure - no template IDs
|
|
*/
|
|
@isTest
|
|
static void testValidationNoTemplates() {
|
|
// Arrange
|
|
DocusignCredentials.setTestCredentials('test-account-id', 'callout:DocusignAPI', 'test-token');
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = new List<String>(); // Empty
|
|
req.recordId = '001000000ABC123';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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);
|
|
}
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = templateIds; // 15 templates (> max of 14)
|
|
req.recordId = '001000000ABC123';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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');
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = new List<String>{'template-1'};
|
|
req.recordId = ''; // Blank
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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');
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = new List<String>{'invalid-template'};
|
|
req.recordId = '001000000ABC123';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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');
|
|
|
|
DocusignCompositeEnvelopeBuilder.Request req = new DocusignCompositeEnvelopeBuilder.Request();
|
|
req.templateIds = new List<String>{'template-1'};
|
|
req.recordId = '001000000ABC123';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
List<DocusignCompositeEnvelopeBuilder.Result> results =
|
|
DocusignCompositeEnvelopeBuilder.sendCompositeEnvelope(new List<DocusignCompositeEnvelopeBuilder.Request>{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');
|
|
}
|
|
|
|
/**
|
|
* @description Test JSON builder with all parameters
|
|
*/
|
|
@isTest
|
|
static void testJSONBuilder() {
|
|
// Arrange
|
|
List<String> templateIds = new List<String>{'template-A', 'template-B'};
|
|
String recordId = '001000000ABC123';
|
|
String language = 'es';
|
|
String emailSubject = 'Custom Subject';
|
|
|
|
// Act
|
|
Test.startTest();
|
|
String json = DocusignCompositeEnvelopeBuilder.buildCompositeEnvelopeJSON(
|
|
templateIds,
|
|
recordId,
|
|
language,
|
|
emailSubject,
|
|
null // customFields - not supported in Phase 1
|
|
);
|
|
Test.stopTest();
|
|
|
|
// Assert
|
|
System.assertNotEquals(null, json, 'JSON should be generated');
|
|
System.assert(json.contains('template-A'), 'Should contain first template');
|
|
System.assert(json.contains('template-B'), 'Should contain second template');
|
|
System.assert(json.contains(emailSubject), 'Should contain email subject');
|
|
System.assert(json.contains('SalesforceRecordId'), 'Should contain record ID field');
|
|
System.assert(json.contains(language), 'Should contain language');
|
|
}
|
|
}
|