Skip to main content
Glama

Discogs MCP Server

by cswkim
userIdentity.test.ts22.3 kB
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; import { FastMCP } from 'fastmcp'; import { describe, expect, it, vi } from 'vitest'; import { formatDiscogsError } from '../../src/errors'; import { OAuthService } from '../../src/services/oauth'; import { UserContributionsService, UserSubmissionsService, } from '../../src/services/user/contribution'; import { UserProfileService } from '../../src/services/user/profile'; import { editUserProfileTool, getUserContributionsTool, getUserIdentityTool, getUserProfileTool, getUserSubmissionsTool, } from '../../src/tools/userIdentity'; import { runWithTestServer } from '../utils/testServer'; describe('User Identity Tools', () => { describe('get_user_identity', () => { it('adds get_user_identity tool', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserIdentityTool); return server; }, run: async ({ client }) => { expect(await client.listTools()).toEqual({ tools: [ { name: 'get_user_identity', description: 'Retrieve basic information about the authenticated user', inputSchema: { additionalProperties: false, $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', properties: {}, }, }, ], }); }, }); }); it('calls get_user_identity tool', async () => { const mockIdentity = { id: 123, username: 'testuser', resource_url: 'https://api.discogs.com/users/testuser', consumer_name: 'Test App', }; await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(OAuthService.prototype, 'getUserIdentity').mockResolvedValue(mockIdentity); server.addTool(getUserIdentityTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_identity', arguments: {}, }), ).toEqual({ content: [{ type: 'text', text: JSON.stringify(mockIdentity) }], }); }, }); }); it('handles get_user_identity DiscogsResourceNotFoundError', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(OAuthService.prototype, 'getUserIdentity').mockRejectedValue( formatDiscogsError('Resource not found'), ); server.addTool(getUserIdentityTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_identity', arguments: {}, }), ).toEqual({ content: [{ type: 'text', text: 'Resource not found' }], isError: true, }); }, }); }); it('handles get_user_identity invalid parameters', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserIdentityTool); return server; }, run: async ({ client }) => { try { await client.callTool({ name: 'get_user_identity', arguments: {}, }); } catch (error) { expect(error).toBeInstanceOf(McpError); expect(error.code).toBe(ErrorCode.InvalidParams); } }, }); }); }); describe('get_user_profile', () => { it('adds get_user_profile tool', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserProfileTool); return server; }, run: async ({ client }) => { expect(await client.listTools()).toEqual({ tools: [ { name: 'get_user_profile', description: 'Retrieve a user by username', inputSchema: { additionalProperties: false, $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', properties: { username: { type: 'string', minLength: 1 }, }, required: ['username'], }, }, ], }); }, }); }); it('calls get_user_profile tool', async () => { const mockProfile = { id: 123, username: 'testuser', name: 'Test User', profile: 'Test profile', location: 'Test Location', resource_url: 'https://api.discogs.com/users/testuser', uri: 'https://www.discogs.com/users/testuser', home_page: '', registered: '2024-01-01T00:00:00Z', rank: 1, num_pending: 0, num_for_sale: 0, num_lists: 0, releases_contributed: 0, releases_rated: 0, rating_avg: 0, inventory_url: 'https://api.discogs.com/users/testuser/inventory', collection_folders_url: 'https://api.discogs.com/users/testuser/collection/folders', collection_fields_url: 'https://api.discogs.com/users/testuser/collection/fields', wantlist_url: 'https://api.discogs.com/users/testuser/wants', avatar_url: 'https://example.com/avatar.jpg', curr_abbr: 'USD', activated: true, marketplace_suspended: false, banner_url: 'https://example.com/banner.jpg', buyer_rating: 0, buyer_rating_stars: 0, buyer_num_ratings: 0, seller_rating: 0, seller_rating_stars: 0, seller_num_ratings: 0, is_staff: false, }; await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserProfileService.prototype, 'get').mockResolvedValue(mockProfile); server.addTool(getUserProfileTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_profile', arguments: { username: 'testuser', }, }), ).toEqual({ content: [{ type: 'text', text: JSON.stringify(mockProfile) }], }); }, }); }); it('handles get_user_profile DiscogsResourceNotFoundError', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserProfileService.prototype, 'get').mockRejectedValue( formatDiscogsError('Resource not found'), ); server.addTool(getUserProfileTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_profile', arguments: { username: 'testuser', }, }), ).toEqual({ content: [{ type: 'text', text: 'Resource not found' }], isError: true, }); }, }); }); it('handles get_user_profile invalid parameters', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserProfileTool); return server; }, run: async ({ client }) => { try { await client.callTool({ name: 'get_user_profile', arguments: {}, }); } catch (error) { expect(error).toBeInstanceOf(McpError); expect(error.code).toBe(ErrorCode.InvalidParams); } }, }); }); }); describe('edit_user_profile', () => { it('adds edit_user_profile tool', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(editUserProfileTool); return server; }, run: async ({ client }) => { expect(await client.listTools()).toEqual({ tools: [ { name: 'edit_user_profile', description: "Edit a user's profile data", inputSchema: { additionalProperties: false, $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', properties: { username: { type: 'string', minLength: 1 }, name: { type: 'string' }, profile: { type: 'string' }, location: { type: 'string' }, home_page: { type: 'string' }, curr_abbr: { type: 'string', enum: [ 'USD', 'GBP', 'EUR', 'CAD', 'AUD', 'JPY', 'CHF', 'MXN', 'BRL', 'NZD', 'SEK', 'ZAR', ], }, }, required: ['username'], }, }, ], }); }, }); }); it('calls edit_user_profile tool', async () => { const mockUpdatedProfile = { id: 123, username: 'testuser', name: 'Updated Name', profile: 'Updated profile', location: 'Updated Location', resource_url: 'https://api.discogs.com/users/testuser', uri: 'https://www.discogs.com/users/testuser', home_page: '', registered: '2024-01-01T00:00:00Z', rank: 1, num_pending: 0, num_for_sale: 0, num_lists: 0, releases_contributed: 0, releases_rated: 0, rating_avg: 0, inventory_url: 'https://api.discogs.com/users/testuser/inventory', collection_folders_url: 'https://api.discogs.com/users/testuser/collection/folders', collection_fields_url: 'https://api.discogs.com/users/testuser/collection/fields', wantlist_url: 'https://api.discogs.com/users/testuser/wants', avatar_url: 'https://example.com/avatar.jpg', curr_abbr: 'USD', activated: true, marketplace_suspended: false, banner_url: 'https://example.com/banner.jpg', buyer_rating: 0, buyer_rating_stars: 0, buyer_num_ratings: 0, seller_rating: 0, seller_rating_stars: 0, seller_num_ratings: 0, is_staff: false, }; await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserProfileService.prototype, 'edit').mockResolvedValue(mockUpdatedProfile); server.addTool(editUserProfileTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'edit_user_profile', arguments: { username: 'testuser', name: 'Updated Name', profile: 'Updated profile', location: 'Updated Location', }, }), ).toEqual({ content: [{ type: 'text', text: JSON.stringify(mockUpdatedProfile) }], }); }, }); }); it('handles edit_user_profile DiscogsResourceNotFoundError', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserProfileService.prototype, 'edit').mockRejectedValue( formatDiscogsError('Resource not found'), ); server.addTool(editUserProfileTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'edit_user_profile', arguments: { username: 'testuser', name: 'Updated Name', profile: 'Updated profile', location: 'Updated Location', }, }), ).toEqual({ content: [{ type: 'text', text: 'Resource not found' }], isError: true, }); }, }); }); it('handles edit_user_profile invalid parameters', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(editUserProfileTool); return server; }, run: async ({ client }) => { try { await client.callTool({ name: 'edit_user_profile', arguments: {}, }); } catch (error) { expect(error).toBeInstanceOf(McpError); expect(error.code).toBe(ErrorCode.InvalidParams); } }, }); }); }); describe('get_user_submissions', () => { it('adds get_user_submissions tool', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserSubmissionsTool); return server; }, run: async ({ client }) => { expect(await client.listTools()).toEqual({ tools: [ { name: 'get_user_submissions', description: `Retrieve a user's submissions by username`, inputSchema: { additionalProperties: false, $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', properties: { username: { type: 'string', minLength: 1 }, }, required: ['username'], }, }, ], }); }, }); }); it('calls get_user_submissions tool', async () => { const mockSubmissions = { pagination: { page: 1, per_page: 50, pages: 1, items: 1, urls: {}, }, submissions: { artists: [], labels: [], releases: [], }, }; await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserSubmissionsService.prototype, 'get').mockResolvedValue(mockSubmissions); server.addTool(getUserSubmissionsTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_submissions', arguments: { username: 'testuser', }, }), ).toEqual({ content: [{ type: 'text', text: JSON.stringify(mockSubmissions) }], }); }, }); }); it('handles get_user_submissions DiscogsResourceNotFoundError', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserSubmissionsService.prototype, 'get').mockRejectedValue( formatDiscogsError('Resource not found'), ); server.addTool(getUserSubmissionsTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_submissions', arguments: { username: 'testuser', }, }), ).toEqual({ content: [{ type: 'text', text: 'Resource not found' }], isError: true, }); }, }); }); it('handles get_user_submissions invalid parameters', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserSubmissionsTool); return server; }, run: async ({ client }) => { try { await client.callTool({ name: 'get_user_submissions', arguments: {}, }); } catch (error) { expect(error).toBeInstanceOf(McpError); expect(error.code).toBe(ErrorCode.InvalidParams); } }, }); }); }); describe('get_user_contributions', () => { it('adds get_user_contributions tool', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserContributionsTool); return server; }, run: async ({ client }) => { expect(await client.listTools()).toEqual({ tools: [ { name: 'get_user_contributions', description: `Retrieve a user's contributions by username`, inputSchema: { additionalProperties: false, $schema: 'https://json-schema.org/draft/2020-12/schema', type: 'object', properties: { username: { type: 'string', minLength: 1 }, page: { type: 'integer', minimum: 1, maximum: 9007199254740991 }, per_page: { type: 'integer', minimum: 1, maximum: 100 }, sort: { type: 'string', enum: [ 'label', 'artist', 'title', 'catno', 'format', 'rating', 'year', 'added', ], }, sort_order: { type: 'string', enum: ['asc', 'desc'] }, }, required: ['username'], }, }, ], }); }, }); }); it('calls get_user_contributions tool', async () => { const mockContributions = { pagination: { page: 1, per_page: 50, pages: 1, items: 1, urls: {}, }, contributions: [], }; await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserContributionsService.prototype, 'get').mockResolvedValue(mockContributions); server.addTool(getUserContributionsTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_contributions', arguments: { username: 'testuser', }, }), ).toEqual({ content: [{ type: 'text', text: JSON.stringify(mockContributions) }], }); }, }); }); it('handles get_user_contributions DiscogsResourceNotFoundError', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); vi.spyOn(UserContributionsService.prototype, 'get').mockRejectedValue( formatDiscogsError('Resource not found'), ); server.addTool(getUserContributionsTool); return server; }, run: async ({ client }) => { expect( await client.callTool({ name: 'get_user_contributions', arguments: { username: 'testuser', }, }), ).toEqual({ content: [{ type: 'text', text: 'Resource not found' }], isError: true, }); }, }); }); it('handles get_user_contributions invalid parameters', async () => { await runWithTestServer({ server: async () => { const server = new FastMCP({ name: 'Test', version: '1.0.0', }); server.addTool(getUserContributionsTool); return server; }, run: async ({ client }) => { try { await client.callTool({ name: 'get_user_contributions', arguments: {}, }); } catch (error) { expect(error).toBeInstanceOf(McpError); expect(error.code).toBe(ErrorCode.InvalidParams); } }, }); }); }); });

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/cswkim/discogs-mcp-server'

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