
    /e=iأ                     b   d Z ddlmZ ddlmZmZ ddlmZmZ ddlm	Z
 ddlmZmZ ddlmZmZmZmZ ddlmZmZmZmZmZmZ dd	lmZmZ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" G d de      Z# G d de      Z$ G d de      Z% G d de      Z&y)z
Comprehensive tests for WalletService covering all documented functionality.

Tests cover:
- Standard cases
- Edge cases
- Error cases
- Outlier cases
    )Decimaldatetime	timedelta)TestCaseTransactionTestCase)transaction)WalletServiceWalletRepository)InsufficientBalanceErrorInvalidPointTypeErrorInvalidParamsErrorWalletOperationError)WALLET_DEPOSITWALLET_WITHDRAWROI_DISTRIBUTIONREFERRAL_BONUSget_transaction_typeget_transaction_type_name)TestUser
TestWalletTestWalletCustomFieldc                   v    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zy)WalletServiceAddPointTestszTests for add_point() method.c                     t         j                  j                  dd      | _        dddd| _        t        t         | j                        | _        t        | j                        | _        y	
Set up test fixtures.testusertest@example.comusernameemail   r      credit_balancereward_pointscrypto_balance
user_modelpoint_typesN	r   objectscreateuserr+   r   repor
   serviceselfs    S/home/cursorai/projects/telegram-earn/sandbox/test_app/tests/test_wallet_service.pysetUpz WalletServiceAddPointTests.setUp$   _    $$++ZGY+Z	

 %((
	 %TYY/    c                 ^   | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  |d       | j                  j                          | j                  | j                  j                  t	        d             y)z)Standard case: Add points to user wallet.r&   100.00zTest deposituser_id
point_typeamountremarksr   N)r1   	add_pointr/   idr   assertIsInstanceintassertGreaterrefresh_from_dbassertEqualr&   r3   transaction_ids     r4   test_add_point_standardz2WalletServiceAddPointTests.test_add_point_standard2   s    //IILL'8$"	 0 
 	nc2>1- 			!!#11783DEr7   c                    | j                   j                  | j                  j                  dt	        d      dt
              }| j                  |t               | j                   j                  |      }| j                  |       | j                  |j                  t
               | j                  |j                  d       y)z*Add points with transaction type constant.r&   50.00Depositr;   r<   r=   r>   
trans_typecN)r1   r?   r/   r@   r   r   rA   rB   get_transaction_by_idassertIsNotNonerE   rM   typer3   rG   r	   s      r4   $test_add_point_with_transaction_typez?WalletServiceAddPointTests.test_add_point_with_transaction_typeB   s    //IILL'7#% 0 
 	nc2 ll88H[)//@))3/r7   c                     d}| j                   j                  | j                  j                  dt	        d      d|      }| j                   j                  |      }| j                  |j                  |       y)z.Add points with initiator ID (user-initiated).  r&   z25.00zUser depositr;   r<   r=   r>   iidNr1   r?   r/   r@   r   rO   rE   rW   )r3   initiator_idrG   r	   s       r4   test_add_point_with_iidz2WalletServiceAddPointTests.test_add_point_with_iidT   sf    //IILL'7#" 0 
 ll88H,7r7   c                     | j                   j                  | j                  j                  dt	        d      d      }| j                   j                  |      }| j                  |j                  d       y)z4Add points with system initiator (default iid=-100).r&   10.00zSystem depositr:   NrX   rR   s      r4   test_add_point_system_initiatedz:WalletServiceAddPointTests.test_add_point_system_initiatedb   s^    //IILL'7#$	 0 
 ll88H$/r7   c           
      :   | j                   j                  | j                  j                  dt	        d      dddddi      }| j                   j                  |      }| j                  |j                  d	   d       | j                  |j                  d
   d       y)z%Add points with extra data in params.r&   r9   zDeposit with extra datadatai90  bank_transfer)
payment_idsourcer;   r<   r=   r>   paramsrb   rc   Nr1   r?   r/   r@   r   rO   rE   
extra_datarR   s      r4   test_add_point_with_extra_dataz9WalletServiceAddPointTests.test_add_point_with_extra_datan   s    //IILL'8$-"'- 0 
 ll88H//=uE//9?Kr7   c                    | j                   j                  | j                  j                  dt	        d      d       | j                   j                  | j                  j                  dt	        d      d       | j                   j                  | j                  j                  dt	        d	      d
       | j                  j                          | j                  | j                  j                  t	        d             | j                  | j                  j                  t	        d             | j                  | j                  j                  t	        d	             y)z$Add points to different point types.r&   r9   zCredit depositr:   r'   50zReward pointsr(   
0.00000001zCrypto depositN
r1   r?   r/   r@   r   rD   rE   r&   r'   r(   r2   s    r4   #test_add_point_multiple_point_typesz>WalletServiceAddPointTests.test_add_point_multiple_point_types   s    	IILL'8$$	 	 	
 	IILL&4=#	 	 	
 	IILL'<($	 	 	
 			!!#11783DE00'$-@117<3HIr7   c                 "   | j                   j                  | j                  j                  dt	        d      d       | j                  j                          | j                  | j                  j                  t	        d             | j                   j                  | j                  j                  dt	        d      d       | j                  j                          | j                  | j                  j                  t	        d             | j                   j                  | j                  j                  d	t	        d
      d       | j                  j                          | j                  | j                  j                  t	        d             y) Test decimal precision handling.r&   100.999Test roundingr:   z101.00r'   z50.751r(   z0.123456789z
