§
     ’jù,  ã                  óº   — 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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  G d
„ de
j        ¦  «        ZdS )zNUnit and integration tests for document upload and AI classification pipeline.é    )ÚannotationsN)ÚPath)Ú	MagicMockÚpatch)Ú
TestClient)Úget_current_user)Ú
create_app)ÚDocumentProcessingServicec                  ó  — e Zd Zd$d„Zd$d„Zd$d„Zd$d„Z ed¦  «        d%d
„¦   «         Z ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «        d&d„¦   «         ¦   «         ¦   «         ¦   «         ¦   «         ¦   «         Z	 ed¦  «         ed¦  «         ed¦  «         ed¦  «         ed¦  «        d'd!„¦   «         ¦   «         ¦   «         ¦   «         ¦   «         Z
 ed¦  «        d(d"„¦   «         Zd#S ))ÚTestDocumentUploadAiÚreturnÚNonec                ó   — g | _         d S ©N)Ú
temp_files)Úselfs    ú3C:\Projects\DSCons\tests\test_document_upload_ai.pyÚsetUpzTestDocumentUploadAi.setUp   s   € Ø&(ˆŒˆˆó    c                óŒ   — | j         D ];}	 |                     ¦   «         r|                     ¦   «          Œ,# t          $ r Y Œ8w xY wd S r   )r   ÚexistsÚunlinkÚ	Exception)r   Úps     r   ÚtearDownzTestDocumentUploadAi.tearDown   s`   € Ø”ð 	ð 	ˆAðØ—8’8‘:”:ð Ø—H’H‘J”J�JøøÝð ð ð Ø�ðøøøð		ð 	s   ‹(4´
AÁ Ac                ó>  — t          ¦   «         }d}d}|                     ||¦  «        \  }}}}}t          |¦  «        }	| j                             |	¦  «         |                      |	                     ¦   «         ¦  «         |                      |t          |¦  «        ¦  «         |                      |d¦  «         |                      | 	                    d¦  «        ¦  «         |                      |	 
                    ¦   «         |¦  «         |                      |¦  «         d S )Ns   Mock document contentztest_doc.txtÚtxtz/v1/erp/documents/vault/)r
   Ú	save_filer   r   ÚappendÚ
assertTruer   ÚassertEqualÚlenÚ
startswithÚ
read_bytesÚassertIsNotNone)
r   ÚserviceÚfile_contentÚfilenameÚfile_urlÚfile_path_strÚ	file_sizeÚfile_formatÚ	file_hashÚ	file_paths
             r   Útest_save_filez#TestDocumentUploadAi.test_save_file   s  € Ý+Ñ-Ô-ˆØ/ˆØ!ˆàEL×EVÒEVØ˜(ñF
ô F
ÑBˆ�- ¨K¸õ ˜Ñ'Ô'ˆ	ØŒ×Ò˜yÑ)Ô)Ð)à�Š˜	×(Ò(Ñ*Ô*Ñ+Ô+Ð+Ø×Ò˜¥C¨Ñ$5Ô$5Ñ6Ô6Ð6Ø×Ò˜ eÑ,Ô,Ð,Ø�Š˜×+Ò+Ð,FÑGÔGÑHÔHÐHØ×Ò˜×-Ò-Ñ/Ô/°Ñ>Ô>Ð>Ø×Ò˜YÑ'Ô'Ð'Ð'Ð'r   c                óØ  — t          ¦   «         }t          j        ¦   «         }t          j        |d¦  «        5 }d}|                     d|¦  «         d d d ¦  «         n# 1 swxY w Y   |                     ¦   «         }|                     |d¦  «        \  }}}}	}
| j         	                    t          |¦  «        ¦  «         |                     ||	¦  «        }|                      |d¦  «         d S )NÚwu   <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <w:body>
    <w:p>
      <w:r>
        <w:t>BiÃªn báº£n nghiá»‡m thu cÃ´ng trÃ¬nh sá»‘ 456</w:t>
      </w:r>
    </w:p>
  </w:body>
