
    P1i<                    h   d Z ddlZddlmZmZmZmZ ddlmZm	Z	 ddl
mZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZmZmZ ddlmZmZmZmZmZmZ ddlmZ ddl m!Z!  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)a>  
Comprehensive unit tests for LiuYao AI conversation feature.

Tests cover:
- Standard cases: normal conversation flow, message sending, context management
- Edge cases: message limits, length limits, context thresholds, permissions
- Outlier cases: AI failures, invalid data, unauthorized access, retry functionality
    N)Mockpatch	MagicMockcall)TestCaseoverride_settings)get_user_model)timezone)datetime)	APIClient)status)ConversationMessageConversationSubject)create_liuyao_conversationsend_conversation_messageprepare_conversation_promptcalculate_context_sizegenerate_conversation_summarymanage_conversation_context)liuyao)UserProfilec                   .    e Zd ZdZd Zd Zd Zd Zd Zy)LiuYaoConversationSubjectTestsz0Test ConversationSubject pivot table for LiuYao.c                 8   t         j                  j                  ddd      | _        t        j                  j                  | j                         t        j                  j                  t        j                         | j                  ddddddd		      | _
        y
Set up test data.
1234567890test@example.comtestpass123phoneemailpassworduserWill I get the job?10	qdater&   questiony1y2y3y4y5y6NUserobjectscreate_userr&   r   get_or_creater   creater
   now
liuyao_objselfs    C/home/cursorai/projects/iching/ai/tests/test_liuyao_conversation.pysetUpz$LiuYaoConversationSubjectTests.setUp$       LL,,$" - 
	
 	))tyy)9 ..//,,.* 0 

    c                 &   t        j                  d| j                  j                        }| j	                  |j                         | j                  |j                  d       | j                  |j                  | j                  j                         y)z-Test creating ConversationSubject for LiuYao.r   N)r   get_or_create_subjectr:   idassertIsNotNoneassertEqualcontent_type	object_id)r<   subjects     r=   !test_get_or_create_subject_liuyaoz@LiuYaoConversationSubjectTests.test_get_or_create_subject_liuyao9   sf    %;;HdooFXFXYWZZ(--x8**DOO,>,>?r@   c                     t        j                  d| j                  j                        }t        j                  d| j                  j                        }| j	                  |j                  |j                         y)z.Test that get_or_create_subject is idempotent.r   N)r   rB   r:   rC   rE   )r<   subject1subject2s      r=   %test_get_or_create_subject_idempotentzDLiuYaoConversationSubjectTests.test_get_or_create_subject_idempotentA   sR    &<<XtGYGYZ&<<XtGYGYZhkk2r@   c                 2   t        j                  d| j                  j                        }|j	                         }| j                  |       | j                  |j                  | j                  j                         | j                  |j                  d       y)z(Test getting LiuYao object from subject.r   r'   N)r   rB   r:   rC   
get_objectrD   rE   r,   )r<   rH   objs      r=   test_subject_get_object_liuyaoz=LiuYaoConversationSubjectTests.test_subject_get_object_liuyaoH   sm    %;;HdooFXFXY  "S!!3!34'<=r@   c                    t        j                  d| j                  j                        }t	        |      }| j                  d|j                                | j                  t	        | j                  j                        |       y)z/Test ConversationSubject string representation.r   N)r   rB   r:   rC   strassertInlower)r<   rH   str_reprs      r=   test_subject_str_representationz>LiuYaoConversationSubjectTests.test_subject_str_representationQ   sY    %;;HdooFXFXYw<h 01c$//,,-x8r@   N)	__name__
__module____qualname____doc__r>   rI   rM   rQ   rW    r@   r=   r   r   !   s    :
*@3>9r@   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)LiuYaoConversationModelTestsz$Test Conversation model with LiuYao.c                 8   t         j                  j                  ddd      | _        t        j                  j                  | j                         t        j                  j                  t        j                         | j                  ddddddd		      | _
        y
r   r3   r;   s    r=   r>   z"LiuYaoConversationModelTests.setUp]   r?   r@   c                    t        j                  d| j                  j                        }t        j
                  j                  | j                  |      }| j                  |j                         | j                  |j                  | j                         | j                  |j                  |       | j                  |j                         d       y)z6Test creating a conversation with ConversationSubject.r   r&   rH   r   N)r   rB   r:   rC   r   r5   r8   r&   rD   rE   rH   get_message_count)r<   rH   conversations      r=   %test_create_conversation_with_subjectzBLiuYaoConversationModelTests.test_create_conversation_with_subjectr   s    %;;HdooFXFXY#++22 3 

 	\__-**DII6--w77791=r@   c                    t        j                  d| j                  j                        }t        j
                  j                  | j                  |      }|j                         }| j                  |       | j                  |j                  | j                  j                         | j                  |j                  d       y)z-Test getting LiuYao object from conversation.r   ra   r'   N)r   rB   r:   rC   r   r5   r8   r&   get_subject_objectrD   rE   r,   )r<   rH   rc   subject_objs       r=   $test_conversation_get_subject_objectzALiuYaoConversationModelTests.test_conversation_get_subject_object   s    %;;HdooFXFXY#++22 3 

 #557[)););<--/DEr@   c                 4   t        j                  d| j                  j                        }t        j
                  j                  | j                  |d      }t        |      }| j                  d|       | j                  t        | j                        |       y)z4Test conversation string representation with LiuYao.r   zTest Conversation)r&   rH   titleN)
r   rB   r:   rC   r   r5   r8   r&   rS   rT   )r<   rH   rc   rV   s       r=   !test_conversation_str_with_liuyaoz>LiuYaoConversationModelTests.test_conversation_str_with_liuyao   sw    %;;HdooFXFXY#++22% 3 
 |$)84c$))nh/r@   c                 "   t        j                  d| j                  j                        }t        j
                  j                  | j                  |      }t        j
                  j                  |dd      }t        j
                  j                  |dddd	
      }| j                  |j                         d       | j                  |j                  d       | j                  |j                  d       | j                  |j                  d       y)z.Test creating messages in LiuYao conversation.r   ra   r&   zWhat does this hexagram mean?rc   rolecontent	assistantzThis hexagram indicates...groqllama-3.3-70b-versatilerc   rn   ro   providermodel   N)r   rB   r:   rC   r   r5   r8   r&   r   rE   rb   rn   rt   )r<   rH   rc   user_msgassistant_msgs        r=   )test_message_creation_liuyao_conversationzFLiuYaoConversationModelTests.test_message_creation_liuyao_conversation   s    %;;HdooFXFXY#++22 3 

 ??))%3 * 
  ..%0+ / 
 	7791=/++[9//8r@   N)	rX   rY   rZ   r[   r>   rd   rh   rk   ry   r\   r@   r=   r^   r^   Z   s    .
*>F09r@   r^   c                      e Zd ZdZd Zd Zd Z ed      d        Z ed      d        Z	d Z
 ed	       ed
       ed      d                      Z ed       ed       ed      d                      Z ed       ed       ed      d                      Z ed	       ed
       ed       ed      d                             Zy)LiuYaoConversationUtilityTestsz+Test LiuYao conversation utility functions.c                 >   t         j                  j                  ddd      | _        t        j                  j                  | j                         t        j                  j                  t        j                         | j                  dddddddd	d
i
      | _
        y)r   r   r   r    r!   r%   r'   r(   r)   hexagram	test_data
r+   r&   r,   r-   r.   r/   r0   r1   r2   dataNr3   r;   s    r=   r>   z$LiuYaoConversationUtilityTests.setUp   s    LL,,$" - 
	
 	))tyy)9 ..//,,.*k* 0 
