- New Cost_Tracker class: logs every API call (model, tokens, cost), enforces monthly budgets with hard-stop mode, provides aggregated reporting - New llm_costs database table with indexes on created_at, model, operation - Modified LLM class: call_openrouter_with_usage() extracts token usage from OpenRouter responses; budget gate checks before each API call - Admin settings: monthly budget (USD), enforcement mode (disabled/warn/hard-stop), cost log retention period - Admin cost dashboard: budget progress bar, daily cost chart (Chart.js), per-model and per-operation breakdowns, recent API call log - PHPUnit tests: 16 tests covering cost calculation, pricing lookups, budget enforcement logic, and model validation - Updated ARCHITECTURE.md with new table schema, data flow, and key decisions - Updated CONVENTIONS.md with "how to add cost tracking for a new operation" - Version bump to 2.4.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
85 lines
2.5 KiB
PHP
Executable File
85 lines
2.5 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Unit tests for the main plugin bootstrap file.
|
|
*
|
|
* Validates constants, version strings, and file structure.
|
|
*
|
|
* @package PeptideNews\Tests
|
|
*/
|
|
|
|
namespace PeptideNews\Tests\Unit;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class PluginBootstrapTest extends TestCase {
|
|
|
|
/**
|
|
* Plugin version constant should be defined and non-empty.
|
|
*/
|
|
public function test_version_constant_is_defined(): void {
|
|
$this->assertTrue( defined( 'PEPTIDE_NEWS_VERSION' ) );
|
|
$this->assertNotEmpty( PEPTIDE_NEWS_VERSION );
|
|
}
|
|
|
|
/**
|
|
* Plugin directory constant should point to a real directory.
|
|
*/
|
|
public function test_plugin_dir_constant_is_valid(): void {
|
|
$this->assertTrue( defined( 'PEPTIDE_NEWS_PLUGIN_DIR' ) );
|
|
$this->assertDirectoryExists( PEPTIDE_NEWS_PLUGIN_DIR );
|
|
}
|
|
|
|
/**
|
|
* Main plugin file should exist.
|
|
*/
|
|
public function test_main_plugin_file_exists(): void {
|
|
$this->assertFileExists( PEPTIDE_NEWS_PLUGIN_DIR . 'peptide-news-plugin.php' );
|
|
}
|
|
|
|
/**
|
|
* All required class files should exist.
|
|
*/
|
|
public function test_required_class_files_exist(): void {
|
|
$files = array(
|
|
'includes/class-peptide-news.php',
|
|
'includes/class-peptide-news-activator.php',
|
|
'includes/class-peptide-news-deactivator.php',
|
|
'includes/class-peptide-news-fetcher.php',
|
|
'includes/class-peptide-news-analytics.php',
|
|
'includes/class-peptide-news-rest-api.php',
|
|
'admin/class-peptide-news-admin.php',
|
|
);
|
|
|
|
foreach ( $files as $file ) {
|
|
$path = PEPTIDE_NEWS_PLUGIN_DIR . $file;
|
|
$this->assertFileExists( $path, "Required file missing: {$file}" );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Admin JavaScript file should exist.
|
|
*/
|
|
public function test_admin_script_exists(): void {
|
|
$this->assertFileExists( PEPTIDE_NEWS_PLUGIN_DIR . 'admin/js/admin-script.js' );
|
|
}
|
|
|
|
/**
|
|
* Admin stylesheet should exist.
|
|
*/
|
|
public function test_admin_style_exists(): void {
|
|
$this->assertFileExists( PEPTIDE_NEWS_PLUGIN_DIR . 'admin/css/admin-style.css' );
|
|
}
|
|
|
|
/**
|
|
* Version string should follow SemVer pattern.
|
|
*/
|
|
public function test_version_follows_semver(): void {
|
|
// Allow semver with optional pre-release suffix (e.g. 1.2.1-test).
|
|
$this->assertMatchesRegularExpression(
|
|
'/^\d+\.\d+\.\d+(-[\w.]+)?$/',
|
|
PEPTIDE_NEWS_VERSION,
|
|
'Version does not follow SemVer pattern.'
|
|
);
|
|
}
|
|
}
|