Repository: gratipay/gratipay.com

Issue:
New tip created by orphaned account
[_check_orphans_no_tips](https://github.com/gittip/www.gittip.com/blob/7890451ac2c86f2eee647a446f706d891cb8961f/gittip/models/__init__.py#L114) now finds two problems instead of just the one already known. See also [sentry](https://app.getsentry.com/gittip/gittip/group/14299085/).

It is the same tip as before, but with refreshed `mtime` for today. It is a self tip (from the definition in `take_over`) in that the tipper has been absorbed some time ago by the tippee (the tippee is still alive). Session token for the tipper is null, session expire time half a year ago.

This is a bug in core assumptions the site is built on. If users with no way to sign in can create tips, what else could be circumvented like this?



Discussion:

Resolving patch:
diff --git a/gittip/models/participant.py b/gittip/models/participant.py
--- a/gittip/models/participant.py
+++ b/gittip/models/participant.py
@@ -643,6 +643,8 @@ def set_tip_to(self, tippee, amount, update_self=True, update_tippee=True, curso
         that as part of our conversion funnel).
 
         """
+        assert self.is_claimed  # sanity check
+
         if not isinstance(tippee, Participant):
             tippee, u = Participant.from_username(tippee), tippee
             if not tippee:


Test patch:
diff --git a/tests/py/test_close.py b/tests/py/test_close.py
--- a/tests/py/test_close.py
+++ b/tests/py/test_close.py
@@ -16,9 +16,9 @@ class TestClosing(Harness):
     # close
 
     def test_close_closes(self):
-        alice = self.make_participant('alice', balance=D('10.00'))
+        alice = self.make_participant('alice', claimed_time='now', balance=D('10.00'))
         bob = self.make_participant('bob', claimed_time='now')
-        carl = self.make_participant('carl')
+        carl = self.make_participant('carl', claimed_time='now')
 
         alice.set_tip_to(bob, D('3.00'))
         carl.set_tip_to(alice, D('2.00'))
@@ -105,7 +105,7 @@ def test_wbtba_raises_NotWhitelisted_if_blacklisted(self):
     # dbafg - distribute_balance_as_final_gift
 
     def test_dbafg_distributes_balance_as_final_gift(self):
-        alice = self.make_participant('alice', balance=D('10.00'))
+        alice = self.make_participant('alice', claimed_time='now', balance=D('10.00'))
         bob = self.make_participant('bob', claimed_time='now')
         carl = self.make_participant('carl', claimed_time='now')
         alice.set_tip_to(bob, D('3.00'))
@@ -117,7 +117,7 @@ def test_dbafg_distributes_balance_as_final_gift(self):
         assert Participant.from_username('alice').balance == D('0.00')
 
     def test_dbafg_needs_claimed_tips(self):
-        alice = self.make_participant('alice', balance=D('10.00'))
+        alice = self.make_participant('alice', claimed_time='now', balance=D('10.00'))
         bob = self.make_participant('bob')
         carl = self.make_participant('carl')
         alice.set_tip_to(bob, D('3.00'))
@@ -130,7 +130,7 @@ def test_dbafg_needs_claimed_tips(self):
         assert Participant.from_username('alice').balance == D('10.00')
 
     def test_dbafg_gives_all_to_claimed(self):
-        alice = self.make_participant('alice', balance=D('10.00'))
+        alice = self.make_participant('alice', claimed_time='now', balance=D('10.00'))
         bob = self.make_participant('bob', claimed_time='now')
         carl = self.make_participant('carl')
         alice.set_tip_to(bob, D('3.00'))
@@ -142,7 +142,7 @@ def test_dbafg_gives_all_to_claimed(self):
         assert Participant.from_username('alice').balance == D('0.00')
 
     def test_dbafg_skips_zero_tips(self):
-        alice = self.make_participant('alice', balance=D('10.00'))
+        alice = self.make_participant('alice', claimed_time='now', balance=D('10.00'))
         bob = self.make_participant('bob', claimed_time='now')
         carl = self.make_participant('carl', claimed_time='now')
         alice.set_tip_to(bob, D('0.00'))
@@ -155,7 +155,7 @@ def test_dbafg_skips_zero_tips(self):
         assert Participant.from_username('alice').balance == D('0.00')
 
     def test_dbafg_favors_highest_tippee_in_rounding_errors(self):
-        alice = self.make_participant('alice', balance=D('10.00'))
+        alice = self.make_participant('alice', claimed_time='now', balance=D('10.00'))
         bob = self.make_participant('bob', claimed_time='now')
         carl = self.make_participant('carl', claimed_time='now')
         alice.set_tip_to(bob, D('3.00'))
@@ -167,7 +167,7 @@ def test_dbafg_favors_highest_tippee_in_rounding_errors(self):
         assert Participant.from_username('alice').balance == D('0.00')
 
     def test_dbafg_with_zero_balance_is_a_noop(self):
-        alice = self.make_participant('alice', balance=D('0.00'))
+        alice = self.make_participant('alice', claimed_time='now', balance=D('0.00'))
         bob = self.make_participant('bob', claimed_time='now')
         carl = self.make_participant('carl', claimed_time='now')
         alice.set_tip_to(bob, D('3.00'))
@@ -183,7 +183,7 @@ def test_dbafg_with_zero_balance_is_a_noop(self):
     # ctg - clear_tips_giving
 
     def test_ctg_clears_tips_giving(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         alice.set_tip_to(self.make_participant('bob', claimed_time='now').username, D('1.00'))
         ntips = lambda: self.db.one("SELECT count(*) FROM current_tips "
                                     "WHERE tipper='alice' AND amount > 0")
@@ -193,7 +193,7 @@ def test_ctg_clears_tips_giving(self):
         assert ntips() == 0
 
     def test_ctg_doesnt_duplicate_zero_tips(self):
-        alice = self.make_participant('alice')
+        alice = self.make_participant('alice', claimed_time='now')
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, D('1.00'))
         alice.set_tip_to(bob, D('0.00'))
@@ -212,7 +212,7 @@ def test_ctg_doesnt_zero_when_theres_no_tip(self):
         assert ntips() == 0
 
     def test_ctg_clears_multiple_tips_giving(self):
-        alice = self.make_participant('alice')
+        alice = self.make_participant('alice', claimed_time='now')
         alice.set_tip_to(self.make_participant('bob', claimed_time='now').username, D('1.00'))
         alice.set_tip_to(self.make_participant('carl', claimed_time='now').username, D('1.00'))
         alice.set_tip_to(self.make_participant('darcy', claimed_time='now').username, D('1.00'))
@@ -230,7 +230,7 @@ def test_ctg_clears_multiple_tips_giving(self):
 
     def test_ctr_clears_tips_receiving(self):
         alice = self.make_participant('alice')
-        self.make_participant('bob').set_tip_to(alice, D('1.00'))
+        self.make_participant('bob', claimed_time='now').set_tip_to(alice, D('1.00'))
         ntips = lambda: self.db.one("SELECT count(*) FROM current_tips "
                                     "WHERE tippee='alice' AND amount > 0")
         assert ntips() == 1
@@ -240,7 +240,7 @@ def test_ctr_clears_tips_receiving(self):
 
     def test_ctr_doesnt_duplicate_zero_tips(self):
         alice = self.make_participant('alice')
-        bob = self.make_participant('bob')
+        bob = self.make_participant('bob', claimed_time='now')
         bob.set_tip_to(alice, D('1.00'))
         bob.set_tip_to(alice, D('0.00'))
         ntips = lambda: self.db.one("SELECT count(*) FROM tips WHERE tippee='alice'")
@@ -259,11 +259,11 @@ def test_ctr_doesnt_zero_when_theres_no_tip(self):
 
     def test_ctr_clears_multiple_tips_receiving(self):
         alice = self.make_participant('alice')
-        self.make_participant('bob').set_tip_to(alice, D('1.00'))
-        self.make_participant('carl').set_tip_to(alice, D('2.00'))
-        self.make_participant('darcy').set_tip_to(alice, D('3.00'))
-        self.make_participant('evelyn').set_tip_to(alice, D('4.00'))
-        self.make_participant('francis').set_tip_to(alice, D('5.00'))
+        self.make_participant('bob', claimed_time='now').set_tip_to(alice, D('1.00'))
+        self.make_participant('carl', claimed_time='now').set_tip_to(alice, D('2.00'))
+        self.make_participant('darcy', claimed_time='now').set_tip_to(alice, D('3.00'))
+        self.make_participant('evelyn', claimed_time='now').set_tip_to(alice, D('4.00'))
+        self.make_participant('francis', claimed_time='now').set_tip_to(alice, D('5.00'))
         ntips = lambda: self.db.one("SELECT count(*) FROM current_tips "
                                     "WHERE tippee='alice' AND amount > 0")
         assert ntips() == 5
diff --git a/tests/py/test_participant.py b/tests/py/test_participant.py
--- a/tests/py/test_participant.py
+++ b/tests/py/test_participant.py
@@ -371,6 +371,7 @@ def test_changing_username_to_restricted_name(self):
     def test_getting_tips_actually_made(self):
         expected = Decimal('1.00')
         user2 = self.make_participant('user2')
+        self.participant.set_as_claimed()
         self.participant.set_tip_to(user2, expected)
         actual = self.participant.get_tip_to('user2')
         assert actual == expected
@@ -392,22 +393,22 @@ def test_participant_gets_a_long_id(self):
     # number
 
     def test_cant_go_singular_with_big_tips(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob', number='plural')
-        carl = self.make_participant('carl')
+        carl = self.make_participant('carl', claimed_time='now')
         carl.set_tip_to(bob, '100.00')
         alice.set_tip_to(bob, '1000.00')
         pytest.raises(HasBigTips, bob.update_number, 'singular')
 
     def test_can_go_singular_without_big_tips(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob', number='plural')
         alice.set_tip_to(bob, '100.00')
         bob.update_number('singular')
         assert Participant.from_username('bob').number == 'singular'
 
     def test_can_go_plural(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '100.00')
         bob.update_number('plural')
@@ -417,7 +418,7 @@ def test_can_go_plural(self):
     # set_tip_to - stt
 
     def test_stt_sets_tip_to(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '1.00')
 
@@ -425,47 +426,47 @@ def test_stt_sets_tip_to(self):
         assert actual == Decimal('1.00')
 
     def test_stt_returns_a_Decimal_and_a_boolean(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
         actual = alice.set_tip_to(bob, '1.00')
         assert actual == (Decimal('1.00'), True)
 
     def test_stt_returns_False_for_second_time_tipper(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '1.00')
         actual = alice.set_tip_to(bob, '2.00')
         assert actual == (Decimal('2.00'), False)
 
     def test_stt_doesnt_allow_self_tipping(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         self.assertRaises(NoSelfTipping, alice.set_tip_to, 'alice', '10.00')
 
     def test_stt_doesnt_allow_just_any_ole_amount(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         self.make_participant('bob')
         self.assertRaises(BadAmount, alice.set_tip_to, 'bob', '1000.00')
 
     def test_stt_allows_higher_tip_to_plural_receiver(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob', number='plural')
         actual = alice.set_tip_to(bob, '1000.00')
         assert actual == (Decimal('1000.00'), True)
 
     def test_stt_still_caps_tips_to_plural_receivers(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         self.make_participant('bob', number='plural')
         self.assertRaises(BadAmount, alice.set_tip_to, 'bob', '1000.01')
 
     def test_stt_fails_to_tip_unknown_people(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         self.assertRaises(NoTippee, alice.set_tip_to, 'bob', '1.00')
 
 
     # giving and receiving
 
     def test_giving_and_receiving_only_count_latest_tip(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob', claimed_time='now')
         alice.set_tip_to(bob, '12.00')
         alice.set_tip_to(bob, '3.00')
@@ -473,7 +474,7 @@ def test_giving_and_receiving_only_count_latest_tip(self):
         assert bob.receiving == Decimal('3.00')
 
     def test_receiving_includes_tips_from_accounts_with_a_working_card(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '3.00')
 
@@ -482,7 +483,7 @@ def test_receiving_includes_tips_from_accounts_with_a_working_card(self):
         assert actual == expected
 
     def test_receiving_ignores_tips_from_accounts_with_no_card_on_file(self):
-        alice = self.make_participant('alice', last_bill_result=None)
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result=None)
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '3.00')
 
@@ -491,7 +492,7 @@ def test_receiving_ignores_tips_from_accounts_with_no_card_on_file(self):
         assert actual == expected
 
     def test_receiving_ignores_tips_from_accounts_with_a_failing_card_on_file(self):
-        alice = self.make_participant('alice', last_bill_result="Fail!")
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result="Fail!")
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '3.00')
 
@@ -501,6 +502,7 @@ def test_receiving_ignores_tips_from_accounts_with_a_failing_card_on_file(self):
 
     def test_receiving_includes_tips_from_whitelisted_accounts(self):
         alice = self.make_participant( 'alice'
+                                     , claimed_time='now'
                                      , last_bill_result=''
                                      , is_suspicious=False
                                       )
@@ -513,6 +515,7 @@ def test_receiving_includes_tips_from_whitelisted_accounts(self):
 
     def test_receiving_includes_tips_from_unreviewed_accounts(self):
         alice = self.make_participant( 'alice'
+                                     , claimed_time='now'
                                      , last_bill_result=''
                                      , is_suspicious=None
                                       )
@@ -525,6 +528,7 @@ def test_receiving_includes_tips_from_unreviewed_accounts(self):
 
     def test_receiving_ignores_tips_from_blacklisted_accounts(self):
         alice = self.make_participant( 'alice'
+                                     , claimed_time='now'
                                      , last_bill_result=''
                                      , is_suspicious=True
                                       )
@@ -536,7 +540,7 @@ def test_receiving_ignores_tips_from_blacklisted_accounts(self):
         assert actual == expected
 
     def test_receiving_includes_taking_when_updated_from_set_tip_to(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob', taking=Decimal('42.00'))
         alice.set_tip_to(bob, '3.00')
         assert Participant.from_username('bob').receiving == bob.receiving == Decimal('45.00')
@@ -545,15 +549,15 @@ def test_receiving_includes_taking_when_updated_from_set_tip_to(self):
     # pledging
 
     def test_pledging_only_counts_latest_tip(self):
-        alice = self.make_participant('alice', last_bill_result='')
-        bob = self.make_elsewhere('github', 1, 'bob').participant
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
+        bob = self.make_elsewhere('github', 58946, 'bob').participant
         alice.set_tip_to(bob, '12.00')
         alice.set_tip_to(bob, '3.00')
         assert alice.pledging == Decimal('3.00')
 
     def test_pledging_isnt_giving(self):
-        alice = self.make_participant('alice', last_bill_result='')
-        bob = self.make_elsewhere('github', 1, 'bob').participant
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
+        bob = self.make_elsewhere('github', 58946, 'bob').participant
         alice.set_tip_to(bob, '3.00')
         assert alice.giving == Decimal('0.00')
 
@@ -561,8 +565,8 @@ def test_pledging_isnt_giving(self):
     # get_number_of_backers - gnob
 
     def test_gnob_gets_number_of_backers(self):
-        alice = self.make_participant('alice', last_bill_result='')
-        bob = self.make_participant('bob', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
+        bob = self.make_participant('bob', claimed_time='now', last_bill_result='')
         clancy = self.make_participant('clancy')
 
         alice.set_tip_to(clancy, '3.00')
@@ -573,7 +577,7 @@ def test_gnob_gets_number_of_backers(self):
 
 
     def test_gnob_includes_backers_with_a_working_card_on_file(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '3.00')
 
@@ -581,7 +585,7 @@ def test_gnob_includes_backers_with_a_working_card_on_file(self):
         assert actual == 1
 
     def test_gnob_ignores_backers_with_no_card_on_file(self):
-        alice = self.make_participant('alice', last_bill_result=None)
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result=None)
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '3.00')
 
@@ -589,7 +593,7 @@ def test_gnob_ignores_backers_with_no_card_on_file(self):
         assert actual == 0
 
     def test_gnob_ignores_backers_with_a_failing_card_on_file(self):
-        alice = self.make_participant('alice', last_bill_result="Fail!")
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result="Fail!")
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '3.00')
 
@@ -599,6 +603,7 @@ def test_gnob_ignores_backers_with_a_failing_card_on_file(self):
 
     def test_gnob_includes_whitelisted_backers(self):
         alice = self.make_participant( 'alice'
+                                     , claimed_time='now'
                                      , last_bill_result=''
                                      , is_suspicious=False
                                       )
@@ -610,6 +615,7 @@ def test_gnob_includes_whitelisted_backers(self):
 
     def test_gnob_includes_unreviewed_backers(self):
         alice = self.make_participant( 'alice'
+                                     , claimed_time='now'
                                      , last_bill_result=''
                                      , is_suspicious=None
                                       )
@@ -621,6 +627,7 @@ def test_gnob_includes_unreviewed_backers(self):
 
     def test_gnob_ignores_blacklisted_backers(self):
         alice = self.make_participant( 'alice'
+                                     , claimed_time='now'
                                      , last_bill_result=''
                                      , is_suspicious=True
                                       )
@@ -632,7 +639,7 @@ def test_gnob_ignores_blacklisted_backers(self):
 
 
     def test_gnob_ignores_backers_where_tip_is_zero(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
         alice.set_tip_to(bob, '0.00')
 
@@ -640,7 +647,7 @@ def test_gnob_ignores_backers_where_tip_is_zero(self):
         assert actual == 0
 
     def test_gnob_looks_at_latest_tip_only(self):
-        alice = self.make_participant('alice', last_bill_result='')
+        alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
         bob = self.make_participant('bob')
 
         alice.set_tip_to(bob, '1.00')
@@ -702,7 +709,7 @@ def test_ru_returns_openstreetmap_url_for_stub_from_openstreetmap(self):
 
     def test_archive_fails_if_ctr_not_run(self):
         alice = self.make_participant('alice')
-        self.make_participant('bob').set_tip_to(alice, Decimal('1.00'))
+        self.make_participant('bob', claimed_time='now').set_tip_to(alice, Decimal('1.00'))
         with self.db.get_cursor() as cursor:
             pytest.raises(alice.StillReceivingTips, alice.archive, cursor)
 
diff --git a/tests/py/test_stats.py b/tests/py/test_stats.py
--- a/tests/py/test_stats.py
+++ b/tests/py/test_stats.py
@@ -35,7 +35,7 @@ class TestChartOfReceiving(Harness):
     def setUp(self):
         Harness.setUp(self)
         for participant in ['alice', 'bob']:
-            p = self.make_participant(participant, last_bill_result='')
+            p = self.make_participant(participant, claimed_time='now', last_bill_result='')
             setattr(self, participant, p)
 
     def test_get_tip_distribution_handles_a_tip(self):
@@ -51,7 +51,7 @@ def test_get_tip_distribution_handles_no_tips(self):
         assert actual == expected
 
     def test_get_tip_distribution_handles_multiple_tips(self):
-        carl = self.make_participant('carl', last_bill_result='')
+        carl = self.make_participant('carl', claimed_time='now', last_bill_result='')
         self.alice.set_tip_to(self.bob, '1.00')
         carl.set_tip_to(self.bob, '3.00')
         expected = ([
@@ -63,7 +63,7 @@ def test_get_tip_distribution_handles_multiple_tips(self):
 
     def test_get_tip_distribution_handles_big_tips(self):
         self.bob.update_number('plural')
-        carl = self.make_participant('carl', last_bill_result='')
+        carl = self.make_participant('carl', claimed_time='now', last_bill_result='')
         self.alice.set_tip_to(self.bob, '200.00')
         carl.set_tip_to(self.bob, '300.00')
         expected = ([
@@ -74,7 +74,7 @@ def test_get_tip_distribution_handles_big_tips(self):
         assert actual == expected
 
     def test_get_tip_distribution_ignores_bad_cc(self):
-        bad_cc = self.make_participant('bad_cc', last_bill_result='Failure!')
+        bad_cc = self.make_participant('bad_cc', claimed_time='now', last_bill_result='Failure!')
         self.alice.set_tip_to(self.bob, '1.00')
         bad_cc.set_tip_to(self.bob, '3.00')
         expected = ([[Decimal('1.00'), 1L, Decimal('1.00'), 1, Decimal('1')]],
@@ -83,7 +83,7 @@ def test_get_tip_distribution_ignores_bad_cc(self):
         assert actual == expected
 
     def test_get_tip_distribution_ignores_missing_cc(self):
-        missing_cc = self.make_participant('missing_cc', last_bill_result=None)
+        missing_cc = self.make_participant('missing_cc', claimed_time='now', last_bill_result=None)
         self.alice.set_tip_to(self.bob, '1.00')
         missing_cc.set_tip_to(self.bob, '3.00')
         expected = ([[Decimal('1.00'), 1L, Decimal('1.00'), 1, Decimal('1')]],
diff --git a/tests/py/test_take.py b/tests/py/test_take.py
--- a/tests/py/test_take.py
+++ b/tests/py/test_take.py
@@ -14,7 +14,10 @@ class Tests(Harness):
     def make_team(self, username=TEAM, **kw):
         team = self.make_participant(username, number='plural', **kw)
         if Participant.from_username('Daddy Warbucks') is None:
-            warbucks = self.make_participant('Daddy Warbucks', last_bill_result='')
+            warbucks = self.make_participant( 'Daddy Warbucks'
+                                            , claimed_time='now'
+                                            , last_bill_result=''
+                                             )
             self.warbucks = warbucks
         self.warbucks.set_tip_to(team, '100')
         return team
diff --git a/tests/py/test_tip_json.py b/tests/py/test_tip_json.py
--- a/tests/py/test_tip_json.py
+++ b/tests/py/test_tip_json.py
@@ -16,7 +16,7 @@ def test_get_amount_and_total_back_from_api(self):
         now = utcnow()
         self.make_participant("test_tippee1", claimed_time=now)
         self.make_participant("test_tippee2", claimed_time=now)
-        self.make_participant("test_tipper")
+        self.make_participant("test_tipper", claimed_time=now)
 
         # Then, add a $1.50 and $3.00 tip
         response1 = self.client.POST( "/test_tippee1/tip.json"