0.12345679Nrl   r2   s    r4    test_add_point_decimal_precisionz;WalletServiceAddPointTests.test_add_point_decimal_precision   s)    	IILL'9%#	 	 	
 			!!#11783DE 	IILL&6?#	 	 	
 			!!#00'$-@ 	IILL'=)#	 	 	
 			!!#117<3HIr7   c                 P   t        d      t        d      t        d      g}|D ]8  }| j                  j                  | j                  j                  d|d|        : | j                  j                          | j                  | j                  j                  t        d             y)	z-Test multiple additions accumulate correctly.r\   z20.00z30.00r&   Deposit r:   z60.00N)r   r1   r?   r/   r@   rD   rE   r&   r3   amountsr=   s      r4   test_add_point_accumulationz6WalletServiceAddPointTests.test_add_point_accumulation   s    7#WW%5ww7GHFLL""		+"6(+	 #   			!!#11773CDr7   c                 :   | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  j                          | j                  | j                  j                  t	        d             y)zEdge case: Add zero amount.r&   0.00zZero depositr:   N)
r1   r?   r/   r@   r   rA   rB   rD   rE   r&   rF   s     r4   test_add_point_zero_amountz5WalletServiceAddPointTests.test_add_point_zero_amount   ss    //IILL'6?"	 0 
 	nc2		!!#1176?Cr7   c                 :   | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  j                          | j                  | j                  j                  t	        d             y)z!Edge case: Add very small amount.r(   rk   zVery small depositr:   N)
r1   r?   r/   r@   r   rA   rB   rD   rE   r(   rF   s     r4    test_add_point_very_small_amountz;WalletServiceAddPointTests.test_add_point_very_small_amount   su    //IILL'<((	 0 
 	nc2		!!#117<3HIr7   c                 ,   t        d      }| j                  j                  | j                  j                  d|d      }| j                  |t               | j                  j                          | j                  | j                  j                  |       y)z!Edge case: Add very large amount.z9999999999999.99r&   zLarge depositr:   N)
r   r1   r?   r/   r@   rA   rB   rD   rE   r&   )r3   large_amountrG   s      r4    test_add_point_very_large_amountz;WalletServiceAddPointTests.test_add_point_very_large_amount   sx     12//IILL'#	 0 
 	nc2		!!#11<@r7   c                    | j                  t              5 }| j                  j                  | j                  j
                  dt        d      d       ddd       | j                  j                  j                  d       y# 1 sw Y   0xY w)zError case: Invalid point type.invalid_typer9   Testr:   N)
