HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
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);
    }
}