示例#1
0
    def test_redeclaration_of_less_time(self):
        """
        test re-declarations of time. E.g., if there is already covered
          declared time, it should not be possible to save comment with
          less declared time than is already covered by transactions.

        -Should not be possible to change the declared time to smaller
        if there are investments already.-
        """

        self.assertEqual(self.comment.claimed_hours, Decimal('1.5'))
        self.assertEqual(self.comment.assumed_hours, Decimal('6.5'))

        self.comment.invest(0.1, 'eur', self.investor)

        self.comment.text = """
        - {1.0},{?0.1} for coming up with basic class structure,
        - {?2.5} for implementation,
        - {?3.5} for testing.

        Here is the result so far:
        https://github.com/wefindx/infty2.0/commit/9f096dc54f94c31eed9558eb32ef0858f51b1aec
        """

        self.comment.save()

        self.assertEqual(self.comment.claimed_hours, Decimal('1.0'))
        self.assertTrue(
            self.comment.assumed_hours - Decimal('6.1') < Decimal('1E-15'))

        self.assertEqual(self.comment.invested(), Decimal('0.1'))

        self.assertEqual(self.comment.matched(), Decimal('0.1'))

        self.assertEqual(self.comment.donated(), Decimal('0.0'))

        # Balances
        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.05'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.05'))

        self.assertEqual(ContributionCertificate.user_unmatched(self.doer),
                         Decimal('0.0'))

        self.assertEqual(ContributionCertificate.user_unmatched(self.investor),
                         Decimal('0.0'))
示例#2
0
    def test_simple_investment_multiparty(self):
        """
        "Simple Investment Multiparty"
        : there is a couple of investors, and the total amount of investment
          is smaller than total declared time.

        DOER
             1.5 h                       6.5 ĥ
        [------------][-------------------------------------------]

        INVESTOR 1

        0.2 ḥ
        [--]

        INVESTOR 2
            0.5 ḥ
            [----]

        CONTRIBUTIONS
        [--][----]
        """
        self.tx1 = self.comment.invest(0.2, 'eur', self.investor)
        self.tx2 = self.comment.invest(0.5, 'cny', self.investor2)

        self.assertTrue(
            Decimal(0.7) - self.comment.invested() < Decimal('1E-28'))

        self.assertTrue(
            self.tx1.hour_unit_cost -
            Decimal('22.38042458862648158969049976') < Decimal('1E-28'))

        self.assertTrue(
            self.tx2.hour_unit_cost -
            Decimal('177.0000639440702549483852555') < Decimal('1E-28'))

        self.assertEqual(
            ContributionCertificate.objects.filter(
                comment_snapshot__comment=self.comment).count(), 4)

        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.35'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.1'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor2),
                         Decimal('0.25'))
示例#3
0
    def test_mixed_present_future_investment_one_investor(self):
        """
        "Mixed Present-Future Investment one investor"
        : there is only one investor, and the amount to invest is larger
          than the time declared.
          (needs to simulate that if there is re-declaration of time,
           where there is more time declared, then the new ContributionCer-
           tificates generated, linked to same Transaction)

        DOER
             1.5 h                       6.5 ĥ
        [------------][-------------------------------------------]

        INVESTOR

                    4.0 ḥ
        [---------------------------]

        CONTRIBUTIONS
        [--PRESENT--][---FUTURE-----] ( .unmatched )
        """
        self.assertEqual(self.comment.claimed_hours, Decimal('1.5'))
        self.assertEqual(self.comment.assumed_hours, Decimal('6.5'))

        self.tx1 = self.comment.invest(4.0, 'eur', self.investor)

        # [INVESTED]
        self.assertEqual(self.comment.invested(), Decimal('4.0'))

        # [PRESENT]
        self.assertEqual(self.comment.matched(), Decimal('1.5'))

        # [FUTURE]
        self.assertEqual(self.comment.donated(), Decimal('2.5'))

        # [REMAINS]
        self.assertEqual(self.comment.remains(), Decimal('4.0'))

        # Balances:
        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.75'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.75'))
