376 lines
14 KiB
Go
Executable File
376 lines
14 KiB
Go
Executable File
package test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/rovina/zsp-backend/internal/handler"
|
|
"github.com/rovina/zsp-backend/internal/model"
|
|
"github.com/rovina/zsp-backend/internal/service"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// mockDeliveryService implements service.DeliveryService for testing
|
|
type mockDeliveryService struct {
|
|
listApplyFn func(page, pageSize int, orderNumber, blNumber, status string) ([]model.DeliveryApply, int64, error)
|
|
getApplyByIDFn func(id uint) (*model.DeliveryApply, error)
|
|
createApplyFn func(e *model.DeliveryApply) error
|
|
deleteApplyFn func(id uint) error
|
|
listOutboundFn func(page, pageSize int, outboundNumber, blNumber, status string) ([]model.DeliveryOutbound, int64, error)
|
|
getOutboundByIDFn func(id uint) (*model.DeliveryOutbound, error)
|
|
createOutboundFn func(e *model.DeliveryOutbound) error
|
|
deleteOutboundFn func(id uint) error
|
|
listWarehousesFn func() ([]model.Warehouse, error)
|
|
createWarehouseFn func(e *model.Warehouse) error
|
|
deleteWarehouseFn func(id uint) error
|
|
listInboundFn func(page, pageSize int, warehouse, commodity string) ([]model.InventoryInbound, int64, error)
|
|
createInboundFn func(e *model.InventoryInbound) error
|
|
deleteInboundFn func(id uint) error
|
|
listOwnershipFn func(page, pageSize int, transferNumber, blNumber, status string) ([]model.OwnershipTransfer, int64, error)
|
|
deleteOwnershipFn func(id uint) error
|
|
dbFn func() *gorm.DB
|
|
}
|
|
|
|
func (m *mockDeliveryService) ListApply(page, pageSize int, orderNumber, blNumber, status string) ([]model.DeliveryApply, int64, error) {
|
|
return m.listApplyFn(page, pageSize, orderNumber, blNumber, status)
|
|
}
|
|
func (m *mockDeliveryService) GetApplyByID(id uint) (*model.DeliveryApply, error) { return m.getApplyByIDFn(id) }
|
|
func (m *mockDeliveryService) CreateApply(e *model.DeliveryApply) error { return m.createApplyFn(e) }
|
|
func (m *mockDeliveryService) UpdateApply(e *model.DeliveryApply) error { return nil }
|
|
func (m *mockDeliveryService) DeleteApply(id uint) error { return m.deleteApplyFn(id) }
|
|
|
|
func (m *mockDeliveryService) ListOutbound(page, pageSize int, outboundNumber, blNumber, status string) ([]model.DeliveryOutbound, int64, error) {
|
|
return m.listOutboundFn(page, pageSize, outboundNumber, blNumber, status)
|
|
}
|
|
func (m *mockDeliveryService) GetOutboundByID(id uint) (*model.DeliveryOutbound, error) { return m.getOutboundByIDFn(id) }
|
|
func (m *mockDeliveryService) CreateOutbound(e *model.DeliveryOutbound) error { return m.createOutboundFn(e) }
|
|
func (m *mockDeliveryService) UpdateOutbound(e *model.DeliveryOutbound) error { return nil }
|
|
func (m *mockDeliveryService) DeleteOutbound(id uint) error { return m.deleteOutboundFn(id) }
|
|
|
|
func (m *mockDeliveryService) ListWarehouses() ([]model.Warehouse, error) { return m.listWarehousesFn() }
|
|
func (m *mockDeliveryService) GetWarehouseByID(id uint) (*model.Warehouse, error) { return nil, nil }
|
|
func (m *mockDeliveryService) CreateWarehouse(e *model.Warehouse) error { return m.createWarehouseFn(e) }
|
|
func (m *mockDeliveryService) UpdateWarehouse(e *model.Warehouse) error { return nil }
|
|
func (m *mockDeliveryService) DeleteWarehouse(id uint) error { return m.deleteWarehouseFn(id) }
|
|
|
|
func (m *mockDeliveryService) ListInbound(page, pageSize int, warehouse, commodity string) ([]model.InventoryInbound, int64, error) {
|
|
return m.listInboundFn(page, pageSize, warehouse, commodity)
|
|
}
|
|
func (m *mockDeliveryService) GetInboundByID(id uint) (*model.InventoryInbound, error) { return nil, nil }
|
|
func (m *mockDeliveryService) CreateInbound(e *model.InventoryInbound) error { return m.createInboundFn(e) }
|
|
func (m *mockDeliveryService) UpdateInbound(e *model.InventoryInbound) error { return nil }
|
|
func (m *mockDeliveryService) DeleteInbound(id uint) error { return m.deleteInboundFn(id) }
|
|
|
|
func (m *mockDeliveryService) ListOwnership(page, pageSize int, transferNumber, blNumber, status string) ([]model.OwnershipTransfer, int64, error) {
|
|
return m.listOwnershipFn(page, pageSize, transferNumber, blNumber, status)
|
|
}
|
|
func (m *mockDeliveryService) GetOwnershipByID(id uint) (*model.OwnershipTransfer, error) { return nil, nil }
|
|
func (m *mockDeliveryService) CreateOwnership(e *model.OwnershipTransfer) error { return nil }
|
|
func (m *mockDeliveryService) DeleteOwnership(id uint) error { return m.deleteOwnershipFn(id) }
|
|
func (m *mockDeliveryService) CreateOwnershipFiles(files []model.OwnershipTransferFile) error { return nil }
|
|
func (m *mockDeliveryService) DB() *gorm.DB { return nil }
|
|
|
|
var _ service.DeliveryService = (*mockDeliveryService)(nil)
|
|
|
|
func setupDeliveryRouter(h *handler.DeliveryHandler) *gin.Engine {
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
api := r.Group("/api")
|
|
{
|
|
applyDelivery := api.Group("/apply-delivery")
|
|
{
|
|
applyDelivery.GET("", h.ListApply)
|
|
applyDelivery.POST("", h.CreateApply)
|
|
applyDelivery.DELETE("/:id", h.DeleteApply)
|
|
}
|
|
deliveryDetails := api.Group("/delivery-details")
|
|
{
|
|
deliveryDetails.GET("", h.ListOutbound)
|
|
deliveryDetails.POST("", h.CreateOutbound)
|
|
deliveryDetails.DELETE("/:id", h.DeleteOutbound)
|
|
}
|
|
inventory := api.Group("/inventory")
|
|
{
|
|
inventory.GET("/warehouses", h.ListWarehouses)
|
|
inventory.POST("/warehouses", h.CreateWarehouse)
|
|
inventory.DELETE("/warehouses/:id", h.DeleteWarehouse)
|
|
inventory.POST("/inbound", h.CreateInbound)
|
|
inventory.DELETE("/inbound/:id", h.DeleteInbound)
|
|
}
|
|
ownershipTransfer := api.Group("/ownership-transfer")
|
|
{
|
|
ownershipTransfer.GET("", h.ListOwnership)
|
|
ownershipTransfer.DELETE("/:id", h.DeleteOwnership)
|
|
}
|
|
}
|
|
return r
|
|
}
|
|
|
|
// ========== 我要提货 /api/apply-delivery ==========
|
|
|
|
func TestDeliveryListApply_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
listApplyFn: func(page, pageSize int, orderNumber, blNumber, status string) ([]model.DeliveryApply, int64, error) {
|
|
return []model.DeliveryApply{
|
|
{ID: 1, OrderNumber: "DA001", Status: "pending"},
|
|
{ID: 2, OrderNumber: "DA002", Status: "approved"},
|
|
}, 2, nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/apply-delivery?page=1&pageSize=10", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
|
|
var resp map[string]interface{}
|
|
json.Unmarshal(w.Body.Bytes(), &resp)
|
|
if resp["success"] != true {
|
|
t.Errorf("expected success true, got %v", resp["success"])
|
|
}
|
|
}
|
|
|
|
func TestDeliveryCreateApply_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
createApplyFn: func(e *model.DeliveryApply) error {
|
|
e.ID = 1
|
|
e.OrderNumber = "DA1234567890"
|
|
return nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
body := `{"blNumber":"BL001","commodity":"燕麦","quantity":100}`
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/apply-delivery", bytes.NewReader([]byte(body)))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryDeleteApply_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
deleteApplyFn: func(id uint) error { return nil },
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("DELETE", "/api/apply-delivery/1", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryDeleteApply_NotFound(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
deleteApplyFn: func(id uint) error { return errors.New("not found") },
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("DELETE", "/api/apply-delivery/999", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusInternalServerError {
|
|
t.Errorf("expected status 500, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
// ========== 提货明细 /api/delivery-details ==========
|
|
|
|
func TestDeliveryListOutbound_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
listOutboundFn: func(page, pageSize int, outboundNumber, blNumber, status string) ([]model.DeliveryOutbound, int64, error) {
|
|
return []model.DeliveryOutbound{
|
|
{ID: 1, OutboundNumber: "OB001", OutboundStatus: "completed"},
|
|
}, 1, nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/delivery-details?page=1&pageSize=10", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryCreateOutbound_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
createOutboundFn: func(e *model.DeliveryOutbound) error {
|
|
e.ID = 1
|
|
e.OutboundNumber = "OB1234567890"
|
|
return nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
body := `{"blNumber":"BL001","warehouse":"A库","quantity":50}`
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/delivery-details", bytes.NewReader([]byte(body)))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryDeleteOutbound_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
deleteOutboundFn: func(id uint) error { return nil },
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("DELETE", "/api/delivery-details/1", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
// ========== 库存 /api/inventory ==========
|
|
|
|
func TestDeliveryListWarehouses_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
listWarehousesFn: func() ([]model.Warehouse, error) {
|
|
return []model.Warehouse{
|
|
{ID: 1, Name: "A库", Status: "active"},
|
|
{ID: 2, Name: "B库", Status: "active"},
|
|
}, nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/inventory/warehouses", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryCreateWarehouse_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
createWarehouseFn: func(e *model.Warehouse) error {
|
|
e.ID = 1
|
|
return nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
body := `{"name":"C库","location":"广州"}`
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/inventory/warehouses", bytes.NewReader([]byte(body)))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryDeleteWarehouse_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
deleteWarehouseFn: func(id uint) error { return nil },
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("DELETE", "/api/inventory/warehouses/1", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryCreateInbound_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
createInboundFn: func(e *model.InventoryInbound) error {
|
|
e.ID = 1
|
|
e.InboundNumber = "IN1234567890"
|
|
return nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
body := `{"warehouse":"A库","commodity":"燕麦","inboundWeight":1000}`
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/inventory/inbound", bytes.NewReader([]byte(body)))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
// ========== 货权转移 /api/ownership-transfer ==========
|
|
|
|
func TestDeliveryListOwnership_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
listOwnershipFn: func(page, pageSize int, transferNumber, blNumber, status string) ([]model.OwnershipTransfer, int64, error) {
|
|
return []model.OwnershipTransfer{
|
|
{ID: 1, TransferNumber: "OT001", Status: "draft"},
|
|
}, 1, nil
|
|
},
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/ownership-transfer?page=1&pageSize=10", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestDeliveryDeleteOwnership_Success(t *testing.T) {
|
|
mock := &mockDeliveryService{
|
|
deleteOwnershipFn: func(id uint) error { return nil },
|
|
}
|
|
h := handler.NewDeliveryHandler(mock)
|
|
router := setupDeliveryRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("DELETE", "/api/ownership-transfer/1", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|