Example #1
0
    def test_adding_donation_proportion_adds_payments_if_amount_set_first(
            self):
        self.da_repo.set_donation_amount(user=test_data.u1,
                                         amount_GBPennies=100)

        self.dp_repo.add_donation_proportion(
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c1,
                                   amount=2))
        expected = [
            Payment(user=test_data.u1,
                    charity=test_data.c1,
                    amount_GBPennies=100)
        ]

        self.assertEquals(
            self.payment_repo.get_next_expected_payments(user=test_data.u1),
            expected)

        self.dp_repo.add_donation_proportion(
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c2,
                                   amount=3))
        expected = [
            Payment(user=test_data.u1,
                    charity=test_data.c1,
                    amount_GBPennies=40),
            Payment(user=test_data.u1,
                    charity=test_data.c2,
                    amount_GBPennies=60),
        ]

        self.assertEquals(
            self.payment_repo.get_next_expected_payments(user=test_data.u1),
            expected)
Example #2
0
    def test_aggregates_charity_totals_across_users(self):
        self.setup_one_incoming_payment({test_data.u1: 250, test_data.u2: 75})

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c1,
                                   amount=100),
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c2,
                                   amount=150),
            DonationProportion.new(user=test_data.u2,
                                   charity=test_data.c1,
                                   amount=75),
        ])

        expected = set([
            OutgoingPayment(charity=test_data.c1,
                            amount_GBPennies=175,
                            status=OutgoingPaymentState.DISPLAYED),
            OutgoingPayment(charity=test_data.c2,
                            amount_GBPennies=150,
                            status=OutgoingPaymentState.DISPLAYED),
        ])

        self.assertEquals(self.payment_repo.get_pending_outgoing_payments(),
                          expected)
Example #3
0
    def test_only_generates_outgoing_payments_if_incoming_payments_received(
            self):
        self.setup_one_incoming_payment({test_data.u1: 250})
        self.setup_one_missing_payment({test_data.u2: 75})

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c1,
                                   amount=100),
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c2,
                                   amount=150),
            DonationProportion.new(user=test_data.u2,
                                   charity=test_data.c1,
                                   amount=75),
        ])

        expected = set([
            OutgoingPayment(charity=test_data.c1,
                            amount_GBPennies=100,
                            status=OutgoingPaymentState.DISPLAYED),
            OutgoingPayment(charity=test_data.c2,
                            amount_GBPennies=150,
                            status=OutgoingPaymentState.DISPLAYED),
        ])

        self.assertEquals(self.payment_repo.get_pending_outgoing_payments(),
                          expected)
Example #4
0
 def test_donation_proportions_are_isolated_per_user(self):
     self.add_donation_proportions([
         DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=1),
         DonationProportion.new(user=test_data.u1, charity=test_data.c2, amount=1),
         DonationProportion.new(user=test_data.u2, charity=test_data.c1, amount=1),
     ])
     self.assertEquals(0.5, self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c1))
Example #5
0
    def test_logs_and_notifies_incoming_and_outgoing_mismatches(self):
        self.setup_one_mismatched_incoming_payment({
            test_data.u1: (250, 249),
            test_data.u2: (250, 251),
            test_data.u4: (200, 200),
            test_data.u5: (75, 75),
        })
        self.setup_one_missing_payment({test_data.u3: 10})

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=100),
            DonationProportion.new(user=test_data.u1, charity=test_data.c2, amount=150),
            DonationProportion.new(user=test_data.u2, charity=test_data.c1, amount=250),
            DonationProportion.new(user=test_data.u3, charity=test_data.c1, amount=10),
            DonationProportion.new(user=test_data.u5, charity=test_data.c1, amount=75),
        ])

        amount_mismatch_notifier = AccumulatingMismatchNotifier()
        self.payment_repo.get_pending_outgoing_payments(amount_mismatch_notifiers=[amount_mismatch_notifier])

        expected = set([
            AmountMismatch(user=test_data.u1, incoming_GBPennies=249, outgoing=[
                OutgoingPayment(charity=test_data.c1, amount_GBPennies=100, status=OutgoingPaymentState.VALUE_MISMATCH),
                OutgoingPayment(charity=test_data.c2, amount_GBPennies=150, status=OutgoingPaymentState.VALUE_MISMATCH),
            ]),
            AmountMismatch(user=test_data.u2, incoming_GBPennies=251, outgoing=[OutgoingPayment(charity=test_data.c1, amount_GBPennies=250, status=OutgoingPaymentState.VALUE_MISMATCH)]),
            AmountMismatch(user=test_data.u3, incoming_GBPennies=0, outgoing=[OutgoingPayment(charity=test_data.c1, amount_GBPennies=10, status=OutgoingPaymentState.VALUE_MISMATCH)]),
            AmountMismatch(user=test_data.u4, incoming_GBPennies=200, outgoing=[]),
        ])

        self.assertEquals(amount_mismatch_notifier.accumulated, expected)
