Skip to main content
Glama
PSPDFKit

Nutrient Document Engine MCP Server

by PSPDFKit
deleteAnnotations.test.ts11.4 kB
import { describe, it, expect, vi, beforeEach } from 'vitest'; import { deleteAnnotations } from '../../../src/tools/annotations/deleteAnnotations.js'; import { createMockClient, MockedDocumentEngineClient } from '../../utils/mockTypes.js'; // Import original functions - no mocking needed // 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(), }, })); describe('deleteAnnotations', () => { let mockClient: MockedDocumentEngineClient; beforeEach(() => { mockClient = createMockClient(); }); describe('successful scenarios', () => { it('should delete annotations successfully', async () => { // Mock annotation details responses const mockAnnotation1 = { id: 'anno_123', content: { type: 'note', pageIndex: 0, bbox: [100, 200, 50, 30], createdAt: '2023-01-01T12:00:00Z', }, createdBy: 'Test User', }; const mockAnnotation2 = { id: 'anno_456', content: { type: 'highlight', pageIndex: 1, bbox: [150, 250, 100, 20], createdAt: '2023-01-02T12:00:00Z', }, createdBy: 'Another User', }; // Set up the mock responses mockClient['get-document-annotation'].mockImplementation( ({ annotationId }: { annotationId: string }) => { if (annotationId === 'anno_123') { return Promise.resolve({ data: mockAnnotation1 }); } else if (annotationId === 'anno_456') { return Promise.resolve({ data: mockAnnotation2 }); } return Promise.reject(new Error('Annotation not found')); } ); mockClient['delete-document-annotation'].mockResolvedValue({}); // Call the function const result = await deleteAnnotations(mockClient, { document_fingerprint: { document_id: 'doc_123' }, annotation_ids: ['anno_123', 'anno_456'], }); // Verify the client was called with the correct parameters expect(mockClient['get-document-annotation']).toHaveBeenCalledTimes(2); expect(mockClient['get-document-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_123', }); expect(mockClient['get-document-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_456', }); expect(mockClient['delete-document-annotation']).toHaveBeenCalledTimes(2); expect(mockClient['delete-document-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_123', }); expect(mockClient['delete-document-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_456', }); // Verify the result contains the expected markdown expect(result.markdown).toContain('# Annotations Deleted Successfully'); expect(result.markdown).toContain('**Status:** 2 annotations removed'); expect(result.markdown).toContain('**Document ID:** doc_123'); expect(result.markdown).toContain('**Deleted Annotation IDs:** anno_123, anno_456'); expect(result.markdown).toContain('## Deleted Annotation Details'); expect(result.markdown).toContain('### Annotation 1: anno_123'); expect(result.markdown).toContain('- **Type:** note'); expect(result.markdown).toContain('- **Author:** Test User'); expect(result.markdown).toContain('- **Page:** 0'); expect(result.markdown).toContain('### Annotation 2: anno_456'); expect(result.markdown).toContain('- **Type:** highlight'); expect(result.markdown).toContain('- **Author:** Another User'); expect(result.markdown).toContain('- **Page:** 1'); }); it('should handle single annotation deletion', async () => { // Mock annotation details response const mockAnnotation = { id: 'anno_123', content: { type: 'note', pageIndex: 0, bbox: [100, 200, 50, 30], createdAt: '2023-01-01T12:00:00Z', }, createdBy: 'Test User', }; // Set up the mock responses mockClient['get-document-annotation'].mockResolvedValue({ data: mockAnnotation }); mockClient['delete-document-annotation'].mockResolvedValue({}); // Call the function with a single annotation ID const result = await deleteAnnotations(mockClient, { document_fingerprint: { document_id: 'doc_123' }, annotation_ids: ['anno_123'], }); // Verify the client was called with the correct parameters expect(mockClient['get-document-annotation']).toHaveBeenCalledTimes(1); expect(mockClient['delete-document-annotation']).toHaveBeenCalledTimes(1); // Verify the result contains the expected markdown expect(result.markdown).toContain('# Annotations Deleted Successfully'); expect(result.markdown).toContain('**Status:** 1 annotation removed'); expect(result.markdown).not.toContain('**Status:** 1 annotations removed'); }); it('should respect confirm_deletion parameter', async () => { // Call the function with confirm_deletion = false const result = await deleteAnnotations(mockClient, { document_fingerprint: { document_id: 'doc_123' }, annotation_ids: ['anno_123'], confirm_deletion: false, }); // Verify the client was not called expect(mockClient['get-document-annotation']).not.toHaveBeenCalled(); expect(mockClient['delete-document-annotation']).not.toHaveBeenCalled(); // Verify the result contains the cancellation message expect(result.markdown).toContain('# Annotation Deletion Cancelled'); expect(result.markdown).toContain('**Status:** Deletion cancelled by user request'); expect(result.markdown).toContain( 'The annotation deletion was cancelled because `confirm_deletion` was set to `false`' ); }); it('should work with layers', async () => { // Mock annotation details responses const mockAnnotation1 = { id: 'anno_123', content: { type: 'note', pageIndex: 0, bbox: [100, 200, 50, 30], createdAt: '2023-01-01T12:00:00Z', }, createdBy: 'Test User', }; const mockAnnotation2 = { id: 'anno_456', content: { type: 'highlight', pageIndex: 1, bbox: [150, 250, 100, 20], createdAt: '2023-01-02T12:00:00Z', }, createdBy: 'Another User', }; // Set up the mock responses for layer-specific endpoints mockClient['get-document-layer-annotation'].mockImplementation( ({ annotationId }: { annotationId: string }) => { if (annotationId === 'anno_123') { return Promise.resolve({ data: mockAnnotation1 }); } else if (annotationId === 'anno_456') { return Promise.resolve({ data: mockAnnotation2 }); } return Promise.reject(new Error('Annotation not found')); } ); mockClient['delete-document-layer-annotation'].mockResolvedValue({}); // Call the function with layer const result = await deleteAnnotations(mockClient, { document_fingerprint: { document_id: 'doc_123', layer: 'review-layer', }, annotation_ids: ['anno_123', 'anno_456'], }); // Verify the layer-specific endpoints were called expect(mockClient['get-document-layer-annotation']).toHaveBeenCalledTimes(2); expect(mockClient['get-document-layer-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_123', layerName: 'review-layer', }); expect(mockClient['get-document-layer-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_456', layerName: 'review-layer', }); expect(mockClient['delete-document-layer-annotation']).toHaveBeenCalledTimes(2); expect(mockClient['delete-document-layer-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_123', layerName: 'review-layer', }); expect(mockClient['delete-document-layer-annotation']).toHaveBeenCalledWith({ documentId: 'doc_123', annotationId: 'anno_456', layerName: 'review-layer', }); // Verify the default endpoints were NOT called expect(mockClient['get-document-annotation']).not.toHaveBeenCalled(); expect(mockClient['delete-document-annotation']).not.toHaveBeenCalled(); // Verify the result contains layer information expect(result.markdown).toContain('# Annotations Deleted Successfully'); expect(result.markdown).toContain('**Status:** 2 annotations removed'); expect(result.markdown).toContain('**Document ID:** doc_123'); expect(result.markdown).toContain('**Layer:** review-layer'); expect(result.markdown).toContain('**Deleted Annotation IDs:** anno_123, anno_456'); }); }); describe('error scenarios', () => { it('should handle annotation not found error', async () => { // Mock the get-document-annotation to throw an error mockClient['get-document-annotation'].mockRejectedValue(new Error('Annotation not found')); // Call the function const result = await deleteAnnotations(mockClient, { document_fingerprint: { document_id: 'doc_123' }, annotation_ids: ['anno_123'], }); // Verify the delete-document-annotation was not called expect(mockClient['delete-document-annotation']).not.toHaveBeenCalled(); // Verify the result contains the error message expect(result.markdown).toContain('# Error: Annotation Not Found'); expect(result.markdown).toContain('**Status:** Annotation does not exist'); expect(result.markdown).toContain('**Document ID:** doc_123'); expect(result.markdown).toContain('**Annotation IDs:** anno_123'); expect(result.markdown).toContain('## Possible Reasons'); }); it('should handle general errors during deletion', async () => { // Mock the get-document-annotation to succeed mockClient['get-document-annotation'].mockResolvedValue({ data: { id: 'anno_123', content: { type: 'note', pageIndex: 0, bbox: [100, 200, 50, 30], }, }, }); // Mock the delete-document-annotation to throw an error const errorMessage = 'API Error: Permission denied'; mockClient['delete-document-annotation'].mockRejectedValue(new Error(errorMessage)); // Call the function const result = await deleteAnnotations(mockClient, { document_fingerprint: { document_id: 'doc_123' }, annotation_ids: ['anno_123'], }); // Verify the result contains the error message expect(result.markdown).toContain('# Error Deleting Annotations'); expect(result.markdown).toContain( `An error occurred while trying to delete the annotations: ${errorMessage}` ); expect(result.markdown).toContain('## Troubleshooting Tips'); }); }); });

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