o
    pjN0                     @  s   d Z ddlmZ ddlZddlZddlmZ ddlmZ ee	
 jd Zejdee ejdZedurAeedsAejd= dd	lmZmZmZmZmZ dd
lmZmZ ddlmZ ddlm Z  G dd dej!Z"e#dkrxej$dd dS dS )z+Standalone Platform App Standard v1 checks.    )annotationsN)Path)patch   platform__path__)ActionContractAgentCapabilityContractAppManifestCredentialFieldWordPressPackageContract)error_envelopesuccess_envelope)resolve_capability)manifest_toolsc                   @  sx   e Zd Zedd Zdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdS )AppContractChecksc                   C  s   t ddddgddS )Nplatform.healthzReport local health.objecthealthytyperequired
capabilitydescriptionoutput_schema)r    r   r   %tests/platform/app_contract_checks.py_health_action   s
   
z AppContractChecks._health_actionc                 C  s^   t ddddtddftddd	d
gddtdddd	ddgdddd}| g |  d S )N
caller_appCaller1.0.0zTest caller application.	api_tokenz	API tokenr   Healthr   r   r   r   zplatform.credentials.testzConnection test)r"   	connectedproviderr   r   required_credentialsr   )	health_v1test_connection_v1)app_iddisplay_nameapp_versionr   credentialsactions)r
   r   r   assertEqualvalidateselfmanifestr   r   r   ,test_valid_manifest_and_credential_reference%   s    

z>AppContractChecks.test_valid_manifest_and_credential_referencec                 C  s^   t ddddtddddd	gd
dtddddgd
ddd}| tdd | D  d S )Nbad_appBadr!   z"Invalid credential reference test.records.lookupLookup)missingr   recordr   r&   r   r#   r   r   )	lookup_v1r(   r*   r+   r,   r   r.   c                 s      | ]}d |v V  qdS )zunknown credentialsNr   .0errorr   r   r   	<genexpr>B       zHAppContractChecks.test_unknown_credential_is_rejected.<locals>.<genexpr>)r
   r   
assertTrueanyr0   r1   r   r   r   #test_unknown_credential_is_rejected5   s   

 z5AppContractChecks.test_unknown_credential_is_rejectedc                 C  sN  t ddddddtddd	d
gddid}t ddddtddd	d
gddtddd	dgdddd}td||gd | dtddd W d    n1 sPw   Y  t dddddtddd	d
gddid}td||gd, | t tddd W d    n1 sw   Y  W d    d S W d    d S 1 sw   Y  d S )Nr   r    r!   zCapability caller test.)ztarget_app:records.lookupr(   r   r#   r   r   r   r   )r*   r+   r,   r   outbound_capabilitiesr.   
target_appTargetzCapability target test.r7   r8   r:   r(   r;   r<   z$platform.apps.registry.load_manifest)side_effectr;   zDenied capability caller test.)r
   r   r   r/   r   assertRaisesPermissionError)r2   callertargetdeniedr   r   r   5test_capability_requires_explicit_outbound_permissionD   sV   
	



"zGAppContractChecks.test_capability_requires_explicit_outbound_permissionc                 C  sV   t dddddid}tdddddd	}| |d
  | |d  | d|d  d S )Napp_alookupz	request-1id   )r*   action
request_iddatarecord_not_foundzRecord not found)r*   rU   rV   codemessager@   rW   z1.0contract_version)r   r   assertIsNoner/   )r2   successfailurer   r   r   'test_envelopes_never_mix_data_and_errorm   s   z9AppContractChecks.test_envelopes_never_mix_data_and_errorc                 C  sZ   t dddddtdddd	gd
ditdddddddd}| tdd | D  d S )Npack_appPackr!   z Invalid package capability test.r(   r   r#   r   r   r   r   pack_app_wpwordpress-pack/packpack.phppack/pack.php)r7   
package_idversionsource_directory
entrypointplugin_filecapabilitiesr*   r+   r,   r   r.   wordpress_packagec                 s  r=   )zunknown capabilitiesNr   r>   r   r   r   rA      rB   zYAppContractChecks.test_wordpress_pack_cannot_use_undeclared_capability.<locals>.<genexpr>r
   r   r   rC   rD   r0   r1   r   r   r   4test_wordpress_pack_cannot_use_undeclared_capabilityy   s   
 zFAppContractChecks.test_wordpress_pack_cannot_use_undeclared_capabilityc                 C  s\   t dddddtdddd	gd
