
    >i                     ^   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 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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    H/home/cursorai/projects/django-wallet-utils/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)r0   	add_pointr.   idr   assertIsInstanceintassertGreaterrefresh_from_dbassertEqualr%   r2   transaction_ids     r3   test_add_point_standardz2WalletServiceAddPointTests.test_add_point_standard1   s    //IILL'8$"	 0 
 	nc2>1- 			!!#11783DEr6   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)r0   r>   r.   r?   r   r   r@   rA   get_transaction_by_idassertIsNotNonerD   rL   typer2   rF   r	   s      r3   $test_add_point_with_transaction_typez?WalletServiceAddPointTests.test_add_point_with_transaction_typeA   s    //IILL'7#% 0 
 	nc2 ll88H[)//@))3/r6   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r0   r>   r.   r?   r   rN   rD   rV   )r2   initiator_idrF   r	   s       r3   test_add_point_with_iidz2WalletServiceAddPointTests.test_add_point_with_iidS   sf    //IILL'7#" 0 
 ll88H,7r6   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 depositr9   NrW   rQ   s      r3   test_add_point_system_initiatedz:WalletServiceAddPointTests.test_add_point_system_initiateda   s^    //IILL'7#$	 0 
 ll88H$/r6   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%   r8   zDeposit with extra datadatai90  bank_transfer)
payment_idsourcer:   r;   r<   r=   paramsra   rb   Nr0   r>   r.   r?   r   rN   rD   
extra_datarQ   s      r3   test_add_point_with_extra_dataz9WalletServiceAddPointTests.test_add_point_with_extra_datam   s    //IILL'8$-"'- 0 
 ll88H//=uE//9?Kr6   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%   r8   zCredit depositr9   r&   50zReward pointsr'   
0.00000001zCrypto depositN
r0   r>   r.   r?   r   rC   rD   r%   r&   r'   r1   s    r3   #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Ir6   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 roundingr9   z101.00r&   z50.751r'   z0.123456789z
0.12345679Nrk   r1   s    r3    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Ir6   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 r9   z60.00N)r   r0   r>   r.   r?   rC   rD   r%   r2   amountsr<   s      r3   test_add_point_accumulationz6WalletServiceAddPointTests.test_add_point_accumulation   s    7#WW%5ww7GHFLL""		+"6(+	 #   			!!#11773CDr6   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 depositr9   N)
r0   r>   r.   r?   r   r@   rA   rC   rD   r%   rE   s     r3   test_add_point_zero_amountz5WalletServiceAddPointTests.test_add_point_zero_amount   ss    //IILL'6?"	 0 
 	nc2		!!#1176?Cr6   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'   rj   zVery small depositr9   N)
r0   r>   r.   r?   r   r@   rA   rC   rD   r'   rE   s     r3    test_add_point_very_small_amountz;WalletServiceAddPointTests.test_add_point_very_small_amount   su    //IILL'<((	 0 
 	nc2		!!#117<3HIr6   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 depositr9   N)
r   r0   r>   r.   r?   r@   rA   rC   rD   r%   )r2   large_amountrF   s      r3    test_add_point_very_large_amountz;WalletServiceAddPointTests.test_add_point_very_large_amount   sx     12//IILL'#	 0 
 	nc2		!!#11<@r6   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_typer8   Testr9   N)
assertRaisesr   r0   r>   r.   r?   r   rD   	exceptionr;   r2   cms     r3   !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%   r8   r   
not a dictrc   Nr>   
r   r   r0   r>   r.   r?   r   rD   r   methodr   s     r3   &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%   r8   r   r_   r   rc   Nr>   r   r   s     r3   +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?   wtyperV   uidrP   r<   balancerL   descrcdater%   r8   r   r_   valuerc   Nr>   r   )r2   reserved_fieldsfieldr   s       r3   +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%   r8   r   r9   N)r   r   r0   r>   r   r1   s    r3   test_add_point_nonexistent_userz:WalletServiceAddPointTests.test_add_point_nonexistent_user/  sG     34LL""+x(	 #  544s   )AAN)__name__
__module____qualname____doc__r4   rG   rR   rY   r]   rg   rl   rr   rw   rz   r|   r   r   r   r   r   r    r6   r3   r   r       sd    '0F 0$8
0L&J>J@EDJA$
B;;?	r6   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 depositr9   Nr   r,   r-   r.   r*   r   r/   r
   r0   r>   r?   r   r1   s    r3   r4   z#WalletServiceDeductPointTests.setUp>  s    $$++ZGY+Z	

 %((
	 %TYY/ 	IILL'9%%	 	 	
r6   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%   r8   
Withdrawalr9   r   z900.00N)r0   deduct_pointr.   r?   r   r@   rA   rB   rC   rD   r%   rE   s     r3   test_deduct_point_standardz8WalletServiceDeductPointTests.test_deduct_point_standardT  s    22IILL'8$ 	 3 
 	nc2>1- 			!!#11783DEr6   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%   rI   r   rK   dN)
r0   r   r.   r?   r   r   rN   rD   rL   rP   rQ   s      r3   'test_deduct_point_with_transaction_typezEWalletServiceDeductPointTests.test_deduct_point_with_transaction_typed  sy    22IILL'7# & 3 
 ll88H//A))3/r6   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 withdrawalr9   Ng     @@)r   r   r0   r   r.   r?   r   rO   r   	available	requestedrD   r   s     r3   &test_deduct_point_insufficient_balancezDWalletServiceDeductPointTests.test_deduct_point_insufficient_balancer  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 withdrawalr9   ry   N)
r.   rC   r%   r0   r   r?   r@   rA   rD   r   )r2   current_balancerF   s      r3   test_deduct_point_exact_balancez=WalletServiceDeductPointTests.test_deduct_point_exact_balance  s    		!!#))2222IILL'"%	 3 
 	nc2		!!#1176?Cr6   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)
