152 lines
4.4 KiB
PHP
152 lines
4.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Feature\Integration;
|
||
|
|
|
||
|
|
use Tests\TestCase;
|
||
|
|
use App\Modules\Core\Models\Tenant;
|
||
|
|
use App\Modules\Core\Models\User;
|
||
|
|
use App\Modules\Inventory\Models\Product;
|
||
|
|
use App\Modules\Inventory\Models\Category;
|
||
|
|
use Stancl\Tenancy\Facades\Tenancy;
|
||
|
|
use Illuminate\Support\Str;
|
||
|
|
|
||
|
|
class ProductSyncTest extends TestCase
|
||
|
|
{
|
||
|
|
protected $tenant;
|
||
|
|
protected $user;
|
||
|
|
protected $domain;
|
||
|
|
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
|
||
|
|
// 每次測試前重置資料庫(在測試環境)
|
||
|
|
\Artisan::call('migrate:fresh');
|
||
|
|
|
||
|
|
$this->domain = 'product-test-' . Str::random(8) . '.erp.local';
|
||
|
|
$tenantId = 'test_tenant_p_' . Str::random(8);
|
||
|
|
|
||
|
|
// 建立租戶
|
||
|
|
tenancy()->central(function () use ($tenantId) {
|
||
|
|
$this->tenant = Tenant::create([
|
||
|
|
'id' => $tenantId,
|
||
|
|
'name' => 'Product Test Tenant',
|
||
|
|
]);
|
||
|
|
$this->tenant->domains()->create(['domain' => $this->domain]);
|
||
|
|
});
|
||
|
|
|
||
|
|
// 初始化租戶並遷移
|
||
|
|
tenancy()->initialize($this->tenant);
|
||
|
|
\Artisan::call('tenants:migrate');
|
||
|
|
|
||
|
|
// 建立測試使用者與分類
|
||
|
|
$this->user = User::factory()->create(['name' => 'Test Admin']);
|
||
|
|
Category::create(['name' => '測試分類', 'code' => 'TEST-CAT']);
|
||
|
|
|
||
|
|
tenancy()->end();
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function tearDown(): void
|
||
|
|
{
|
||
|
|
if ($this->tenant) {
|
||
|
|
$this->tenant->delete();
|
||
|
|
}
|
||
|
|
parent::tearDown();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 測試產品同步新增功能
|
||
|
|
*/
|
||
|
|
public function test_product_sync_can_create_new_product()
|
||
|
|
{
|
||
|
|
\Laravel\Sanctum\Sanctum::actingAs($this->user, ['*']);
|
||
|
|
|
||
|
|
$payload = [
|
||
|
|
'external_pos_id' => 'POS-NEW-999',
|
||
|
|
'name' => '全新同步商品',
|
||
|
|
'price' => 299,
|
||
|
|
'barcode' => '1234567890123',
|
||
|
|
'category' => '測試分類',
|
||
|
|
'cost_price' => 150
|
||
|
|
];
|
||
|
|
|
||
|
|
$response = $this->withHeaders([
|
||
|
|
'X-Tenant-Domain' => $this->domain,
|
||
|
|
'Accept' => 'application/json',
|
||
|
|
])->postJson('/api/v1/integration/products/upsert', $payload);
|
||
|
|
|
||
|
|
$response->assertStatus(200)
|
||
|
|
->assertJsonPath('message', 'Product synced successfully');
|
||
|
|
|
||
|
|
// 驗證租戶資料庫
|
||
|
|
tenancy()->initialize($this->tenant);
|
||
|
|
$this->assertDatabaseHas('products', [
|
||
|
|
'external_pos_id' => 'POS-NEW-999',
|
||
|
|
'name' => '全新同步商品',
|
||
|
|
'price' => 299,
|
||
|
|
]);
|
||
|
|
tenancy()->end();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 測試產品同步更新功能 (Upsert)
|
||
|
|
*/
|
||
|
|
public function test_product_sync_can_update_existing_product()
|
||
|
|
{
|
||
|
|
// 先建立一個既有商品
|
||
|
|
tenancy()->initialize($this->tenant);
|
||
|
|
Product::create([
|
||
|
|
'name' => '舊商品名稱',
|
||
|
|
'code' => 'OLD-CODE',
|
||
|
|
'external_pos_id' => 'POS-EXIST-001',
|
||
|
|
'price' => 100,
|
||
|
|
'category_id' => Category::first()->id,
|
||
|
|
]);
|
||
|
|
tenancy()->end();
|
||
|
|
|
||
|
|
\Laravel\Sanctum\Sanctum::actingAs($this->user, ['*']);
|
||
|
|
|
||
|
|
$payload = [
|
||
|
|
'external_pos_id' => 'POS-EXIST-001',
|
||
|
|
'name' => '更新後的商品名稱',
|
||
|
|
'price' => 888,
|
||
|
|
];
|
||
|
|
|
||
|
|
$response = $this->withHeaders([
|
||
|
|
'X-Tenant-Domain' => $this->domain,
|
||
|
|
'Accept' => 'application/json',
|
||
|
|
])->postJson('/api/v1/integration/products/upsert', $payload);
|
||
|
|
|
||
|
|
$response->assertStatus(200);
|
||
|
|
|
||
|
|
tenancy()->initialize($this->tenant);
|
||
|
|
$this->assertDatabaseHas('products', [
|
||
|
|
'external_pos_id' => 'POS-EXIST-001',
|
||
|
|
'name' => '更新後的商品名稱',
|
||
|
|
'price' => 888,
|
||
|
|
]);
|
||
|
|
tenancy()->end();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 測試產品同步驗證失敗
|
||
|
|
*/
|
||
|
|
public function test_product_sync_validation_fails_without_required_fields()
|
||
|
|
{
|
||
|
|
\Laravel\Sanctum\Sanctum::actingAs($this->user, ['*']);
|
||
|
|
|
||
|
|
$payload = [
|
||
|
|
'external_pos_id' => '', // 缺少此欄位
|
||
|
|
'name' => '', // 缺少此欄位
|
||
|
|
];
|
||
|
|
|
||
|
|
$response = $this->withHeaders([
|
||
|
|
'X-Tenant-Domain' => $this->domain,
|
||
|
|
'Accept' => 'application/json',
|
||
|
|
])->postJson('/api/v1/integration/products/upsert', $payload);
|
||
|
|
|
||
|
|
$response->assertStatus(422)
|
||
|
|
->assertJsonValidationErrors(['external_pos_id', 'name']);
|
||
|
|
}
|
||
|
|
}
|