assertRaisesr   r1   r?   r/   r@   r   rE   	exceptionr<   r3   cms     r4   !test_add_point_invalid_point_typez<WalletServiceAddPointTests.test_add_point_invalid_point_type   sm    45LL""		)x(	 #  6 	00.A 65s   =BBc                    | j                  t              5 }| j                  j                  | j                  j
                  dt        d      dd       ddd       | j                  j                  j                  d       y# 1 sw Y   0xY w)z!Error case: params is not a dict.r&   r9   r   
not a dictrd   Nr?   
r   r   r1   r?   r/   r@   r   rE   r   methodr   s     r4   &test_add_point_invalid_params_not_dictzAWalletServiceAddPointTests.test_add_point_invalid_params_not_dict  sp    12bLL""		+x(# #  3 	,,k: 32s   >BBc           	      "   | j                  t              5 }| j                  j                  | j                  j
                  dt        d      dddi       ddd       | j                  j                  j                  d       y# 1 sw Y   0xY w)	z)Error case: params['data'] is not a dict.r&   r9   r   r`   r   rd   Nr?   r   r   s     r4   +test_add_point_invalid_params_data_not_dictzFWalletServiceAddPointTests.test_add_point_invalid_params_data_not_dict  su    12bLL""		+x(- #  3 	,,k: 32s   A BBc                 <   g d}|D ]  }| j                  t              5 }| j                  j                  | j                  j
                  dt        d      dd|dii       ddd       | j                  j                  j                  d	        y# 1 sw Y   2xY w)
z)Error case: Reserved field in extra_data.)
r@   wtyperW   uidrQ   r=   balancerM   descrcdater&   r9   r   r`   valuerd   Nr?   r   )r3   reserved_fieldsfieldr   s       r4   +test_add_point_reserved_field_in_extra_datazFWalletServiceAddPointTests.test_add_point_reserved_field_in_extra_data!  s    t$E""#56"&& IILL/"8,""UG$45 '  7 R\\00+> %66s   ABB	c                     | j                  t              5  | j                  j                  ddt	        d      d       ddd       y# 1 sw Y   yxY w)z+Edge case: Add points to non-existent user.韆 r&   r9   r   r:   N)r   r   r1   r?   r   r2   s    r4   test_add_point_nonexistent_userz:WalletServiceAddPointTests.test_add_point_nonexistent_user0  sG     34LL""+x(	 #  544s   )AAN)__name__
__module____qualname____doc__r5   rH   rS   rZ   r^   rh   rm   rs   rx   r{   r}   r   r   r   r   r   r    r7   r4   r   r   !   sd    '0F 0$8
0L&J>J@EDJA$
B;;?	r7   r   c                   L    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zy)WalletServiceDeductPointTestsz Tests for deduct_point() method.c                 R   t         j                  j                  dd      | _        dddd| _        t        t         | j                        | _        t        | j                        | _        | j                  j                  | j                  j                  d	t        d
      d       y)r   r   r   r    r#   r   r$   r%   r)   r&   1000.00Initial depositr:   Nr   r-   r.   r/   r+   r   r0   r
   r1   r?   r@   r   r2   s    r4   r5   z#WalletServiceDeductPointTests.setUp?  s    $$++ZGY+Z	

 %((
	 %TYY/ 	IILL'9%%	 	 	
r7   c                 ^   | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  |d       | j                  j                          | j                  | j                  j                  t	        d             y)z)Standard case: Deduct points from wallet.r&   r9   
Withdrawalr:   r   z900.00N)r1   deduct_pointr/   r@   r   rA   rB   rC   rD   rE   r&   rF   s     r4   test_deduct_point_standardz8WalletServiceDeductPointTests.test_deduct_point_standardU  s    22IILL'8$ 	 3 
 	nc2>1- 			!!#11783DEr7   c                 4   | j                   j                  | j                  j                  dt	        d      dt
              }| j                   j                  |      }| j                  |j                  t
               | j                  |j                  d       y)z-Deduct points with transaction type constant.r&   rJ   r   rL   dN)
r1   r   r/   r@   r   r   rO   rE   rM   rQ   rR   s      r4   'test_deduct_point_with_transaction_typezEWalletServiceDeductPointTests.test_deduct_point_with_transaction_typee  sy    22IILL'7# & 3 
 ll88H//A))3/r7   c                    | j                  t              5 }| j                  j                  | j                  j
                  dt        d      d       ddd       | j                  j                  j                         | j                  |j                  j                         | j                  |j                  j                  d       y# 1 sw Y   zxY w)z!Error case: Insufficient balance.r&   2000.00zLarge withdrawalr:   Ng     @@)r   r   r1   r   r/   r@   r   rP   r   	available	requestedrE   r   s     r4   &test_deduct_point_insufficient_balancezDWalletServiceDeductPointTests.test_deduct_point_insufficient_balances  s    78BLL%%		+y)*	 &  9 	R\\334R\\334//9 98s   =CCc                    | j                   j                          | j                   j                  }| j                  j	                  | j                   j
                  d|d      }| j                  |t               | j                   j                          | j                  | j                   j                  t        d             y)z Edge case: Deduct exact balance.r&   zFull withdrawalr:   rz   N)
r/   rD   r&   r1   r   r@   rA   rB   rE   r   )r3   current_balancerG   s      r4   test_deduct_point_exact_balancez=WalletServiceDeductPointTests.test_deduct_point_exact_balance  s    		!!#))2222IILL'"%	 3 
 	nc2		!!#1176?Cr7   c                 <   | j                   j                  | j                  j                  dt	        d      dd      }| j                  |t               | j                  j                          | j                  | j                  j                  t	        d             y)z"Edge case: Allow negative balance.r&   r   	OverdraftT)r;   r<   r=   r>   allow_negativez-1000.00N)
r1   r   r/   r@   r   rA   rB   rD   rE   r&   rF   s     r4    test_deduct_point_allow_negativez>WalletServiceDeductPointTests.test_deduct_point_allow_negative  sx    22IILL'9% 3 
 	nc2		!!#117:3FGr7   c                    | j                   j                  | j                  j                  dt	        d      d       | j                  j                          | j                  | j                  j                  t	        d             y)ro   r&   rp   rq   r:   z899.00N)r1   r   r/   r@   r   rD   rE   r&   r2   s    r4   #test_deduct_point_decimal_precisionzAWalletServiceDeductPointTests.test_deduct_point_decimal_precision  se     	!!IILL'9%#	 	" 	
 			!!#11783DEr7   c                    | j                   j                          | j                   j                  }| j                  j	                  | j                   j
                  dt        d      d      }| j                  |t               | j                   j                          | j                  | j                   j                  |       y)zEdge case: Deduct zero amount.r&   rz   zZero withdrawalr:   N)
r/   rD   r&   r1   r   r@   r   rA   rB   rE   )r3   initial_balancerG   s      r4   test_deduct_point_zero_amountz;WalletServiceDeductPointTests.test_deduct_point_zero_amount  s     			!!#))2222IILL'6?%	 3 
 	nc2		!!#11?Cr7   c                 P   t        d      t        d      t        d      g}|D ]8  }| j                  j                  | j                  j                  d|d|        : | j                  j                          | j                  | j                  j                  t        d             y)	zTest multiple deductions.r9   z200.00z300.00r&   Withdrawal r:   400.00N)r   r1   r   r/   r@   rD   rE   r&   rv   s      r4   %test_deduct_point_multiple_deductionszCWalletServiceDeductPointTests.test_deduct_point_multiple_deductions  s    8$gh&79JKFLL%%		+%fX.	 &   			!!#11783DEr7   c                 b   | j                  t              5  | j                  j                  | j                  j
                  dt        d      d       ddd       | j                  j                          | j                  | j                  j                  t        d             y# 1 sw Y   SxY w)z/Test atomic deduction prevents race conditions.r&   r   zRace condition testr:   Nr   )
r   r   r1   r   r/   r@   r   rD   rE   r&   r2   s    r4   +test_deduct_point_race_condition_preventionzIWalletServiceDeductPointTests.test_deduct_point_race_condition_prevention  s     78LL%%		+y)-	 &  9 			!!#11793EF 98s   =B%%B.N)r   r   r   r   r5   r   r   r   r   r   r   r   r   r   r   r7   r4   r   r   <  s>    *
,F 0:D H
FD"FGr7   r   c                   |    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)$WalletServiceTransactionHistoryTestsz0Tests for transaction history retrieval methods.c           
         t         j                  j                  dd      | _        t         j                  j                  dd      | _        ddd| _        t        t         | j
                  	      | _        t        | j                        | _	        g | _
        t        d
      D ]m  }| j                  j                  | j                  j                  dt        d|dz   z   d      d|dz    t              }| j                  j!                  |       o t        d      D ]m  }| j                  j                  | j                  j                  dt        d|dz   z   d      d|dz    t              }| j                  j!                  |       o t        d      D ]d  }| j                  j                  | j                  j                  dt        d      d|dz    t"              }| j                  j!                  |       f y)r   user1zuser1@example.comr    user2zuser2@example.comr#   r   r&   r'   r)      r&   
      z.00ru   rL         r'   100zReward N)r   r-   r.   r   r   r+   r   r0   r
   r1   transaction_idsranger?   r@   r   r   appendr   )r3   itids      r4   r5   z*WalletServiceTransactionHistoryTests.setUp  s   %%,,gEX,Y
%%,,gEX,Y
  
 %((
	 %TYY/  " qA,,((

+"A,s34"1Q3%() ) C   '',  qA,,((

+"A,s34"1Q3%() ) C   '',  qA,,((

*u~!!A#+ ) C   '', r7   c                    | j                   j                  | j                  j                        }| j	                  t        |      d       |D ]2  }| j	                  |j                  | j                  j                         4 y)z%Get transactions filtered by user_id.r;      N)r1   get_transaction_historyr   r@   rE   lenr   r3   transactionstxns      r4   'test_get_transaction_history_by_user_idzLWalletServiceTransactionHistoryTests.test_get_transaction_history_by_user_id  s\    ||;;DJJMM;R\*A.CSWWdjjmm4  r7   c                     | j                   j                  | j                  j                  d      }| j	                  t        |      d       |D ]  }| j	                  |j                  d         y)z(Get transactions filtered by point_type.r&   r;   r<   r   N)r1   r   r   r@   rE   r   r   r   s      r4   *test_get_transaction_history_by_point_typezOWalletServiceTransactionHistoryTests.test_get_transaction_history_by_point_type  s_    ||;;JJMM' < 

 	\*A.CSYY(89  r7   c                     | j                   j                  t              }| j                  t	        |      d       |D ]"  }| j                  |j
                  t               $ y)z(Get transactions filtered by trans_type.rM   r$   N)r1   r   r   rE   r   rM   r   s      r4   *test_get_transaction_history_by_trans_typezOWalletServiceTransactionHistoryTests.test_get_transaction_history_by_trans_type'  sS    ||;;% < 
 	\*A.CS^^^<  r7   c                     | j                   j                  d      }| j                  t        |      d       |D ]  }| j                  |j                  d         y)z2Get transactions filtered by transaction_type='c'.rN   transaction_typer   N)r1   r   rE   r   rQ   r   s      r4   7test_get_transaction_history_by_transaction_type_creditz\WalletServiceTransactionHistoryTests.test_get_transaction_history_by_transaction_type_credit1  sS    ||;;  < 
 	\*B/CSXXs+  r7   c                 (   | j                   j                  | j                  j                  dt	        d      d       | j                   j                  d      }| j                  t        |      d       | j                  |d   j                  d       y	)
z2Get transactions filtered by transaction_type='d'.r&   r\   r   r:   r   r   r   r   N)	r1   r   r   r@   r   r   rE   r   rQ   r3   r   s     r4   6test_get_transaction_history_by_transaction_type_debitz[WalletServiceTransactionHistoryTests.test_get_transaction_history_by_transaction_type_debit;  s     	!!JJMM'7# 	 	" 	
 ||;;  < 
 	\*A.a--s3r7   c                 .   d}| j                   j                  | j                  j                  dt	        d      d|       | j                   j                  |      }| j                  t        |      d       | j                  |d   j                  |       y	)
z*Get transactions filtered by initiator ID.rU   r&   rJ   r   rV   )rW   r   r   N)	r1   r?   r   r@   r   r   rE   r   rW   )r3   rY   r   s      r4   #test_get_transaction_history_by_iidzHWalletServiceTransactionHistoryTests.test_get_transaction_history_by_iidL  s     JJMM'7# 	 	
 ||;;;M\*A.a,,l;r7   c                 `   ddl m }m} ddl}|j                  d       | j                  j                  | j                  j                  dt        d      d        |j                         }| |d	
      z
  }| j                  j                  ||      }| j                  t        |      d	       y)z(Get transactions filtered by date range.r   r   Ng?r&   r9   zRecent depositr:   r   )minutes
