Skip to main content
Glama
PSPDFKit

Nutrient Document Engine MCP Server

by PSPDFKit
addNewPage.test.ts12 kB
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { addNewPage } from '../../../src/tools/document-editing/addNewPage.js'; import { createMockClient, MockedDocumentEngineClient } from '../../utils/mockTypes.js'; // Mock the logger to prevent console output during tests vi.mock('../../../src/utils/Logger.js', () => ({ logger: { error: vi.fn(), info: vi.fn(), debug: vi.fn(), warn: vi.fn(), }, })); // Mock the handleApiError function vi.mock('../../../src/utils/ErrorHandling.js', () => ({ handleApiError: vi.fn(error => error), })); describe('addNewPage', () => { let mockClient: MockedDocumentEngineClient; const mockDate = new Date('2023-01-01T12:00:00Z'); beforeEach(() => { mockClient = createMockClient(); // Mock Date to return a consistent date for testing vi.spyOn(global, 'Date').mockImplementation(() => mockDate as unknown as Date); // Mock Date.now // Mock Date.now() to return a consistent date Date.now = vi.fn(() => mockDate.getTime()); // Reset mocks }); afterEach(() => { vi.restoreAllMocks(); }); describe('successful scenarios', () => { it('should add a new page at the end of the document successfully', async () => { // Mock document info response mockClient['fetch-document-info'].mockResolvedValue({ data: { data: { pageCount: 5, title: 'Test Document', }, }, }); // Mock apply instructions response mockClient['document-apply-instructions'].mockResolvedValue({ data: { data: { title: 'Test Document', pageCount: 6, }, }, }); // Call the function const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123' }, page_size: 'A4', orientation: 'portrait', }); // Basic verification - just check that the function completed and returned markdown expect(result.markdown).toBeDefined(); expect(typeof result.markdown).toBe('string'); expect(result.markdown).toContain('# New Page Added Successfully'); expect(result.markdown).toContain('**Status:** 1 new page added'); expect(result.markdown).toContain('**Page Size:** A4'); expect(result.markdown).toContain('**Orientation:** Portrait'); }); it('should add a new page at a specific position successfully', async () => { // Mock document info response mockClient['fetch-document-info'].mockResolvedValue({ data: { data: { pageCount: 3, title: 'Test Document', }, }, }); // Mock apply instructions response mockClient['document-apply-instructions'].mockResolvedValue({ data: { data: { title: 'Test Document', pageCount: 4, }, }, }); // Call the function const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123' }, position: 1, // Add after the first page (0-based index) page_size: 'Letter', orientation: 'landscape', }); // Verify document-apply-instructions was called with the correct parameters expect(mockClient['document-apply-instructions']).toHaveBeenCalledWith( { documentId: 'doc_123' }, expect.objectContaining({ parts: [ { document: { id: '#self' }, pages: { start: 0, end: 0 }, }, { page: 'new', pageCount: 1, layout: { size: 'Letter', orientation: 'landscape', }, }, { document: { id: '#self' }, pages: { start: 1, end: -1 }, }, ], }) ); // Verify the result contains the expected markdown expect(result.markdown).toContain('# New Page Added Successfully'); expect(result.markdown).toContain('**Page Size:** Letter'); expect(result.markdown).toContain('**Orientation:** Landscape'); expect(result.markdown).toContain('**Position:** at position 1 (0-based index)'); expect(result.markdown).toContain('**Original Page Count:** 3'); expect(result.markdown).toContain('**New Page Count:** 4'); }); it('should use default values when optional parameters are not provided', async () => { // Mock document info response mockClient['fetch-document-info'].mockResolvedValue({ data: { data: { pageCount: 2, title: 'Test Document', }, }, }); // Mock apply instructions response mockClient['document-apply-instructions'].mockResolvedValue({ data: { data: { title: 'Test Document', pageCount: 3, }, }, }); // Call the function with minimal parameters const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123' }, page_size: 'A4', orientation: 'portrait', }); // Verify document-apply-instructions was called with default values expect(mockClient['document-apply-instructions']).toHaveBeenCalledWith( { documentId: 'doc_123' }, expect.objectContaining({ parts: [ { document: { id: '#self' } }, { page: 'new', pageCount: 1, layout: { size: 'A4', orientation: 'portrait', }, }, ], }) ); // Verify the result contains the expected markdown with default values expect(result.markdown).toContain('**Page Size:** A4'); expect(result.markdown).toContain('**Orientation:** Portrait'); expect(result.markdown).toContain('**Position:** at the end (position 2)'); }); it('should work with layers', async () => { // Mock layer info response mockClient['fetch-document-layer-info'].mockResolvedValue({ data: { data: { pageCount: 3, title: 'Test Document', layer: 'review-layer', documentId: 'doc_123', createdAt: '2023-01-01T12:00:00Z', updatedAt: '2023-01-02T12:00:00Z', }, }, }); // Mock apply instructions response for layer-specific endpoint mockClient['document-layer-apply-instructions'].mockResolvedValue({ data: { data: { title: 'Test Document', pageCount: 4, }, }, }); // Call the function with layer const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123', layer: 'review-layer', }, page_size: 'Letter', orientation: 'landscape', position: 2, }); // Verify the layer-specific endpoint was called expect(mockClient['document-layer-apply-instructions']).toHaveBeenCalledWith( { documentId: 'doc_123', layerName: 'review-layer', }, expect.objectContaining({ parts: [ { document: { id: '#self' }, pages: { start: 0, end: 1 }, }, { page: 'new', pageCount: 1, layout: { size: 'Letter', orientation: 'landscape', }, }, { document: { id: '#self' }, pages: { start: 2, end: -1 }, }, ], }) ); // Verify the default endpoint was NOT called expect(mockClient['document-apply-instructions']).not.toHaveBeenCalled(); // Verify the result contains the expected markdown expect(result.markdown).toContain('# New Page Added Successfully'); expect(result.markdown).toContain('**Status:** 1 new page added'); expect(result.markdown).toContain('**Document Title:** Test Document'); expect(result.markdown).toContain('**New Page Count:** 4'); expect(result.markdown).toContain('**Page Size:** Letter'); expect(result.markdown).toContain('**Orientation:** Landscape'); expect(result.markdown).toContain('**Position:** at position 2 (0-based index)'); }); }); describe('error scenarios', () => { it('should handle invalid position', async () => { // Mock document info response mockClient['fetch-document-info'].mockResolvedValue({ data: { data: { pageCount: 3, title: 'Test Document', }, }, }); // Call the function with an invalid position const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123' }, position: 5, // Out of bounds (document has 3 pages) }); // Verify document-apply-instructions was not called expect(mockClient['document-apply-instructions']).not.toHaveBeenCalled(); // Verify the result contains the error message expect(result.markdown).toContain('# Error Adding New Page'); expect(result.markdown).toContain('**Status:** Failed'); expect(result.markdown).toContain( 'An error occurred while trying to add a new page to the document:' ); expect(result.markdown).toContain('Position 5 is out of bounds (document has 3 pages)'); }); it('should handle API errors from document-apply-instructions', async () => { // Mock document info response mockClient['fetch-document-info'].mockResolvedValue({ data: { data: { pageCount: 5, title: 'Test Document', }, }, }); // Mock apply instructions to throw an error const errorMessage = 'API Error: Failed to add page'; mockClient['document-apply-instructions'].mockRejectedValue(new Error(errorMessage)); // Call the function const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123' }, page_size: 'A4', }); // Verify the result contains the error message expect(result.markdown).toContain('# Error Adding New Page'); expect(result.markdown).toContain( `An error occurred while trying to add a new page to the document: ${errorMessage}` ); }); it('should handle errors from fetch-document-info', async () => { // Mock fetch-document-info to throw an error const errorMessage = 'API Error: Document not found'; mockClient['fetch-document-info'].mockRejectedValue(new Error(errorMessage)); // Call the function const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123' }, }); // Verify the result contains the error message expect(result.markdown).toContain('# Error Adding New Page'); expect(result.markdown).toContain( `An error occurred while trying to add a new page to the document: ${errorMessage}` ); }); it('should handle validation errors', async () => { // Call the function with invalid parameters const result = await addNewPage(mockClient, { document_fingerprint: { document_id: 'doc_123' }, // eslint-disable-next-line @typescript-eslint/no-explicit-any page_size: 'invalid-size' as any, // Testing invalid page size for validation }); // Verify the result contains the validation error expect(result.markdown).toContain('# Error Adding New Page'); expect(result.markdown).toContain( 'An error occurred while trying to add a new page to the document:' ); expect(result.markdown).toContain('invalid-size'); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/PSPDFKit/nutrient-document-engine-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server