98 lines
4.7 KiB
PHP
98 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Console;
|
|
|
|
use Illuminate\Contracts\Console\Kernel;
|
|
use Illuminate\Console\Scheduling\Schedule;
|
|
use Illuminate\Support\Carbon;
|
|
use Mockery;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorSynchronizer;
|
|
use RuntimeException;
|
|
use Tests\TestCase;
|
|
|
|
class SupplierManagementMirrorSyncCommandTest extends TestCase
|
|
{
|
|
private const DATASETS = [
|
|
'jiansun.dbo.js_supplier_View',
|
|
'jiansun.dbo.js_supplier_contract_View',
|
|
'jiansun.dbo.js_supplier_linkers',
|
|
'jiansun.dbo.js_supplier_payinfo',
|
|
];
|
|
|
|
public function test_daily_sync_finishes_all_four_datasets_in_order(): void
|
|
{
|
|
config(['upstream_mirrors.refresh_enabled' => true]);
|
|
$registry = Mockery::mock(BusinessMirrorDatasetRegistry::class);
|
|
$sync = Mockery::mock(BusinessMirrorSynchronizer::class);
|
|
foreach (self::DATASETS as $key) {
|
|
$registry->shouldReceive('scheduled')->once()->with($key)->andReturn(true);
|
|
$sync->shouldReceive('sync')->once()->with($key, true, null, 0)->ordered()
|
|
->andReturn(['status' => 'succeeded', 'batches' => 3, 'rows' => 1200]);
|
|
}
|
|
$this->app->instance(BusinessMirrorDatasetRegistry::class, $registry);
|
|
$this->app->instance(BusinessMirrorSynchronizer::class, $sync);
|
|
$this->artisan('business-mirror:sync-supplier-management')->assertSuccessful();
|
|
}
|
|
|
|
public function test_one_failure_does_not_prevent_other_supplier_data_from_refreshing(): void
|
|
{
|
|
config(['upstream_mirrors.refresh_enabled' => true]);
|
|
$registry = Mockery::mock(BusinessMirrorDatasetRegistry::class);
|
|
$sync = Mockery::mock(BusinessMirrorSynchronizer::class);
|
|
foreach (self::DATASETS as $index => $key) {
|
|
$registry->shouldReceive('scheduled')->once()->with($key)->andReturn(true);
|
|
$expectation = $sync->shouldReceive('sync')->once()->with($key, true, null, 0)->ordered();
|
|
if ($index === 0) $expectation->andThrow(new RuntimeException('upstream unavailable'));
|
|
else $expectation->andReturn(['status' => 'succeeded', 'batches' => 1, 'rows' => 5]);
|
|
}
|
|
$this->app->instance(BusinessMirrorDatasetRegistry::class, $registry);
|
|
$this->app->instance(BusinessMirrorSynchronizer::class, $sync);
|
|
$this->artisan('business-mirror:sync-supplier-management')
|
|
->expectsOutputToContain('同步失败')->assertExitCode(1);
|
|
}
|
|
|
|
public function test_local_refresh_disabled_never_reads_upstream(): void
|
|
{
|
|
config(['upstream_mirrors.refresh_enabled' => false]);
|
|
$registry = Mockery::mock(BusinessMirrorDatasetRegistry::class);
|
|
$registry->shouldNotReceive('scheduled');
|
|
$sync = Mockery::mock(BusinessMirrorSynchronizer::class);
|
|
$sync->shouldNotReceive('sync');
|
|
$this->app->instance(BusinessMirrorDatasetRegistry::class, $registry);
|
|
$this->app->instance(BusinessMirrorSynchronizer::class, $sync);
|
|
$this->artisan('business-mirror:sync-supplier-management')->assertSuccessful();
|
|
}
|
|
|
|
public function test_disabled_supplier_datasets_are_not_synced(): void
|
|
{
|
|
config(['upstream_mirrors.refresh_enabled' => true]);
|
|
$registry = Mockery::mock(BusinessMirrorDatasetRegistry::class);
|
|
$registry->shouldReceive('scheduled')->times(4)->andReturn(false);
|
|
$sync = Mockery::mock(BusinessMirrorSynchronizer::class);
|
|
$sync->shouldNotReceive('sync');
|
|
$this->app->instance(BusinessMirrorDatasetRegistry::class, $registry);
|
|
$this->app->instance(BusinessMirrorSynchronizer::class, $sync);
|
|
$this->artisan('business-mirror:sync-supplier-management')->assertSuccessful();
|
|
}
|
|
|
|
public function test_schedule_runs_at_0815_shanghai_even_when_app_timezone_is_utc(): void
|
|
{
|
|
config(['app.installed' => true, 'app.schedule_time' => '09:00', 'app.timezone' => 'UTC']);
|
|
$schedule = new Schedule('UTC');
|
|
(new \ReflectionMethod(\App\Console\Kernel::class, 'schedule'))->invoke($this->app->make(Kernel::class), $schedule);
|
|
$events = collect($schedule->events())
|
|
->filter(fn ($event) => str_contains($event->command ?? '', 'business-mirror:sync-supplier-management'));
|
|
$this->assertCount(1, $events);
|
|
$event = $events->first();
|
|
try {
|
|
foreach (['00:14' => false, '00:15' => true, '00:16' => false] as $time => $due) {
|
|
Carbon::setTestNow(Carbon::parse('2026-10-12 ' . $time . ':00', 'UTC'));
|
|
$this->assertSame($due, $event->isDue($this->app), $time);
|
|
}
|
|
} finally {
|
|
Carbon::setTestNow();
|
|
}
|
|
}
|
|
}
|