o
    ‹w•jž#  ã                   @   s  d Z ddlZddlm  mZ ddl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 dd
lmZ ddlmZmZmZ ejjdd„ ƒZejjdd„ ƒZ ejjdd„ ƒZ!ejjdd„ ƒZ"ejjdd„ ƒZ#ejjdd„ ƒZ$dS )zˆ
Tests for:
1. Super Admin email update to alok.chaudhary2001@gmail.com
2. End Chat conversation transcript email generation & dispatch
é    N)ÚpatchÚ	MagicMock)Úget_database)Úsettings)Úcreate_session)Úget_or_create_conversation)Úcreate_message)Úget_agent_by_email)Úadd_active_session)Úbuild_transcript_email_contentÚ"send_conversation_transcript_emailÚ_format_time_strc                 Ã   sê  �ddl m} |dd�}|d  ddi¡I dH }d}||u}|sPt d	|fd
||f¡dt ¡ v s5t |¡r:t |¡ndt |¡dœ }dd|i }t	t 
|¡ƒ‚d }}|d }d}	||	k}|sƒt d|fd||	f¡t |¡t |	¡dœ }
dd|
i }t	t 
|¡ƒ‚d } }}	|d }d}	||	k}|s¸t d|fd||	f¡t |¡t |	¡dœ }
dd|
i }t	t 
|¡ƒ‚d } }}	|d }d}	||	k}|sít d|fd||	f¡t |¡t |	¡dœ }
dd|
i }t	t 
|¡ƒ‚d } }}	dS )zq
    Verify that the Super Admin seed has email alok.chaudhary2001@gmail.com
    and retains its ADMIN role.
    r   )ÚInMemoryDatabaseT)Úseed_defaultÚagentsÚroleÚADMINN)úis not)z%(py0)s is not %(py3)sÚadmin)Úpy0Úpy3úassert %(py5)sÚpy5Úemailúalok.chaudhary2001@gmail.com©ú==©z%(py1)s == %(py4)s©Úpy1Úpy4úassert %(py6)sÚpy6ÚstatusÚACTIVE)Úapp.databaser   Úfind_oneÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚAssertionErrorÚ_format_explanation)Úclientr   Ú	seeded_dbr   Ú@py_assert2Ú@py_assert1Ú@py_format4Ú@py_format6Ú@py_assert0Ú@py_assert3Ú@py_format5Ú@py_format7© r9   ú:/web/html/dev/chatbot/backend/tests/test_end_chat_email.pyÚ'test_super_admin_email_is_updated_in_db   s   €
