100 lines
5.0 KiB
PHP
100 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Console;
|
|
|
|
use Mockery;
|
|
use Modules\EcommerceFinance\Contracts\BusinessMirrorDataset;
|
|
use Modules\EcommerceFinance\Repositories\GenericBusinessMirrorRepository;
|
|
use Modules\EcommerceFinance\Repositories\ProductCatalogMirrorRepository;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorDatasetRegistry;
|
|
use Modules\EcommerceFinance\Services\BusinessMirrorSynchronizer;
|
|
use Tests\TestCase;
|
|
|
|
class BusinessMirrorScheduleTest extends TestCase
|
|
{
|
|
public function test_unapproved_first_sync_is_skipped(): void
|
|
{
|
|
config(['upstream_mirrors.refresh_enabled' => true]);
|
|
$dataset = Mockery::mock(BusinessMirrorDataset::class);
|
|
$registry = Mockery::mock(BusinessMirrorDatasetRegistry::class);
|
|
$registry->shouldReceive('all')->once()->andReturn(['pending' => $dataset]);
|
|
$registry->shouldReceive('scheduled')->with('pending')->andReturn(true);
|
|
$registry->shouldReceive('automaticInitialSyncAllowed')->with('pending')->andReturn(false);
|
|
$mirror = Mockery::mock(GenericBusinessMirrorRepository::class);
|
|
$mirror->shouldReceive('state')->with($dataset)->andReturn(null);
|
|
$sync = Mockery::mock(BusinessMirrorSynchronizer::class);
|
|
$sync->shouldNotReceive('sync');
|
|
$this->app->instance(BusinessMirrorDatasetRegistry::class, $registry);
|
|
$this->app->instance(GenericBusinessMirrorRepository::class, $mirror);
|
|
$this->app->instance(BusinessMirrorSynchronizer::class, $sync);
|
|
$this->artisan('business-mirror:sync-tables')->assertSuccessful();
|
|
}
|
|
|
|
public function test_catchup_and_routine_datasets_both_receive_a_turn(): void
|
|
{
|
|
config(['upstream_mirrors.refresh_enabled' => true, 'upstream_pipeline.sync.max_datasets' => 2]);
|
|
$registry = Mockery::mock(BusinessMirrorDatasetRegistry::class);
|
|
$mirror = Mockery::mock(GenericBusinessMirrorRepository::class);
|
|
$objects = [];
|
|
foreach (['routine-a', 'routine-b', 'catchup-z'] as $key) {
|
|
$objects[$key] = Mockery::mock(BusinessMirrorDataset::class);
|
|
$registry->shouldReceive('scheduled')->with($key)->andReturn(true);
|
|
$mirror->shouldReceive('state')->with($objects[$key])->andReturn([
|
|
'initial_completed_at' => '2026-08-01 00:00:00', 'last_attempted_at' => '2026-08-01 00:00:00',
|
|
'status' => $key === 'catchup-z' ? 'running' : 'succeeded',
|
|
]);
|
|
}
|
|
$registry->shouldReceive('all')->andReturn($objects);
|
|
$sync = Mockery::mock(BusinessMirrorSynchronizer::class);
|
|
$result = ['status' => 'succeeded', 'batches' => 1, 'rows' => 1];
|
|
$sync->shouldReceive('sync')->once()->with('routine-a', false, null, null)->ordered()->andReturn($result);
|
|
$sync->shouldReceive('sync')->once()->with('catchup-z', false, null, 6)->ordered()->andReturn($result);
|
|
$this->app->instance(BusinessMirrorDatasetRegistry::class, $registry);
|
|
$this->app->instance(GenericBusinessMirrorRepository::class, $mirror);
|
|
$this->app->instance(BusinessMirrorSynchronizer::class, $sync);
|
|
$this->artisan('business-mirror:sync-tables')->assertSuccessful();
|
|
}
|
|
|
|
public function test_generic_rotation_excludes_datasets_with_a_dedicated_scheduler(): void
|
|
{
|
|
config([
|
|
'upstream_mirrors.refresh_enabled' => true,
|
|
'upstream_mirrors.table_sync.dedicated_datasets' => [
|
|
ProductCatalogMirrorRepository::DATASET_KEY,
|
|
],
|
|
]);
|
|
|
|
$catalog = Mockery::mock(BusinessMirrorDataset::class);
|
|
$other = Mockery::mock(BusinessMirrorDataset::class);
|
|
$datasets = Mockery::mock(BusinessMirrorDatasetRegistry::class);
|
|
$datasets->shouldReceive('all')->once()->andReturn([
|
|
ProductCatalogMirrorRepository::DATASET_KEY => $catalog,
|
|
'test.dbo.other' => $other,
|
|
]);
|
|
$datasets->shouldReceive('scheduled')->once()->with('test.dbo.other')->andReturn(true);
|
|
$mirror = Mockery::mock(GenericBusinessMirrorRepository::class);
|
|
$mirror->shouldReceive('state')->once()->with($other)->andReturn([
|
|
'initial_completed_at' => '2026-08-01 02:00:00',
|
|
'last_attempted_at' => '2026-08-15 01:00:00',
|
|
]);
|
|
$mirror->shouldNotReceive('state')->with($catalog);
|
|
$synchronizer = Mockery::mock(BusinessMirrorSynchronizer::class);
|
|
$synchronizer->shouldReceive('sync')
|
|
->once()
|
|
->with('test.dbo.other', false, null, null)
|
|
->andReturn([
|
|
'status' => 'succeeded',
|
|
'mode' => 'incremental',
|
|
'batches' => 1,
|
|
'rows' => 10,
|
|
'dataset' => 'test.dbo.other',
|
|
]);
|
|
|
|
$this->app->instance(BusinessMirrorDatasetRegistry::class, $datasets);
|
|
$this->app->instance(GenericBusinessMirrorRepository::class, $mirror);
|
|
$this->app->instance(BusinessMirrorSynchronizer::class, $synchronizer);
|
|
|
|
$this->artisan('business-mirror:sync-tables')->assertSuccessful();
|
|
}
|
|
}
|