121 lines
5.3 KiB
PHP
121 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\EcommerceFinance;
|
|
|
|
use Modules\EcommerceFinance\Repositories\ProductPriceRepository;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
|
|
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
class ProductPriceRepositoryTest extends TestCase
|
|
{
|
|
public function test_filters_are_parameterized_and_page_queries_overfetch_one_row(): void
|
|
{
|
|
$query = $this->createMock(UpstreamReadOnlyQuery::class);
|
|
$query->expects($this->once())->method('select')->willReturnCallback(
|
|
function (string $sql, array $bindings): array {
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
$this->assertStringContainsString('[rpt].[Bulk_Price_Limit]', $sql);
|
|
$this->assertStringContainsString('[product_code] LIKE ?', $sql);
|
|
$this->assertStringContainsString("WHEN 'COMPLETED' THEN N'已完成'", $sql);
|
|
$this->assertStringContainsString("WHEN 'agree' THEN N'已同意'", $sql);
|
|
$this->assertStringContainsString('[process_end_date] < DATEADD(day, 1, CAST(? AS date))', $sql);
|
|
$this->assertStringContainsString('OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY', $sql);
|
|
$this->assertSame(
|
|
['%ABC\\%\\_%', '2026-07-01', '2026-07-31'],
|
|
$bindings,
|
|
);
|
|
|
|
return [
|
|
[
|
|
'barcode' => 'A',
|
|
'minimum_price' => '10.00',
|
|
'price_limit' => '11.50',
|
|
'purchase_price' => '7.25',
|
|
'shipping_fee' => '2.00',
|
|
'jingxi_limit_price' => '9.50',
|
|
],
|
|
[
|
|
'barcode' => 'B',
|
|
'minimum_price' => '',
|
|
'price_limit' => null,
|
|
'purchase_price' => '0.00',
|
|
'shipping_fee' => null,
|
|
'jingxi_limit_price' => '',
|
|
],
|
|
[
|
|
'barcode' => 'C',
|
|
'minimum_price' => '3.00',
|
|
'price_limit' => '4.00',
|
|
'purchase_price' => '2.00',
|
|
'shipping_fee' => '1.00',
|
|
'jingxi_limit_price' => '3.50',
|
|
],
|
|
];
|
|
},
|
|
);
|
|
|
|
$factory = $this->createMock(UpstreamReadOnlyQueryFactory::class);
|
|
$factory->expects($this->once())->method('forSource')->with('operations_replica')->willReturn($query);
|
|
|
|
$result = (new ProductPriceRepository($factory))->paginate([
|
|
'barcode' => 'ABC%_',
|
|
'completed_from' => '2026-07-01',
|
|
'completed_to' => '2026-07-31',
|
|
], 2, 2);
|
|
|
|
$this->assertCount(3, $result['rows']);
|
|
$this->assertSame(10.0, $result['rows'][0]['minimum_price']);
|
|
$this->assertSame(11.5, $result['rows'][0]['price_limit']);
|
|
$this->assertNull($result['rows'][1]['minimum_price']);
|
|
$this->assertSame(0.0, $result['rows'][1]['purchase_price']);
|
|
}
|
|
|
|
public function test_mirror_batch_uses_stable_keyset_cursor_and_bounded_window(): void
|
|
{
|
|
$query = $this->createMock(UpstreamReadOnlyQuery::class);
|
|
$query->expects($this->once())->method('select')->willReturnCallback(
|
|
function (string $sql, array $bindings): array {
|
|
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
|
|
$this->assertStringContainsString('SELECT TOP 200', $sql);
|
|
$this->assertStringContainsString("COALESCE([businessId], '') AS business_id", $sql);
|
|
$this->assertStringContainsString('[process_end_date] > CAST(? AS datetime2(7))', $sql);
|
|
$this->assertStringContainsString('CONVERT(varchar(33), [process_end_date], 126) AS cursor_completed_at', $sql);
|
|
$this->assertStringNotContainsString('OFFSET', $sql);
|
|
$this->assertSame([
|
|
'2026-08-01 00:00:00',
|
|
'2026-08-14 00:00:00',
|
|
'2026-08-10 12:00:00',
|
|
'2026-08-10 12:00:00',
|
|
'B100',
|
|
'2026-08-10 12:00:00',
|
|
'B100',
|
|
'SKU100',
|
|
], $bindings);
|
|
|
|
return [[
|
|
'business_id' => 'B101',
|
|
'barcode' => 'SKU101',
|
|
'completed_at' => '2026-08-10 12:01:00',
|
|
'minimum_price' => '10.25',
|
|
'price_limit' => null,
|
|
'purchase_price' => '8.00',
|
|
'shipping_fee' => '1.00',
|
|
'jingxi_limit_price' => '9.00',
|
|
]];
|
|
},
|
|
);
|
|
$factory = $this->createMock(UpstreamReadOnlyQueryFactory::class);
|
|
$factory->method('forSource')->with('operations_replica')->willReturn($query);
|
|
|
|
$rows = (new ProductPriceRepository($factory))->mirrorBatch([
|
|
'completed_at' => '2026-08-10 12:00:00',
|
|
'business_id' => 'B100',
|
|
'barcode' => 'SKU100',
|
|
], '2026-08-01 00:00:00', '2026-08-14 00:00:00', 200);
|
|
|
|
$this->assertSame('B101', $rows[0]['business_id']);
|
|
$this->assertSame(10.25, $rows[0]['minimum_price']);
|
|
}
|
|
}
|