r@   c                 $   t        | j                  | j                        }| j                  |j                         | j                  |j                  | j                         | j                  |j                         | j                  |j                  j                  d       | j                  |j                  j                  | j                  j                         | j                  | j                  j                  dd |j                         y)z1Test create_liuyao_conversation utility function.r&   r   r   N2   )r   r&   r:   rD   rC   rE   rH   rF   rG   rT   r,   rj   r<   rc   s     r=   (test_create_liuyao_conversation_functionzGLiuYaoConversationUtilityTests.test_create_liuyao_conversation_function   s    1??

 	\__-**DII6\112--::HE--779K9KLdoo..s3\5G5GHr@   c                     t        | j                  | j                  d      }| j                  |j                  d       y)z2Test create_liuyao_conversation with custom title.zCustom LiuYao Conversation)r&   r   rj   N)r   r&   r:   rE   rj   r   s     r=   *test_create_liuyao_conversation_with_titlezILiuYaoConversationUtilityTests.test_create_liuyao_conversation_with_title   s6    1??.
 	++-IJr@   +ai.utils.conversation.prepare_liuyao_promptc                    d|_         t        j                  d| j                  j                        }t
        j                  j                  | j                  |      }ddddddg}t        ||d	d
      }| j                  d|       | j                  d|       | j                  d|       | j                  d	|       |j                  | j                  d
       y)z5Test prepare_conversation_prompt function for LiuYao.zLiuYao hexagram data herer   ra   r&   zWhat does this mean?rn   ro   rp   zIt means...zTell me moreenrc   conversation_historyuser_messagelanguager   N)return_valuer   rB   r:   rC   r   r5   r8   r&   r   rT   assert_called_once_with)r<   mock_prepare_liuyaorH   rc   historyprompts         r=   'test_prepare_conversation_prompt_liuyaozFLiuYaoConversationUtilityTests.test_prepare_conversation_prompt_liuyao   s     ,G(%;;HdooFXFXY#++22 3 
 (>? ];

 -%!('	
 	16:,f5mV,nf-33DOOd3Sr@   c                 ,   d|_         t        j                  d| j                  j                        }t
        j                  j                  | j                  |      }d|_	        |j                          t        |g dd      }| j                  d|       y)	z6Test prepare_conversation_prompt with context summary.LiuYao datar   ra   zPrevious conversation summaryzNew questionr   r   N)r   r   rB   r:   rC   r   r5   r8   r&   context_summarysaver   rT   )r<   r   rH   rc   r   s        r=   -test_prepare_conversation_prompt_with_summaryzLLiuYaoConversationUtilityTests.test_prepare_conversation_prompt_with_summary  s     ,9(%;;HdooFXFXY#++22 3 
 (G$,%!#'	
 	5v>r@   c                     d}ddddddg}d}t        |||      }| j                  |d	       | j                  |t               y
)z8Test calculate_context_size function with LiuYao prompt.a  LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data LiuYao data r&   z	Message 1r   rp   z
Response 1zCurrent messagedivination_promptr   current_messager   N)r   assertGreaterassertIsInstanceint)r<   liuyao_promptr   r   sizes        r=   "test_calculate_context_size_liuyaozALiuYaoConversationUtilityTests.test_calculate_context_size_liuyao  sZ    ,4 \:
 ,%+!(+
 	4#dC(r@   'ai.utils.conversation.LLMServiceFactory#ai.utils.conversation.get_ai_configc                 $   d|_         ddd|_         t               }d|j                  _         ||j                  _         t	        j
                  d| j                  j                        }t        j                  j                  | j                  |      }t        j                  j                  |dd	
      t        j                  j                  |dd
      g}t        ||d      }| j                  |d       |j                  j                          y)z7Test generate_conversation_summary function for LiuYao.r   rq   rr   rt   ru   z-This is a summary of the LiuYao conversation.r   ra   r&   z
Question 1rm   rp   zAnswer 1r   )rc   messages_to_summarizer   N)r   r   get_completionget_servicer   rB   r:   rC   r   r5   r8   r&   r   r   rE   assert_called_once)	r<   r   mock_get_configmock_factorymock_servicerH   rc   messagessummarys	            r=   )test_generate_conversation_summary_liuyaozHLiuYaoConversationUtilityTests.test_generate_conversation_summary_liuyao+  s   
 ,9(4:E^'_$ {3b##00<  -%;;HdooFXFXY#++22 3 
 OO"")$ # 
 OO"") " # 
 0%"*
 	"QR##668r@   3ai.utils.conversation.generate_conversation_summary  CONVERSATION_CONTEXT_THRESHOLDc                 t   d|_         t        j                  d| j                  j                        }t
        j                  j                  | j                  |      }t        d      D ]1  }t        j                  j                  ||dz  dk(  rdndd	| 
       3 t        |d       |j                          y)z6Test manage_conversation_context when under threshold.zSmall LiuYao datar   ra      rv   r   r&   rp   Message rm   r   r   N)r   r   rB   r:   rC   r   r5   r8   r&   ranger   r   assert_not_calledr<   r   mock_generate_summaryrH   rc   is         r=   0test_manage_conversation_context_under_thresholdzOLiuYaoConversationUtilityTests.test_manage_conversation_context_under_thresholdS  s    
 ,?(%;;HdooFXFXY#++22 3 
 qAOO"") 1uzV{"1# #   	$L4@ 	//1r@   d   c                    ddz  |_         d|_         t        j                  d| j                  j                        }t
        j                  j                  | j                  |      }t        d      D ]1  }t        j                  j                  ||dz  dk(  rd	nd
ddz         3 t        |d       |j                          |j                          | j                  |j                  d       y)z:Test manage_conversation_context when exceeding threshold.LiuYao data r   zSummary of old messagesr   ra      rv   r   r&   rp   zLong message content 
   rm   r   r   N)r   r   rB   r:   rC   r   r5   r8   r&   r   r   r   assert_calledrefresh_from_dbrE   r   r   s         r=   2test_manage_conversation_context_exceeds_thresholdzQLiuYaoConversationUtilityTests.test_manage_conversation_context_exceeds_thresholdm  s    
 ,:D+@(-F*%;;HdooFXFXY#++22 3 
 rAOO"") 1uzV{/25 #   	$L4@ 	++-$$&557PQr@   1ai.utils.conversation.manage_conversation_context1ai.utils.conversation.prepare_conversation_promptc                 .   ddd|_         d|_         t               }d|j                  _         ||j                  _         t	        j
                  d| j                  j                        }t        j                  j                  | j                  |      }t        |dd	
      }| j                  |       | j                  |j                  d       | j                  |j                   d       | j                  |j"                  d       |j%                          y)z7Test send_conversation_message success case for LiuYao.rq   rr   r   zFull promptzAI response herer   ra   Hellor   rc   r   r   rp   N)r   r   r   r   r   rB   r:   rC   r   r5   r8   r&   r   rD   rE   rn   ro   rt   r   )	r<   mock_prepare_promptmock_manage_contextr   r   r   rH   rc   rx   s	            r=   -test_send_conversation_message_success_liuyaozLLiuYaoConversationUtilityTests.test_send_conversation_message_success_liuyao  s     5;E^'_$+8( {3E##00<  -%;;HdooFXFXY#++22 3 

 2% 
 	]+++[9..0BC//8..0r@   N)rX   rY   rZ   r[   r>   r   r   r   r   r   r   r   r   r   r   r   r\   r@   r=   r{   r{      s<   5
,IK 89T :T8 89? :?*)$ 45
01
89#9 : 2 6#9J @A
89d;2 < : B2. @A
89c:R ; : BR6 45
01
>?
>?1 @ @ 2 61r@   r{   c                      e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Z ed
      d        Zd Zd Z ed       ed
      d               Zd Z ed
      d        Z ed
      d        Z ed
      d        Zd Z ed
      d        Zd Zy)LiuYaoConversationAPITestsz'Test LiuYao conversation API endpoints.c                    t               | _        t        j                  j	                  ddd      | _        t        j                  j                  | j
                         | j                  j                  | j
                         t        j                  j                  t        j                         | j
                  ddddddd		      | _        y
r   )r   clientr4   r5   r6   r&   r   r7   force_authenticater   r8   r
   r9   r:   r;   s    r=   r>   z LiuYaoConversationAPITests.setUp  s    kLL,,$" - 
	
 	))tyy)9&&DII&6 ..//,,.* 0 

r@   c                 P   d| j                   j                   d}| j                  j                  |      }| j	                  |j
                  t        j                         | j	                  |j                  d   d       | j	                  t        |j                  d         d       y)z+Test listing conversations when none exist./api/liuyao//conversations/countr   resultsN)
