calculator = new CostCalculator(); } public function test_calculates_cost_correctly(): void { ModelPricing::create([ 'provider' => 'openai', 'model' => 'gpt-4o-mini', 'input_price_per_million' => 0.15, 'output_price_per_million' => 0.60, 'is_active' => true, 'effective_from' => now(), ]); Cache::flush(); $costs = $this->calculator->calculate('openai', 'gpt-4o-mini', 1000, 500); // (1000/1M * 0.15) + (500/1M * 0.60) = 0.00015 + 0.0003 = 0.00045 $this->assertEquals(0.00015, $costs['prompt_cost']); $this->assertEquals(0.0003, $costs['completion_cost']); $this->assertEquals(0.00045, $costs['total_cost']); } public function test_returns_zero_cost_for_unknown_model(): void { Cache::flush(); $costs = $this->calculator->calculate('unknown', 'unknown-model', 1000, 500); $this->assertEquals(0.0, $costs['prompt_cost']); $this->assertEquals(0.0, $costs['completion_cost']); $this->assertEquals(0.0, $costs['total_cost']); } public function test_uses_cache_for_pricing(): void { ModelPricing::create([ 'provider' => 'anthropic', 'model' => 'claude-sonnet-4', 'input_price_per_million' => 3.00, 'output_price_per_million' => 15.00, 'is_active' => true, 'effective_from' => now(), ]); Cache::flush(); // First call - should query database $costs1 = $this->calculator->calculate('anthropic', 'claude-sonnet-4', 1000, 500); // Second call - should use cache $costs2 = $this->calculator->calculate('anthropic', 'claude-sonnet-4', 1000, 500); $this->assertEquals($costs1, $costs2); $this->assertTrue(Cache::has('pricing:anthropic:claude-sonnet-4')); } public function test_estimate_cost(): void { ModelPricing::create([ 'provider' => 'openai', 'model' => 'gpt-4o', 'input_price_per_million' => 2.50, 'output_price_per_million' => 10.00, 'is_active' => true, 'effective_from' => now(), ]); Cache::flush(); $estimatedCost = $this->calculator->estimateCost('openai', 'gpt-4o', 2000, 1000); // (2000/1M * 2.50) + (1000/1M * 10.00) = 0.005 + 0.01 = 0.015 $this->assertEquals(0.015, $estimatedCost); } public function test_clear_cache(): void { Cache::put('pricing:test:model', 'test_data', 3600); $this->calculator->clearCache('test', 'model'); $this->assertFalse(Cache::has('pricing:test:model')); } }