n8n-nodes-docuseal
Version:
Manage DocuSeal documents, templates, and submissions within n8n workflows.
629 lines • 33.9 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const DocusealApi_node_1 = require("../../nodes/Docuseal/DocusealApi.node");
const GenericFunctions = __importStar(require("../../nodes/Docuseal/GenericFunctions"));
jest.mock('../../nodes/Docuseal/GenericFunctions');
describe('DocusealApi.node', () => {
let docusealApi;
let mockExecuteFunctions;
let mockLoadOptionsFunctions;
beforeEach(() => {
docusealApi = new DocusealApi_node_1.DocusealApi();
mockExecuteFunctions = {
getInputData: jest.fn().mockReturnValue([{ json: {} }]),
getNodeParameter: jest.fn(),
getCredentials: jest.fn().mockResolvedValue({
environment: 'production',
productionApiKey: 'test-api-key',
testApiKey: 'test-api-key-sandbox',
baseUrl: 'https://api.docuseal.com',
}),
getNode: jest.fn().mockReturnValue({ name: 'DocuSeal Test' }),
continueOnFail: jest.fn().mockReturnValue(false),
helpers: {
request: jest.fn().mockResolvedValue({ success: true }),
returnJsonArray: jest
.fn()
.mockImplementation((data) => (Array.isArray(data) ? data : [data])),
constructExecutionMetaData: jest
.fn()
.mockImplementation((data, _metadata) => data.map ? data.map((item) => ({ json: item })) : [{ json: data }]),
},
};
mockLoadOptionsFunctions = {
getCredentials: jest.fn().mockResolvedValue({
environment: 'production',
productionApiKey: 'test-api-key',
testApiKey: 'test-api-key-sandbox',
baseUrl: 'https://api.docuseal.com',
}),
getNode: jest.fn().mockReturnValue({ name: 'DocuSeal Test' }),
helpers: {
request: jest.fn().mockResolvedValue({ success: true }),
returnJsonArray: jest
.fn()
.mockImplementation((data) => (Array.isArray(data) ? data : [data])),
constructExecutionMetaData: jest
.fn()
.mockImplementation((data, _metadata) => data.map ? data.map((item) => ({ json: item })) : [{ json: data }]),
},
};
jest.clearAllMocks();
});
describe('Node Description', () => {
it('should have correct basic properties', () => {
expect(docusealApi.description.displayName).toBe('DocuSeal');
expect(docusealApi.description.name).toBe('docusealApi');
expect(docusealApi.description.group).toEqual(['transform']);
expect(docusealApi.description.version).toBe(1);
});
it('should have correct credentials configuration', () => {
expect(docusealApi.description.credentials).toEqual([
{
name: 'docusealApi',
required: true,
},
]);
});
it('should have all required resources', () => {
const resourceProperty = docusealApi.description.properties?.find((prop) => prop.name === 'resource');
expect(resourceProperty).toBeDefined();
expect(resourceProperty.options).toHaveLength(5);
const resourceValues = resourceProperty.options.map((opt) => opt.value);
expect(['aiTool', 'form', 'submission', 'submitter', 'template']).toEqual(expect.arrayContaining(resourceValues));
});
});
describe('Load Options Methods', () => {
it('should have getTemplates method', () => {
expect(docusealApi.methods?.loadOptions?.getTemplates).toBeDefined();
expect(typeof docusealApi.methods?.loadOptions?.getTemplates).toBe('function');
});
it('should call getTemplates from GenericFunctions', async () => {
const mockGetTemplates = jest
.spyOn(GenericFunctions, 'getTemplates')
.mockResolvedValue([{ name: 'Template 1', value: '1' }]);
const result = await docusealApi.methods?.loadOptions?.getTemplates?.call(mockLoadOptionsFunctions);
expect(mockGetTemplates).toHaveBeenCalled();
expect(result).toEqual([{ name: 'Template 1', value: '1' }]);
});
it('should return empty array on error', async () => {
jest.spyOn(GenericFunctions, 'getTemplates').mockRejectedValue(new Error('API Error'));
const result = await docusealApi.methods?.loadOptions?.getTemplates?.call(mockLoadOptionsFunctions);
expect(result).toEqual([]);
});
});
describe('Execute Method - Template Operations', () => {
it('should get template by ID', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, name: 'Test Template' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('get')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/templates/1');
expect(result[0]).toHaveLength(1);
expect(result[0]?.[0]?.json).toEqual({ id: 1, name: 'Test Template' });
});
it('should get many templates with limit', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue([
{ id: 1, name: 'Template 1' },
{ id: 2, name: 'Template 2' },
]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('getMany')
.mockReturnValueOnce({})
.mockReturnValueOnce(50);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/templates', {}, { limit: 50 });
expect(result[0]).toHaveLength(2);
expect(result[0]?.[0]?.json).toEqual({ id: 1, name: 'Template 1' });
expect(result[0]?.[1]?.json).toEqual({ id: 2, name: 'Template 2' });
});
it('should create template from PDF with binary data', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, name: 'PDF Template' });
const mockPrepareBinaryData = jest
.spyOn(GenericFunctions, 'prepareBinaryData')
.mockResolvedValue(Buffer.from('pdf data'));
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('createFromPdf')
.mockReturnValueOnce('Test PDF Template')
.mockReturnValueOnce('binary')
.mockReturnValueOnce({})
.mockReturnValueOnce('data');
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockPrepareBinaryData).toHaveBeenCalledWith('data', 0);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/templates/pdf', {}, {}, expect.objectContaining({ formData: expect.any(Object) }));
expect(result[0]?.[0]?.json).toEqual({ id: 1, name: 'PDF Template' });
});
it('should create template from PDF with URL', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, name: 'PDF Template' });
const mockValidateUrl = jest
.spyOn(GenericFunctions, 'validateUrl')
.mockReturnValue({ isValid: true });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('createFromPdf')
.mockReturnValueOnce('Test PDF Template')
.mockReturnValueOnce('url')
.mockReturnValueOnce({})
.mockReturnValueOnce('https://example.com/test.pdf');
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockValidateUrl).toHaveBeenCalledWith('https://example.com/test.pdf');
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/templates/pdf', {}, {}, expect.objectContaining({ formData: expect.any(Object) }));
expect(result[0]?.[0]?.json).toEqual({ id: 1, name: 'PDF Template' });
});
it('should create template from HTML', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, name: 'HTML Template' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('createFromHtml')
.mockReturnValueOnce('Test HTML Template')
.mockReturnValueOnce('<html><body>Test</body></html>')
.mockReturnValueOnce({});
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/templates/html', expect.objectContaining({
name: 'Test HTML Template',
html: '<html><body>Test</body></html>',
}));
expect(result[0]?.[0]?.json).toEqual({ id: 1, name: 'HTML Template' });
});
it('should clone template', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 2, name: 'Cloned Template' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('clone')
.mockReturnValueOnce(1)
.mockReturnValueOnce('Cloned Template')
.mockReturnValueOnce({});
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/templates/1/clone', expect.objectContaining({ name: 'Cloned Template' }));
expect(result[0]?.[0]?.json).toEqual({ id: 2, name: 'Cloned Template' });
});
it('should merge templates', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 3, name: 'Merged Template' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('merge')
.mockReturnValueOnce('1,2')
.mockReturnValueOnce('Merged Template');
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/templates/merge', expect.objectContaining({
template_ids: [1, 2],
name: 'Merged Template',
}));
expect(result[0]?.[0]?.json).toEqual({ id: 3, name: 'Merged Template' });
});
it('should update template', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, name: 'Updated Template' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('update')
.mockReturnValueOnce(1)
.mockReturnValueOnce({ name: 'Updated Template' });
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('PUT', '/templates/1', expect.objectContaining({ name: 'Updated Template' }));
expect(result[0]?.[0]?.json).toEqual({ id: 1, name: 'Updated Template' });
});
it('should archive template', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ success: true });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('archive')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('DELETE', '/templates/1');
expect(result[0]?.[0]?.json).toEqual({ success: true });
});
});
describe('Execute Method - Submission Operations', () => {
it('should create submission', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, status: 'pending' });
const mockBuildSubmittersArray = jest
.spyOn(GenericFunctions, 'buildSubmittersArray')
.mockReturnValue([{ email: 'test@example.com' }]);
const mockBuildFieldValues = jest
.spyOn(GenericFunctions, 'buildFieldValues')
.mockReturnValue({});
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('create')
.mockReturnValueOnce(1)
.mockReturnValueOnce([{ email: 'test@example.com' }])
.mockReturnValueOnce({})
.mockReturnValue({});
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockBuildSubmittersArray).toHaveBeenCalled();
expect(mockBuildFieldValues).toHaveBeenCalled();
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/submissions', expect.objectContaining({
template_id: 1,
submitters: [{ email: 'test@example.com' }],
}));
expect(result[0]?.[0]?.json).toEqual({ id: 1, status: 'pending' });
});
it('should get submission by ID', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, status: 'completed' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('get')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/submissions/1');
expect(result[0]?.[0]?.json).toEqual({ id: 1, status: 'completed' });
});
it('should get submission documents', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue([{ id: 1, filename: 'document.pdf' }]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('getDocuments')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/submissions/1/documents');
expect(result[0]?.[0]?.json).toEqual({ id: 1, filename: 'document.pdf' });
});
it('should get many submissions with filters', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue([
{ id: 1, status: 'completed' },
{ id: 2, status: 'pending' },
]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('getMany')
.mockReturnValueOnce({ status: ['completed', 'pending'] })
.mockReturnValueOnce(50);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/submissions', {}, expect.objectContaining({
status: 'completed,pending',
limit: 50,
}));
expect(result[0]).toHaveLength(2);
});
it('should create submission from PDF', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, status: 'pending' });
const mockBuildSubmittersArray = jest
.spyOn(GenericFunctions, 'buildSubmittersArray')
.mockReturnValue([{ email: 'test@example.com' }]);
const mockPrepareBinaryData = jest
.spyOn(GenericFunctions, 'prepareBinaryData')
.mockResolvedValue(Buffer.from('pdf data'));
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('createFromPdf')
.mockReturnValueOnce('binary')
.mockReturnValueOnce([{ email: 'test@example.com' }])
.mockReturnValueOnce({})
.mockReturnValueOnce('data');
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockBuildSubmittersArray).toHaveBeenCalled();
expect(mockPrepareBinaryData).toHaveBeenCalledWith('data', 0);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/submissions/pdf', {}, {}, expect.objectContaining({ formData: expect.any(Object) }));
expect(result[0]?.[0]?.json).toEqual({ id: 1, status: 'pending' });
});
it('should create submission from HTML', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, status: 'pending' });
const mockBuildSubmittersArray = jest
.spyOn(GenericFunctions, 'buildSubmittersArray')
.mockReturnValue([{ email: 'test@example.com' }]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('createFromHtml')
.mockReturnValueOnce('<html><body>Document</body></html>')
.mockReturnValueOnce([{ email: 'test@example.com' }])
.mockReturnValueOnce({});
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockBuildSubmittersArray).toHaveBeenCalled();
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/submissions/html', expect.objectContaining({
html: '<html><body>Document</body></html>',
submitters: [{ email: 'test@example.com' }],
}));
expect(result[0]?.[0]?.json).toEqual({ id: 1, status: 'pending' });
});
it('should archive submission', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ success: true });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('archive')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('DELETE', '/submissions/1');
expect(result[0]?.[0]?.json).toEqual({ success: true });
});
});
describe('Execute Method - Submitter Operations', () => {
it('should get submitter by ID', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, email: 'test@example.com' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submitter')
.mockReturnValueOnce('get')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/submitters/1');
expect(result[0]?.[0]?.json).toEqual({ id: 1, email: 'test@example.com' });
});
it('should update submitter', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, email: 'updated@example.com' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submitter')
.mockReturnValueOnce('update')
.mockReturnValueOnce(1)
.mockReturnValueOnce({ email: 'updated@example.com' })
.mockReturnValueOnce({})
.mockReturnValueOnce({});
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('PUT', '/submitters/1', {
email: 'updated@example.com',
});
expect(result[0]?.[0]?.json).toEqual({ id: 1, email: 'updated@example.com' });
});
it('should get many submitters with filters', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue([
{ id: 1, email: 'user1@example.com' },
{ id: 2, email: 'user2@example.com' },
]);
const mockFormatDate = jest
.spyOn(GenericFunctions, 'formatDate')
.mockReturnValue('2023-01-01T00:00:00Z');
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submitter')
.mockReturnValueOnce('getMany')
.mockReturnValueOnce({ completed_after: '2023-01-01' })
.mockReturnValueOnce(50);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockFormatDate).toHaveBeenCalledWith('2023-01-01');
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/submitters', {}, expect.objectContaining({
completed_after: '2023-01-01T00:00:00Z',
limit: 50,
}));
expect(result[0]).toHaveLength(2);
});
});
describe('Execute Method - Form Operations', () => {
it('should get form started events', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue([{ id: 1, event: 'form_started', timestamp: '2023-01-01T00:00:00Z' }]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('form')
.mockReturnValueOnce('getStarted')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/submitters/1/form_started');
expect(result).toHaveLength(1);
expect(result[0]).toHaveLength(1);
expect(result[0]?.[0]).toHaveProperty('json');
expect(result[0]?.[0]?.json).toEqual({
id: 1,
event: 'form_started',
timestamp: '2023-01-01T00:00:00Z',
});
});
it('should get form viewed events', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue([{ id: 1, event: 'form_viewed', timestamp: '2023-01-01T00:00:00Z' }]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('form')
.mockReturnValueOnce('getViewed')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockDocusealApiRequest).toHaveBeenCalledWith('GET', '/submitters/1/form_viewed');
expect(result).toHaveLength(1);
expect(result[0]).toHaveLength(1);
expect(result[0]?.[0]?.json).toEqual({
id: 1,
event: 'form_viewed',
timestamp: '2023-01-01T00:00:00Z',
});
});
});
describe('Error Handling', () => {
it('should handle errors gracefully', async () => {
jest.spyOn(GenericFunctions, 'docusealApiRequest').mockRejectedValue(new Error('API Error'));
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('get')
.mockReturnValueOnce(1);
await expect(docusealApi.execute.call(mockExecuteFunctions)).rejects.toThrow('API Error');
});
it('should handle multiple items', async () => {
jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValueOnce({ id: 1, name: 'Template 1' })
.mockResolvedValueOnce({ id: 2, name: 'Template 2' });
mockExecuteFunctions.getInputData.mockReturnValue([
{ json: {} },
{ json: {} },
]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('get')
.mockReturnValueOnce(1)
.mockReturnValueOnce('template')
.mockReturnValueOnce('get')
.mockReturnValueOnce(2);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(result[0]).toHaveLength(2);
expect(result[0]?.[0]?.json).toEqual({ id: 1, name: 'Template 1' });
expect(result[0]?.[1]?.json).toEqual({ id: 2, name: 'Template 2' });
});
it('should handle continueOnFail errors', async () => {
jest.spyOn(GenericFunctions, 'docusealApiRequest').mockRejectedValue(new Error('API Error'));
mockExecuteFunctions.continueOnFail.mockReturnValue(true);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('get')
.mockReturnValueOnce(1);
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(result[0]).toHaveLength(1);
expect(result[0]?.[0]?.json).toEqual({ error: 'API Error' });
});
it('should validate URL for template creation', async () => {
const mockValidateUrl = jest
.spyOn(GenericFunctions, 'validateUrl')
.mockReturnValue({ isValid: false, message: 'Invalid URL format' });
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('createFromPdf')
.mockReturnValueOnce('Test Template')
.mockReturnValueOnce('url')
.mockReturnValueOnce({})
.mockReturnValueOnce('invalid-url');
await expect(docusealApi.execute.call(mockExecuteFunctions)).rejects.toThrow('Invalid file URL: Invalid URL format');
expect(mockValidateUrl).toHaveBeenCalledWith('invalid-url');
});
it('should handle template update with no fields', async () => {
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('template')
.mockReturnValueOnce('update')
.mockReturnValueOnce(1)
.mockReturnValueOnce({});
await expect(docusealApi.execute.call(mockExecuteFunctions)).rejects.toThrow('At least one field must be updated');
});
it('should handle submitter update with no fields', async () => {
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submitter')
.mockReturnValueOnce('update')
.mockReturnValueOnce(1)
.mockReturnValueOnce({})
.mockReturnValueOnce({})
.mockReturnValueOnce({});
await expect(docusealApi.execute.call(mockExecuteFunctions)).rejects.toThrow('At least one field must be updated');
});
it('should handle submission creation with no submitters', async () => {
const mockBuildSubmittersArray = jest
.spyOn(GenericFunctions, 'buildSubmittersArray')
.mockReturnValue([]);
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('create')
.mockReturnValueOnce(1)
.mockReturnValueOnce({})
.mockReturnValueOnce({});
await expect(docusealApi.execute.call(mockExecuteFunctions)).rejects.toThrow('At least one submitter is required');
expect(mockBuildSubmittersArray).toHaveBeenCalled();
});
});
describe('Additional Coverage Tests', () => {
it('should handle submission creation with all options', async () => {
const mockDocusealApiRequest = jest
.spyOn(GenericFunctions, 'docusealApiRequest')
.mockResolvedValue({ id: 1, status: 'pending' });
const mockBuildSubmittersArray = jest
.spyOn(GenericFunctions, 'buildSubmittersArray')
.mockReturnValue([{ email: 'test@example.com' }]);
const mockBuildFieldValues = jest
.spyOn(GenericFunctions, 'buildFieldValues')
.mockReturnValue({ field1: 'value1' });
const mockParseJsonInput = jest
.spyOn(GenericFunctions, 'parseJsonInput')
.mockReturnValue({ meta: 'data' });
const mockFormatDate = jest
.spyOn(GenericFunctions, 'formatDate')
.mockReturnValue('2023-12-31T23:59:59Z');
mockExecuteFunctions.getNodeParameter
.mockReturnValueOnce('submission')
.mockReturnValueOnce('create')
.mockReturnValueOnce(1)
.mockReturnValueOnce([{ email: 'test@example.com' }])
.mockReturnValueOnce({
bcc_completed: 'admin@example.com',
reply_to: 'noreply@example.com',
completed_redirect_url: 'https://example.com/completed',
expire_at: '2023-12-31',
external_id: 'ext123',
message: { messageFields: { subject: 'Please sign' } },
metadata: '{"key": "value"}',
order: 'sequential',
send_email: true,
send_sms: false,
})
.mockReturnValue({});
const result = await docusealApi.execute.call(mockExecuteFunctions);
expect(mockBuildSubmittersArray).toHaveBeenCalled();
expect(mockBuildFieldValues).toHaveBeenCalled();
expect(mockParseJsonInput).toHaveBeenCalledWith('{"key": "value"}');
expect(mockFormatDate).toHaveBeenCalledWith('2023-12-31');
expect(mockDocusealApiRequest).toHaveBeenCalledWith('POST', '/submissions', expect.objectContaining({
template_id: 1,
submitters: [{ email: 'test@example.com' }],
values: { field1: 'value1' },
preferences: {
bcc_completed: 'admin@example.com',
reply_to: 'noreply@example.com',
},
completed_redirect_url: 'https://example.com/completed',
expire_at: '2023-12-31T23:59:59Z',
external_id: 'ext123',
message: { subject: 'Please sign' },
metadata: { meta: 'data' },
order: 'sequential',
send_email: true,
send_sms: false,
}));
expect(result[0]?.[0]?.json).toEqual({ id: 1, status: 'pending' });
});
});
});
//# sourceMappingURL=DocusealApi.node.test.js.map