
    BkJiD                         d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZmZ  G d de      Z G d	 d
e      Z G d de      Z G d de      Zy)z-Tests for the hook system core functionality.    )Decimal)TestCase)HookManagerHookRegistryHookTypePostHookError)HookContext)HookRejectionErrorHookExecutionErrorc                   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)TestHookRegistryzTests for HookRegistry class.c                 0   t               }dt        dt        fd}|j                  dt        j
                  |dd       |j                  dt        j
                        }t        |      dk(  sJ |d	   j                  dk(  sJ |d	   j                  dk(  sJ y
)zTest registering a basic hook.contextreturnc                      yNT r   s    ?/home/cursorai/projects/django-wallet-utils/tests/test_hooks.pymy_hookz:TestHookRegistry.test_register_hook_basic.<locals>.my_hook           	test_hookaddd   name	hook_typecallback	operationpriority   r   N)
r   r	   boolregisterr   PRE	get_hookslenr   r!   )selfregistryr   hookss       r   test_register_hook_basicz)TestHookRegistry.test_register_hook_basic   s    >	[ 	T 	 	ll 	 	
 ""5(,,75zQQx}}+++Qx  C'''r   c                 (   t               }dt        dt        fd}dt        dt        fd}dt        dt        fd}|j                  dt        j
                  |dd	       |j                  d
t        j
                  |dd	       |j                  dt        j
                  |dd	       |j                  dt        j
                        }t        |      dk(  sJ |d   j                  d
k(  sJ |d   j                  dk(  sJ |d   j                  dk(  sJ y)z'Test that hooks are sorted by priority.r   r   c                      yr   r   r   s    r   hook1z@TestHookRegistry.test_register_hook_with_priority.<locals>.hook1+   r   r   c                      yr   r   r   s    r   hook2z@TestHookRegistry.test_register_hook_with_priority.<locals>.hook2.   r   r   c                      yr   r   r   s    r   hook3z@TestHookRegistry.test_register_hook_with_priority.<locals>.hook31   r   r   hook_lowr   i  r!   	hook_high
   hook_mediumr      r   r"      N	r   r	   r#   r$   r   r%   r&   r'   r   )r(   r)   r.   r0   r2   r*   s         r    test_register_hook_with_priorityz1TestHookRegistry.test_register_hook_with_priority'   s   >	; 	4 		; 	4 		; 	4 	 	*hllE53O+x||UEBO-uecR""5(,,75zQQx}}+++Qx}}---Qx}}
***r   c                    t               }dt        dt        fd}|j                  dt        j
                  |dd       dD ]F  }|j                  |t        j
                        }t        |      d	k(  sJ |d
   j                  dk(  rFJ  y)z>Test registering a global hook that applies to all operations.r   r   c                      yr   r   r   s    r   global_hookz?TestHookRegistry.test_register_global_hook.<locals>.global_hookC   r   r   r>   *r   r   )r   deducttransferr"   r   Nr:   )r(   r)   r>   r    r*   s        r   test_register_global_hookz*TestHookRegistry.test_register_global_hook?   s    >	 	 	 	ll  	 	
 7I&&y(,,?Eu:?"?8==M111 7r   c                 ^   t               }dt        dt        fd}|j                  dt        j
                  |d       | j                  t              5 }|j                  dt        j
                  |d       ddd       | j                  dt        j                               y# 1 sw Y   /xY w)	z>Test that registering a hook with duplicate name raises error.r   r   c                      yr   r   r   s    r   r.   zITestHookRegistry.test_register_duplicate_name_raises_error.<locals>.hook1X   r   r   	duplicater   r@   Nzalready registered)r   r	   r#   r$   r   r%   assertRaises
ValueErrorassertInstr	exceptionr(   r)   r.   cms       r   )test_register_duplicate_name_raises_errorz:TestHookRegistry.test_register_duplicate_name_raises_errorT   s    >	; 	4 	 	+x||UEB z*bk8<<I +*C,=> +*s   #B##B,c                    t               }dt        dt        fd}| j                  t              5 }|j                  dt        j                  |d       ddd       | j                  dt        j                               y# 1 sw Y   /xY w)z:Test that registering with invalid operation raises error.r   r   c                      yr   r   r   s    r   r.   zLTestHookRegistry.test_register_invalid_operation_raises_error.<locals>.hook1f   r   r   test
invalid_opNzInvalid operation)r   r	   r#   rF   rG   r$   r   r%   rH   rI   rJ   rK   s       r   ,test_register_invalid_operation_raises_errorz=TestHookRegistry.test_register_invalid_operation_raises_errorb   sl    >	; 	4 	 z*bfhllE<H +)3r||+<= +*s   #BB
c                 b   t               }dt        dt        fd}|j                  dt        j
                  |d       t        |j                  dt        j
                              dk(  sJ |j                  d      }|du sJ t        |j                  dt        j
                              dk(  sJ y	)
zTest unregistering a hook.r   r   c                      yr   r   r   s    r   r   z6TestHookRegistry.test_unregister_hook.<locals>.my_hookq   r   r   r   r   r"   Tr   N)	r   r	   r#   r$   r   r%   r'   r&   
unregister)r(   r)   r   results       r   test_unregister_hookz%TestHookRegistry.test_unregister_hookm   s    >	[ 	T 	 	+x||WeD8%%eX\\:;q@@@ $$[1~~8%%eX\\:;q@@@r   c                 F    t               }|j                  d      }|du sJ y)z-Test unregistering a hook that doesn't exist.nonexistentFN)r   rU   )r(   r)   rV   s      r    test_unregister_nonexistent_hookz1TestHookRegistry.test_unregister_nonexistent_hook|   s%    >$$]3r   c                    t               }dt        dt        fd}dt        ddfd}|j                  dt        j
                  |d       |j                  dt        j                  |d       |j                  dt        j
                        }|j                  dt        j                        }t        |      d	k(  sJ |d
   j                  dk(  sJ t        |      d	k(  sJ |d
   j                  dk(  sJ y)z)Test that get_hooks filters by hook type.r   r   c                      yr   r   r   s    r   pre_hookzATestHookRegistry.test_get_hooks_filters_by_type.<locals>.pre_hook   r   r   Nc                      y )Nr   r   s    r   	post_hookzBTestHookRegistry.test_get_hooks_filters_by_type.<locals>.post_hook   s    r   r]   r   r_   r"   r   )
r   r	   r#   r$   r   r%   POSTr&   r'   r   )r(   r)   r]   r_   	pre_hooks
post_hookss         r   test_get_hooks_filters_by_typez/TestHookRegistry.test_get_hooks_filters_by_type   s    >	k 	d 		{ 	t 	 	*hllHeD+x}}iG&&uhll;	''x}}=
9~"""|  J...:!###!}!![000r   c                    t               }dt        dt        fd}dt        dt        fd}|j                  dt        j
                  |dd       |j                  d	t        j
                  |d
d       |j                  dt        j
                        }t        |      dk(  sJ |d   j                  d	k(  sJ |d   j                  dk(  sJ y)zATest that get_hooks combines operation-specific and global hooks.r   r   c                      yr   r   r   s    r   r.   zLTestHookRegistry.test_get_hooks_combines_operation_and_global.<locals>.hook1   r   r   c                      yr   r   r   s    r   r0   zLTestHookRegistry.test_get_hooks_combines_operation_and_global.<locals>.hook2   r   r   specific_hookr   r   r4   r>   r?   2   r9   r   r"   Nr:   )r(   r)   r.   r0   r*   s        r   ,test_get_hooks_combines_operation_and_globalz=TestHookRegistry.test_get_hooks_combines_operation_and_global   s    >	; 	4 		; 	4 	 	/8<<PST-ucBO""5(,,75zQQx}}---Qx}}///r   c                    t               }dt        dt        fd}|j                  dt        j
                  |d       |j                  dt        j                  |d       |j                          t        |j                  dt        j
                              dk(  sJ t        |j                  dt        j                              dk(  sJ y	)
zTest clearing all hooks.r   r   c                      yr   r   r   s    r   r.   z0TestHookRegistry.test_clear_hooks.<locals>.hook1   r   r   r.   r   r0   r@   r   N)
r   r	   r#   r$   r   r%   r`   clearr'   r&   )r(   r)   r.   s      r   test_clear_hooksz!TestHookRegistry.test_clear_hooks   s    >	; 	4 	 	'8<<>'8==%B8%%eX\\:;q@@@8%%h>?1DDDr   N)__name__
__module____qualname____doc__r+   r;   rB   rM   rR   rW   rZ   rc   ri   rm   r   r   r   r   r      s9    '((+02*?	>A1,0&Er   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)TestHookManagerzTests for HookManager class.c           	      v   t               }t        |      }g dt        dt        ffd}dt        dt        ffd}|j	                  dt
        j                  |dd       |j	                  d	t
        j                  |dd
       t        dddt        d      ddd      }|j                  |       dd	gk(  sJ y)z&Test executing PRE hooks successfully.r   r   c                 (    j                  d       yNr.   Tappendr   executeds    r   r.   z=TestHookManager.test_execute_pre_hooks_success.<locals>.hook1       OOG$r   c                 (    j                  d       y)Nr0   Trw   ry   s    r   r0   z=TestHookManager.test_execute_pre_hooks_success.<locals>.hook2   r{   r   r.   r   r6   r4   r0      r"   cash100rP   Nr    user_id
point_typeamountremarks
trans_typeiid)	r   r   r	   r#   r$   r   r%   r   execute_pre_hooks)r(   r)   managerr.   r0   r   rz   s         @r   test_execute_pre_hooks_successz.TestHookManager.test_execute_pre_hooks_success   s    >h'	; 	4 		; 	4 	 	'8<<K'8<<K5>
 	!!'* GW----r   c           	         t               }t        |      }dt        dt        fd}|j	                  dt
        j                  |d       t        dddt        d      d	d
d      }| j                  t              5 }|j                  |       d
d
d
       | j                  dj                  j                         y
# 1 sw Y   0xY w)z7Test PRE hook rejecting transaction by returning False.r   r   c                      y)NFr   r   s    r   rejecting_hookzNTestHookManager.test_execute_pre_hooks_rejection_false.<locals>.rejecting_hook   s    r   r   r   r"   r~   r   rP   Nr   r   HOOK_REJECTED_REJECTING_HOOK)r   r   r	   r#   r$   r   r%   r   rF   r
   r   rH   rJ   
error_coder(   r)   r   r   r   rL   s         r   &test_execute_pre_hooks_rejection_falsez6TestHookManager.test_execute_pre_hooks_rejection_false   s    >h'	K 	D 	 	*HLL.%P5>
 12b%%g. 3 	4bll6M6MN 32s   8B99Cc           	      (   t               }t        |      }dt        dt        fd}|j	                  dt
        j                  |d       t        dddt        d      d	d
d      }| j                  t              5 }|j                  |       d
d
d
       | j                  j                  j                  d       | j                  |j                  j                  d       | j                  |j                  j                  d   d	       y
# 1 sw Y   xY w)zBTest PRE hook rejecting transaction by raising HookRejectionError.r   r   c                 "    t        ddddi      )NCUSTOM_ERRORTransaction not allowedreasonrP   r   messagedetailsr
   r   s    r   r   zRTestHookManager.test_execute_pre_hooks_rejection_exception.<locals>.rejecting_hook   s    $)1!6* r   r   r   r"   r~   r   rP   Nr   r   r   r   r   )r   r   r	   r#   r$   r   r%   r   rF   r
   r   assertEqualrJ   r   r   r   r   s         r   *test_execute_pre_hooks_rejection_exceptionz:TestHookManager.test_execute_pre_hooks_rejection_exception   s    >h'	K 	D 	 	*HLL.%P5>
 12b%%g. 3 	00.A--/HI--h7@ 32s   8DDc           	         t               }t        |      }dt        dt        fd}|j	                  dt
        j                  |d       t        dddt        d      d	d
d      }| j                  t              5 }|j                  |       d
d
d
       | j                  j                  j                  d       | j                  dt        |j                               y
# 1 sw Y   UxY w)z+Test PRE hook raising unexpected exception.r   r   c                     t        d      )NSomething went wrongrG   r   s    r   failing_hookzMTestHookManager.test_execute_pre_hooks_unexpected_error.<locals>.failing_hook  s    344r   r   r   r"   r~   r   rP   Nr   r   r   )r   r   r	   r#   r$   r   r%   r   rF   r   r   r   rJ   	hook_namerH   rI   )r(   r)   r   r   r   rL   s         r   'test_execute_pre_hooks_unexpected_errorz7TestHookManager.test_execute_pre_hooks_unexpected_error  s    >h'	5+ 	5$ 	5 	.(,,eL5>
 12b%%g. 3 	//@,c",,.?@	 32s   8CC'c           	      L   t               }t        |      }g dt        dt        ffd}dt        dt        ffd}dt        dt        ffd}|j	                  dt
        j                  |dd	       |j	                  d
t
        j                  |dd	       |j	                  dt
        j                  |dd	       t        dddt        d      ddd      }| j                  t              5  |j                  |       ddd       | j                  dd
g       y# 1 sw Y   xY w)z7Test that PRE hook execution stops when a hook rejects.r   r   c                 (    j                  d       yrv   rw   ry   s    r   r.   zHTestHookManager.test_execute_pre_hooks_stops_on_rejection.<locals>.hook18  r{   r   c                 (    j                  d       y)N	rejectingFrw   ry   s    r   r   zQTestHookManager.test_execute_pre_hooks_stops_on_rejection.<locals>.rejecting_hook<  s    OOK(r   c                 (    j                  d       y)Nr2   Trw   ry   s    r   r2   zHTestHookManager.test_execute_pre_hooks_stops_on_rejection.<locals>.hook3@  r{   r   r.   r   r6   r4   r   r}   r2      r"   r~   r   rP   Nr   r   )r   r   r	   r#   r$   r   r%   r   rF   r
   r   r   )r(   r)   r   r.   r   r2   r   rz   s          @r   )test_execute_pre_hooks_stops_on_rejectionz9TestHookManager.test_execute_pre_hooks_stops_on_rejection1  s   >h'	; 	4 		K 	D 		; 	4 	 	'8<<K+x||^UUWX'8<<K5>
 12%%g. 3 	G[#9:	 32s   +DD#c           	         t               }t        |      }g dt        ddffd}dt        ddffd}|j                  dt        j
                  |dd	       |j                  d
t        j
                  |dd	       t        dddt        d      ddd      }|j                  |      }t        |      dk(  sJ dd
gk(  sJ y)z'Test executing POST hooks successfully.r   r   Nc                 (    j                  d       y Nr.   rw   ry   s    r   r.   z>TestHookManager.test_execute_post_hooks_success.<locals>.hook1_      OOG$r   c                 (    j                  d       y )Nr0   rw   ry   s    r   r0   z>TestHookManager.test_execute_post_hooks_success.<locals>.hook2b  r   r   r.   r   r6   r4   r0   r}   r"   r~   r   rP   r   r   r   )	r   r   r	   r$   r   r`   r   execute_post_hooksr'   )r(   r)   r   r.   r0   r   errorsrz   s          @r   test_execute_post_hooks_successz/TestHookManager.test_execute_post_hooks_successX  s    >h'	%; 	%4 	%	%; 	%4 	% 	'8==%L'8==%L5>
 ++G46{aGW----r   c           	      x   t               }t        |      }dt        ddfd}|j                  dt        j
                  |d       t        dddt        d	      d
dd      }|j                  |      }t        |      dk(  sJ |d   j                  dk(  sJ |d   j                  dk(  sJ d|d   j                  v sJ y)z4Test that POST hook errors are captured, not raised.r   r   Nc                     t        d      )NPOST hook failedr   r   s    r   r   zMTestHookManager.test_execute_post_hooks_captures_errors.<locals>.failing_hook|  s    /00r   r   r   r"   r~   r   rP   r   r   r   HOOK_EXECUTION_ERRORr   )r   r   r	   r$   r   r`   r   r   r'   r   r   r   )r(   r)   r   r   r   r   s         r   'test_execute_post_hooks_captures_errorsz7TestHookManager.test_execute_post_hooks_captures_errorsw  s    >h'	1+ 	1$ 	1 	.(--uM5>
 ++G46{aay""n444ay##'====!VAY%6%6666r   c           	      R   t               }t        |      }dt        ddfd}|j                  dt        j
                  |d       t        dddt        d	      d
dd      }|j                  |      }t        |      dk(  sJ |d   j                  dk(  sJ |d   j                  dk(  sJ y)z=Test that POST hooks trying to reject are captured as errors.r   r   Nc                     t        ddi       )NTRYING_TO_REJECTzPOST hook should not rejectr   r   r   s    r   rejecting_post_hookzRTestHookManager.test_execute_post_hooks_cannot_reject.<locals>.rejecting_post_hook  s    $-5 r   r   r   r"   r~   r   rP   r   r   r   r   )r   r   r	   r$   r   r`   r   r   r'   r   r   )r(   r)   r   r   r   r   s         r   %test_execute_post_hooks_cannot_rejectz5TestHookManager.test_execute_post_hooks_cannot_reject  s    >h'	 	 	 	+x}}6I5Q5>
 ++G46{aay""k111ay##'9999r   c           	         t               }t        |      }g dt        ddffd}dt        ddffd}dt        ddffd}|j                  dt        j
                  |dd	
       |j                  dt        j
                  |dd
       |j                  dt        j
                  |dd
       t        dddt        d      ddd      }|j                  |      }g dk(  sJ t        |      dk(  sJ |d   j                  dk(  sJ y)z8Test that POST hooks continue executing after one fails.r   r   Nc                 (    j                  d       y r   rw   ry   s    r   r.   zLTestHookManager.test_execute_post_hooks_continues_after_error.<locals>.hook1  r   r   c                 <    j                  d       t        d      )NfailingFailed)rx   rG   ry   s    r   r   zSTestHookManager.test_execute_post_hooks_continues_after_error.<locals>.failing_hook  s    OOI&X&&r   c                 (    j                  d       y )Nr2   rw   ry   s    r   r2   zLTestHookManager.test_execute_post_hooks_continues_after_error.<locals>.hook3  r   r   r.   r   r6   r4   r   r}   r2   r   r"   r~   r   rP   r   r   )r.   r   r2   r   )
r   r   r	   r$   r   r`   r   r   r'   r   )	r(   r)   r   r.   r   r2   r   r   rz   s	           @r   -test_execute_post_hooks_continues_after_errorz=TestHookManager.test_execute_post_hooks_continues_after_error  s   >h'	%; 	%4 	%	'+ 	'$ 	'	%; 	%4 	% 	'8==%L)X]]L%RTU'8==%L5>
 ++G4 88886{aay""i///r   N)rn   ro   rp   rq   r   r   r   r   r   r   r   r   r   r   r   r   rs   rs      s7    &.BO2A>A4%;N.>76:<%0r   rs   c                   "    e Zd ZdZd Zd Zd Zy)TestHookContextz Tests for HookContext dataclass.c           	         t        dddt        d      ddd      }| j                  t              5  d	|_        ddd       | j                  t              5  t        d
      |_        ddd       y# 1 sw Y   8xY w# 1 sw Y   yxY w)z2Test that HookContext fields are frozen/immutable.r   r"   r~   r   rP   Nr   r   r@   200)r	   r   rF   	Exceptionr    r   r(   r   s     r   test_hook_context_immutablez+TestHookContext.test_hook_context_immutable  sw    5>
 y) (G * y)$U^GN *) *) *)s   A0A<0A9<Bc           	          t        dddt        d      ddd      }d	|j                  d
<   |j                  d
   d	k(  sJ y)z@Test that metadata dict is mutable for inter-hook communication.r   r"   r~   r   rP   Nr   r   custom_value
custom_key)r	   r   metadatar   s     r   "test_hook_context_metadata_mutablez2TestHookContext.test_hook_context_metadata_mutable  sP    5>
 *8&-???r   c                     t        dddt        d      ddddd		      }|j                  dk(  sJ |j                  dk(  sJ y)
z/Test HookContext with transfer-specific fields.rA   r"   r~   r   Nr   r9   credit)	r    r   r   r   r   r   r   
to_user_idto_point_type)r	   r   r   r   r   s     r   !test_hook_context_transfer_fieldsz1TestHookContext.test_hook_context_transfer_fields  sU     5>"

 !!Q&&&$$000r   N)rn   ro   rp   rq   r   r   r   r   r   r   r   r     s    *,&@ 1r   r   c                       e Zd ZdZd Zy)TestPostHookErrorz"Tests for PostHookError dataclass.c                     t        d      }t        dddddi|      }|j                  dk(  sJ |j                  dk(  sJ |j                  dk(  sJ |j
                  d   dk(  sJ |j                  |u sJ y)	zTest creating a PostHookError.z
Test errorr   
TEST_ERRORzTest error messagekeyvalue)r   r   r   r   rJ   N)rG   r   r   r   r   r   rJ   )r(   rJ   errors      r   test_post_hook_error_creationz/TestPostHookError.test_post_hook_error_creation  s    |,	!#(G$
 +---<///}} 4444}}U#w...)+++r   N)rn   ro   rp   rq   r   r   r   r   r   r     s
    ,,r   r   N)rq   decimalr   django.testr   wallet_utilsr   r   r   r   wallet_utils.hooksr	   wallet_utils.exceptionsr
   r   r   rs   r   r   r   r   r   <module>r      sY    3     + JhEx hEVZ0h Z0z51h 51p, ,r   