- TestCase 공통화: setUpAuthenticatedUser(), api(), assertApiSuccess(), assertApiPaginated() - 기존 10개 테스트 파일의 중복 setUp 코드 → TestCase 상속으로 전환 - Factory 3개 추가: TenantFactory, ClientFactory, OrderFactory - OrderApiTest 12개 테스트 신규 작성 (목록/생성/조회/수정/삭제/상태변경/인증) - 발견: 빈 데이터로 수주 생성 가능 (FormRequest 검증 강화 필요)
269 lines
8.0 KiB
PHP
269 lines
8.0 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Orders;
|
|
|
|
use App\Models\Orders\Client;
|
|
use App\Models\Orders\Order;
|
|
use Tests\TestCase;
|
|
|
|
class OrderApiTest extends TestCase
|
|
{
|
|
private Client $client;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->setUpAuthenticatedUser();
|
|
|
|
// 테스트용 거래처
|
|
$this->client = Client::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'name' => '테스트 거래처',
|
|
'client_code' => 'CLI'.uniqid(),
|
|
'is_active' => true,
|
|
'created_by' => $this->user->id,
|
|
]);
|
|
}
|
|
|
|
// ==================== 목록 조회 ====================
|
|
|
|
public function test_수주_목록_조회(): void
|
|
{
|
|
Order::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'order_no' => 'ORD-'.uniqid(),
|
|
'order_type_code' => Order::TYPE_ORDER,
|
|
'status_code' => Order::STATUS_DRAFT,
|
|
'client_id' => $this->client->id,
|
|
'client_name' => $this->client->name,
|
|
'quantity' => 10,
|
|
'supply_amount' => 1000000,
|
|
'tax_amount' => 100000,
|
|
'total_amount' => 1100000,
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->api('get', '/api/v1/orders');
|
|
|
|
$this->assertApiPaginated($response);
|
|
|
|
$data = $response->json('data.data');
|
|
$this->assertNotEmpty($data);
|
|
}
|
|
|
|
public function test_수주_통계_조회(): void
|
|
{
|
|
Order::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'order_no' => 'ORD-'.uniqid(),
|
|
'order_type_code' => Order::TYPE_ORDER,
|
|
'status_code' => Order::STATUS_CONFIRMED,
|
|
'client_id' => $this->client->id,
|
|
'client_name' => $this->client->name,
|
|
'quantity' => 5,
|
|
'supply_amount' => 500000,
|
|
'tax_amount' => 50000,
|
|
'total_amount' => 550000,
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
|
|
$response = $this->api('get', '/api/v1/orders/stats');
|
|
|
|
$response->assertStatus(200)
|
|
->assertJsonStructure(['success', 'data']);
|
|
}
|
|
|
|
// ==================== 생성 ====================
|
|
|
|
public function test_수주_생성_성공(): void
|
|
{
|
|
$response = $this->api('post', '/api/v1/orders', [
|
|
'order_type_code' => Order::TYPE_ORDER,
|
|
'status_code' => Order::STATUS_DRAFT,
|
|
'client_id' => $this->client->id,
|
|
'client_name' => $this->client->name,
|
|
'site_name' => '테스트 현장',
|
|
'supply_amount' => 2000000,
|
|
'tax_amount' => 200000,
|
|
'total_amount' => 2200000,
|
|
'delivery_date' => now()->addDays(14)->format('Y-m-d'),
|
|
'items' => [
|
|
[
|
|
'item_name' => '블라인드 A형',
|
|
'quantity' => 10,
|
|
'unit_price' => 200000,
|
|
],
|
|
],
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
$this->assertTrue($response->json('success'));
|
|
|
|
$this->assertDatabaseHas('orders', [
|
|
'client_id' => $this->client->id,
|
|
'site_name' => '테스트 현장',
|
|
'tenant_id' => $this->tenant->id,
|
|
]);
|
|
}
|
|
|
|
public function test_수주_생성_빈_데이터_허용_확인(): void
|
|
{
|
|
// NOTE: 현재 API는 빈 데이터로도 수주 생성을 허용함
|
|
// FormRequest 검증 강화가 필요한 지점 (D4 개선 대상)
|
|
$response = $this->api('post', '/api/v1/orders', []);
|
|
|
|
$response->assertStatus(200);
|
|
}
|
|
|
|
// ==================== 상세 조회 ====================
|
|
|
|
public function test_수주_상세_조회(): void
|
|
{
|
|
$order = $this->createOrder();
|
|
|
|
$response = $this->api('get', "/api/v1/orders/{$order->id}");
|
|
|
|
$this->assertApiSuccess($response);
|
|
|
|
$data = $response->json('data');
|
|
$this->assertEquals($order->id, $data['id']);
|
|
$this->assertEquals($order->order_no, $data['order_no']);
|
|
}
|
|
|
|
public function test_존재하지_않는_수주_조회시_404(): void
|
|
{
|
|
$response = $this->api('get', '/api/v1/orders/999999');
|
|
|
|
$response->assertStatus(404);
|
|
}
|
|
|
|
// ==================== 수정 ====================
|
|
|
|
public function test_수주_수정_성공(): void
|
|
{
|
|
$order = $this->createOrder();
|
|
|
|
$response = $this->api('put', "/api/v1/orders/{$order->id}", [
|
|
'order_type_code' => Order::TYPE_ORDER,
|
|
'status_code' => Order::STATUS_DRAFT,
|
|
'client_id' => $this->client->id,
|
|
'client_name' => '수정된 거래처명',
|
|
'site_name' => '수정된 현장',
|
|
'supply_amount' => 3000000,
|
|
'tax_amount' => 300000,
|
|
'total_amount' => 3300000,
|
|
'items' => [
|
|
[
|
|
'item_name' => '블라인드 B형',
|
|
'quantity' => 20,
|
|
'unit_price' => 150000,
|
|
],
|
|
],
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertDatabaseHas('orders', [
|
|
'id' => $order->id,
|
|
'site_name' => '수정된 현장',
|
|
]);
|
|
}
|
|
|
|
// ==================== 삭제 ====================
|
|
|
|
public function test_수주_삭제_성공(): void
|
|
{
|
|
$order = $this->createOrder();
|
|
|
|
$response = $this->api('delete', "/api/v1/orders/{$order->id}");
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertSoftDeleted('orders', ['id' => $order->id]);
|
|
}
|
|
|
|
public function test_수주_일괄_삭제(): void
|
|
{
|
|
$order1 = $this->createOrder();
|
|
$order2 = $this->createOrder();
|
|
|
|
$response = $this->api('delete', '/api/v1/orders/bulk', [
|
|
'ids' => [$order1->id, $order2->id],
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertSoftDeleted('orders', ['id' => $order1->id]);
|
|
$this->assertSoftDeleted('orders', ['id' => $order2->id]);
|
|
}
|
|
|
|
// ==================== 상태 변경 ====================
|
|
|
|
public function test_수주_상태_등록에서_확정으로_변경(): void
|
|
{
|
|
$order = $this->createOrder(Order::STATUS_DRAFT);
|
|
|
|
$response = $this->api('patch', "/api/v1/orders/{$order->id}/status", [
|
|
'status' => Order::STATUS_CONFIRMED,
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertDatabaseHas('orders', [
|
|
'id' => $order->id,
|
|
'status_code' => Order::STATUS_CONFIRMED,
|
|
]);
|
|
}
|
|
|
|
public function test_수주_상태_취소(): void
|
|
{
|
|
$order = $this->createOrder(Order::STATUS_DRAFT);
|
|
|
|
$response = $this->api('patch', "/api/v1/orders/{$order->id}/status", [
|
|
'status' => Order::STATUS_CANCELLED,
|
|
]);
|
|
|
|
$response->assertStatus(200);
|
|
|
|
$this->assertDatabaseHas('orders', [
|
|
'id' => $order->id,
|
|
'status_code' => Order::STATUS_CANCELLED,
|
|
]);
|
|
}
|
|
|
|
// ==================== 인증 ====================
|
|
|
|
public function test_미인증_요청시_401(): void
|
|
{
|
|
$response = $this->withHeaders([
|
|
'X-API-KEY' => $this->apiKey,
|
|
'Accept' => 'application/json',
|
|
])->getJson('/api/v1/orders');
|
|
|
|
$response->assertStatus(401);
|
|
}
|
|
|
|
// ==================== 헬퍼 ====================
|
|
|
|
private function createOrder(string $status = Order::STATUS_DRAFT): Order
|
|
{
|
|
return Order::create([
|
|
'tenant_id' => $this->tenant->id,
|
|
'order_no' => 'ORD-'.uniqid(),
|
|
'order_type_code' => Order::TYPE_ORDER,
|
|
'status_code' => $status,
|
|
'client_id' => $this->client->id,
|
|
'client_name' => $this->client->name,
|
|
'site_name' => '테스트 현장',
|
|
'quantity' => 10,
|
|
'supply_amount' => 1000000,
|
|
'tax_amount' => 100000,
|
|
'total_amount' => 1100000,
|
|
'created_by' => $this->user->id,
|
|
'updated_by' => $this->user->id,
|
|
]);
|
|
}
|
|
}
|