</w:document>zword/document.xmlztest_document.docxu.   BiÃªn báº£n nghiá»‡m thu cÃ´ng trÃ¬nh sá»‘ 456)r
   ÚioÚBytesIOÚzipfileÚZipFileÚwritestrÚgetvaluer   r   r   r   Úextract_textr!   )r   r&   Údocx_bufferÚzÚxml_contentÚ	docx_datar)   r*   r+   r,   r-   Úextracted_texts               r   Útest_extract_text_docxz+TestDocumentUploadAi.test_extract_text_docx1   s,  € Ý+Ñ-Ô-ˆÝ”j‘l”lˆõ Œ_˜[¨#Ñ.Ô.ð 	9°!ð	 ð ð �JŠJÐ*¨KÑ8Ô8Ð8ð	9ð 	9ð 	9ñ 	9ô 	9ð 	9ð 	9ð 	9ð 	9ð 	9ð 	9øøøð 	9ð 	9ð 	9ð 	9ð  ×(Ò(Ñ*Ô*ˆ	ØEL×EVÒEVØÐ+ñF
ô F
ÑBˆ�- ¨K¸ð 	Œ×Ò�t MÑ2Ô2Ñ3Ô3Ð3à ×-Ò-¨m¸[ÑIÔIˆØ×Ò˜Ð)YÑZÔZÐZÐZÐZs   ·AÁA Á#A z8app.modules.agents.application.llm_client.LLMClient.chatÚ	mock_chatr   c                ó”   ‡ ‡‡— dd l }dŠd
ˆfd„}||_        t          ¦   «         Šˆ ˆfd	„}|                      |¦   «         ¦  «         d S )Nr   uÞ  ```json
{
  "document_group": "acceptance",
  "document_type": "BB",
  "document_code": "BB-NT-456",
  "document_title": "BiÃªn báº£n nghiá»‡m thu hoÃ n thÃ nh",
  "issue_date": "2026-08-19",
  "issuer_name": "DSCons Corp",
  "signer_name": "Nguyá»…n VÄƒn A",
  "summary_content": "Nghiá»‡m thu hoÃ n thÃ nh háº¡ng má»¥c káº¿t cáº¥u táº§ng háº§m.",
  "ai_risk_assessment": "KhÃ´ng phÃ¡t hiá»‡n rá»§i ro.",
  "ai_legal_references": ["Luáº­t XÃ¢y dá»±ng 2025 (Ä�iá»�u 135)"]
}
```ÚargsÚAnyÚkwargsr   Ústrc               Ÿ  ó   •K  — ‰S r   © )rA   rC   Úmock_responses     €r   Ú	fake_chatz<TestDocumentUploadAi.test_analyze_with_ai.<locals>.fake_chatc   s   øè è € Ø Ð r   c               “  ó\  •K  — ‰                      dd¦  «        ƒ d {V —†} ‰                     | d         d¦  «         ‰                     | d         d¦  «         ‰                     | d         d¦  «         ‰                     | d	         d
¦  «         ‰                     | d         d¦  «         d S )NzMock document text contentztest.pdfÚdocument_groupÚ
acceptanceÚdocument_typeÚBBÚdocument_codez	BB-NT-456Údocument_titleu%   BiÃªn báº£n nghiá»‡m thu hoÃ n thÃ nhÚsigner_nameu   Nguyá»…n VÄƒn A)Úanalyze_with_air!   )Úresultr   r&   s    €€r   Úrun_testz;TestDocumentUploadAi.test_analyze_with_ai.<locals>.run_testj   sÒ   øè è € Ø"×2Ò2Ø,¨jñô ð ð ð ð ð ð ˆFð ×Ò˜VÐ$4Ô5°|ÑDÔDÐDØ×Ò˜V OÔ4°dÑ;Ô;Ð;Ø×Ò˜V OÔ4°kÑBÔBÐBØ×Ò˜VÐ$4Ô5Ð7^Ñ_Ô_Ð_Ø×Ò˜V MÔ2Ð4EÑFÔFÐFÐFÐFr   )rA   rB   rC   rB   r   rD   )ÚasyncioÚside_effectr
   Úrun)r   r?   rT   rH   rS   rG   r&   s   `    @@r   Útest_analyze_with_aiz)TestDocumentUploadAi.test_analyze_with_aiN   s�   øøø€ àˆˆˆðð 	ð"	!ð 	!ð 	!ð 	!ð 	!ð 	!ð !*ˆ	Ôå+Ñ-Ô-ˆð	Gð 	Gð 	Gð 	Gð 	Gð 	Gð 	�Š�H�H‘J”JÑÔÐÐÐr   zKapp.core.postgres.erp_client.ErpDatabaseClient.create_project_from_documentz;app.core.postgres.erp_client.ErpDatabaseClient.get_documentzhapp.modules.core.application.document_processing_service.DocumentProcessingService.run_cross_agent_auditzbapp.modules.core.application.document_processing_service.DocumentProcessingService.analyze_with_aiz_app.modules.core.application.document_processing_service.DocumentProcessingService.extract_textz>app.core.postgres.erp_client.ErpDatabaseClient.update_documentÚmock_updateÚmock_extractÚmock_analyzeÚmock_cross_auditÚmock_get_docÚmock_create_projc                óú   ‡ ‡‡‡‡	— dd l }ddd dœ|_        ddddœd	œ|_        d
‰_        ddg dœ|_        ddddddddddgdœ
‰_        t          ¦   «         Š	ˆˆˆˆ ˆ	fd„}|                      |¦   «         ¦  «         d S )Nr   ú
doc-uuid-1zTEMP-123)ÚidrN   Ú
project_idTzp-1ÚDA)r`   Úproject_name)Úcreated_newÚprojectuj   Cá»™ng hÃ²a XÃ£ há»™i Chá»§ nghÄ©a Viá»‡t Nam. extracted sample text há»£p Ä‘á»“ng kinh táº¿ Ä‘áº§y Ä‘á»§.é_   u3   Há»“ sÆ¡ trÃ­ch xuáº¥t hoÃ n chá»‰nh, chuáº©n xÃ¡c.)Úconfidence_scoreÚcross_audit_summaryÚflagsÚcontractÚHDúHD-123õ   Há»£p Ä‘á»“ng thiáº¿t káº¿z
2026-08-19z
DSCons Ltdu   Tráº§n Bu4   Há»£p Ä‘á»“ng thiáº¿t káº¿ kiáº¿n trÃºc cáº£nh quan.u    CÃ³ rá»§i ro cháº­m thanh toÃ¡n.u   Nghá»‹ Ä‘á»‹nh 206/2026/NÄ�-CP)
rJ   rL   rN   rO   Ú
issue_dateÚissuer_namerP   Úsummary_contentÚai_risk_assessmentÚai_legal_referencesc               “  ó„  •K  — ‰                      dddd¦  «        ƒ d {V —† ‰                     dd¦  «         ‰                     ‰j        d¦  «         ‰                     ¦   «          ‰j        d         } ‰                     | d         d¦  «         | d         }‰                     |d         d¦  «         ‰                     |d	         d
¦  «         ‰                     |d         d¦  «         ‰                     |d         d¦  «         ‰                     |d         d¦  «         ‰                     |d         d¦  «         d S )Nr_   z/tmp/fake_path.pdfzfake_path.pdfÚpdfr   é   rN   rl   rO   rm   rJ   rj   rL   rk   ÚstatusÚpending_reviewÚverification_status)Úrun_pipelineÚassert_called_once_withÚreturn_valueÚassert_called_onceÚ	call_argsr!   )r}   ÚpayloadrZ   rY   rX   r   r&   s     €€€€€r   rS   z8TestDocumentUploadAi.test_run_pipeline.<locals>.run_test­   st  øè è € Ø×&Ò&ØÐ2°OÀUñô ð ð ð ð ð ð ð ð ×0Ò0Ð1EÀuÑMÔMÐMØ×0Ò0ØÔ)¨?ñô ð ð ×*Ò*Ñ,Ô,Ð,ð $Ô-¨aÔ0ˆIØ×Ò˜Y qœ\¨<Ñ8Ô8Ð8Ø ”lˆGØ×Ò˜W _Ô5°xÑ@Ô@Ð@Ø×Ò˜WÐ%5Ô6Ð8TÑUÔUÐUØ×Ò˜WÐ%5Ô6¸
ÑCÔCÐCØ×Ò˜W _Ô5°tÑ<Ô<Ð<Ø×Ò˜W XÔ.Ð0@ÑAÔAÐAØ×Ò˜WÐ%:Ô;Ð=MÑNÔNÐNÐNÐNr   )rT   r{   r
   rV   )
