CaiWuXiTong/tests/Unit/EcommerceFinance/SupplierPayableRepositoryTest.php
renshen 433c8ab762 修复供应商赔偿明细数据来源 (#11)
接手 sumu 本地任务,复用既有只读 Repository 契约,将赔偿明细切换到 dbo.fys_supplierPaymentSummary,并按附件保留五列表头。
2026-08-06 16:26:51 +08:00

111 lines
4.1 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Modules\EcommerceFinance\Repositories\SupplierPayableRepository;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
use PHPUnit\Framework\TestCase;
class SupplierPayableRepositoryTest extends TestCase
{
public function test_compensation_queries_use_the_supplier_payment_summary_contract(): void
{
$query = $this->createMock(UpstreamReadOnlyQuery::class);
$bindings = ['%Factory\\%\\_%', '2026-07', '2026-08'];
$query->expects($this->once())
->method('scalar')
->with(
$this->callback(function (string $sql): bool {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
$this->assertStringContainsString('[dbo].[fys_supplierPaymentSummary]', $sql);
$this->assertStringContainsString('[Totalindemnity] <> 0', $sql);
return true;
}),
$bindings,
)
->willReturn(1);
$query->expects($this->once())
->method('select')
->with(
$this->callback(function (string $sql): bool {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
$this->assertStringContainsString('[Totalindemnity] AS decimal(18,2)', $sql);
$this->assertStringContainsString('[remarks] AS remark', $sql);
$this->assertStringContainsString('OFFSET 25 ROWS FETCH NEXT 25 ROWS ONLY', $sql);
$this->assertStringNotContainsString('fys_paper_factory_compensation_detail', $sql);
return true;
}),
$bindings,
)
->willReturn([[
'month' => '2026-07',
'supplier' => 'Factory%_',
'amount' => '12.50',
'reason' => 'Reason',
'remark' => 'Remark',
]]);
$result = $this->repository($query)->compensationDetails([
'supplier' => 'Factory%_',
'month_from' => '2026-07',
'month_to' => '2026-08',
], 2, 25);
$this->assertSame(1, $result['total']);
$this->assertSame(12.5, $result['data'][0]['amount']);
$this->assertSame('Remark', $result['data'][0]['remark']);
}
public function test_compensation_summary_and_options_are_bounded_read_only_queries(): void
{
$query = $this->createMock(UpstreamReadOnlyQuery::class);
$query->expects($this->once())
->method('first')
->with(
$this->callback(function (string $sql): bool {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
$this->assertStringContainsString('SUM([Totalindemnity])', $sql);
return true;
}),
[],
)
->willReturn(['total_amount' => '20.25', 'total_count' => '2']);
$query->expects($this->once())
->method('select')
->with($this->callback(function (string $sql): bool {
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
$this->assertStringContainsString('DISTINCT TOP 200', $sql);
return true;
}))
->willReturn([['value' => 'Supplier A']]);
$repository = $this->repository($query);
$this->assertSame(
['totalAmount' => 20.25, 'totalCount' => 2],
$repository->compensationDetailSummary([]),
);
$this->assertSame(
['suppliers' => ['Supplier A']],
$repository->filterOptionsForCompensation(),
);
}
private function repository(UpstreamReadOnlyQuery $query): SupplierPayableRepository
{
$factory = $this->createMock(UpstreamReadOnlyQueryFactory::class);
$factory->expects($this->once())
->method('forSource')
->with('jiansun')
->willReturn($query);
return new SupplierPayableRepository($factory);
}
}