§
    ¤OÇjˆ  ã                   ó€  — d 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 ddlmZmZ  ee¦  «                             ¦   «         j        j        Zedz  Z ee¦  «        ej        vr$ej                             d ee¦  «        ¦  «         ddlZ G d„ de
j        ¦  «        Zedk    r e
j        ¦   «          dS dS )	zâ
Adversarial Stress Test Suite for 05_Production_Pipeline/run_shot.py CLI and Engine.
Empirically verifies CLI argument parsing, aliasing (--shot vs --shot-id),
default fallbacks, prompt resolution, and audio guard injection.
é    N)ÚPath)ÚpatchÚ	MagicMockÚ05_Production_Pipelinec                   óB   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
S )ÚTestAdversarialCliRunShotzFStress testing run_shot.py CLI arguments, aliases, and pipeline logic.c                 óš  — t          j        t          j        t	          t
          dz  ¦  «        dgddd¬¦  «        }|                      |j        d¦  «         |j        }|  	                    d|¦  «         |  	                    d|¦  «         |  	                    d	|¦  «         |  	                    d
|¦  «         |  	                    d|¦  «         dS )z@CLI --help must return 0 and document both --shot and --shot-id.úrun_shot.pyz--helpTúutf-8©Úcapture_outputÚtextÚencodingr   ú--shotú	--shot-idú--input-frameú--promptú	--sessionN)
Ú
subprocessÚrunÚsysÚ
executableÚstrÚPIPELINE_DIRÚassertEqualÚ
returncodeÚstdoutÚassertIn)ÚselfÚprocr   s      ú<C:\Projects\KieuStory\tests\test_adversarial_cli_run_shot.pyÚ(test_help_flag_displays_shot_and_shot_idzBTestAdversarialCliRunShot.test_help_flag_displays_shot_and_shot_id   sÅ   € åŒ~ÝŒ^�S¥°Ñ!=Ñ>Ô>ÀÐIØØØð	
ñ 
ô 
ˆð 	×Ò˜œ¨!Ñ,Ô,Ð,Ø”ˆØ�Š�h Ñ'Ô'Ð'Ø�Š�k 6Ñ*Ô*Ð*Ø�Š�o vÑ.Ô.Ð.Ø�Š�j &Ñ)Ô)Ð)Ø�Š�k 6Ñ*Ô*Ð*Ð*Ð*ó    c                 ó  — t          j        t          j        t	          t
          dz  ¦  «        gddd¬¦  «        }|                      |j        d¦  «         |j        |j	        z   }|  
                    d|v pd|v ¦  «         dS )	zMCLI invocation without --shot or --shot-id must fail with non-zero exit code.r
   Tr   r   r   zerror:ÚrequiredN)r   r   r   r   r   r   ÚassertNotEqualr   r   ÚstderrÚ
assertTrue)r   r    Úcombineds      r!   Ú test_missing_required_args_failsz:TestAdversarialCliRunShot.test_missing_required_args_fails+   s‡   € åŒ~ÝŒ^�S¥°Ñ!=Ñ>Ô>Ð?ØØØð	
ñ 
ô 
ˆð 	×Ò˜DœO¨QÑ/Ô/Ð/Ø”; ¤Ñ,ˆØ�Š˜ HÐ,ÐF°
¸hÐ0FÑGÔGÐGÐGÐGr#   c                 ó´   — t          j        t          j        t	          t
          dz  ¦  «        dddgddd¬¦  «        }|                      |j        d¦  «         d	S )
