Ë
    ñçHiú7  ã                   óŠ   — d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 ddl
mZmZmZ ddlmZ ddlmZ d	d
lmZ  G d„ de«      Zy)z!Tests for point transfer feature.é    )ÚDecimal)ÚMockÚpatch)ÚTestCase)ÚWalletService)ÚInsufficientBalanceErrorÚInvalidParamsErrorÚUserNotFoundError)Útransfer_completed)ÚWALLET_TRANSFERé   )ÚTestUserc                   ój   — 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y)ÚTransferPointsTestsz*Test cases for the transfer_points method.c                 ó†  — ddl m} t        j                  j	                  dd¬«      | _        t        j                  j	                  dd¬«      | _        dddd	œ} |t        |¬
«      | _        t        | j                  «      | _	        | j                  j                  | j
                  j                  dt        d«      d¬«       y)zSet up test data.r   )ÚWalletRepositoryÚuser1zuser1@test.com)ÚusernameÚemailÚuser2zuser2@test.comé   )Úcash_balanceÚcredit_balanceÚreward_points)Ú
user_modelÚpoint_typesr   ú1000.00zInitial balance©Úuser_idÚ
point_typeÚamountÚremarksN)Úwallet_utilsr   r   ÚobjectsÚcreater   r   Úrepor   ÚserviceÚ	add_pointÚidr   )Úselfr   r   s      úI/home/cursorai/projects/django-wallet-utils/tests/test_transfer_points.pyÚsetUpzTransferPointsTests.setUp   s§   € å1ô ×%Ñ%×,Ñ,°gÐEUÐ,ÓVˆŒ
Ü×%Ñ%×,Ñ,°gÐEUÐ,ÓVˆŒ
ð ØØñ
ˆñ
 %´ÀkÔRˆŒ	Ü$ T§Y¡YÓ/ˆŒð 	�‰×ÑØ—J‘J—M‘MØ%Ü˜9Ó%Ø%ð	 	õ 	
ó    c                 ó  — t        d«      }| j                  j                  | j                  j                  | j
                  j                  dd|d¬«      }| j                  d|«       | j                  d|«       | j                  d|«       | j                  |d   | j                  j                  «       | j                  |d	   | j
                  j                  «       | j                  |d
   |«       | j                  j                  | j                  j                  d«      }| j                  j                  | j
                  j                  d«      }| j                  |t        d«      «       | j                  |t        d«      «       y)z8Test transferring points of the same type between users.ú100.00r   zTransfer test©Úfrom_user_idÚ
to_user_idÚfrom_point_typeÚto_point_typer!   r"   Útransfer_idÚfrom_transaction_idÚto_transaction_idr1   r2   r!   z900.00N)
r   r'   Útransfer_pointsr   r)   r   ÚassertInÚassertEqualr&   Úget_user_balance)r*   Útransfer_amountÚresultÚuser1_balanceÚuser2_balances        r+   Útest_transfer_same_point_typez1TransferPointsTests.test_transfer_same_point_type0   s0  € ô " (Ó+ˆð —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø*Ø(Ø"Ø#ð .ó 
ˆð 	�‰�m VÔ,Ø�‰Ð+¨VÔ4Ø�‰Ð)¨6Ô2Ø×Ñ˜ Ñ/°·±·±Ô?Ø×Ñ˜ Ñ-¨t¯z©z¯}©}Ô=Ø×Ñ˜ Ñ)¨?Ô;ð Ÿ	™	×2Ñ2°4·:±:·=±=À.ÓQˆØŸ	™	×2Ñ2°4·:±:·=±=À.ÓQˆØ×Ñ˜¬°Ó(9Ô:Ø×Ñ˜¬°Ó(9Õ:r-   c                 ó,  — t        d«      }| j                  j                  | j                  j                  | j
                  j                  dd|d¬«      }| j                  |d   d«       | j                  |d   d«       | j                  j                  | j                  j                  d«      }| j                  j                  | j
                  j                  d«      }| j                  |t        d«      «       | j                  |t        d«      «       y	)
