CaiWuXiTong/tests/Unit/EcommerceFinance/GoodsProfitAfsRepositoryTest.php
renshen 537aa8d21e 提前跳过未覆盖月份的宽表查询 (#580)
6 月查询按日期边界直接跳过商品利润宽表
2026-10-26 11:25:11 +08:00

176 lines
8.2 KiB
PHP

<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Modules\EcommerceFinance\Repositories\GoodsProfitAfsRepository;
use Modules\EcommerceFinance\Services\GoodsProfitAfsLookupSchema;
use Tests\TestCase;
class GoodsProfitAfsRepositoryTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config(['database.connections.business_mirror' => [
'driver' => 'sqlite', 'database' => ':memory:', 'prefix' => '',
], 'upstream_mirrors.connection' => 'business_mirror']);
DB::purge('business_mirror');
$schema = Schema::connection('business_mirror');
$schema->create(GoodsProfitAfsLookupSchema::TABLE, function (Blueprint $table): void {
$table->integer('id')->primary();
foreach ([
'undefined1', 'undefined2', 'undefined7', 'undefined8', 'undefined10',
'undefined12', 'undefined13', 'undefined20', 'undefined21', 'undefined25',
'_mirror_afs_order_time',
] as $column) {
$table->string($column)->nullable();
}
});
$schema->create('ops_jst_goods_profit_kpi_items_afs_schemas', function (Blueprint $table): void {
$table->integer('id'); $table->string('column'); $table->string('name');
});
$schema->create('business_mirror_table_states', function (Blueprint $table): void {
$table->string('dataset_key'); $table->dateTime('initial_completed_at')->nullable();
});
$db = DB::connection('business_mirror');
$db->table('business_mirror_table_states')->insert([
'dataset_key' => GoodsProfitAfsRepository::MAIN_DATASET, 'initial_completed_at' => '2026-10-01 00:00:00',
]);
foreach ([
'undefined1' => '内部订单号', 'undefined2' => '线上订单号', 'undefined7' => '订单时间',
'undefined8' => '店铺名称', 'undefined10' => '商品编码',
'undefined12' => '店铺商品编码', 'undefined13' => '店铺款式编码',
'undefined20' => '商品数量', 'undefined25' => '商品金额',
] as $column => $name) {
$db->table('ops_jst_goods_profit_kpi_items_afs_schemas')->insert(['id' => (int) substr($column, 9), 'column' => $column, 'name' => $name]);
}
$db->getPdo()->sqliteCreateFunction('STR_TO_DATE', static function (?string $date): ?string {
return $date === null || trim($date) === '' ? null : date('Y-m-d H:i:s', strtotime($date));
});
for ($id = 1; $id <= 60; $id++) {
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
'id' => $id, 'undefined1' => 'ORDER-' . $id, 'undefined2' => 'ONLINE-' . $id,
'undefined7' => sprintf('2026/10/19 1:%d:00', $id - 1),
'_mirror_afs_order_time' => sprintf('2026-10-19 01:%02d:00', $id - 1),
'undefined8' => $id % 2 ? '店铺甲' : '店铺乙', 'undefined10' => 'SKU_1', 'undefined25' => '123.45',
]);
}
}
public function test_next_page_does_not_skip_the_lookahead_row(): void
{
$repo = new GoodsProfitAfsRepository();
$filters = ['from' => '2026-10-19', 'to' => '2026-10-19'];
$pages = array_map(fn ($page) => $repo->paginate($filters, $page, 25), [1, 2, 3]);
$orders = array_merge(...array_map(fn ($page) => array_column($page['rows'], 'internal_order_no'), $pages));
$this->assertSame(array_map(fn ($id) => 'ORDER-' . $id, range(60, 1)), $orders);
$this->assertSame([true, true, false], array_column($pages, 'has_more'));
$this->assertSame(123.45, $pages[0]['rows'][0]['product_amount']);
}
public function test_dates_before_goods_profit_coverage_skip_mirror_queries(): void
{
$db = DB::connection('business_mirror');
$db->flushQueryLog();
$db->enableQueryLog();
$covered = (new GoodsProfitAfsRepository())->covers([
'from' => '2026-06-01',
'to' => '2026-06-30',
'order_no' => '',
]);
$this->assertFalse($covered);
$this->assertSame([], $db->getQueryLog());
}
public function test_date_boundaries_and_multi_shop_filters_preserve_values(): void
{
$db = DB::connection('business_mirror');
foreach ([61 => ['2026/10/19 23:59:59', '2026-10-19 23:59:59'],
62 => ['2026/10/20 0:00:00', '2026-10-20 00:00:00'],
63 => ['2026/8/23 14:58:51', '2026-08-23 14:58:51']] as $id => [$raw, $parsed]) {
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
'id' => $id, 'undefined1' => 'ORDER-' . $id, 'undefined7' => $raw,
'_mirror_afs_order_time' => $parsed, 'undefined8' => '店铺甲', 'undefined25' => '-31.20',
]);
}
$db->enableQueryLog();
$result = (new GoodsProfitAfsRepository())->paginate([
'from' => '2026-10-19', 'to' => '2026-10-19', 'shop_names' => ['店铺甲', '店铺乙'],
], 1, 100);
$this->assertCount(61, $result['rows']);
$this->assertSame('ORDER-61', $result['rows'][0]['internal_order_no']);
$this->assertSame(-31.2, $result['rows'][0]['product_amount']);
$this->assertStringNotContainsString('STR_TO_DATE', implode(' ', array_column($db->getQueryLog(), 'query')));
}
public function test_missing_lookup_keeps_the_original_parser(): void
{
Schema::connection('business_mirror')->table(GoodsProfitAfsLookupSchema::TABLE, function (Blueprint $table): void {
$table->dropColumn('_mirror_afs_order_time');
});
$result = (new GoodsProfitAfsRepository())->paginate(['from' => '2026-10-19', 'to' => '2026-10-19'], 1, 25);
$this->assertCount(25, $result['rows']);
$this->assertSame('ORDER-60', $result['rows'][0]['internal_order_no']);
}
public function test_moved_dynamic_header_does_not_use_the_old_lookup_column(): void
{
Schema::connection('business_mirror')->table(GoodsProfitAfsLookupSchema::TABLE, function (Blueprint $table): void {
$table->string('undefined9')->nullable();
});
$db = DB::connection('business_mirror');
$db->table(GoodsProfitAfsLookupSchema::TABLE)->update(['undefined9' => '2026/8/23 14:58:51']);
$db->table('ops_jst_goods_profit_kpi_items_afs_schemas')->where('name', '订单时间')->update(['column' => 'undefined9']);
$result = (new GoodsProfitAfsRepository())->paginate(['from' => '2026-08-23', 'to' => '2026-08-23'], 1, 25);
$this->assertCount(25, $result['rows']);
$this->assertSame('2026/8/23 14:58:51', $result['rows'][0]['order_time']);
}
public function test_positive_component_rows_are_returned_for_candidate_orders(): void
{
$db = DB::connection('business_mirror');
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
'id' => 100,
'undefined1' => 'ORDER-100',
'undefined2' => 'ONLINE-100',
'undefined7' => '2026/9/1 10:00:00',
'undefined8' => '测试店铺',
'undefined10' => 'INTERNAL-COMPONENT',
'undefined12' => 'SHOP-SKU',
'undefined13' => 'SHOP-ITEM',
'undefined20' => '2',
'undefined25' => '199.98',
]);
$db->table(GoodsProfitAfsLookupSchema::TABLE)->insert([
'id' => 101,
'undefined1' => 'ORDER-100',
'undefined2' => 'ONLINE-100',
'undefined7' => '',
'undefined8' => '测试店铺',
'undefined10' => 'ZERO-PLACEHOLDER',
'undefined12' => 'SHOP-SKU',
'undefined13' => 'SHOP-ITEM',
'undefined20' => '0',
'undefined25' => '0',
]);
$rows = (new GoodsProfitAfsRepository())->positiveComponentRowsForOrders(['ONLINE-100']);
$this->assertSame([[
'online_order_no' => 'ONLINE-100',
'shop_name' => '测试店铺',
'shop_sku_id' => 'SHOP-SKU',
'shop_i_id' => 'SHOP-ITEM',
'product_code' => 'INTERNAL-COMPONENT',
'product_quantity' => 2.0,
'product_amount' => 199.98,
]], $rows);
}
}