r:   rC   r   getrE   status_coder   HTTP_200_OKr   lenr<   urlresponses      r=   test_list_conversations_emptyz8LiuYaoConversationAPITests.test_list_conversations_empty  s    T__//0@;;??3'--v/A/ABw/3X]]956:r@   c                    t        | j                  | j                        }t        | j                  | j                        }d| j                  j                   d}| j                  j                  |      }| j                  |j                  t        j                         | j                  |j                  d   d       | j                  t        |j                  d         d       y)z.Test listing conversations with existing data.r   r   r   r   rv   r   N)r   r&   r:   rC   r   r   rE   r   r   r   r   r   )r<   conversation1conversation2r   r   s        r=   !test_list_conversations_with_dataz<LiuYaoConversationAPITests.test_list_conversations_with_data  s    2??
 3??

 T__//0@;;??3'--v/A/ABw/3X]]956:r@   c                 f   t         j                  j                  ddd      }t        j                  j	                  t        j                         |ddddddd	      }d	|j                   d
}| j                  j                  |      }| j                  |j                  t        j                         y)z5Test listing conversations for another user's LiuYao.
9999999999other@example.comr    r!   Other questionr(   r)   r*   r   r   N)r4   r5   r6   r   r8   r
   r9   rC   r   r   rE   r   r   HTTP_404_NOT_FOUNDr<   
other_userother_liuyaor   r   s        r=   "test_list_conversations_other_userz=LiuYaoConversationAPITests.test_list_conversations_other_user  s    \\--%" . 


 ~~,,,,.% - 

 \__-_=;;??3'--v/H/HIr@   c                 @   t        | j                  | j                        }t        j                  j                  |dd       t        j                  j                  |dd       d| j                  j                   d|j                   d	}| j                  j                  |      }| j                  |j                  t        j                         | j                  t        |j                  d
         d       | j                  |j                  d
   d   d   d       y)z!Test getting conversation detail.r   r&   r   rm   rp   z	Hi there!r   r   /r   rv   r   ro   N)r   r&   r:   r   r5   r8   rC   r   r   rE   r   r   r   r   r   r<   rc   r   r   s       r=   test_get_conversation_detailz7LiuYaoConversationAPITests.test_get_conversation_detail  s    1??

 	% 	 	
 	% 	 	
 T__//0?PPQR;;??3'--v/A/ABX]]:67;z215i@'Jr@   c                     d| j                   j                   d}| j                  j                  |      }| j	                  |j
                  t        j                         y)z'Test getting non-existent conversation.r   z/conversations/999/N)r:   rC   r   r   rE   r   r   r   r   s      r=   test_get_conversation_not_foundz:LiuYaoConversationAPITests.test_get_conversation_not_found  sJ    T__//00CD;;??3'--v/H/HIr@   c                     d| j                   j                   d}| j                  j                  |      }| j	                  |j
                  t        j                         | j                  d|j                         y)z!Test creating a new conversation.r   /conversations/create/rC   N)
r:   rC   r   postrE   r   r   HTTP_201_CREATEDrT   r   r   s      r=   test_create_conversationz3LiuYaoConversationAPITests.test_create_conversation  s^    T__//00FG;;##C(--v/F/FGdHMM*r@   c                 f   t         j                  j                  ddd      }t        j                  j	                  t        j                         |ddddddd	      }d	|j                   d
}| j                  j                  |      }| j                  |j                  t        j                         y)z3Test creating conversation for unauthorized LiuYao.r   r   r    r!   r   r(   r)   r*   r   r   N)r4   r5   r6   r   r8   r
   r9   rC   r   r   rE   r   r   r   r   s        r=   ,test_create_conversation_unauthorized_liuyaozGLiuYaoConversationAPITests.test_create_conversation_unauthorized_liuyao#  s    \\--%" . 


 ~~,,,,.% - 

 \__--CD;;##C(--v/H/HIr@   #api.views.send_conversation_messagec                    t        | j                  | j                        fd}||_        d| j                  j                   dj                   d}| j
                  j                  |ddd      }| j                  |j                  t        j                         | j                  d	|j                         | j                  d
|j                         |j                          y)z$Test sending a message successfully.r   c                      t         j                  j                  d|d         }t         j                  j                  dddd      S )	Nr&   r   rm   rp   AI responserq   rr   rs   r   r5   r8   )argskwargsrw   rc   s      r=   mock_send_side_effectzSLiuYaoConversationAPITests.test_send_message_success.<locals>.mock_send_side_effectD  sW    --)~. . H ??))) %/ *  r@   r   r   /send/r   r   messager   r   assistant_messageN)r   r&   r:   side_effectrC   r   r   rE   r   r   r   rT   r   r   )r<   mock_send_messager  r   r   rc   s        @r=   test_send_message_successz4LiuYaoConversationAPITests.test_send_message_success;  s     2??
	  )>%T__//0?PPVW;;##C*
 
 	--v/A/ABnhmm4)8==9,,.r@   c                 &   t        | j                  | j                        }d| j                  j                   d|j                   d}| j                  j                  |ddd      }| j                  |j                  t        j                         y)	zTest sending empty message.r   r   r   r  z   r   r  N
r   r&   r:   rC   r   r   rE   r   r   HTTP_400_BAD_REQUESTr   s       r=   test_send_message_emptyz2LiuYaoConversationAPITests.test_send_message_emptya  s    1??

 T__//0?PPVW;;##C*
 
 	--v/J/JKr@   c                 *   t        | j                  | j                        }d}d| j                  j                   d|j                   d}| j                  j                  ||dd      }| j                  |j                  t        j                         y)	z,Test sending message exceeding length limit.r     aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar   r   r  r   r  Nr  )r<   rc   long_messager   r   s        r=   test_send_message_too_longz5LiuYaoConversationAPITests.test_send_message_too_longp  s    1??

 "T__//0?PPVW;;##C#*
 
 	--v/J/JKr@      CONVERSATION_MAX_MESSAGESc                    t        | j                  | j                        }t        d      D ]1  }t        j
                  j                  ||dz  dk(  rdndd|        3 d	| j                  j                   d
|j                   d}| j                  j                  |ddd      }| j                  |j                  t        j                         | j                  d|j                  d          |j!                          y)z+Test sending message when limit is reached.r   r  rv   r   r&   rp   r   rm   r   r   r  zShould failr   r  zmaximum message limiterrorN)r   r&   r:   r   r   r5   r8   rC   r   r   rE   r   r   r  rT   r   r   )r<   r
  rc   r   r   r   s         r=   test_send_message_limit_reachedz:LiuYaoConversationAPITests.test_send_message_limit_reached  s     2??
 qAOO"") 1uzV{"1# #   T__//0?PPVW;;##C$*
 
 	--v/J/JK-x}}W/EF++-r@   c                    t        | j                  | j                        }d| j                  j                  _        | j                  j                  j                          d| j                  j                   d|j                   d}| j                  j                  |dddd	      }| j                  |j                  t        j                         y
)z0Test provider/model override without permission.r   Fr   r   r  r   openaigpt-4or  rt   ru   N)r   r&   r:   profilecan_regenerate_air   rC   r   r   rE   r   r   HTTP_403_FORBIDDENr   s       r=   6test_send_message_provider_override_without_permissionzQLiuYaoConversationAPITests.test_send_message_provider_override_without_permission  s    1??
 /4		+		 T__//0?PPVW;;##C *
  	--v/H/HIr@   c                    t        | j                  | j                        d| j                  j                  _        | j                  j                  j                          fd}||_        d| j                  j                   dj                   d}| j                  j                  |ddd	d
      }| j                  |j                  t        j                         |j                          |j                  r|j                  d   ni }|rC| j                  |j!                  d      d       | j                  |j!                  d      d	       yy)z-Test provider/model override with permission.r   Tc                      t         j                  j                  d|d          t         j                  j                  dddd      S )	Nr&   r   rm   rp   r   r  r  rs   r  r  r  rc   s     r=   r  zmLiuYaoConversationAPITests.test_send_message_provider_override_with_permission.<locals>.mock_send_side_effect  sU    OO"")~. #  ??))) %! *  r@   r   r   r  r   r  r  r     rt   ru   N)r   r&   r:   r  r  r   r	  rC   r   r   rE   r   r   r   r   	call_argsr   r<   r
  r  r   r   call_kwargsrc   s         @r=   3test_send_message_provider_override_with_permissionzNLiuYaoConversationAPITests.test_send_message_provider_override_with_permission  s     2??
 /3		+		 	  )>%T__//0?PPVW;;##C *
  	--v/A/AB,,.8I8S8S'11!4Y[[__Z8(C[__W5x@ r@   c                 ~   t        | j                  | j                        }t        d      |_        d| j                  j
                   d|j
                   d}| j                  j                  |ddd      }| j                  |j                  t        j                         | j                  d	|j                         y
)z!Test handling AI service failure.r   AI service errorr   r   r  r   r   r  r  N)r   r&   r:   	Exceptionr	  rC   r   r   rE   r   r   HTTP_500_INTERNAL_SERVER_ERRORrT   r   )r<   r
  rc   r   r   s        r=   test_send_message_ai_failurez7LiuYaoConversationAPITests.test_send_message_ai_failure  s     2??

 )22D(E%T__//0?PPVW;;##C*
 
 	--v/T/TUgx}}-r@   c                    t        | j                  | j                        t        j                  j                  dd      }fd}||_        d| j                  j                   dj                   d}| j                  j                  |      }| j                  |j                  t        j                         |j                          |j                  r|j                  d	   ni }|r"| j                  |j!                  d
      d       yy)z%Test retrying a message successfully.r   r&   r   rm   c                  L    t         j                  j                  dddd      S )Nrp   zRetry responserq   rr   rs   r  r$  s     r=   r  zTLiuYaoConversationAPITests.test_retry_message_success.<locals>.mock_send_side_effect  s.    ??))) (/ *  r@   r   r   /retry/r%  r   N)r   r&   r:   r   r5   r8   r	  rC   r   r   rE   r   r   r   r   r&  r   )r<   r
  rw   r  r   r   r(  rc   s          @r=   test_retry_message_successz5LiuYaoConversationAPITests.test_retry_message_success  s     2??

 ??))% * 
	 )>%T__//0?PPWX;;##C(--v/A/AB,,.8I8S8S'11!4Y[[__^<gF r@   c                 b   t        | j                  | j                        }t        j                  j                  |dd       d| j                  j                   d|j                   d}| j                  j                  |      }| j                  |j                  t        j                         y)	z'Test retry when no user message exists.r   rp   zOnly assistantrm   r   r   r1  N)r   r&   r:   r   r5   r8   rC   r   r   rE   r   r   r  r   s       r=   "test_retry_message_no_user_messagez=LiuYaoConversationAPITests.test_retry_message_no_user_message  s    1??
 	%$ 	 	
 T__//0?PPWX;;##C(--v/J/JKr@   c           	      L   t        | j                  | j                        t        j                  j                  dd       t        j                  j                  ddddd	d
