@@ -69,6 +69,44 @@ def test_credits_remaining_property(self):
6969 response .credits_used = 50
7070 self .assertEqual (response .credits_remaining , 0 ) # 50 - 50
7171
72+ def test_is_exhausted_property (self ):
73+ """Test credit exhaustion detection."""
74+ response = CreditTrackingResponse .from_api_response (self .sample_api_data )
75+
76+ # Not exhausted with 43 remaining
77+ self .assertFalse (response .is_exhausted )
78+
79+ # Exhausted at exactly 0 remaining
80+ response .credits_used = 50
81+ self .assertTrue (response .is_exhausted )
82+
83+ # Exhausted when over limit
84+ response .credits_used = 55
85+ self .assertTrue (response .is_exhausted )
86+
87+ def test_is_low_property (self ):
88+ """Test low credit detection."""
89+ response = CreditTrackingResponse .from_api_response (self .sample_api_data )
90+
91+ # Not low with 43 remaining
92+ self .assertFalse (response .is_low )
93+
94+ # Low with exactly 5 remaining
95+ response .credits_used = 45
96+ self .assertTrue (response .is_low )
97+
98+ # Low with 1 remaining
99+ response .credits_used = 49
100+ self .assertTrue (response .is_low )
101+
102+ # Not low when exhausted (0 remaining)
103+ response .credits_used = 50
104+ self .assertFalse (response .is_low )
105+
106+ # Not low with 6 remaining
107+ response .credits_used = 44
108+ self .assertFalse (response .is_low )
109+
72110 def test_to_log_message_enabled (self ):
73111 """Test log message formatting when enabled."""
74112 response = CreditTrackingResponse .from_api_response (self .sample_api_data )
@@ -77,6 +115,64 @@ def test_to_log_message_enabled(self):
77115 expected = "Credits: 7/50 used (43 remaining). Trial expires 2024-11-12T14:30:00Z"
78116 self .assertEqual (message , expected )
79117
118+ def test_get_credit_warning_message (self ):
119+ """Test credit warning message generation."""
120+ response = CreditTrackingResponse .from_api_response (self .sample_api_data )
121+
122+ # Test exhausted credits
123+ response .credits_used = 50
124+ warning_msg = response .get_credit_warning_message ()
125+
126+ self .assertEqual (warning_msg , "Credits have been exhausted. Contact your CSM to request additional credits." )
127+
128+ # Test low credits (with color formatting)
129+ response .credits_used = 45 # 5 remaining
130+ warning_msg = response .get_credit_warning_message ()
131+
132+ self .assertIn ("5 credits remaining" , warning_msg )
133+ self .assertIn ("\033 [0;33m" , warning_msg ) # Yellow color code
134+ self .assertIn ("\033 [0m" , warning_msg ) # Reset color code
135+
136+ # Test normal credits (no warning)
137+ response .credits_used = 44 # 6 remaining
138+ warning_msg = response .get_credit_warning_message ()
139+
140+ self .assertEqual (warning_msg , "" )
141+
142+ def test_should_log_warning (self ):
143+ """Test warning condition detection."""
144+ response = CreditTrackingResponse .from_api_response (self .sample_api_data )
145+
146+ # Normal state - no warning
147+ self .assertFalse (response .should_log_warning ())
148+
149+ # Low credits - should warn
150+ response .credits_used = 45
151+ self .assertTrue (response .should_log_warning ())
152+
153+ # Exhausted - should warn
154+ response .credits_used = 50
155+ self .assertTrue (response .should_log_warning ())
156+
157+ def test_basic_functionality_only (self ):
158+ """Test that we only have basic client-side functionality."""
159+ response = CreditTrackingResponse .from_api_response (self .sample_api_data )
160+
161+ # Verify the basic properties work
162+ self .assertEqual (response .credits_remaining , 43 )
163+ self .assertFalse (response .is_exhausted )
164+ self .assertFalse (response .is_low )
165+
166+ # Verify exhaustion detection
167+ response .credits_used = 50
168+ self .assertTrue (response .is_exhausted )
169+ self .assertFalse (response .is_low )
170+
171+ # Verify low credit detection
172+ response .credits_used = 46 # 4 remaining
173+ self .assertFalse (response .is_exhausted )
174+ self .assertTrue (response .is_low )
175+
80176 def test_to_log_message_disabled (self ):
81177 """Test log message formatting when disabled."""
82178 response = CreditTrackingResponse .from_api_response (self .disabled_api_data )
@@ -90,11 +186,12 @@ def test_to_pr_body_section_enabled(self):
90186 response = CreditTrackingResponse .from_api_response (self .sample_api_data )
91187 pr_section = response .to_pr_body_section ()
92188
189+ # Test new format matches documentation spec
93190 self .assertIn ("### Contrast LLM Credits" , pr_section )
94- self .assertIn ("**Used:** 7/50" , pr_section )
95- self .assertIn ("**Remaining:** 43" , pr_section )
96- self . assertIn ( "**Trial Period:** Oct 01, 2024 to Nov 12, 2024" , pr_section )
97- self .assertTrue ( pr_section . startswith ( " \n --- \n " ) )
191+ self .assertIn ("- **Used:** 7/50" , pr_section )
192+ self .assertIn ("- **Remaining:** 43" , pr_section )
193+ # Should include trial period dates
194+ self .assertIn ( "- **Trial Period:** Oct 01, 2024 to Nov 12, 2024" , pr_section )
98195
99196 def test_to_pr_body_section_disabled (self ):
100197 """Test PR body section formatting when disabled."""
@@ -155,15 +252,19 @@ def test_edge_cases(self):
155252
156253 response = CreditTrackingResponse .from_api_response (data )
157254 pr_section = response .to_pr_body_section ()
158- self .assertIn ("**Trial Period:** Jan 15, 2025 to Mar 31, 2025" , pr_section )
255+ self .assertIn ("- **Used:** 0/50" , pr_section )
256+ self .assertIn ("- **Remaining:** 50" , pr_section )
257+ self .assertIn ("- **Trial Period:** Jan 15, 2025 to Mar 31, 2025" , pr_section )
159258
160259 # Test empty dates edge case
161260 data ["startDate" ] = ""
162261 data ["endDate" ] = ""
163262
164263 response = CreditTrackingResponse .from_api_response (data )
165264 pr_section = response .to_pr_body_section ()
166- self .assertIn ("**Trial Period:** Unknown to Unknown" , pr_section )
265+ self .assertIn ("- **Used:** 0/50" , pr_section )
266+ self .assertIn ("- **Remaining:** 50" , pr_section )
267+ self .assertIn ("- **Trial Period:** Unknown to Unknown" , pr_section )
167268
168269
169270if __name__ == '__main__' :
0 commit comments