xjjnr;   c                  Ã   s.	  �ddl m } m} ddddd| dd	d
ddd|jd�dœ}ddddœ}ddd| dd	d
ddd|jd�dœddd| dd	d
ddd|jd�dœddd| dd	d
ddd|jd�dœg}t|dd i||d| dd	d
dd!d|jd�d"�\}}d#}||v }|s¤t d$|fd%||f¡t |¡d&t ¡ v s�t 	|¡r’t |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d+}||v }|sàt d$|fd%||f¡t |¡d&t ¡ v sÉt 	|¡rÎt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d,}||v }|�st d$|fd%||f¡t |¡d&t ¡ v �st 	|¡�rt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d-}||v }|�s^t d$|fd%||f¡t |¡d&t ¡ v �sGt 	|¡�rLt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d.}||v }|�s�t d$|fd%||f¡t |¡d&t ¡ v �s†t 	|¡�r‹t |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d/}||v }|�sÜt d$|fd%||f¡t |¡d&t ¡ v �sÅt 	|¡�rÊt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d0}||v }|�st d$|fd%||f¡t |¡d&t ¡ v �st 	|¡�r	t |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d1}||v }|�sZt d$|fd%||f¡t |¡d&t ¡ v �sCt 	|¡�rHt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d2}||v }|�s™t d$|fd%||f¡t |¡d&t ¡ v �s‚t 	|¡�r‡t |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d3}||v }|�sØt d$|fd%||f¡t |¡d&t ¡ v �sÁt 	|¡�rÆt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d4}||v }|�st d$|fd%||f¡t |¡d&t ¡ v �s t 	|¡�rt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d5}||v }|�sVt d$|fd%||f¡t |¡d&t ¡ v �s?t 	|¡�rDt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d6}||v }|�s•t d$|fd%||f¡t |¡d&t ¡ v �s~t 	|¡�rƒt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d7}||v }|�sÔt d$|fd%||f¡t |¡d&t ¡ v �s½t 	|¡�rÂt |¡nd&d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d}||v }|�st d$|fd%||f¡t |¡d8t ¡ v �süt 	|¡�rt |¡nd8d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d}||v }|�sRt d$|fd%||f¡t |¡d8t ¡ v �s;t 	|¡�r@t |¡nd8d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d}||v }|�s‘t d$|fd%||f¡t |¡d8t ¡ v �szt 	|¡�rt |¡nd8d'œ }	d(d)|	i }
t
t |
¡ƒ‚d* }}d*S )9zx
    Verify that build_transcript_email_content generates the required metadata
    and chronological message list.
    r   )ÚdatetimeÚtimezoneÚsess_test_12345Úsite_demo_abcz198.51.100.42ÚIndiaÚagent_alpha_999iê  é   é   é
   )Útzinfo)Ú	sessionIdÚsiteIdÚ	ipAddressÚcountryÚassignedAgentIdÚ	createdAtzAlok Chaudharyr   )ÚagentIdÚnamer   Úmsg_1Úuserz'Hello, I need assistance with my order.é   é   )Ú	messageIdr   ÚcontentrK   Úmsg_2Úagentz(Hello! I am happy to help you with that.é-   Úmsg_3ÚsystemzVideo call ended.é   ÚconversationIdÚconv_test_1é   )ÚsessionÚconversationÚmessagesÚ
agent_infoÚended_byÚended_atzChat Session Details©Úin)z%(py1)s in %(py3)sÚ	text_body)r   r   r   r   NzSession ID: sess_test_12345zSite ID: site_demo_abczVisitor IP: 198.51.100.42zCountry: IndiazAssigned Agent: Alok Chaudharyz)Agent Email: alok.chaudhary2001@gmail.comz(Chat Started At: 2026-08-31 10:00:00 UTCz&Chat Ended At: 2026-08-31 10:06:00 UTCzEnded By: agentzConversation Transcriptz?[10:01:15 UTC] Visitor:
Hello, I need assistance with my order.zO[10:01:45 UTC] Agent (Alok Chaudhary):
Hello! I am happy to help you with that.z([10:05:00 UTC] System:
Video call ended.Ú	html_body)r<   r=   Úutcr   r'   r(   r,   r)   r*   r+   r-   r.   )r<   r=   r]   r`   r_   re   rf   r5   r1   r3   r4   r9   r9   r:   Ú(test_transcript_email_content_formatting%   sl   €ú	ýüüüó
úx
x~~~~~~~~~~~~~~‚rh   c                 Ã   s  �t ƒ }t|dd�I dH }|d }t||dƒI dH }|d }t|||ddƒI dH  t|||dd	d
d�I dH  t|||ddƒI dH  ddlm} |ƒ }t|d|dd
d� tdƒ��«}d|_| j	d|ddœd�}	|	j
}
d}|
|k}|s¥t d|fd|
|f¡dt ¡ v s†t |	¡r‹t |	¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d }
 }}|	 ¡ d }d}||k}|sÜt d|fd||f¡t |¡t |¡d œ }d!d"|i }tt |¡ƒ‚d } }}| ¡  |jj}|d# }d$}||k}|�st d|fd||f¡t |¡t |¡d œ }d!d"|i }tt |¡ƒ‚d } }}|d% }d&|› �}||k}|�sSt d|fd||f¡t |¡t |¡d œ }d!d"|i }tt |¡ƒ‚d } }}d}|d' }||v }|�s‰t d(|fd)||f¡t |¡t |¡d œ }d!d"|i }tt |¡ƒ‚d } }}d	}|d' }||v }|�s¿t d(|fd)||f¡t |¡t |¡d œ }d!d"|i }tt |¡ƒ‚d } }}d}|d' }||v }|�sõt d(|fd)||f¡t |¡t |¡d œ }d!d"|i }tt |¡ƒ‚d } }}W d  ƒ dS 1 �sw   Y  dS )*u«   
    End Chat HTTP endpoint should load complete conversation and dispatch email to
    alok.chaudhary2001@gmail.com with subject 'Chat Conversation â€” <sessionId>'.
    Úsite_demo_123©Úsite_idNrF   rZ   rO   zVisitor initial queryrU   zAgent first responseÚagent_1)Úagent_idzVisitor follow-up queryr   ©Ú	AsyncMockÚIN_CHAT©Ú