i       fd}||_        d| j                  j                   dj                   d}| j                  j                  |      }| j                  |j                  t        j                         |j                  r|j                  d   ni }|r"| j                  |j                  d	      d
       yy)z:Test retry preserves language from last assistant message.r   r&   r   rm   rp   Responserq   rr   r   r   )rc   rn   ro   rt   ru   metac                  H    t         j                  j                  dd      S )Nrp   Retryrm   r  r$  s     r=   r  z_LiuYaoConversationAPITests.test_retry_message_preserves_language.<locals>.mock_send_side_effect>  s(    ??)))  *  r@   r   r   r1  r%  N)r   r&   r:   r   r5   r8   r	  rC   r   r   rE   r   r   r   r&  r   r'  s         @r=   %test_retry_message_preserves_languagez@LiuYaoConversationAPITests.test_retry_message_preserves_language'  s    2??

 	% 	 	
 	%+d# 	 	
	 )>%T__//0?PPWX;;##C(--v/A/AB8I8S8S'11!4Y[[__Z8$? r@   c                     | j                   j                          d| j                  j                   d}| j                   j	                  |      }| j                  |j                  t        j                         y)z&Test unauthorized access to endpoints.r   r   N)	r   logoutr:   rC   r   rE   r   r   HTTP_401_UNAUTHORIZEDr   s      r=   test_unauthorized_accessz3LiuYaoConversationAPITests.test_unauthorized_accessP  sY    T__//0@;;??3'--v/K/KLr@   N)rX   rY   rZ   r[   r>   r   r   r   r   r   r   r   r   r  r  r  r   r  r!  r)  r.  r2  r4  r:  r>  r\   r@   r=   r   r     s   1
.;;$J0K4J+J0 01#/ 2#/JLL" 3
01. 2 4.2J( 01*A 2*AX 01. 2.$ 01!G 2!GFL& 01&@ 2&@PMr@   r   c                       e Zd ZdZd Zd Zd Z ed      d        Z ed      d        Z	 e
d	      d
        Zd Zd Zy)LiuYaoConversationEdgeCaseTestszATest edge cases and boundary conditions for LiuYao conversations.c                 8   t         j                  j                  ddd      | _        t        j                  j                  | j                         t        j                  j                  t        j                         | j                  ddddddd		      | _
        y
r   r3   r;   s    r=   r>   z%LiuYaoConversationEdgeCaseTests.setUp]  r?   r@   c                 j    ddl m} d} ||dd      }| j                  |j                                y)z*Test message with exactly 2000 characters.r   SendMessageSerializer  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar   r  r   N)api.serializersrD  
assertTrueis_validr<   rD  r  
serializers       r=   test_message_exactly_2000_charsz?LiuYaoConversationEdgeCaseTests.test_message_exactly_2000_charsr  s6    9*1
 

 	
++-.r@   c                 j    ddl m} d} ||dd      }| j                  |j                                y)z/Test message with 2001 characters (over limit).r   rC  r  r   r  rF  N)rG  rD  assertFalserI  rJ  s       r=   test_message_2001_charsz7LiuYaoConversationEdgeCaseTests.test_message_2001_chars~  s8    9*1
 

 	,,./r@      r  c                    t        | j                  | j                        }t        d      D ]1  }t        j
                  j                  ||dz  dk(  rdndd|        3 | j                  |j                         d       y	)
z+Test conversation with exactly 25 messages.r   rP  rv   r   r&   rp   r   rm   N)	r   r&   r:   r   r   r5   r8   rE   rb   )r<   rc   r   s      r=   test_exactly_25_messagesz8LiuYaoConversationEdgeCaseTests.test_exactly_25_messages  sy     2??
 rAOO"") 1uzV{"1# #   	7792>r@   c                    t        | j                  | j                        }t        d      D ]1  }t        j
                  j                  ||dz  dk(  rdndd|        3 t               }|j                  | j                  	       d
| j                  j                   d|j                   d}|j                  |ddd      }| j                  |j                  t        j                         y)z"Test that 26th message is blocked.r   rP  rv   r   r&   rp   r   rm   r%   r   r   r  z26th messager   r  N)r   r&   r:   r   r   r5   r8   r   r   rC   r   rE   r   r   r  )r<   rc   r   r   r   r   s         r=   test_26_messages_blocks_newz;LiuYaoConversationEdgeCaseTests.test_26_messages_blocks_new  s     2??
 rAOO"") 1uzV{"1# #   !!tyy!1T__//0?PPVW;;s%%
 
 	--v/J/JKr@   r   c                    t        | j                  | j                        fd}||_        t	               }|j                  | j                         d| j                  j                   dj                   d}|j                  |ddd	      }| j                  |j                  t        j                         |j                  r|j                  d
   ni }|r"| j                  |j                  d      d       yy)z(Test conversation with Chinese language.r   c                      t         j                  j                  d|d          t         j                  j                  dd      S )Nr&   r   rm   rp   u   中文回复r  r$  s     r=   r  zTLiuYaoConversationEdgeCaseTests.test_chinese_language.<locals>.mock_send_side_effect  sO    OO"")~. #  ??))) & *  r@   r%   r   r   r  u   你好zzh-hansr  r%  r   N)r   r&   r:   r	  r   r   rC   r   rE   r   r   r   r&  r   )r<   r
  r  r   r   r   r(  rc   s          @r=   test_chinese_languagez5LiuYaoConversationEdgeCaseTests.test_chinese_language  s     2??

	 )>%!!tyy!1T__//0?PPVW;;s!%
 
 	--v/A/AB8I8S8S'11!4Y[[__Z8)D r@   c                     t        | j                  | j                        }d}t        j                  j                  |d|      }| j                  |j                  |       y)z"Test message with unicode content.r   u   你好 🌟 测试 émojisr&   rm   N)r   r&   r:   r   r5   r8   rE   ro   )r<   rc   unicode_messagemsgs       r=   test_unicode_message_contentz<LiuYaoConversationEdgeCaseTests.test_unicode_message_content  sY    1??

 7oo$$%# % 
 	o6r@   c                     t        | j                  | j                        }t        | j                  | j                        }| j                  |j                  |j                         | j                  |j                  |j                         y)z,Test multiple conversations for same LiuYao.r   N)r   r&   r:   assertNotEqualrC   rE   rH   )r<   r   r   s      r=   'test_multiple_conversations_same_liuyaozGLiuYaoConversationEdgeCaseTests.test_multiple_conversations_same_liuyao  sn    2??
 3??

 	M,,m.>.>?..0E0EFr@   N)rX   rY   rZ   r[   r>   rL  rO  r   rR  rT  r   rW  r[  r^  r\   r@   r=   r@  r@  Z  sp    K
*
/
0 4? 5?" 4L 5L6 01#E 2#EJ7 Gr@   r@  c                   R   e Zd ZdZd Zd Zd Z ed       ed       ed      d	                      Z	 ed
       ed       ed       ed      d                             Z
d Zd Zd Z ed
       ed       ed       ed      d                             Zd Zd Zd Zd Zy)LiuYaoConversationOutlierTestsz@Test outlier cases and error scenarios for LiuYao conversations.c                 8   t         j                  j                  ddd      | _        t        j                  j                  | j                         t        j                  j                  t        j                         | j                  ddddddd		      | _
        y
r   r3   r;   s    r=   r>   z$LiuYaoConversationOutlierTests.setUp   r?   r@   c                     t               }|j                  | j                         d}|j                  |      }| j	                  |j
                  t        j                         y)z Test API with invalid LiuYao ID.r%   z /api/liuyao/99999/conversations/N)r   r   r&   r   rE   r   r   r   r<   r   r   r   s       r=   test_invalid_liuyao_idz5LiuYaoConversationOutlierTests.test_invalid_liuyao_id  sL    !!tyy!10::c?--v/H/HIr@   c                     t               }|j                  | j                         d| j                  j                   d}|j                  |      }| j                  |j                  t        j                         y)z&Test API with invalid conversation ID.r%   r   z/conversations/99999/N)
