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') )
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') )
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')) 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') )
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') ) 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') )
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') )
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') )
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') )