/home/alixis5/integrate.sellofinance.com/tests/Unit/Services
NameSizeModeActions
CatalogAggregatorTest.php81420644editdlrm
MeritRankerTest.php52900644editdlrm
Edit: /home/alixis5/integrate.sellofinance.com/tests/Unit/Services/MeritRankerTest.php (5290B)
ranker = new MeritRanker(); } public function test_rate_competitiveness_at_average_scores_zero(): void { $r = $this->ranker->rateCompetitiveness(productMidRate: 5.0, categoryAvgRate: 5.0); $this->assertSame(0.0, $r); } public function test_rate_competitiveness_below_average_scores_positive(): void { // categoryAvg = 5.0; productMid = 4.0 → 20% below → 0.2 $r = $this->ranker->rateCompetitiveness(productMidRate: 4.0, categoryAvgRate: 5.0); $this->assertEqualsWithDelta(0.2, $r, 1e-6); } public function test_rate_competitiveness_category_avg_zero_returns_one(): void { $r = $this->ranker->rateCompetitiveness(productMidRate: 0.0, categoryAvgRate: 0.0); $this->assertSame(1.0, $r); } public function test_eligibility_breadth_zero_requirements_scores_high(): void { // Product has minSalary=0 in group [0..10000], minScore=0 in group [0..700] $b = $this->ranker->eligibilityBreadth( minSalary: 0, salaryMin: 0, salaryMax: 10000, minScore: 0, scoreMin: 0, scoreMax: 700, ); $this->assertEqualsWithDelta(1.0, $b, 1e-6); } public function test_eligibility_breadth_max_requirements_scores_zero(): void { $b = $this->ranker->eligibilityBreadth( minSalary: 10000, salaryMin: 0, salaryMax: 10000, minScore: 700, scoreMin: 0, scoreMax: 700, ); $this->assertEqualsWithDelta(0.0, $b, 1e-6); } public function test_eligibility_breadth_returns_half_when_group_flat(): void { // All products in group share same salary/score → no signal $b = $this->ranker->eligibilityBreadth( minSalary: 5000, salaryMin: 5000, salaryMax: 5000, minScore: 600, scoreMin: 600, scoreMax: 600, ); $this->assertEqualsWithDelta(0.5, $b, 1e-6); } public function test_freshness_decays_exponentially(): void { $this->assertEqualsWithDelta(1.0, $this->ranker->freshness(0), 1e-6); $this->assertEqualsWithDelta(0.72, $this->ranker->freshness(30), 0.01); $this->assertEqualsWithDelta(0.37, $this->ranker->freshness(90), 0.01); } public function test_score_combines_three_weighted_components(): void { // Weights 0.5 / 0.3 / 0.2 — all inputs = 1.0 → score = 1.0 $s = $this->ranker->score(rate: 1.0, eligibility: 1.0, freshness: 1.0); $this->assertEqualsWithDelta(1.0, $s, 1e-6); // All inputs = 0 → 0 $this->assertEqualsWithDelta(0.0, $this->ranker->score(0.0, 0.0, 0.0), 1e-6); // Rate=1 only → 0.5 $this->assertEqualsWithDelta(0.5, $this->ranker->score(1.0, 0.0, 0.0), 1e-6); } public function test_diversity_cap_limits_per_institution(): void { $products = []; for ($i = 0; $i < 10; $i++) { $products[] = [ 'id' => "p{$i}", 'accountId' => 'bank-A', '_score' => 1.0 - ($i * 0.01), 'modifiedAt' => '2026-04-22T12:00:00+00:00', ]; } for ($i = 0; $i < 3; $i++) { $products[] = [ 'id' => "pB{$i}", 'accountId' => 'bank-B', '_score' => 0.5 - ($i * 0.01), 'modifiedAt' => '2026-04-22T12:00:00+00:00', ]; } $top = $this->ranker->applyDiversityCap($products, limitPerInstitution: 3, finalLimit: 5); $this->assertCount(5, $top); $byBank = array_count_values(array_column($top, 'accountId')); $this->assertSame(3, $byBank['bank-A']); $this->assertSame(2, $byBank['bank-B']); } public function test_rank_full_pipeline_returns_top_n(): void { $products = [ // Cheapest rate, zero requirements — should win ['id' => 'winner', 'productType' => 'personalLoan', 'categoryId' => 'cat-1', 'accountId' => 'bank-A', 'profitRateMin' => 1.0, 'profitRateMax' => 2.0, 'minSalary' => 0, 'minCreditScore' => 0, 'createdAt' => '2026-04-22T00:00:00+00:00', 'modifiedAt' => '2026-04-22T00:00:00+00:00'], ['id' => 'avg', 'productType' => 'personalLoan', 'categoryId' => 'cat-1', 'accountId' => 'bank-A', 'profitRateMin' => 5.0, 'profitRateMax' => 6.0, 'minSalary' => 5000, 'minCreditScore' => 600, 'createdAt' => '2026-02-01T00:00:00+00:00', 'modifiedAt' => '2026-02-01T00:00:00+00:00'], ['id' => 'expensive','productType' => 'personalLoan', 'categoryId' => 'cat-1', 'accountId' => 'bank-A', 'profitRateMin' => 9.0, 'profitRateMax' => 10.0,'minSalary' => 10000,'minCreditScore' => 700, 'createdAt' => '2026-01-01T00:00:00+00:00', 'modifiedAt' => '2026-01-01T00:00:00+00:00'], ]; $top = $this->ranker->rank($products, now: new \DateTimeImmutable('2026-04-22T12:00:00+00:00'), limit: 3); $this->assertSame('winner', $top[0]['id']); } }