r   r   r&   r:   rC   r   rE   r   r   r   rc  s       r=   test_invalid_conversation_idz;LiuYaoConversationOutlierTests.test_invalid_conversation_id  sa    !!tyy!1T__//00EF::c?--v/H/HIr@   r   r   r   r   c                    ddz  |_         t        d      |_        t        | j                  | j
                        }t        d      D ]1  }t        j                  j                  ||dz  dk(  rdnd	d
dz         3 	 t        |d       |j                          | j                  |j                         y# t        $ r | j                  d       Y Hw xY w)z)Test handling summary generation failure.zLarge LiuYao data r   zSummary generation failedr   r   rv   r   r&   rp   zLong message r   rm   r   r   zEmanage_conversation_context should handle summary failures gracefullyN)r   r,  r	  r   r&   r:   r   r   r5   r8   r   failr   rN  r   )r<   r   r   rc   r   s        r=   test_summary_generation_failurez>LiuYaoConversationOutlierTests.test_summary_generation_failure)  s    
 ,@$+F(,56Q,R)1??
 rAOO"") 1uzV{'2- #  	_'tD
 	$$&556  	_II]^	_s   <B5 5CCr   r   r   r   c                 j   ddd|_         t        d      |_        t               }d|j                  _         ||j
                  _         t        | j                  | j                        }t        d      5 }d|_         	 t        |d	d
       ddd       y# t        $ r
}Y d}~d}~ww xY w# 1 sw Y   yxY w)z)Test handling prompt preparation failure.rq   rr   r   zPrompt preparation failedr   r   r   r   Testr   r   N)r   r,  r	  r   r   r   r   r&   r:   r   r   )	r<   r   r   r   r   r   rc   mock_liuyao_promptes	            r=   test_prompt_preparation_failurez>LiuYaoConversationOutlierTests.test_prompt_preparation_failureH  s     5;E^'_$*34O*P' {3@##00<  -1??
 @AEW.;+)!-!'! BA   BAs*   3B)<B	B&B)!B&&B))B2c                    t        | j                  | j                        }|j                  }| j                  j	                          | j                  t        j                  j                  |      j                                y)z2Test conversation behavior when LiuYao is deleted.r   rC   N)
r   r&   r:   rC   deleterH  r   r5   filterexistsr<   rc   conversation_ids      r=   %test_conversation_with_deleted_liuyaozDLiuYaoConversationOutlierTests.test_conversation_with_deleted_liuyaoi  sb    1??

 '// 	  	,,333GNNPQr@   c                 <   t        | j                  | j                        }t        j                  j                  |dd      }|j                  }|j                          | j                  t        j                  j                  |      j                                y)z3Test message behavior when conversation is deleted.r   r&   rk  rm   rp  N)r   r&   r:   r   r5   r8   rC   rq  rN  rr  rs  )r<   rc   rZ  msg_ids       r=   &test_message_with_deleted_conversationzELiuYaoConversationOutlierTests.test_message_with_deleted_conversationx  s    1??

 oo$$% % 
  	 	//6/:AACDr@   c                    t        | j                  | j                        }|j                  }| j                  j	                          | j                  t        j                  j                  |      j                                y)z0Test conversation behavior when user is deleted.r   rp  N)
r   r&   r:   rC   rq  rN  r   r5   rr  rs  rt  s      r=   #test_conversation_with_deleted_userzBLiuYaoConversationOutlierTests.test_conversation_with_deleted_user  sd    1??

 '// 			 	--444HOOQRr@   c                 B   ddd|_         d|_         t               }t        d      |j                  _        ||j
                  _         t        | j                  | j                        }| j                  t              5  t        |dd	       d
d
d
       y
# 1 sw Y   y
xY w)z"Test handling LLM service failure.rq   rr   r   PromptzLLM service errorr   rk  r   r   N)r   r   r,  r   r	  r   r   r&   r:   assertRaisesr   )r<   r   r   r   r   r   rc   s          r=   test_llm_service_failurez7LiuYaoConversationOutlierTests.test_llm_service_failure  s     5;E^'_$+3( {2;<O2P##/0<  -1??

 y)%)# *))s   =BBc                 .   t        | j                  | j                        }|j                         }t	        d      D ]1  }t
        j                  j                  ||dz  dk(  rdndd|        3 |j                         }| j                  ||dz          y	)
z5Test handling concurrent message sending (simulated).r   r   rv   r   r&   rp   r   rm   N)	r   r&   r:   rb   r   r   r5   r8   rE   )r<   rc   initial_countr   final_counts        r=   test_concurrent_message_sendingz>LiuYaoConversationOutlierTests.test_concurrent_message_sending  s    1??
 %668 qAOO"") 1uzV{"1# #   #446ma&78r@   c                    t        | j                  | j                        }t        d      5 }ddz  |_        t        |j                  g d      }| j                  |d       | j                  |t               ddd       y# 1 sw Y   yxY w)	z&Test handling very long LiuYao prompt.r   r   r   i'  rk  r   r   N)	r   r&   r:   r   r   r   r   r   r   )r<   rc   mock_liuyaor   s       r=   test_very_long_liuyao_promptz;LiuYaoConversationOutlierTests.test_very_long_liuyao_prompt  s|    1??

 @A['5'=K$)"-":":%' &D tQ'!!$, BAAs   ABB
c                 ^   t         j                  j                  t        j                         | j
                  dddddddd
      }t        | j
                  |      }| j                  |j                         |j                         }| j                  |j                  |j                         y)z<Test LiuYao conversation with LiuYao that has no data field.zTest questionr(   r)   Nr   r   )r   r5   r8   r
   r9   r&   r   rD   rC   rf   rE   )r<   liuyao_no_datarc   rg   s       r=   test_liuyao_without_data_fieldz=LiuYaoConversationOutlierTests.test_liuyao_without_data_field  s    ..,,.$ / 
 2!
 	\__-"557):):;r@   c                 &   t         j                  j                  t        j                         | j
                  ddddddd	      }t        | j
                  |      }| j                  |j                         | j                  |j                         y)z-Test LiuYao conversation with empty question. r(   r)   r*   r   N)
r   r5   r8   r
   r9   r&   r   rD   rC   rj   )r<   liuyao_emptyrc   s      r=   test_liuyao_with_empty_questionz>LiuYaoConversationOutlierTests.test_liuyao_with_empty_question  s~    ~~,,,,. - 

 2
 	\__-\//0r@   N)rX   rY   rZ   r[   r>   rd  rf  r   r   ri  rn  rv  ry  r{  r  r  r  r  r  r\   r@   r=   r`  r`    s    J