r0   r   r.   r?   r   r@   rA   rC   rD   r%   rE   s     r3    test_deduct_point_allow_negativez>WalletServiceDeductPointTests.test_deduct_point_allow_negative  sx    22IILL'9% 3 
 	nc2		!!#117:3FGr6   c                    | j                   j                  | j                  j                  dt	        d      d       | j                  j                          | j                  | j                  j                  t	        d             y)rn   r%   ro   rp   r9   z899.00N)r0   r   r.   r?   r   rC   rD   r%   r1   s    r3   #test_deduct_point_decimal_precisionzAWalletServiceDeductPointTests.test_deduct_point_decimal_precision  se     	!!IILL'9%#	 	" 	
 			!!#11783DEr6   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%   ry   zZero withdrawalr9   N)
r.   rC   r%   r0   r   r?   r   r@   rA   rD   )r2   initial_balancerF   s      r3   test_deduct_point_zero_amountz;WalletServiceDeductPointTests.test_deduct_point_zero_amount  s     			!!#))2222IILL'6?%	 3 
 	nc2		!!#11?Cr6   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.r8   z200.00z300.00r%   Withdrawal r9   400.00N)r   r0   r   r.   r?   rC   rD   r%   ru   s      r3   %test_deduct_point_multiple_deductionszCWalletServiceDeductPointTests.test_deduct_point_multiple_deductions  s    8$gh&79JKFLL%%		+%fX.	 &   			!!#11783DEr6   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 testr9   Nr   )
