Add complete Laravel LLM Gateway implementation
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
This commit is contained in:
97
laravel-app/tests/Unit/Services/ProviderFactoryTest.php
Normal file
97
laravel-app/tests/Unit/Services/ProviderFactoryTest.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?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'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user