start_dateend_date)r   r   timesleepr1   r?   r   r@   r   nowr   assertGreaterEqualr   )r3   r   r   r   r   r   r   s          r4   'test_get_transaction_history_date_rangezLWalletServiceTransactionHistoryTests.test_get_transaction_history_date_range\  s    0 	

3 	JJMM'8$$	 	 	
  8<<>	! 44
||;;! < 
 	L 115r7   c                     ddl m }m}  |j                         }| |d      z
  }| j                  j	                  |j                         |j                               }| j                  t        |      d       y)z<Get transactions filtered by date range (ISO string format).r   r   r   )daysr   r   N)r   r   r   r1   r   	isoformatr   r   )r3   r   r   r   r   r   s         r4   .test_get_transaction_history_date_range_stringzSWalletServiceTransactionHistoryTests.test_get_transaction_history_date_range_stringx  si    08<<>	q 11
||;;!++-'') < 
 	L 126r7   c                     | j                   j                  | j                  j                  d      }| j	                  t        |      d       y)zGet transactions with limit.r   )r;   limitN)r1   r   r   r@   rE   r   r   s     r4   -test_get_transaction_history_pagination_limitzRWalletServiceTransactionHistoryTests.test_get_transaction_history_pagination_limit  s@    ||;;JJMM < 

 	\*A.r7   c                 l   | j                   j                  | j                  j                        }| j                   j                  | j                  j                  d      }| j	                  t        |      t        |      dz
         | j                  |d   j                  |d   j                         y)zGet transactions with offset.r   r#   )r;   offsetr   N)r1   r   r   r@   rE   r   assertNotEqual)r3   all_transactionsoffset_transactionss      r4   .test_get_transaction_history_pagination_offsetzSWalletServiceTransactionHistoryTests.test_get_transaction_history_pagination_offset  s    <<??JJMM @ 
 #llBBJJMM C 

 	0137G3H13LM,Q/224G4J4M4MNr7   c                 N   | j                   j                  | j                  j                        }t	        t        |      dz
        D ][  }t        j                  ||   j                        }t        j                  ||dz      j                        }| j                  ||       ] y)zCTest that transactions are ordered by creation date (newest first).r   r   N)