r   r   r0   r   r.   r?   r   rC   rD   r%   r1   s    r3   +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   r4   r   r   r   r   r   r   r   r   r   r   r6   r3   r   r   ;  s>    *
,F 0:D H
FD"FGr6   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.00rt   rK         r&   100zReward N)r   r,   r-   r   r   r*   r   r/   r
   r0   transaction_idsranger>   r?   r   r   appendr   )r2   itids      r3   r4   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   '', r6   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)r0   get_transaction_historyr   r?   rD   lenr   r2   transactionstxns      r3   'test_get_transaction_history_by_user_idzLWalletServiceTransactionHistoryTests.test_get_transaction_history_by_user_id  s\    ||;;DJJMM;R\*A.CSWWdjjmm4  r6   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)r0   r   r   r?   rD   r   r   r   s      r3   *test_get_transaction_history_by_point_typezOWalletServiceTransactionHistoryTests.test_get_transaction_history_by_point_type  s_    ||;;JJMM' < 

 	\*A.CSYY(89  r6   c                     | j                   j                  t              }| j                  t	        |      d       |D ]"  }| j                  |j
                  t               $ y)z(Get transactions filtered by trans_type.rL   r#   N)r0   r   r   rD   r   rL   r   s      r3   *test_get_transaction_history_by_trans_typezOWalletServiceTransactionHistoryTests.test_get_transaction_history_by_trans_type&  sS    ||;;% < 
 	\*A.CS^^^<  r6   c                     | j                   j                  d      }| j                  t        |      d       |D ]  }| j                  |j                  d         y)z2Get transactions filtered by transaction_type='c'.rM   transaction_typer   N)r0   r   rD   r   rP   r   s      r3   7test_get_transaction_history_by_transaction_type_creditz\WalletServiceTransactionHistoryTests.test_get_transaction_history_by_transaction_type_credit0  sS    ||;;  < 
 	\*B/CSXXs+  r6   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   r9   r   r   r   r   N)	r0   r   r   r?   r   r   rD   r   rP   r2   r   s     r3   6test_get_transaction_history_by_transaction_type_debitz[WalletServiceTransactionHistoryTests.test_get_transaction_history_by_transaction_type_debit:  s     	!!JJMM'7# 	 	" 	
 ||;;  < 
 	\*A.a--s3r6   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.rT   r%   rI   r   rU   )rV   r   r   N)	r0   r>   r   r?   r   r   rD   r   rV   )r2   rX   r   s      r3   #test_get_transaction_history_by_iidzHWalletServiceTransactionHistoryTests.test_get_transaction_history_by_iidK  s     JJMM'7# 	 	
 ||;;;M\*A.a,,l;r6   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%   r8   zRecent depositr9   r   )minutes
start_dateend_date)r   r   timesleepr0   r>   r   r?   r   nowr   assertGreaterEqualr   )r2   r   r   r   r   r   r   s          r3   'test_get_transaction_history_date_rangezLWalletServiceTransactionHistoryTests.test_get_transaction_history_date_range[  s    0 	

3 	JJMM'8$$	 	 	
  8<<>	! 44
||;;! < 
 	L 115r6   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   r0   r   	isoformatr   r   )r2   r   r   r   r   r   s         r3   .test_get_transaction_history_date_range_stringzSWalletServiceTransactionHistoryTests.test_get_transaction_history_date_range_stringw  si    08<<>	q 11
||;;!++-'') < 
 	L 126r6   c                     | j                   j                  | j                  j                  d      }| j	                  t        |      d       y)zGet transactions with limit.r   )r:   limitN)r0   r   r   r?   rD   r   r   s     r3   -test_get_transaction_history_pagination_limitzRWalletServiceTransactionHistoryTests.test_get_transaction_history_pagination_limit  s@    ||;;JJMM < 

 	\*A.r6   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)r0   r   r   r?   rD   r   assertNotEqual)r2   all_transactionsoffset_transactionss      r3   .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Nr6   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)
r0   r   r   r?   r   r   r   fromisoformatr   r   )r2   r   r   date1date2s        r3   %test_get_transaction_history_orderingzJWalletServiceTransactionHistoryTests.test_get_transaction_history_ordering  s    ||;;JJMM < 

 s<(1,-A**<?+@+@AE**<A+>+D+DEE##E51	 .r6   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%   rM   )r:   r;   r   rL   r   N)r0   r   r   r?   r   rD   r   r   r   rP   rL   r   s      r3   -test_get_transaction_history_combined_filterszRWalletServiceTransactionHistoryTests.test_get_transaction_history_combined_filters  s    ||;;JJMM' %	 < 
 	\*A.CSWWdjjmm4SYY(89SXXs+S^^^<	  r6   c                    | j                   d   }| j                  j                  |      }| j                  |       | j	                  |j
                  |       | j	                  |j                  | j                  j
                         y)zGet a single transaction by ID.r   N)r   r0   rN   rO   rD   r?   r   r   rQ   s      r3   test_get_transaction_by_idz?WalletServiceTransactionHistoryTests.test_get_transaction_by_id  sd    --a0ll88H[)8$**--8r6   c                 \    | j                   j                  d      }| j                  |       y)z#Get transaction by non-existent ID.r   N)r0   rN   assertIsNone)r2   r	   s     r3   $test_get_transaction_by_id_not_foundzIWalletServiceTransactionHistoryTests.test_get_transaction_by_id_not_found  s$    ll88?+&r6   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)r0   count_transactionsr   r?   rD   r   )r2   counts     r3   test_count_transactionsz<WalletServiceTransactionHistoryTests.test_count_transactions  s    //