*JJ @A
89c:7 ; : B78 45
01
>?
>? @ @ 2 6:RE*S 45
01
>?
>? @ @ 2 6*9*-(<21r@   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d Zd Zd Zy)$LiuYaoConversationFailedMessageTestsz6Test failed message handling for LiuYao conversations.c                    t         j                  j                  ddd      | _        t        j                  j                  | j                         t        j                  j                  t        j                         | j                  ddddddd		      | _
        t        | j                  | j                  
      | _        y)r   r   r   r    r!   r%   r'   r(   r)   r*   r   N)r4   r5   r6   r&   r   r7   r   r8   r
   r9   r:   r   rc   r;   s    r=   r>   z*LiuYaoConversationFailedMessageTests.setUp  s    LL,,$" - 
	
 	))tyy)9 ..//,,.* 0 

 7??
r@   c                    t         j                  j                  | j                  dddd      }| j	                  |j
                  d       | j	                  |j                  d       | j	                  |j                  d       t         j                  j                  |j                        }| j	                  |j
                  d       | j	                  |j                  d       y)z>Test that failed messages are created and persisted correctly.r&   Test messagefailedr+  rc   rn   ro   r   error_messagerp  N)
r   r5   r8   rc   rE   r   r  ro   r   rC   )r<   
failed_msg	saved_msgs      r=   ,test_failed_message_creation_and_persistencezQLiuYaoConversationFailedMessageTests.test_failed_message_creation_and_persistence,  s     __++**", , 

 	**H5113EF++^< OO'':=='9	))84002DEr@   c                 n   t        d      D ]<  }t        j                  j                  | j                  |dz  dk(  rdndd| d       > t        d	      D ]3  }t        j                  j                  | j                  dd
| dd       5 | j                  | j                  j                         d       y)z;Test that failed messages don't count toward message limit.r   rv   r   r&   rp   r   sentrc   rn   ro   r   r   Failed message r  Errorr  Nr   r   r5   r8   rc   rE   rb   r<   r   s     r=   (test_failed_message_not_counted_in_limitzMLiuYaoConversationFailedMessageTests.test_failed_message_not_counted_in_limitA  s     rAOO""!.. 1uzV{"1#	 #   qAOO""!..)!-% #   	**<<>Cr@   c           	         ddl m} t        d      5 }t               }t	        d      |j
                  _        ||j                  _        t        d      5 }ddd|_        t        d	      5 }d
|_        | j                  t              5   || j                  dd       ddd       ddd       ddd       ddd       t        j                  j                  | j                  dd      j                         }| j                  |       | j!                  |j"                  d       | j                  |j$                         | j'                  d|j$                         y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)zQTest that when send_conversation_message fails, user message is marked as failed.r   r   r   zModel decommissionedr   rq   rr   r   r   r   r  r   r   Nr&   rm   r  )ai.utils.conversationr   r   r   r,  r   r	  r   r   r~  rc   r   r5   rr  firstrD   rE   r   r  rT   )r<   r   r   r   mock_configmock_promptrw   s          r=   %test_send_message_failure_sets_statuszJLiuYaoConversationFailedMessageTests.test_send_message_failure_sets_statusY  sK   C <=$;L6?@V6WL''34@L$$1<=8>Ib+c(HI[/<K, **951)-):):)7%) 6	 J > >( ??))**" * 
 %'	 	 	X&(3X334,h.D.DE# 65	 JI >= >=sT   AE?E3)E'E	E'$E3,E?E$ E''E0,E33E<	8E??Fc           	      B   t         j                  j                  | j                  dddd      }|j                  }t        d      5 }t               }d|j                  _        ||j                  _        t        d      5 }d	d
d|_        t        d      5 }d|_        t        | j                  dd|      }ddd       ddd       ddd       |j                          | j                  |j                  |       | j                  |j                  d       | j                  |j                         t         j                  j!                  | j                  dd      }| j                  |j#                         d       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)z@Test that retrying a failed message reuses the existing message.r&   Original messager  Previous errorr  r   r   r   rq   rr   r   r   r   r   rc   r   r   existing_user_messageNr  rm   r%  )r   r5   r8   rc   rC   r   r   r   r   r   r   r   rE   r   assertIsNoner  rr  r   )	r<   r  original_idr   r   r  r  rx   user_messagess	            r=   )test_retry_failed_message_reuses_existingzNLiuYaoConversationFailedMessageTests.test_retry_failed_message_reuses_existing}  sr    __++**&* , 

 !mm <=$;L7DL''44@L$$1<=8>Ib+c(HI[/<K,$=%)%6%6%7!%.8	%M J > >& 	""$4**F3*223  ..**& / 

 	,,.2- JI >= >=s<   8F>F	!E=5F	=F=FF		F	FFc           	         t         j                  j                  | j                  dddd      }t	        d      5 }t               }d|j                  _        ||j                  _        t	        d      5 }d	d
d|_        t	        d      5 }d|_        t        | j                  dd|      }ddd       ddd       ddd       |j                          | j                  |j                  d       | j                  |j                  d       | j                  |j                         y# 1 sw Y   }xY w# 1 sw Y   xY w# 1 sw Y   xY w)z6Test that retrying allows editing the message content.r&   r  r  r  r  r   r   r   rq   rr   r   r   r   Edited messager   r  Nr  )r   r5   r8   rc   r   r   r   r   r   r   r   rE   ro   r   r  r  r<   r  r   r   r  r  rx   s          r=   #test_retry_failed_message_with_editzHLiuYaoConversationFailedMessageTests.test_retry_failed_message_with_edit  s%    __++**&* , 

 <=$;L7DL''44@L$$1<=8>Ib+c(HI[/<K,$=%)%6%6%5!%.8	%M J > >& 	""$++-=>**F3*223 JI >= >=s;   8D=2D1!D%)D11D=%D.*D11D:	6D==Ec           	      $   t         j                  j                  | j                  dddd      }t	        d      5 }t               }d|j                  _        ||j                  _        t	        d      5 }d	d
