Files
zyt/server/tests/TcmAttachmentAvailabilityRoleTest.php
T
2026-10-27 14:03:35 +08:00

77 lines
4.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
require dirname(__DIR__) . '/vendor/autoload.php';
require __DIR__ . '/fixtures/CompleteTcmCase.php';
use app\adminapi\logic\tcm\PatientAiReportLogic;
use app\adminapi\service\AiRequiredSource;
use app\adminapi\service\TcmClinicalFactStateGuard as Guard;
use app\adminapi\service\TcmClinicalReportStream;
$snapshot = (new ReflectionMethod(PatientAiReportLogic::class, 'buildSourceSnapshotFromRows'))
->invoke(null, CompleteTcmCase::rows());
$submission = (new ReflectionMethod(PatientAiReportLogic::class, 'sanitizeSnapshotForUpstream'))
->invoke(null, AiRequiredSource::submission($snapshot));
$ledger = Guard::build(CompleteTcmCase::current(), $submission);
$checks = 0;
$expect = static function (bool $condition, string $message) use (&$checks): void {
++$checks;
if (!$condition) throw new RuntimeException($message);
};
$tongueSource = array_values(array_filter($ledger['sources'], static fn (array $row): bool => $row['field'] === 'tongue'))[0];
$original = '舌象:2026-10-23“' . $tongueSource['quote'] . '”(' . $tongueSource['id']
. ')。本次无舌照附件,以文字记录为限。' . "\n\n";
$expect(Guard::validate($ledger, $original)['valid'], 'The original retained tongue paragraph has no clinical state conflict.');
foreach ([1, 2, 7, 31] as $size) {
$visible = '';
$stream = new TcmClinicalReportStream($ledger, static function (string $delta) use (&$visible): bool {
$visible .= $delta;
return true;
});
foreach (str_split($original, $size) as $chunk) $stream->push($chunk);
$expect($stream->finish() && $visible === $original, 'The original paragraph preserves every accepted source/metadata byte.');
}
foreach (['本次', '此次', '当前', '目前'] as $scope) {
foreach (['无舌照附件', '未提供图片附件'] as $missing) {
$metadata = $scope . $missing . ',以文字记录为限。';
$expect(Guard::validate($ledger, $metadata)['valid'], 'Missing material is metadata, not an absent tongue examination.');
foreach ([1, 2, 7, 31] as $size) {
$visible = '';
$wire = $metadata . "\r\n\r\n";
$stream = new TcmClinicalReportStream($ledger, static function (string $delta) use (&$visible): bool {
$visible .= $delta;
return true;
});
foreach (str_split($wire, $size) as $chunk) $stream->push($chunk);
$expect($stream->finish() && $visible === $wire, 'Metadata forwards exact original UTF-8/CRLF bytes.');
}
foreach (['患者有固定刺痛。', '患者无固定刺痛。', '口干未记录。', '舌象未记录。', '舌红绛。', '脉滑。'] as $actual) {
foreach ([',', '且'] as $join) {
$text = $scope . $missing . $join . $actual;
$expect(!Guard::validate($ledger, $text)['valid'], 'A material prefix cannot exempt an adjacent patient assertion.');
$visible = '';
$stream = new TcmClinicalReportStream($ledger, static function (string $delta) use (&$visible): bool {
$visible .= $delta;
return true;
});
foreach (str_split($text . "\n\n", 7) as $chunk) $stream->push($chunk);
$expect(!$stream->finish() && $visible === '', 'Unsupported findings remain withheld before delivery.');
}
}
}
}
$expect(!Guard::validate($ledger, '本次无舌照附件(s999999),以文字记录为限。')['valid'],
'The metadata role cannot waive an invalid source annotation.');
$expect(!Guard::validate($ledger, '本次无舌象。')['valid'], 'Missing tongue examination is not missing tongue image.');
foreach (['舌象', '脉象'] as $exam) {
foreach (['本次', '此次', '当前', '目前'] as $scope) {
foreach (['无', '没有', '未提供'] as $absence) {
$result = Guard::validate($ledger, $scope . $absence . $exam . '。');
$expect(!$result['valid'] && in_array('RECORDED_TO_UNKNOWN', array_column($result['issues'], 'code'), true),
'An existing named tongue/pulse examination cannot be erased by a bare missing-result claim.');
}
}
}
echo "TCM scoped attachment availability: {$checks} assertions passed (offline).\n";