Skip to content

Commit 92faab2

Browse files
committed
Update cli_output tests for promo credits refactor
Rename test references from _display_purchased_credit_line to the generalized _display_bucket_credit_line, pass the new promo_credits argument to _display_status_message, and add coverage for promo display, promo-only remaining balance, and backward compatibility when the API omits promo_credits.
1 parent fb30ece commit 92faab2

1 file changed

Lines changed: 118 additions & 12 deletions

File tree

tests/test_cli_output.py

Lines changed: 118 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
from cli_output.status import (
66
_create_progress_bar,
7+
_display_bucket_credit_line,
78
_display_credit_line,
8-
_display_purchased_credit_line,
99
_display_status_message,
1010
print_status,
1111
)
@@ -132,8 +132,8 @@ def test_timezone_naive_datetime(self, mock_console):
132132
mock_console.print.assert_called_once()
133133

134134

135-
class TestDisplayPurchasedCreditLine:
136-
"""Tests for _display_purchased_credit_line function."""
135+
class TestDisplayBucketCreditLine:
136+
"""Tests for _display_bucket_credit_line function."""
137137

138138
@patch("cli_output.status.console")
139139
def test_display_active_purchased_credits(self, mock_console):
@@ -143,13 +143,28 @@ def test_display_active_purchased_credits(self, mock_console):
143143
"remaining": 20,
144144
"expiry_date": "2028-12-12T00:00:00+00:00",
145145
}
146-
_display_purchased_credit_line(bucket)
146+
_display_bucket_credit_line(bucket, "Purchased")
147147

148148
call_args = mock_console.print.call_args[0][0]
149149
assert "Purchased" in call_args
150150
assert "20 of 100 remaining" in call_args
151151
assert "expires Dec 12, 2028" in call_args
152152

153+
@patch("cli_output.status.console")
154+
def test_display_active_promo_credits(self, mock_console):
155+
"""Test displaying active promo credits."""
156+
bucket = {
157+
"total": 100,
158+
"remaining": 20,
159+
"expiry_date": "2028-12-12T00:00:00+00:00",
160+
}
161+
_display_bucket_credit_line(bucket, "Promo")
162+
163+
call_args = mock_console.print.call_args[0][0]
164+
assert "Promo" in call_args
165+
assert "20 of 100 remaining" in call_args
166+
assert "expires Dec 12, 2028" in call_args
167+
153168
@patch("cli_output.status.console")
154169
def test_display_expired_purchased_credits(self, mock_console):
155170
"""Test displaying expired purchased credits."""
@@ -158,7 +173,7 @@ def test_display_expired_purchased_credits(self, mock_console):
158173
"remaining": 20,
159174
"expiry_date": "2024-01-01T00:00:00+00:00",
160175
}
161-
_display_purchased_credit_line(bucket)
176+
_display_bucket_credit_line(bucket, "Purchased")
162177

163178
call_args = mock_console.print.call_args[0][0]
164179
assert "expired Jan 1, 2024" in call_args
@@ -173,7 +188,7 @@ def test_timezone_naive_datetime(self, mock_console):
173188
"expiry_date": "2026-06-12T00:00:00", # No timezone
174189
}
175190
# Should not raise exception
176-
_display_purchased_credit_line(bucket)
191+
_display_bucket_credit_line(bucket, "Purchased")
177192
mock_console.print.assert_called_once()
178193

179194

@@ -187,7 +202,7 @@ def test_has_active_plan_credits(self, mock_console):
187202
"remaining": 10,
188203
"period_end": "2028-12-01T00:00:00+00:00",
189204
}
190-
_display_status_message(plan_credits, [])
205+
_display_status_message(plan_credits, [], [])
191206

192207
# Should not print warning message
193208
mock_console.print.assert_not_called()
@@ -201,7 +216,21 @@ def test_has_active_purchased_credits(self, mock_console):
201216
"expiry_date": "2030-06-12T00:00:00+00:00",
202217
}
203218
]
204-
_display_status_message(None, purchased_credits)
219+
_display_status_message(None, purchased_credits, [])
220+
221+
# Should not print warning message
222+
mock_console.print.assert_not_called()
223+
224+
@patch("cli_output.status.console")
225+
def test_has_active_promo_credits(self, mock_console):
226+
"""Test when user only has active promo credits."""
227+
promo_credits = [
228+
{
229+
"remaining": 20,
230+
"expiry_date": "2030-06-12T00:00:00+00:00",
231+
}
232+
]
233+
_display_status_message(None, [], promo_credits)
205234

