120 lines
3.7 KiB
Go
120 lines
3.7 KiB
Go
package repository
|
|
|
|
import (
|
|
"database/sql"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/wmms/wmms/internal/model"
|
|
)
|
|
|
|
func TestOutboundRepoOrganizationIsolationReads(t *testing.T) {
|
|
db := isolationDB(t, false)
|
|
seedOrderIsolation(t, db)
|
|
repo := NewOutboundRepo()
|
|
|
|
ownOrder, err := repo.GetByID(102, 102)
|
|
if err != nil || ownOrder.ID != 102 || ownOrder.OrganizationID != 102 {
|
|
t.Fatalf("B 读自己的单据失败: %+v err=%v", ownOrder, err)
|
|
}
|
|
if _, err := repo.GetByID(102, 101); err != sql.ErrNoRows {
|
|
t.Fatalf("B 读 A 的单据必须 ErrNoRows, got %v", err)
|
|
}
|
|
|
|
ordersA, totalA, err := repo.List(101, "", 20, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if totalA != 1 || len(ordersA) != 1 || ordersA[0].ID != 101 {
|
|
t.Fatalf("A 列表=%+v total=%d", ordersA, totalA)
|
|
}
|
|
ordersB, totalB, err := repo.List(102, "", 20, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if totalB != 1 || len(ordersB) != 1 || ordersB[0].ID != 102 {
|
|
t.Fatalf("B 列表=%+v total=%d", ordersB, totalB)
|
|
}
|
|
|
|
recordsB, err := repo.GetByMaterialID(102, 102)
|
|
if err != nil || len(recordsB) != 1 {
|
|
t.Fatalf("B 物料历史=%+v err=%v", recordsB, err)
|
|
}
|
|
recordsCross, err := repo.GetByMaterialID(102, 101)
|
|
if err != nil || len(recordsCross) != 0 {
|
|
t.Fatalf("B 读 A 物料历史必须为空, got %+v err=%v", recordsCross, err)
|
|
}
|
|
}
|
|
|
|
func TestOutboundRepoCreatePersistsDimensionsAndRestrictsItems(t *testing.T) {
|
|
db := isolationDB(t, false)
|
|
seedOrderIsolation(t, db)
|
|
repo := NewOutboundRepo()
|
|
|
|
order := &model.OutboundOrder{
|
|
OrganizationID: 102,
|
|
WarehouseID: 102,
|
|
LocationID: 102,
|
|
OutboundDate: time.Now(),
|
|
Operator: "op",
|
|
Handler: "h",
|
|
Receiver: "r",
|
|
Items: []model.OutboundItem{{MaterialID: 102, Quantity: 2}},
|
|
}
|
|
if err := repo.Create(order); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var org, warehouse, location int64
|
|
if err := db.QueryRow(`SELECT organization_id, warehouse_id, location_id FROM outbound_orders WHERE id = ?`, order.ID).Scan(&org, &warehouse, &location); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if org != 102 || warehouse != 102 || location != 102 {
|
|
t.Fatalf("头表维度=%d/%d/%d, want 102/102/102", org, warehouse, location)
|
|
}
|
|
|
|
// 塞一条 A 的物料明细:物料外键合法,但读取时的同组织关联会把它挡掉。
|
|
mustSQL(t, db, `INSERT INTO outbound_items(outbound_order_id, material_id, quantity) VALUES (?, ?, ?)`, order.ID, 101, 9)
|
|
loaded, err := repo.GetByID(102, order.ID)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(loaded.Items) != 1 || loaded.Items[0].MaterialID != 102 {
|
|
t.Fatalf("跨公司物料明细必须被关联条件挡掉, got %+v", loaded.Items)
|
|
}
|
|
}
|
|
|
|
func TestOutboundRepoUpdateAndDeleteScopeToOrganization(t *testing.T) {
|
|
db := isolationDB(t, false)
|
|
seedOrderIsolation(t, db)
|
|
repo := NewOutboundRepo()
|
|
|
|
if err := repo.Update(102, 101, &model.UpdateOutboundRequest{Handler: "hacked", Receiver: "hacked"}); err != sql.ErrNoRows {
|
|
t.Fatalf("B 改 A 的单据必须 ErrNoRows, got %v", err)
|
|
}
|
|
var handler, receiver string
|
|
if err := db.QueryRow(`SELECT handler, receiver FROM outbound_orders WHERE id = 101`).Scan(&handler, &receiver); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if handler != "A-out" || receiver != "recA" {
|
|
t.Fatalf("A 的单据头被改动: %s/%s", handler, receiver)
|
|
}
|
|
var itemCount int
|
|
if err := db.QueryRow(`SELECT COUNT(*) FROM outbound_items WHERE outbound_order_id = 101`).Scan(&itemCount); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if itemCount != 1 {
|
|
t.Fatalf("A 的明细被改动: %d 行", itemCount)
|
|
}
|
|
|
|
if err := repo.Delete(102, 101); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var orderCount int
|
|
if err := db.QueryRow(`SELECT COUNT(*) FROM outbound_orders WHERE id = 101`).Scan(&orderCount); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if orderCount != 1 {
|
|
t.Fatal("B 删掉了 A 的单据")
|
|
}
|
|
}
|