
    |Si\                       d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ  G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zy)zAUnit tests for wallet-utils integration in investment operations.    )annotations)Decimal)TestCaseTransactionTestCase)reverse)status)	APIClientAPITestCase)InsufficientBalanceError)WalletTransaction)
Investment)Transaction)UserMAKE_INVESTMENTc                  6    e Zd ZdZd	dZd Zd Zd Zd Zd Z	y)
 InvestmentWalletIntegrationTestsz@Standard test cases for wallet-utils integration in investments.c                    t         j                  j                  ddd      | _        t	               | _        | j
                  j                  | j                         y)Set up test user and client.i  TestUsertestusertelegram_user_id
first_nameusernameuserNr   objectscreate_userr   r	   clientforce_authenticateselfs    _/home/cursorai/projects/telegram-earn/backend/apps/investments/tests/test_wallet_integration.pysetUpz&InvestmentWalletIntegrationTests.setUp   J    LL,,!! - 
	
  k&&DII&6    c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  j                          ||z
  }| j                  | j                  j                  |       y)z7Standard: Investment successfully deducts user balance.1000.00000000100.00000000investment-listamountjsonformatNr   r   credit_balancesaver   r!   poststrassertEqualstatus_coder   HTTP_201_CREATEDrefresh_from_dbr$   initial_balanceinvestment_amounturlresponseexpected_balances         r%   *test_successful_investment_deducts_balancezKInvestmentWalletIntegrationTests.test_successful_investment_deducts_balance"   s    !/2#N3#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG		!!#*->>113CDr(   c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         t        j                  j                  | j                  j                  dt               }| j                  |j#                         d	       |j%                         }| j                  |j&                  d
       | j                  |j(                  |       | j                  |j*                  | j                  j                         | j-                  d|j.                         y)z@Standard: Wallet transaction record is created via wallet-utils.500.00000000z150.00000000r,   r-   r.   r/   r2   )uidwtype
