
    *jjg                        d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
Z
ddlZddlZddlmZ ej        d             Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zd ZdS )zBDD tests for runtime/api/chat.py.

Given: compiled test-persona fixture package (personas/examples/test-persona)
When:  user sends a message about a corpus topic
Then:  streamed SSE reply contains relevant persona content (via FakeProvider)
    )annotationsN)
TestClientc                    |                     dd           |                     dt          |                      ddlm} t	          |          S )z;TestClient with FakeProvider and examples/ as persona root.FAKE_PROVIDER1MENTORCORE_PERSONAS_ROOTr   app)setenvstrruntime.api.appr
   r   )examples_persona_rootmonkeypatchr
   s      D/Users/jameslopez/projects/MentorCore/tests/runtime/test_chat_api.pyclientr      sX     ,,,137L3M3MNNN######c??    c                   |                      dd           dd lmc m} |                                }|j        }d}||k    }|st          j        d|fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          t          j        |          d	z  }d
d|iz  }t          t          j        |                    d x}x}}|j        }|j        }d}||k    }	|	st          j        d|	fd||f          dt          j	                    v st          j
        |          rt          j        |          ndt          j        |          t          j        |          t          j        |          dz  }dd|iz  }
t          t          j        |
                    d x}x}x}	}d S )Nr   F)raisingr   personas==)z,%(py2)s
{%(py2)s = %(py0)s.name
} == %(py5)srootpy0py2py5assert %(py7)spy7
MentorCore)zH%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.parent
}.name
} == %(py7)s)r   r   py4r   zassert %(py9)spy9)delenvruntime.api.chatapichat_personas_rootname
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationparent)r   chat_moduler   @py_assert1@py_assert4@py_assert3@py_format6@py_format8@py_assert6@py_assert5@py_format10s              r   5test_default_personas_root_points_at_project_personasr:       s'   15AAA*********%%''D9"
"9
""""""""""9
""""""""""""4"""""4""""""9""""
""""""""""""""""""""""""""";+;+|+|++++++++++|++++++++++++4+++++4++++++;++++++++|+++++++++++++++++++++++++++++++r   c                4   |                      d          }|j        }d}||k    }|st          j        d|fd||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j	        |                    d	x}x}}d
 |
                                D             }d}||v }	|	st          j        d|	fd||f          t          j        |          dt	          j                    v st          j        |          rt          j        |          nddz  }
dd|
iz  }t          t          j	        |                    d	x}}	d	S )zVGiven: examples/ has test-persona. When: GET /api/personas. Then: test-persona listed./api/personas   r   z3%(py2)s
{%(py2)s = %(py0)s.status_code
} == %(py5)srespr   r   r   Nc                    g | ]
}|d          S slug .0ps     r   
<listcomp>z;test_list_personas_returns_test_persona.<locals>.<listcomp>-   s    ,,,1QvY,,,r   test-personain)z%(py1)s in %(py3)sslugs)py1py3zassert %(py5)sr   getstatus_coder(   r)   r*   r+   r,   r-   r.   r/   json)r   r?   r2   r3   r4   r5   r6   rK   @py_assert0@py_assert2@py_format4s              r   'test_list_personas_returns_test_personarU   )   s   ::o&&D"s"s""""""""""s""""""""""""4"""""4""""""""""s""""""""""""""""""""""""""",,		,,,E">U"""""""""">U""""">"""""""""""U"""""U"""""""""""""""""""""""""""""r   c                   |                      d          }d |                                D             }|d         d         }d}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }d	d
|iz  }t          t          j        |                    d x}x}}d S )Nr<   c                     i | ]}|d          |S rA   rC   rD   s     r   
<dictcomp>z7test_list_personas_has_display_name.<locals>.<dictcomp>3   s    222&	1222r   rH   display_namezTest Personar   z%(py1)s == %(py4)srL   r    assert %(py6)spy6)rO   rQ   r(   r)   r-   r.   r/   )r   r?   r   rR   r4   rS   @py_format5@py_format7s           r   #test_list_personas_has_display_namer`   1   s    ::o&&D22diikk222HN#N3E~E3~EEEEEEEEEE3~EEEEE3EEEE~EEEEEEEEEEEEEEEEEEEEEEEEEEEEEr   bodyr   return
list[dict]c                    g }|                                  D ]F}|                    d          r/|                    t          j        |dd                               G|S )Nzdata:    )
splitlines
startswithappendrQ   loads)ra   eventslines      r   
_parse_sserl   :   s^    F!! 0 0??8$$ 	0MM$*T!""X..///Mr   c                   |                      dddi          }|j        }d}||k    }|st          j        d|fd||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          d	z  }d
d|iz  }t          t          j	        |                    dx}x}}d}|j
        d         }||v }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j	        |
                    dx}x}}dS )zRGiven: test-persona. When: POST /api/chat/test-persona. Then: SSE stream received./api/chat/test-personamessagezTell me about virtue.rQ   r=   r   r>   r?   r   r   r   Nztext/event-streamzcontent-typerI   z%(py1)s in %(py4)sr[   r\   r]   )postrP   r(   r)   r*   r+   r,   r-   r.   r/   headersr   r?   r2   r3   r4   r5   r6   rR   rS   r^   r_   s              r   test_chat_streams_sseru   B   s   ;; 01   D "s"s""""""""""s""""""""""""4"""""4""""""""""s""""""""""""""""""""""""""">$,~">>">>>>>>>>>>>">>>>>>>>>>">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>r   c                   |                      dddi          }t          |j                  }d |D             }t          |          }d}||k    }|st	          j        d|fd||f          d	t          j                    v st	          j        t                    rt	          j	        t                    nd	d
