UNPKG

@tiberriver256/mcp-server-azure-devops

Version:

Azure DevOps reference server for the Model Context Protocol (MCP)

393 lines 18.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const feature_1 = require("./feature"); const feature_2 = require("../get-wikis/feature"); const test_helpers_1 = require("@/shared/test/test-helpers"); const environment_1 = require("@/utils/environment"); const azure_devops_errors_1 = require("@/shared/errors/azure-devops-errors"); // Ensure environment variables are set for testing process.env.AZURE_DEVOPS_DEFAULT_PROJECT = process.env.AZURE_DEVOPS_DEFAULT_PROJECT || 'default-project'; describe('listWikiPages integration', () => { let projectName; let orgUrl; let organizationId; beforeAll(async () => { // Mock the required environment variable for testing process.env.AZURE_DEVOPS_ORG_URL = process.env.AZURE_DEVOPS_ORG_URL || 'https://example.visualstudio.com'; // Get and validate required environment variables const envProjectName = process.env.AZURE_DEVOPS_DEFAULT_PROJECT; if (!envProjectName) { throw new Error('AZURE_DEVOPS_DEFAULT_PROJECT environment variable is required'); } projectName = envProjectName; const envOrgUrl = process.env.AZURE_DEVOPS_ORG_URL; if (!envOrgUrl) { throw new Error('AZURE_DEVOPS_ORG_URL environment variable is required'); } orgUrl = envOrgUrl; organizationId = (0, environment_1.getOrgNameFromUrl)(orgUrl); }); describe('Happy Path Tests', () => { test('should list pages in real test wiki', async () => { // Skip if no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } // List wiki pages const result = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); // Verify the result structure expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); // If pages exist, verify their structure matches WikiPageSummary interface if (result.length > 0) { const page = result[0]; expect(page).toHaveProperty('id'); expect(page).toHaveProperty('path'); expect(page).toHaveProperty('url'); expect(typeof page.id).toBe('number'); expect(typeof page.path).toBe('string'); // url and order are optional if (page.url !== undefined) { expect(typeof page.url).toBe('string'); } if (page.order !== undefined) { expect(typeof page.order).toBe('number'); } } }); test('should handle wiki listing for different wiki structures', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } // Get all pages for different wiki structures const allPages = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); expect(Array.isArray(allPages)).toBe(true); // If we have pages, verify they have expected structure if (allPages.length > 0) { const firstPage = allPages[0]; expect(firstPage).toHaveProperty('id'); expect(firstPage).toHaveProperty('path'); expect(firstPage).toHaveProperty('url'); // Verify nested pages if they exist const nestedPages = allPages.filter((page) => page.path.includes('/') && page.path !== '/'); console.log(`Found ${nestedPages.length} nested pages out of ${allPages.length} total pages`); } }); test('should handle basic wiki page listing consistently', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } // Test basic page listing const firstResult = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); expect(Array.isArray(firstResult)).toBe(true); // Test again to ensure consistency const secondResult = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); expect(Array.isArray(secondResult)).toBe(true); // Results should be consistent expect(secondResult.length).toBe(firstResult.length); }); }); describe('Error Scenarios', () => { test('should handle invalid wikiId (expect 404 error)', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } const invalidWikiId = 'non-existent-wiki-id-12345'; await expect((0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: invalidWikiId, })).rejects.toThrow(azure_devops_errors_1.AzureDevOpsError); }); test('should handle invalid projectId', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } const invalidProjectId = 'non-existent-project-12345'; await expect((0, feature_1.listWikiPages)({ organizationId, projectId: invalidProjectId, wikiId: 'any-wiki', })).rejects.toThrow(azure_devops_errors_1.AzureDevOpsError); }); test('should handle invalid organizationId', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } const invalidOrgId = 'non-existent-org-12345'; await expect((0, feature_1.listWikiPages)({ organizationId: invalidOrgId, projectId: projectName, wikiId: 'any-wiki', })).rejects.toThrow(azure_devops_errors_1.AzureDevOpsError); }); }); describe('Edge Cases', () => { test('should handle empty wikis gracefully', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } // Test with a path that likely doesn't exist const result = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); // Should return an array (may be empty or contain all pages depending on API behavior) expect(Array.isArray(result)).toBe(true); // Note: Azure DevOps API may return all pages when path doesn't match console.log(`Path filter test returned ${result.length} pages`); }); test('should handle deeply nested paths', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } // Test with default parameters const result = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); expect(Array.isArray(result)).toBe(true); // Should not throw error with basic parameters }); test('should handle boundary recursionLevel values', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } // Test basic page listing const firstResult = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); expect(Array.isArray(firstResult)).toBe(true); // Test again for consistency const secondResult = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); expect(Array.isArray(secondResult)).toBe(true); }); }); describe('Data Structure Validation', () => { test('should verify returned data structure matches WikiPageSummary interface', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } const result = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); expect(Array.isArray(result)).toBe(true); // Validate each page in the result result.forEach((page) => { // Required fields expect(page).toHaveProperty('id'); expect(page).toHaveProperty('path'); expect(page).toHaveProperty('url'); expect(typeof page.id).toBe('number'); expect(typeof page.path).toBe('string'); // Optional fields if (page.url !== undefined) { expect(typeof page.url).toBe('string'); } if (page.order !== undefined) { expect(typeof page.order).toBe('number'); } // Validate URL format (if present) if (page.url !== undefined) { expect(page.url).toMatch(/^https?:\/\//); } // Validate path format (should start with /) expect(page.path).toMatch(/^\//); }); }); }); describe('Performance and Pagination', () => { test('should handle large wiki structures efficiently', async () => { // Skip if integration tests are disabled or no connection available if ((0, test_helpers_1.shouldSkipIntegrationTest)()) { return; } // Get a real connection using environment variables const connection = await (0, test_helpers_1.getTestConnection)(); if (!connection) { throw new Error('Connection should be available when test is not skipped'); } // First get available wikis const wikis = await (0, feature_2.getWikis)(connection, { projectId: projectName }); // Skip if no wikis are available if (wikis.length === 0) { console.log('Skipping test: No wikis available in the project'); return; } // Use the first available wiki const wiki = wikis[0]; if (!wiki.name) { throw new Error('Wiki name is undefined'); } const startTime = Date.now(); const result = await (0, feature_1.listWikiPages)({ organizationId, projectId: projectName, wikiId: wiki.name, }); const endTime = Date.now(); const duration = endTime - startTime; expect(Array.isArray(result)).toBe(true); // Performance check - should complete within reasonable time (30 seconds) expect(duration).toBeLessThan(30000); console.log(`Retrieved ${result.length} pages in ${duration}ms`); }); }); }); //# sourceMappingURL=feature.spec.int.js.map