Add unit and feature tests for ticket processing and article management
- Implement Fake repositories and services for testing purposes. - Create tests for Article API including creation, validation, and listing. - Develop ProcessTicketJobFlowTest to validate ticket processing logic. - Add QuickReplyAdminTest for creating and updating quick replies. - Implement TicketAndArticleModelTest to ensure proper cascading deletes and credential encryption. - Create TicketIngestionTest for ticket creation and job dispatching. - Add TicketShowPageTest to verify rendering of quick replies and tool calls. - Implement unit tests for ClassifierPromptBuilder, EmbeddingService, LlmJsonDecoder, QuickReplyResolver, SupportReplyService, TicketResultPayloadBuilder, TicketToolCallService, and ToolCallRequestValidator.
This commit is contained in:
@@ -41,22 +41,9 @@ class AIClassifierServiceTest extends TestCase
|
||||
}
|
||||
};
|
||||
|
||||
$settings = new class extends AppSettingsService
|
||||
{
|
||||
public function getPrompt(string $key, ?string $default = null): ?string
|
||||
{
|
||||
return 'Select best article.';
|
||||
}
|
||||
|
||||
public function get(string $key, ?string $default = null): ?string
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
};
|
||||
|
||||
$service = new AIClassifierService(
|
||||
$client,
|
||||
$settings,
|
||||
$this->fakeSettings(),
|
||||
new ClassifierPromptBuilder,
|
||||
new LlmJsonDecoder,
|
||||
new ToolCallRequestValidator
|
||||
@@ -81,4 +68,122 @@ class AIClassifierServiceTest extends TestCase
|
||||
$this->assertStringContainsString('Allowed actions: ["domain_inf"]', $client->prompt);
|
||||
$this->assertStringContainsString('Internal note for support assistant', $client->prompt);
|
||||
}
|
||||
|
||||
public function test_it_falls_back_when_ranking_disabled(): void
|
||||
{
|
||||
config()->set('services.llm.ranking_enabled', false);
|
||||
|
||||
$client = new class implements LlmClientInterface
|
||||
{
|
||||
public function embed(string $text): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function generate(string $prompt, array $options = []): string
|
||||
{
|
||||
return '{}';
|
||||
}
|
||||
};
|
||||
|
||||
$service = new AIClassifierService(
|
||||
$client,
|
||||
$this->fakeSettings(),
|
||||
new ClassifierPromptBuilder,
|
||||
new LlmJsonDecoder,
|
||||
new ToolCallRequestValidator
|
||||
);
|
||||
|
||||
$result = $service->rank('vraag', [$this->candidate(15)]);
|
||||
$this->assertSame(15, $result->articleId);
|
||||
$this->assertSame(0.2, $result->confidence);
|
||||
}
|
||||
|
||||
public function test_it_falls_back_when_llm_json_is_invalid(): void
|
||||
{
|
||||
config()->set('services.llm.ranking_enabled', true);
|
||||
|
||||
$client = new class implements LlmClientInterface
|
||||
{
|
||||
public function embed(string $text): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function generate(string $prompt, array $options = []): string
|
||||
{
|
||||
return 'not-json';
|
||||
}
|
||||
};
|
||||
|
||||
$service = new AIClassifierService(
|
||||
$client,
|
||||
$this->fakeSettings(),
|
||||
new ClassifierPromptBuilder,
|
||||
new LlmJsonDecoder,
|
||||
new ToolCallRequestValidator
|
||||
);
|
||||
|
||||
$result = $service->rank('vraag', [$this->candidate(21)]);
|
||||
$this->assertSame(21, $result->articleId);
|
||||
$this->assertStringContainsString('invalid JSON', $result->explanation);
|
||||
}
|
||||
|
||||
public function test_it_falls_back_when_article_id_not_in_candidates(): void
|
||||
{
|
||||
$client = new class implements LlmClientInterface
|
||||
{
|
||||
public function embed(string $text): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public function generate(string $prompt, array $options = []): string
|
||||
{
|
||||
return json_encode([
|
||||
'article_id' => 999,
|
||||
'confidence' => 0.9,
|
||||
'explanation' => 'x',
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
$service = new AIClassifierService(
|
||||
$client,
|
||||
$this->fakeSettings(),
|
||||
new ClassifierPromptBuilder,
|
||||
new LlmJsonDecoder,
|
||||
new ToolCallRequestValidator
|
||||
);
|
||||
|
||||
$result = $service->rank('vraag', [$this->candidate(33)]);
|
||||
$this->assertSame(33, $result->articleId);
|
||||
$this->assertStringContainsString('schema invalid', $result->explanation);
|
||||
}
|
||||
|
||||
private function fakeSettings(): AppSettingsService
|
||||
{
|
||||
return new class extends AppSettingsService
|
||||
{
|
||||
public function getPrompt(string $key, ?string $default = null): ?string
|
||||
{
|
||||
return 'Select best article.';
|
||||
}
|
||||
|
||||
public function get(string $key, ?string $default = null): ?string
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private function candidate(int $id): ArticleCandidateDTO
|
||||
{
|
||||
return new ArticleCandidateDTO(
|
||||
articleId: $id,
|
||||
title: 'A',
|
||||
content: 'B',
|
||||
distance: 0.2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user