t          j                    v st	          j        |          rt	          j	        |          nd
t	          j	        |          t	          j	        |          dz  }dd|iz  }t          t	          j        |                    d x}x}}d S )Nrn   ro   zWhat do you say about virtue?rp   c                D    g | ]}|                     d           dk    |S )typetextrO   rE   es     r   rG   z8test_chat_reply_contains_text_events.<locals>.<listcomp>R   s,    @@@f(?(?1(?(?(?r   r   )>)z/%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} > %(py6)slentext_eventsr   rL   rM   r]   assert %(py8)spy8rr   rl   ry   r~   r(   r)   r*   r+   r,   r-   r.   r/   )	r   r?   rj   r   rS   r8   r3   r_   @py_format9s	            r   $test_chat_reply_contains_text_eventsr   L   sp   ;; 89   D 	""F@@f@@@K{aaa33{{ar   c                t   |                      dddi          }t          |j                  }|d         d         }d}||k    }|slt          j        d|fd	||f          t          j        |          t          j        |          d
z  }dd|iz  }t          t          j        |                    d x}x}}d S )Nrn   ro   Hellorp   rx   doner   rZ   r[   r\   r]   )rr   rl   ry   r(   r)   r-   r.   r/   )r   r?   rj   rR   r4   rS   r^   r_   s           r   test_chat_reply_ends_with_doner   V   s    ;; !   D 	""F":f''''''''''''''''''''''''''''''''''''''''''''''''''r   c                   |                      dddi          }t          |j                  }d |D             }t          |          }d}||k    }|st	          j        d|fd||f          d	t          j                    v st	          j        t                    rt	          j	        t                    nd	d
t          j                    v st	          j        |          rt	          j	        |          nd
t	          j	        |          t	          j	        |          dz  }dd|iz  }t          t	          j        |                    d x}x}}d}	|d         }
|	|
v }|slt	          j        d|fd|	|
f          t	          j	        |	          t	          j	        |
          dz  }dd|iz  }t          t	          j        |                    d x}	x}}
d S )Nrn   ro   r   rp   c                D    g | ]}|                     d           dk    |S )rx   sessionrz   r{   s     r   rG   z0test_chat_returns_session_id.<locals>.<listcomp>b   s,    FFFA155==I+E+Ea+E+E+Er      r   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr~   session_eventsr   r   r   
session_idr   rI   rq   r[   r\   r]   r   )r   r?   rj   r   rS   r8   r3   r_   r   rR   r4   r^   s               r   test_chat_returns_session_idr   _   s   ;;/y'6J;KKD	""FFFFFFN~#!#!##########!############3#####3#############~#####~##########!###########################,>!,,<,,,,,,,,,,,<,,,,,,<,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,r   c                   |                      dddi          }t          |j                  }t          d |D                       }|                      dd|d          }|j        }d}||k    }|st          j        d	|fd
||f          dt          j                    v st          j	        |          rt          j
        |          ndt          j
        |          t          j
        |          dz  }dd|iz  }	t          t          j        |	                    dx}x}}t          |j                  }
