§
    ”¢ªj8,  ã                   óÂ   — d Z ddlmZmZ ddlZddlmZ ddlmZm	Z	m
Z
mZ ddl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mZmZ d„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z d„ Z!dS )u½  AutoPOE2 - Unit Tests for Stash & Inventory Management (Doc 63 / SSoT 2026).

Kiá»ƒm thá»­ toÃ n diá»‡n há»‡ thá»‘ng Stash:
- TÃ­nh toÃ¡n tá»�a Ä‘á»™ vÃ  co giÃ£n Ä‘á»™ phÃ¢n giáº£i 1080p -> 1440p.
- PhÃ¢n loáº¡i tÃªn Tab Stash.
- Ä�Ã¡nh giÃ¡ quy táº¯c cáº¥t Ä‘á»“ (Deposit) vÃ  giá»¯ láº¡i (Keep) theo Pickit.
- Ä�Ã¡nh giÃ¡ quy táº¯c rÃºt Waystone (Withdraw).
- Giáº£ láº­p chu trÃ¬nh Ä‘iá»�u phá»‘i StashOrchestrator khÃ´ng cáº§n game client.
é    )Ú	MagicMockÚpatchN)ÚImage)ÚStashActionÚStashConfigÚStashTabTypeÚTAB_NAME_MAPPINGS)ÚStashTabInfoÚStashUiScanner)ÚStashItemMatrixÚSlotItemInfo)ÚStashEvaluator)ÚStashOrchestrator)ÚItemCategoryÚItemInspectionReportÚ
ItemRarityc                  ó:  — t          dd¬¦  «        } |                      dd¦  «        }|dk    sJ ‚|                      dd¦  «        }|dk    sJ ‚t          dd¬¦  «        }|                     dd¦  «        }|d	k    sJ ‚|                     dd¦  «        }|d
k    sJ ‚dS )uN   Kiá»ƒm tra co giÃ£n tá»�a Ä‘á»™ tham chiáº¿u 1080p sang 1440p (tá»· lá»‡ 4/3).i€  i8  ©Úscreen_wÚscreen_hr   )i  ih  )éÎ   éØ   é 
  é   )éÃ  é6  )i  i   N)r   Úget_inventory_slot_centerÚget_stash_slot_center)Úmatrix_1080Úinv_0_0_1080Ústash_0_0_1080Úmatrix_1440Úinv_0_0_1440Ústash_0_0_1440s         ú0C:\Projects\AutoPOE2\tests\test_stash_manager.pyÚtest_stash_coordinates_scalingr&       sÈ   € õ "¨4¸$Ð?Ñ?Ô?€KØ×8Ò8¸¸AÑ>Ô>€LØ˜;Ò&Ð&Ð&Ð&à ×6Ò6°q¸!Ñ<Ô<€NØ˜ZÒ'Ð'Ð'Ð'õ "¨4¸$Ð?Ñ?Ô?€KØ×8Ò8¸¸AÑ>Ô>€LØ˜;Ò&Ð&Ð&Ð&à ×6Ò6°q¸!Ñ<Ô<€NØ˜ZÒ'Ð'Ð'Ð'Ð'Ð'ó    c                  óÂ  — t          dd¬¦  «        } |                      d¦  «        t          j        k    sJ ‚|                      d¦  «        t          j        k    sJ ‚|                      d¦  «        t          j        k    sJ ‚|                      d¦  «        t          j        k    sJ ‚|                      d¦  «        t          j        k    sJ ‚|                      d	¦  «        t          j        k    sJ ‚|                      d
