Files
2026-07-01 10:30:32 +09:00

110 lines
3.7 KiB
PHP

<?php
namespace Modules\Sirsoft\Ecommerce\Tests\Feature\Console;
// ModuleTestCase를 수동으로 require (autoload 전에 로드 필요)
require_once __DIR__.'/../../ModuleTestCase.php';
use Carbon\CarbonImmutable;
use Modules\Sirsoft\Ecommerce\Enums\OrderStatusEnum;
use Modules\Sirsoft\Ecommerce\Models\EcommerceStat;
use Modules\Sirsoft\Ecommerce\Models\Order;
use Modules\Sirsoft\Ecommerce\Models\OrderOption;
use Modules\Sirsoft\Ecommerce\Tests\ModuleTestCase;
use PHPUnit\Framework\Attributes\Test;
/**
* 이커머스 판매 현황 집계 커맨드 테스트
*
* sirsoft-ecommerce:aggregate-stats {--dry-run}
*/
class AggregateEcommerceStatsCommandTest extends ModuleTestCase
{
protected function setUp(): void
{
parent::setUp();
OrderOption::query()->forceDelete();
Order::query()->forceDelete();
EcommerceStat::query()->delete();
}
/**
* 오늘 주문일의 매출 반영 옵션 1건을 생성합니다.
*/
private function makeTodayOption(int $quantity, int $unitPrice): void
{
$order = Order::factory()->create(['ordered_at' => CarbonImmutable::today()->setTime(12, 0)->toDateTimeString()]);
OrderOption::factory()->create([
'order_id' => $order->id,
'option_status' => OrderStatusEnum::PAYMENT_COMPLETE,
'quantity' => $quantity,
'cancelled_quantity' => 0,
'unit_price' => $unitPrice,
]);
}
#[Test]
public function test_dry_run_does_not_persist_rows(): void
{
$this->makeTodayOption(2, 1000);
$this->artisan('sirsoft-ecommerce:aggregate-stats', ['--dry-run' => true])
->assertExitCode(0);
$this->assertSame(0, EcommerceStat::count());
}
#[Test]
public function test_aggregates_recent_7_days_and_preserves_older(): void
{
$today = CarbonImmutable::today();
$eightDaysAgo = $today->subDays(8)->toDateString();
EcommerceStat::create(['date' => $eightDaysAgo, 'sales_quantity' => 99, 'sales_amount' => 99000, 'option_status_counts' => []]);
$this->makeTodayOption(2, 1000);
$this->artisan('sirsoft-ecommerce:aggregate-stats')->assertExitCode(0);
// 오늘 행: 수량 2, 순매출 2000
$todayRow = EcommerceStat::where('date', $today->toDateString())->first();
$this->assertSame(2, $todayRow->sales_quantity);
$this->assertSame('2000.00', $todayRow->sales_amount);
// 8일 전 행 보존
$oldRow = EcommerceStat::where('date', $eightDaysAgo)->first();
$this->assertSame(99, $oldRow->sales_quantity);
// 7일치 + 8일전 1행 = 8행
$this->assertSame(8, EcommerceStat::count());
}
#[Test]
public function test_is_idempotent_on_rerun(): void
{
$this->makeTodayOption(2, 1000);
$this->artisan('sirsoft-ecommerce:aggregate-stats')->assertExitCode(0);
$this->artisan('sirsoft-ecommerce:aggregate-stats')->assertExitCode(0);
$this->assertSame(7, EcommerceStat::count());
$todayRow = EcommerceStat::where('date', CarbonImmutable::today()->toDateString())->first();
$this->assertSame(2, $todayRow->sales_quantity);
}
#[Test]
public function test_skips_when_scheduler_disabled(): void
{
// g7_module_settings 는 g7_settings.modules.{id} 에서 읽으므로 해당 경로를 설정한다.
config()->set('g7_settings.modules.sirsoft-ecommerce.dashboard.scheduler_enabled', false);
$this->makeTodayOption(2, 1000);
$this->artisan('sirsoft-ecommerce:aggregate-stats')->assertExitCode(0);
// 스케줄러 비활성화 시 저장하지 않음
$this->assertSame(0, EcommerceStat::count());
}
}