first commit
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
use app\common\service\DifyChatService;
|
||||
|
||||
function expectSame($expected, $actual, string $message): void
|
||||
{
|
||||
if ($expected !== $actual) {
|
||||
fwrite(STDERR, "FAIL: {$message}\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function callPrivate(string $name, array $arguments)
|
||||
{
|
||||
$method = (new ReflectionClass(DifyChatService::class))->getMethod($name);
|
||||
return $method->invoke(null, ...$arguments);
|
||||
}
|
||||
|
||||
$generic = callPrivate('buildRequestSpecs', [
|
||||
'https://ai.example.test/v1',
|
||||
'model-name',
|
||||
['prompt_version' => 'test'],
|
||||
'clinical prompt',
|
||||
'server-user',
|
||||
]);
|
||||
expectSame(2, count($generic), 'ambiguous /v1 base should support both protocols');
|
||||
expectSame('https://ai.example.test/v1/chat-messages', $generic[0]['url'], 'Dify endpoint');
|
||||
expectSame('blocking', $generic[0]['payload']['response_mode'], 'Dify blocking request');
|
||||
expectSame('https://ai.example.test/v1/chat/completions', $generic[1]['url'], 'OpenAI endpoint');
|
||||
expectSame('model-name', $generic[1]['payload']['model'], 'profile model selection');
|
||||
expectSame('clinical prompt', $generic[1]['payload']['messages'][0]['content'], 'OpenAI prompt');
|
||||
$serializedSpecs = json_encode($generic, JSON_UNESCAPED_SLASHES) ?: '';
|
||||
expectSame(false, str_contains($serializedSpecs, 'api_key'), 'credential field is absent from request bodies');
|
||||
expectSame(false, str_contains($serializedSpecs, 'provider'), 'provider override is absent from request bodies');
|
||||
expectSame(false, str_contains($serializedSpecs, 'base_url'), 'base URL override is absent from request bodies');
|
||||
|
||||
$openAi = callPrivate('buildRequestSpecs', [
|
||||
'https://ai.example.test/v1/chat/completions',
|
||||
'model-name',
|
||||
[],
|
||||
'prompt',
|
||||
'server-user',
|
||||
]);
|
||||
expectSame(1, count($openAi), 'explicit OpenAI endpoint should not probe Dify');
|
||||
expectSame('openai', $openAi[0]['protocol'], 'explicit OpenAI protocol');
|
||||
|
||||
$dify = callPrivate('buildRequestSpecs', [
|
||||
'https://ai.example.test/v1/chat-messages',
|
||||
'model-name',
|
||||
[],
|
||||
'prompt',
|
||||
'server-user',
|
||||
]);
|
||||
expectSame(1, count($dify), 'explicit Dify endpoint should not probe OpenAI');
|
||||
expectSame('dify', $dify[0]['protocol'], 'explicit Dify protocol');
|
||||
|
||||
expectSame('Dify answer', callPrivate('extractContent', [['answer' => ' Dify answer ']]), 'Dify response');
|
||||
expectSame(
|
||||
'OpenAI answer',
|
||||
callPrivate('extractContent', [['choices' => [['message' => ['content' => ' OpenAI answer ']]]]]),
|
||||
'OpenAI response'
|
||||
);
|
||||
expectSame(
|
||||
'multipart answer',
|
||||
callPrivate('extractContent', [['choices' => [['message' => ['content' => [
|
||||
['type' => 'text', 'text' => 'multipart '],
|
||||
['type' => 'text', 'text' => 'answer'],
|
||||
]]]]]]),
|
||||
'OpenAI multipart response'
|
||||
);
|
||||
|
||||
expectSame(true, callPrivate('isValidBaseUrl', ['https://ai.example.test/v1']), 'https URL');
|
||||
expectSame(true, callPrivate('isValidBaseUrl', ['http://127.0.0.1:8080/v1']), 'internal http URL');
|
||||
expectSame(false, callPrivate('isValidBaseUrl', ['file:///tmp/socket']), 'non-http URL');
|
||||
expectSame(false, callPrivate('isValidBaseUrl', ['https://user@example.test/v1']), 'userinfo URL');
|
||||
expectSame(false, callPrivate('isValidBaseUrl', ['https://ai.example.test/v1?unsafe=query']), 'query URL');
|
||||
expectSame(true, callPrivate('isValidTimeout', [90]), 'normal timeout');
|
||||
expectSame(false, callPrivate('isValidTimeout', [0]), 'zero timeout');
|
||||
expectSame(false, callPrivate('isValidTimeout', [301]), 'excessive timeout');
|
||||
|
||||
echo "Prescription AI upstream contract: OK\n";
|
||||
Reference in New Issue
Block a user