zCCLI invocation with unknown flag must fail with non-zero exit code.r
   r   Úep01_scene01_shot01z--unsupported-flagTr   r   r   N)r   r   r   r   r   r   r&   r   )r   r    s     r!   Útest_unknown_flag_failsz1TestAdversarialCliRunShot.test_unknown_flag_fails7   s`   € åŒ~ÝŒ^�S¥°Ñ!=Ñ>Ô>ÀÐJ_ÐauÐvØØØð	
ñ 
ô 
ˆð 	×Ò˜DœO¨QÑ/Ô/Ð/Ð/Ð/r#   c                 óR  — ddl }|                     ¦   «         }|                     dddd¬¦  «         |                     dd¬	¦  «         |                     d
d¬	¦  «         |                     dd¬	¦  «         |                     dd¬	¦  «         |                     dd¬	¦  «         |                     ddg¦  «        }|                      |j        d¦  «         |                      |j        ¦  «         |                      |j        ¦  «         |                      |j	        d¦  «         |                     ddg¦  «        }|                      |j        d¦  «         |                      |j        ¦  «         |                      |j        ¦  «         |                      |j	        d¦  «         dS )zEParser must parse --shot and --shot-id identically into args.shot_id.r   Nr   r   Úshot_idT)Údestr%   r   )Údefaultr   z--prev-videor   Úmusez--download-dirr,   )
ÚargparseÚArgumentParserÚadd_argumentÚ
parse_argsr   r/   ÚassertIsNoneÚinput_frameÚpromptÚsession)r   r3   ÚparserÚargs1Úargs2s        r!   Útest_shot_argument_alias_parityz9TestAdversarialCliRunShot.test_shot_argument_alias_parityA   s«  € àˆˆˆØ×(Ò(Ñ*Ô*ˆØ×Ò˜H k¸	ÈDÐÑQÔQÐQØ×Ò˜O°TÐÑ:Ô:Ð:Ø×Ò˜J°ÐÑ5Ô5Ð5Ø×Ò˜N°DÐÑ9Ô9Ð9Ø×Ò˜K°ÐÑ8Ô8Ð8Ø×ÒÐ,°dÐÑ;Ô;Ð;à×!Ò! 8Ð-BÐ"CÑDÔDˆØ×Ò˜œÐ(=Ñ>Ô>Ð>Ø×Ò˜%Ô+Ñ,Ô,Ð,Ø×Ò˜%œ,Ñ'Ô'Ð'Ø×Ò˜œ¨Ñ/Ô/Ð/à×!Ò! ;Ð0EÐ"FÑGÔGˆØ×Ò˜œÐ(=Ñ>Ô>Ð>Ø×Ò˜%Ô+Ñ,Ô,Ð,Ø×Ò˜%œ,Ñ'Ô'Ð'Ø×Ò˜œ¨Ñ/Ô/Ð/Ð/Ð/r#   c                 óü   — ddl m}  |¦   «         }|                      d|¦  «         |d         }|                     d¦  «        }|                      |¦  «         |                      t          |¦  «        d¦  «         dS )zPrun_shot_pipeline must resolve motion prompt for known shot ep01_scene01_shot01.r   )Úget_all_shotsr,   Úmotion_prompté
   N)Úproduction_orchestratorr@   r   ÚgetÚassertIsNotNoneÚassertGreaterÚlen)r   r@   ÚshotsÚ	shot_datarA   s        r!   Ú*test_auto_prompt_resolution_for_known_shotzDTestAdversarialCliRunShot.test_auto_prompt_resolution_for_known_shotX   sŠ   € ð 	:Ð9Ð9Ð9Ð9Ð9Ø�‘”ˆØ�ŠÐ+¨UÑ3Ô3Ð3ØÐ/Ô0ˆ	Ø!Ÿš oÑ6Ô6ˆØ×Ò˜]Ñ+Ô+Ð+Ø×Ò�3˜}Ñ-Ô-¨rÑ2Ô2Ð2Ð2Ð2r#   c                 óÌ   — d}d}|}d|vrd|vr|                      ¦   «         |z   }|                      d|¦  «         |                      |                     |¦  «        ¦  «         dS )z4Audio guard must be appended if missing from prompt.z%Slow cinematic pan over spring gardenõè    Ã‚m thanh: Chá»‰ sinh Ã¢m thanh mÃ´i trÆ°á»�ng tá»± nhiÃªn (foley, ambience) vÃ  thoáº¡i nhÃ¢n váº­t chÃ¢n thá»±c. Tuyá»‡t Ä‘á»‘i KHÃ”NG sinh nháº¡c ná»�n (no music/BGM), khÃ´ng Ã¢m thanh Ä‘iá»‡n tá»­, khÃ´ng táº¡p Ã¢m rÃ¨ nhiá»…u.õ'   Tuyá»‡t Ä‘á»‘i KHÃ”NG sinh nháº¡c ná»�núStrictly NO background musicN)Úrstripr   r(   Ú
startswith)r   Útest_promptÚaudio_guardÚps       r!   Ú'test_audio_guard_injection_when_missingzATestAdversarialCliRunShot.test_audio_guard_injection_when_missingc   sx   € à=ˆð Aˆð ˆØ4¸AÐ=Ð=ÐB`ÐhiÐBiÐBiØ—’‘
”
˜[Ñ(ˆAà�ŠÐ?ÀÑCÔCÐCØ�Š˜Ÿš [Ñ1Ô1Ñ2Ô2Ð2Ð2Ð2r#   c                 ó¨   — d}d|z   }|}d|vrd|vr|                      ¦   «         |z   }|                      |                     d¦  «        d¦  «         dS )z6Audio guard must not be duplicated if already present.rL   z	Pan shot.rM   rN   é   N)rO   r   Úcount)r   rR   rQ   rS   s       r!   Útest_audio_guard_not_duplicatedz9TestAdversarialCliRunShot.test_audio_guard_not_duplicatedp   sk   € ð AˆØ! KÑ/ˆàˆØ4¸AÐ=Ð=ÐB`ÐhiÐBiÐBiØ—’‘
”
˜[Ñ(ˆAà×Ò˜ŸšÐ!JÑKÔKÈQÑOÔOÐOÐOÐOr#   c                 óŠ   — t          j        d¬¦  «        \  }}|                      |¦  «         |                      |¦  «         dS )zIrun_shot_pipeline returns (False, None) when shot prompt cannot be found.Úshot_does_not_exist_9999)r/   N)Úrun_shotÚrun_shot_pipelineÚassertFalser7   )r   ÚsuccessÚress      r!   Ú(test_nonexistent_shot_graceful_rejectionzBTestAdversarialCliRunShot.test_nonexistent_shot_graceful_rejection{   sH   € åÔ1Ð:TÐUÑUÔU‰ˆ�Ø×Ò˜Ñ!Ô!Ð!Ø×Ò˜#ÑÔÐÐÐr#   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   r*   r-   r>   rJ   rT   rX   r`   © r#   r!   r   r      s˜   € € € € € ØPÐPð+ð +ð +ð 
Hð 
Hð 
Hð0ð 0ð 0ð0ð 0ð 0ð.	3ð 	3ð 	3ð3ð 3ð 3ð	Pð 	Pð 	Pðð ð ð ð r#   r   Ú__main__)rd   ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arÚosr   r   ÚunittestÚpathlibr   Úunittest.mockr   r   Ú__file__ÚresolveÚparentÚBASE_DIRr   r   ÚpathÚinsertr[   ÚTestCaser   ra   Úmainre   r#   r!   ú<module>ry      sB  ððð ð € € € € € € € € € € € € €	€	€	€	Ø 
€
€
€
Ø Ð Ð Ð Ø €€€Ø Ð Ð Ð Ð Ð Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *àˆ4�‰>Œ>×!Ò!Ñ#Ô#Ô*Ô1€ØÐ2Ñ2€Ø€3€|ÑÔ˜CœHÐ$Ð$Ø„H‡O‚O�A�s�s˜<Ñ(Ô(Ñ)Ô)Ð)à €€€ðgð gð gð gð g Ô 1ñ gô gð gðT ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr#   