z6Test transferring points across different point types.ú50.00r   r   zCash to credit transferr0   r3   r4   z950.00N)	r   r'   r8   r   r)   r   r:   r&   r;   )r*   r<   r=   Ú
user1_cashÚuser2_credits        r+   Útest_transfer_cross_typez,TransferPointsTests.test_transfer_cross_typeM   sâ   € ô " 'Ó*ˆð —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø*Ø*Ø"Ø-ð .ó 
ˆð 	×Ñ˜Ð 1Ñ2°NÔCØ×Ñ˜ Ñ0Ð2BÔCð —Y‘Y×/Ñ/°·
±
·±¸~ÓNˆ
Ø—y‘y×1Ñ1°$·*±*·-±-ÐAQÓRˆØ×Ñ˜¤W¨XÓ%6Ô7Ø×Ñ˜¤w¨wÓ'7Õ8r-   c                 ó  — t        d«      }| j                  j                  | j                  j                  | j                  j                  dd|d¬«      }| j                  |d   |d   «       | j                  j                  | j                  j                  d«      }| j                  j                  | j                  j                  d«      }| j                  |t        d«      «       | j                  |t        d«      «       y	)
z6Test self-transfer (same user, different point types).z200.00r   r   zConvert cash to creditr0   r1   r2   z800.00N)r   r'   r8   r   r)   r:   r&   r;   )r*   r<   r=   ÚcashÚcredits        r+   Útest_transfer_selfz&TransferPointsTests.test_transfer_selff   sÐ   € ô " (Ó+ˆð —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø*Ø*Ø"Ø,ð .ó 
ˆð 	×Ñ˜ Ñ/°¸Ñ1EÔFð �y‰y×)Ñ)¨$¯*©*¯-©-¸ÓHˆØ—‘×+Ñ+¨D¯J©J¯M©MÐ;KÓLˆØ×Ñ˜œw xÓ0Ô1Ø×Ñ˜¤¨Ó!2Õ3r-   c           	      ó”  — t        d«      }| j                  t        «      5 }| j                  j	                  | j
                  j                  | j                  j                  dd|d¬«       ddd«       | j                  j                  j                  «       | j                  |j                  j                  «       y# 1 sw Y   ŒTxY w)z(Test transfer with insufficient balance.z2000.00r   zOver budgetr0   N)r   ÚassertRaisesr   r'   r8   r   r)   r   ÚassertIsNotNoneÚ	exceptionÚ	availableÚ	requested)r*   r<   Úctxs      r+   Ú"test_transfer_insufficient_balancez6TransferPointsTests.test_transfer_insufficient_balance~   sš   € ô " )Ó,ˆð ×ÑÔ7Ô8¸CØ�L‰L×(Ñ(Ø!ŸZ™ZŸ]™]ØŸ:™:Ÿ=™=Ø .Ø,Ø&Ø%ð )ô ÷ 9ð 	×Ñ˜SŸ]™]×4Ñ4Ô5Ø×Ñ˜SŸ]™]×4Ñ4Õ5÷ 9Ð8ús   ¡A
B>Â>Cc           
      ó$  — d}| j                  t        «      5 }| j                  j                  | j                  j
                  |ddt        d«      d¬«       ddd«       | j                  j                  j                  |«       y# 1 sw Y   Œ0xY w)z+Test transfer to a user that doesn't exist.iŸ† r   r/   zTo ghostr0   N)