status_valÚassigned_agent_idú*app.services.email_service._send_smtp_syncTú/api/v1/handoff/end©rF   ÚendedBy©ÚjsonéÈ   r   ©z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)sÚresp©r   Úpy2r   úassert %(py7)sÚpy7r#   ÚENDEDr   r   r!   r"   Ú	recipientr   Úsubjectu   Chat Conversation â€” Útext_contentrc   )z%(py1)s in %(py4)s)r   r   r   r   Úunittest.mockro   r
   r   Úreturn_valueÚpostÚstatus_coder'   r(   r)   r*   r+   r,   r-   r.   ry   Úassert_called_onceÚ	call_argsÚkwargs)r/   ÚdbÚsessÚsidÚconvÚcidro   Úmock_wsÚ	mock_smtpr|   r2   Ú@py_assert4r6   r4   Ú@py_format8r5   r1   r7   r8   Úcall_kwargsr9   r9   r:   Ú'test_end_chat_triggers_transcript_emailp   s8   €
þŠnlrlln$ïr–   c                 Ã   s
  �t ƒ }t|dd�I dH }|d }t||dƒI dH }|d }t|||ddƒI dH  dd	lm} |ƒ }t|d|d
dd� tdƒ��:}d|_| j	d|ddœd�}	|	j
}
d}|
|k}|s�t d|fd|
|f¡dt ¡ v snt |	¡rst |	¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d }
 }}|j}
d}|
|k}|sÒt d|fd|
|f¡dt ¡ v s³t |¡r¸t |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d }
 }}| j	d|ddœd�}|j
}
d}|
|k}|�s$t d|fd|
|f¡dt ¡ v �st |¡�r
t |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d }
 }}|j}
d}|
|k}|�slt d|fd|
|f¡dt ¡ v �sMt |¡�rRt |¡ndt |
¡t |¡dœ }dd|i }tt |¡ƒ‚d }
 }}W d  ƒ dS 1 �s~w   Y  dS )zY
    Subsequent calls to end_chat for the same session should not re-send the email.
    ri   rj   NrF   rZ   rO   zTest messager   rn   rp   rl   rq   rt   Tru   rU   rv   rx   rz   r   r{   Úresp1r}   r   r€   rP   )z2%(py2)s
{%(py2)s = %(py0)s.call_count
} == %(py5)sr’   Úresp2)r   r   r   r   r…   ro   r
   r   r†   r‡   rˆ   r'   r(   r)   r*   r+   r,   r-   r.   Ú