/F"//JJMM' 0 
 	"//>/J"r6   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   r0   r   r1   s    r3   /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   r0   r   r1   s    r3   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   r4   r   r   r   r   r   r   r   r   r   r  r	  r  r  r  r  r  r  r   r6   r3   r   r     sa    :1-f5	:=,4"< 687/O2= 9'
#r6   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   r/   r
   r0   r1   s    r3   r4   z+WalletServiceSeparateWalletModelTests.setUp  s    $$++ZGY+Z	 ((//IILL"8, 0 
  
 %!+((
	
 %TYY/r6   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%   r8   rJ   r9   600.00ry   Nr0   r>   r.   r?   r   r@   rA   r   rC   rD   r%   rE   s     r3   $test_add_point_separate_wallet_modelzJWalletServiceSeparateWalletModelTests.test_add_point_separate_wallet_model  s    //IILL'8$	 0 
 	nc2 	##%		!!#33WX5FG1176?Cr6   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%   r8   r   r9   r   N)r0   r   r.   r?   r   r@   rA   r   rC   rD   r%   rE   s     r3   'test_deduct_point_separate_wallet_modelzMWalletServiceSeparateWalletModelTests.test_deduct_point_separate_wallet_model  su    22IILL'8$ 	 3 
 	nc2##%33WX5FGr6   c                     | j                   j                  j                  | j                  j                  d      }| j                  |t        d             y)z'Get balance from separate wallet model.r%   r  N)r0   
repositoryget_user_balancer.   r?   rD   r   )r2   r   s     r3   +test_get_user_balance_separate_wallet_modelzQWalletServiceSeparateWalletModelTests.test_get_user_balance_separate_wallet_model  sA    ,,))::IILL

 	'("34r6   N)r   r   r   r   r4   r$  r&  r*  r   r6   r3   r  r    s    80&D$H5r6   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+   r1   s    r3   r4   z'WalletServiceCustomFieldNameTests.setUp)  sg    $$++ZGY+Z	 Q
 %(("
	 %TYY/r6   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   Rewardr9   0N)r0   r>   r.   r?   r   r@   rA   rC   rD   r.  r&   rE   s     r3    test_add_point_custom_field_namezBWalletServiceCustomFieldNameTests.test_add_point_custom_field_name9  s    //IILL&5>	 0 
 	nc2 			!!#))75>:00'#,?r6   N)r   r   r   r   r4   r3  r   r6   r3   r,  r,  &  s    .0 @r6   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"   r7  )r)   r  r*   wallet_user_id_fieldN)r   r,   r-   r.   r   r?   r   r   r*   r   r/   r
   r0   r1   s    r3   r4   z-WalletServiceCustomWalletUserFieldTests.setUpM  s    $$++ZGY+Z	+33::YY\\"8, ; 
 a
 %!6((!+	
	 %TYY/r6   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%   r8   rJ   r9   r"  Nr#  rE   s     r3   #test_add_point_custom_user_id_fieldzKWalletServiceCustomWalletUserFieldTests.test_add_point_custom_user_id_field`  su    //IILL'8$	 0 
 	nc2##%33WX5FGr6   N)r   r   r   r   r4   r:  r   r6   r3   r5  r5  J  s    50&Hr6   r5  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+   r1   s    r3   r4   z(WalletServiceTransactionTypesTests.setUpr  sW    $$++ZGY+Z	,a0$((
	 %TYY/r6   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   r@   rA   rD   )r2   r   r   r   s       r3   test_transaction_type_constantszBWalletServiceTransactionTypesTests.test_transaction_type_constants|  sp    	
 	
 	nc2os3.4.$/)40r6   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-withdrawr@  roi-distributionrA  zinvalid-typeN)rD   r   r   