trans_type   dInvestment in tierN)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   r8   r   r   filteridr   countfirsttyper-   iidassertIndescr)r$   r;   r<   r=   r>   wallet_txns
wallet_txns          r%   "test_wallet_transaction_is_createdzCInvestmentWalletIntegrationTests.test_wallet_transaction_is_created1   s2   !.1#N3#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG (//66		"& 7 

 	**,a0 &&(
#.**,=>6*J,<,<=r(   c                n   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         t        j                  j                  | j                  t        j                        }| j                  |j!                         d       |j#                         }| j                  |j$                  |       | j                  |j                  t        j&                         | j                  |j(                  |       | j                  |j*                  ||z
         | j                  |j,                  d	   |j,                  d
          y)z<Standard: App Transaction record is created for audit trail.200.0000000050.00000000r,   r-   r.   r/   r   transaction_typerF   investment_idrJ   N)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   r8   r   r   rI   TYPE_INVESTMENTrK   rL   r-   STATUS_COMPLETEDbalance_beforebalance_afterdata)r$   r;   r<   r=   r>   app_txnsapp_txns          r%   &test_app_transaction_record_is_createdzGInvestmentWalletIntegrationTests.test_app_transaction_record_is_createdK   sT   !.1#M2#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG &&--(88 . 
 	)1-.."):;)E)EF//A..BS0STo6d8KLr(   c                *   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         t        j                  j                  | j                  t        j                        }| j                  |j                   |       | j                  |j"                  ||z
         y)	z9Standard: Balance before and after are correctly tracked.z300.00000000z75.50000000r,   r-   r.   r/   rW   N)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   r8   r   r   getrZ   r\   r]   )r$   r;   r<   r=   r>   r`   s         r%   /test_balance_before_and_after_tracked_correctlyzPInvestmentWalletIntegrationTests.test_balance_before_and_after_tracked_correctlye   s    !.1#M2#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG%%))(88 * 
 	//A..BS0STr(   c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         t        j                  j                  |j                  d         }| j                  |j                   |       | j                  |j                  | j                         | j                  |j"                  d       | j                  |j                  t        j$                         y	)
zFStandard: Investment record is created with correct tier and metadata.z1500.00000000r,   r-   r.   r/   rJ   rJ      N)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   r8   r   r   rc   r^   r-   tierSTATUS_PENDING)r$   r;   r<   r=   r>   
investments         r%   -test_investment_created_with_correct_metadatazNInvestmentWalletIntegrationTests.test_investment_created_with_correct_metadatax   s    !/2#O4#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG''++x}}T/B+C
**,=>$))4!,**J,E,EFr(   NreturnNone)
__name__
__module____qualname____doc__r&   r@   rS   ra   rd   rk    r(   r%   r   r      s'    J7E>4M4U&Gr(   r   c                  <    e Zd ZdZd
dZd Zd Zd Zd Zd Z	d Z
y	)InvestmentWalletEdgeCasesTestsz-Edge case tests for wallet-utils integration.c                    t         j                  j                  ddd      | _        t	               | _        | j
                  j                  | j                         y)r   i  EdgeUseredgeuserr   r   Nr   r#   s    r%   r&   z$InvestmentWalletEdgeCasesTests.setUp   r'   r(   c                   t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d             y)z8Edge: User has exactly the amount needed for investment.r+   r,   r-   r.   r/   
0.00000000Nr1   )r$   r<   r=   r>   s       r%   test_exact_balance_matchz7InvestmentWalletEdgeCasesTests.test_exact_balance_match   s    #N3#4		 		'(;;##C(C8I4J)KTZ#[--v/F/FG		!!#117<3HIr(   c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d             y)z6Edge: Minimum investment amount ($10) works correctly.z10.00000000r,   r-   r.   r/   rz   Nr1   r$   r;   r<   r=   r>   s        r%   test_minimum_investment_amountz=InvestmentWalletEdgeCasesTests.test_minimum_investment_amount   s    !-0#M2#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG		!!#117<3HIr(   c                ^   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  j                          ||z
  }| j                  | j                  j                  |       t        j                  j                  |j                   d         }| j                  |j"                  d	       y
)z7Edge: Large investment amount (tier 6) works correctly.10000.00000000z6000.00000000r,   r-   r.   r/   rJ   rf      N)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   r8   r9   r   r   rc   r^   rh   )r$   r;   r<   r=   r>   r?   rj   s          r%   test_large_investment_amountz;InvestmentWalletEdgeCasesTests.test_large_investment_amount   s    !"23#O4#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG		!!#*->>113CD''++x}}T/B+C
!,r(   c                   t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d             | j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d	             | j
                  j                  |dd
id      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d             t        j                  j                  | j                        }| j                  |j                         d       y)z@Edge: Multiple investments in sequence correctly deduct balance.rB   r,   r-   100r.   r/   z400.00000000150z250.00000000200rV   r      N)r   r   r2   r3   r   r!   r4   r6   r7   r   r8   r9   r   r   rI   rK   r$   r;   r=   	response1	response2	response3investmentss          r%   $test_multiple_sequential_investmentszCInvestmentWalletEdgeCasesTests.test_multiple_sequential_investments   s   !.1#2		 		 '(KK$$S8U*;F$K	..0G0GH		!!#117>3JK KK$$S8U*;F$K	..0G0GH		!!#117>3JK KK$$S8U*;F$K	..0G0GH		!!#117=3IJ !((//TYY/?**,a0r(   c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  j                          ||z
  }| j                  | j                  j                  |       t        j                  j                  | j                  j                   d      j#                         }| j%                  |       | j                  |j&                  t        d	             y
)zCEdge: Decimal precision of 8 places is maintained for user balance.z100.12345678z50.98765432r,   r-   r.   r/   r2   rC   rD   z50.99N)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   r8   r9   r   r   rI   rJ   rL   assertIsNotNoner-   )r$   r;   r<   r=   r>   r?   rR   s          r%   #test_decimal_precision_eight_placeszBInvestmentWalletEdgeCasesTests.test_decimal_precision_eight_places   s   !.1#M2#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG		!!#*->>113CD
 '..55		" 6 
 %' 	 	Z( 	**GG,<=r(   c                $   t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d             | j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d	             | j
                  j                  |dd
id      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d             t        j                  j                  | j                        j                  d      }| j                  |d   j                   d       | j                  |d   j                   d       | j                  |d   j                   d       y)z:Edge: Different tier investments correctly deduct balance.r   r,   r-   50r.   r/   z9950.00000000300z9650.00000000800z8850.00000000r   
created_atr   rF      r   N)r   r   r2   r3   r   r!   r4   r6   r7   r   r8   r9   r   r   rI   order_byrh   r   s          r%   test_different_tier_investmentsz>InvestmentWalletEdgeCasesTests.test_different_tier_investments   s   !"23#2		 		'( KK$$S8T*:6$J	..0G0GH		!!#117?3KL KK$$S8U*;F$K	..0G0GH		!!#117?3KL KK$$S8U*;F$K	..0G0GH		!!#117?3KL !((//TYY/?HHVQ,,a0Q,,a0Q,,a0r(   Nrl   )ro   rp   rq   rr   r&   r{   r~   r   r   r   r   rs   r(   r%   ru   ru      s+    77JJ-$1@>61r(   ru   c                  N    e Zd ZdZddZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zy)InvestmentWalletOutlierTestsz6Outlier/error case tests for wallet-utils integration.c                    t         j                  j                  ddd      | _        t	               | _        | j
                  j                  | j                         y)r   i  OutlierUseroutlieruserr   r   Nr   r#   s    r%   r&   z"InvestmentWalletOutlierTests.setUp$  sJ    LL,,!$" - 
	
  k&&DII&6r(   c                0   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  d|j                         | j                  dt        |j                  d   d                | j                  dt        |j                  d   d                | j                  dt        |j                  d   d                | j                  j                          | j                  | j                  j                  |       | j                  t        j                   j#                  | j                  	      j%                         d       | j                  t&        j                   j#                  | j                  j(                  
      j%                         d       y)z:Outlier: Investment with insufficient balance is rejected.rV   r+   r,   r-   r.   r/   Insufficient balancer   r   )rC   N)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   HTTP_400_BAD_REQUESTrO   r^   r9   r   r   rI   rK   r   rJ   r}   s        r%   ,test_insufficient_balance_rejects_investmentzIInvestmentWalletOutlierTests.test_insufficient_balance_rejects_investment.  s   !-0#N3#2		 		'(;;##C(C8I4J)KTZ#[--v/J/JKh.,c(--2I!2L.MNmSx)@)C%DEnc(--*A!*D&EF 			!!#11?C 	++22		2BHHJAN 	%%,,,>DDF	
r(   c                l   t        d      | j                  _        | j                  j                          t	        d      }| j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  dt        |j                  d   d                y	)
z.Outlier: User with zero balance cannot invest.rz   r,   r-   10r.   r/   r   r   N)r   r   r2   r3   r   r!   r4   r6   r7   r   r   rO   r5   r^   )r$   r=   r>   s      r%   $test_zero_balance_rejects_investmentzAInvestmentWalletOutlierTests.test_zero_balance_rejects_investmentJ  s    #*<#8		 		'(;;##C(D)9&#I--v/J/JK,c(--2I!2L.MNr(   c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  dt        |j                  d   d                y	)
zLOutlier: Attempting to invest more than balance fails (no negative balance).r+   z100.00000001r,   r-   r.   r/   r   r   N)r   r   r2   r3   r   r!   r4   r5   r6   r7   r   r   rO   r^   r}   s        r%   #test_negative_balance_attempt_failsz@InvestmentWalletOutlierTests.test_negative_balance_attempt_failsU  s    !.1#N3#2		 		'(;;##C(C8I4J)KTZ#[--v/J/JK,c(--2I!2L.MNr(   c                R   t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  d|j                         y)z5Outlier: Amount just below minimum ($10) is rejected.r*   r,   r-   z
9.99999999r.   r/   Nr   r   r2   r3   r   r!   r4   r6   r7   r   r   rO   r^   r$   r;   r=   r>   s       r%   test_amount_just_below_minimumz;InvestmentWalletOutlierTests.test_amount_just_below_minimumb  s    !/2#2		 		'(;;##C(L)A&#Q--v/J/JKh.r(   c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  j                          ||z
  }| j                  | j                  j                  |       y)z4Outlier: Very small amount just above minimum works.r+   z10.00000001r,   r-   r.   r/   Nr1   r:   s         r%   $test_very_small_amount_above_minimumzAInvestmentWalletOutlierTests.test_very_small_amount_above_minimumn  s    !.1#M2#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG		!!#*->>113CDr(   c                   t        d      }t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |dt        |      id      }| j                  |j                  t        j                         | j                  j                          ||z
  }| j                  | j                  j                  |       y)zEOutlier: Very large investment amount works if balance is sufficient.z1000000.00000000z999999.99999999r,   r-   r.   r/   Nr1   r:   s         r%   test_very_large_amountz3InvestmentWalletOutlierTests.test_very_large_amount}  s    !"45#$56#2		 		'(;;##C(C8I4J)KTZ#[--v/F/FG		!!#*->>113CDr(   c                R   t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  d|j                         y)z>Outlier: Negative amount is rejected by serializer validation.r+   r,   r-   z-10r.   r/   Nr   r   s       r%   test_negative_amount_rejectedz:InvestmentWalletOutlierTests.test_negative_amount_rejected      !.1#2		 		'(;;##C(E):6#J--v/J/JKh.r(   c                R   t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  d|j                         y)z:Outlier: Zero amount is rejected by serializer validation.r+   r,   r-   0r.   r/   Nr   r   s       r%   test_zero_amount_rejectedz6InvestmentWalletOutlierTests.test_zero_amount_rejected  s~    !.1#2		 		'(;;##C(C#H--v/J/JKh.r(   c                R   t        d      }|| j                  _        | j                  j                          t	        d      }| j
                  j                  |ddid      }| j                  |j                  t        j                         | j                  d|j                         y)z(Outlier: Non-numeric amount is rejected.r+   r,   r-   abcr.   r/   Nr   r   s       r%    test_non_numeric_amount_rejectedz=InvestmentWalletOutlierTests.test_non_numeric_amount_rejected  r   r(   Nrl   )ro   rp   rq   rr   r&   r   r   r   r   r   r   r   r   r   rs   r(   r%   r   r   !  s;    @7
8	OO
/EE
/
/
/r(   r   c                  $    e Zd ZdZddZd Zd Zy) InvestmentWalletConcurrencyTestsz;Concurrency and race condition tests for wallet operations.c                R    t         j                  j                  ddd      | _        y)zSet up test user.i  ConcurrentUserconcurrentuserr   N)r   r   r    r   r#   s    r%   r&   z&InvestmentWalletConcurrencyTests.setUp  s&    LL,,!'% - 
	r(   c                    t        d      }| j                  _         j                  j                           fd} |       } j	                  |j
                  t        j                          j                  j                           j	                   j                  j                  t        d              |       } j	                  |j
                  t        j                          j                  dt        |j                  d   d                 j	                  t        j                  j                   j                        j!                         d       y	)
z7Outlier: Concurrent investments are handled atomically.rU   c                     t               } | j                  j                         t        d      }| j	                  |ddid      S )Nr   r,   r-   r   r.   r/   )r	   r"   r   r   r4   )r!   r=   r$   s     r%   create_investmentznInvestmentWalletConcurrencyTests.test_concurrent_investments_prevent_race_condition.<locals>.create_investment  sD    [F%%499%5+,C;;sXu$5f;EEr(   rV   r   r-   r   r   rF   N)r   r   r2   r3   r6   r7   r   r8   r9   r   rO   r5   r^   r   r   rI   rK   )r$   r;   r   r   r   s   `    r%   2test_concurrent_investments_prevent_race_conditionzSInvestmentWalletConcurrencyTests.test_concurrent_investments_prevent_race_condition  s    !.1#2		 			F &'	..0G0GH		!!#117=3IJ &'	..0K0KL,c)..2J12M.NO 	++22		2BHHJANr(   c                   t        d      }|| j                  _        | j                  j                          t	               }|j                  | j                         t        d      }|j                  |ddid      }| j                  |j                  t        j                         | j                  j                          | j                  | j                  j                  t        d             t        j                  j                  |j                   d	   
      }| j#                  |       t$        j                  j'                  | j                  j(                  d      j+                         }| j#                  |       t,        j                  j'                  | j                  t,        j.                        j+                         }| j#                  |       | j                  |j0                  |       | j                  |j2                  t        d             | j                  |j4                  t        d             y)z:Outlier: All operations in investment creation are atomic.r+   r   r,   r-   r   r.   r/   rV   rJ   rf   r2   r   rW   N)r   r   r2   r3   r	   r"   r   r4   r6   r7   r   r8   r9   r   r   rc   r^   r   r   rI   rJ   rL   r   rZ   r\   r]   balance)r$   r;   r!   r=   r>   rj   rR   r`   s           r%   #test_atomic_transaction_consistencyzDInvestmentWalletConcurrencyTests.test_atomic_transaction_consistency  s   !.1#2		 		 !!tyy!1'(;;sXt$4V;D--v/F/FG 			!!#117=3IJ  ''++x}}T/B+C