r1   r   r   r@   r   r   r   fromisoformatr   r   )r3   r   r   date1date2s        r4   %test_get_transaction_history_orderingzJWalletServiceTransactionHistoryTests.test_get_transaction_history_ordering  s    ||;;JJMM < 

 s<(1,-A**<?+@+@AE**<A+>+D+DEE##E51	 .r7   c                    | j                   j                  | j                  j                  ddt              }| j                  t        |      d       |D ]  }| j                  |j                  | j                  j                         | j                  |j                  d       | j                  |j                  d       | j                  |j                  t                y)z'Get transactions with multiple filters.r&   rN   )r;   r<   r   rM   r   N)r1   r   r   r@   r   rE   r   r   r   rQ   rM   r   s      r4   -test_get_transaction_history_combined_filterszRWalletServiceTransactionHistoryTests.test_get_transaction_history_combined_filters  s    ||;;JJMM' %	 < 
 	\*A.CSWWdjjmm4SYY(89SXXs+S^^^<	  r7   c                    | j                   d   }| j                  j                  |      }| j                  |       | j	                  |j
                  |       | j	                  |j                  | j                  j
                         y)zGet a single transaction by ID.r   N)r   r1   rO   rP   rE   r@   r   r   rR   s      r4   test_get_transaction_by_idz?WalletServiceTransactionHistoryTests.test_get_transaction_by_id  sd    --a0ll88H[)8$**--8r7   c                 \    | j                   j                  d      }| j                  |       y)z#Get transaction by non-existent ID.r   N)r1   rO   assertIsNone)r3   r	   s     r4   $test_get_transaction_by_id_not_foundzIWalletServiceTransactionHistoryTests.test_get_transaction_by_id_not_found  s$    ll88?+&r7   c                 r   | j                   j                  | j                  j                        }| j	                  |d       | j                   j                  | j                  j                  d      }| j	                  |d       | j                   j                  t
              }| j	                  |d       y)	z$Count transactions matching filters.r   r   r&   r   r   r   r$   N)r1   count_transactionsr   r@   rE   r   )r3   counts     r4   test_count_transactionsz<WalletServiceTransactionHistoryTests.test_count_transactions  s    //