ValueErrorr1   s    r3   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?  rE  r@  rF  rA  rG  r   N)rD   r   r  r1   s    r3   test_get_transaction_type_namezAWalletServiceTransactionTypesTests.test_get_transaction_type_name  s[    248:JK248:KL248:LM3E:;r6   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%   r8   r   rK   rE  N)
r0   r>   r.   r?   r   r   rN   rD   rL   r   )r2   rF   r	   names       r3   +test_transaction_type_in_transaction_recordzNWalletServiceTransactionTypesTests.test_transaction_type_in_transaction_record  s    //IILL'8$% 0 
 ll88H//@ ))?)?@/0r6   N)	r   r   r   r   r4   rC  rI  rK  rN  r   r6   r3   r<  r<  o  s    ;01 1<1r6   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+   r1   s    r3   r4   z!WalletServiceEdgeCasesTests.setUp  r5   r6   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%   r8   zSystem walletrU   N)r0   r>   r   rN   rD   r   rV   rQ   s      r3   test_system_user_idz/WalletServiceEdgeCasesTests.test_system_user_id  so     //'8$# 0 
 ll88H$/$/r6   c                     ddz  }| j                   j                  | j                  j                  dt	        d      |      }| j                   j                  |      }| j                  |j                  |       y)zTest with very long remarks.Ai'  r%   r8   r9   Nr0   r>   r.   r?   r   rN   rD   r   )r2   long_remarksrF   r	   s       r3   test_very_long_remarksz2WalletServiceEdgeCasesTests.test_very_long_remarks  si    U{//IILL'8$ 	 0 
 ll88H**L9r6   c                     | j                   j                  | j                  j                  dt	        d      d      }| j                   j                  |      }| j                  |j                  d       y)zTest with empty remarks.r%   r8    r9   NrV  rQ   s      r3   test_empty_remarksz.WalletServiceEdgeCasesTests.test_empty_remarks  s`    //IILL'8$	 0 
 ll88H**B/r6   c                     | j                   j                  | j                  j                  dt	        d      dd      }| j                   j                  |      }| j                  |j                         y)z Test with None transaction type.r%   r8   r   NrK   )r0   r>   r.   r?   r   rN   r  rL   rQ   s      r3   test_none_transaction_typez6WalletServiceEdgeCasesTests.test_none_transaction_type  sa    //IILL'8$ 0 
 ll88H+001r6   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%   r8   r   r_   rc   Nre   rQ   s      r3   test_empty_extra_dataz1WalletServiceEdgeCasesTests.test_empty_extra_data  sg    //IILL'8$B< 0 
 ll88H//4r6   c                     | j                   j                  | j                  j                  dt	        d      d      }| j                   j                  |      }| j                  |j                  i        y)zTest without params parameter.r%   r8   r   r9   Nre   rQ   s      r3   test_no_paramsz*WalletServiceEdgeCasesTests.test_no_params  s`    //IILL'8$	 0 
 ll88H//4r6   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[   rt   r9   r8   r   r   rI   N
r   r0   r>   r.   r?   r   rC   rD   r%   r   r2   r   s     r3   #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Dr6   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 r9   z1.002   zMicro withdrawal z0.50Nrc  rd  s     r3   /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?Cr6   N)r   r   r   r   r4   rS  rX  r[  r]  r_  ra  re  ri  r   r6   r3   rP  rP    s4    ,00 :
025
5E4Dr6   rP  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   r9   Nr   r1   s    r3   r4   z%WalletServiceRaceConditionTests.setUpF  s    $$++ZGY+Z	,a0$((
	 %TYY/ 	IILL'9%%	 	 	
r6   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 withdrawalr9   )r0   r   r.   r?   r   r   r1   s   r3   
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     r3   	<genexpr>z`WalletServiceRaceConditionTests.test_atomic_deduction_prevents_race_condition.<locals>.<genexpr>n  s     K'9!Q]A'9s   r   r   r   N)sumassertLessEqualr.   rC   rD   r%   r   )r2   ro  result1result2success_counts   `    r3   -test_atomic_deduction_prevents_race_conditionzMWalletServiceRaceConditionTests.test_atomic_deduction_prevents_race_conditionX  s    
		 ,, K'9KK]A. 			!!#ATYY55wx7HI TYY55wy7IJr6   N)r   r   r   r   r4   ry  r   r6   r3   rk  rk  C  s    M
$ Kr6   rk  N)&r   decimalr   r   r   django.testr   r   	django.dbr	   db_transactionwallet_utilsr
   r   wallet_utils.exceptionsr   r   r   r   rB  r   r   r   r   r   tests.modelsr   r   r   r   r   r   r  r,  r5  r<  rP  rk  r   r6   r3   <module>r     s     ( 5 3 8   E D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r6   