def testCountryRegionBlacklistFilterPrize(self): # Somewhat ethnocentric testing country = models.Country.objects.all()[0] prize = models.Prize.objects.create(event=self.event) donors = [] allowedState = 'StateOne' disallowedState = 'StateTwo' for state in [allowedState, disallowedState]: donor = randgen.generate_donor(self.rand) donor.addresscountry = country donor.addressstate = state donor.save() donors.append(donor) randgen.generate_donation( self.rand, event=self.event, donor=donor, minAmount=Decimal(prize.minimumbid)).save() eligible = prize.eligible_donors() self.assertEqual(2, len(eligible)) # Test a different country set countryRegion = models.CountryRegion.objects.create( country=country, name=disallowedState) prize.disallowed_prize_regions.add(countryRegion) prize.custom_country_filter = True prize.save() eligible = prize.eligible_donors() self.assertEqual(1, len(eligible))
def test_draw_prize_multiple_donors_norandom_sum(self): startRun = self.runsList[5] endRun = self.runsList[9] prize = randgen.generate_prize( self.rand, event=self.event, sumDonations=True, randomDraw=False, startRun=startRun, endRun=endRun) prize.save() donationDonors = {} for donor in self.donorList: numDonations = self.rand.getrandbits(4) redHerrings = self.rand.getrandbits(4) donationDonors[donor.id] = { 'donor': donor, 'amount': Decimal('0.00')} for i in range(0, numDonations): donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal( '0.01'), maxAmount=Decimal('100.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() donationDonors[donor.id]['amount'] += donation.amount # toss in a few extras to keep the drawer on its toes for i in range(0, redHerrings): donation = None if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal( '1000.01'), maxAmount=Decimal('2000.00'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) else: donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal( '1000.01'), maxAmount=prize.minimumbid - Decimal('2000.00'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation.save() maxDonor = max(donationDonors.items(), key=lambda x: x[1]['amount'])[1] eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(maxDonor['donor'].id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(maxDonor['amount'], eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(maxDonor['donor'].id, prize.get_winner().id) oldMaxDonor = maxDonor del donationDonors[oldMaxDonor['donor'].id] maxDonor = max(donationDonors.items(), key=lambda x: x[1]['amount'])[1] diff = oldMaxDonor['amount'] - maxDonor['amount'] newDonor = maxDonor['donor'] newDonation = randgen.generate_donation(self.rand, donor=newDonor, event=self.event, minAmount=diff + Decimal( '0.01'), maxAmount=diff + Decimal('100.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) newDonation.save() maxDonor['amount'] += newDonation.amount prize = models.Prize.objects.get(id=prize.id) eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(maxDonor['donor'].id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(maxDonor['amount'], eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(maxDonor['donor'].id, prize.get_winner().id)
def testCountryRegionBlacklistFilterPrize(self): # Somewhat ethnocentric testing country = models.Country.objects.all()[0] prize = models.Prize.objects.create(event=self.event) donors = [] allowedState = 'StateOne' disallowedState = 'StateTwo' for state in [allowedState, disallowedState]: donor = randgen.generate_donor(self.rand) donor.addresscountry = country donor.addressstate = state donor.save() donors.append(donor) randgen.generate_donation(self.rand, event=self.event, donor=donor, minAmount=Decimal( prize.minimumbid)).save() eligible = prize.eligible_donors() self.assertEqual(2, len(eligible)) # Test a different country set countryRegion = models.CountryRegion.objects.create( country=country, name=disallowedState) prize.disallowed_prize_regions.add(countryRegion) prize.custom_country_filter = True prize.save() eligible = prize.eligible_donors() self.assertEqual(1, len(eligible))
def test_decline_prize_single(self): amount = Decimal('50.0') targetPrize = randgen.generate_prize(self.rand,event=self.event,sumDonations=False,randomDraw=False,minAmount=amount,maxAmount=amount,maxwinners=1) targetPrize.save() self.assertEqual(0, len(targetPrize.eligible_donors())) donorA = randgen.generate_donor(self.rand) donorA.save() donorB = randgen.generate_donor(self.rand) donorB.save() donationA = randgen.generate_donation(self.rand,donor=donorA,minAmount=amount,maxAmount=amount,event=self.event) donationA.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(donorA.id, targetPrize.eligible_donors()[0]['donor']) viewutil.draw_prize(targetPrize) self.assertEqual(donorA, targetPrize.get_winner()) self.assertEqual(0, len(targetPrize.eligible_donors())) donationB = randgen.generate_donation(self.rand,donor=donorB,minAmount=amount,maxAmount=amount,event=self.event) donationB.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(donorB.id, targetPrize.eligible_donors()[0]['donor']) prizeWinnerEntry = targetPrize.prizewinner_set.filter(winner=donorA)[0] prizeWinnerEntry.acceptstate = 'DECLINED'; prizeWinnerEntry.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(donorB.id, targetPrize.eligible_donors()[0]['donor']) viewutil.draw_prize(targetPrize) self.assertEqual(donorB, targetPrize.get_winner()) self.assertEqual(1, len(targetPrize.get_winners())) self.assertEqual(0, len(targetPrize.eligible_donors()))
def test_draw_prize_multiple_donors_random_sum(self): startRun = self.runsList[41] endRun = self.runsList[46] prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=True, randomDraw=True, startRun=startRun, endRun=endRun) prize.save() donationDonors = {} for donor in self.donorList: numDonations = self.rand.getrandbits(4) redHerrings = self.rand.getrandbits(4) donationDonors[donor.id] = { 'donor': donor, 'amount': Decimal('0.00') } for i in range(0, numDonations): donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=prize.minimumbid - Decimal('0.10'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() donationDonors[donor.id]['amount'] += donation.amount # toss in a few extras to keep the drawer on its toes for i in range(0, redHerrings): donation = None if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=prize.minimumbid - Decimal('0.10'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) else: donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=prize.minimumbid - Decimal('0.10'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation.save() if donationDonors[donor.id]['amount'] < prize.minimumbid: del donationDonors[donor.id] eligibleDonors = prize.eligible_donors() self.assertEqual(len(donationDonors.keys()), len(eligibleDonors)) for eligibleDonor in eligibleDonors: found = False if eligibleDonor['donor'] in donationDonors: entry = donationDonors[eligibleDonor['donor']] donor = entry['donor'] if entry['amount'] >= prize.minimumbid: donations = donor.donation_set.filter(timereceived__gte=prize.start_draw_time(), timereceived__lte=prize.end_draw_time()) countAmount = Decimal('0.00') for donation in donations: countAmount += donation.amount self.assertEqual(entry['amount'], eligibleDonor['amount']) self.assertEqual(countAmount, eligibleDonor['amount']) self.assertAlmostEqual(min(prize.maximumbid / prize.minimumbid, entry['amount'] / prize.minimumbid), Decimal(eligibleDonor['weight'])) found = True self.assertTrue(found and "Could not find the donor in the list") winners = [] for seed in [51234, 235426, 62363245]: result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertIn(prize.get_winner().id, donationDonors) winners.append(prize.get_winner()) current = prize.get_winner() prize.prizewinner_set.all().delete() prize.save() result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(current, prize.get_winner()) prize.prizewinner_set.all().delete() prize.save() self.assertNotEqual(winners[0], winners[1]) self.assertNotEqual(winners[1], winners[2]) self.assertNotEqual(winners[0], winners[2]) return
def test_draw_prize_multiple_donors_norandom_nosum(self): startRun = self.runsList[25] endRun = self.runsList[34] prize = randgen.generate_prize( self.rand, event=self.event, sumDonations=False, randomDraw=False, startRun=startRun, endRun=endRun) prize.save() largestDonor = None largestAmount = Decimal('0.00') for donor in self.donorList: numDonations = self.rand.getrandbits(4) redHerrings = self.rand.getrandbits(4) for i in range(0, numDonations): donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal( '0.01'), maxAmount=Decimal('1000.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() if donation.amount > largestAmount: largestDonor = donor largestAmount = donation.amount # toss in a few extras to keep the drawer on its toes for i in range(0, redHerrings): donation = None if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal( '1000.01'), maxAmount=Decimal('2000.00'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) else: donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=Decimal( '1000.01'), maxAmount=prize.minimumbid - Decimal('2000.00'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation.save() eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(largestDonor.id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(largestAmount, eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(largestDonor.id, prize.get_winner().id) newDonor = randgen.generate_donor(self.rand) newDonor.save() newDonation = randgen.generate_donation(self.rand, donor=newDonor, event=self.event, minAmount=Decimal( '1000.01'), maxAmount=Decimal('2000.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) newDonation.save() eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(newDonor.id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(newDonation.amount, eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(newDonor.id, prize.get_winner().id)
def testCountryFilterPrize(self): # TODO: fix this so either there's less boilerplate, or the boilerplate is shared countries = list(models.Country.objects.all()[0:4]) prize = models.Prize.objects.create(event=self.event) for country in countries[0:3]: self.event.allowed_prize_countries.add(country) self.event.save() prize.allowed_prize_countries.add(countries[0]) prize.allowed_prize_countries.add(countries[1]) prize.save() donors = [] for country in countries: donor = randgen.generate_donor(self.rand) donor.addresscountry = country donor.save() donors.append(donor) randgen.generate_donation(self.rand, event=self.event, donor=donor, minAmount=Decimal( prize.minimumbid)).save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[2])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[3])) # by default don't use the prize filter eligible = prize.eligible_donors() self.assertEqual(3, len(eligible)) prize.custom_country_filter = True prize.save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(2, len(eligible)) # Test a different country set prize.allowed_prize_countries.add(countries[3]) prize.save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(3, len(eligible)) # Test a blank country set prize.allowed_prize_countries.clear() prize.save() for donor in donors: self.assertTrue(prize.is_donor_allowed_to_receive(donor)) eligible = prize.eligible_donors() self.assertEqual(4, len(eligible))
def test_draw_prize_multiple_donors_random_nosum(self): startRun = self.runsList[28] endRun = self.runsList[30] prize = randgen.generate_prize( self.rand, event=self.event, sumDonations=False, randomDraw=True, startRun=startRun, endRun=endRun) prize.save() donationDonors = {} for donor in self.donorList: if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid + Decimal('100.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() donationDonors[donor.id] = donor # Add a few red herrings to make sure out of range donations aren't # used donation2 = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid + Decimal('100.00'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) donation2.save() donation3 = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid + Decimal('100.00'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation3.save() eligibleDonors = prize.eligible_donors() self.assertEqual(len(donationDonors.keys()), len(eligibleDonors)) for eligibleDonor in eligibleDonors: found = False if eligibleDonor['donor'] in donationDonors: donor = donationDonors[eligibleDonor['donor']] donation = donor.donation_set.filter(timereceived__gte=prize.start_draw_time( ), timereceived__lte=prize.end_draw_time())[0] self.assertEqual(donation.amount, eligibleDonor['amount']) self.assertEqual(1.0, eligibleDonor['weight']) found = True self.assertTrue(found and "Could not find the donor in the list") winners = [] for seed in [15634, 12512, 666]: result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertIn(prize.get_winner().id, donationDonors) winners.append(prize.get_winner()) current = prize.get_winner() prize.prizewinner_set.all().delete() prize.save() result, message = viewutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(current, prize.get_winner()) prize.prizewinner_set.all().delete() prize.save() self.assertNotEqual(winners[0], winners[1]) self.assertNotEqual(winners[1], winners[2]) self.assertNotEqual(winners[0], winners[2]) return
def testCountryFilterPrize(self): # TODO: fix this so either there's less boilerplate, or the boilerplate is shared countries = list(models.Country.objects.all()[0:4]) prize = models.Prize.objects.create(event=self.event) for country in countries[0:3]: self.event.allowed_prize_countries.add(country) self.event.save() prize.allowed_prize_countries.add(countries[0]) prize.allowed_prize_countries.add(countries[1]) prize.save() donors = [] for country in countries: donor = randgen.generate_donor(self.rand) donor.addresscountry = country donor.save() donors.append(donor) randgen.generate_donation( self.rand, event=self.event, donor=donor, minAmount=Decimal(prize.minimumbid)).save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[2])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[3])) # by default don't use the prize filter eligible = prize.eligible_donors() self.assertEqual(3, len(eligible)) prize.custom_country_filter = True prize.save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(2, len(eligible)) # Test a different country set prize.allowed_prize_countries.add(countries[3]) prize.save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(3, len(eligible)) # Test a blank country set prize.allowed_prize_countries.clear() prize.save() for donor in donors: self.assertTrue(prize.is_donor_allowed_to_receive(donor)) eligible = prize.eligible_donors() self.assertEqual(4, len(eligible))
def test_correct_prize_amount_with_split_tickets(self): prize0 = randgen.generate_prize( self.rand, event=self.event, sumDonations=True, randomDraw=True, ticketDraw=True) prize0.maximumbid = None prize0.save() prize1 = randgen.generate_prize( self.rand, event=self.event, sumDonations=True, randomDraw=True, ticketDraw=True) prize1.maximumbid = None prize1.save() donor = self.donorList[0] donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=prize0.minimumbid + prize1.minimumbid) donation.save() prize0Eligible = prize0.eligible_donors() self.assertEqual(0, len(prize0Eligible)) prize1Eligible = prize1.eligible_donors() self.assertEqual(0, len(prize1Eligible)) models.PrizeTicket.objects.create( donation=donation, prize=prize0, amount=donation.amount * Decimal('2.0')) models.PrizeTicket.objects.create( donation=donation, prize=prize1, amount=donation.amount * Decimal('2.0')) prize0Eligible = prize0.eligible_donors() self.assertEqual(1, len(prize0Eligible)) prize1Eligible = prize1.eligible_donors() self.assertEqual(1, len(prize1Eligible))
def test_draw_prize_with_tickets(self): prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=True, randomDraw=True, ticketDraw=True) prize.maximumbid = None prize.save() donor = self.donorList[0] donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid, minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() models.PrizeTicket.objects.create(donation=donation, prize=prize, amount=donation.amount) eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(eligibleDonors[0]['donor'], donor.id) result, message = prizeutil.draw_prize(prize) self.assertTrue(result) self.assertEqual(donor, prize.get_winner())
def test_accept_deadline_offset(self): # 10 days in the future self.event.prize_accept_deadline_delta = 10 # TODO: it should not take this much set-up to draw a single donor to a single prize amount = Decimal('50.0') targetPrize = randgen.generate_prize( self.rand, event=self.event, sumDonations=False, randomDraw=False, minAmount=amount, maxAmount=amount, maxwinners=1) targetPrize.save() winner = randgen.generate_donor(self.rand) winner.save() winningDonation = randgen.generate_donation( self.rand, donor=winner, minAmount=amount, maxAmount=amount, event=self.event) winningDonation.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(winner.id, targetPrize.eligible_donors()[0]['donor']) self.assertEqual( 0, len(prizeutil.get_past_due_prize_winners(self.event))) currentDate = datetime.date.today() result, status = prizeutil.draw_prize(targetPrize) prizeWin = models.PrizeWinner.objects.get(prize=targetPrize) self.assertEqual(prizeWin.accept_deadline_date(), currentDate + datetime.timedelta(days=self.event.prize_accept_deadline_delta)) prizeWin.acceptdeadline = datetime.datetime.utcnow().replace( tzinfo=pytz.utc) - datetime.timedelta(days=2) prizeWin.save() self.assertEqual(0, len(targetPrize.eligible_donors())) pastDue = prizeutil.get_past_due_prize_winners(self.event) self.assertEqual( 1, len(prizeutil.get_past_due_prize_winners(self.event))) self.assertEqual(prizeWin, pastDue[0])
def test_draw_prize_with_tickets_multiple_donors(self): prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=True, randomDraw=True, ticketDraw=True) prize.maximumbid = None prize.save() donor = self.donorList[0] donation = randgen.generate_donation(self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid, minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() tracker.models.PrizeTicket.objects.create(donation=donation, prize=prize, amount=donation.amount) donor2 = self.donorList[1] donation2 = randgen.generate_donation(self.rand, donor=donor2, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid, minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation2.save() eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(eligibleDonors[0]['donor'], donor.id) self.assertAlmostEqual(eligibleDonors[0]['weight'], donation.amount / prize.minimumbid) result, message = viewutil.draw_prize(prize) self.assertTrue(result) self.assertEqual(donor, prize.get_winner())
def test_decline_prize_single(self): amount = Decimal('50.0') targetPrize = randgen.generate_prize(self.rand, event=self.event, sumDonations=False, randomDraw=False, minAmount=amount, maxAmount=amount, maxwinners=1) targetPrize.save() self.assertEqual(0, len(targetPrize.eligible_donors())) donorA = randgen.generate_donor(self.rand) donorA.save() donorB = randgen.generate_donor(self.rand) donorB.save() donationA = randgen.generate_donation(self.rand, donor=donorA, minAmount=amount, maxAmount=amount, event=self.event) donationA.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(donorA.id, targetPrize.eligible_donors()[0]['donor']) prizeutil.draw_prize(targetPrize) self.assertEqual(donorA, targetPrize.get_winner()) self.assertEqual(0, len(targetPrize.eligible_donors())) donationB = randgen.generate_donation(self.rand, donor=donorB, minAmount=amount, maxAmount=amount, event=self.event) donationB.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(donorB.id, targetPrize.eligible_donors()[0]['donor']) prizeWinnerEntry = targetPrize.prizewinner_set.filter(winner=donorA)[0] prizeWinnerEntry.pendingcount = 0 prizeWinnerEntry.declinecount = 1 prizeWinnerEntry.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(donorB.id, targetPrize.eligible_donors()[0]['donor']) prizeutil.draw_prize(targetPrize) self.assertEqual(donorB, targetPrize.get_winner()) self.assertEqual(1, targetPrize.current_win_count()) self.assertEqual(0, len(targetPrize.eligible_donors()))
def test_draw_prize_one_donor(self): startRun = self.runsList[14] endRun = self.runsList[28] for useRandom in [True, False]: for useSum in [True, False]: for donationSize in ['top', 'bottom', 'above', 'below', 'within']: prize = randgen.generate_prize( self.rand, event=self.event, sumDonations=useSum, randomDraw=useRandom, startRun=startRun, endRun=endRun) prize.save() donor = randgen.pick_random_element( self.rand, self.donorList) donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) if donationSize == 'above': donation.amount = prize.maximumbid + Decimal('5.00') elif donationSize == 'top': donation.amount = prize.maximumbid elif donationSize == 'within': donation.amount = randgen.random_amount( self.rand, rounded=False, minAmount=prize.minimumbid, maxAmount=prize.maximumbid) elif donationSize == 'bottom': donation.amount = prize.minimumbid elif donationSize == 'below': donation.amount = max( Decimal('0.00'), prize.minimumbid - Decimal('5.00')) donation.save() eligibleDonors = prize.eligible_donors() if donationSize == 'below' and prize.randomdraw: self.assertEqual(0, len(eligibleDonors)) else: self.assertEqual(1, len(eligibleDonors)) self.assertEqual(donor.id, eligibleDonors[0]['donor']) self.assertEqual( donation.amount, eligibleDonors[0]['amount']) if prize.sumdonations and prize.randomdraw: if donationSize == 'top' or donationSize == 'above': expectedRatio = float( prize.maximumbid / prize.minimumbid) else: expectedRatio = float( donation.amount / prize.minimumbid) self.assertAlmostEqual( expectedRatio, eligibleDonors[0]['weight']) else: self.assertEqual(1.0, eligibleDonors[0]['weight']) result, message = viewutil.draw_prize(prize) if donationSize != 'below' or not prize.randomdraw: self.assertTrue(result) self.assertEqual(donor, prize.get_winner()) else: self.assertFalse(result) self.assertEqual(None, prize.get_winner()) donation.delete() prize.prizewinner_set.all().delete() prize.delete() return
def testCountryFilterEvent(self): countries = list(models.Country.objects.all()[0:4]) self.event.allowed_prize_countries.add(countries[0]) self.event.allowed_prize_countries.add(countries[1]) self.event.save() prize = models.Prize.objects.create(event=self.event) donors = [] for country in countries: donor = randgen.generate_donor(self.rand) donor.addresscountry = country donor.save() donors.append(donor) randgen.generate_donation(self.rand, event=self.event, donor=donor, minAmount=Decimal( prize.minimumbid)).save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(2, len(eligible)) # Test a different country set self.event.allowed_prize_countries.add(countries[3]) self.event.save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(3, len(eligible)) # Test a blank country set self.event.allowed_prize_countries.clear() self.event.save() for donor in donors: self.assertTrue(prize.is_donor_allowed_to_receive(donor)) eligible = prize.eligible_donors() self.assertEqual(4, len(eligible))
def testCountryFilterEvent(self): countries = list(models.Country.objects.all()[0:4]) self.event.allowed_prize_countries.add(countries[0]) self.event.allowed_prize_countries.add(countries[1]) self.event.save() prize = models.Prize.objects.create(event=self.event) donors = [] for country in countries: donor = randgen.generate_donor(self.rand) donor.addresscountry = country donor.save() donors.append(donor) randgen.generate_donation( self.rand, event=self.event, donor=donor, minAmount=Decimal(prize.minimumbid)).save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(2, len(eligible)) # Test a different country set self.event.allowed_prize_countries.add(countries[3]) self.event.save() self.assertTrue(prize.is_donor_allowed_to_receive(donors[0])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[1])) self.assertFalse(prize.is_donor_allowed_to_receive(donors[2])) self.assertTrue(prize.is_donor_allowed_to_receive(donors[3])) eligible = prize.eligible_donors() self.assertEqual(3, len(eligible)) # Test a blank country set self.event.allowed_prize_countries.clear() self.event.save() for donor in donors: self.assertTrue(prize.is_donor_allowed_to_receive(donor)) eligible = prize.eligible_donors() self.assertEqual(4, len(eligible))
def test_accept_deadline_offset(self): # 10 days in the future self.event.prize_accept_deadline_delta = 10 # TODO: it should not take this much set-up to draw a single donor to a single prize amount = Decimal('50.0') targetPrize = randgen.generate_prize(self.rand, event=self.event, sumDonations=False, randomDraw=False, minAmount=amount, maxAmount=amount, maxwinners=1) targetPrize.save() winner = randgen.generate_donor(self.rand) winner.save() winningDonation = randgen.generate_donation(self.rand, donor=winner, minAmount=amount, maxAmount=amount, event=self.event) winningDonation.save() self.assertEqual(1, len(targetPrize.eligible_donors())) self.assertEqual(winner.id, targetPrize.eligible_donors()[0]['donor']) self.assertEqual(0, len(prizeutil.get_past_due_prize_winners(self.event))) currentDate = datetime.date.today() result, status = prizeutil.draw_prize(targetPrize) prizeWin = models.PrizeWinner.objects.get(prize=targetPrize) self.assertEqual( prizeWin.accept_deadline_date(), currentDate + datetime.timedelta(days=self.event.prize_accept_deadline_delta)) prizeWin.acceptdeadline = datetime.datetime.utcnow().replace( tzinfo=pytz.utc) - datetime.timedelta(days=2) prizeWin.save() self.assertEqual(0, len(targetPrize.eligible_donors())) pastDue = prizeutil.get_past_due_prize_winners(self.event) self.assertEqual(1, len(prizeutil.get_past_due_prize_winners(self.event))) self.assertEqual(prizeWin, pastDue[0])
def test_draw_prize_one_donor(self): startRun = self.runsList[14] endRun = self.runsList[28] for useRandom in [True, False]: for useSum in [True, False]: for donationSize in [ 'top', 'bottom', 'above', 'below', 'within' ]: prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=useSum, randomDraw=useRandom, startRun=startRun, endRun=endRun) prize.save() donor = randgen.pick_random_element( self.rand, self.donorList) donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) if donationSize == 'above': donation.amount = prize.maximumbid + Decimal('5.00') elif donationSize == 'top': donation.amount = prize.maximumbid elif donationSize == 'within': donation.amount = randgen.random_amount( self.rand, rounded=False, minAmount=prize.minimumbid, maxAmount=prize.maximumbid) elif donationSize == 'bottom': donation.amount = prize.minimumbid elif donationSize == 'below': donation.amount = max( Decimal('0.00'), prize.minimumbid - Decimal('5.00')) donation.save() eligibleDonors = prize.eligible_donors() if donationSize == 'below' and prize.randomdraw: self.assertEqual(0, len(eligibleDonors)) else: self.assertEqual(1, len(eligibleDonors)) self.assertEqual(donor.id, eligibleDonors[0]['donor']) self.assertEqual(donation.amount, eligibleDonors[0]['amount']) if prize.sumdonations and prize.randomdraw: if donationSize == 'top' or donationSize == 'above': expectedRatio = float(prize.maximumbid / prize.minimumbid) else: expectedRatio = float(donation.amount / prize.minimumbid) self.assertAlmostEqual(expectedRatio, eligibleDonors[0]['weight']) else: self.assertEqual(1.0, eligibleDonors[0]['weight']) result, message = prizeutil.draw_prize(prize) if donationSize != 'below' or not prize.randomdraw: self.assertTrue(result) self.assertEqual(donor, prize.get_winner()) else: self.assertFalse(result) self.assertEqual(None, prize.get_winner()) donation.delete() prize.prizewinner_set.all().delete() prize.delete()
def test_draw_prize_multiple_donors_random_nosum(self): startRun = self.runsList[28] endRun = self.runsList[30] prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=False, randomDraw=True, startRun=startRun, endRun=endRun) prize.save() donationDonors = {} for donor in self.donorList: if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid + Decimal('100.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() donationDonors[donor.id] = donor # Add a few red herrings to make sure out of range donations aren't # used donation2 = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid + Decimal('100.00'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) donation2.save() donation3 = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=prize.minimumbid, maxAmount=prize.minimumbid + Decimal('100.00'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation3.save() eligibleDonors = prize.eligible_donors() self.assertEqual(len(donationDonors.keys()), len(eligibleDonors)) for eligibleDonor in eligibleDonors: found = False if eligibleDonor['donor'] in donationDonors: donor = donationDonors[eligibleDonor['donor']] donation = donor.donation_set.filter( timereceived__gte=prize.start_draw_time(), timereceived__lte=prize.end_draw_time())[0] self.assertEqual(donation.amount, eligibleDonor['amount']) self.assertEqual(1.0, eligibleDonor['weight']) found = True self.assertTrue(found and "Could not find the donor in the list") winners = [] for seed in [15634, 12512, 666]: result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertIn(prize.get_winner().id, donationDonors) winners.append(prize.get_winner()) current = prize.get_winner() prize.prizewinner_set.all().delete() prize.save() result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(current, prize.get_winner()) prize.prizewinner_set.all().delete() prize.save() self.assertNotEqual(winners[0], winners[1]) self.assertNotEqual(winners[1], winners[2]) self.assertNotEqual(winners[0], winners[2])
def test_draw_prize_multiple_donors_random_sum(self): startRun = self.runsList[41] endRun = self.runsList[46] prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=True, randomDraw=True, startRun=startRun, endRun=endRun) prize.save() donationDonors = {} for donor in self.donorList: numDonations = self.rand.getrandbits(4) redHerrings = self.rand.getrandbits(4) donationDonors[donor.id] = { 'donor': donor, 'amount': Decimal('0.00') } for i in range(0, numDonations): donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=prize.minimumbid - Decimal('0.10'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() donationDonors[donor.id]['amount'] += donation.amount # toss in a few extras to keep the drawer on its toes for i in range(0, redHerrings): donation = None if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=prize.minimumbid - Decimal('0.10'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) else: donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=prize.minimumbid - Decimal('0.10'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation.save() if donationDonors[donor.id]['amount'] < prize.minimumbid: del donationDonors[donor.id] eligibleDonors = prize.eligible_donors() self.assertEqual(len(donationDonors.keys()), len(eligibleDonors)) for eligibleDonor in eligibleDonors: found = False if eligibleDonor['donor'] in donationDonors: entry = donationDonors[eligibleDonor['donor']] donor = entry['donor'] if entry['amount'] >= prize.minimumbid: donations = donor.donation_set.filter( timereceived__gte=prize.start_draw_time(), timereceived__lte=prize.end_draw_time()) countAmount = Decimal('0.00') for donation in donations: countAmount += donation.amount self.assertEqual(entry['amount'], eligibleDonor['amount']) self.assertEqual(countAmount, eligibleDonor['amount']) self.assertAlmostEqual( min(prize.maximumbid / prize.minimumbid, entry['amount'] / prize.minimumbid), Decimal(eligibleDonor['weight'])) found = True self.assertTrue(found and "Could not find the donor in the list") winners = [] for seed in [51234, 235426, 62363245]: result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertIn(prize.get_winner().id, donationDonors) winners.append(prize.get_winner()) current = prize.get_winner() prize.prizewinner_set.all().delete() prize.save() result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(current, prize.get_winner()) prize.prizewinner_set.all().delete() prize.save() self.assertNotEqual(winners[0], winners[1]) self.assertNotEqual(winners[1], winners[2]) self.assertNotEqual(winners[0], winners[2])
def test_draw_prize_multiple_donors_norandom_nosum(self): startRun = self.runsList[25] endRun = self.runsList[34] prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=False, randomDraw=False, startRun=startRun, endRun=endRun) prize.save() largestDonor = None largestAmount = Decimal('0.00') for donor in self.donorList: numDonations = self.rand.getrandbits(4) redHerrings = self.rand.getrandbits(4) for i in range(0, numDonations): donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=Decimal('1000.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() if donation.amount > largestAmount: largestDonor = donor largestAmount = donation.amount # toss in a few extras to keep the drawer on its toes for i in range(0, redHerrings): donation = None if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('1000.01'), maxAmount=Decimal('2000.00'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) else: donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('1000.01'), maxAmount=prize.minimumbid - Decimal('2000.00'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation.save() eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(largestDonor.id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(largestAmount, eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(largestDonor.id, prize.get_winner().id) newDonor = randgen.generate_donor(self.rand) newDonor.save() newDonation = randgen.generate_donation( self.rand, donor=newDonor, event=self.event, minAmount=Decimal('1000.01'), maxAmount=Decimal('2000.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) newDonation.save() eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(newDonor.id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(newDonation.amount, eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(newDonor.id, prize.get_winner().id)
def test_draw_prize_multiple_donors_norandom_sum(self): startRun = self.runsList[5] endRun = self.runsList[9] prize = randgen.generate_prize(self.rand, event=self.event, sumDonations=True, randomDraw=False, startRun=startRun, endRun=endRun) prize.save() donationDonors = {} for donor in self.donorList: numDonations = self.rand.getrandbits(4) redHerrings = self.rand.getrandbits(4) donationDonors[donor.id] = { 'donor': donor, 'amount': Decimal('0.00') } for i in range(0, numDonations): donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('0.01'), maxAmount=Decimal('100.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) donation.save() donationDonors[donor.id]['amount'] += donation.amount # toss in a few extras to keep the drawer on its toes for i in range(0, redHerrings): donation = None if self.rand.getrandbits(1) == 0: donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('1000.01'), maxAmount=Decimal('2000.00'), maxTime=prize.start_draw_time() - datetime.timedelta(seconds=1)) else: donation = randgen.generate_donation( self.rand, donor=donor, event=self.event, minAmount=Decimal('1000.01'), maxAmount=prize.minimumbid - Decimal('2000.00'), minTime=prize.end_draw_time() + datetime.timedelta(seconds=1)) donation.save() maxDonor = max(donationDonors.items(), key=lambda x: x[1]['amount'])[1] eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(maxDonor['donor'].id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(maxDonor['amount'], eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(maxDonor['donor'].id, prize.get_winner().id) oldMaxDonor = maxDonor del donationDonors[oldMaxDonor['donor'].id] maxDonor = max(donationDonors.items(), key=lambda x: x[1]['amount'])[1] diff = oldMaxDonor['amount'] - maxDonor['amount'] newDonor = maxDonor['donor'] newDonation = randgen.generate_donation( self.rand, donor=newDonor, event=self.event, minAmount=diff + Decimal('0.01'), maxAmount=diff + Decimal('100.00'), minTime=prize.start_draw_time(), maxTime=prize.end_draw_time()) newDonation.save() maxDonor['amount'] += newDonation.amount prize = models.Prize.objects.get(id=prize.id) eligibleDonors = prize.eligible_donors() self.assertEqual(1, len(eligibleDonors)) self.assertEqual(maxDonor['donor'].id, eligibleDonors[0]['donor']) self.assertEqual(1.0, eligibleDonors[0]['weight']) self.assertEqual(maxDonor['amount'], eligibleDonors[0]['amount']) for seed in [9524, 373, 747]: prize.prizewinner_set.all().delete() prize.save() result, message = prizeutil.draw_prize(prize, seed) self.assertTrue(result) self.assertEqual(maxDonor['donor'].id, prize.get_winner().id)