164 lines
6.6 KiB
Python
164 lines
6.6 KiB
Python
import pytest
|
|
import aiohttp
|
|
from unittest.mock import Mock, patch, AsyncMock
|
|
from exceptions import DatabaseError
|
|
import api_calls
|
|
|
|
|
|
class TestUtilityFunctions:
|
|
"""Test utility functions in api_calls."""
|
|
|
|
def test_param_char_with_params(self):
|
|
"""Test param_char returns & when other_params is truthy."""
|
|
assert api_calls.param_char(True) == '&'
|
|
assert api_calls.param_char(['param1']) == '&'
|
|
assert api_calls.param_char({'key': 'value'}) == '&'
|
|
assert api_calls.param_char('some_param') == '&'
|
|
|
|
def test_param_char_without_params(self):
|
|
"""Test param_char returns ? when other_params is falsy."""
|
|
assert api_calls.param_char(False) == '?'
|
|
assert api_calls.param_char(None) == '?'
|
|
assert api_calls.param_char([]) == '?'
|
|
assert api_calls.param_char({}) == '?'
|
|
assert api_calls.param_char('') == '?'
|
|
assert api_calls.param_char(0) == '?'
|
|
|
|
@patch('api_calls.DB_URL', 'https://test.example.com/api')
|
|
def test_get_req_url_basic(self):
|
|
"""Test basic URL generation without object_id or params."""
|
|
result = api_calls.get_req_url('teams')
|
|
expected = 'https://test.example.com/api/v2/teams'
|
|
assert result == expected
|
|
|
|
@patch('api_calls.DB_URL', 'https://test.example.com/api')
|
|
def test_get_req_url_with_version(self):
|
|
"""Test URL generation with custom API version."""
|
|
result = api_calls.get_req_url('teams', api_ver=1)
|
|
expected = 'https://test.example.com/api/v1/teams'
|
|
assert result == expected
|
|
|
|
@patch('api_calls.DB_URL', 'https://test.example.com/api')
|
|
def test_get_req_url_with_object_id(self):
|
|
"""Test URL generation with object_id."""
|
|
result = api_calls.get_req_url('teams', object_id=123)
|
|
expected = 'https://test.example.com/api/v2/teams/123'
|
|
assert result == expected
|
|
|
|
@patch('api_calls.DB_URL', 'https://test.example.com/api')
|
|
def test_get_req_url_with_params(self):
|
|
"""Test URL generation with parameters."""
|
|
params = [('season', '7'), ('active', 'true')]
|
|
result = api_calls.get_req_url('teams', params=params)
|
|
expected = 'https://test.example.com/api/v2/teams?season=7&active=true'
|
|
assert result == expected
|
|
|
|
@patch('api_calls.DB_URL', 'https://test.example.com/api')
|
|
def test_get_req_url_complete(self):
|
|
"""Test URL generation with all parameters."""
|
|
params = [('season', '7'), ('limit', '10')]
|
|
result = api_calls.get_req_url('games', api_ver=1, object_id=456, params=params)
|
|
expected = 'https://test.example.com/api/v1/games/456?season=7&limit=10'
|
|
assert result == expected
|
|
|
|
@patch('api_calls.logger')
|
|
def test_log_return_value_short_string(self, mock_logger):
|
|
"""Test logging short return values."""
|
|
api_calls.log_return_value('Short log message')
|
|
mock_logger.info.assert_called_once_with('\n\nreturn: Short log message')
|
|
|
|
@patch('api_calls.logger')
|
|
def test_log_return_value_long_string(self, mock_logger):
|
|
"""Test logging long return values that get chunked."""
|
|
long_string = 'A' * 5000 # 5000 character string
|
|
api_calls.log_return_value(long_string)
|
|
|
|
# Should have been called twice (first chunk + second chunk)
|
|
assert mock_logger.info.call_count == 2
|
|
# First call should include the "return:" prefix
|
|
assert '\n\nreturn: ' in mock_logger.info.call_args_list[0][0][0]
|
|
|
|
@patch('api_calls.logger')
|
|
def test_log_return_value_extremely_long_string(self, mock_logger):
|
|
"""Test logging extremely long return values that get snipped."""
|
|
extremely_long_string = 'B' * 400000 # 400k character string (exceeds 300k limit)
|
|
api_calls.log_return_value(extremely_long_string)
|
|
|
|
# Should warn about snipping
|
|
mock_logger.warning.assert_called_with('[ S N I P P E D ]')
|
|
|
|
def test_team_hash(self):
|
|
"""Test team hash generation."""
|
|
mock_team = {
|
|
'sname': 'TestTeam',
|
|
'gmid': 1234567
|
|
}
|
|
|
|
result = api_calls.team_hash(mock_team)
|
|
# Expected format: last char + gmid/6950123 + second-to-last char + gmid/42069123
|
|
expected = f'm{1234567 / 6950123:.0f}a{1234567 / 42069123:.0f}'
|
|
assert result == expected
|
|
|
|
|
|
# Note: Async database function tests are complex due to aiohttp mocking
|
|
# For now, focusing on utility functions which provide significant coverage improvement
|
|
|
|
|
|
class TestSpecificFunctions:
|
|
"""Test specific API wrapper functions."""
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('api_calls.db_get')
|
|
async def test_get_team_by_abbrev_found(self, mock_db_get):
|
|
"""Test get_team_by_abbrev function when team is found."""
|
|
mock_db_get.return_value = {
|
|
'count': 1,
|
|
'teams': [{'id': 123, 'abbrev': 'TEST', 'name': 'Test Team'}]
|
|
}
|
|
|
|
result = await api_calls.get_team_by_abbrev('TEST')
|
|
|
|
assert result == {'id': 123, 'abbrev': 'TEST', 'name': 'Test Team'}
|
|
mock_db_get.assert_called_once_with('teams', params=[('abbrev', 'TEST')])
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('api_calls.db_get')
|
|
async def test_get_team_by_abbrev_not_found(self, mock_db_get):
|
|
"""Test get_team_by_abbrev function when team is not found."""
|
|
mock_db_get.return_value = {
|
|
'count': 0,
|
|
'teams': []
|
|
}
|
|
|
|
result = await api_calls.get_team_by_abbrev('NONEXISTENT')
|
|
|
|
assert result is None
|
|
mock_db_get.assert_called_once_with('teams', params=[('abbrev', 'NONEXISTENT')])
|
|
|
|
@pytest.mark.asyncio
|
|
@patch('api_calls.db_post')
|
|
async def test_post_to_dex(self, mock_db_post):
|
|
"""Test post_to_dex function."""
|
|
mock_db_post.return_value = {'id': 456, 'posted': True}
|
|
|
|
mock_player = {'id': 123}
|
|
mock_team = {'id': 456}
|
|
|
|
result = await api_calls.post_to_dex(mock_player, mock_team)
|
|
|
|
assert result == {'id': 456, 'posted': True}
|
|
mock_db_post.assert_called_once_with('paperdex', payload={'player_id': 123, 'team_id': 456})
|
|
|
|
|
|
class TestEnvironmentConfiguration:
|
|
"""Test environment-based configuration."""
|
|
|
|
def test_db_url_exists(self):
|
|
"""Test that DB_URL is configured."""
|
|
assert api_calls.DB_URL is not None
|
|
assert 'manticorum.com' in api_calls.DB_URL
|
|
|
|
def test_auth_token_exists(self):
|
|
"""Test that AUTH_TOKEN is configured."""
|
|
assert api_calls.AUTH_TOKEN is not None
|
|
assert 'Authorization' in api_calls.AUTH_TOKEN |