/F"//JJMM' 0 
 	"//>/J"r7   c                     | j                  t              5  | j                  j                  d       ddd       y# 1 sw Y   yxY w)z)Error case: Invalid point type in filter.r   )r<   N)r   r   r1   r   r2   s    r4   /test_get_transaction_history_invalid_point_typezTWalletServiceTransactionHistoryTests.test_get_transaction_history_invalid_point_type  s7    45LL00) 1  655	   <Ac                     | j                  t              5  | j                  j                  d       ddd       y# 1 sw Y   yxY w)z+Error case: Invalid transaction_type value.xr   N)r   r   r1   r   r2   s    r4   5test_get_transaction_history_invalid_transaction_typezZWalletServiceTransactionHistoryTests.test_get_transaction_history_invalid_transaction_type  s7    12LL00!$ 1  322r  N)r   r   r   r   r5   r   r   r   r   r   r   r   r   r   r  r
  r  r  r  r  r  r  r   r7   r4   r   r     sa    :1-f5	:=,4"< 687/O2= 9'
#r7   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)%WalletServiceSeparateWalletModelTestsz.Tests for using separate wallet balance model.c                 h   t         j                  j                  dd      | _        t        j                  j                  | j                  j
                  t        d            | _        ddd| _        t        t         t        | j                  	      | _
        t        | j                        | _        y
)r   r   r   r    500.00)r;   r&   r#   r   r   )r*   wallet_balance_modelr+   N)r   r-   r.   r/   r   r@   r   walletr+   r   r0   r
   r1   r2   s    r4   r5   z+WalletServiceSeparateWalletModelTests.setUp  s    $$++ZGY+Z	 ((//IILL"8, 0 
  
 %!+((
	
 %TYY/r7   c                    | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  j                          | j                  j                          | j                  | j                  j                  t	        d             | j                  | j                  j                  t	        d             y)z'Add points using separate wallet model.r&   r9   rK   r:   600.00rz   Nr1   r?   r/   r@   r   rA   rB   r!  rD   rE   r&   rF   s     r4   $test_add_point_separate_wallet_modelzJWalletServiceSeparateWalletModelTests.test_add_point_separate_wallet_model  s    //IILL'8$	 0 
 	nc2 	##%		!!#33WX5FG1176?Cr7   c                 :   | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  j                          | j                  | j                  j                  t	        d             y)z*Deduct points using separate wallet model.r&   r9   r   r:   r   N)r1   r   r/   r@   r   rA   rB   r!  rD   rE   r&   rF   s     r4   'test_deduct_point_separate_wallet_modelzMWalletServiceSeparateWalletModelTests.test_deduct_point_separate_wallet_model  su    22IILL'8$ 	 3 
 	nc2##%33WX5FGr7   c                     | j                   j                  j                  | j                  j                  d      }| j                  |t        d             y)z'Get balance from separate wallet model.r&   r  N)r1   
repositoryget_user_balancer/   r@   rE   r   )r3   r   s     r4   +test_get_user_balance_separate_wallet_modelzQWalletServiceSeparateWalletModelTests.test_get_user_balance_separate_wallet_model  sA    ,,))::IILL

 	'("34r7   N)r   r   r   r   r5   r%  r'  r+  r   r7   r4   r  r    s    80&D$H5r7   r  c                       e Zd ZdZd Zd Zy)!WalletServiceCustomFieldNameTestsz$Tests for custom field name mapping.c                     t         j                  j                  dd      | _        ddi| _        t        t         | j                  ddi      | _        t        | j                        | _        y)	r   r   r   r    r'   r   points)r*   r+   point_type_field_mapNr,   r2   s    r4   r5   z'WalletServiceCustomFieldNameTests.setUp*  sg    $$++ZGY+Z	 Q
 %(("
	 %TYY/r7   c                    | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  j                          | j                  | j                  j                  t	        d             | j                  | j                  j                  t	        d             y)z#Add points using custom field name.r'   r   Rewardr:   0N)r1   r?   r/   r@   r   rA   rB   rD   rE   r/  r'   rF   s     r4    test_add_point_custom_field_namezBWalletServiceCustomFieldNameTests.test_add_point_custom_field_name:  s    //IILL&5>	 0 
 	nc2 			!!#))75>:00'#,?r7   N)r   r   r   r   r5   r4  r   r7   r4   r-  r-  '  s    .0 @r7   r-  c                       e Zd ZdZd Zd Zy)'WalletServiceCustomWalletUserFieldTestsz+Tests for custom wallet user_id field name.c                 h   t         j                  j                  dd      | _        t        j                  j                  | j                  j
                  t        d            | _        ddi| _        t        t         t        | j                  d	      | _
        t        | j                        | _        y
)r   r   r   r    r  )owner_idr&   r&   r#   r8  )r*   r   r+   wallet_user_id_fieldN)r   r-   r.   r/   r   r@   r   r!  r+   r   r0   r
   r1   r2   s    r4   r5   z-WalletServiceCustomWalletUserFieldTests.setUpN  s    $$++ZGY+Z	+33::YY\\"8, ; 
 a
 %!6((!+	
	 %TYY/r7   c                 :   | j                   j                  | j                  j                  dt	        d      d      }| j                  |t               | j                  j                          | j                  | j                  j                  t	        d             y)z+Add points using custom user_id field name.r&   r9   rK   r:   r#  Nr$  rF   s     r4   #test_add_point_custom_user_id_fieldzKWalletServiceCustomWalletUserFieldTests.test_add_point_custom_user_id_fielda  su    //IILL'8$	 0 
 	nc2##%33WX5FGr7   N)r   r   r   r   r5   r;  r   r7   r4   r6  r6  K  s    50&Hr7   r6  c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)"WalletServiceTransactionTypesTestsz1Tests for transaction type constants and helpers.c                     t         j                  j                  dd      | _        ddi| _        t        t         | j                        | _        t        | j                        | _        y)r   r   r   r    r&   r#   r)   Nr,   r2   s    r4   r5   z(WalletServiceTransactionTypesTests.setUps  sW    $$++ZGY+Z	,a0$((
	 %TYY/r7   c                    ddl m}m}m} | j	                  |t
               | j	                  |t
               | j	                  |t
               | j                  |d       | j                  |d       | j                  |d       y)z2Test that transaction type constants are integers.r   )r   r   r         N)wallet_utils.transaction_typesr   r   r   rA   rB   rE   )r3   r   r   r   s       r4   test_transaction_type_constantszBWalletServiceTransactionTypesTests.test_transaction_type_constants}  sp    	
 	
 	nc2os3.4.$/)40r7   c                    | j                  t        d      d       | j                  t        d      d       | j                  t        d      d       | j                  t              5  t        d       ddd       y# 1 sw Y   yxY w)	z,Test get_transaction_type() helper function.wallet-depositr@  wallet-withdrawrA  roi-distributionrB  zinvalid-typeN)rE   r   r   
