Files
xin-procurement/tests/Feature/ProductPriceTest.php
T
2026-08-10 08:55:22 +08:00

130 lines
5.7 KiB
PHP
Raw 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\CustomerLevelModel;
use App\Models\NoticeModel;
use App\Models\ProductModel;
use App\Models\ProductPriceModel;
use App\Models\StoreModel;
use App\Models\UserModel;
/**
* A2 等级价格体系:等级价匹配、批量调价事务与调价通知
*/
class ProductPriceTest extends ProcurementTestCase
{
/** 小程序商品列表返回当前门店等级对应的价格 */
public function test_product_list_returns_price_for_store_level(): void
{
$levelA = CustomerLevelModel::factory()->create();
$levelB = CustomerLevelModel::factory()->create();
$store = StoreModel::factory()->create(['level_id' => $levelA->id]);
$product = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON]);
ProductPriceModel::factory()->create(['product_id' => $product->id, 'level_id' => $levelA->id, 'price' => 5.50]);
ProductPriceModel::factory()->create(['product_id' => $product->id, 'level_id' => $levelB->id, 'price' => 3.00]);
$this->actingAsMiniUser(UserModel::factory()->forStore($store->id)->create());
$response = $this->getJson('/mini/product/list');
$response->assertOk()->assertJsonPath('success', true);
$row = collect($response->json('data.data'))->firstWhere('id', $product->id);
$this->assertNotNull($row, '商品应出现在列表中');
$this->assertSame(5.50, (float) $row['price'], '应返回门店所在等级的价格');
}
/** 门店未设置客户等级:仍可浏览商品,但价格不可见(price=null */
public function test_store_without_level_sees_products_without_price(): void
{
$store = StoreModel::factory()->create(['level_id' => 0]);
$product = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON]);
$this->actingAsMiniUser(UserModel::factory()->forStore($store->id)->create());
$response = $this->getJson('/mini/product/list');
$response->assertOk()->assertJsonPath('success', true);
$row = collect($response->json('data.data'))->firstWhere('id', $product->id);
$this->assertNotNull($row, '未设等级的门店仍应能看到商品');
$this->assertNull($row['price'], '未设等级时价格应为 null');
}
/** 未绑定门店:可浏览商品与分类,但价格不可见;加购仍被拦截(购买前置校验不变) */
public function test_unbound_user_can_browse_products_without_price_but_cannot_cart(): void
{
$product = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON]);
$this->actingAsMiniUser(UserModel::factory()->create()); // type=0 待绑定
$list = $this->getJson('/mini/product/list');
$list->assertOk()->assertJsonPath('success', true);
$row = collect($list->json('data.data'))->firstWhere('id', $product->id);
$this->assertNotNull($row, '未绑定门店应能看到商品');
$this->assertNull($row['price'], '未绑定门店不得看到价格');
$this->getJson('/mini/product/categories')
->assertOk()
->assertJsonPath('success', true);
$this->postJson('/mini/cart', ['product_id' => $product->id, 'quantity' => 1])
->assertJsonPath('success', false)
->assertJsonPath('msg', '尚未绑定门店,请联系客服处理');
}
/** 批量调价:事务写入 + 通知受影响门店用户(不影响无关门店) */
public function test_batch_price_updates_and_notifies_affected_stores(): void
{
$this->actingAsSysUser();
$level = CustomerLevelModel::factory()->create();
$affectedStore = StoreModel::factory()->create(['level_id' => $level->id]);
$unaffectedStore = StoreModel::factory()->create(['level_id' => CustomerLevelModel::factory()->create()->id]);
$affectedUser = UserModel::factory()->forStore($affectedStore->id)->create();
$unaffectedUser = UserModel::factory()->forStore($unaffectedStore->id)->create();
$product = ProductModel::factory()->create();
ProductPriceModel::factory()->create(['product_id' => $product->id, 'level_id' => $level->id, 'price' => 5.00]);
$this->putJson('/product/goods/batchPrice', [
'updates' => [
['product_id' => $product->id, 'level_id' => $level->id, 'price' => 8.80],
],
])->assertOk()->assertJsonPath('success', true);
$this->assertSame(
8.80,
(float) ProductPriceModel::forProductLevel($product->id, $level->id)->first()->price,
'等级价格应已更新'
);
$this->assertSame(
1,
NoticeModel::where('user_id', $affectedUser->id)->where('type', NoticeModel::TYPE_PRICE)->count(),
'受影响门店用户应收到价格变更通知'
);
$this->assertSame(
0,
NoticeModel::where('user_id', $unaffectedUser->id)->count(),
'无关门店用户不应收到通知'
);
}
/** 价格矩阵:行=商品 × 列=启用等级 */
public function test_price_matrix_structure(): void
{
$this->actingAsSysUser();
$level = CustomerLevelModel::factory()->create();
$product = ProductModel::factory()->create();
ProductPriceModel::factory()->create(['product_id' => $product->id, 'level_id' => $level->id, 'price' => 6.00]);
$response = $this->getJson('/product/goods/priceMatrix');
$response->assertOk()->assertJsonPath('success', true);
$this->assertNotEmpty($response->json('data.levels'));
$row = collect($response->json('data.rows'))->firstWhere('id', $product->id);
$this->assertNotNull($row);
$this->assertSame(6.0, (float) $row['price_' . $level->id]);
}
}