import unittest from unittest.mock import Mock, patch import requests from fjerkroa_bot.igdblib import IGDBQuery class TestIGDBQuery(unittest.TestCase): def setUp(self): self.client_id = "test_client_id" self.api_key = "test_api_key" self.igdb = IGDBQuery(self.client_id, self.api_key) def test_init(self): """Test IGDBQuery initialization.""" self.assertEqual(self.igdb.client_id, self.client_id) self.assertEqual(self.igdb.igdb_api_key, self.api_key) @patch("fjerkroa_bot.igdblib.requests.post") def test_send_igdb_request_success(self, mock_post): """Test successful IGDB API request.""" mock_response = Mock() mock_response.json.return_value = {"id": 1, "name": "Test Game"} mock_response.raise_for_status.return_value = None mock_post.return_value = mock_response result = self.igdb.send_igdb_request("games", "fields name; limit 1;") self.assertEqual(result, {"id": 1, "name": "Test Game"}) mock_post.assert_called_once_with( "https://api.igdb.com/v4/games", headers={"Client-ID": self.client_id, "Authorization": f"Bearer {self.api_key}"}, data="fields name; limit 1;", ) @patch("fjerkroa_bot.igdblib.requests.post") def test_send_igdb_request_failure(self, mock_post): """Test IGDB API request failure.""" mock_post.side_effect = requests.RequestException("API Error") result = self.igdb.send_igdb_request("games", "fields name; limit 1;") self.assertIsNone(result) def test_build_query_basic(self): """Test building basic query.""" query = IGDBQuery.build_query(["name", "summary"]) expected = "fields name,summary; limit 10;" self.assertEqual(query, expected) def test_build_query_with_limit(self): """Test building query with custom limit.""" query = IGDBQuery.build_query(["name"], limit=5) expected = "fields name; limit 5;" self.assertEqual(query, expected) def test_build_query_with_offset(self): """Test building query with offset.""" query = IGDBQuery.build_query(["name"], offset=10) expected = "fields name; limit 10; offset 10;" self.assertEqual(query, expected) def test_build_query_with_filters(self): """Test building query with filters.""" filters = {"name": "Mario", "platform": "Nintendo"} query = IGDBQuery.build_query(["name"], filters=filters) expected = "fields name; limit 10; where name Mario & platform Nintendo;" self.assertEqual(query, expected) def test_build_query_empty_fields(self): """Test building query with empty fields.""" query = IGDBQuery.build_query([]) expected = "fields *; limit 10;" self.assertEqual(query, expected) def test_build_query_none_fields(self): """Test building query with None fields.""" query = IGDBQuery.build_query(None) expected = "fields *; limit 10;" self.assertEqual(query, expected) @patch.object(IGDBQuery, "send_igdb_request") def test_generalized_igdb_query(self, mock_send): """Test generalized IGDB query method.""" mock_send.return_value = [{"id": 1, "name": "Test Game"}] params = {"name": "Mario"} result = self.igdb.generalized_igdb_query(params, "games", ["name"], limit=5) expected_filters = {"name": '~ "Mario"*'} expected_query = 'fields name; limit 5; where name ~ "Mario"*;' mock_send.assert_called_once_with("games", expected_query) self.assertEqual(result, [{"id": 1, "name": "Test Game"}]) @patch.object(IGDBQuery, "send_igdb_request") def test_generalized_igdb_query_with_additional_filters(self, mock_send): """Test generalized query with additional filters.""" mock_send.return_value = [{"id": 1, "name": "Test Game"}] params = {"name": "Mario"} additional_filters = {"platform": "= 1"} result = self.igdb.generalized_igdb_query(params, "games", ["name"], additional_filters, limit=5) expected_query = 'fields name; limit 5; where name ~ "Mario"* & platform = 1;' mock_send.assert_called_once_with("games", expected_query) def test_create_query_function(self): """Test creating a query function.""" func_def = self.igdb.create_query_function( "test_func", "Test function", {"name": {"type": "string"}}, "games", ["name"], limit=5 ) self.assertEqual(func_def["name"], "test_func") self.assertEqual(func_def["description"], "Test function") self.assertEqual(func_def["parameters"]["type"], "object") self.assertIn("function", func_def) @patch.object(IGDBQuery, "generalized_igdb_query") def test_platform_families(self, mock_query): """Test platform families caching.""" mock_query.return_value = [ {"id": 1, "name": "PlayStation"}, {"id": 2, "name": "Nintendo"} ] # First call result1 = self.igdb.platform_families() expected = {1: "PlayStation", 2: "Nintendo"} self.assertEqual(result1, expected) # Second call should use cache result2 = self.igdb.platform_families() self.assertEqual(result2, expected) # Should only call the API once due to caching mock_query.assert_called_once_with({}, "platform_families", ["id", "name"], limit=500) @patch.object(IGDBQuery, "generalized_igdb_query") @patch.object(IGDBQuery, "platform_families") def test_platforms(self, mock_families, mock_query): """Test platforms method.""" mock_families.return_value = {1: "PlayStation"} mock_query.return_value = [ { "id": 1, "name": "PlayStation 5", "alternative_name": "PS5", "abbreviation": "PS5", "platform_family": 1 }, { "id": 2, "name": "Nintendo Switch" } ] result = self.igdb.platforms() expected = { 1: {"names": ["PlayStation 5", "PS5", "PS5"], "family": "PlayStation"}, 2: {"names": ["Nintendo Switch"], "family": None} } mock_query.assert_called_once_with( {}, "platforms", ["id", "name", "alternative_name", "abbreviation", "platform_family"], limit=500 ) @patch.object(IGDBQuery, "generalized_igdb_query") def test_game_info(self, mock_query): """Test game info method.""" mock_query.return_value = [{"id": 1, "name": "Super Mario Bros"}] result = self.igdb.game_info("Mario") expected_fields = [ "id", "name", "alternative_names", "category", "release_dates", "franchise", "language_supports", "keywords", "platforms", "rating", "summary" ] mock_query.assert_called_once_with( {"name": "Mario"}, expected_fields, limit=100 ) self.assertEqual(result, [{"id": 1, "name": "Super Mario Bros"}]) if __name__ == "__main__": unittest.main()