CaiWuXiTong/tests/Unit/EcommerceFinance/UpstreamBusinessInformationTest.php
WuYongJie eb1036d0c3 整合业务资料查询与表格交互 (#266)
整合业务资料字段查询、排序、列设置与导出,并保留最新主线的数据隔离和报表修复。
2026-09-24 15:10:33 +08:00

135 lines
5.4 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use App\Business\UpstreamBusinessInformation;
use Closure;
use Mockery;
use Modules\EcommerceFinance\Repositories\BusinessInformationMirrorRepository;
use Modules\EcommerceFinance\Repositories\InstallationDetailMirrorRepository;
use Modules\EcommerceFinance\Services\UpstreamQueryCache;
use Modules\EcommerceFinance\Services\UpstreamQueryCacheFactory;
use Tests\TestCase;
class UpstreamBusinessInformationTest extends TestCase
{
/**
* @dataProvider businessInformationPages
*/
public function test_local_direct_page_resolver_passes_pagination_to_its_fixed_snapshot(
string $section,
string $page,
string $scope,
): void {
config(['upstreams.local_configuration.enabled' => true]);
$cache = new class extends UpstreamQueryCache {
public array $calls = [];
public function __construct()
{
}
public function remember(string $scope, array $parameters, Closure $resolver): mixed
{
$this->calls[] = compact('scope', 'parameters');
return $resolver();
}
};
$caches = new class($cache) extends UpstreamQueryCacheFactory {
public function __construct(private readonly UpstreamQueryCache $cache)
{
}
public function forSource(string $source): UpstreamQueryCache
{
return $this->cache;
}
};
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
$mirror->shouldReceive('ready')->once()->with($scope)->andReturnFalse();
$information = new class($caches, $mirror, Mockery::mock(InstallationDetailMirrorRepository::class)) extends UpstreamBusinessInformation {
public array $snapshots = [];
public function snapshot(string $scope, array $parameters): array
{
$this->snapshots[] = compact('scope', 'parameters');
return ['data' => [], 'total' => 0];
}
};
$this->app['request']->merge(['page' => 3]);
$paginator = $information->paginate($section, $page, 25);
$expected = ['scope' => $scope, 'parameters' => ['page' => 3, 'perPage' => 25]];
$this->assertSame(3, $paginator->currentPage());
$this->assertSame($expected, $cache->calls[0]);
$this->assertSame($expected, $information->snapshots[0]);
}
/**
* @dataProvider businessInformationPages
*/
public function test_ready_business_mirror_is_used_without_registering_a_page_snapshot(
string $section,
string $page,
string $scope,
): void {
config(['operations_replica.enabled' => false, 'upstreams.stored_configuration.enabled' => false]);
$cache = new class extends UpstreamQueryCache {
public function __construct() {}
public function remember(string $scope, array $parameters, Closure $resolver): mixed
{
throw new \RuntimeException('镜像就绪后不应再读取分页快照。');
}
};
$caches = new class($cache) extends UpstreamQueryCacheFactory {
public function __construct(private readonly UpstreamQueryCache $cache) {}
public function forSource(string $source): UpstreamQueryCache { return $this->cache; }
};
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
$mirror->shouldReceive('ready')->once()->with($scope)->andReturnTrue();
$mirror->shouldReceive('paginate')->once()->with($scope, 2, 25, [])->andReturn([
'data' => [['id' => 10]],
'total' => 51,
]);
$this->app['request']->merge(['page' => 2]);
$paginator = (new UpstreamBusinessInformation($caches, $mirror, Mockery::mock(InstallationDetailMirrorRepository::class)))
->paginate($section, $page, 25);
$this->assertSame(2, $paginator->currentPage());
$this->assertSame(51, $paginator->total());
$this->assertSame(10, $paginator->items()[0]->id);
}
public function test_bootstrap_without_mirror_explains_shared_connection_instead_of_requesting_upstream_credentials(): void
{
config(['system_database.mode' => 'bootstrap', 'upstreams.local_configuration.enabled' => false]);
$caches = Mockery::mock(UpstreamQueryCacheFactory::class);
$caches->shouldNotReceive('forSource');
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
$mirror->shouldReceive('ready')->once()->with('store-information.read')->andReturnFalse();
$this->expectException(\Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException::class);
$this->expectExceptionMessage('无需另配上游 SQL Server');
(new UpstreamBusinessInformation($caches, $mirror, Mockery::mock(InstallationDetailMirrorRepository::class)))
->paginate('store-management', 'basic-information');
}
public static function businessInformationPages(): array
{
return [
'company' => ['company-management', 'basic-information', 'company-information.read'],
'store' => ['store-management', 'basic-information', 'store-information.read'],
'trademark' => ['trademark-management', 'information', 'trademark-information.read'],
];
}
}