示例#4
0
    def test_mixed_present_future_investment_multiparty(self):
        """
        "Mixed Present-Future Investment Multiparty
        : there is a couple of investors ,and the total amount of investment
          is larger than the time declared.
          (needs to simulate that if there is re-declaration of time,
          where there is more time declared, then the new ContributionCer-
          tificates are generated, so as to preserve priority of investors'
          sequence. E.g., if small extra time is declared, the newly
          crated ContributionCertificate is for the earlier investments.)

        DOER
             1.5 h                       6.5 ĥ
        [------------][-------------------------------------------]

        INVESTOR1 INVESTOR2                INVESTOR3

           1.0 ḥ    1.0 ḥ                    6.0 ḥ
        [--------][--------][-------------------------------------]

        CONTRIBUTIONS
        [----P---][P-][-F--][--------------FUTURE-----------------]

        """
        self.assertEqual(self.comment.claimed_hours, Decimal('1.5'))
        self.assertEqual(self.comment.assumed_hours, Decimal('6.5'))
        self.assertEqual(self.comment.remains(), Decimal('8.0'))

        self.tx1 = self.comment.invest(1.0, 'eur', self.investor)
        self.assertEqual(self.comment.invested(), Decimal('1.0'))
        self.assertEqual(self.comment.remains(), Decimal('7.0'))
        self.assertEqual(self.comment.donated(), Decimal('0.0'))
        self.assertEqual(self.comment.contributions(), 2)

        self.assertEqual(self.comment.claimed_hours - self.comment.matched(),
                         Decimal(0.5))

        self.assertEqual(self.comment.assumed_hours - self.comment.donated(),
                         Decimal(6.5))

        self.assertEqual(self.comment.remains(), Decimal('7.0'))

        self.tx2 = self.comment.invest(1.0, 'eur', self.investor2)
        self.assertEqual(self.comment.invested(), Decimal('2.0'))
        self.assertEqual(self.comment.remains(), Decimal('6.0'))
        self.assertEqual(self.comment.contributions(), 6)
        self.assertEqual(self.comment.donated(), Decimal('0.5'))

        ### Make sure investor3 has enough quota and reserve.
        payment = Payment.objects.create(request={
            "amount": "200",
            "currency": "usd",
        },
                                         platform=0,
                                         provider=0,
                                         owner=self.investor3)
        ### /Make sure investor3 has enough quota and reserve.

        self.tx3 = self.comment.invest(6.0, 'eur', self.investor3)
        self.assertEqual(self.comment.invested(), Decimal('8.0'))
        self.assertEqual(self.comment.remains(), Decimal('0.0'))
        self.assertEqual(self.comment.donated(), Decimal('6.5'))

        self.assertEqual(self.comment.remains(), Decimal('0.0'))

        self.assertEqual(self.comment.matched(), Decimal('1.5'))

        self.assertEqual(self.comment.donated(), Decimal('6.5'))

        # Balances
        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.75'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.5'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor2),
                         Decimal('0.25'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor3),
                         Decimal('0.0'))

        self.assertEqual(ContributionCertificate.user_unmatched(self.doer),
                         Decimal('3.25'))

        self.assertEqual(ContributionCertificate.user_unmatched(self.investor),
                         Decimal('0.0'))

        self.assertEqual(
            ContributionCertificate.user_unmatched(self.investor2),
            Decimal('0.25'))

        self.assertEqual(
            ContributionCertificate.user_unmatched(self.investor3),
            Decimal('3.0'))
示例#5
0
    def test_future_investment_multiparty(self):
        """
        DOER
                                     8.0 ĥ
        [---------------------------------------------------------]

        INVESTOR1 INVESTOR2                INVESTOR3

           1.0 ḥ    1.0 ḥ                    6.0 ḥ
        [--------][--------][-------------------------------------]

        CONTRIBUTIONS
        [-FUTURE-][-FUTURE-][---------------FUTURE----------------]
        ( .unmatched ) ( .unmatched ) ( .unmatched )
        """

        self.assertEqual(self.comment2.remains(), Decimal('8.0'))

        ### Make sure investor3 has enough quota and reserve.
        self.investor3
        payment = Payment.objects.create(request={
            "amount": "150",
            "currency": "usd",
        },
                                         platform=0,
                                         provider=0,
                                         owner=self.investor3)
        ### /Make sure investor3 has enough quota and reserve.

        self.tx1 = self.comment2.invest(1.0, 'eur', self.investor)
        self.tx2 = self.comment2.invest(1.0, 'eur', self.investor2)
        self.tx3 = self.comment2.invest(6.0, 'eur', self.investor3)

        self.assertEqual(self.comment2.invested(), Decimal('8.0'))

        self.assertEqual(self.comment2.remains(), Decimal('0.0'))

        # [PRESENT]
        self.assertEqual(self.comment2.matched(), Decimal('0.0'))

        # [FUTURE]
        self.assertEqual(self.comment2.donated(), Decimal('8.0'))

        # .matched_hours by investors must be zero.
        self.assertEqual(self.comment2.matched(by=self.investor),
                         Decimal('0.0'))
        self.assertEqual(self.comment2.matched(by=self.investor2),
                         Decimal('0.0'))
        self.assertEqual(self.comment2.matched(by=self.investor3),
                         Decimal('0.0'))

        # .donated_hours by investors must be 1/2,1/2,6/2 respectively.
        self.assertEqual(self.comment2.donated(by=self.investor),
                         Decimal('1.0') / Decimal(2))
        self.assertEqual(self.comment2.donated(by=self.investor2),
                         Decimal('1.0') / Decimal(2))
        self.assertEqual(self.comment2.donated(by=self.investor3),
                         Decimal('6.0') / Decimal(2))

        # .donated_hours by doer must be 4, or 1/2+1/2+6/2, as doer gets 50%.
        self.assertEqual(self.comment2.donated(by=self.doer), Decimal('4.0'))

        # Balances
        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.0'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.0'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor2),
                         Decimal('0.0'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor3),
                         Decimal('0.0'))

        self.assertEqual(ContributionCertificate.user_unmatched(self.doer),
                         Decimal('4.0'))

        self.assertEqual(ContributionCertificate.user_unmatched(self.investor),
                         Decimal('0.5'))

        self.assertEqual(
            ContributionCertificate.user_unmatched(self.investor2),
            Decimal('0.5'))

        self.assertEqual(
            ContributionCertificate.user_unmatched(self.investor3),
            Decimal('3.0'))
