bgneal@33: """ bgneal@316: Tests for the donations application. bgneal@316: """ bgneal@316: import urlparse bgneal@316: from decimal import Decimal bgneal@316: import datetime bgneal@33: bgneal@316: from django.contrib.auth.models import User bgneal@316: from django.test import TestCase bgneal@316: from django.core.urlresolvers import reverse bgneal@619: from django.conf import settings bgneal@33: bgneal@316: from donations.models import Donation bgneal@316: import bio.badges bgneal@33: bgneal@316: bgneal@316: # This data was copy/pasted from my actual Paypal IPN history. Some alterations bgneal@316: # were made since this file is getting committed to version control and I bgneal@316: # didn't want to store "real" data that could be used to trace a transaction or bgneal@316: # real payer. bgneal@316: bgneal@316: # This data is for a non-anonymous donation: bgneal@316: TEST_POST_DATA_1 = """\ bgneal@316: mc_gross=5.00&protection_eligibility=Ineligible&payer_id=FAKEPAYERID01&tax=0.00&payment_date=04:14:08 Jan 21, 2011 PST&payment_status=Completed&charset=windows-1252&first_name=John&option_selection1=No&mc_fee=0.50¬ify_version=3.0&custom=test_user&payer_status=verified&business=brian@surfguitar101.com&quantity=1&verify_sign=Ai1PaTHIS-IS-FAKE-DATA-jB264AOjpiTa4vcsPCEavq-83oyIclHKI&payer_email=test_user@example.com&option_name1=List your name?&txn_id=TESTTXNID5815921V&payment_type=instant&last_name=Doe&receiver_email=brian@surfguitar101.com&payment_fee=0.50&receiver_id=FAKERECEIVERU&txn_type=web_accept&item_name=Donation for www.surfguitar101.com&mc_currency=USD&item_number=500&residence_country=AU&handling_amount=0.00&transaction_subject=test_user&payment_gross=5.00&shipping=0.00""" bgneal@316: bgneal@316: # Data from a user that wanted to remain anonymous bgneal@316: TEST_POST_DATA_2 = """\ bgneal@316: mc_gross=100.00&protection_eligibility=Ineligible&payer_id=FAKEPAYERID02&tax=0.00&payment_date=05:40:33 Jan 16, 2011 PST&payment_status=Completed&charset=windows-1252&first_name=John&option_selection1=No&mc_fee=3.20¬ify_version=3.0&custom=test_user&payer_status=unverified&business=brian@surfguitar101.com&quantity=1&verify_sign=AIkKNFAKE-DATA-NOT-REALpqCSxA-E7Tm4rMGlUpNy6ym0.exBzfiyI&payer_email=test_user@example.com&option_name1=List your name?&txn_id=TESTTXNIDK548343A&payment_type=instant&last_name=Doe&receiver_email=brian@surfguitar101.com&payment_fee=3.20&receiver_id=FAKERECEIVERU&txn_type=web_accept&item_name=Donation for www.surfguitar101.com&mc_currency=USD&item_number=501&residence_country=US&handling_amount=0.00&transaction_subject=test_user&payment_gross=100.00&shipping=0.00""" bgneal@316: bgneal@316: bgneal@619: class DonationsIpnTestCase(TestCase): bgneal@316: fixtures = ['badges'] bgneal@316: bgneal@316: def test_ipn_post_1(self): bgneal@33: """ bgneal@316: Test a simulated IPN post bgneal@33: """ bgneal@316: user = User.objects.create_user('test_user', 'test_user@example.com', bgneal@316: 'password') bgneal@316: user.save() bgneal@33: bgneal@316: args = urlparse.parse_qs(TEST_POST_DATA_1) bgneal@316: response = self.client.post(reverse('donations-ipn'), args) bgneal@33: bgneal@316: self.assertEqual(response.status_code, 200) bgneal@33: bgneal@316: try: bgneal@316: d = Donation.objects.get(pk=1) bgneal@316: except Donation.DoesNotExist: bgneal@316: self.fail("Donation object was not created") bgneal@316: else: bgneal@316: self.assertEqual(d.user, user) bgneal@316: self.assertFalse(d.is_anonymous) bgneal@316: self.assertFalse(d.test_ipn) bgneal@316: self.assertEqual(d.txn_id, 'TESTTXNID5815921V') bgneal@316: self.assertEqual(d.txn_type, 'web_accept') bgneal@316: self.assertEqual(d.first_name, 'John') bgneal@316: self.assertEqual(d.last_name, 'Doe') bgneal@316: self.assertEqual(d.payer_email, 'test_user@example.com') bgneal@316: self.assertEqual(d.payer_id, 'FAKEPAYERID01') bgneal@316: self.assertEqual(d.mc_fee, Decimal('0.50')) bgneal@316: self.assertEqual(d.mc_gross, Decimal('5.00')) bgneal@316: self.assertEqual(d.memo, '') bgneal@316: self.assertEqual(d.payer_status, 'verified') bgneal@316: self.assertEqual(d.payment_date, bgneal@316: datetime.datetime(2011, 1, 21, 4, 14, 8)) bgneal@316: bgneal@316: # user should have got a badge for donating bgneal@316: p = user.get_profile() bgneal@316: badges = list(p.badges.all()) bgneal@316: self.assertEqual(len(badges), 1) bgneal@316: if len(badges) == 1: bgneal@316: self.assertEqual(badges[0].numeric_id, bio.badges.CONTRIBUTOR_PIN) bgneal@316: bgneal@316: def test_ipn_post_2(self): bgneal@316: """ bgneal@316: Test a simulated IPN post bgneal@316: """ bgneal@316: user = User.objects.create_user('test_user', 'test_user@example.com', bgneal@316: 'password') bgneal@316: user.save() bgneal@316: bgneal@316: args = urlparse.parse_qs(TEST_POST_DATA_2) bgneal@316: response = self.client.post(reverse('donations-ipn'), args) bgneal@316: bgneal@316: self.assertEqual(response.status_code, 200) bgneal@316: bgneal@316: try: bgneal@316: d = Donation.objects.get(pk=1) bgneal@316: except Donation.DoesNotExist: bgneal@316: self.fail("Donation object was not created") bgneal@316: else: bgneal@316: self.assertEqual(d.user, user) bgneal@316: self.assertTrue(d.is_anonymous) bgneal@316: self.assertFalse(d.test_ipn) bgneal@316: self.assertEqual(d.txn_id, 'TESTTXNIDK548343A') bgneal@316: self.assertEqual(d.txn_type, 'web_accept') bgneal@316: self.assertEqual(d.first_name, 'John') bgneal@316: self.assertEqual(d.last_name, 'Doe') bgneal@316: self.assertEqual(d.payer_email, 'test_user@example.com') bgneal@316: self.assertEqual(d.payer_id, 'FAKEPAYERID02') bgneal@316: self.assertEqual(d.mc_fee, Decimal('3.20')) bgneal@316: self.assertEqual(d.mc_gross, Decimal('100.00')) bgneal@316: self.assertEqual(d.memo, '') bgneal@577: self.assertEqual(d.payer_status, 'unverified') bgneal@316: self.assertEqual(d.payment_date, bgneal@316: datetime.datetime(2011, 1, 16, 5, 40, 33)) bgneal@316: bgneal@316: # user should not have got a badge for donating bgneal@316: p = user.get_profile() bgneal@316: self.assertEqual(p.badges.count(), 0) bgneal@619: bgneal@619: bgneal@619: class DonationsManagerTestCase(TestCase): bgneal@619: fixtures = ['donations_test'] bgneal@619: bgneal@619: def test_monthly_goal_pct(self): bgneal@619: bgneal@619: self.assertEqual(settings.DONATIONS_GOAL, Decimal('100.00')) bgneal@619: pct = Donation.objects.monthly_goal_pct(year=2012, month=9) bgneal@619: self.assertEqual(pct, 23) bgneal@619: bgneal@619: def test_monthly_goal_pct2(self): bgneal@619: bgneal@619: # Ensure we get 0 when there are no records bgneal@619: bgneal@619: Donation.objects.all().delete() bgneal@619: pct = Donation.objects.monthly_goal_pct(year=2012, month=9) bgneal@619: self.assertEqual(pct, 0) bgneal@619: bgneal@619: def test_monthly_stats(self): bgneal@619: bgneal@619: gross, net, donations = Donation.objects.monthly_stats(year=2012, month=9) bgneal@619: self.assertEqual(gross, Decimal('25.00')) bgneal@619: self.assertEqual(net, Decimal('23.47')) bgneal@619: self.assertEqual(len(donations), 2) bgneal@619: bgneal@619: def test_monthly_stats2(self): bgneal@619: bgneal@619: # Ensure we get 0 when there are no records bgneal@619: bgneal@619: Donation.objects.all().delete() bgneal@619: bgneal@619: gross, net, donations = Donation.objects.monthly_stats(year=2012, month=9) bgneal@619: self.assertEqual(gross, Decimal('0.00')) bgneal@619: self.assertEqual(net, Decimal('0.00')) bgneal@619: self.assertEqual(len(donations), 0)