rK   r
   r'   r8   r   r)   r   r:   rM   r   )r*   Únonexistent_user_idrP   s      r+   Ú#test_transfer_nonexistent_recipientz7TransferPointsTests.test_transfer_nonexistent_recipient’   s~   € ð $Ðð ×ÑÔ0Ô1°SØ�L‰L×(Ñ(Ø!ŸZ™ZŸ]™]Ø.Ø .Ø,Ü˜xÓ(Ø"ð )ô ÷ 2ð 	×Ñ˜Ÿ™×.Ñ.Ð0CÕD÷ 2Ð1ús   ˜?BÂBc           
      óH  — | j                  t        «      5 }| j                  j                  | j                  j
                  | j                  j
                  ddt        d«      d¬«       ddd«       | j                  j                  j                  d«       y# 1 sw Y   Œ0xY w)z#Test transfer with negative amount.r   z-50.00zNegative testr0   Nr8   ©rK   r	   r'   r8   r   r)   r   r   r:   rM   Úmethod©r*   rP   s     r+   Útest_transfer_negative_amountz1TransferPointsTests.test_transfer_negative_amount¥   s~   € ð ×ÑÔ1Ô2°cØ�L‰L×(Ñ(Ø!ŸZ™ZŸ]™]ØŸ:™:Ÿ=™=Ø .Ø,Ü˜xÓ(Ø'ð )ô ÷ 3ð 	×Ñ˜Ÿ™×-Ñ-Ð/@ÕA÷ 3Ð2úó   –ABÂB!c           
      óH  — | j                  t        «      5 }| j                  j                  | j                  j
                  | j                  j
                  ddt        d«      d¬«       ddd«       | j                  j                  j                  d«       y# 1 sw Y   Œ0xY w)zTest transfer with zero amount.r   z0.00z	Zero testr0   Nr8   rV   rX   s     r+   Útest_transfer_zero_amountz-TransferPointsTests.test_transfer_zero_amount´   s}   € ð ×ÑÔ1Ô2°cØ�L‰L×(Ñ(Ø!ŸZ™ZŸ]™]ØŸ:™:Ÿ=™=Ø .Ø,Ü˜v“Ø#ð )ô ÷ 3ð 	×Ñ˜Ÿ™×-Ñ-Ð/@ÕA÷ 3Ð2úrZ   c           	      óT  — dddœ}| j                   j                  | j                  j                  | j                  j                  ddt        d«      d|¬«      }| j                   j                  |d   «      }| j                   j                  |d	   «      }| j                  d
|j                  «       | j                  |j                  d
   d«       | j                  d|j                  «       | j                  |j                  d   | j                  j                  «       | j                  d|j                  «       | j                  |j                  d   d«       | j                  d|j                  «       | j                  |j                  d   | j                  j                  «       y)z#Test transfer with custom metadata.zORD-123Úsummer_promo)Úorder_idÚcampaignr   z75.00zPromo transfer)r1   r2   r3   r4   r!   r"   Úmetadatar6   r7   r_   Útransfer_tor`   Útransfer_fromN)
r'   r8   r   r)   r   r   Úget_transaction_by_idr9   Ú
extra_datar:   )r*   ra   r=   Úfrom_recordÚ	to_records        r+   Útest_transfer_with_metadataz/TransferPointsTests.test_transfer_with_metadataÃ   sU  € ð !*°~ÑFˆð —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø*Ø(Ü˜7Ó#Ø$Øð .ó 
ˆð —l‘l×8Ñ8¸Ð@UÑ9VÓWˆØ—L‘L×6Ñ6°vÐ>QÑ7RÓSˆ	à�‰�j +×"8Ñ"8Ô9Ø×Ñ˜×/Ñ/°
Ñ;¸YÔGØ�‰�m [×%;Ñ%;Ô<Ø×Ñ˜×/Ñ/°Ñ>ÀÇ
Á
ÇÁÔNà�‰�j )×"6Ñ"6Ô7Ø×Ñ˜×-Ñ-¨jÑ9¸>ÔJØ�‰�o y×';Ñ';Ô<Ø×Ñ˜×-Ñ-¨oÑ>ÀÇ
Á
ÇÁÕNr-   c                 ó2  — | j                   j                  }d„ }t        j                  | j                   d|¬«      5  | j	                  t
        «      5  | j                   j                  | j                  j                  | j                  j                  ddt        d«      d¬«       ddd«       ddd«       | j                  j                  | j                  j                  d«      }| j                  |t        d	«      «       y# 1 sw Y   Œ]xY w# 1 sw Y   ŒaxY w)
