Skip to content

Commit 58d8427

Browse files
committed
Enhance API response handling and update datetime formatting
- Improved the GitHub API client to handle empty response content more robustly by checking for whitespace. - Updated the `format_datetime` function to accept both datetime objects and strings, allowing for more flexible input handling. - Refactored test cases to run synchronously, ensuring compatibility with the updated testing framework.
1 parent a2d2cb2 commit 58d8427

File tree

4 files changed

+21
-12
lines changed

4 files changed

+21
-12
lines changed

github_stats_analyzer/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ async def github_request(self, method: str, endpoint: str, **kwargs) -> Tuple[in
110110

111111
# Return response
112112
if response.status_code < 400:
113-
return response.status_code, response.json() if response.content else None
113+
return response.status_code, response.json() if response.content and response.content.strip() else None
114114
else:
115115
logger.warning(f"GitHub API error: {response.status_code} - {response.text}")
116116
return response.status_code, None

github_stats_analyzer/utils.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ def should_exclude_repo(repo_name: str, languages: Dict[str, int], excluded_lang
5353

5454
return False
5555

56-
def format_datetime(dt: Optional[datetime], output_format: str = "%Y-%m-%d") -> str:
57-
"""Format a datetime object to a string.
56+
def format_datetime(dt: Optional[datetime | str], output_format: str = "%Y-%m-%d") -> str:
57+
"""Format a datetime object or string to a string.
5858
5959
Args:
60-
dt: Datetime object to format
60+
dt: Datetime object or string to format
6161
output_format: Output format string
6262
6363
Returns:
@@ -67,6 +67,11 @@ def format_datetime(dt: Optional[datetime], output_format: str = "%Y-%m-%d") ->
6767
return "Unknown"
6868

6969
try:
70+
# If dt is already a string, return it directly
71+
if isinstance(dt, str):
72+
return dt
73+
74+
# If dt is a datetime object, format it
7075
return dt.strftime(output_format)
7176
except Exception as e:
7277
logger.warning(f"Could not format date: {e}")

tests/run_all_tests.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ def run_unit_tests():
2929
suite = unittest.TestSuite()
3030

3131
# 添加测试用例
32-
suite.addTest(unittest.makeSuite(TestGitHubStatsAnalyzer))
33-
suite.addTest(unittest.makeSuite(TestGitHubAPIClient))
32+
loader = unittest.TestLoader()
33+
suite.addTest(loader.loadTestsFromTestCase(TestGitHubStatsAnalyzer))
34+
suite.addTest(loader.loadTestsFromTestCase(TestGitHubAPIClient))
3435

3536
# 运行测试
3637
runner = unittest.TextTestRunner(verbosity=2)

tests/test_analyzer.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def test_init_with_params(self, mock_api_client):
6161
@patch('github_stats_analyzer.analyzer.GitHubStatsAnalyzer.fetch_user_repos')
6262
@patch('github_stats_analyzer.analyzer.GitHubStatsAnalyzer.process_repos')
6363
@patch('github_stats_analyzer.analyzer.GitHubStatsAnalyzer.calculate_language_percentages')
64-
async def test_analyze(self, mock_calc, mock_process, mock_fetch):
64+
def test_analyze(self, mock_calc, mock_process, mock_fetch):
6565
"""测试分析方法"""
6666
# 创建模拟仓库列表
6767
mock_repos = [
@@ -85,8 +85,9 @@ async def test_analyze(self, mock_calc, mock_process, mock_fetch):
8585
excluded_languages=self.excluded_languages
8686
)
8787

88-
# 调用分析方法
89-
await analyzer.analyze()
88+
# 创建事件循环并运行异步方法
89+
loop = asyncio.get_event_loop()
90+
loop.run_until_complete(analyzer.analyze())
9091

9192
# 验证方法调用
9293
mock_fetch.assert_called_once()
@@ -196,11 +197,12 @@ def test_init(self, mock_client):
196197
self.assertIsNotNone(client.client)
197198

198199
@patch('httpx.AsyncClient.get')
199-
async def test_get_user_repos_basic(self, mock_get):
200+
def test_get_user_repos_basic(self, mock_get):
200201
"""测试获取用户仓库 (基本访问级别)"""
201202
# 创建模拟响应
202203
mock_response = MagicMock()
203204
mock_response.status_code = 200
205+
mock_response.content = b'{"some": "content"}'
204206
mock_response.json.return_value = [
205207
{
206208
"name": "repo1",
@@ -217,8 +219,9 @@ async def test_get_user_repos_basic(self, mock_get):
217219
# 创建客户端实例
218220
client = GitHubAPIClient(AccessLevel.BASIC)
219221

220-
# 调用方法
221-
repos = await client.get_user_repos("test-user")
222+
# 创建事件循环并运行异步方法
223+
loop = asyncio.get_event_loop()
224+
repos = loop.run_until_complete(client.get_user_repos("test-user"))
222225

223226
# 验证结果
224227
self.assertEqual(len(repos), 1)

0 commit comments

Comments
 (0)