d|_        t	        d      5 }d|_        t        | j                  dd|      }ddd       ddd       ddd       |j                          | j                  |j                  d       y# 1 sw Y   FxY w# 1 sw Y   JxY w# 1 sw Y   NxY w)zHTest that retry correctly transitions status: failed -> pending -> sent.r&   r  r  r  r  r   r   r   rq   rr   r   r   r   r   r  Nr  )r   r5   r8   rc   r   r   r   r   r   r   r   rE   r   r  s          r=   test_retry_status_transitionzALiuYaoConversationFailedMessageTests.test_retry_status_transition  s     __++**"! , 

 <=$;L7DL''44@L$$1<=8>Ib+c(HI[/<K, %>%)%6%6%3!%.8	%M J > >* 	""$**F3 JI >= >=s;   8D2C:!C.)C:1D.C73C::D	?DDc                 X    t               }|j                   j                         t        j                  j                   j                  dddd      }|j                  t        d      5 } fd}||_	        d	 j                  j                   d
 j                  j                   d}|j                  |ddi      }ddd        j                  j                  t        j                          j!                  d|j"                          j                  |j"                  d   d           j                  |j"                  d   d   d       t        j                  j%                   j                  dd      } j                  |j'                         d       y# 1 sw Y   xY w)z3Test retry endpoint reuses existing failed message.r%   r&   r  r  r  r  r   c                  $   j                  |j                  d             j                  |d   j                         |d   }d|_        d |_        |j                          t        j                  j                  j                  dddd      S )Nr  r  rp   r   rq   rr   rs   )rD   r   rE   rC   r   r  r   r   r5   r8   rc   )r  r  existing_msgr  r<   s      r=   r  zjLiuYaoConversationFailedMessageTests.test_retry_failed_message_api_endpoint.<locals>.mock_send_side_effect  s    $$VZZ0G%HI  (?!@!C!C[Q  &&=>&,#-1*!!# --!%!2!2$)#3 .  r@   r   r   r1  r  Nr   rC   r   r  rm   r%  )r   r   r&   r   r5   r8   rc   rC   r   r	  r:   r   rE   r   r   r   rT   r   rr  r   )	r<   r   r  	mock_sendr  r   r   r  r  s	   `       @r=   &test_retry_failed_message_api_endpointzKLiuYaoConversationFailedMessageTests.test_retry_failed_message_api_endpoint  s}   !!tyy!1 __++**"* , 

 !mm 89Y( %:I! !3!3 4ODDUDUDXDXCYY`aC{{3>) H1 :8 	--v/A/ABnhmm4~6t<kJ~6x@&I  ..**" / 

 	,,.2O :9s   .AF  F)c                     t               }|j                   j                         t        j                  j                   j                  dddd      }t        d      5 } fd}||_        d	 j                  j                   d
 j                  j                   d}|j                  |d|j                  d      }ddd        j                  j                  t        j                          j                  |j                   d   d   d       |j#                           j                  |j$                  d        j                  |j                  d       y# 1 sw Y   xY w)z3Test retry endpoint allows editing message content.r%   r&   r  r  r  r  r   c                      |d   }|d   |_         d|_        d |_        |j                          t        j
                  j                  j                  dddd      S )	Nr  r   r  rp   r   rq   rr   rs   )ro   r   r  r   r   r5   r8   rc   r  r  r  r<   s      r=   r  zkLiuYaoConversationFailedMessageTests.test_retry_failed_message_with_edit_api.<locals>.mock_send_side_effect=  sh    %&=>'-n'=$&,#-1*!!#--!%!2!2$)#3 .  r@   r   r   r1  r  )r  
message_idNr   ro   r  )r   r   r&   r   r5   r8   rc   r   r	  r:   rC   r   rE   r   r   r   r   r   ro   )r<   r   r  r  r  r   r   s   `      r=   'test_retry_failed_message_with_edit_apizLLiuYaoConversationFailedMessageTests.test_retry_failed_message_with_edit_api-  s=   !!tyy!1 __++**&* , 

 89Y  %:I! !3!3 4ODDUDUDXDXCYY`aC{{3+(mm) H) :2 	--v/A/AB~6yACST 	""$++-=>**F3? :9s   !AEE$c                    t               }|j                  | j                         t        j                  j                  | j                  dddd      }t        d      5 }t        d      |_	        d	| j                  j                   d
| j                  j                   d}|j                  |ddi      }ddd       | j                  j                  t        j                          | j#                  d|j$                         | j#                  d|j$                         | j                  |j$                  d   d   |j                         y# 1 sw Y   xY w)z/Test retry endpoint handles failures correctly.r%   r&   r  r  r  r  r   zRetry failedr   r   r1  r  Nr  r   rC   )r   r   r&   r   r5   r8   rc   r   r,  r	  r:   rC   r   rE   r   r   r-  rT   r   )r<   r   r  r  r   r   s         r=   %test_retry_failed_message_api_failurezJLiuYaoConversationFailedMessageTests.test_retry_failed_message_api_failure]  s#   !!tyy!1 __++**"* , 

 89Y$-n$=I! !3!3 4ODDUDUDXDXCYY`aC{{3>) H	 : 	--v/T/TUgx}}-nhmm4 	~6t<jmmL :9s    AEEc                    t        d      D ]<  }t        j                  j                  | j                  |dz  dk(  rdndd| d       > t        d	      D ]3  }t        j                  j                  | j                  dd
| dd       5 t        d      D ]2  }t        j                  j                  | j                  dd| d       4 | j                  | j                  j                         d       y)z=Test that message count excludes failed and pending messages.r   rv   r   r&   rp   Sent message r  r  r  r  r  r  r  zPending message pendingNr  r  s     r=   .test_message_count_excludes_failed_and_pendingzSLiuYaoConversationFailedMessageTests.test_message_count_excludes_failed_and_pending{  s     qAOO""!.. 1uzV{'s+	 #   qAOO""!..)!-% #   qAOO""!..*1#. 	 #   	**<<>Br@   c                 ~   t        d      D ];  }t        j                  j                  | j                  |dz  dk(  rdndd|        = t        d      D ]<  }t        j                  j                  | j                  |dz  dk(  rdndd| d	
       > | j                  | j                  j                         d       y)zPTest that messages without status (None) are counted for backward compatibility.r  rv   r   r&   rp   zOld message rm   r  r  r  r   Nr  r  s     r=   )test_message_count_backward_compatibilityzNLiuYaoConversationFailedMessageTests.test_message_count_backward_compatibility  s     qAOO""!.. 1uzV{&qc* #   qAOO""!.. 1uzV{'s+	 #   	**<<>Br@   c                     t               }|j                   j                         t        d      5 } fd}||_        d j
                  j                   d j                  j                   d}|j                  |ddd	      }d
d
d
        j                  j                  t        j                          j                  d|j                          j                  d|j                  d           j                  |j                  d   d   d        j                  d|j                  d           j                  |j                  d   d   d        j                  |j                  d           j                  d|j                          j                  d|j                         |j                  d   d   } j!                  |        j#                  |t$               y
# 1 sw Y   bxY w)zLTest that send message API returns failed message with ID in error response.r%   r   c                      t         j                  j                  j                  d|d   d      }d|_        d|_        |j                          t        d      Nr&   r   r  r  r  r+  r   r5   r8   rc   r   r  r   r,  r  r  rw   r<   s      r=   r  zyLiuYaoConversationFailedMessageTests.test_send_message_api_returns_failed_message_on_error.<locals>.mock_send_side_effect  sY    "??11!%!2!2">2$	 2  #+);& 233r@   r   r   r  r  r   r  Nr   rC   r   r  r  ro   r  r  detail)r   r   r&   r   r	  r:   rC   rc   r   rE   r   r   r-  rT   r   r  rD   r   r   )r<   r   r  r  r   r   r  s   `      r=   5test_send_message_api_returns_failed_message_on_errorzZLiuYaoConversationFailedMessageTests.test_send_message_api_returns_failed_message_on_error  s   !!tyy!1 89Y4 %:I! !3!3 4ODDUDUDXDXCYY_`C{{3) ) H' :2 	--v/T/TUnhmm4dHMM.9:~6x@(Kox}}^'DE~6yA>R(--(;<=gx}}-h. ]]>248
Z(j#.M :9s   AG&&G0c                 :    t               }|j                   j                         t        j                  j                   j                  ddddt        j                         t        j                  d      z
        }t        j                  j                   j                  dd	dd
t        j                         t        j                  d      z
        }t        d      5 } fd}||_        d j                  j                   d j                  j                   d}|j                  |      }ddd        j                  j                   t"        j$                          j                  |j&                  d   d   |j                         y# 1 sw Y   `xY w)z;Test that retry endpoint retries the latest failed message.r%   r&   First failedr  Error 1r   minutesrc   rn   ro   r   r  
created_atSecond failedError 2r   r   c                      |d   }d|_         |j                          t        j                  j	                  j
                  dd      S Nr  r  rp   r   rm   r   r   r   r5   r8   rc   r  s      r=   r  znLiuYaoConversationFailedMessageTests.test_multiple_failed_messages_retry_latest.<locals>.mock_send_side_effect  M    %&=>&,#!!#--!%!2!2$) .  r@   r   r   r1  Nr   rC   )r   r   r&   r   r5   r8   rc   r
   r9   	timedeltar   r	  r:   rC   r   rE   r   r   r   r   r<   r   failed_msg1failed_msg2r  r  r   r   s   `       r=   *test_multiple_failed_messages_retry_latestzOLiuYaoConversationFailedMessageTests.test_multiple_failed_messages_retry_latest  sV   !!tyy!1 oo,,**"#||~(:(:2(FF - 
 oo,,**##||~(:(:1(EE - 
 89Y %:I! !3!3 4ODDUDUDXDXCYY`aC{{3'H :" 	--v/A/AB~6t<knnM% :9s   #AFFc                     t               }|j                   j                         t        j                  j                   j                  dddd      }t        j                  j                   j                  dddd      }t        d	      5 } fd
}||_        d j                  j                   d j                  j                   d}|j                  |d|j                  i      }ddd        j                  j                  t        j                          j                  |j                   d   d   |j                         y# 1 sw Y   `xY w)z7Test retry endpoint can retry a specific message by ID.r%   r&   r  r  r  r  r  r  r   c                      |d   }d|_         |j                          t        j                  j	                  j
                  dd      S r  r  r  s      r=   r  zeLiuYaoConversationFailedMessageTests.test_retry_specific_message_by_id.<locals>.mock_send_side_effect&  r  r@   r   r   r1  r  Nr   rC   )r   r   r&   r   r5   r8   rc   r   r	  r:   rC   r   rE   r   r   r   r   r  s   `       r=   !test_retry_specific_message_by_idzFLiuYaoConversationFailedMessageTests.test_retry_specific_message_by_id  s4   !!tyy!1 oo,,**"# - 
 oo,,**## - 
 89Y %:I! !3!3 4ODDUDUDXDXCYY`aC{{3knn) H :& 	--v/A/AB~6t<knnM) :9s   AE

