File: /home/xedaptot/ai.naniguide.com/tests/Unit/WarmupStrategyTest.php
<?php
namespace Tests\Unit;
use App\Dto\WarmupStrategyData;
use App\Model\WarmupStrategy;
use App\Services\WarmupStrategyService;
use Tests\TestCase;
class WarmupStrategyTest extends TestCase
{
public function test_balanced_preset_seeds_expected_defaults()
{
$service = new WarmupStrategyService();
$strategy = $service->newStrategy(WarmupStrategy::PRESET_BALANCED);
$this->assertEquals(WarmupStrategy::PRESET_BALANCED, $strategy->preset);
$this->assertEquals(WarmupStrategy::GROWTH_STRATEGY_LINEAR, $strategy->growth_strategy);
$this->assertEquals(20, $strategy->starting_volume);
$this->assertEquals(15, $strategy->daily_increment);
$this->assertEquals(1.15, $strategy->exponential_factor);
$this->assertEquals(WarmupStrategy::LIMIT_TYPE_PER_DAY_CAP, $strategy->limit_type);
$this->assertEquals(1000, $strategy->limit_per_day_cap);
$this->assertEquals(8000, $strategy->limit_target_volume);
$this->assertEquals(30, $strategy->limit_stop_after_days);
$this->assertFalse($strategy->send_on_weekends);
}
public function test_preview_uses_calendar_days_when_weekends_are_disabled()
{
$service = new WarmupStrategyService();
$preview = $service->buildPreview(WarmupStrategyData::fromArray([
'name' => 'Linear',
'description' => 'Linear strategy',
'preset' => WarmupStrategy::PRESET_BALANCED,
'growth_strategy' => WarmupStrategy::GROWTH_STRATEGY_LINEAR,
'starting_volume' => 10,
'quota_type' => WarmupStrategy::QUOTA_TYPE_DAILY,
'daily_increment' => 10,
'limit_type' => WarmupStrategy::LIMIT_TYPE_PER_DAY_CAP,
'limit_per_day_cap' => 60,
'send_on_weekends' => false,
'enable_safety_checks' => true,
'pause_on_negative_signals' => true,
'max_bounce_rate' => 4.0,
'max_complaint_rate' => 0.3,
'status' => WarmupStrategy::STATUS_ACTIVE,
]));
$this->assertEquals(8, $preview->estimatedFullWarmupDay);
$this->assertSame('low', $preview->riskLevel);
$this->assertEquals(10, $preview->planDetails[0]['sendingOfStep']);
$this->assertEquals(60, $preview->planDetails[5]['sendingOfStep']);
}
public function test_aggressive_exponential_preview_reports_high_risk()
{
$service = new WarmupStrategyService();
$preview = $service->buildPreview(WarmupStrategyData::fromArray([
'name' => 'Aggressive',
'description' => 'Aggressive strategy',
'preset' => WarmupStrategy::PRESET_AGGRESSIVE,
'growth_strategy' => WarmupStrategy::GROWTH_STRATEGY_EXPONENTIAL,
'starting_volume' => 50,
'quota_type' => WarmupStrategy::QUOTA_TYPE_DAILY,
'daily_increment' => 20,
'exponential_factor' => 1.20,
'limit_type' => WarmupStrategy::LIMIT_TYPE_STOP_AFTER_DAYS,
'limit_stop_after_days' => 21,
'send_on_weekends' => true,
'enable_safety_checks' => true,
'pause_on_negative_signals' => true,
'max_bounce_rate' => 5.0,
'max_complaint_rate' => 0.6,
'status' => WarmupStrategy::STATUS_ACTIVE,
]));
$this->assertSame('high', $preview->riskLevel);
$this->assertGreaterThan(0, count($preview->milestones));
$this->assertEquals(50, $preview->planDetails[0]['sendingOfStep']);
$this->assertCount(21, $preview->planDetails);
$this->assertEquals(1917, end($preview->planDetails)['sendingOfStep']);
}
// -------------------------------------------------------------------------
// Computed fields (sending_count, sending_limit, increment_percentage)
// -------------------------------------------------------------------------
public function test_create_populates_sending_limit_and_sending_count(): void
{
$service = new WarmupStrategyService();
// LINEAR 10→40 cap: 4 steps (10, 20, 30, 40)
// sending_count = 4, sending_limit = 40, increment_percentage = 10
$strategy = $service->create(WarmupStrategyData::fromArray([
'name' => 'Computed Fields Test',
'description' => '',
'preset' => WarmupStrategy::PRESET_BALANCED,
'growth_strategy' => WarmupStrategy::GROWTH_STRATEGY_LINEAR,
'starting_volume' => 10,
'quota_type' => WarmupStrategy::QUOTA_TYPE_DAILY,
'daily_increment' => 10,
'limit_type' => WarmupStrategy::LIMIT_TYPE_PER_DAY_CAP,
'limit_per_day_cap' => 40,
'send_on_weekends' => true,
'enable_safety_checks' => true,
'pause_on_negative_signals' => true,
'max_bounce_rate' => 4.0,
'max_complaint_rate' => 0.3,
'status' => WarmupStrategy::STATUS_ACTIVE,
]));
$this->assertSame(4, $strategy->sending_count);
$this->assertSame(40, $strategy->sending_limit);
$this->assertSame(10, $strategy->increment_percentage);
}
// -------------------------------------------------------------------------
// buildPreview full structure
// -------------------------------------------------------------------------
public function test_build_preview_returns_exact_expected_structure(): void
{
$service = new WarmupStrategyService();
// LINEAR 10→40 cap, send_on_weekends=true
// Plan: 4 steps (10, 20, 30, 40), cumulative 10, 30, 60, 100
$preview = $service->buildPreview(WarmupStrategyData::fromArray([
'name' => 'Full Test',
'description' => '',
'preset' => WarmupStrategy::PRESET_BALANCED,
'growth_strategy' => WarmupStrategy::GROWTH_STRATEGY_LINEAR,
'starting_volume' => 10,
'quota_type' => WarmupStrategy::QUOTA_TYPE_DAILY,
'daily_increment' => 10,
'exponential_factor' => 1.10,
'limit_type' => WarmupStrategy::LIMIT_TYPE_PER_DAY_CAP,
'limit_per_day_cap' => 40,
'send_on_weekends' => true,
'enable_safety_checks' => true,
'pause_on_negative_signals' => true,
'max_bounce_rate' => 4.0,
'max_complaint_rate' => 0.3,
'status' => WarmupStrategy::STATUS_ACTIVE,
]));
$this->assertSame('linear', $preview->growthStrategy);
$this->assertSame('per_day_cap', $preview->limitType);
$this->assertSame(10, $preview->startVolume);
$this->assertSame(10, $preview->dailyIncrement);
$this->assertSame(1.10, $preview->exponentialFactor);
$this->assertSame(40, $preview->activeLimitValue);
$this->assertSame(40, $preview->projectedPeakVolume);
$this->assertSame(100, $preview->projectedTotalVolume);
$this->assertSame(4, $preview->estimatedFullWarmupDay);
$this->assertSame('low', $preview->riskLevel);
$this->assertEquals([
['step' => 1, 'sendingOfStep' => 10, 'quota' => 10],
['step' => 2, 'sendingOfStep' => 20, 'quota' => 30],
['step' => 3, 'sendingOfStep' => 30, 'quota' => 60],
['step' => 4, 'sendingOfStep' => 40, 'quota' => 100],
], $preview->planDetails);
// 4 steps total ≤ 4 milestones requested → all steps returned as-is
$this->assertEquals([
['label' => 'Day 1', 'volume' => 10],
['label' => 'Day 2', 'volume' => 20],
['label' => 'Day 3', 'volume' => 30],
['label' => 'Day 4', 'volume' => 40],
], $preview->milestones);
// 4 steps total ≤ 14 chart points requested → all steps returned as-is
$this->assertEquals([
['day' => 1, 'volume' => 10, 'cumulative' => 10],
['day' => 2, 'volume' => 20, 'cumulative' => 30],
['day' => 3, 'volume' => 30, 'cumulative' => 60],
['day' => 4, 'volume' => 40, 'cumulative' => 100],
], $preview->chartPoints);
}
}