r   rX   rY   rZ   r[   r\   r]   rT   rS   r&   s
   ````     @r   Útest_run_pipelinez&TestDocumentUploadAi.test_run_pipelinev   s  øøøøø€ ð. 	ˆˆˆð Ø'Øð%
ð %
ˆÔ!ð  Ø#°TÐ:Ð:ð)
ð )
ÐÔ%ð %QˆÔ!à "Ø#XØð)
ð )
ÐÔ%ð )Ø!Ø%Ø:Ø&Ø'Ø%ØUØ"DØ$DÐ#Eð%
ð %
ˆÔ!õ ,Ñ-Ô-ˆð	Oð 	Oð 	Oð 	Oð 	Oð 	Oð 	Oð 	Oð 	Oð* 	�Š�H�H‘J”JÑÔÐÐÐr   zGapp.core.postgres.erp_client.ErpDatabaseClient.check_duplicate_documentz>app.core.postgres.erp_client.ErpDatabaseClient.create_documentz=app.core.postgres.erp_client.ErpDatabaseClient.get_connectionz\app.modules.core.application.document_processing_service.DocumentProcessingService.save_fileÚ	mock_saveÚmock_get_connÚmock_update_docÚmock_create_docÚmock_check_dupc                óÞ  — t          ¦   «         }t          ¦   «         }ddiddig|j        _        ||j        j        j        _        ||j        j        _        d|_        d |_        ddi|_        dddœ|_        t          ¦   «         }d„ |j        t          <   t          |¦  «        }	t          d	¦  «        5 }
|	                     d
ddiddi¬¦  «        }|                      |j        d¦  «         |                      |                     ¦   «         d         d¦  «         |                     ¦   «          |                     ¦   «          |
                     ¦   «          d d d ¦  «         d S # 1 swxY w Y   d S )Nr`   zcompany-uuid-1zproject-uuid-1)z/static/uploads/file.pdfz/disk/file.pdféd   rt   Úmock_hash_123údoc-uuid-101Ú