示例#6
0
    def test_future_investment_one_investor(self):
        """
        DOER
                                     8.0 ĥ
        [---------------------------------------------------------]

        INVESTOR

          1.0 ħ
        [--------]

        CONTRIBUTIONS
        [-FUTURE-] ( .unmatched )


        Now, let's say that the doer updates the comment to show
        the progress (changes the .assumed_hours to .claimed_hours)

                                     8.0 ĥ
        [---------------------------------------------------------]
        COMMENT UPDATE
             |
            \ /
             v

        DOER
        0.4 h                       7.6 ĥ
        [--][-----------------------------------------------------]

        INVESTOR

          1.0 ħ
        [--------]

        CONTRIBUTIONS
        [-FUTURE-] ( .unmatched )

        0.4 ḥ
        [--]

        HAPPENS

        (1) We go through old certificates with broken=False, matched=False,
        (2) Make new child certificates with broken=False, matched=True,
        (3) and at the points of overflow, broken=False, matched=False.
        (4) invalidate parent certificates.
        """

        # We have correct initial state:
        self.assertEqual(self.comment2.claimed_hours, Decimal(0.0))
        self.assertEqual(self.comment2.assumed_hours, Decimal(8.0))
        self.assertEqual(self.comment2.remains(), Decimal(8.0))

        # An investor comes to make an investment of 1.0

        self.tx = self.comment2.invest(1.0, 'eur', self.investor)

        # Both investor and doer get a certificate of investment.
        self.assertEqual(
            ContributionCertificate.objects.filter(
                comment_snapshot__comment=self.comment2).count(), 2)

        # Invested amount 1.0
        self.assertEqual(Decimal('1.0'), self.comment2.invested())

        # Remains to invest 7.0
        self.assertEqual(self.comment2.remains(), Decimal('7.0'))

        # None is matched yet.
        self.assertEqual(self.comment2.matched(), Decimal('0.0'))

        # Both investor and doer should by now have zero matched time.
        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.0'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.0'))

        # Both doer and investor should have '0.5' h each as 'unmatched'
        self.assertEqual(ContributionCertificate.user_unmatched(self.doer),
                         Decimal('0.5'))

        self.assertEqual(ContributionCertificate.user_unmatched(self.investor),
                         Decimal('0.5'))

        # Let's say, the doer updates comment to show progress.

        self.comment2.text = """
        - {0.4}{?7.6} for testing.

        Here is the result so far:
        https://wiki.mindey.com/shared/screens/7e402349b3c2e3a626b5d25fd.png
        https://wiki.mindey.com/shared/screens/92fe2c4d8c795e4ff39884622.png
        """
        self.comment2.save()

        # The matched time is 0.4
        self.assertEqual(self.comment2.matched(), Decimal('0.4'))

        # The donated time is 0.6
        self.assertEqual(self.comment2.donated(), Decimal('0.6'))

        # Invested should be 1.0 as before
        self.assertEqual(self.comment2.invested(), Decimal('1.0'))

        # Remains the same amount to invest:
        self.assertTrue(
            Decimal('7.0') - self.comment2.remains() < Decimal('1E-15'))

        # Number of certificates for the comment should be:
        self.assertEqual(
            ContributionCertificate.objects.filter(
                transaction__comment=self.comment2).count(), 6)

        # Two of them broken:
        self.assertEqual(
            ContributionCertificate.objects.filter(
                transaction__comment=self.comment2, broken=True).count(), 2)

        # Four of them not broken:
        self.assertEqual(
            ContributionCertificate.objects.filter(
                transaction__comment=self.comment2, broken=False).count(), 4)

        # Two of unbroken those received by doer:
        self.assertEqual(
            ContributionCertificate.objects.filter(
                transaction__comment=self.comment2,
                received_by=self.doer,
                broken=False).count(), 2)

        # Two of unbroken those received by the investor:
        self.assertEqual(
            ContributionCertificate.objects.filter(
                transaction__comment=self.comment2,
                received_by=self.investor,
                broken=False).count(), 2)

        # Doer has 0.2, and investor also 0.2 matched hours.

        # Two of unbroken those received by the investor, summing to 0.2:
        self.assertEqual(
            Decimal(
                ContributionCertificate.objects.filter(
                    transaction__comment=self.comment2,
                    received_by=self.investor,
                    matched=True,
                    broken=False).aggregate(total=Sum('hours')).get('total')
                or 0), Decimal('0.2'))

        # Two of unbroken those received by the doer, summing to 0.2:
        self.assertEqual(
            Decimal(
                ContributionCertificate.objects.filter(
                    transaction__comment=self.comment2,
                    received_by=self.doer,
                    matched=True,
                    broken=False).aggregate(total=Sum('hours')).get('total')
                or 0), Decimal('0.2'))

        # Doer has 0.2 matched hours
        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.2'))

        # Investor has 0.2 matched hours
        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.2'))
