Core Features: - Multi-provider support (OpenAI, Anthropic, DeepSeek, Gemini, Mistral) - Provider service architecture with abstract base class - Dynamic model discovery from provider APIs - Encrypted per-user provider credentials storage Admin Interface: - Complete admin panel with Livewire components - User management with CRUD operations - API key management with testing capabilities - Budget system with limits and reset schedules - Usage logs with filtering and CSV export - Model pricing management with cost calculator - Dashboard with Chart.js visualizations Database Schema: - MariaDB migrations for all tables - User provider credentials (encrypted) - LLM request logging - Budget tracking and rate limiting - Model pricing configuration API Implementation: - OpenAI-compatible endpoints - Budget checking middleware - Rate limit enforcement - Request logging jobs - Cost calculation service Testing: - Unit tests for all provider services - Provider factory tests - Cost calculator tests Documentation: - Admin user seeder - Model pricing seeder - Configuration files
98 lines
3.1 KiB
PHP
98 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\Services;
|
|
|
|
use Tests\TestCase;
|
|
use App\Services\LLM\ProviderFactory;
|
|
use App\Services\LLM\Providers\{
|
|
OpenAIProvider,
|
|
AnthropicProvider,
|
|
MistralProvider,
|
|
GeminiProvider,
|
|
DeepSeekProvider
|
|
};
|
|
|
|
class ProviderFactoryTest extends TestCase
|
|
{
|
|
public function test_creates_openai_provider(): void
|
|
{
|
|
$provider = ProviderFactory::create('openai', 'test-key');
|
|
|
|
$this->assertInstanceOf(OpenAIProvider::class, $provider);
|
|
}
|
|
|
|
public function test_creates_anthropic_provider(): void
|
|
{
|
|
$provider = ProviderFactory::create('anthropic', 'test-key');
|
|
|
|
$this->assertInstanceOf(AnthropicProvider::class, $provider);
|
|
}
|
|
|
|
public function test_creates_mistral_provider(): void
|
|
{
|
|
$provider = ProviderFactory::create('mistral', 'test-key');
|
|
|
|
$this->assertInstanceOf(MistralProvider::class, $provider);
|
|
}
|
|
|
|
public function test_creates_gemini_provider(): void
|
|
{
|
|
$provider = ProviderFactory::create('gemini', 'test-key');
|
|
|
|
$this->assertInstanceOf(GeminiProvider::class, $provider);
|
|
}
|
|
|
|
public function test_creates_deepseek_provider(): void
|
|
{
|
|
$provider = ProviderFactory::create('deepseek', 'test-key');
|
|
|
|
$this->assertInstanceOf(DeepSeekProvider::class, $provider);
|
|
}
|
|
|
|
public function test_throws_exception_for_unknown_provider(): void
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('Unknown provider: unknown');
|
|
|
|
ProviderFactory::create('unknown', 'test-key');
|
|
}
|
|
|
|
public function test_is_case_insensitive(): void
|
|
{
|
|
$provider1 = ProviderFactory::create('OpenAI', 'test-key');
|
|
$provider2 = ProviderFactory::create('ANTHROPIC', 'test-key');
|
|
|
|
$this->assertInstanceOf(OpenAIProvider::class, $provider1);
|
|
$this->assertInstanceOf(AnthropicProvider::class, $provider2);
|
|
}
|
|
|
|
public function test_get_supported_providers(): void
|
|
{
|
|
$providers = ProviderFactory::getSupportedProviders();
|
|
|
|
$this->assertIsArray($providers);
|
|
$this->assertContains('openai', $providers);
|
|
$this->assertContains('anthropic', $providers);
|
|
$this->assertContains('mistral', $providers);
|
|
$this->assertContains('gemini', $providers);
|
|
$this->assertContains('deepseek', $providers);
|
|
$this->assertCount(5, $providers);
|
|
}
|
|
|
|
public function test_is_supported(): void
|
|
{
|
|
$this->assertTrue(ProviderFactory::isSupported('openai'));
|
|
$this->assertTrue(ProviderFactory::isSupported('anthropic'));
|
|
$this->assertTrue(ProviderFactory::isSupported('mistral'));
|
|
$this->assertTrue(ProviderFactory::isSupported('gemini'));
|
|
$this->assertTrue(ProviderFactory::isSupported('deepseek'));
|
|
$this->assertFalse(ProviderFactory::isSupported('unknown'));
|
|
}
|
|
|
|
public function test_is_supported_case_insensitive(): void
|
|
{
|
|
$this->assertTrue(ProviderFactory::isSupported('OpenAI'));
|
|
$this->assertTrue(ProviderFactory::isSupported('ANTHROPIC'));
|
|
}
|
|
}
|