z9Test that transfer is atomic (both succeed or both fail).c                  ó   — t        d«      ‚)NzSimulated failure)Ú	Exception)ÚargsÚkwargss     r+   Úfailing_add_pointzFTransferPointsTests.test_transfer_atomicity.<locals>.failing_add_pointé   s   € ÜÐ/Ó0Ð0r-   r(   )Úside_effectr   r/   zShould failr0   Nr   )r'   r(   r   ÚobjectrK   rk   r8   r   r)   r   r   r&   r;   r:   )r*   Úoriginal_add_pointrn   Úbalances       r+   Útest_transfer_atomicityz+TransferPointsTests.test_transfer_atomicityá   sÏ   € ð "Ÿ\™\×3Ñ3Ðò	1ô �\‰\˜$Ÿ,™,¨ÐARÖSØ×"Ñ"¤9Õ-Ø—‘×,Ñ,Ø!%§¡§¡Ø#Ÿz™zŸ}™}Ø$2Ø"0Ü" 8Ó,Ø)ð -ô ÷ .÷ Tð —)‘)×,Ñ,¨T¯Z©Z¯]©]¸NÓKˆØ×Ñ˜¤'¨)Ó"4Õ5÷ .Ð-ú÷ TÐSús$   ¼DÁADÂ%DÄD
	ÄDÄDc           	      óâ  ‡— g Šˆfd„}t        j                  |«       	 | j                  j                  | j                  j
                  | j                  j
                  ddt        d«      d¬«      }| j                  t        ‰«      d«       ‰d   }| j                  |d   |d   «       | j                  |d	   | j                  j
                  «       | j                  |d
   | j                  j
                  «       | j                  |d   t        d«      «       | j                  |d   «       | j                  |d   «       t        j                  |«       y# t        j                  |«       w xY w)zFTest that transfer_completed signal is sent after successful transfer.c                 ó(   •— ‰j                  |«       y )N)Úappend)Úsenderrm   Úsignal_receiveds     €r+   Úsignal_handlerzETransferPointsTests.test_transfer_signal_sent.<locals>.signal_handler  s   ø€ Ø×"Ñ" 6Õ*r-   r   r/   zSignal testr0   r   r   r5   r1   r2   r!   rf   rg   N)r   Úconnectr'   r8   r   r)   r   r   r:   ÚlenrL   Ú
disconnect)r*   ry   r=   Úsignal_datarx   s       @r+   Útest_transfer_signal_sentz-TransferPointsTests.test_transfer_signal_sentü   s7  ø€ ð ˆô	+ô 	×"Ñ" >Ô2ð	:à—\‘\×1Ñ1Ø!ŸZ™ZŸ]™]ØŸ:™:Ÿ=™=Ø .Ø,Ü˜xÓ(Ø%ð 2ó ˆFð ×ÑœS Ó1°1Ô5Ø)¨!Ñ,ˆKØ×Ñ˜[¨Ñ7¸ÀÑ9NÔOØ×Ñ˜[¨Ñ8¸$¿*¹*¿-¹-ÔHØ×Ñ˜[¨Ñ6¸¿
¹
¿¹ÔFØ×Ñ˜[¨Ñ2´G¸HÓ4EÔFØ× Ñ  ¨]Ñ!;Ô<Ø× Ñ  ¨[Ñ!9Ô:ä×)Ñ)¨.Õ9øÔ×)Ñ)¨.Õ9ús   ŸD"E ÅE.c           	      óž  — ddl m} | j                  j                  | j                  j
                  | j                  j
                  ddt        d«      d|¬«      }| j                  j                  |d   «      }| j                  j                  |d   «      }| j                  |j                  |«       | j                  |j                  |«       y	)