示例#7
0
    def test_simple_investment(self):
        """
        "Simple Investment"
        : there is only one investor, and the amount to invest is smaller
          than then time declared.

        DOER
             1.5 h                       6.5 ĥ
        [------------][-------------------------------------------]

        INVESTOR

        0.2 ḥ
        [--]

        CONTRIBUTIONS
        [--]

        # https://wiki.mindey.com/shared/screens/b6767a949a4884cfd4fe17b41.png
        """

        # Investor decides that s/he wants to invest into 0.2, and pay in EUR
        # of claimed time;  sees the "(1.5 h) invest" button, and clicks it.

        self.tx = self.comment.invest(0.2, 'eur', self.investor)

        self.assertTrue(
            self.tx.hour_unit_cost -
            Decimal('22.38042458862648158969049976') < Decimal('1E-28'))

        # As part of transaction, the ContributionCertificates
        # are generated to both parties - the doer, and investor.
        # For thinker -- will add the option to auto-generate
        # first comment with amount of time claimed to write the topic.

        # Generated amount is approximately equal to amount purchased.
        self.assertTrue(
            (self.tx.matched_hours - Decimal(0.2)) < Decimal('1E-28'))

        # Doer and Investor gets equal amount as contributors.

        # There should be 2 parts of the transaction:
        self.assertEqual(
            ContributionCertificate.objects.filter(
                transaction=self.tx).count(), 2)

        # Both parts should be equal:
        self.assertEqual(
            ContributionCertificate.objects.filter(
                transaction=self.tx).first().hours,
            ContributionCertificate.objects.filter(
                transaction=self.tx).last().hours,
        )

        # Both parts of the transaction should be
        self.assertTrue((ContributionCertificate.objects.filter(
            transaction=self.tx).first().hours -
                         Decimal(0.1)) < Decimal('1E-28'))

        # The balance (score) of user is defined as sum of all contributions!
        self.assertEqual(
            Decimal('0.1'),
            ContributionCertificate.objects.filter(
                received_by=self.doer).aggregate(total=Sum('hours'))['total'])

        # The balance (score) of user is defined as sum of all contributions!
        self.assertEqual(
            Decimal('0.1'),
            ContributionCertificate.objects.filter(
                received_by=self.investor).aggregate(
                    total=Sum('hours'))['total'])

        self.assertEqual(self.comment.remains(),
                         Decimal('1.5') + Decimal('6.5') - Decimal('0.2'))

        # Test the balances of the users.
        self.assertEqual(ContributionCertificate.user_matched(self.doer),
                         Decimal('0.1'))

        self.assertEqual(ContributionCertificate.user_matched(self.investor),
                         Decimal('0.1'))
示例#8
0
 def matched(self, obj):
     return ContributionCertificate.user_matched(obj)