diff --git a/fundraising/admin_views.py b/fundraising/admin_views.py index 48aab99934..7677ee158e 100644 --- a/fundraising/admin_views.py +++ b/fundraising/admin_views.py @@ -44,7 +44,7 @@ def download_donor_report(modeladmin, request, queryset): alternate_email, last_gift_date, last_gift_amount, - last_gift.get_interval_display().replace("donation", ""), + last_gift.get_interval_display().replace("donation", "").strip(), "Yes" if last_gift.stripe_subscription_id else "", donor.location, ] diff --git a/fundraising/tests/test_admin.py b/fundraising/tests/test_admin.py new file mode 100644 index 0000000000..a24094dffe --- /dev/null +++ b/fundraising/tests/test_admin.py @@ -0,0 +1,91 @@ +from django.contrib.admin import helpers +from django.contrib.auth.models import User +from django.test import TestCase +from django.urls import reverse +from django.utils import timezone +from django.utils.crypto import get_random_string + +from fundraising.models import DjangoHero + + +class CustomViewTests(TestCase): + @classmethod + def setUpTestData(cls): + cls.super_user = User.objects.create_superuser(username="superuser") + + def setUp(self): + super().setUp() + self.client.force_login(self.super_user) + + def test_download_donor_report(self): + heroes = [] + for _ in range(3): + a_hero = DjangoHero.objects.create(approved=True, is_visible=True) + donation = a_hero.donation_set.create(interval="onetime") + donation.payment_set.create( + amount=42, + stripe_charge_id=get_random_string(length=12), + ) + heroes.append(a_hero) + num_queries = ( + 1 # SELECT "django_session" + + 1 # SELECT "auth_user" + + 2 # COUNT("fundraising_djangohero") + + 1 # SELECT "fundraising_djangohero" + + 3 # SELECT "fundraising_payment". FIXME: N+1 queries + ) + with self.assertNumQueries(num_queries): + response = self.client.post( + reverse("admin:fundraising_djangohero_changelist"), + { + "action": "download_donor_report", + helpers.ACTION_CHECKBOX_NAME: [h.pk for h in heroes], + }, + follow=True, + ) + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.content, + "\r\n".join( + [ + "name,email,alternate email,last gift date,gift amount (US$)," + "interval,recurring active?,location", + f",,,{timezone.now():%Y-%m-%d},42.00,One-time,,", + f",,,{timezone.now():%Y-%m-%d},42.00,One-time,,", + f",,,{timezone.now():%Y-%m-%d},42.00,One-time,,", + "", # empty end line + ] + ).encode(), + ) + + def test_download_donor_report_get_latest_payment(self): + a_hero = DjangoHero.objects.create(approved=True, is_visible=True) + donation = a_hero.donation_set.create(interval="onetime") + donation.payment_set.create( + amount=42, + stripe_charge_id=get_random_string(length=12), + ) + donation.payment_set.create( + amount=21, + stripe_charge_id=get_random_string(length=12), + ) + response = self.client.post( + reverse("admin:fundraising_djangohero_changelist"), + { + "action": "download_donor_report", + helpers.ACTION_CHECKBOX_NAME: [a_hero.pk], + }, + follow=True, + ) + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.content, + "\r\n".join( + [ + "name,email,alternate email,last gift date,gift amount (US$)," + "interval,recurring active?,location", + f",,,{timezone.now():%Y-%m-%d},21.00,One-time,,", + "", # empty end line + ] + ).encode(), + )