wpdb = $this->create_mock_wpdb(); $GLOBALS['wpdb'] = $this->wpdb; // CostTracker methods call get_option for budget settings. $this->stub_get_option( [ 'prautoblogger_monthly_budget_usd' => '50.00', ] ); // Stub current_time used in date-based queries. $this->stub_current_time( '2026-04-12 10:00:00' ); } protected function tearDown(): void { unset( $GLOBALS['wpdb'] ); parent::tearDown(); } /** * Test set_run_id and get_run_id. */ public function test_set_and_get_run_id(): void { $tracker = new \PRAutoBlogger_Cost_Tracker(); $tracker->set_run_id( 'run_abc123' ); $this->assertSame( 'run_abc123', $tracker->get_run_id() ); } /** * Test get_run_id returns null when not set. */ public function test_get_run_id_returns_null_when_not_set(): void { $tracker = new \PRAutoBlogger_Cost_Tracker(); $this->assertNull( $tracker->get_run_id() ); } /** * Test is_budget_exceeded returns false by default. */ public function test_is_budget_exceeded_returns_false_by_default(): void { $tracker = new \PRAutoBlogger_Cost_Tracker(); $this->assertFalse( $tracker->is_budget_exceeded() ); } /** * Test get_current_run_cost returns float. */ public function test_get_current_run_cost_returns_float(): void { $this->wpdb->method( 'prepare' )->willReturn( 'prepared' ); $this->wpdb->method( 'get_var' )->willReturn( '0.05' ); $tracker = new \PRAutoBlogger_Cost_Tracker(); $tracker->set_run_id( 'run_abc123' ); $cost = $tracker->get_current_run_cost(); $this->assertIsFloat( $cost ); $this->assertGreaterThanOrEqual( 0.0, $cost ); } /** * Test log_api_call with mock database. */ public function test_log_api_call_interacts_with_database(): void { $tracker = new \PRAutoBlogger_Cost_Tracker(); $tracker->set_run_id( 'run_test' ); // Allow multiple inserts — log_api_call inserts a generation log row, // and Logger may also insert an event log row if a warning fires. $this->wpdb->expects( $this->atLeastOnce() ) ->method( 'insert' ) ->willReturn( 1 ); // Actual signature: log_api_call(?int $post_id, string $stage, // string $provider, string $model, int $prompt_tokens, // int $completion_tokens, string $response_status, string $error_message). // Use 'openai/gpt-4o' which IS in MODEL_PRICING to avoid unknown-model warnings. $tracker->log_api_call( 123, 'analysis', 'openrouter', 'openai/gpt-4o', 500, 250 ); // If we get here without exception, the method worked. $this->assertTrue( true ); } }