Example #6
0
    def test_updates_multiple_donations(self):
        dp = DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=1)
        self.dp_repo.add_donation_proportion(dp)
        self.assertSequenceEqual(self.dp_repo.get_donation_proportions(user=test_data.u1), [dp])

        dp2 = DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=2)
        self.dp_repo.add_donation_proportion(dp2)
        self.assertSequenceEqual(self.dp_repo.get_donation_proportions(user=test_data.u1), [dp2])
Example #7
0
    def test_can_add_donation_proportions(self):
        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=2),
            DonationProportion.new(user=test_data.u1, charity=test_data.c2, amount=6),
        ])

        self.assertEquals(0.25, self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c1))
        self.assertEquals(0.75, self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c2))
        self.assertEquals(0, self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c3))
Example #8
0
    def test_updates_multiple_donations(self):
        dp = DonationProportion.new(user=test_data.u1,
                                    charity=test_data.c1,
                                    amount=1)
        self.dp_repo.add_donation_proportion(dp)
        self.assertSequenceEqual(
            self.dp_repo.get_donation_proportions(user=test_data.u1), [dp])

        dp2 = DonationProportion.new(user=test_data.u1,
                                     charity=test_data.c1,
                                     amount=2)
        self.dp_repo.add_donation_proportion(dp2)
        self.assertSequenceEqual(
            self.dp_repo.get_donation_proportions(user=test_data.u1), [dp2])
Example #9
0
    def test_adding_donation_proportion_adds_payments_if_amount_set_first(self):
        self.da_repo.set_donation_amount(user=test_data.u1, amount_GBPennies=100)

        self.dp_repo.add_donation_proportion(DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=2))
        expected = [Payment(user=test_data.u1, charity=test_data.c1, amount_GBPennies=100)]

        self.assertEquals(self.payment_repo.get_next_expected_payments(user=test_data.u1), expected)

        self.dp_repo.add_donation_proportion(DonationProportion.new(user=test_data.u1, charity=test_data.c2, amount=3))
        expected = [
            Payment(user=test_data.u1, charity=test_data.c1, amount_GBPennies=40),
            Payment(user=test_data.u1, charity=test_data.c2, amount_GBPennies=60),
        ]

        self.assertEquals(self.payment_repo.get_next_expected_payments(user=test_data.u1), expected)
Example #10
0
 def test_donation_proportions_are_isolated_per_user(self):
     self.add_donation_proportions([
         DonationProportion.new(user=test_data.u1,
                                charity=test_data.c1,
                                amount=1),
         DonationProportion.new(user=test_data.u1,
                                charity=test_data.c2,
                                amount=1),
         DonationProportion.new(user=test_data.u2,
                                charity=test_data.c1,
                                amount=1),
     ])
     self.assertEquals(
         0.5,
         self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c1))
Example #11
0
    def test_only_generates_outgoing_payments_if_incoming_payments_received(self):
        self.setup_one_incoming_payment({test_data.u1: 250})
        self.setup_one_missing_payment({test_data.u2: 75})

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=100),
            DonationProportion.new(user=test_data.u1, charity=test_data.c2, amount=150),
            DonationProportion.new(user=test_data.u2, charity=test_data.c1, amount=75),
        ])

        expected = set([
            OutgoingPayment(charity=test_data.c1, amount_GBPennies=100, status=OutgoingPaymentState.DISPLAYED),
            OutgoingPayment(charity=test_data.c2, amount_GBPennies=150, status=OutgoingPaymentState.DISPLAYED),
        ])

        self.assertEquals(self.payment_repo.get_pending_outgoing_payments(), expected)
Example #12
0
    def test_generates_outgoing_payments_despite_mismatches(self):
        self.setup_one_incoming_payment({
            test_data.u1: 100,
            test_data.u2: 75,
        })

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c1,
                                   amount=100),
        ])

        expected = set([
            OutgoingPayment(charity=test_data.c1,
                            amount_GBPennies=100,
                            status=OutgoingPaymentState.DISPLAYED),
        ])
        expected_notifications = set([
            AmountMismatch(user=test_data.u2,
                           incoming_GBPennies=75,
                           outgoing=[]),
        ])

        amount_mismatch_notifier = AccumulatingMismatchNotifier()
        self.assertEquals(
            self.payment_repo.get_pending_outgoing_payments(
                amount_mismatch_notifiers=[amount_mismatch_notifier]),
            expected)
        self.assertEquals(amount_mismatch_notifier.accumulated,
                          expected_notifications)
Example #13
0
    def test_aggregates_charity_totals_across_users(self):
        self.setup_one_incoming_payment({
            test_data.u1: 250,
            test_data.u2: 75
        })

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=100),
            DonationProportion.new(user=test_data.u1, charity=test_data.c2, amount=150),
            DonationProportion.new(user=test_data.u2, charity=test_data.c1, amount=75),
        ])

        expected = set([
            OutgoingPayment(charity=test_data.c1, amount_GBPennies=175, status=OutgoingPaymentState.DISPLAYED),
            OutgoingPayment(charity=test_data.c2, amount_GBPennies=150, status=OutgoingPaymentState.DISPLAYED),
        ])

        self.assertEquals(self.payment_repo.get_pending_outgoing_payments(), expected)
