Files
zyt/server/tests/FollowupAudioManualReviewTest.php
T

17 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
require dirname(__DIR__).'/vendor/autoload.php';require dirname(__DIR__).'/vendor/topthink/framework/src/helper.php';
use app\common\service\followupaudio\FollowupAudioGate as G;use app\common\service\followupaudio\FollowupAudioProviderConfig as P;use app\common\service\followupaudio\FollowupAudioStore as S;
new think\App();$config=new think\Config();think\Container::getInstance()->instance('config',$config);
$n=0;$ok=static function(bool$b,string$m)use(&$n){if(!$b)throw new RuntimeException($m);$n++;};
$slot=['driver'=>'asr_then_llm','label'=>'Synthetic','asr'=>['protocol'=>'dify','binding_revision'=>'fixture','base_url'=>'https://asr.invalid/v1','api_key'=>'synthetic','model'=>'synthetic-asr'],'extraction'=>['base_url'=>'https://text.invalid/v1','api_key'=>'synthetic','model'=>'synthetic-text']];
$s=['enabled'=>true,'preview_only'=>false,'manual_review_enabled'=>true,'audio_verified'=>false,'verified_profiles'=>[],'providers'=>['openai'=>$slot],'profile'=>'openai','test_diagnosis_ids'=>'1'];$p=P::resolve('openai',$s,[]);$s['providers']['openai']['preview_verified_fingerprint']=$p['fingerprint'];$config->set($s,'followup_audio');
$ok(G::ready('openai'),'explicit manual business readiness supported');$ok(!S::verified(),'not an accuracy certification');$ok(G::manualReviewReady()&&G::manualReviewReady('openai'),'any and selected readiness');$ok(G::scopeAllowed(1131,1)&&G::scopeAllowed(12335,1),'no preview whitelist in business mode');$ok(array_column(P::readyModels(),'value')===['openai'],'only actual ready model advertised');
foreach([false,'true',null]as$flag){$x=$s;$x['manual_review_enabled']=$flag;$ok(!G::ready('openai',$x,[]),'explicit boolean operator grant required');}
foreach(['','different-binding']as$fp){$x=$s;$x['providers']['openai']['preview_verified_fingerprint']=$fp;$ok(!G::ready('openai',$x,[]),'binding readiness required');}
$x=$s;$x['providers']['openai']['extraction']['model']='changed-model';$ok(!G::ready('openai',$x,[]),'model drift invalidates manual readiness');$ok(!G::manualReviewReady('qwen',$s,[]),'one profile does not grant another');
$x=$s;$x['preview_only']=true;$config->set($x,'followup_audio');$ok(!G::manualReviewReady(),'preview dominates manual grant');$ok(!G::scopeAllowed(1131,1),'preview keeps its scoped list');try{G::assertMayApply();throw new RuntimeException('expected deny');}catch(DomainException$e){$ok($e->getMessage()==='FOLLOWUP_AUDIO_PREVIEW_ONLY','preview hard denial');}
$config->set($s,'followup_audio');G::assertMayApply(['upstream_ids_json'=>'{}']);$ok(true,'new business task may reach human Apply');try{G::assertMayApply(['upstream_ids_json'=>'{"preview_only":true}']);throw new RuntimeException('expected origin deny');}catch(DomainException$e){$ok($e->getMessage()==='FOLLOWUP_AUDIO_PREVIEW_ONLY','old synthetic preview remains nonadoptable');}
$x=$s;$x['manual_review_enabled']=false;$config->set($x,'followup_audio');try{S::assertEnabled('openai');throw new RuntimeException('expected revoke');}catch(DomainException$e){$ok($e->getMessage()==='FOLLOWUP_AUDIO_DISABLED_OR_UNVERIFIED','manual grant revocation stops writes and processing');}
echo 'FOLLOWUP_AUDIO_MANUAL_REVIEW assertions='.$n.' PASS all_authorized_diagnoses=1 explicit_human_apply=1 accuracy_flag_unchanged=1 binding_required=1 preview_origin_retained=1'.PHP_EOL;