Match tests to the reworked dashboard, surface the renewals KPI
The club table was rebuilt (logo, status badges, Plan/Dues columns, an Edit
action) and the dashboard dropped the second chart, so three render tests were
asserting columns and a canvas that no longer exist. Updated to the current
layout — the service-level tests were already correct, since the annotations they
check still exist even where the template stopped rendering them.
Worked the renewals KPI into the billing card: "N awaiting renewal", shown only
when non-zero. It should sit at 0 in normal running — the cron renews clubs 30
days out and they fall past the horizon — so a number here means the job has
stopped and a club is about to use the platform free, which nothing else on the
page reveals because nothing has been billed yet.
Fixed two things in the WIP table while here: a debug line that printed the raw
grace/period/owed values into the Dues cell, and a missing {% empty %} clause
(so an empty list showed a headed table with no "no clubs" row, and empty_message
was dead). Removed the stale commented-out copy of the old table.
Answers "auto-renewed but unpaid?": it is not a special case. Renewal opens an
ordinary unpaid Due, which flows unpaid -> grace -> overdue -> archive like any
period — so the safety net that the never-billed club slipped past now fires,
because there is a due to be overdue. Tested both ways.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -457,3 +457,34 @@ class RenewalTests(BillingTestBase):
|
||||
out = StringIO()
|
||||
call_command("renew_subscriptions", *args, stdout=out)
|
||||
return out.getvalue()
|
||||
|
||||
|
||||
class RenewedButUnpaidTests(BillingTestBase):
|
||||
"""A club auto-renewed that never pays the new fee flows through the ordinary
|
||||
unpaid -> grace -> overdue -> archive path. Renewal creates a normal Due; it does not
|
||||
create a special case, and the safety net that the never-billed club slipped past now
|
||||
fires, because there IS an unpaid due."""
|
||||
|
||||
def lapsed_club(self):
|
||||
"""A club on its first, PAID period — far enough back that a renewal from its end is
|
||||
itself already past grace, so only the renewal's payment state decides the outcome."""
|
||||
club = Club.objects.create(name="Renewed FC")
|
||||
subscribe(club, self.tier, start=self.today - datetime.timedelta(days=800))
|
||||
first = club.dues.first()
|
||||
record_payment(first, first.amount) # the FIRST period is settled; only the renewal is in question
|
||||
return club
|
||||
|
||||
def test_an_unpaid_renewal_becomes_overdue_and_archivable(self):
|
||||
club = self.lapsed_club()
|
||||
renewed = renew(club.subscription) # continues from the first period's end, unpaid
|
||||
|
||||
self.assertTrue(renewed.is_overdue(self.today))
|
||||
self.assertIn(renewed, dues_overdue(self.today))
|
||||
self.assertIn(club, [d.club for d in archivable_clubs(self.today)])
|
||||
|
||||
def test_a_paid_renewal_is_not_chased(self):
|
||||
club = self.lapsed_club()
|
||||
renewed = renew(club.subscription)
|
||||
record_payment(renewed, renewed.amount)
|
||||
|
||||
self.assertNotIn(club, [d.club for d in archivable_clubs(self.today)])
|
||||
|
||||
Reference in New Issue
Block a user