z+Test transfer with custom transaction type.r   )ÚSYSTEM_REWARDr   rB   zCustom type test)r1   r2   r3   r4   r!   r"   Ú
trans_typer6   r7   N)Úwallet_utils.transaction_typesr€   r'   r8   r   r)   r   r   rd   r:   r�   )r*   r€   r=   rf   rg   s        r+   Útest_transfer_custom_trans_typez3TransferPointsTests.test_transfer_custom_trans_type  s¯   € õ 	Að —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø*Ø(Ü˜7Ó#Ø&Ø$ð .ó 
ˆð —l‘l×8Ñ8¸Ð@UÑ9VÓWˆØ—L‘L×6Ñ6°vÐ>QÑ7RÓSˆ	Ø×Ñ˜×/Ñ/°Ô?Ø×Ñ˜×-Ñ-¨}Õ=r-   c           	      ó–  — d}| j                   j                  | j                  j                  | j                  j                  ddt        d«      d|¬«      }| j                   j                  |d   «      }| j                   j                  |d   «      }| j                  |j                  |«       | j                  |j                  |«       y)	z'Test transfer with custom initiator ID.éc   r   z25.00zAdmin transfer)r1   r2   r3   r4   r!   r"   Úiidr6   r7   N)	r'   r8   r   r)   r   r   rd   r:   r†   )r*   Úadmin_user_idr=   rf   rg   s        r+   Útest_transfer_with_custom_iidz1TransferPointsTests.test_transfer_with_custom_iid3  s¬   € ð ˆð —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø*Ø(Ü˜7Ó#Ø$Øð .ó 
ˆð —l‘l×8Ñ8¸Ð@UÑ9VÓWˆØ—L‘L×6Ñ6°vÐ>QÑ7RÓSˆ	Ø×Ñ˜Ÿ™¨-Ô8Ø×Ñ˜Ÿ™¨Õ6r-   c           	      óp  — | j                   j                  | j                  j                  | j                  j                  ddt        d«      d¬«      }h d£}| j                  t        |j                  «       «      |«       | j                  d|d   «       |d   › d|d	   › �}| j                  |d   |«       y
)z/Test that transfer returns all expected values.r   r/   zComplete testr0   >   r!   ÚsuccessÚ
to_balancer2   r5   Úfrom_balancer1   r4   r3   r7   r6   Ú:r5   r6   r7   N)
r'   r8   r   r)   r   r   r:   ÚsetÚkeysr9   )r*   r=   Úexpected_keysÚexpected_ids       r+   Útest_transfer_return_valuesz/TransferPointsTests.test_transfer_return_valuesI  s°   € ð —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø*Ø(Ü˜8Ó$Ø#ð .ó 
ˆò
ˆð 	×Ñœ˜VŸ[™[›]Ó+¨]Ô;ð 	�‰�c˜6 -Ñ0Ô1ØÐ 5Ñ6Ð7°q¸Ð@SÑ9TÐ8UÐVˆØ×Ñ˜ Ñ.°Õ<r-   c           	      óL  — | j                   j                  | j                  j                  dt	        d«      d¬«       | j                   j                  | j                  j                  | j                  j                  ddt	        d«      d¬«      }| j                  j                  | j                  j                  d«      }| j                  j                  | j                  j                  d«      }| j                  |t	        d«      «       | j                  |t	        d	«      «       y
)z>Test that transfer respects decimal precision for point types.r   Ú100zInitial pointsr   z25.999zRounding testr0   Ú74Ú26N)
r'   r(   r   r)   r   r8   r   r&   r;   r:   )r*   r=   Úuser1_pointsÚuser2_pointss       r+   Útest_transfer_decimal_precisionz3TransferPointsTests.test_transfer_decimal_precisionj  sÛ   € ð 	�‰×ÑØ—J‘J—M‘MØ&Ü˜5“>Ø$ð	 	ô 	
ð —‘×-Ñ-ØŸ™Ÿ™Ø—z‘z—}‘}Ø+Ø)Ü˜8Ó$Ø#ð .ó 
ˆð —y‘y×1Ñ1°$·*±*·-±-ÀÓQˆØ—y‘y×1Ñ1°$·*±*·-±-ÀÓQˆà×Ñ˜¤w¨t£}Ô5Ø×Ñ˜¤w¨t£}Õ5r-   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r,   r@   rE   rI   rQ   rT   rY   r\   rh   rs   r~   rƒ   rˆ   r’   r™   © r-   r+   r   r      sV   „ Ù4ò
ò2;ò:9ò24ò06ò(Eò&BòBòOò<6ò6:òB>ò,7ò,=óB6r-   r   N)r�   Údecimalr   Úunittest.mockr   r   Údjango.testr   r#   r   Úwallet_utils.exceptionsr   r	   r
   Úwallet_utils.signalsr   r‚   r   Úmodelsr   r   rž   r-   r+   Ú<module>r¥      s7   ðÙ 'å ß %å  å &÷ñ õ
 4Ý :å ôo6˜(õ o6r-   