call_count)r/   rŒ   r�   rŽ   r�   r�   ro   r‘   r’   r—   r2   r“   r6   r4   r”   r˜   r9   r9   r:   Ú6test_duplicate_end_chat_does_not_send_duplicate_emailsš   s&   €ŠŠ�’$ôrš   c                 Ã   s8  �t ƒ }t|dd�I dH }|d }t||dƒI dH }|d }t|||ddƒI dH  dd	lm} |ƒ }t|d|d
d� tdtdƒd��Ž | j	d|ddœd�}|j
}	d}
|	|
k}|sŒt d|fd|	|
f¡dt ¡ v smt |¡rrt |¡ndt |	¡t |
¡dœ }dd|i }tt |¡ƒ‚d }	 }}
| ¡ d }d}||k}|sÃt d|fd||f¡t |¡t |¡dœ }dd|i }tt |¡ƒ‚d } }}W d  ƒ n1 sÓw   Y  |d   d|i¡I dH }|d }d}||k}|�st d|fd||f¡t |¡t |¡dœ }dd|i }tt |¡ƒ‚d } }}dS )!zœ
    If the email dispatch raises an unhandled exception or SMTP fails,
    End Chat must still succeed cleanly with status 200 and mark chat as ENDED.
    ri   rj   NrF   rZ   rO   zHello before errorr   rn   rp   ©rr   rt   zSMTP server connection timeout)Úside_effectru   Úvisitorrv   rx   rz   r   r{   r|   r}   r   r€   r#   r�   r   r   r!   r"   Úsessions)r   r   r   r   r…   ro   r
   r   Ú	Exceptionr‡   rˆ   r'   r(   r)   r*   r+   r,   r-   r.   ry   r&   )r/   rŒ   r�   rŽ   r�   r�   ro   r‘   r|   r2   r“   r6   r4   r”   r5   r1   r7   r8   Úupdated_sessr9   r9   r:   Ú*test_email_failure_does_not_break_end_chatº   s"   €Špýpr¡   c                 Ã   sH  �t ƒ }t|dd�I dH }|d }ddlm} |ƒ }t|d|dd� dd	lm}m} ||d
dƒ ||v }|sst 	d|fd||f¡dt
 ¡ v sKt |¡rPt |¡nddt
 ¡ v s\t |¡rat |¡nddœ }	dd|	i }
tt |
¡ƒ‚d}tddd��W | jd|ddœd�}|j}d}||k}|sÅt 	d|fd||f¡dt
 ¡ v s¦t |¡r«t |¡ndt |¡t |¡dœ }dd |i }tt |¡ƒ‚d } }}W d  ƒ n1 sÕw   Y  ||v}|�s t 	d!|fd"||f¡dt
 ¡ v söt |¡rût |¡nddt
 ¡ v �s	t |¡�rt |¡nddœ }	dd|	i }
tt |
¡ƒ‚d}dS )#zV
    Verifies that video calls are cleanly terminated when end_chat is triggered.
    ri   rj   NrF   r   rn   rp   r›   )Úactive_callsÚset_call_stateÚ	CONNECTEDrl   rc   )z%(py0)s in %(py2)srŽ   r¢   )r   r~   zassert %(py4)sr    rt   T)r†   ru   rU   rv   rx   rz   r   r{   r|   r}   r   r€   )únot in)z%(py0)s not in %(py2)s)r   r   r…   ro   r
   Úapp.services.video_signalingr¢   r£   r'   r(   r)   r*   r+   r,   r-   r.   r   r‡   rˆ   )r/   rŒ   r�   rŽ   ro   r‘   r¢   r£   r2   Ú@py_format3r7   r|   r“   r6   r4   r”   r9   r9   r:   Ú1test_video_call_termination_on_end_chat_preservedÕ   s   €ŠŒþ”r¨   )%Ú__doc__Úbuiltinsr)   Ú_pytest.assertion.rewriteÚ	assertionÚrewriter'   Úpytestr…   r   r   r%   r   Ú
app.configr   Ú#app.repositories.session_repositoryr   Ú(app.repositories.conversation_repositoryr   Ú#app.repositories.message_repositoryr   Ú!app.repositories.agent_repositoryr	   Úapp.services.presencer
   Úapp.services.email_servicer   r   r   ÚmarkÚanyior;   rh   r–   rš   r¡   r¨   r9   r9   r9   r:   Ú<module>   s.    "

J
)