processing)r`   rv   c                 ó   — ddddœS ©Nzuser-1ztest@dscons.vnÚ
superadmin)r`   ÚemailÚrolerF   rF   r   r   ú<lambda>z?TestDocumentUploadAi.test_api_upload_document.<locals>.<lambda>é   ó   € ØØ%Ø ð>
ð >
€ r   z fastapi.BackgroundTasks.add_taskz/v1/erp/documents/uploadÚfile)z
report.pdfs   pdf content byteszapplication/pdfÚproject_codezPRJ-999)ÚfilesÚdataéÈ   )r   ÚfetchonerU   Úcursorr{   Ú	__enter__r	   Údependency_overridesr   r   r   Úpostr!   Ústatus_codeÚjsonr|   )r   r€   r�   r‚   rƒ   r„   Ú	mock_connÚmock_curÚappÚclientÚmock_add_taskÚresponses               r   Útest_api_upload_documentz-TestDocumentUploadAi.test_api_upload_documentÄ   sÄ  € õ  ‘K”Kˆ	Ý‘;”;ˆàÐ#Ð$ØÐ#Ð$ð)
ˆÔÔ%ð @Hˆ	ÔÔ%Ô/Ô<Ø<EˆÔ"Ô,Ô9ð"
ˆ	Ôð '+ˆÔ#Ø(,¨nÐ'=ˆÔ$Ø.<ÈÐ'UÐ'UˆÔ$å‰lŒlˆð6
ð 6
ˆÔ Õ!1Ñ2õ
 ˜C‘”ˆåÐ5Ñ6Ô6ð 	/¸-Ø—{’{Ø*ØÐVÐWØ$ iÐ0ð #ñ ô ˆHð ×Ò˜XÔ1°3Ñ7Ô7Ð7Ø×Ò˜XŸ]š]™_œ_¨TÔ2°NÑCÔCÐCØ×.Ò.Ñ0Ô0Ð0Ø×.Ò.Ñ0Ô0Ð0Ø×,Ò,Ñ.Ô.Ð.ð	/ð 	/ð 	/ñ 	/ô 	/ð 	/ð 	/ð 	/ð 	/ð 	/ð 	/ð 	/øøøð 	/ð 	/ð 	/ð 	/ð 	/ð 	/s   Â3B"E"Å"E&Å)E&c                óÆ  — ddddœ|_         t          ¦   «         }d„ |j        t          <   t	          |¦  «        }|                     dddd	œ¬
¦  «        }|                      |j        d¦  «         |                      |                     ¦   «         d         d¦  «         |                      |                     ¦   «         d         d¦  «         | 	                    ¦   «          |j
        d         d         }|                      |d         d¦  «         |                      |d         d¦  «         |                      |d         d¦  «         |                      |d         d¦  «         d S )Nrˆ   ÚvalidÚverified)r`   rv   rx   c                 ó   — ddddœS r‹   rF   rF   r   r   r�   z@TestDocumentUploadAi.test_api_approve_document.<locals>.<lambda>  r�   r   z&/v1/erp/documents/doc-uuid-101/approveu   Ä�Ã£ phÃª duyá»‡t trÃ­ch xuáº¥tz	CV-OK-101)rO   rN   )rœ   r•   rv   rx   r   ru   rO   rN   )r{   r	   r™   r   r   rš   r!   r›   rœ   r|   r}   )r   rX   rŸ   r    r¢   r~   s         r   Útest_api_approve_documentz.TestDocumentUploadAi.test_api_approve_documentý   so  € ð !ØØ#-ð$
ð $
ˆÔ õ ‰lŒlˆð6
ð 6
ˆÔ Õ!1Ñ2õ
 ˜C‘”ˆà—;’;Ø4à"CØ!,ðð ð ñ 
ô 
ˆð 	×Ò˜Ô-¨sÑ3Ô3Ð3Ø×Ò˜Ÿš™œ¨Ô2°GÑ<Ô<Ð<Ø×Ò˜Ÿš™œÐ)>Ô?ÀÑLÔLÐLØ×&Ò&Ñ(Ô(Ð(ØÔ'¨Ô*¨1Ô-ˆØ×Ò˜ Ô*¨GÑ4Ô4Ð4Ø×Ò˜Ð!6Ô7¸ÑDÔDÐDØ×Ò˜Ð!1Ô2Ð4UÑVÔVÐVØ×Ò˜ Ô1°;Ñ?Ô?Ð?Ð?Ð?r   N)r   r   )r?   r   r   r   )rX   r   rY   r   rZ   r   r[   r   r\   r   r]   r   r   r   )r€   r   r�   r   r‚   r   rƒ   r   r„   r   r   r   )rX   r   r   r   )Ú__name__Ú
__module__Ú__qualname__r   r   r/   r>   r   rW   r   r£   r¨   rF   r   r   r   r      s  € € € € € ð)ð )ð )ð )ðð ð ð ð(ð (ð (ð (ð&[ð [ð [ð [ð: €UÐEÑFÔFð% ð % ð % ñ GÔFð% ðN €UØUñô ð €UÐHÑIÔIØ
€UØrñô ð €UØlñô ð €UØiñô ð €UÐKÑLÔLð> ð > ð > ñ MÔLñô ñô ñô ñ JÔIñô ð> ð@ €UÐTÑUÔUØ
€UÐKÑLÔLØ
€UÐKÑLÔLØ
€UÐJÑKÔKØ
€UØfñô ð0/ð 0/ð 0/ñô ñ LÔKñ MÔLñ MÔLñ VÔUð0/ðd €UÐKÑLÔLð@ð @ð @ñ MÔLð@ð @ð @r   r   )Ú__doc__Ú
__future__r   ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arr2   Úunittestr4   Úpathlibr   Úunittest.mockr   r   Úfastapi.testclientr   Ú"app.modules.auth.presentation.authr   Úapp.mainr	   Ú8app.modules.core.application.document_processing_servicer
   ÚTestCaser   rF   r   r   ú<module>r¼      s  ðØ TÐ Tà "Ð "Ð "Ð "Ð "Ð "à  € € € € € € € € € € € € €	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *à )Ð )Ð )Ð )Ð )Ð )à ?Ð ?Ð ?Ð ?Ð ?Ð ?Ø Ð Ð Ð Ð Ð Ø ^Ð ^Ð ^Ð ^Ð ^Ð ^ðK@ð K@ð K@ð K@ð K@˜8Ô,ñ K@ô K@ð K@ð K@ð K@r   