206235
# Should not print warning message
207236
mock_console.print.assert_not_called()
@@ -213,7 +242,7 @@ def test_no_credits_remaining(self, mock_console):
213242
"remaining": 0,
214243
"period_end": "2028-12-01T00:00:00+00:00",
215244
}
216-
_display_status_message(plan_credits, [])
245+
_display_status_message(plan_credits, [], [])
217246

218247
mock_console.print.assert_called_once()
219248
call_args = mock_console.print.call_args[0][0]
@@ -226,16 +255,16 @@ def test_expired_plan_credits(self, mock_console):
226255
"remaining": 10,
227256
"period_end": "2024-01-01T00:00:00+00:00",
228257
}
229-
_display_status_message(plan_credits, [])
258+
_display_status_message(plan_credits, [], [])
230259

231260
mock_console.print.assert_called_once()
232261
call_args = mock_console.print.call_args[0][0]
233262
assert "No rendering credits remaining" in call_args
234263

235264
@patch("cli_output.status.console")
236265
def test_null_plan_credits_and_empty_purchased(self, mock_console):
237-
"""Test when plan_credits is None and purchased_credits is empty."""
238-
_display_status_message(None, [])
266+
"""Test when plan_credits is None and purchased/promo credits are empty."""
267+
_display_status_message(None, [], [])
239268

240269
mock_console.print.assert_called_once()
241270
call_args = mock_console.print.call_args[0][0]
@@ -384,6 +413,83 @@ def test_multiple_purchased_credit_buckets(self, mock_console, mock_api_class):
384413
purchased_calls = [c for c in calls if "Purchased" in c]
385414
assert len(purchased_calls) == 2
386415

416+
@patch("cli_output.status.codeplain_api.CodeplainAPI")
417+
@patch("cli_output.status.console")
418+
def test_promo_credit_buckets(self, mock_console, mock_api_class):
419+
"""Test status display includes promo credit buckets."""
420+
mock_api = Mock()
421+
mock_api_class.return_value = mock_api
422+
mock_api.connection_check.return_value = {
423+
"client_version_valid": True,
424+
"min_client_version": "0.3.0",
425+
}
426+
mock_api.status.return_value = {
427+
"user": {
428+
"first_name": "John",
429+
"last_name": "Doe",
430+
"email": "john@example.com",
431+
},
432+
"api_key_label": "test-key",
433+
"organization_owner_email": "owner@example.com",
434+
"plan_credits": None,
435+
"purchased_credits": [
436+
{
437+
"total": 100,
438+
"remaining": 50,
439+
"expiry_date": "2030-06-12T00:00:00+00:00",
440+
},
441+
],
442+
"promo_credits": [
443+
{
444+
"total": 30,
445+
"remaining": 15,
446+
"expiry_date": "2030-12-31T00:00:00+00:00",
447+
},
448+
],
449+
}
450+
451+
print_status("fake-key", "http://localhost:5000", "0.3.0")
452+
453+
calls = [str(call) for call in mock_console.print.call_args_list]
454+
promo_calls = [c for c in calls if "Promo" in c]
455+
assert len(promo_calls) == 1
456+
# Active credits remain, so no "no credits remaining" warning
457+
assert not any("No rendering credits remaining" in c for c in calls)
458+
459+
@patch("cli_output.status.codeplain_api.CodeplainAPI")
460+
@patch("cli_output.status.console")
461+
def test_missing_promo_credits_key_is_backward_compatible(self, mock_console, mock_api_class):
462+
"""Test status display when API response omits promo_credits (older API)."""
463+
mock_api = Mock()
464+
mock_api_class.return_value = mock_api
465+
mock_api.connection_check.return_value = {
466+
"client_version_valid": True,
467+
"min_client_version": "0.3.0",
468+
}
469+
mock_api.status.return_value = {
470+
"user": {
471+
"first_name": "John",
472+
"last_name": "Doe",
473+
"email": "john@example.com",
474+
},
475+
"api_key_label": "test-key",
476+
"organization_owner_email": "owner@example.com",
477+
"plan_credits": {
478+
"type": "free",
479+
"total": 50,
480+
"remaining": 10,
481+
"period_end": "2030-12-01T00:00:00+00:00",
482+
},
483+
"purchased_credits": [],
484+
# promo_credits intentionally omitted
485+
}
486+
487+
# Should not raise
488+
print_status("fake-key", "http://localhost:5000", "0.3.0")
489+
490+
calls = [str(call) for call in mock_console.print.call_args_list]
491+
assert not any("Promo" in c for c in calls)
492+
387493

388494
class TestVersionFlag:
389495
"""Tests for --version flag."""

0 commit comments

Comments
 (0)