¦  «        t          j        k    sJ ‚|                      d¦  «        t          j        k    sJ ‚|                      d¦  «        t          j        k    sJ ‚dS )u9   Kiá»ƒm tra nháº­n diá»‡n vÃ  phÃ¢n loáº¡i tÃªn Stash Tab.r   r   r   ÚCURRENCYÚCurrÚ	WaystoneszT16 MapsÚGEMSz
Uncut GemsÚ	FRAGMENTSzDump 1z
Random TabN)	r   Ú_classify_tab_namer   r)   Ú	WAYSTONESr,   r-   ÚDUMPÚGENERAL)Úscanners    r%   Útest_tab_name_classificationr3   3   sL  € å d°TÐ:Ñ:Ô:€GØ×%Ò% jÑ1Ô1µ\Ô5JÒJÐJÐJÐJØ×%Ò% fÑ-Ô-µÔ1FÒFÐFÐFÐFØ×%Ò% kÑ2Ô2µlÔ6LÒLÐLÐLÐLØ×%Ò% jÑ1Ô1µ\Ô5KÒKÐKÐKÐKØ×%Ò% fÑ-Ô-µÔ1BÒBÐBÐBÐBØ×%Ò% lÑ3Ô3µ|Ô7HÒHÐHÐHÐHØ×%Ò% kÑ2Ô2µlÔ6LÒLÐLÐLÐLØ×%Ò% hÑ/Ô/µ<Ô3DÒDÐDÐDÐDØ×%Ò% lÑ3Ô3µ|Ô7KÒKÐKÐKÐKÐKÐKr'   c                  ó²  — t          d¬¦  «        } t          | ¬¦  «        }t          ddt          j        ¬¦  «        }|                     |¦  «        }|j        t          j        k    sJ ‚t          ddt          j	        ¬¦  «        }|                     |d¬	¦  «        }|j        t          j        k    sJ ‚|j
        t          j        k    sJ ‚|                     |d¬	¦  «        }|j        t          j        k    sJ ‚|j
        t          j        k    sJ ‚t          t          d
¬¦  «        ¬¦  «        }t          d
¦  «        D ]<}|                     ||¬	¦  «        }	|	j        t          j        k    sJ d|› d�¦   «         ‚Œ=|                     |d
¬	¦  «        }
|
j        t          j        k    s
J d¦   «         ‚t          ddt          j        ¬¦  «        }|                     |¦  «        }|j        t          j        k    sJ ‚|j
        t          j        k    sJ ‚t          ddt          j        ¬¦  «        }|                     |¦  «        }|j        t          j        k    sJ ‚|j
        t          j        k    sJ ‚t          ddt          j        t$          j        ¬¦  «        }|                     |¦  «        }|j        t          j        k    sJ ‚|j
        t          j        k    sJ ‚dS )uP   Kiá»ƒm tra logic phÃ¢n luá»“ng vÃ  ra quyáº¿t Ä‘á»‹nh cáº¥t Ä‘á»“ / giá»¯ láº¡i.é   ©Úkeep_waystones_count©ÚconfigzScroll of Wisdom)Ú	item_nameÚ	base_typeÚcategoryzWaystone (Tier 15)ÚWaystoner   )Úcurrent_waystones_kepté   z	Waystone u     pháº£i Ä‘Æ°á»£c KEEP khi keep=5u3   Waystone thá»© 6 pháº£i Ä‘Æ°á»£c DEPOSIT khi keep=5z	Chaos OrbzUncut Skill Gem (Tier 19)zUncut Skill GemzSpire of TormentzGothic Quarterstaff)r:   r;   r<   ÚrarityN)r   r   r   r   r)   Úevaluate_inventory_itemÚactionr   ÚKEEPÚWAYSTONEÚtarget_tab_typer   r/   ÚDEPOSITÚrangeÚOTHERr,   ÚWEAPONr   ÚRAREr0   )ÚcfgÚ	evaluatorÚscrollÚd1Ú	waystone1Úd2Úd3Úevaluator_5ÚiÚdecision_keepÚdecision_depÚchaosÚd4ÚgemÚd5ÚgearÚd6s                    r%   Ú%test_stash_evaluator_deposit_and_keepr\   A   s
  € å
¨1Ð
-Ñ
-Ô
-€CÝ cÐ*Ñ*Ô*€Iõ "Ø$Ø$ÝÔ&ðñ ô €Fð
 
