Skip to main content
Glama

MCP Spotify Server

artists.test.ts7.64 kB
import { jest } from '@jest/globals'; import { ArtistsHandler } from '../handlers/artists.js'; import { SpotifyApi } from '../utils/api.js'; import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'; import { AuthManager } from '../utils/auth.js'; // Mock the SpotifyApi class jest.mock('../utils/api.js'); describe('ArtistsHandler', () => { let handler: ArtistsHandler; let mockApi: jest.Mocked<SpotifyApi>; beforeEach(() => { // Clear all mocks before each test jest.clearAllMocks(); // Create a mock instance of SpotifyApi mockApi = { makeRequest: jest.fn(), buildQueryString: jest.fn(), } as unknown as jest.Mocked<SpotifyApi>; handler = new ArtistsHandler(mockApi); }); describe('getArtist', () => { it('should fetch an artist by ID', async () => { const mockResponse = { id: '123', name: 'Test Artist' }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getArtist({ id: '123' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123'); expect(result).toEqual(mockResponse); }); it('should handle spotify:artist: prefixed IDs', async () => { const mockResponse = { id: '123', name: 'Test Artist' }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getArtist({ id: 'spotify:artist:123' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123'); expect(result).toEqual(mockResponse); }); }); describe('getMultipleArtists', () => { it('should fetch multiple artists by IDs', async () => { const mockResponse = { artists: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getMultipleArtists({ ids: ['123', '456'] }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists?ids=123,456'); expect(result).toEqual(mockResponse); }); it('should handle spotify:artist: prefixed IDs', async () => { const mockResponse = { artists: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getMultipleArtists({ ids: ['spotify:artist:123', 'spotify:artist:456'] }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists?ids=123,456'); expect(result).toEqual(mockResponse); }); it('should throw error when no IDs provided', async () => { await expect(handler.getMultipleArtists({ ids: [] })).rejects.toThrow( new McpError(ErrorCode.InvalidParams, 'At least one artist ID must be provided') ); }); it('should throw error when too many IDs provided', async () => { const ids = Array(51).fill('123'); await expect(handler.getMultipleArtists({ ids })).rejects.toThrow( new McpError(ErrorCode.InvalidParams, 'Maximum of 50 artist IDs allowed') ); }); }); describe('getArtistTopTracks', () => { it('should fetch artist top tracks with market', async () => { const mockResponse = { tracks: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getArtistTopTracks({ id: '123', market: 'US' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123/top-tracks?market=US'); expect(result).toEqual(mockResponse); }); it('should handle spotify:artist: prefixed IDs', async () => { const mockResponse = { tracks: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getArtistTopTracks({ id: 'spotify:artist:123', market: 'US' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123/top-tracks?market=US'); expect(result).toEqual(mockResponse); }); it('should throw error when market is not provided', async () => { await expect(handler.getArtistTopTracks({ id: '123' })).rejects.toThrow( new McpError(ErrorCode.InvalidParams, 'market parameter is required for top tracks') ); }); }); describe('getArtistRelatedArtists', () => { it('should fetch artist related artists', async () => { const mockResponse = { artists: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getArtistRelatedArtists({ id: '123' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123/related-artists'); expect(result).toEqual(mockResponse); }); it('should handle spotify:artist: prefixed IDs', async () => { const mockResponse = { artists: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); const result = await handler.getArtistRelatedArtists({ id: 'spotify:artist:123' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123/related-artists'); expect(result).toEqual(mockResponse); }); }); describe('getArtistAlbums', () => { it('should fetch artist albums with default parameters', async () => { const mockResponse = { items: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); mockApi.buildQueryString.mockReturnValue('?limit=20&offset=0'); const result = await handler.getArtistAlbums({ id: '123' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123/albums?limit=20&offset=0'); expect(result).toEqual(mockResponse); }); it('should fetch artist albums with custom parameters', async () => { const mockResponse = { items: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); mockApi.buildQueryString.mockReturnValue('?limit=30&offset=20&include_groups=album,single'); const result = await handler.getArtistAlbums({ id: '123', limit: 30, offset: 20, include_groups: ['album', 'single'] }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123/albums?limit=30&offset=20&include_groups=album,single'); expect(result).toEqual(mockResponse); }); it('should handle spotify:artist: prefixed IDs', async () => { const mockResponse = { items: [{ id: '123' }, { id: '456' }] }; mockApi.makeRequest.mockResolvedValue(mockResponse); mockApi.buildQueryString.mockReturnValue('?limit=20&offset=0'); const result = await handler.getArtistAlbums({ id: 'spotify:artist:123' }); expect(mockApi.makeRequest).toHaveBeenCalledWith('/artists/123/albums?limit=20&offset=0'); expect(result).toEqual(mockResponse); }); it('should throw error when limit is less than 1', async () => { await expect(handler.getArtistAlbums({ id: '123', limit: 0 })).rejects.toThrow( new McpError(ErrorCode.InvalidParams, 'Limit must be between 1 and 50') ); }); it('should throw error when limit is greater than 50', async () => { await expect(handler.getArtistAlbums({ id: '123', limit: 51 })).rejects.toThrow( new McpError(ErrorCode.InvalidParams, 'Limit must be between 1 and 50') ); }); it('should throw error when offset is negative', async () => { await expect(handler.getArtistAlbums({ id: '123', offset: -1 })).rejects.toThrow( new McpError(ErrorCode.InvalidParams, 'Offset must be non-negative') ); }); }); });

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/superseoworld/mcp-spotify'

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