ValueErrorr2   s    r4   test_get_transaction_typez<WalletServiceTransactionTypesTests.test_get_transaction_type  si    -.>?F-.?@$G-.@A4Hz* 0 +**s   'A<<Bc                     | j                  t        d      d       | j                  t        d      d       | j                  t        d      d       | j                  t        d             y)	z1Test get_transaction_type_name() helper function.r@  rF  rA  rG  rB  rH  r   N)rE   r   r  r2   s    r4   test_get_transaction_type_namezAWalletServiceTransactionTypesTests.test_get_transaction_type_name  s[    248:JK248:KL248:LM3E:;r7   c                 J   | j                   j                  | j                  j                  dt	        d      dt
              }| j                   j                  |      }| j                  |j                  t
               t        |j                        }| j                  |d       y)z*Test transaction type is stored correctly.r&   r9   r   rL   rF  N)
r1   r?   r/   r@   r   r   rO   rE   rM   r   )r3   rG   r	   names       r4   +test_transaction_type_in_transaction_recordzNWalletServiceTransactionTypesTests.test_transaction_type_in_transaction_record  s    //IILL'8$% 0 
 ll88H//@ ))?)?@/0r7   N)	r   r   r   r   r5   rD  rJ  rL  rO  r   r7   r4   r=  r=  p  s    ;01 1<1r7   r=  c                   F    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zy)WalletServiceEdgeCasesTestsz"Tests for edge cases and outliers.c                     t         j                  j                  dd      | _        dddd| _        t        t         | j                        | _        t        | j                        | _        y	r   r,   r2   s    r4   r5   z!WalletServiceEdgeCasesTests.setUp  r6   r7   c                     | j                   j                  ddt        d      dd      }| j                   j                  |      }| j	                  |j
                  d       | j	                  |j                  d       y)z)Test using system user ID (-100) for uid.r]   r&   r9   zSystem walletrV   N)r1   r?   r   rO   rE   r   rW   rR   s      r4   test_system_user_idz/WalletServiceEdgeCasesTests.test_system_user_id  so     //'8$# 0 
 ll88H$/$/r7   c                     ddz  }| j                   j                  | j                  j                  dt	        d      |      }| j                   j                  |      }| j                  |j                  |       y)zTest with very long remarks.Ai'  r&   r9   r:   Nr1   r?   r/   r@   r   rO   rE   r   )r3   long_remarksrG   r	   s       r4   test_very_long_remarksz2WalletServiceEdgeCasesTests.test_very_long_remarks  si    U{//IILL'8$ 	 0 
 ll88H**L9r7   c                     | j                   j                  | j                  j                  dt	        d      d      }| j                   j                  |      }| j                  |j                  d       y)zTest with empty remarks.r&   r9    r:   NrW  rR   s      r4   test_empty_remarksz.WalletServiceEdgeCasesTests.test_empty_remarks  s`    //IILL'8$	 0 
 ll88H**B/r7   c                     | j                   j                  | j                  j                  dt	        d      dd      }| j                   j                  |      }| j                  |j                         y)z Test with None transaction type.r&   r9   r   NrL   )r1   r?   r/   r@   r   rO   r  rM   rR   s      r4   test_none_transaction_typez6WalletServiceEdgeCasesTests.test_none_transaction_type  sa    //IILL'8$ 0 
 ll88H+001r7   c                     | j                   j                  | j                  j                  dt	        d      ddi i      }| j                   j                  |      }| j                  |j                  i        y)zTest with empty extra_data.r&   r9   r   r`   rd   Nrf   rR   s      r4   test_empty_extra_dataz1WalletServiceEdgeCasesTests.test_empty_extra_data  sg    //IILL'8$B< 0 
 ll88H//4r7   c                     | j                   j                  | j                  j                  dt	        d      d      }| j                   j                  |      }| j                  |j                  i        y)zTest without params parameter.r&   r9   r   r:   Nrf   rR   s      r4   test_no_paramsz*WalletServiceEdgeCasesTests.test_no_params  s`    //IILL'8$	 0 
 ll88H//4r7   c                 d   t        d      D ]A  }| j                  j                  | j                  j                  dt        d      d|        C | j                  j                          | j                  | j                  j                  t        d             t        d      D ]A  }| j                  j                  | j                  j                  dt        d      d|        C | j                  j                          | j                  | j                  j                  t        d	             y
)z$Test multiple concurrent operations.r   r&   r\   ru   r:   r9   r   r   rJ   N
r   r1   r?   r/   r@   r   rD   rE   r&   r   r3   r   s     r4   #test_multiple_concurrent_operationsz?WalletServiceEdgeCasesTests.test_multiple_concurrent_operations  s     rALL""		+w'"1#	 #   			!!#11783DE qALL%%		+w'%aS)	 &   			!!#11773CDr7   c                 d   t        d      D ]A  }| j                  j                  | j                  j                  dt        d      d|        C | j                  j                          | j                  | j                  j                  t        d             t        d      D ]A  }| j                  j                  | j                  j                  dt        d      d|        C | j                  j                          | j                  | j                  j                  t        d	             y
)z,Test balance accuracy after many operations.d   r&   z0.01zMicro deposit r:   z1.002   zMicro withdrawal z0.50Nrd  re  s     r4   /test_balance_accuracy_after_multiple_operationszKWalletServiceEdgeCasesTests.test_balance_accuracy_after_multiple_operations)  s     sALL""		+v(,	 #   			!!#1176?C rALL%%		+v+A3/	 &   			!!#1176?Cr7   N)r   r   r   r   r5   rT  rY  r\  r^  r`  rb  rf  rj  r   r7   r4   rQ  rQ    s4    ,00 :
025
5E4Dr7   rQ  c                       e Zd ZdZd Zd Zy)WalletServiceRaceConditionTestszCTests for race condition prevention (requires TransactionTestCase).c                 N   t         j                  j                  dd      | _        ddi| _        t        t         | j                        | _        t        | j                        | _        | j                  j                  | j                  j                  dt        d      d	       y
)r   r   r   r    r&   r#   r)   r   r   r:   Nr   r2   s    r4   r5   z%WalletServiceRaceConditionTests.setUpG  s    $$++ZGY+Z	,a0$((
	 %TYY/ 	IILL'9%%	 	 	