×	*Ò	*¨6Ñ	2Ô	2€BØŒ9�Ô(Ò(Ð(Ð(Ð(õ %Ø&ØÝÔ&ðñ ô €Ið
 
×	*Ò	*¨9ÈQÐ	*Ñ	OÔ	O€BØŒ9�Ô(Ò(Ð(Ð(Ð(ØÔ¥Ô!7Ò7Ð7Ð7Ð7ð 
×	*Ò	*¨9ÈQÐ	*Ñ	OÔ	O€BØŒ9�Ô+Ò+Ð+Ð+Ð+ØÔ¥Ô!7Ò7Ð7Ð7Ð7õ !­ÈÐ(KÑ(KÔ(KÐLÑLÔL€KÝ�1‰XŒXð ið iˆØ#×;Ò;¸IÐ^_Ð;Ñ`Ô`ˆØÔ#¥{Ô'7Ò7Ð7Ð7Ð9hÀQÐ9hÐ9hÐ9hÑ7Ô7Ð7Ð7Ø×6Ò6°yÐYZÐ6Ñ[Ô[€LØÔ¥+Ô"5Ò5Ð5Ð5Ð7lÑ5Ô5Ð5õ !ØØÝÔ&ðñ ô €Eð
 
×	*Ò	*¨5Ñ	1Ô	1€BØŒ9�Ô+Ò+Ð+Ð+Ð+ØÔ¥Ô!6Ò6Ð6Ð6Ð6õ Ø-Ø#ÝÔ#ðñ ô €Cð
 
×	*Ò	*¨3Ñ	/Ô	/€BØŒ9�Ô+Ò+Ð+Ð+Ð+ØÔ¥Ô!2Ò2Ð2Ð2Ð2õ  Ø$Ø'ÝÔ$ÝŒð	ñ ô €Dð 
×	*Ò	*¨4Ñ	0Ô	0€BØŒ9�Ô+Ò+Ð+Ð+Ð+ØÔ¥Ô!2Ò2Ð2Ð2Ð2Ð2Ð2r'   c                  óâ   — t          d¬¦  «        } t          | ¬¦  «        }|                     d¬¦  «        du sJ ‚|                     d¬¦  «        du sJ ‚|                     d¬¦  «        du sJ ‚d	S )
uI   Kiá»ƒm tra Ä‘iá»�u kiá»‡n rÃºt Waystone bá»• sung khi tÃºi Ä‘á»“ thiáº¿u.r5   r6   r8   r   )Ú current_inventory_waystone_countTFé   N)r   r   Úshould_withdraw_waystone)rK   rL   s     r%   Útest_stash_evaluator_withdrawra   †   s“   € å
¨1Ð
-Ñ
-Ô
-€CÝ cÐ*Ñ*Ô*€Ið ×-Ò-ÈqÐ-ÑQÔQÐUYÐYÐYÐYÐYà×-Ò-ÈqÐ-ÑQÔQÐUZÐZÐZÐZÐZà×-Ò-ÈqÐ-ÑQÔQÐUZÐZÐZÐZÐZÐZÐZr'   c            
      ó6  — t          dd¬¦  «        } t          j        ddd¬¦  «        }dd	d	d
ddddœdœgdœdddddddœdœgdœdddddddœdœgdœgi}t          d|¬¦  «        5  |                      |¦  «        }t          |¦  «        dk    sJ ‚|d         j        d	k    sJ ‚|d         j        t          j	        k    sJ ‚|d         j        dk    sJ ‚|d         j        t          j
        k    sJ ‚|d         j        dk    sJ ‚|d         j        t          j        k    sJ ‚|                      t          j	        ¦  «        }|€J ‚|j        d	k    sJ ‚|                      d¦  «        }|€J ‚|j        t          j
        k    sJ ‚	 ddd¦  «         dS # 1 swxY w Y   dS )u,   Kiá»ƒm tra quÃ©t Tab Bar báº±ng Mock WinOCR.r   r   r   ÚRGB©r   r   )é   re   re   ©ÚcolorÚlinesÚCurrencyé2   re   éP   é   )ÚxÚyÚwidthÚheight)ÚtextÚbounding_rect)rq   Úwordsr+   é    éZ   ÚGemsi  é<   zwinocr.recognize_pil_sync©Úreturn_valueé   r   r5   r_   Nr=   )r   r   Únewr   Úscan_stash_tabsÚlenÚnameÚtab_typer   r)   r/   r,   Úfind_tab_by_typeÚfind_tab_by_name)r2   Úfake_imgÚmock_ocr_resultÚtabsÚcurr_tabÚway_tabs         r%   Útest_stash_ui_scanner_mock_ocrr‡   “   sc  € å d°TÐ:Ñ:Ô:€Gõ Œy˜ °LÐAÑAÔA€Hð 	à"Ø#-ÀbÈrÐ\^ÐjlÐ@mÐ@mÐnÐnÐoðð ð
 $Ø#.ÀsÐQSÐ^`ÐlnÐAoÐAoÐpÐpÐqðð ð
 Ø#)À#ÈBÐY[ÐgiÐ<jÐ<jÐkÐkÐlðð ð
ð€Oõ" 
Ð*¸Ð	IÑ	IÔ	Ið :ð :Ø×&Ò& xÑ0Ô0ˆÝ�4‰yŒy˜AŠ~ˆ~ˆ~ˆ~Ø�AŒwŒ|˜zÒ)Ð)Ð)Ð)Ø�AŒwÔ¥<Ô#8Ò8Ð8Ð8Ð8Ø�AŒwŒ|˜{Ò*Ð*Ð*Ð*Ø�AŒwÔ¥<Ô#9Ò9Ð9Ð9Ð9Ø�AŒwŒ|˜vÒ%Ð%Ð%Ð%Ø�AŒwÔ¥<Ô#4Ò4Ð4Ð4Ð4ð ×+Ò+­LÔ,AÑBÔBˆØÐ#Ð#Ð#ØŒ} 
Ò*Ð*Ð*Ð*à×*Ò*¨:Ñ6Ô6ˆØÐ"Ð"Ð"ØÔ¥<Ô#9Ò9Ð9Ð9Ð9Ð9ð#:ð :ð :ñ :ô :ð :ð :ð :ð :ð :ð :ð :øøøð :ð :ð :ð :ð :ð :s   Á%DFÆFÆFc                  óÜ  ‡	— t          j        ddd¬¦  «        Š	t          d¬¦  «        } t          dd| ˆ	fd	„¬
¦  «        }d|_        t          j        |j        dd¬¦  «        5  t          j        |dd¬¦  «        5  t          d¦  «        5 }t          d¦  «        5 }t          j        |j        d¦  «        5 }t          ddddd¬¦  «        }t          ddddd¬¦  «        }t          ddddd¬¦  «        }t          j        |j	        d|||g¬¦  «        5  | 
                    ‰	d¬¦  «        }|dk    sJ ‚|j        dk    sJ ‚	 ddd¦  «         n# 1 swxY w Y   |                     ¦   «          |j        dk    sJ ‚	 ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )uH   Kiá»ƒm tra chu trÃ¬nh Ä‘iá»�u phá»‘i StashOrchestrator vá»›i mock input.rc   rd   ©é
   rŠ   rŠ   rf   F©Úbackground_inputr   r   c                  ó   •— ‰ S ©N© ©r‚   s   €r%   ú<lambda>z4test_stash_orchestrator_mock_cycle.<locals>.<lambda>É   ó   ø€ ˜X€ r'   ©r   r   r9   Úcapture_funcr   Úis_stash_openTrx   Ú_ensure_focusz1src.assistant_tool.stash.stash_orchestrator.clickz6src.assistant_tool.stash.stash_orchestrator.ctrl_clickÚclose_stashr   r   )ÚcolÚrowÚcenter_xÚcenter_yÚis_occupiedr5   i	  r_   iO  Úscan_inventory_occupancy)Úinspect_items_liveN)r   r{   r   r   Úhwndr   ÚobjectÚ
