test: [work-order] 작업지시 API 테스트 16개 추가

- CRUD 테스트 5개 (생성/상세/수정/삭제/404)
- 상태전이 테스트 4개 (미배정→대기→준비→진행→완료)
- 담당자 배정 테스트 1개
- 공정단계/자재 조회 테스트 3개
- 목록/통계/인증 테스트 3개
This commit is contained in:
김보곤
2026-03-14 14:35:02 +09:00
parent 63b174811c
commit 877d15420a

View File

@@ -0,0 +1,299 @@
<?php
namespace Tests\Feature\Production;
use App\Models\Orders\Client;
use App\Models\Orders\Order;
use App\Models\Process;
use App\Models\Production\WorkOrder;
use App\Models\Production\WorkOrderItem;
use Tests\TestCase;
class WorkOrderApiTest extends TestCase
{
private Process $process;
private Order $order;
protected function setUp(): void
{
parent::setUp();
$this->setUpAuthenticatedUser();
// 공정
$this->process = Process::create([
'tenant_id' => $this->tenant->id,
'process_code' => 'PRC-'.uniqid(),
'process_name' => '스크린 조립',
'process_type' => 'assembly',
'is_active' => true,
'created_by' => $this->user->id,
'updated_by' => $this->user->id,
]);
// 수주 (작업지시의 부모)
$client = Client::create([
'tenant_id' => $this->tenant->id,
'name' => '테스트 거래처',
'client_code' => 'CLI'.uniqid(),
'is_active' => true,
'created_by' => $this->user->id,
]);
$this->order = Order::create([
'tenant_id' => $this->tenant->id,
'order_no' => 'ORD-'.uniqid(),
'order_type_code' => Order::TYPE_ORDER,
'status_code' => Order::STATUS_CONFIRMED,
'client_id' => $client->id,
'client_name' => $client->name,
'quantity' => 10,
'supply_amount' => 1000000,
'tax_amount' => 100000,
'total_amount' => 1100000,
'created_by' => $this->user->id,
'updated_by' => $this->user->id,
]);
}
// ==================== 목록/통계 조회 ====================
public function test_작업지시_목록_조회(): void
{
$this->createWorkOrder();
$response = $this->api('get', '/api/v1/work-orders');
$this->assertApiPaginated($response);
}
public function test_작업지시_통계_조회(): void
{
$this->createWorkOrder();
$response = $this->api('get', '/api/v1/work-orders/stats');
$response->assertStatus(200)
->assertJsonStructure(['success', 'data']);
}
// ==================== CRUD ====================
public function test_작업지시_생성_성공(): void
{
$response = $this->api('post', '/api/v1/work-orders', [
'process_id' => $this->process->id,
'sales_order_id' => $this->order->id,
'assignee_ids' => [$this->user->id],
'priority' => 5,
'scheduled_date' => now()->addDays(7)->format('Y-m-d'),
'memo' => '테스트 작업지시',
]);
$response->assertStatus(200);
$this->assertTrue($response->json('success'));
$this->assertDatabaseHas('work_orders', [
'process_id' => $this->process->id,
'sales_order_id' => $this->order->id,
'tenant_id' => $this->tenant->id,
]);
}
public function test_작업지시_상세_조회(): void
{
$wo = $this->createWorkOrder();
$response = $this->api('get', "/api/v1/work-orders/{$wo->id}");
$this->assertApiSuccess($response);
$data = $response->json('data');
$this->assertEquals($wo->id, $data['id']);
}
public function test_작업지시_수정(): void
{
$wo = $this->createWorkOrder();
$response = $this->api('put', "/api/v1/work-orders/{$wo->id}", [
'memo' => '수정된 메모',
'priority' => 1,
]);
$response->assertStatus(200);
$this->assertDatabaseHas('work_orders', [
'id' => $wo->id,
'memo' => '수정된 메모',
]);
}
public function test_작업지시_삭제(): void
{
$wo = $this->createWorkOrder();
$response = $this->api('delete', "/api/v1/work-orders/{$wo->id}");
$response->assertStatus(200);
$this->assertSoftDeleted('work_orders', ['id' => $wo->id]);
}
public function test_존재하지_않는_작업지시_조회시_404(): void
{
$response = $this->api('get', '/api/v1/work-orders/999999');
$response->assertStatus(404);
}
// ==================== 상태 전이 ====================
public function test_상태_미배정에서_대기로_변경(): void
{
$wo = $this->createWorkOrder(WorkOrder::STATUS_UNASSIGNED);
$response = $this->api('patch', "/api/v1/work-orders/{$wo->id}/status", [
'status' => WorkOrder::STATUS_PENDING,
]);
$response->assertStatus(200);
$this->assertDatabaseHas('work_orders', [
'id' => $wo->id,
'status' => WorkOrder::STATUS_PENDING,
]);
}
public function test_상태_대기에서_준비중으로_변경(): void
{
$wo = $this->createWorkOrder(WorkOrder::STATUS_PENDING);
$response = $this->api('patch', "/api/v1/work-orders/{$wo->id}/status", [
'status' => WorkOrder::STATUS_WAITING,
]);
$response->assertStatus(200);
$this->assertDatabaseHas('work_orders', [
'id' => $wo->id,
'status' => WorkOrder::STATUS_WAITING,
]);
}
public function test_상태_준비중에서_진행중으로_변경(): void
{
$wo = $this->createWorkOrder(WorkOrder::STATUS_WAITING);
$response = $this->api('patch', "/api/v1/work-orders/{$wo->id}/status", [
'status' => WorkOrder::STATUS_IN_PROGRESS,
]);
$response->assertStatus(200);
$this->assertDatabaseHas('work_orders', [
'id' => $wo->id,
'status' => WorkOrder::STATUS_IN_PROGRESS,
]);
}
public function test_상태_진행중에서_완료로_변경(): void
{
$wo = $this->createWorkOrder(WorkOrder::STATUS_IN_PROGRESS);
$response = $this->api('patch', "/api/v1/work-orders/{$wo->id}/status", [
'status' => WorkOrder::STATUS_COMPLETED,
]);
$response->assertStatus(200);
$this->assertDatabaseHas('work_orders', [
'id' => $wo->id,
'status' => WorkOrder::STATUS_COMPLETED,
]);
}
// ==================== 담당자 배정 ====================
public function test_담당자_배정(): void
{
$wo = $this->createWorkOrder(WorkOrder::STATUS_UNASSIGNED);
$response = $this->api('patch', "/api/v1/work-orders/{$wo->id}/assign", [
'assignee_id' => $this->user->id,
]);
$response->assertStatus(200);
$this->assertDatabaseHas('work_orders', [
'id' => $wo->id,
'assignee_id' => $this->user->id,
]);
}
// ==================== 공정 단계 ====================
public function test_공정_단계_진행_조회(): void
{
$wo = $this->createWorkOrder();
$response = $this->api('get', "/api/v1/work-orders/{$wo->id}/step-progress");
$response->assertStatus(200)
->assertJsonStructure(['success', 'data']);
}
// ==================== 자재 ====================
public function test_자재_목록_조회(): void
{
$wo = $this->createWorkOrder();
$response = $this->api('get', "/api/v1/work-orders/{$wo->id}/materials");
$response->assertStatus(200)
->assertJsonStructure(['success', 'data']);
}
public function test_자재_투입_이력_조회(): void
{
$wo = $this->createWorkOrder();
$response = $this->api('get', "/api/v1/work-orders/{$wo->id}/material-input-history");
$response->assertStatus(200)
->assertJsonStructure(['success', 'data']);
}
// ==================== 인증 ====================
public function test_미인증_요청시_401(): void
{
$response = $this->withHeaders([
'X-API-KEY' => $this->apiKey,
'Accept' => 'application/json',
])->getJson('/api/v1/work-orders');
$response->assertStatus(401);
}
// ==================== 헬퍼 ====================
private function createWorkOrder(string $status = WorkOrder::STATUS_UNASSIGNED): WorkOrder
{
return WorkOrder::create([
'tenant_id' => $this->tenant->id,
'work_order_no' => 'WO-'.uniqid(),
'sales_order_id' => $this->order->id,
'process_id' => $this->process->id,
'project_name' => '테스트 프로젝트',
'status' => $status,
'priority' => 5,
'scheduled_date' => now()->addDays(7),
'memo' => '테스트 작업지시',
'is_active' => true,
'created_by' => $this->user->id,
'updated_by' => $this->user->id,
]);
}
}