Files
xin-procurement/tests/Feature/ExportTest.php
T
2026-08-14 21:28:55 +08:00

92 lines
3.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\ProductCategoryModel;
use App\Models\ProductModel;
use App\Models\ProductPriceModel;
use App\Models\PurchaseOrderModel;
use App\Models\StoreModel;
use App\Models\StoreOrderModel;
use App\Models\UserModel;
/**
* 采购单导出(仅 Excel 表格,全品类):xlsx Content-Type /
* 权限拦截 / 中文文件名 RFC 5987 编码
*/
class ExportTest extends ProcurementTestCase
{
/**
* 构造含蔬果 + 肉禽两类商品的采购单(下单 → 汇总生成)
*/
private function buildPurchaseWithItems(): PurchaseOrderModel
{
$vegRoot = ProductCategoryModel::create(['name' => '蔬菜', 'parent_id' => 0, 'sort' => 0, 'status' => 1]);
$meatRoot = ProductCategoryModel::create(['name' => '肉禽蛋', 'parent_id' => 0, 'sort' => 1, 'status' => 1]);
$level = CustomerLevelModel::factory()->create();
$store = StoreModel::factory()->create(['level_id' => $level->id]);
$veg = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON, 'category_id' => $vegRoot->id]);
$meat = ProductModel::factory()->create(['status' => ProductModel::STATUS_ON, 'category_id' => $meatRoot->id]);
ProductPriceModel::factory()->create(['product_id' => $veg->id, 'level_id' => $level->id, 'price' => '5.00']);
ProductPriceModel::factory()->create(['product_id' => $meat->id, 'level_id' => $level->id, 'price' => '20.00']);
$this->actingAsMiniUser(UserModel::factory()->forStore($store->id)->create());
$this->postJson('/mini/order', ['items' => [
['product_id' => $veg->id, 'quantity' => 2],
['product_id' => $meat->id, 'quantity' => 1],
]])->assertJsonPath('success', true);
// 接单后生成采购单
StoreOrderModel::query()->update(['status' => StoreOrderModel::STATUS_SUMMARIZED]);
$this->actingAsSysUser();
$this->postJson('/purchase/order/generate', ['purchase_date' => now()->toDateString()])
->assertJsonPath('success', true);
return PurchaseOrderModel::first();
}
/** xlsx 导出:正确 Content-Type + 中文文件名 RFC 5987 编码 */
public function test_export_xlsx_with_encoded_chinese_filename(): void
{
$purchase = $this->buildPurchaseWithItems();
$this->actingAsSysUser();
$response = $this->get("/purchase/order/{$purchase->id}/export");
$response->assertOk();
$this->assertStringContainsString(
'spreadsheetml',
(string) $response->headers->get('Content-Type'),
'xlsx 应返回电子表格 Content-Type'
);
$disposition = (string) $response->headers->get('Content-Disposition');
// Symfony 输出小写 utf-8''RFC 5987),大小写不敏感断言
$this->assertMatchesRegularExpression("/filename\*=utf-8''/i", $disposition, '中文文件名应走 RFC 5987 编码');
$this->assertStringContainsString(rawurlencode('采购单'), $disposition);
}
/** 采购单不存在 → 拒绝 */
public function test_export_missing_purchase_rejected(): void
{
$this->actingAsSysUser();
$this->get('/purchase/order/99999/export')
->assertJsonPath('success', false);
}
/** 无 purchase.order.export 权限点 → 拦截 */
public function test_export_requires_export_permission(): void
{
$purchase = $this->buildPurchaseWithItems();
// 仅持有查询权限的用户
$this->actingAsSysUser(['purchase.order.query']);
$response = $this->get("/purchase/order/{$purchase->id}/export");
$this->assertFalse($response->json('success'), '缺少权限点应被拦截');
}
}