519 lines
18 KiB
Go
519 lines
18 KiB
Go
package repositories
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"os"
|
||
"testing"
|
||
"time"
|
||
"wm-backend/internal/models"
|
||
db "wm-backend/sqlc_gen"
|
||
|
||
"github.com/jackc/pgx/v5/pgxpool"
|
||
)
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Test helpers
|
||
// ---------------------------------------------------------------------------
|
||
|
||
// testDB returns a connection pool for tests. Set WM_TEST_DB_URL to override
|
||
// the default connection string. If the DB is not available the test is skipped.
|
||
func testDB(t *testing.T) *pgxpool.Pool {
|
||
t.Helper()
|
||
dsn := os.Getenv("WM_TEST_DB_URL")
|
||
if dsn == "" {
|
||
dsn = "postgres://root:Smatec2026@localhost:5432/warehouse_management?sslmode=disable"
|
||
}
|
||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||
defer cancel()
|
||
pool, err := pgxpool.New(ctx, dsn)
|
||
if err != nil {
|
||
t.Skipf("skipping integration test: cannot connect to DB: %v", err)
|
||
}
|
||
if err := pool.Ping(ctx); err != nil {
|
||
pool.Close()
|
||
t.Skipf("skipping integration test: cannot ping DB: %v", err)
|
||
}
|
||
return pool
|
||
}
|
||
|
||
// seedComponentItem inserts all required parent records and returns
|
||
// the created component_item ID, plus its component_id and container_id.
|
||
func seedComponentItem(t *testing.T, pool *pgxpool.Pool, q *db.Queries, quantity int32, status db.ComponentItemStatusEnum) (itemID, componentID, containerID int64) {
|
||
t.Helper()
|
||
ctx := context.Background()
|
||
|
||
// warehouse
|
||
w, err := q.CreateWarehouse(ctx, db.CreateWarehouseParams{
|
||
Name: fmt.Sprintf("test-wh-%d", time.Now().UnixNano()),
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed warehouse: %v", err)
|
||
}
|
||
// room
|
||
r, err := q.CreateRoom(ctx, db.CreateRoomParams{
|
||
WarehouseID: w.ID,
|
||
Name: fmt.Sprintf("test-room-%d", time.Now().UnixNano()),
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed room: %v", err)
|
||
}
|
||
// cabinet
|
||
cb, err := q.CreateCabinet(ctx, db.CreateCabinetParams{
|
||
RoomID: r.ID,
|
||
Name: fmt.Sprintf("test-cab-%d", time.Now().UnixNano()),
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed cabinet: %v", err)
|
||
}
|
||
// shelf
|
||
s, err := q.CreateShelve(ctx, db.CreateShelveParams{
|
||
CabinetID: cb.ID,
|
||
Name: fmt.Sprintf("test-shelf-%d", time.Now().UnixNano()),
|
||
LevelIndex: 1,
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed shelf: %v", err)
|
||
}
|
||
// container
|
||
cn, err := q.CreateContainer(ctx, db.CreateContainerParams{
|
||
ShelfID: s.ID,
|
||
Name: fmt.Sprintf("test-cont-%d", time.Now().UnixNano()),
|
||
ContainerType: db.ContainerTypeEnumOther,
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed container: %v", err)
|
||
}
|
||
containerID = cn.ID
|
||
|
||
// component_type
|
||
ct, err := q.CreateComponentType(ctx, db.CreateComponentTypeParams{
|
||
Name: fmt.Sprintf("test-ctype-%d", time.Now().UnixNano()),
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed component_type: %v", err)
|
||
}
|
||
// component
|
||
c, err := q.CreateComponent(ctx, db.CreateComponentParams{
|
||
ComponentTypeID: ct.ID,
|
||
Name: fmt.Sprintf("test-comp-%d", time.Now().UnixNano()),
|
||
Unit: "cái",
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed component: %v", err)
|
||
}
|
||
componentID = c.ID
|
||
|
||
// component_item
|
||
ci, err := q.CreateComponentItem(ctx, db.CreateComponentItemParams{
|
||
ComponentID: componentID,
|
||
ContainerID: containerID,
|
||
Quantity: quantity,
|
||
Status: status,
|
||
Metadata: []byte("{}"),
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("seed component_item: %v", err)
|
||
}
|
||
return ci.ID, componentID, containerID
|
||
}
|
||
|
||
// cleanupSeeded removes test data in reverse dependency order.
|
||
func cleanupSeeded(t *testing.T, pool *pgxpool.Pool, itemID, componentID, containerID int64) {
|
||
t.Helper()
|
||
ctx := context.Background()
|
||
q := db.New(pool)
|
||
// Delete history rows referencing this item
|
||
_, _ = pool.Exec(ctx, "DELETE FROM component_status_history WHERE component_item_id = $1", itemID)
|
||
// Delete component_items (including those possibly created by the test)
|
||
_, _ = pool.Exec(ctx, "DELETE FROM component_items WHERE component_id = $1", componentID)
|
||
_, _ = q.DeleteComponent(ctx, componentID)
|
||
// Delete component_type – we need to find it from the component
|
||
_, _ = pool.Exec(ctx, "DELETE FROM component_types WHERE id = (SELECT component_type_id FROM components WHERE id = $1)", componentID)
|
||
_, _ = q.DeleteContainer(ctx, containerID)
|
||
// Delete container's hierarchy
|
||
_, _ = pool.Exec(ctx, "DELETE FROM shelves WHERE id = (SELECT shelf_id FROM containers WHERE id = $1)", containerID)
|
||
_, _ = pool.Exec(ctx, "DELETE FROM cabinets WHERE id IN (SELECT cabinet_id FROM shelves WHERE id = (SELECT shelf_id FROM containers WHERE id = $1))", containerID)
|
||
_, _ = pool.Exec(ctx, "DELETE FROM rooms WHERE id IN (SELECT room_id FROM cabinets WHERE id IN (SELECT cabinet_id FROM shelves WHERE id = (SELECT shelf_id FROM containers WHERE id = $1)))", containerID)
|
||
_, _ = pool.Exec(ctx, "DELETE FROM warehouses WHERE id IN (SELECT warehouse_id FROM rooms WHERE id IN (SELECT room_id FROM cabinets WHERE id IN (SELECT cabinet_id FROM shelves WHERE id = (SELECT shelf_id FROM containers WHERE id = $1))))", containerID)
|
||
}
|
||
|
||
// ---------------------------------------------------------------------------
|
||
// Tests
|
||
// ---------------------------------------------------------------------------
|
||
|
||
func TestUpdateComponentItemStatus_Case1_ChangeAll_NilQuantity(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 20, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
result, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, nil, "test note", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
|
||
// Verify result
|
||
if result.StatusHistory.OldStatus != "normal" {
|
||
t.Errorf("expected old status 'normal', got '%s'", result.StatusHistory.OldStatus)
|
||
}
|
||
if result.StatusHistory.NewStatus != "damaged" {
|
||
t.Errorf("expected new status 'damaged', got '%s'", result.StatusHistory.NewStatus)
|
||
}
|
||
if result.StatusHistory.ChangedQuantity != 20 {
|
||
t.Errorf("expected changed quantity 20, got %d", result.StatusHistory.ChangedQuantity)
|
||
}
|
||
if result.StatusHistory.ChangedBy != "system" {
|
||
t.Errorf("expected changed_by 'system', got '%s'", result.StatusHistory.ChangedBy)
|
||
}
|
||
if result.NewComponentItemID != nil {
|
||
t.Error("expected NewComponentItemID to be nil for case 1")
|
||
}
|
||
if result.MergedComponentItemID != nil {
|
||
t.Error("expected MergedComponentItemID to be nil for case 1")
|
||
}
|
||
|
||
// Verify DB state
|
||
updated, err := q.GetComponentItemByID(context.Background(), itemID)
|
||
if err != nil {
|
||
t.Fatalf("get updated item: %v", err)
|
||
}
|
||
if updated.Status != db.ComponentItemStatusEnumDamaged {
|
||
t.Errorf("expected status 'damaged', got '%s'", updated.Status)
|
||
}
|
||
if updated.Quantity != 20 {
|
||
t.Errorf("expected quantity 20, got %d", updated.Quantity)
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Case1_ChangeAll_ExplicitQuantity(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 15, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
changedQty := int32(15)
|
||
result, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, &changedQty, "", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
if result.StatusHistory.ChangedQuantity != 15 {
|
||
t.Errorf("expected changed quantity 15, got %d", result.StatusHistory.ChangedQuantity)
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Case2_Split_NoExistingTarget(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 20, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
changedQty := int32(5)
|
||
result, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, &changedQty, "split test", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
|
||
// Verify result
|
||
if result.NewComponentItemID == nil {
|
||
t.Fatal("expected NewComponentItemID to be set for case 2")
|
||
}
|
||
if result.MergedComponentItemID != nil {
|
||
t.Error("expected MergedComponentItemID to be nil for case 2")
|
||
}
|
||
|
||
// Original record should have reduced quantity
|
||
orig, err := q.GetComponentItemByID(context.Background(), itemID)
|
||
if err != nil {
|
||
t.Fatalf("get original item: %v", err)
|
||
}
|
||
if orig.Quantity != 15 {
|
||
t.Errorf("expected original quantity 15, got %d", orig.Quantity)
|
||
}
|
||
if orig.Status != db.ComponentItemStatusEnumNormal {
|
||
t.Errorf("expected original status 'normal', got '%s'", orig.Status)
|
||
}
|
||
|
||
// New record should have the split quantity with target status
|
||
newItem, err := q.GetComponentItemByID(context.Background(), *result.NewComponentItemID)
|
||
if err != nil {
|
||
t.Fatalf("get new item: %v", err)
|
||
}
|
||
if newItem.Quantity != 5 {
|
||
t.Errorf("expected new item quantity 5, got %d", newItem.Quantity)
|
||
}
|
||
if newItem.Status != db.ComponentItemStatusEnumDamaged {
|
||
t.Errorf("expected new item status 'damaged', got '%s'", newItem.Status)
|
||
}
|
||
if newItem.ComponentID != orig.ComponentID {
|
||
t.Error("new item should have same component_id")
|
||
}
|
||
if newItem.ContainerID != orig.ContainerID {
|
||
t.Error("new item should have same container_id")
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Case3_Merge_ExistingTarget(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 20, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
// Pre-create a damaged record to merge into
|
||
ctx := context.Background()
|
||
existingDamaged, err := q.CreateComponentItem(ctx, db.CreateComponentItemParams{
|
||
ComponentID: compID,
|
||
ContainerID: contID,
|
||
Quantity: 3,
|
||
Status: db.ComponentItemStatusEnumDamaged,
|
||
Metadata: []byte("{}"),
|
||
CreatedAt: time.Now(),
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("pre-create damaged record: %v", err)
|
||
}
|
||
|
||
changedQty := int32(5)
|
||
result, err := UpdateComponentItemStatus(ctx, pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, &changedQty, "merge test", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
|
||
// Verify result
|
||
if result.NewComponentItemID != nil {
|
||
t.Error("expected NewComponentItemID to be nil for case 3")
|
||
}
|
||
if result.MergedComponentItemID == nil {
|
||
t.Fatal("expected MergedComponentItemID to be set for case 3")
|
||
}
|
||
if *result.MergedComponentItemID != existingDamaged.ID {
|
||
t.Errorf("expected merged ID %d, got %d", existingDamaged.ID, *result.MergedComponentItemID)
|
||
}
|
||
|
||
// Original record should have reduced quantity
|
||
orig, err := q.GetComponentItemByID(ctx, itemID)
|
||
if err != nil {
|
||
t.Fatalf("get original item: %v", err)
|
||
}
|
||
if orig.Quantity != 15 {
|
||
t.Errorf("expected original quantity 15, got %d", orig.Quantity)
|
||
}
|
||
|
||
// Merged record should have increased quantity
|
||
merged, err := q.GetComponentItemByID(ctx, existingDamaged.ID)
|
||
if err != nil {
|
||
t.Fatalf("get merged item: %v", err)
|
||
}
|
||
if merged.Quantity != 8 { // 3 + 5
|
||
t.Errorf("expected merged quantity 8, got %d", merged.Quantity)
|
||
}
|
||
if merged.Status != db.ComponentItemStatusEnumDamaged {
|
||
t.Errorf("expected merged status 'damaged', got '%s'", merged.Status)
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Edge_StatusUnchanged(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 10, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
_, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumNormal, nil, "", "system")
|
||
if err == nil {
|
||
t.Fatal("expected error for status unchanged")
|
||
}
|
||
if err.Error() != "status unchanged" {
|
||
t.Errorf("expected 'status unchanged', got '%s'", err.Error())
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Edge_ChangedQuantityZero(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 10, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
changedQty := int32(0)
|
||
_, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, &changedQty, "", "system")
|
||
if err == nil {
|
||
t.Fatal("expected error for zero changed_quantity")
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Edge_ChangedQuantityNegative(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 10, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
changedQty := int32(-5)
|
||
_, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, &changedQty, "", "system")
|
||
if err == nil {
|
||
t.Fatal("expected error for negative changed_quantity")
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Edge_ChangedQuantityExceedsQuantity(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 10, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
changedQty := int32(25)
|
||
_, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, &changedQty, "", "system")
|
||
if err == nil {
|
||
t.Fatal("expected error for changed_quantity > quantity")
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Edge_ItemNotFound(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
|
||
_, err := UpdateComponentItemStatus(context.Background(), pool, 999999,
|
||
db.ComponentItemStatusEnumDamaged, nil, "", "system")
|
||
if err == nil {
|
||
t.Fatal("expected error for non-existent item")
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_Edge_QuantityBecomesZero(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 5, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
// Change all 5 to damaged → original record quantity becomes 0 → should be deleted
|
||
changedQty := int32(5)
|
||
_, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, &changedQty, "zero qty test", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
|
||
// The original record should be deleted (quantity became 0)
|
||
_, err = q.GetComponentItemByID(context.Background(), itemID)
|
||
if err == nil {
|
||
t.Error("expected original item to be deleted when quantity becomes 0")
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_ChangeToPendingInspection(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 30, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
result, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumPendingInspection, nil, "pending inspection check", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
|
||
if result.StatusHistory.NewStatus != "pending_inspection" {
|
||
t.Errorf("expected new status 'pending_inspection', got '%s'", result.StatusHistory.NewStatus)
|
||
}
|
||
|
||
updated, _ := q.GetComponentItemByID(context.Background(), itemID)
|
||
if updated.Status != db.ComponentItemStatusEnumPendingInspection {
|
||
t.Errorf("expected status 'pending_inspection', got '%s'", updated.Status)
|
||
}
|
||
}
|
||
|
||
func TestUpdateComponentItemStatus_HistoryRecordIntegrity(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 10, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
result, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumLongUnused, nil, "history integrity test note", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
|
||
history := result.StatusHistory
|
||
if history.ComponentItemID != itemID {
|
||
t.Errorf("expected component_item_id %d, got %d", itemID, history.ComponentItemID)
|
||
}
|
||
if history.OldStatus != "normal" {
|
||
t.Errorf("expected old_status 'normal', got '%s'", history.OldStatus)
|
||
}
|
||
if history.NewStatus != "long_unused" {
|
||
t.Errorf("expected new_status 'long_unused', got '%s'", history.NewStatus)
|
||
}
|
||
if history.Note != "history integrity test note" {
|
||
t.Errorf("expected note 'history integrity test note', got '%s'", history.Note)
|
||
}
|
||
if history.ChangedBy != "system" {
|
||
t.Errorf("expected changed_by 'system', got '%s'", history.ChangedBy)
|
||
}
|
||
if history.ChangedQuantity != 10 {
|
||
t.Errorf("expected changed_quantity 10, got %d", history.ChangedQuantity)
|
||
}
|
||
if history.ID == 0 {
|
||
t.Error("expected history ID to be non-zero")
|
||
}
|
||
}
|
||
|
||
// TestUpdateComponentItemStatus_ResultType ensures the UpdateStatusResult domain
|
||
// model is populated correctly.
|
||
func TestUpdateComponentItemStatus_ResultType(t *testing.T) {
|
||
pool := testDB(t)
|
||
defer pool.Close()
|
||
q := db.New(pool)
|
||
itemID, compID, contID := seedComponentItem(t, pool, q, 10, db.ComponentItemStatusEnumNormal)
|
||
defer cleanupSeeded(t, pool, itemID, compID, contID)
|
||
|
||
result, err := UpdateComponentItemStatus(context.Background(), pool, itemID,
|
||
db.ComponentItemStatusEnumDamaged, nil, "", "system")
|
||
if err != nil {
|
||
t.Fatalf("unexpected error: %v", err)
|
||
}
|
||
|
||
// Verify UpdateStatusResult fields
|
||
var _ models.UpdateStatusResult = result // compile-time check
|
||
if result.ComponentItem.ID == 0 && result.NewComponentItemID == nil && result.MergedComponentItemID == nil {
|
||
// Case 1 doesn't set ComponentItem either in current impl — that's fine
|
||
// ComponentItem is only set in Case 1 (change all). Let's verify.
|
||
// Actually looking at the repo code, ComponentItem is only set in Case 1.
|
||
// For Case 2/3 it's not set because the original item is only partially changed.
|
||
// This is intentional.
|
||
|
||
// For Case 1, ComponentItem should be set
|
||
if result.ComponentItem.ID == 0 {
|
||
t.Error("expected ComponentItem.ID to be set for Case 1 (change all)")
|
||
}
|
||
}
|
||
if result.StatusHistory.ID == 0 {
|
||
t.Error("expected StatusHistory.ID to be non-zero")
|
||
}
|
||
}
|