ui_scannerr   ÚmatrixÚdeposit_inventory_itemsÚ
call_countr—   )
rK   ÚorchestratorÚ
mock_clickÚmock_ctrl_clickÚ
mock_closeÚslot0Úslot1Ú
slot_emptyÚ	depositedr‚   s
            @r%   Ú"test_stash_orchestrator_mock_cycler­   ¿   s­  ø€ õ Œy˜ °LÐAÑAÔA€Hå
 uÐ
-Ñ
-Ô
-€CÝ$ØØØØ%Ð%Ð%Ð%ð	ñ ô €Lð €LÔõ 
Œ�lÔ-¨ÈTÐ	RÑ	RÔ	Rð *ð *Ý	Œ�l OÀ$Ð	GÑ	GÔ	Gð*ð *å	ÐBÑ	CÔ	Cð*àGQÝ	ÐGÑ	HÔ	Hð*ð M\Ý	Œ�lÔ-¨}Ñ	=Ô	=ð	*ð BLõ  ¨°DÀ3ÐTXÐYÑYÔYˆÝ ¨°DÀ3ÐTXÐYÑYÔYˆÝ! a¨Q¸ÈÐY^Ð_Ñ_Ô_ˆ
åŒ\˜,Ô-Ð/IÐY^Ð`eÐgqÐXrÐsÑsÔsð 	3ð 	3à$×<Ò<¸XÐZ_Ð<Ñ`Ô`ˆIà ’>�>�>�>Ø"Ô-°Ò2Ð2Ð2Ð2Ð2ð	3ð 	3ð 	3ñ 	3ô 	3ð 	3ð 	3ð 	3ð 	3ð 	3ð 	3øøøð 	3ð 	3ð 	3ð 	3ð 	× Ò Ñ"Ô"Ð"ØÔ$¨Ò)Ð)Ð)Ð)Ð)ð)*ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *ð *ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *ð *ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *ð *ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *ð *ð *ð *ñ *ô *ð *ð *ð *ð *ð *ð *ð *øøøð *ð *ð *ð *ð *ð *sÇ   Á"G!Á:G	Â
F2ÂF	Â5AFÄ-EÄ?FÅEÅFÅEÅ$FÅ8F	ÆFÆF	ÆFÆF	ÆF2ÆFÆF2Æ"FÆ#F2Æ&G	Æ2F6Æ6G	Æ9F6Æ:G	Æ=G!Ç	G	ÇG!ÇG	ÇG!Ç!G%Ç(G%c            	      óÞ  ‡— t          j        ddd¬¦  «        Št          d¬¦  «        } t          dd| ˆfd	„¬
¦  «        }d|_        t          d¦  «        5 }t          d¦  «        5 }|                     dd¦  «         |                     ddddd¬¦  «         |                     ¦   «          | 	                    ¦   «          ddd¦  «         n# 1 swxY w Y   ddd¦  «         dS # 1 swxY w Y   dS )uP   Kiá»ƒm tra cháº¿ Ä‘á»™ tÆ°Æ¡ng tÃ¡c ngáº§m PostMessageW trong StashOrchestrator.rc   rd   r‰   rf   Tr‹   r   r   c                  ó   •— ‰ S rŽ   r�   r�   s   €r%   r‘   z:test_stash_orchestrator_background_input.<locals>.<lambda>í   r’   r'   r“   iE# zCsrc.assistant_tool.stash.stash_orchestrator.post_message_ctrl_clickz<src.assistant_tool.stash.stash_orchestrator.post_message_keyéd   éÈ   g{®Gáz¤?gš™™™™™¹?)Úhold_msÚdelay_afterN)
r   r{   r   r   rŸ   r   Ú_ctrl_clickÚassert_called_once_withr—   Úassert_called_once)rK   r¥   Úmock_pm_ctrlÚmock_pm_keyr‚   s       @r%   Ú(test_stash_orchestrator_background_inputr¹   å   s‰  ø€ åŒy˜ °LÐAÑAÔA€HÝ
 tÐ
,Ñ
,Ô
,€CÝ$ØØØØ%Ð%Ð%Ð%ð	ñ ô €Lð  €LÔå	ÐTÑ	UÔ	Uð )ÐYeÝ	ÐMÑ	NÔ	Nð)ØR]Ø× Ò   cÑ*Ô*Ð*Ø×,Ò,¨W°c¸3ÈÐZ]Ð,Ñ^Ô^Ð^à× Ò Ñ"Ô"Ð"Ø×&Ò&Ñ(Ô(Ð(ð)ð )ð )ñ )ô )ð )ð )ð )ð )ð )ð )øøøð )ð )ð )ð )ð )ð )ð )ñ )ô )ð )ð )ð )ð )ð )ð )ð )øøøð )ð )ð )ð )ð )ð )s7   ÁC"Á%AC
Â>C"Ã
C	ÃC"ÃC	ÃC"Ã"C&Ã)C&c                  óò  — t          dd¬¦  «        } |                      dd¦  «        }d|d         cxk    rdk    sn J ‚d|d         cxk    rd	k    sn J ‚t          j        d
dd¬¦  «        }t	          dd¬¦  «        5  |                      |¦  «        }|du sJ ‚|                      dd¦  «        }d|d         cxk    rdk    sn J ‚d|d         cxk    rd	k    sn J ‚	 ddd¦  «         dS # 1 swxY w Y   dS )uj   Kiá»ƒm tra tÃ­nh toÃ¡n tá»�a Ä‘á»™ lÆ°á»›i trong cháº¿ Ä‘á»™ Windowed (4:3) vÃ  hiá»‡u chuáº©n tá»« áº£nh.é¥  é{  r   r   iŠ  i¨  i  r5   i&  rc   )r»   r¼   r‰   rf   z)src.common.vision_ocr.find_button_by_text)i’  é:   rx   Ti£  N)r   r   r   r{   r   Úcalibrate_from_image)Ú
matrix_winÚslot_0_0r‚   Ú
calibratedÚcal_0_0s        r%   Ú0test_windowed_aspect_ratio_and_image_calibrationrÃ   ú   s›  € õ !¨$¸Ð=Ñ=Ô=€JØ×3Ò3°A°qÑ9Ô9€Hà�(˜1”+Ð$Ð$Ò$Ð$ Ò$Ð$Ð$Ð$Ð$Ð$Ø�(˜1”+Ð$Ð$Ò$Ð$ Ò$Ð$Ð$Ð$Ð$Ð$õ Œy˜ °<Ð@Ñ@Ô@€HÝ	Ð:ÈÐ	SÑ	SÔ	Sð (ð (Ø×4Ò4°XÑ>Ô>ˆ
Ø˜TÐ!Ð!Ð!Ð!Ø×6Ò6°q¸!Ñ<Ô<ˆØ�g˜a”jÐ'Ð'Ò'Ð' CÒ'Ð'Ð'Ð'Ð'Ð'Ø�g˜a”jÐ'Ð'Ò'Ð' CÒ'Ð'Ð'Ð'Ð'Ð'Ð'ð(ð (ð (ñ (ô (ð (ð (ð (ð (ð (ð (ð (øøøð (ð (ð (ð (ð (ð (s   Á>A C,Ã,C0Ã3C0)"Ú__doc__Úunittest.mockr   r   ÚpytestÚPILr   Ú(src.assistant_tool.stash.stash_constantsr   r   r   r	   Ú)src.assistant_tool.stash.stash_ui_scannerr
   r   Ú*src.assistant_tool.stash.stash_item_matrixr   r   Ú(src.assistant_tool.stash.stash_evaluatorr   Ú+src.assistant_tool.stash.stash_orchestratorr   Ú!src.assistant_tool.item_inspectorr   r   r   r&   r3   r\   ra   r‡   r­   r¹   rÃ   r�   r'   r%   ú<module>rÎ      s—  ððð ð +Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ø €€€Ø Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð SÐ RÐ RÐ RÐ RÐ RÐ RÐ RØ TÐ TÐ TÐ TÐ TÐ TÐ TÐ TØ CÐ CÐ CÐ CÐ CÐ CØ IÐ IÐ IÐ IÐ IÐ Iðð ð ð ð ð ð ð ð ð ð(ð (ð (ð&Lð Lð LðB3ð B3ð B3ðJ
[ð 
[ð 
[ð):ð ):ð ):ðX#*ð #*ð #*ðL)ð )ð )ð*(ð (ð (ð (ð (r'   