CaiWuXiTong/tests/Unit/EcommerceFinance/OrderDataRepositoryTest.php

175 lines
7.2 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Modules\EcommerceFinance\Repositories\OrderDataRepository;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery;
use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory;
use PHPUnit\Framework\TestCase;
class OrderDataRepositoryTest extends TestCase
{
public function test_after_sales_uses_fixed_joins_parameterized_filters_and_overfetch_pagination(): void
{
$query = $this->createMock(UpstreamReadOnlyQuery::class);
$call = 0;
$query->expects($this->exactly(2))->method('select')->willReturnCallback(
function (string $sql, array $bindings) use (&$call): array {
$call++;
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
if ($call === 2) {
$this->assertStringContainsString('[rpt].[jst_returnAndRefundInfo]', $sql);
$this->assertSame(['1'], $bindings);
return [[
'internal_order_no' => '1',
'after_sales_id' => 'AF-1',
'after_sales_time' => '2026-08-02 12:00:00',
'sub_order_no' => 'SUB-1',
'product_code' => 'SKU-1',
'application_quantity' => '1',
'application_amount' => '6.00',
'return_quantity' => '1',
'return_amount' => '6.00',
]];
}
$this->assertStringContainsString('[rpt].[jst_Orders]', $sql);
$this->assertStringContainsString('[rpt].[jst_OrderItem]', $sql);
$this->assertStringContainsString('OFFSET 2 ROWS FETCH NEXT 3 ROWS ONLY', $sql);
$this->assertStringNotContainsString('COUNT(*) OVER', $sql);
$this->assertSame([
'2026-08-01',
'2026-08-02',
'%SO\%\_%',
'%SO\%\_%',
'%SO\%\_%',
'%JD%',
'%SKU%',
'%SKU%',
'%SKU%',
], $bindings);
return [[
'internal_order_no' => '1',
'sub_order_no' => 'SUB-1',
'product_code' => 'SKU-1',
'shop_site' => 'jd',
'shop_style_code' => '1001',
'send_time' => '2026-08-02 10:00:00',
'unit_cost' => '3.00',
'product_amount' => '12.34',
'product_quantity' => '2',
'actual_shipped_amount' => '12.34',
'actual_shipped_quantity' => '2',
'actual_shipped_cost' => '6.00',
'pre_application_quantity' => '0',
'pre_application_amount' => '0',
'pre_application_cost' => '0',
'pre_return_quantity' => '0',
'pre_return_amount' => '0',
'pre_return_cost' => '0',
'pre_refund_amount' => '0',
'pre_refund_cost' => '0',
'pre_platform_subsidy' => '0',
'post_application_quantity' => '0',
'post_application_amount' => '0',
'post_application_cost' => '0',
'post_return_quantity' => '0',
'post_return_amount' => '0',
'post_return_cost' => '0',
'post_refund_amount' => '0',
'post_refund_cost' => '0',
'post_platform_subsidy' => '0',
'defective_quantity' => '0',
]];
},
);
$result = (new OrderDataRepository($this->factory($query)))->afterSales([
'from' => '2026-08-01',
'to' => '2026-08-02',
'order_no' => 'SO%_',
'shop_name' => 'JD',
'sku_id' => 'SKU',
], 2, 2);
$this->assertCount(1, $result['rows']);
$this->assertSame(12.34, $result['rows'][0]['product_amount']);
$this->assertSame(2.0, $result['rows'][0]['product_quantity']);
$this->assertSame('https://item.jd.com/1001.html', $result['rows'][0]['product_link']);
$this->assertSame('AF-1', $result['rows'][0]['after_sales_no']);
$this->assertSame(1.0, $result['rows'][0]['post_return_quantity']);
$this->assertNull($result['rows'][0]['account_500112']);
$this->assertNull($result['rows'][0]['account_8001201']);
}
public function test_promotion_expenses_use_one_statistics_date_and_map_only_the_page_rows(): void
{
$query = $this->createMock(UpstreamReadOnlyQuery::class);
$call = 0;
$query->expects($this->exactly(2))->method('select')->willReturnCallback(
function (string $sql, array $bindings) use (&$call): array {
$call++;
UpstreamReadOnlyQuery::assertReadOnlySql($sql);
if ($call === 2) {
$this->assertStringContainsString('[rpt].[jst_skumap]', $sql);
$this->assertSame(['ITEM-1'], $bindings);
return [[
'shop_style_code' => 'ITEM-1',
'shop_name' => 'JD',
'product_code' => 'SKU-1',
'style_code' => 'STYLE-1',
'shop_product_code' => 'SHOP-SKU-1',
'online_color_spec' => '黑色',
]];
}
$this->assertStringContainsString('[rpt].[ads_itemid_sales_cost_ratio_v2_di]', $sql);
$this->assertStringContainsString('OFFSET 3 ROWS FETCH NEXT 4 ROWS ONLY', $sql);
$this->assertStringContainsString('FROM paged p', $sql);
$this->assertStringNotContainsString('SUM(c.[push_fee])', $sql);
$this->assertStringNotContainsString('COUNT(*) OVER', $sql);
$this->assertSame([
'2026-08-09',
'%JD%',
'%SKU\_%',
'%SKU\_%',
'%SKU\_%',
'%SKU\_%',
], $bindings);
return [[
'shop_name' => 'JD',
'shop_style_code' => 'ITEM-1',
'promotion_fee' => '9.05',
]];
},
);
$result = (new OrderDataRepository($this->factory($query)))->promotionExpenses([
'date' => '2026-08-09',
'shop_name' => 'JD',
'sku_id' => 'SKU_',
], 2, 3);
$this->assertSame('2026-08-09', $result['date']);
$this->assertSame(9.05, $result['rows'][0]['promotion_fee']);
$this->assertSame('SKU-1', $result['rows'][0]['product_code']);
}
private function factory(UpstreamReadOnlyQuery $query): UpstreamReadOnlyQueryFactory
{
$factory = $this->createMock(UpstreamReadOnlyQueryFactory::class);
$factory->expects($this->once())
->method('forSource')
->with('operations_replica')
->willReturn($query);
return $factory;
}
}