r7   c                 t     fd} |       } |       }t        d ||fD              } j                  |d        j                  j                          |dk(  r0 j	                   j                  j
                  t        d             y j	                   j                  j
                  t        d             y)z4Test that atomic deduction prevents race conditions.c                      	  j                   j                   j                  j                  dt	        d      d      S # t
        $ r Y y w xY w)Nr&   r#  zConcurrent withdrawalr:   )r1   r   r/   r@   r   r   r2   s   r4   
deduct_600zaWalletServiceRaceConditionTests.test_atomic_deduction_prevents_race_condition.<locals>.deduct_600^  sQ    ||00 IILL/"8,3	 1   , s   ;? 	A
Ac              3   &   K   | ]	  }|d  y w)Nr   r   ).0rs     r4   	<genexpr>z`WalletServiceRaceConditionTests.test_atomic_deduction_prevents_race_condition.<locals>.<genexpr>o  s     K'9!Q]A'9s   r   r   r   N)sumassertLessEqualr/   rD   rE   r&   r   )r3   rp  result1result2success_counts   `    r4   -test_atomic_deduction_prevents_race_conditionzMWalletServiceRaceConditionTests.test_atomic_deduction_prevents_race_conditionY  s    
		 ,, K'9KK]A. 			!!#ATYY55wx7HI TYY55wy7IJr7   N)r   r   r   r   r5   rz  r   r7   r4   rl  rl  D  s    M
$ Kr7   rl  N)'r   decimalr   r   r   django.testr   r   	django.dbr	   db_transactionwallet_utilsr
   r   wallet_utils.exceptionsr   r   r   r   rC  r   r   r   r   r   r   test_app.modelsr   r   r   r   r   r   r  r-  r6  r=  rQ  rl  r   r7   r4   <module>r     s     ( 5 3 8   H GX Xv_GH _GDF8 FR=5H =5@!@ !@H"Hh "HJ<1 <1~RD( RDj5K&9 5Kr7   