UNPKG

@tiberriver256/mcp-server-azure-devops

Version:

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

169 lines 7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const feature_1 = require("./feature"); const server_1 = require("../../../server"); const auth_1 = require("../../../shared/auth"); // Skip tests if no PAT is available const hasPat = process.env.AZURE_DEVOPS_PAT && process.env.AZURE_DEVOPS_ORG_URL; const describeOrSkip = hasPat ? describe : describe.skip; describeOrSkip('searchWorkItems (Integration)', () => { let connection; let config; let projectId; beforeAll(async () => { // Set up the connection config = { organizationUrl: process.env.AZURE_DEVOPS_ORG_URL || '', authMethod: auth_1.AuthenticationMethod.PersonalAccessToken, personalAccessToken: process.env.AZURE_DEVOPS_PAT || '', defaultProject: process.env.AZURE_DEVOPS_DEFAULT_PROJECT || '', }; connection = await (0, server_1.getConnection)(config); projectId = config.defaultProject || ''; // Skip tests if no default project is set if (!projectId) { console.warn('Skipping integration tests: No default project set'); } }, 30000); it('should search for work items', async () => { // Skip test if no default project if (!projectId) { return; } // Act const result = await (0, feature_1.searchWorkItems)(connection, { searchText: 'test', projectId, top: 10, includeFacets: true, }); // Assert expect(result).toBeDefined(); expect(typeof result.count).toBe('number'); expect(Array.isArray(result.results)).toBe(true); // If there are results, verify their structure if (result.results.length > 0) { const firstResult = result.results[0]; expect(firstResult.project).toBeDefined(); expect(firstResult.fields).toBeDefined(); expect(firstResult.fields['system.id']).toBeDefined(); expect(firstResult.fields['system.title']).toBeDefined(); expect(firstResult.hits).toBeDefined(); expect(firstResult.url).toBeDefined(); } // If facets were requested, verify their structure if (result.facets) { expect(result.facets).toBeDefined(); } }, 30000); it('should filter work items by type', async () => { // Skip test if no default project if (!projectId) { return; } // Act const result = await (0, feature_1.searchWorkItems)(connection, { searchText: 'test', projectId, filters: { 'System.WorkItemType': ['Bug'], }, top: 10, }); // Assert expect(result).toBeDefined(); // If there are results, verify they are all bugs if (result.results.length > 0) { result.results.forEach((item) => { expect(item.fields['system.workitemtype'].toLowerCase()).toBe('bug'); }); } }, 30000); it('should support pagination', async () => { // Skip test if no default project if (!projectId) { return; } // Act - Get first page const firstPage = await (0, feature_1.searchWorkItems)(connection, { searchText: 'test', projectId, top: 5, skip: 0, }); // If there are enough results, test pagination if (firstPage.count > 5) { // Act - Get second page const secondPage = await (0, feature_1.searchWorkItems)(connection, { searchText: 'test', projectId, top: 5, skip: 5, }); // Assert expect(secondPage).toBeDefined(); expect(secondPage.results).toBeDefined(); // Verify the pages have different items if (firstPage.results.length > 0 && secondPage.results.length > 0) { const firstPageIds = firstPage.results.map((r) => r.fields['system.id']); const secondPageIds = secondPage.results.map((r) => r.fields['system.id']); // Check that the pages don't have overlapping IDs const overlap = firstPageIds.filter((id) => secondPageIds.includes(id)); expect(overlap.length).toBe(0); } } }, 30000); it('should support sorting', async () => { // Skip test if no default project if (!projectId) { return; } // Act - Get results sorted by creation date (newest first) const result = await (0, feature_1.searchWorkItems)(connection, { searchText: 'test', projectId, orderBy: [{ field: 'System.CreatedDate', sortOrder: 'DESC' }], top: 10, }); // Assert expect(result).toBeDefined(); // If there are multiple results, verify they are sorted if (result.results.length > 1) { const dates = result.results .filter((r) => r.fields['system.createddate'] !== undefined) .map((r) => new Date(r.fields['system.createddate']).getTime()); // Check that dates are in descending order for (let i = 0; i < dates.length - 1; i++) { expect(dates[i]).toBeGreaterThanOrEqual(dates[i + 1]); } } }, 30000); // Add a test to verify Azure Identity authentication if configured if (process.env.AZURE_DEVOPS_AUTH_METHOD?.toLowerCase() === 'azure-identity') { test('should search work items using Azure Identity authentication', async () => { // Skip if required environment variables are missing if (!process.env.AZURE_DEVOPS_ORG_URL || !process.env.TEST_PROJECT_ID) { console.log('Skipping test: required environment variables missing'); return; } // Create a config with Azure Identity authentication const testConfig = { organizationUrl: process.env.AZURE_DEVOPS_ORG_URL, authMethod: auth_1.AuthenticationMethod.AzureIdentity, defaultProject: process.env.TEST_PROJECT_ID, }; // Create the connection using the config const connection = await (0, server_1.getConnection)(testConfig); // Search work items const result = await (0, feature_1.searchWorkItems)(connection, { projectId: process.env.TEST_PROJECT_ID, searchText: 'test', }); // Check that the response is properly formatted expect(result).toBeDefined(); expect(result.count).toBeDefined(); expect(Array.isArray(result.results)).toBe(true); }); } }); //# sourceMappingURL=feature.spec.int.js.map