@@ -42,17 +42,26 @@ def test_generate_prompt_text_files(ai_service, mock_git_file):
4242
4343def test_generate_prompt_binary_files (ai_service , mock_git_file ):
4444 """Test prompt generation for binary files."""
45- files = [mock_git_file ("image.png" , size = 1024 )]
46- diff = "Binary files changed"
45+ files = [mock_git_file ("image.png" , size = 1024 , hash_ = "abc123" )]
46+ prompt = ai_service .generate_prompt ("" , files )
47+ assert "image.png" in prompt
48+ assert "binary file changes" in prompt
4749
48- prompt = ai_service .generate_prompt (diff , files )
4950
51+ def test_generate_prompt_mixed_files (ai_service , mock_git_file ):
52+ """Prompt should mention both binary and text changes."""
53+ files = [
54+ mock_git_file ("image.png" , size = 1024 , hash_ = "abc123" ),
55+ mock_git_file ("test.py" ),
56+ ]
57+ diff = "diff content"
58+ prompt = ai_service .generate_prompt (diff , files )
5059 assert "image.png" in prompt
51- assert "Binary files changed" in prompt
60+ assert "test.py" in prompt
61+ assert "Binary files" in prompt
5262
5363
54- @patch ("requests.post" )
55- def test_generate_commit_message_success (mock_post , ai_service , mock_git_file ):
64+ def test_generate_commit_message_success (ai_service , mock_git_file ):
5665 """Test successful commit message generation."""
5766 mock_response = {
5867 "choices" : [
@@ -76,7 +85,7 @@ def test_generate_commit_message_success(mock_post, ai_service, mock_git_file):
7685 "usage" : {"prompt_tokens" : 100 , "completion_tokens" : 50 , "total_tokens" : 150 },
7786 }
7887
79- mock_post . return_value = MagicMock (status_code = 200 , json = lambda : mock_response )
88+ ai_service . session . post = MagicMock (return_value = MagicMock ( status_code = 200 , json = lambda : mock_response ) )
8089
8190 suggestion , usage = ai_service .generate_commit_message ("test diff" , [mock_git_file ("test.py" )])
8291
@@ -85,11 +94,10 @@ def test_generate_commit_message_success(mock_post, ai_service, mock_git_file):
8594 assert usage .total_tokens == 150
8695
8796
88- @patch ("requests.post" )
89- def test_generate_commit_message_api_error (mock_post , ai_service , mock_git_file ):
97+ def test_generate_commit_message_api_error (ai_service , mock_git_file ):
9098 """Test handling of API errors."""
91- mock_post . return_value = MagicMock (
92- status_code = 400 , json = lambda : {"error" : {"message" : "API Error" }}
99+ ai_service . session . post = MagicMock (
100+ return_value = MagicMock ( status_code = 400 , json = lambda : {"error" : {"message" : "API Error" }})
93101 )
94102
95103 with pytest .raises (ValueError ) as exc_info :
@@ -98,33 +106,61 @@ def test_generate_commit_message_api_error(mock_post, ai_service, mock_git_file)
98106 assert "API Error" in str (exc_info .value )
99107
100108
101- @patch ("requests.post" )
102- def test_generate_commit_message_invalid_json (mock_post , ai_service , mock_git_file ):
109+ def test_generate_commit_message_invalid_json (ai_service , mock_git_file ):
103110 """Test handling of invalid JSON response."""
104111 mock_response = {
105112 "choices" : [{"message" : {"content" : "Invalid JSON" }}],
106113 "usage" : {"prompt_tokens" : 100 , "completion_tokens" : 50 , "total_tokens" : 150 },
107114 }
108115
109- mock_post . return_value = MagicMock (status_code = 200 , json = lambda : mock_response )
116+ ai_service . session . post = MagicMock (return_value = MagicMock ( status_code = 200 , json = lambda : mock_response ) )
110117
111118 with pytest .raises (ValueError ) as exc_info :
112119 ai_service .generate_commit_message ("test diff" , [mock_git_file ("test.py" )])
113120
114121 assert "Failed to parse AI response" in str (exc_info .value )
115122
116123
117- @patch ("requests.post" )
118- def test_generate_commit_message_network_error (mock_post , ai_service , mock_git_file ):
124+ def test_generate_commit_message_network_error (ai_service , mock_git_file ):
119125 """Test handling of network errors."""
120- mock_post . side_effect = requests .exceptions .RequestException ("Network Error" )
126+ ai_service . session . post = MagicMock ( side_effect = requests .exceptions .RequestException ("Network Error" ) )
121127
122128 with pytest .raises (ValueError ) as exc_info :
123129 ai_service .generate_commit_message ("test diff" , [mock_git_file ("test.py" )])
124130
125131 assert "Network Error" in str (exc_info .value )
126132
127133
134+ @patch ("time.sleep" , return_value = None )
135+ def test_generate_commit_message_retries (mock_sleep , ai_service , mock_git_file ):
136+ """Temporary failures should be retried."""
137+ mock_response = {
138+ "choices" : [
139+ {
140+ "message" : {
141+ "content" : json .dumps (
142+ {
143+ "title" : "✨ feat: retry success" ,
144+ "body" : {"Features" : {"emoji" : "✨" , "changes" : ["Added new functionality" ]}},
145+ "summary" : "Added new feature" ,
146+ }
147+ )
148+ }
149+ }
150+ ],
151+ "usage" : {"prompt_tokens" : 1 , "completion_tokens" : 1 , "total_tokens" : 2 },
152+ }
153+ ai_service .session .post = MagicMock (
154+ side_effect = [
155+ requests .exceptions .RequestException ("temp" ),
156+ MagicMock (status_code = 200 , json = lambda : mock_response ),
157+ ]
158+ )
159+ suggestion , _ = ai_service .generate_commit_message ("diff" , [mock_git_file ("test.py" )])
160+ assert suggestion .title == "✨ feat: retry success"
161+ assert ai_service .session .post .call_count == 2
162+
163+
128164def test_format_commit_message ():
129165 """Test commit message formatting."""
130166 suggestion = CommitSuggestion (
0 commit comments