Ec                 B   ddl m} t        d      5 }t               }d|j                  _        ||j                  _        t        d      5 }ddd|_        t        d	      5 }d
|_         || j                  dd      }ddd       ddd       ddd       t        j                  j                  | j                  dd      j                         }| j                  |       | j                  |j                  d       y# 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   xY w)z1Test that new messages start with pending status.r   r  r   r   r   rq   rr   r   r   r   r  r   r   Nr&   rm   r  )r  r   r   r   r   r   r   rc   r   r5   rr  r  rD   rE   r   )r<   r   r   r   r  r  rx   rw   s           r=   #test_pending_message_status_on_sendzHLiuYaoConversationFailedMessageTests.test_pending_message_status_on_send;  s   C <=$;L7DL''44@L$$1<=8>Ib+c(HI[/<K,
 %>%)%6%6%3!%%M J > >* ??))**" * 
 %'	 	 	X&&1) JI >= >=s;   8D
D	 C==D	D=DD		D	DDc                    t         j                  j                  | j                  dddd      }| j                  j                  }t
        j                  j                  |      }|j                  j                         }|D cg c]  }|j                  dk(  s| }}| j                  t        |      d       | j                  |d   j                  |j                         | j                  |d   j                  d       y	c c}w )
z?Test that failed messages persist and are visible after reload.r&   r  r  r+  r  rp  r%  r   N)r   r5   r8   rc   rC   r   r   r   allr   rE   r   r  )r<   r  ru  reloaded_conversationr   mfailed_messagess          r=   .test_failed_message_persistence_across_reloadszSLiuYaoConversationFailedMessageTests.test_failed_message_persistence_across_reloads^  s     __++**", , 

 ++.. , 4 4 8 8O 8 L )11557&.Gh!((h2F1hG_-q1+..
>+99;MN	 Hs   DDc           	      Z   t         j                  j                  | j                  dddd      }t	        d      5 }t               }d|j                  _        ||j                  _        t	        d      5 }d	d
d|_        t	        d      5 }d|_        t        | j                  dd|      }ddd       ddd       ddd       |j                          | j                  |j                         | j                  |j                  d       y# 1 sw Y   axY w# 1 sw Y   exY w# 1 sw Y   ixY w)z0Test that successful retry clears error_message.r&   r  r  r  r  r   r   r   rq   rr   r   r   r   r   r  Nr  )r   r5   r8   rc   r   r   r   r   r   r   r   r  r  rE   r   r  s          r=   test_retry_clears_error_messagezDLiuYaoConversationFailedMessageTests.test_retry_clears_error_messageu  s    __++**"* , 

 <=$;L7DL''44@L$$1<=8>Ib+c(HI[/<K,$=%)%6%6%3!%.8	%M J > >& 	""$*223**F3 JI >= >=s;   8D!2D!D	)D1D!	DDD	D!!D*c                     t               }|j                   j                         t        j                  j                   j                  ddddt        j                         t        j                  d      z
        }t        j                  j                   j                  dd	dd
t        j                         t        j                  d      z
        }t        d      5 } fd}||_        d j                  j                   d j                  j                   d}|j                  |ddd      }ddd        j                  j                   t"        j$                          j'                  d|j(                          j'                  d|j(                  d           j                  |j(                  d   d   d        j                  |j(                  d   d   d        j                  |j(                  d   d   d       |j(                  d   d   } j+                  ||j                          j+                  ||j                         y# 1 sw Y    xY w)zQTest that send message API returns the latest failed message when multiple exist.r%   r&   zFirst failed messager  r  r   r  r  zSecond failed messager  r   r   c                      t         j                  j                  j                  d|d   d      }d|_        d|_        |j                          t        d      )Nr&   r   r  r  r  Latest errorzLatest AI service errorr  r  s      r=   r  zLiuYaoConversationFailedMessageTests.test_send_message_api_returns_latest_failed_message_on_error.<locals>.mock_send_side_effect  sY    "??11!%!2!2">2$	 2  #+)7& 9::r@   r   r   r  zLatest test messager   r  Nr   rC   ro   r   r  r  )r   r   r&   r   r5   r8   rc   r
   r9   r  r   r	  r:   rC   r   rE   r   r   r-  rT   r   r]  )	r<   r   r  r  r  r  r   r   returned_ids	   `        r=   <test_send_message_api_returns_latest_failed_message_on_errorzaLiuYaoConversationFailedMessageTests.test_send_message_api_returns_latest_failed_message_on_error  s   !!tyy!1 oo,,***#||~(:(:2(FF - 
 oo,,**+#||~(:(:1(EE - 
 89Y; %:I! !3!3 4ODDUDUDXDXCYY_`C{{30 ) H% :0 	--v/T/TUnhmm4dHMM.9:~6yACXY~6x@(K~6GX mmN3D9K8K8E :9s   #AIIc                     t               }|j                  | j                         t        d      5 }t	        d      |_        d| j                  j                   d| j                  j                   d}|j                  |ddd	      }d
d
d
       | j                  j                  t        j                         | j                  d|j                         | j                  d|j                         y
# 1 sw Y   lxY w)zDTest API error response when no failed message is found (edge case).r%   r   zError before message creationr   r   r  r  r   r  Nr  r  )r   r   r&   r   r,  r	  r:   rC   rc   r   rE   r   r   r-  rT   r   )r<   r   r  r   r   s        r=   8test_send_message_api_error_when_no_failed_message_foundz]LiuYaoConversationFailedMessageTests.test_send_message_api_error_when_no_failed_message_found  s    !!tyy!1 89Y$-.M$NI! !3!3 4ODDUDUDXDXCYY_`C{{3) ) H : 	--v/T/TUgx}}-h. :9s   AC44C=c                     t               }|j                   j                         t        d      5 } fd|_        d j
                  j                   d j                  j                   d}|j                  |ddd	      }d
d
d
        j                  j                  t        j                          j                  d|j                         |j                  d   d   }t        j                   j#                  |      } j                  |j                  |        j                  |j                  d        j                  |j$                  d        j                  |j&                  d        j                  |j                  j                   j                  j                         y
# 1 sw Y   -xY w)zHTest that returned failed message ID matches the actual database record.r%   r   c                      t         j                  j                  j                  d|d   d      }d|_        d|_        |j                          |j                  _        t        d      r  )
r   r5   r8   rc   r   r  r   rC   created_message_idr,  )r  r  rw   r  r<   s      r=   r  z|LiuYaoConversationFailedMessageTests.test_send_message_api_failed_message_id_matches_database.<locals>.mock_send_side_effect  sf    "??11!%!2!2">2$	 2  #+);&;C;;%8 233r@   r   r   r  z Test message for ID verificationr   r  Nr   rC   rp  r  r+  )r   r   r&   r   r	  r:   rC   rc   r   rE   r   r   r-  rT   r   r   r5   r   ro   r  )r<   r   r  r   r   returned_message_id
db_messager  s   `      @r=   8test_send_message_api_failed_message_id_matches_databasez]LiuYaoConversationFailedMessageTests.test_send_message_api_failed_message_id_matches_database  sq   !!tyy!1 89Y4" %:I! !3!3 4ODDUDUDXDXCYY_`C{{3= ) H+ :6 	--v/T/TUnhmm4&mmN;DA __((,?(@
(;<**H5++-OP113EF0033T5F5F5I5IJK :9s   AF33F=N)rX   rY   rZ   r[   r>   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r\   r@   r=   r  r    s    @
2F*D0"FH,3\"4H"4H83t.4`M<CBC.,/\+NZ+NZ!2FO.!4F;9z/.+Kr@   r  )*r[   jsonunittest.mockr   r   r   r   django.testr   r   django.contrib.authr	   django.utilsr
   r   rest_framework.testr   rest_frameworkr   	ai.modelsr   r   r   r  r   r   r   r   r   r   liuyao.modelsr   accounts.modelsr   r4   r   r^   r{   r   r@  r`  r  r\   r@   r=   <module>r     s     6 6 3 . !  ) ! @ @  ! '69X 69rX98 X9vs1X s1llM lM^`Gh `GFP1X P1fGK8 GKr@   