status===$status,'Expected HTTP '.$status.', got '.$e->status);return;}throw new \RuntimeException('Expected rejection '.$status);} $dir=sys_get_temp_dir().'/caterium-support-test-'.bin2hex(random_bytes(6));mkdir($dir,0700); $input=['name'=>'Тест','email'=>'learner@example.invalid','topic'=>'question','subject'=>'Вопрос по меню','message'=>'Как создать новое предложение?','request_id'=>'10000000-0000-4000-8000-000000000001','website'=>'']; try{ $row=validate($input);check($row['name']==='Тест','Unicode preserved'); foreach([ ['email'=>"test@example.com\r\nBcc: stranger@example.com"],['topic'=>'unknown'],['message'=>''],['subject'=>"New\nheader"],['name'=>['invalid']],['message'=>str_repeat('x',16001)],['website'=>'bot-filled'],['to'=>'someone@example.com'],['csrf'=>['invalid']] ] as $bad){if(isset($bad['csrf']))continue;denies(static function()use($input,$bad){validate(array_merge($input,$bad));},422);} $count=0;$send=static function($row,$id)use(&$count){$count++;return deliver($row,$id);}; $answer=submit($row,'127.0.0.1',$dir,$send,1000000);check($answer['status']==='accepted','Mail accepted'); $repeat=submit($row,'127.0.0.2',$dir,$send,1000001);check($repeat===$answer&&$count===1,'Retries must not send duplicates'); $changed=$row;$changed['message']='Changed';denies(static function()use($changed,$dir,$send){submit($changed,'127.0.0.1',$dir,$send,1000002);},409); [$to,$subject,$body,$headers,$params]=$GLOBALS['capturedMail'];check($to==='support@caterium.ru','Recipient exactly matches user request');check($headers['Reply-To']===$input['email'],'Reply to sender');check($params==='-fno-reply@caterium.ru','Fixed envelope'); check(strpos(base64_decode($body),$input['message'])!==false,'UTF-8 message is intact');check(strpos($subject,'SUP-')!==false,'Request ID in subject'); $saved=file_get_contents($dir.'/limits.json');check(strpos($saved,$input['email'])===false&&strpos($saved,$input['message'])===false,'Do not store message/email in rate-limit file'); for($i=2;$i<=3;$i++){$next=$row;$next['request_id']=sprintf('10000000-0000-4000-8000-%012d',$i);submit($next,'127.0.0.1',$dir,$send,1000000+$i);} $next['request_id']='10000000-0000-4000-8000-000000000004';denies(static function()use($next,$dir,$send){submit($next,'127.0.0.3',$dir,$send,1000010);},429); $failure=$row;$failure['email']='other@example.invalid';$failure['request_id']='20000000-0000-4000-8000-000000000001'; denies(static function()use($failure,$dir){submit($failure,'127.0.0.4',$dir,static function(){return false;},1000020);},503); $uncertain=$row;$uncertain['email']='uncertain@example.invalid';$uncertain['request_id']='30000000-0000-4000-8000-000000000001'; try{submit($uncertain,'127.0.0.5',$dir,static function(){throw new \RuntimeException('transport stopped');},1000030);}catch(\RuntimeException $e){} denies(static function()use($uncertain,$dir,$send){submit($uncertain,'127.0.0.5',$dir,$send,1000031);},409); echo "PASS support mail: fixed recipient, reply address, validation, Unicode, idempotency, rate limits, rejection and uncertain-state protection; no real email sent.\n"; }finally{foreach(glob($dir.'/*') as $path)unlink($path);rmdir($dir);}