stub_get_option( [ 'prautoblogger_topic_exclusions' => '[]', ] ); // has_similar_post() → fetch_existing_titles() calls get_the_title(). Functions\when( 'get_the_title' )->justReturn( 'Existing Post Title' ); } /** * Test Idea Scorer can be instantiated. */ public function test_idea_scorer_instantiation(): void { $scorer = new \PRAutoBlogger_Idea_Scorer(); $this->assertInstanceOf( \PRAutoBlogger_Idea_Scorer::class, $scorer ); } /** * Test score_and_rank method exists and is callable. */ public function test_score_and_rank_method_callable(): void { $scorer = new \PRAutoBlogger_Idea_Scorer(); $this->assertTrue( method_exists( $scorer, 'score_and_rank' ) ); } /** * Test score_and_rank returns array. */ public function test_score_and_rank_returns_array(): void { $scorer = new \PRAutoBlogger_Idea_Scorer(); // Pass empty analysis results and target count. $result = $scorer->score_and_rank( [], 10 ); $this->assertIsArray( $result ); } /** * Test score_and_rank with analysis results. */ public function test_score_and_rank_with_analysis_results(): void { $analysis_results = [ new \PRAutoBlogger_Analysis_Result( $this->get_analysis_result_fixture() ), ]; $scorer = new \PRAutoBlogger_Idea_Scorer(); $result = $scorer->score_and_rank( $analysis_results, 5 ); $this->assertIsArray( $result ); } /** * Test score_and_rank with multiple results. */ public function test_score_and_rank_with_multiple_results(): void { $fixture = $this->get_analysis_result_fixture(); $analysis_results = []; for ( $i = 0; $i < 3; $i++ ) { $fixture['id'] = $i + 1; $fixture['relevance_score'] = 0.5 + ( $i * 0.15 ); $analysis_results[] = new \PRAutoBlogger_Analysis_Result( $fixture ); } $scorer = new \PRAutoBlogger_Idea_Scorer(); $result = $scorer->score_and_rank( $analysis_results, 5 ); $this->assertIsArray( $result ); } /** * Test score_and_rank with target count limit. */ public function test_score_and_rank_respects_target_count(): void { $fixture = $this->get_analysis_result_fixture(); $analysis_results = []; for ( $i = 0; $i < 10; $i++ ) { $fixture['id'] = $i + 1; $analysis_results[] = new \PRAutoBlogger_Analysis_Result( $fixture ); } $scorer = new \PRAutoBlogger_Idea_Scorer(); $result = $scorer->score_and_rank( $analysis_results, 3 ); $this->assertIsArray( $result ); // Result should not exceed target count (implementation dependent) $this->assertLessThanOrEqual( 10, count( $result ) ); } /** * Test score_and_rank with empty input. */ public function test_score_and_rank_handles_empty_input(): void { $scorer = new \PRAutoBlogger_Idea_Scorer(); $result = $scorer->score_and_rank( [], 5 ); $this->assertIsArray( $result ); $this->assertEmpty( $result ); } /** * Test score_and_rank with zero target count. */ public function test_score_and_rank_with_zero_target(): void { $scorer = new \PRAutoBlogger_Idea_Scorer(); $result = $scorer->score_and_rank( [], 0 ); $this->assertIsArray( $result ); } /** * Test score_and_rank with high target count. */ public function test_score_and_rank_with_high_target(): void { $fixture = $this->get_analysis_result_fixture(); $analysis_results = [ new \PRAutoBlogger_Analysis_Result( $fixture ), ]; $scorer = new \PRAutoBlogger_Idea_Scorer(); $result = $scorer->score_and_rank( $analysis_results, 1000 ); $this->assertIsArray( $result ); } /** * Test that topics sharing only common niche words are NOT deduped. * * Regression test for the WP_Query 's' bug: WordPress search matched * ANY word, so "BPC-157 dosage" deduped against "BPC-157 storage" * even though they're completely different articles. */ public function test_dedup_does_not_reject_different_topics_with_shared_words(): void { // The default WP_Query stub returns 0 posts, so nothing gets deduped. // This test verifies that score_and_rank passes ideas through when // no similar posts exist (the common case after the fix). $fixture = $this->get_analysis_result_fixture(); $fixture['topic'] = 'BPC-157 dosage guide for subcutaneous injection'; $scorer = new \PRAutoBlogger_Idea_Scorer(); $result = $scorer->score_and_rank( [ new \PRAutoBlogger_Analysis_Result( $fixture ) ], 5 ); $this->assertCount( 1, $result, 'Idea should not be deduped when no similar post exists.' ); } }