d |
D             }t          |          }|sddt          j                    v st          j	        t                    rt          j
        t                    ndt          j
        |          t          j
        |          dz  }t          t          j        |                    dx}}dS )zRGiven: session_id from turn 1. When: turn 2 sends same session_id. Then: accepted.rn   ro   r   rp   c              3  X   K   | ]%}|                     d           dk    |d         V  &dS )rx   r   r   Nrz   r{   s     r   	<genexpr>z5test_chat_multiturn_reuses_session.<locals>.<genexpr>k   s:      UU!!%%--9:T:Tao:T:T:T:TUUr   z	Continue.)ro   r   r=   r   r>   resp2r   r   r   Nc              3  H   K   | ]}|                     d           dk    V  dS )rx   r   Nrz   r{   s     r   r   z5test_chat_multiturn_reuses_session.<locals>.<genexpr>s   s1      881quuV}}&888888r   z,assert %(py4)s
{%(py4)s = %(py0)s(%(py2)s)
}any)r   r   r    )rr   rl   ry   nextrP   r(   r)   r*   r+   r,   r-   r.   r/   r   )r   resp1events1r   r   r2   r3   r4   r5   r6   events2r^   s               r   "test_chat_multiturn_reuses_sessionr   g   s   KK0	77KKLLE$$GUUwUUUUUJKK $J??   E ########################5#####5#####################################$$G888888388888888888888883888883888888888888888888888888888888888r   c                   |                      dddi          }|j        }d}||k    }|st          j        d|fd||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          d	z  }d
d|iz  }t          t          j	        |                    d x}x}}d S )Nz/api/chat/nonexistentro   Hirp   i  r   r>   r?   r   r   r   )
rr   rP   r(   r)   r*   r+   r,   r-   r.   r/   )r   r?   r2   r3   r4   r5   r6   s          r   %test_chat_unknown_persona_returns_404r   v   s   ;;.i5F;GGD"s"s""""""""""s""""""""""""4"""""4""""""""""s"""""""""""""""""""""""""""""r   c                   |dz  }t          j        | |dz             |dz  dz  }t          j        |                                          }d|d<   |                    t          j        |                     i dd dfd
}|                    d	d
           |                    dt          |                     dd l	m
c m} ddlm} |                    |d|           t          |          }	|	                    dddi          }
|
j        }d}||k    }|st%          j        d|fd||f          dt)          j                    v st%          j        |
          rt%          j        |
          ndt%          j        |          t%          j        |          dz  }dd|iz  }t1          t%          j        |                    d x}x}}d         }d}||k    }|slt%          j        d|fd||f          t%          j        |          t%          j        |          dz  }dd|iz  }t1          t%          j        |                    d x}x}}d S )Nr   rH   zpersona.yaml   retrieval_top_k   )top_kembedderc                   |d<   g S )Nr   rC   )query	index_dirr   r   observeds       r   fake_retrievez>test_chat_uses_manifest_retrieval_top_k.<locals>.fake_retrieve   s    !	r   r   r   r   r   r	   retrievern   ro   r   rp   r=   r   r>   r?   r   r   r   r   rZ   r[   r\   r]   )shutilcopytreeyaml	safe_load	read_text
write_textdumpr   r   r#   r$   r%   r   r
   setattrr   rr   rP   r(   r)   r*   r+   r,   r-   r.   r/   )test_persona_dirtmp_pathr   r   manifest_pathmanifestr   r1   r
   r   r?   r2   r3   r4   r5   r6   rR   rS   r^   r_   r   s                       @r   'test_chat_uses_manifest_retrieval_top_kr   {   s   j D
O$d^&;<<<>)N:M~m557788H"#HTYx00111H12T        ,,,13t99===*********######Z???__F;;/y'6J;KKD"s"s""""""""""s""""""""""""4"""""4""""""""""s"""""""""""""""""""""""""""G!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!r   c                   |                      d          }|j        }d}||k    }|st          j        d|fd||f          dt	          j                    v st          j        |          rt          j        |          ndt          j        |          t          j        |          dz  }dd|iz  }t          t          j	        |                    d x}x}}|
                                d	         }d
}||k    }|slt          j        d|fd||f          t          j        |          t          j        |          dz  }	dd|	iz  }
t          t          j	        |
                    d x}x}}d S )Nz/healthr=   r   r>   r?   r   r   r   statusokrZ   r[   r\   r]   rN   rt   s              r   test_health_endpointr      s   ::i  D"s"s""""""""""s""""""""""""4"""""4""""""""""s"""""""""""""""""""""""""""99;;x (D( D(((((((((( D((((( ((((D(((((((((((((((((((((((((((((r   )ra   r   rb   rc   )__doc__
__future__r   builtinsr*   _pytest.assertion.rewrite	assertionrewriter(   rQ   r   pytestr   fastapi.testclientr   fixturer   r:   rU   r`   rl   ru   r   r   r   r   r   r   r   rC   r   r   <module>r      sV    # " " " " "                  ) ) ) ) ) )   , , ,# # #F F F   ? ? ?     ( ( (- - -9 9 9# # #
" " "8) ) ) ) )r   