Skip to main content
Glama
getFieldMetadata.test.ts9.25 kB
/** * Tests for the field metadata retrieval functionality */ import { Failure, Success } from '../../../utils/try' import { FieldCategory } from '../../types/fieldMetadata.types' import { callJiraApi } from '../callJiraApi' import { categorizeFields } from '../categorizeFields' import { clearCache } from '../fieldMetadataCache' import { findTargetProject } from '../findTargetProject' import { getAndCategorizeFields } from '../getAndCategorizeFields' import { getFieldMetadata } from '../getFieldMetadataFunction' import type { JiraFieldMetadataResponse, JiraProjectFieldMetadata } from '../../types/fieldMetadata.types' import type { JiraApiConfig } from '../apiTypes' // Mock dependencies jest.mock('../callJiraApi') jest.mock('../findTargetProject') const mockedCallJiraApi = callJiraApi as jest.MockedFunction<typeof callJiraApi> const mockedFindTargetProject = findTargetProject as jest.MockedFunction<typeof findTargetProject> describe('Field Metadata Retrieval', () => { const mockConfig: JiraApiConfig = { baseUrl: 'https://example.atlassian.net', username: 'test-user', apiToken: 'test-token', } const mockProjectKey = 'TEST' const mockIssueTypeId = '10001' // Sample field metadata response const mockFieldMetadataResponse: JiraFieldMetadataResponse = { projects: [ { id: '10000', key: 'TEST', name: 'Test Project', issuetypes: [ { id: '10001', name: 'Story', subtask: false, fields: { summary: { id: 'summary', name: 'Summary', required: true, schema: { type: 'string', system: 'summary', }, }, description: { id: 'description', name: 'Description', required: false, schema: { type: 'doc', system: 'description', }, }, customfield_10001: { id: 'customfield_10001', name: 'Story Points', required: false, custom: true, schema: { type: 'number', custom: 'com.atlassian.jira.plugin.system.customfieldtypes:float', }, }, }, }, ], }, ], } beforeEach(() => { jest.clearAllMocks() clearCache() }) describe('getFieldMetadata', () => { it('should retrieve field metadata successfully', async () => { // Setup mock response mockedCallJiraApi.mockResolvedValueOnce(Success(mockFieldMetadataResponse)) // Call the function const result = await getFieldMetadata(mockProjectKey, mockIssueTypeId, mockConfig) // Assert results expect(result.error).toBeUndefined() expect(result.value).toEqual(mockFieldMetadataResponse) expect(mockedCallJiraApi).toHaveBeenCalledWith({ config: mockConfig, endpoint: `/rest/api/3/issue/createmeta?projectKeys=${mockProjectKey}&issuetypeIds=${mockIssueTypeId}&expand=projects.issuetypes.fields`, method: 'GET', }) }) it('should return error when project key is missing', async () => { // Call with empty project key const result = await getFieldMetadata('', mockIssueTypeId, mockConfig) // Assert results expect(result.error).not.toBeNull() expect(result.error?.message).toContain('Project key is required') expect(mockedCallJiraApi).not.toHaveBeenCalled() }) it('should return error when issue type ID is missing', async () => { // Call with empty issue type ID const result = await getFieldMetadata(mockProjectKey, '', mockConfig) // Assert results expect(result.error).not.toBeNull() expect(result.error?.message).toContain('Issue type ID is required') expect(mockedCallJiraApi).not.toHaveBeenCalled() }) it('should return cached data when available', async () => { // First call to populate cache mockedCallJiraApi.mockResolvedValueOnce(Success(mockFieldMetadataResponse)) await getFieldMetadata(mockProjectKey, mockIssueTypeId, mockConfig) // Reset mock to verify it's not called again mockedCallJiraApi.mockClear() // Second call should use cache const result = await getFieldMetadata(mockProjectKey, mockIssueTypeId, mockConfig) // Assert results expect(result.error).toBeUndefined() expect(result.value).toEqual(mockFieldMetadataResponse) expect(mockedCallJiraApi).not.toHaveBeenCalled() }) it('should force refresh when requested', async () => { // First call to populate cache mockedCallJiraApi.mockResolvedValueOnce(Success(mockFieldMetadataResponse)) await getFieldMetadata(mockProjectKey, mockIssueTypeId, mockConfig, true) // Reset mock for second call mockedCallJiraApi.mockClear() mockedCallJiraApi.mockResolvedValueOnce(Success(mockFieldMetadataResponse)) // Second call with force refresh const result = await getFieldMetadata(mockProjectKey, mockIssueTypeId, mockConfig, true) // Assert results expect(result.error).toBeUndefined() expect(result.value).toEqual(mockFieldMetadataResponse) expect(mockedCallJiraApi).toHaveBeenCalledTimes(1) }) it('should handle API errors', async () => { // Setup mock error response const mockError = new Error('API error') mockedCallJiraApi.mockResolvedValueOnce(Failure(mockError)) // Call the function const result = await getFieldMetadata(mockProjectKey, mockIssueTypeId, mockConfig) // Assert results expect(result.error).toBe(mockError) expect(result.value).toBeUndefined() }) }) describe('categorizeFields', () => { it('should categorize fields correctly', () => { // Create a sample project metadata const projectMetadata: JiraProjectFieldMetadata = mockFieldMetadataResponse.projects[0] // Call the function const result = categorizeFields(projectMetadata) // Assert results expect(result).toHaveLength(3) // Check summary field is categorized as required const summaryField = result.find((field) => field.id === 'summary') expect(summaryField).toBeDefined() expect(summaryField?.category).toBe(FieldCategory.REQUIRED) // Check description field is categorized as system const descField = result.find((field) => field.id === 'description') expect(descField).toBeDefined() expect(descField?.category).toBe(FieldCategory.SYSTEM) // Check custom field is categorized as custom const customField = result.find((field) => field.id === 'customfield_10001') expect(customField).toBeDefined() expect(customField?.category).toBe(FieldCategory.CUSTOM) }) it('should return empty array for empty issuetypes', () => { // Create a project metadata with no issue types const emptyProjectMetadata: JiraProjectFieldMetadata = { id: '10000', key: 'TEST', name: 'Test Project', issuetypes: [], } // Call the function const result = categorizeFields(emptyProjectMetadata) // Assert results expect(result).toEqual([]) }) }) describe('getAndCategorizeFields', () => { it('should retrieve and categorize fields successfully', async () => { // Setup mock responses mockedCallJiraApi.mockResolvedValueOnce(Success(mockFieldMetadataResponse)) mockedFindTargetProject.mockReturnValueOnce(Success(mockFieldMetadataResponse.projects[0])) // Call the function const result = await getAndCategorizeFields(mockProjectKey, '10000', mockIssueTypeId, mockConfig) // Assert results expect(result.error).toBeUndefined() expect(result.value).toHaveLength(3) // Verify the first field is correctly categorized expect(result.value?.[0]).toHaveProperty('id') expect(result.value?.[0]).toHaveProperty('name') expect(result.value?.[0]).toHaveProperty('metadata') expect(result.value?.[0]).toHaveProperty('category') }) it('should handle API errors', async () => { // Setup mock error response const mockError = new Error('API error') mockedCallJiraApi.mockResolvedValueOnce(Failure(mockError)) // Call the function const result = await getAndCategorizeFields(mockProjectKey, '10000', mockIssueTypeId, mockConfig) // Assert results expect(result.error).toBe(mockError) expect(result.value).toBeUndefined() }) it('should handle empty projects in response', async () => { // Setup mock response with empty projects mockedCallJiraApi.mockResolvedValueOnce(Success({ projects: [] })) // Call the function const result = await getAndCategorizeFields(mockProjectKey, '10000', mockIssueTypeId, mockConfig) // Assert results expect(result.error).toBeUndefined() expect(result.value).toEqual([]) }) it('should handle project not found in response', async () => { // Setup mock responses const differentProjectResponse = { projects: [ { id: '10000', key: 'DIFFERENT', name: 'Different Project', issuetypes: [], }, ], } mockedCallJiraApi.mockResolvedValueOnce(Success(differentProjectResponse)) mockedFindTargetProject.mockReturnValueOnce(Failure(new Error('Project not found'))) // Call the function const result = await getAndCategorizeFields(mockProjectKey, '10000', mockIssueTypeId, mockConfig) // Assert results expect(result.error).toBeDefined() expect(result.error?.message).toBe(`Project ${mockProjectKey} not found`) expect(result.value).toBeUndefined() }) }) })

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/tbreeding/jira-mcp'

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