ditddddddddd}| tdd | D  d S )Nr`   ra   r!   zPartial package metadata test.r(   r   r#   r   r   r   r   rb   rc   rd   re   r   zpack.zip)rg   rh   ri   rj   rk   rl   artifact_namerm   c                 s  r=   )zrelease metadataNr   r>   r   r   r   rA      rB   zNAppContractChecks.test_partial_release_metadata_is_rejected.<locals>.<genexpr>ro   r1   r   r   r   )test_partial_release_metadata_is_rejected   s   
 z;AppContractChecks.test_partial_release_metadata_is_rejectedc                 C  sV   t ddddd|  id}| }| tdd |D  | td	d |D  d S )
Nr5   zBad versiononezInvalid versioning test.healthr<   c                 s  r=   )zsemantic versioningNr   r>   r   r   r   rA      rB   zSAppContractChecks.test_semver_and_versioned_actions_are_required.<locals>.<genexpr>c                 s  r=   )zcontract suffixNr   r>   r   r   r   rA      rB   )r
   r   r0   rC   rD   r2   r3   errorsr   r   r   .test_semver_and_versioned_actions_are_required   s   
z@AppContractChecks.test_semver_and_versioned_actions_are_requiredc                 C  sh   t dddd|  tddddid	d
dd}| }| tdd |D  | tdd |D  d S )Nr5   z
Bad schemar!   zInvalid schema and error test.r7   r8   r   array)zBad-Code)r   r   r   rw   rI   r<   c                 s  r=   )r   Nr   r>   r   r   r   rA      rB   zUAppContractChecks.test_output_schema_and_error_codes_are_validated.<locals>.<genexpr>c                 s  r=   )zinvalid error codeNr   r>   r   r   r   rA      rB   )r
   r   r   r0   rC   rD   rv   r   r   r   0test_output_schema_and_error_codes_are_validated   s"   zBAppContractChecks.test_output_schema_and_error_codes_are_validatedc                 C  sR   t dddd|  tddddgd	d
dddd}| tdd | D  d S )Nr5   zBad side effectr!   zInvalid idempotency test.zrecords.createCreater   	record_idr   TF)r   r   r   side_effects
idempotent)r(   	create_v1r<   c                 s  r=   )zidempotency keyNr   r>   r   r   r   rA      rB   zQAppContractChecks.test_non_idempotent_side_effect_requires_key.<locals>.<genexpr>)r
   r   r   rC   rD   r0   r1   r   r   r   ,test_non_idempotent_side_effect_requires_key   s$   
z>AppContractChecks.test_non_idempotent_side_effect_requires_keyc                 C  sL   t ddddd|  itddddd	d
dd}| tdd | D  d S )Nr`   ra   r!   z'Invalid WordPress plugin identity test.r(   rb   rc   rd   zanother/pack.phprq   rf   rm   c                 s  r=   )rk   Nr   r>   r   r   r   rA      rB   zWAppContractChecks.test_wordpress_plugin_file_must_match_package_root.<locals>.<genexpr>)r
   r   r   rC   rD   r0   r1   r   r   r   2test_wordpress_plugin_file_must_match_package_root   s$   
zDAppContractChecks.test_wordpress_plugin_file_must_match_package_rootc                 C  s   t dddd|  tddddgd	dd
gd	tddddddddd}| g |  t|}t|dd}| d|d d  | d|d  | dg|d d d  | |d d d  d S )N	agent_appAgentr!   zAgent contract test.r7   zLookup a record.r   r|   r   r:   TzLook up a recordz(Retrieve one record by exact identifier.)z(An exact record identifier is available.)zrecords.read)exposedtitlesummaryuse_whenrequired_permissions)r   r   input_schemar   agentrI   r<   F)compactr   r   r   r   	executionr}   )	r
   r   r   r	   r/   r0   r   assertNotInassertFalse)r2   r3   r   fullr   r   r   9test_agent_read_tool_generates_compact_and_full_contracts   s0   

zKAppContractChecks.test_agent_read_tool_generates_compact_and_full_contractsc                 C  s~   t dddd|  tddddgd	td
dddddddddd}| }| tdd |D  | tdd |D  d S )Nr   r   r!   zUnsafe agent contract test.zrecords.deletezDelete a record.r   deletedr   TzDelete a recordzPermanently delete one record.)z0The user explicitly requests permanent deletion.write_irreversiblehighnever)r   r   r   r   risk_category
risk_levelconfirmation)r   r   r   r   )r(   	delete_v1r<   c                 s  r=   )zmust declare side_effectsNr   r>   r   r   r   rA     rB   z[AppContractChecks.test_agent_write_requires_side_effect_and_confirmation.<locals>.<genexpr>c                 s  r=   )zalways require confirmationNr   r>   r   r   r   rA     rB   )r
   r   r   r	   r0   rC   rD   rv   r   r   r   6test_agent_write_requires_side_effect_and_confirmation   s(   
zHAppContractChecks.test_agent_write_requires_side_effect_and_confirmationN)__name__
__module____qualname__staticmethodr   r4   rE   rP   r_   rp   rs   rx   rz   r   r   r   r   r   r   r   r   r      s    
)r   __main__)	verbosity)%__doc__
__future__r   sysunittestpathlibr   unittest.mockr   __file__resolveparentsPROJECT_ROOTpathinsertstrmodulesgetloaded_platformhasattrbridge_platform.apps.contractsr   r	   r
   r   r   bridge_platform.apps.envelopesr   r   bridge_platform.apps.registryr   #bridge_platform.agents.tool_catalogr   TestCaser   r   mainr   r   r   r   <module>   s(     y