Example #14
0
    def test_can_add_donation_proportions(self):
        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c1,
                                   amount=2),
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c2,
                                   amount=6),
        ])

        self.assertEquals(
            0.25,
            self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c1))
        self.assertEquals(
            0.75,
            self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c2))
        self.assertEquals(
            0,
            self.dp_repo.get_fraction(user=test_data.u1, charity=test_data.c3))
Example #15
0
    def get_donation_proportions(self, user=None, charity=None):
        """Gets the donation proportions filtered by user and/or charity.

        If user is unspecified, returns for all users.
        If charity is unspecified, returns for all charities.

        It does not make sense to specify charity without user, and the magnitude of DonationProportion.amount is relative to the user's other donations.
        """
        query = DonationProportion.all()
        if user is not None:
            query.ancestor(user.key())
        if charity is not None:
            query.filter('charity =', charity)
        return [dp for dp in query.run()]
Example #16
0
    def get_donation_proportions(self, user=None, charity=None):
        """Gets the donation proportions filtered by user and/or charity.

        If user is unspecified, returns for all users.
        If charity is unspecified, returns for all charities.

        It does not make sense to specify charity without user, and the magnitude of DonationProportion.amount is relative to the user's other donations.
        """
        query = DonationProportion.all()
        if user is not None:
            query.ancestor(user.key())
        if charity is not None:
            query.filter('charity =', charity)
        return [dp for dp in query.run()]
Example #17
0
    def test_generates_outgoing_payments_despite_mismatches(self):
        self.setup_one_incoming_payment({
            test_data.u1: 100,
            test_data.u2: 75,
        })

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1, charity=test_data.c1, amount=100),
        ])

        expected = set([
            OutgoingPayment(charity=test_data.c1, amount_GBPennies=100, status=OutgoingPaymentState.DISPLAYED),
        ])
        expected_notifications = set([
            AmountMismatch(user=test_data.u2, incoming_GBPennies=75, outgoing=[]),
        ])

        amount_mismatch_notifier = AccumulatingMismatchNotifier()
        self.assertEquals(self.payment_repo.get_pending_outgoing_payments(amount_mismatch_notifiers=[amount_mismatch_notifier]), expected)
        self.assertEquals(amount_mismatch_notifier.accumulated, expected_notifications)
Example #18
0
    def test_logs_and_notifies_incoming_and_outgoing_mismatches(self):
        self.setup_one_mismatched_incoming_payment({
            test_data.u1: (250, 249),
            test_data.u2: (250, 251),
            test_data.u4: (200, 200),
            test_data.u5: (75, 75),
        })
        self.setup_one_missing_payment({test_data.u3: 10})

        self.add_donation_proportions([
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c1,
                                   amount=100),
            DonationProportion.new(user=test_data.u1,
                                   charity=test_data.c2,
                                   amount=150),
            DonationProportion.new(user=test_data.u2,
                                   charity=test_data.c1,
                                   amount=250),
            DonationProportion.new(user=test_data.u3,
                                   charity=test_data.c1,
                                   amount=10),
            DonationProportion.new(user=test_data.u5,
                                   charity=test_data.c1,
                                   amount=75),
        ])

        amount_mismatch_notifier = AccumulatingMismatchNotifier()
        self.payment_repo.get_pending_outgoing_payments(
            amount_mismatch_notifiers=[amount_mismatch_notifier])

        expected = set([
            AmountMismatch(user=test_data.u1,
                           incoming_GBPennies=249,
                           outgoing=[
                               OutgoingPayment(
                                   charity=test_data.c1,
                                   amount_GBPennies=100,
                                   status=OutgoingPaymentState.VALUE_MISMATCH),
                               OutgoingPayment(
                                   charity=test_data.c2,
                                   amount_GBPennies=150,
                                   status=OutgoingPaymentState.VALUE_MISMATCH),
                           ]),
            AmountMismatch(user=test_data.u2,
                           incoming_GBPennies=251,
                           outgoing=[
                               OutgoingPayment(
                                   charity=test_data.c1,
                                   amount_GBPennies=250,
                                   status=OutgoingPaymentState.VALUE_MISMATCH)
                           ]),
            AmountMismatch(user=test_data.u3,
                           incoming_GBPennies=0,
                           outgoing=[
                               OutgoingPayment(
                                   charity=test_data.c1,
                                   amount_GBPennies=10,
                                   status=OutgoingPaymentState.VALUE_MISMATCH)
                           ]),
            AmountMismatch(user=test_data.u4,
                           incoming_GBPennies=200,
                           outgoing=[]),
        ])

        self.assertEquals(amount_mismatch_notifier.accumulated, expected)