Add unit test suite: 54 tests across models, core, and providers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
peptiderepo
2026-04-12 00:36:59 +07:00
parent 88d674d679
commit c6370cf854
19 changed files with 1585 additions and 478 deletions

View File

@@ -0,0 +1,69 @@
<?php
/**
* Tests for PRAutoBlogger_Analysis_Result value object.
*
* @package PRAutoBlogger\Tests\Models
*/
namespace PRAutoBlogger\Tests\Models;
use PRAutoBlogger\Tests\BaseTestCase;
class AnalysisResultTest extends BaseTestCase {
protected function setUp(): void {
parent::setUp();
require_once PRAB_PLUGIN_DIR . 'includes/models/class-prab-analysis-result.php';
}
/**
* Test construction with valid analysis data.
*/
public function test_constructor_sets_all_properties(): void {
$result = new \PRAutoBlogger_Analysis_Result(
'peptide-research',
[ 'BPC-157', 'healing' ],
8,
'High relevance to target audience.',
[ 'regenerative medicine', 'peptide therapy' ]
);
$this->assertSame( 'peptide-research', $result->get_category() );
$this->assertSame( [ 'BPC-157', 'healing' ], $result->get_keywords() );
$this->assertSame( 8, $result->get_relevance_score() );
$this->assertSame( 'High relevance to target audience.', $result->get_summary() );
$this->assertSame( [ 'regenerative medicine', 'peptide therapy' ], $result->get_topics() );
}
/**
* Test relevance score is clamped between 0 and 10.
*/
public function test_relevance_score_boundaries(): void {
$high = new \PRAutoBlogger_Analysis_Result( 'cat', [], 10, 'Max score.', [] );
$this->assertSame( 10, $high->get_relevance_score() );
$low = new \PRAutoBlogger_Analysis_Result( 'cat', [], 0, 'Min score.', [] );
$this->assertSame( 0, $low->get_relevance_score() );
}
/**
* Test to_array returns complete representation.
*/
public function test_to_array_completeness(): void {
$result = new \PRAutoBlogger_Analysis_Result(
'news',
[ 'test' ],
5,
'Summary text.',
[ 'topic1' ]
);
$array = $result->to_array();
$this->assertIsArray( $array );
$this->assertArrayHasKey( 'category', $array );
$this->assertArrayHasKey( 'keywords', $array );
$this->assertArrayHasKey( 'relevance_score', $array );
$this->assertArrayHasKey( 'summary', $array );
$this->assertArrayHasKey( 'topics', $array );
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* Tests for PRAutoBlogger_Article_Idea value object.
*
* @package PRAutoBlogger\Tests\Models
*/
namespace PRAutoBlogger\Tests\Models;
use PRAutoBlogger\Tests\BaseTestCase;
class ArticleIdeaTest extends BaseTestCase {
protected function setUp(): void {
parent::setUp();
require_once PRAB_PLUGIN_DIR . 'includes/models/class-prab-article-idea.php';
}
/**
* Test construction with full data.
*/
public function test_constructor_sets_all_properties(): void {
$idea = new \PRAutoBlogger_Article_Idea(
'The Future of BPC-157 Research',
'An in-depth look at recent clinical trials.',
[ 'BPC-157', 'clinical trials', 'peptides' ],
'peptide-research',
85.5
);
$this->assertSame( 'The Future of BPC-157 Research', $idea->get_title() );
$this->assertSame( 'An in-depth look at recent clinical trials.', $idea->get_description() );
$this->assertSame( [ 'BPC-157', 'clinical trials', 'peptides' ], $idea->get_keywords() );
$this->assertSame( 'peptide-research', $idea->get_category() );
$this->assertSame( 85.5, $idea->get_score() );
}
/**
* Test to_array returns all fields.
*/
public function test_to_array_returns_complete_data(): void {
$idea = new \PRAutoBlogger_Article_Idea(
'Test Title',
'Test description.',
[ 'kw1' ],
'general',
50.0
);
$array = $idea->to_array();
$this->assertIsArray( $array );
$this->assertArrayHasKey( 'title', $array );
$this->assertArrayHasKey( 'description', $array );
$this->assertArrayHasKey( 'keywords', $array );
$this->assertArrayHasKey( 'category', $array );
$this->assertArrayHasKey( 'score', $array );
}
/**
* Test score can be zero.
*/
public function test_allows_zero_score(): void {
$idea = new \PRAutoBlogger_Article_Idea(
'Low Score Idea',
'Not great.',
[],
'general',
0.0
);
$this->assertSame( 0.0, $idea->get_score() );
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* Tests for PRAutoBlogger_Content_Request value object.
*
* @package PRAutoBlogger\Tests\Models
*/
namespace PRAutoBlogger\Tests\Models;
use PRAutoBlogger\Tests\BaseTestCase;
class ContentRequestTest extends BaseTestCase {
protected function setUp(): void {
parent::setUp();
require_once PRAB_PLUGIN_DIR . 'includes/models/class-prab-content-request.php';
}
/**
* Test construction with required fields.
*/
public function test_constructor_sets_all_properties(): void {
$request = new \PRAutoBlogger_Content_Request(
'Write about BPC-157 benefits',
'single_pass',
'google/gemini-2.0-flash-001',
[ 'tone' => 'informative', 'length' => 'long' ]
);
$this->assertSame( 'Write about BPC-157 benefits', $request->get_prompt() );
$this->assertSame( 'single_pass', $request->get_pipeline_mode() );
$this->assertSame( 'google/gemini-2.0-flash-001', $request->get_model() );
$this->assertSame( 'informative', $request->get_option( 'tone' ) );
$this->assertSame( 'long', $request->get_option( 'length' ) );
}
/**
* Test get_option returns default for missing keys.
*/
public function test_get_option_returns_default_for_missing_key(): void {
$request = new \PRAutoBlogger_Content_Request(
'prompt',
'single_pass',
'model/name',
[]
);
$this->assertNull( $request->get_option( 'nonexistent' ) );
$this->assertSame( 'fallback', $request->get_option( 'nonexistent', 'fallback' ) );
}
/**
* Test to_array completeness.
*/
public function test_to_array_returns_all_fields(): void {
$request = new \PRAutoBlogger_Content_Request(
'test prompt',
'multi_step',
'model/x',
[ 'key' => 'val' ]
);
$array = $request->to_array();
$this->assertIsArray( $array );
$this->assertArrayHasKey( 'prompt', $array );
$this->assertArrayHasKey( 'pipeline_mode', $array );
$this->assertArrayHasKey( 'model', $array );
$this->assertArrayHasKey( 'options', $array );
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* Tests for PRAutoBlogger_Content_Score value object.
*
* @package PRAutoBlogger\Tests\Models
*/
namespace PRAutoBlogger\Tests\Models;
use PRAutoBlogger\Tests\BaseTestCase;
class ContentScoreTest extends BaseTestCase {
protected function setUp(): void {
parent::setUp();
require_once PRAB_PLUGIN_DIR . 'includes/models/class-prab-content-score.php';
}
/**
* Test construction with scoring dimensions.
*/
public function test_constructor_sets_all_dimensions(): void {
$score = new \PRAutoBlogger_Content_Score(
8.0, // relevance
7.5, // quality
9.0, // originality
6.5, // seo
7.75 // overall
);
$this->assertSame( 8.0, $score->get_relevance() );
$this->assertSame( 7.5, $score->get_quality() );
$this->assertSame( 9.0, $score->get_originality() );
$this->assertSame( 6.5, $score->get_seo() );
$this->assertSame( 7.75, $score->get_overall() );
}
/**
* Test boundary scores (0 and 10).
*/
public function test_boundary_scores(): void {
$min = new \PRAutoBlogger_Content_Score( 0.0, 0.0, 0.0, 0.0, 0.0 );
$this->assertSame( 0.0, $min->get_overall() );
$max = new \PRAutoBlogger_Content_Score( 10.0, 10.0, 10.0, 10.0, 10.0 );
$this->assertSame( 10.0, $max->get_overall() );
}
/**
* Test to_array completeness.
*/
public function test_to_array_returns_all_dimensions(): void {
$score = new \PRAutoBlogger_Content_Score( 5.0, 5.0, 5.0, 5.0, 5.0 );
$array = $score->to_array();
$this->assertArrayHasKey( 'relevance', $array );
$this->assertArrayHasKey( 'quality', $array );
$this->assertArrayHasKey( 'originality', $array );
$this->assertArrayHasKey( 'seo', $array );
$this->assertArrayHasKey( 'overall', $array );
}
}

View File

@@ -0,0 +1,70 @@
<?php
/**
* Tests for PRAutoBlogger_Editorial_Review value object.
*
* @package PRAutoBlogger\Tests\Models
*/
namespace PRAutoBlogger\Tests\Models;
use PRAutoBlogger\Tests\BaseTestCase;
class EditorialReviewTest extends BaseTestCase {
protected function setUp(): void {
parent::setUp();
require_once PRAB_PLUGIN_DIR . 'includes/models/class-prab-editorial-review.php';
}
/**
* Test construction with approval.
*/
public function test_approved_review(): void {
$review = new \PRAutoBlogger_Editorial_Review(
true,
'Content meets quality standards.',
8.5,
[ 'Good structure', 'Clear language' ],
[]
);
$this->assertTrue( $review->is_approved() );
$this->assertSame( 'Content meets quality standards.', $review->get_feedback() );
$this->assertSame( 8.5, $review->get_quality_score() );
$this->assertSame( [ 'Good structure', 'Clear language' ], $review->get_strengths() );
$this->assertEmpty( $review->get_issues() );
}
/**
* Test construction with rejection and issues.
*/
public function test_rejected_review_with_issues(): void {
$review = new \PRAutoBlogger_Editorial_Review(
false,
'Content needs improvement.',
4.0,
[],
[ 'Too short', 'Missing citations', 'Unclear conclusion' ]
);
$this->assertFalse( $review->is_approved() );
$this->assertCount( 3, $review->get_issues() );
$this->assertSame( 4.0, $review->get_quality_score() );
}
/**
* Test to_array completeness.
*/
public function test_to_array_returns_all_fields(): void {
$review = new \PRAutoBlogger_Editorial_Review(
true, 'OK', 7.0, [ 'Good' ], []
);
$array = $review->to_array();
$this->assertArrayHasKey( 'approved', $array );
$this->assertArrayHasKey( 'feedback', $array );
$this->assertArrayHasKey( 'quality_score', $array );
$this->assertArrayHasKey( 'strengths', $array );
$this->assertArrayHasKey( 'issues', $array );
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* Tests for PRAutoBlogger_Generation_Log value object.
*
* @package PRAutoBlogger\Tests\Models
*/
namespace PRAutoBlogger\Tests\Models;
use PRAutoBlogger\Tests\BaseTestCase;
class GenerationLogTest extends BaseTestCase {
protected function setUp(): void {
parent::setUp();
require_once PRAB_PLUGIN_DIR . 'includes/models/class-prab-generation-log.php';
}
/**
* Test construction with all fields.
*/
public function test_constructor_sets_all_properties(): void {
$log = new \PRAutoBlogger_Generation_Log(
'google/gemini-2.0-flash-001',
'content_generation',
500,
1200,
0.0034,
2.45,
true,
''
);
$this->assertSame( 'google/gemini-2.0-flash-001', $log->get_model() );
$this->assertSame( 'content_generation', $log->get_step() );
$this->assertSame( 500, $log->get_prompt_tokens() );
$this->assertSame( 1200, $log->get_completion_tokens() );
$this->assertSame( 0.0034, $log->get_cost() );
$this->assertSame( 2.45, $log->get_duration() );
$this->assertTrue( $log->is_success() );
$this->assertSame( '', $log->get_error() );
}
/**
* Test failed generation log.
*/
public function test_failed_generation_log(): void {
$log = new \PRAutoBlogger_Generation_Log(
'anthropic/claude-3-haiku',
'analysis',
200,
0,
0.0,
0.0,
false,
'Rate limit exceeded'
);
$this->assertFalse( $log->is_success() );
$this->assertSame( 'Rate limit exceeded', $log->get_error() );
$this->assertSame( 0, $log->get_completion_tokens() );
}
/**
* Test total tokens calculation.
*/
public function test_get_total_tokens(): void {
$log = new \PRAutoBlogger_Generation_Log(
'model/x', 'step', 300, 700, 0.01, 1.0, true, ''
);
$this->assertSame( 1000, $log->get_total_tokens() );
}
/**
* Test to_array completeness.
*/
public function test_to_array_returns_all_fields(): void {
$log = new \PRAutoBlogger_Generation_Log(
'model', 'step', 100, 200, 0.001, 0.5, true, ''
);
$array = $log->to_array();
$this->assertArrayHasKey( 'model', $array );
$this->assertArrayHasKey( 'step', $array );
$this->assertArrayHasKey( 'prompt_tokens', $array );
$this->assertArrayHasKey( 'completion_tokens', $array );
$this->assertArrayHasKey( 'cost', $array );
$this->assertArrayHasKey( 'duration', $array );
$this->assertArrayHasKey( 'success', $array );
$this->assertArrayHasKey( 'error', $array );
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* Tests for PRAutoBlogger_Source_Data value object.
*
* @package PRAutoBlogger\Tests\Models
*/
namespace PRAutoBlogger\Tests\Models;
use PRAutoBlogger\Tests\BaseTestCase;
class SourceDataTest extends BaseTestCase {
/**
* Require the class under test.
*/
protected function setUp(): void {
parent::setUp();
require_once PRAB_PLUGIN_DIR . 'includes/models/class-prab-source-data.php';
}
/**
* Test construction with all required fields.
*/
public function test_constructor_sets_all_properties(): void {
$data = new \PRAutoBlogger_Source_Data(
'Test Title',
'https://example.com/article',
'This is the content body.',
'rss'
);
$this->assertSame( 'Test Title', $data->get_title() );
$this->assertSame( 'https://example.com/article', $data->get_url() );
$this->assertSame( 'This is the content body.', $data->get_content() );
$this->assertSame( 'rss', $data->get_source_type() );
}
/**
* Test that to_array returns all fields.
*/
public function test_to_array_returns_complete_representation(): void {
$data = new \PRAutoBlogger_Source_Data(
'Array Test',
'https://example.com',
'Content here.',
'manual'
);
$array = $data->to_array();
$this->assertIsArray( $array );
$this->assertArrayHasKey( 'title', $array );
$this->assertArrayHasKey( 'url', $array );
$this->assertArrayHasKey( 'content', $array );
$this->assertArrayHasKey( 'source_type', $array );
$this->assertSame( 'Array Test', $array['title'] );
}
/**
* Test construction with empty content is allowed.
*/
public function test_allows_empty_content(): void {
$data = new \PRAutoBlogger_Source_Data(
'Title Only',
'https://example.com',
'',
'rss'
);
$this->assertSame( '', $data->get_content() );
}
}