228 lines
8.6 KiB
PHP
228 lines
8.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Business;
|
|
|
|
use App\Models\Auth\Permission;
|
|
use App\Models\Auth\Role;
|
|
use App\Models\Auth\User;
|
|
use App\Utilities\BusinessNavigation;
|
|
use App\Utilities\SidebarPermissions;
|
|
use Modules\EcommerceFinance\Repositories\NonJingxiRefundMirrorRepository;
|
|
use Tests\Feature\FeatureTestCase;
|
|
|
|
class WarningPageTest extends FeatureTestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
}
|
|
|
|
public function test_warning_page_contains_after_sales_return_refund_child(): void
|
|
{
|
|
$warnings = collect(BusinessNavigation::all())
|
|
->firstWhere('slug', 'other')['pages'];
|
|
$warnings = collect($warnings)->firstWhere('slug', 'warnings');
|
|
|
|
$this->assertSame(
|
|
['warning-overview', 'after-sales-return-refund'],
|
|
array_column($warnings['children'], 'slug'),
|
|
);
|
|
$this->assertSame(
|
|
['预警总览', '售后退货退款'],
|
|
array_column($warnings['children'], 'title'),
|
|
);
|
|
}
|
|
|
|
public function test_warning_children_render_and_are_linked_from_the_sidebar(): void
|
|
{
|
|
$this->loginAs();
|
|
$this->bindReadyRefundMirror();
|
|
|
|
$overviewUrl = route('business.pages.show', [
|
|
'section' => 'other',
|
|
'page' => 'warning-overview',
|
|
]);
|
|
$afterSalesRefundUrl = route('business.pages.show', [
|
|
'section' => 'other',
|
|
'page' => 'after-sales-return-refund',
|
|
]);
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'other',
|
|
'page' => 'warnings',
|
|
]))
|
|
->assertRedirect($overviewUrl);
|
|
|
|
$this->get($overviewUrl)
|
|
->assertOk()
|
|
->assertSeeText('预警总览')
|
|
->assertSeeText('售后退货退款')
|
|
->assertSeeText('风险等级')
|
|
->assertSee($afterSalesRefundUrl, false);
|
|
|
|
$this->get($afterSalesRefundUrl)
|
|
->assertOk()
|
|
->assertSeeText('售后退货退款')
|
|
->assertSeeText('聚水潭售后数据已接入')
|
|
->assertSeeText('AS-WARNING-001')
|
|
->assertSeeText('WB-WARNING-001')
|
|
->assertSeeText('售后测试店')
|
|
->assertSeeText('退款总金额')
|
|
->assertSeeText('运单号')
|
|
->assertSee('data-refund-page="after-sales-warning"', false)
|
|
->assertSee('action="' . $afterSalesRefundUrl . '"', false)
|
|
->assertSee('name="waybill_no"', false)
|
|
->assertSee(route('business.other.after-sales-return-refund.export'), false)
|
|
->assertDontSee(route('business.refunds.non-jingxi-refund-data.export'), false)
|
|
->assertDontSeeText('售后退货退款预警规则待接入');
|
|
}
|
|
|
|
public function test_existing_warning_page_permission_keeps_both_child_entries(): void
|
|
{
|
|
$regular = $this->regularAccount();
|
|
$subject = 'user_' . $regular->id;
|
|
|
|
setting()->set('system.sidebar_permissions', [
|
|
'configured' => [$subject],
|
|
'subjects' => [$subject => ['other/warnings']],
|
|
]);
|
|
|
|
$other = collect(SidebarPermissions::navigationFor($regular))
|
|
->firstWhere('slug', 'other');
|
|
$warnings = collect($other['pages'])->firstWhere('slug', 'warnings');
|
|
|
|
$this->assertSame(
|
|
['warning-overview', 'after-sales-return-refund'],
|
|
array_column($warnings['children'], 'slug'),
|
|
);
|
|
|
|
$this->bindReadyRefundMirror();
|
|
|
|
$this->loginAs($regular)
|
|
->get(route('business.pages.show', [
|
|
'section' => 'other',
|
|
'page' => 'after-sales-return-refund',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('聚水潭售后数据已接入')
|
|
->assertSeeText('AS-WARNING-001');
|
|
}
|
|
|
|
public function test_warning_page_exports_filtered_rows_without_refund_page_permission(): void
|
|
{
|
|
$regular = $this->regularAccount();
|
|
$subject = 'user_' . $regular->id;
|
|
setting()->set('system.sidebar_permissions', [
|
|
'configured' => [$subject],
|
|
'subjects' => [$subject => ['other/warnings']],
|
|
]);
|
|
|
|
$filters = [
|
|
'from' => '2026-10-23',
|
|
'to' => '2026-10-29',
|
|
'order_no' => 'ORDER-WARNING-001',
|
|
'waybill_no' => 'WB-WARNING-001',
|
|
'shop_name' => '售后测试店',
|
|
'sku_id' => 'SKU-WARNING-001',
|
|
];
|
|
$repository = \Mockery::mock(NonJingxiRefundMirrorRepository::class);
|
|
$repository->shouldReceive('available', 'ready', 'queryReady')->andReturnTrue();
|
|
$repository->shouldReceive('exportRows')->once()->with($filters)->andReturn([(object) [
|
|
'Id' => 9001,
|
|
'refundDate' => '2026-10-28 10:00:00.123456',
|
|
'waybillNo' => 'WB-WARNING-001',
|
|
'outer_as_id' => 'AS-WARNING-001',
|
|
'shop_name' => '售后测试店',
|
|
'sku_id' => 'SKU-WARNING-001',
|
|
]]);
|
|
$this->app->instance(NonJingxiRefundMirrorRepository::class, $repository);
|
|
|
|
$response = $this->loginAs($regular)->get(route(
|
|
'business.other.after-sales-return-refund.export',
|
|
$filters + ['columns' => 'refundDate,waybillNo,outer_as_id,shop_name,sku_id'],
|
|
));
|
|
|
|
$response->assertOk()->assertDownload(
|
|
'after_sales_refund_warning_2026-10-23_2026-10-29.csv'
|
|
);
|
|
$content = $response->streamedContent();
|
|
$lines = preg_split('/\r?\n/', trim($content));
|
|
$this->assertSame(
|
|
['退款日期', '运单号', '外部售后单号', '店铺名称', 'SKU编码'],
|
|
str_getcsv(ltrim($lines[0], "\xEF\xBB\xBF")),
|
|
);
|
|
$this->assertSame(
|
|
['2026-10-28 10:00:00', "'WB-WARNING-001", "'AS-WARNING-001", '售后测试店', "'SKU-WARNING-001"],
|
|
str_getcsv($lines[1]),
|
|
);
|
|
}
|
|
|
|
private function regularAccount(): User
|
|
{
|
|
$name = 'fixture-warning-page-' . User::count();
|
|
$user = User::create([
|
|
'name' => $name,
|
|
'email' => $name . '@example.test',
|
|
'password' => 'fixture-unused-password',
|
|
'enabled' => true,
|
|
'locale' => 'zh-CN',
|
|
'landing_page' => 'dashboard',
|
|
]);
|
|
$user->roles()->attach(Role::where('name', 'user')->firstOrFail()->id);
|
|
$user->permissions()->attach(Permission::where('name', 'read-admin-panel')->firstOrFail()->id);
|
|
$user->companies()->attach($this->company->id);
|
|
|
|
return $user;
|
|
}
|
|
|
|
private function bindReadyRefundMirror(): void
|
|
{
|
|
$states = [
|
|
NonJingxiRefundMirrorRepository::INFO_DATASET => [
|
|
'status' => 'succeeded',
|
|
'initial_completed_at' => '2026-10-01 00:00:00',
|
|
],
|
|
NonJingxiRefundMirrorRepository::ITEM_DATASET => [
|
|
'status' => 'succeeded',
|
|
'initial_completed_at' => '2026-10-01 00:00:00',
|
|
],
|
|
];
|
|
$repository = \Mockery::mock(NonJingxiRefundMirrorRepository::class);
|
|
$repository->shouldReceive('available')->once()->andReturnTrue();
|
|
$repository->shouldReceive('states')->once()->andReturn($states);
|
|
$repository->shouldReceive('syncStatus')->once()->with($states)->andReturn([
|
|
'code' => 'healthy',
|
|
'last_succeeded_at' => '2026-10-29 09:00:00',
|
|
]);
|
|
$repository->shouldReceive('ready')->once()->andReturnTrue();
|
|
$repository->shouldReceive('queryReady')->once()->andReturnTrue();
|
|
$repository->shouldReceive('paginate')->once()->andReturn([
|
|
'data' => [(object) [
|
|
'Id' => 9001,
|
|
'refundDate' => '2026-10-28 10:00:00',
|
|
'dataSource' => '售后资料',
|
|
'detailStatus' => '已关联',
|
|
'as_id' => 8001,
|
|
'outer_as_id' => 'AS-WARNING-001',
|
|
'waybillNo' => 'WB-WARNING-001',
|
|
'o_id' => 'ORDER-WARNING-001',
|
|
'so_id' => 'SUB-WARNING-001',
|
|
'type' => '退货退款',
|
|
'shop_name' => '售后测试店',
|
|
'platform' => '天猫',
|
|
'totalRefundMoney' => 128.5,
|
|
'sku_id' => 'SKU-WARNING-001',
|
|
'detailRefundMoney' => 128.5,
|
|
'refundQty' => 1,
|
|
'status' => '退款完成',
|
|
]],
|
|
'total' => 1,
|
|
]);
|
|
$this->app->instance(NonJingxiRefundMirrorRepository::class, $repository);
|
|
}
|
|
}
|