Files
saasshop/tests/Feature/AdminBillingClosedLoopNewPurchaseSopRefundExistsShouldBlockBmpaTest.php

83 lines
2.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace Tests\Feature;
use App\Models\Merchant;
use App\Models\Plan;
use App\Models\PlatformOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
* 收费闭环异常分支(可验收 SOP
* 订单一旦存在退款轨迹refund_summary/refund_receiptsBMPA 必须阻断。
* 目的:避免“带退款的订单被强行推进并同步订阅”,导致财务/状态混乱。
*/
class AdminBillingClosedLoopNewPurchaseSopRefundExistsShouldBlockBmpaTest extends TestCase
{
use RefreshDatabase;
protected function loginAsPlatformAdmin(): void
{
$this->seed();
$this->post('/admin/login', [
'email' => 'platform.admin@demo.local',
'password' => 'Platform@123456',
])->assertRedirect('/admin');
}
public function test_sop_new_purchase_refund_exists_should_block_bmpa(): void
{
$this->loginAsPlatformAdmin();
$merchant = Merchant::query()->firstOrFail();
$plan = Plan::query()->create([
'code' => 'sop_new_purchase_refund_guard_monthly',
'name' => 'SOP新购退款阻断 BMPA月付',
'billing_cycle' => 'monthly',
'price' => 30,
'list_price' => 30,
'status' => 'active',
'sort' => 10,
'published_at' => now(),
]);
// 1) 创建平台订单(新购)
$this->post('/admin/platform-orders', [
'merchant_id' => $merchant->id,
'plan_id' => $plan->id,
'order_type' => 'new_purchase',
'quantity' => 1,
'discount_amount' => 0,
'payment_channel' => 'bank_transfer',
'remark' => 'SOP 新购(退款阻断 BMPA',
])->assertRedirect();
/** @var PlatformOrder $order */
$order = PlatformOrder::query()->latest('id')->firstOrFail();
// 2) 构造“退款轨迹”但订单仍为 unpaid/pending模拟脏数据/误操作场景)
$meta = (array) ($order->meta ?? []);
data_set($meta, 'refund_summary', [
'count' => 1,
'total_amount' => 10.0,
]);
$order->meta = $meta;
$order->save();
// 3) BMPA 必须阻断
$res = $this->from('/admin/platform-orders/' . $order->id)
->post('/admin/platform-orders/' . $order->id . '/mark-paid-and-activate');
$res->assertRedirect('/admin/platform-orders/' . $order->id);
$res->assertSessionHas('warning');
$order->refresh();
$this->assertSame('unpaid', (string) $order->payment_status);
$this->assertSame('pending', (string) $order->status);
$this->assertNull($order->site_subscription_id);
}
}