Skip to main content
Glama

Spotify Playlist MCP Server

by kylestratis
test_utils.py7.28 kB
"""Tests for spotify_mcp/utils.py""" import pytest from spotify_mcp.utils import ( CHARACTER_LIMIT, check_character_limit, format_track_markdown, format_truncation_message, truncate_list_response, ) class TestFormatTrackMarkdown: """Tests for format_track_markdown function.""" def test_basic_track_formatting(self, sample_track): """Test basic track formatting with all fields present.""" result = format_track_markdown(sample_track) assert "**Bohemian Rhapsody**" in result assert "Artists: Queen" in result assert "Album: Bohemian Rhapsody (The Original Soundtrack)" in result assert "Duration: 5:54" in result assert "Spotify ID: `4u7EnebtmKWzUH433cf5Qv`" in result assert "URI: `spotify:track:4u7EnebtmKWzUH433cf5Qv`" in result assert "Popularity: 87/100" in result def test_track_with_multiple_artists(self): """Test formatting track with multiple artists.""" track = { "id": "test_id", "name": "Test Song", "artists": [{"name": "Artist 1"}, {"name": "Artist 2"}], "album": {"name": "Test Album"}, "duration_ms": 180000, "uri": "spotify:track:test_id", } result = format_track_markdown(track) assert "Artists: Artist 1, Artist 2" in result def test_track_with_no_popularity(self): """Test track formatting when popularity field is missing.""" track = { "id": "test_id", "name": "Test Song", "artists": [{"name": "Test Artist"}], "album": {"name": "Test Album"}, "duration_ms": 120000, "uri": "spotify:track:test_id", } result = format_track_markdown(track) assert "Popularity:" not in result def test_track_with_zero_duration(self): """Test track formatting with zero duration.""" track = { "id": "test_id", "name": "Test Song", "artists": [{"name": "Test Artist"}], "album": {"name": "Test Album"}, "duration_ms": 0, "uri": "spotify:track:test_id", } result = format_track_markdown(track) assert "Duration: 0:00" in result def test_duration_formatting(self): """Test various duration formats.""" test_cases = [ (59000, "0:59"), # Under 1 minute (60000, "1:00"), # Exactly 1 minute (125000, "2:05"), # 2 minutes 5 seconds (600000, "10:00"), # Exactly 10 minutes ] for duration_ms, expected in test_cases: track = { "id": "test", "name": "Test", "artists": [{"name": "Test"}], "album": {"name": "Test"}, "duration_ms": duration_ms, "uri": "spotify:track:test", } result = format_track_markdown(track) assert f"Duration: {expected}" in result class TestCheckCharacterLimit: """Tests for check_character_limit function (deprecated).""" def test_under_limit(self): """Test content under character limit.""" content = "Short content" data_list = [1, 2, 3] result = check_character_limit(content, data_list) assert result == "" def test_over_limit(self): """Test content over character limit.""" content = "x" * (CHARACTER_LIMIT + 1000) data_list = list(range(100)) result = check_character_limit(content, data_list) assert "Response truncated" in result assert "50 items" in result class TestTruncateListResponse: """Tests for truncate_list_response function.""" def test_no_truncation_needed(self): """Test when content is under limit.""" items = [{"id": i, "value": f"item_{i}"} for i in range(10)] def format_func(items_list): return "\n".join([f"{item['id']}: {item['value']}" for item in items_list]) truncated, was_truncated = truncate_list_response(items, format_func) assert was_truncated is False assert truncated == items def test_truncation_needed(self): """Test when content exceeds limit.""" # Create items that will exceed CHARACTER_LIMIT items = [{"id": i, "value": "x" * 1000} for i in range(100)] def format_func(items_list): return "\n".join( [f"{item['id']}: {item['value']}" for item in items_list] ) truncated, was_truncated = truncate_list_response(items, format_func) assert was_truncated is True assert len(truncated) < len(items) # Verify the truncated result is under limit assert len(format_func(truncated)) <= CHARACTER_LIMIT def test_empty_list(self): """Test with empty list.""" def format_func(items_list): return str(items_list) truncated, was_truncated = truncate_list_response([], format_func) assert was_truncated is False assert truncated == [] def test_single_item_over_limit(self): """Test when even single item exceeds limit.""" items = [{"value": "x" * (CHARACTER_LIMIT + 1000)}] def format_func(items_list): return items_list[0]["value"] if items_list else "" truncated, was_truncated = truncate_list_response(items, format_func) # Should return at least one item, but mark as truncated since it exceeds limit assert len(truncated) == 1 # Note: Even though we return 1 item, it's still marked as truncated # because the formatted output exceeds the character limit def test_custom_max_chars(self): """Test with custom character limit.""" items = [{"id": i, "value": "x" * 100} for i in range(20)] def format_func(items_list): return "\n".join([f"{item['value']}" for item in items_list]) truncated, was_truncated = truncate_list_response( items, format_func, max_chars=500 ) if was_truncated: assert len(format_func(truncated)) <= 500 class TestFormatTruncationMessage: """Tests for format_truncation_message function.""" def test_basic_message(self): """Test basic truncation message.""" result = format_truncation_message(100, 50) assert "truncated from 100 to 50 items" in result assert f"{CHARACTER_LIMIT:,} character limit" in result assert "offset" in result assert "limit" in result def test_custom_response_type(self): """Test with custom response type.""" result = format_truncation_message(200, 100, "tracks") assert "truncated from 200 to 100 tracks" in result def test_different_counts(self): """Test with various count combinations.""" test_cases = [ (1000, 500, "items"), (50, 25, "playlists"), (10, 5, "results"), ] for original, truncated, response_type in test_cases: result = format_truncation_message(original, truncated, response_type) assert f"from {original} to {truncated} {response_type}" in result

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

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