Skip to main content
Glama
test_get_ad_creatives_fix.py6.26 kB
"""Regression tests for get_ad_creatives function bug fix. Tests for issue where get_ad_creatives would throw: 'TypeError: 'dict' object is not callable' This was caused by trying to call ad_creative_images(creative) where ad_creative_images is a dictionary, not a function. The fix was to create extract_creative_image_urls() function and use that instead. """ import pytest import json from unittest.mock import AsyncMock, patch from meta_ads_mcp.core.ads import get_ad_creatives from meta_ads_mcp.core.utils import ad_creative_images @pytest.mark.asyncio class TestGetAdCreativesBugFix: """Regression test cases for the get_ad_creatives function bug fix.""" async def test_get_ad_creatives_regression_fix(self): """Regression test: ensure get_ad_creatives works correctly and doesn't throw 'dict' object is not callable.""" # Mock the make_api_request to return sample creative data sample_creative_data = { "data": [ { "id": "123456789", "name": "Test Creative", "status": "ACTIVE", "thumbnail_url": "https://example.com/thumb.jpg", "image_url": "https://example.com/image.jpg", "image_hash": "abc123", "object_story_spec": { "page_id": "987654321", "link_data": { "image_hash": "abc123", "link": "https://example.com", "name": "Test Ad" } } } ] } with patch('meta_ads_mcp.core.ads.make_api_request', new_callable=AsyncMock) as mock_api: mock_api.return_value = sample_creative_data # This should NOT raise a TypeError anymore # Previously this would fail with: TypeError: 'dict' object is not callable result = await get_ad_creatives(access_token="test_token", ad_id="120228922933270272") # Parse the result result_data = json.loads(result) # Verify the structure is correct assert "data" in result_data assert len(result_data["data"]) == 1 creative = result_data["data"][0] assert creative["id"] == "123456789" assert creative["name"] == "Test Creative" assert "image_urls_for_viewing" in creative assert isinstance(creative["image_urls_for_viewing"], list) async def test_extract_creative_image_urls_function(self): """Test the extract_creative_image_urls function works correctly.""" from meta_ads_mcp.core.utils import extract_creative_image_urls # Test creative with various image URL fields test_creative = { "id": "123456789", "name": "Test Creative", "status": "ACTIVE", "thumbnail_url": "https://example.com/thumb.jpg", "image_url": "https://example.com/image.jpg", "image_hash": "abc123", "object_story_spec": { "page_id": "987654321", "link_data": { "image_hash": "abc123", "link": "https://example.com", "name": "Test Ad", "picture": "https://example.com/picture.jpg" } } } urls = extract_creative_image_urls(test_creative) # Should extract URLs in order: image_url, picture, thumbnail_url (new priority order) expected_urls = [ "https://example.com/image.jpg", "https://example.com/picture.jpg", "https://example.com/thumb.jpg" ] assert urls == expected_urls # Test with empty creative empty_urls = extract_creative_image_urls({}) assert empty_urls == [] # Test with duplicates (should remove them) duplicate_creative = { "image_url": "https://example.com/same.jpg", "thumbnail_url": "https://example.com/same.jpg", # Same URL } unique_urls = extract_creative_image_urls(duplicate_creative) assert unique_urls == ["https://example.com/same.jpg"] async def test_get_ad_creatives_no_ad_id(self): """Test get_ad_creatives with no ad_id provided.""" result = await get_ad_creatives(access_token="test_token", ad_id=None) result_data = json.loads(result) # The @meta_api_tool decorator wraps the result in a data field assert "data" in result_data error_data = json.loads(result_data["data"]) assert "error" in error_data assert error_data["error"] == "No ad ID provided" async def test_get_ad_creatives_empty_data(self): """Test get_ad_creatives when API returns empty data.""" empty_data = {"data": []} with patch('meta_ads_mcp.core.ads.make_api_request', new_callable=AsyncMock) as mock_api: mock_api.return_value = empty_data result = await get_ad_creatives(access_token="test_token", ad_id="120228922933270272") result_data = json.loads(result) assert "data" in result_data assert len(result_data["data"]) == 0 def test_ad_creative_images_is_dict(): """Test that ad_creative_images is a dictionary, not a function. This confirms the original issue: ad_creative_images is a dict for storing image data, but was being called as a function ad_creative_images(creative), which would fail. This test ensures we don't accidentally change ad_creative_images to a function and break its intended purpose as a storage dictionary. """ assert isinstance(ad_creative_images, dict) # This would raise TypeError: 'dict' object is not callable # This is the original bug - trying to call a dict as a function with pytest.raises(TypeError, match="'dict' object is not callable"): ad_creative_images({"test": "data"})

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/pipeboard-co/meta-ads-mcp'

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