Z( '..55		" 6 
 %' 	 	Z( %%,,(88 - 
 %' 	 	W% 	//A..0FG++W]-CDr(   Nrl   )ro   rp   rq   rr   r&   r   r   rs   r(   r%   r   r     s    E
O:'Er(   r   c                  "    e Zd ZdZd Zd Zd Zy)$InvestmentWalletTransactionTypeTestsz2Tests for transaction type registration and usage.c                4    ddl m} | j                  |d       y)z8Standard: MAKE_INVESTMENT constant is correctly defined.r   r   i'  N)utils.walletr   r6   )r$   r   s     r%   .test_make_investment_transaction_type_constantzSInvestmentWalletTransactionTypeTests.test_make_investment_transaction_type_constant  s    0%0r(   c                b   t         j                  j                  ddd      }t        d      |_        |j                          t               }|j                  |       t        d      }|j                  |dd	id
      }| j                  |j                  t        j                         t        j                  j                  |j                   d      j#                         }| j%                  |       | j                  |j&                  t(               | j                  |j*                  d       y)zCStandard: Wallet transactions use MAKE_INVESTMENT transaction type.i  TypeUsertypeuserr   r*   r   r,   r-   r   r.   r/   r2   r   rG   N)r   r   r    r   r2   r3   r	   r"   r   r4   r6   r7   r   r8   r   rI   rJ   rL   r   rE   r   rM   r$   r   r!   r=   r>   rR   s         r%   )test_wallet_transaction_uses_correct_typezNInvestmentWalletTransactionTypeTests.test_wallet_transaction_uses_correct_type  s    ||''!! ( 

 &o6		!!t!,'(;;sXu$5f;E--v/F/FG&..55" 6 
 %' 	
 	Z(..@#.r(   c                8   t         j                  j                  ddd      }t        d      |_        |j                          t               }|j                  |       t        d      }|j                  |dd	id
      }| j                  |j                  t        j                         t        j                  j                  |j                   d      j#                         }| j%                  d|j&                         | j%                  d|j&                         y)z>Standard: Wallet transaction remarks include tier information.i  RemarksUserremarksuserr   z2000.00000000r   r,   r-   1500r.   r/   r2   r   rH   4N)r   r   r    r   r2   r3   r	   r"   r   r4   r6   r7   r   r8   r   rI   rJ   rL   rO   rP   r   s         r%   ,test_wallet_transaction_remarks_include_tierzQInvestmentWalletTransactionTypeTests.test_wallet_transaction_remarks_include_tier&  s    ||''!$" ( 

 &o6		!!t!,'(;;sXv$6v;F--v/F/FG&..55" 6 
 %' 	
 	*J,<,<=c:++,r(   N)ro   rp   rq   rr   r   r   r   rs   r(   r%   r   r     s    <1/4-r(   r   N) rr   
__future__r   decimalr   django.testr   r   django.urlsr   rest_frameworkr   rest_framework.testr	   r
   django_wallet_utils.exceptionsr   django_wallet_utils.modelsr   apps.investments.modelsr   apps.transactions.modelsr   apps.users.modelsr   r   r   r   ru   r   r   r   rs   r(   r%   <module>r      sy    G "  5  ! 6 C 8 . 0 " (sG{ sGlS1[ S1lM/; M/`OE': OEd:-8 :-r(   