217 lines
7.8 KiB
Go
Executable File
217 lines
7.8 KiB
Go
Executable File
package test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"mime/multipart"
|
|
"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"
|
|
)
|
|
|
|
// ----- mock contract services -----
|
|
type mockContractService struct {
|
|
listFn func(contractType string) ([]model.Contract, error)
|
|
getByIDFn func(id uint) (*model.Contract, error)
|
|
}
|
|
|
|
func (m *mockContractService) CreateContract(contract *model.Contract, files []model.ContractFile) error { return nil }
|
|
func (m *mockContractService) SaveFiles(files []model.ContractFile) error { return nil }
|
|
func (m *mockContractService) BatchSaveFiles(basePath string, files []*multipart.FileHeader) (int, error) { return 0, nil }
|
|
func (m *mockContractService) List(contractType string) ([]model.Contract, error) { return m.listFn(contractType) }
|
|
func (m *mockContractService) GetByID(id uint) (*model.Contract, error) { return m.getByIDFn(id) }
|
|
func (m *mockContractService) Update(contract *model.Contract) error { return nil }
|
|
func (m *mockContractService) UpdateWithFiles(id uint, keepFileIDs []uint, newFileModels []model.ContractFile, form map[string]string) error {
|
|
return nil
|
|
}
|
|
func (m *mockContractService) Delete(id uint) error { return nil }
|
|
|
|
type mockContractFolderService struct {
|
|
listFn func() ([]model.ContractFolder, error)
|
|
createFn func(name, description string) (*model.ContractFolder, error)
|
|
getByIDFn func(id uint) (*model.ContractFolder, error)
|
|
updateFn func(id uint, name, description string) error
|
|
deleteFn func(id uint) error
|
|
}
|
|
|
|
func (m *mockContractFolderService) List() ([]model.ContractFolder, error) { return m.listFn() }
|
|
func (m *mockContractFolderService) Create(name, description string) (*model.ContractFolder, error) { return m.createFn(name, description) }
|
|
func (m *mockContractFolderService) GetByID(id uint) (*model.ContractFolder, error) { return m.getByIDFn(id) }
|
|
func (m *mockContractFolderService) Update(id uint, name, description string) error { return m.updateFn(id, name, description) }
|
|
func (m *mockContractFolderService) Delete(id uint) error { return m.deleteFn(id) }
|
|
|
|
type mockContractBatchService struct {
|
|
listFn func(folderID *uint) ([]model.ContractBatch, error)
|
|
getByIDFn func(id uint) (*model.ContractBatch, error)
|
|
deleteFn func(id uint) error
|
|
}
|
|
|
|
func (m *mockContractBatchService) List(folderID *uint) ([]model.ContractBatch, error) { return m.listFn(folderID) }
|
|
func (m *mockContractBatchService) GetByID(id uint) (*model.ContractBatch, error) { return m.getByIDFn(id) }
|
|
func (m *mockContractBatchService) Create(folderID uint, batchName, remark string, files []model.ContractBatchFile) (*model.ContractBatch, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *mockContractBatchService) Delete(id uint) error { return m.deleteFn(id) }
|
|
|
|
func setupContractRouter(h *handler.ContractHandler) *gin.Engine {
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
api := r.Group("/api")
|
|
{
|
|
contracts := api.Group("/contract")
|
|
{
|
|
contracts.GET("", h.List)
|
|
contracts.GET("/folders", h.ListFolders)
|
|
contracts.POST("/folders", h.CreateFolder)
|
|
contracts.GET("/folders/:id", h.GetFolder)
|
|
contracts.PUT("/folders/:id", h.UpdateFolder)
|
|
contracts.DELETE("/folders/:id", h.DeleteFolder)
|
|
contracts.GET("/:id", h.Get)
|
|
}
|
|
}
|
|
return r
|
|
}
|
|
|
|
func TestContractList_Success(t *testing.T) {
|
|
mockContract := &mockContractService{
|
|
listFn: func(contractType string) ([]model.Contract, error) {
|
|
return []model.Contract{
|
|
{ID: 1, Name: "合同1", ContractCode: "C001"},
|
|
{ID: 2, Name: "合同2", ContractCode: "C002"},
|
|
}, nil
|
|
},
|
|
}
|
|
mockFolder := &mockContractFolderService{
|
|
listFn: func() ([]model.ContractFolder, error) { return nil, nil },
|
|
}
|
|
mockBatch := &mockContractBatchService{
|
|
listFn: func(folderID *uint) ([]model.ContractBatch, error) { return nil, nil },
|
|
}
|
|
|
|
h := handler.NewContractHandler(mockContract, mockFolder, mockBatch)
|
|
router := setupContractRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/contract", 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 TestContractGet_Success(t *testing.T) {
|
|
mockContract := &mockContractService{
|
|
getByIDFn: func(id uint) (*model.Contract, error) {
|
|
return &model.Contract{ID: 1, Name: "合同1", ContractCode: "C001"}, nil
|
|
},
|
|
}
|
|
mockFolder := &mockContractFolderService{
|
|
listFn: func() ([]model.ContractFolder, error) { return nil, nil },
|
|
}
|
|
mockBatch := &mockContractBatchService{
|
|
listFn: func(folderID *uint) ([]model.ContractBatch, error) { return nil, nil },
|
|
}
|
|
|
|
h := handler.NewContractHandler(mockContract, mockFolder, mockBatch)
|
|
router := setupContractRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/contract/1", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestContractGet_NotFound(t *testing.T) {
|
|
mockContract := &mockContractService{
|
|
getByIDFn: func(id uint) (*model.Contract, error) {
|
|
return nil, errors.New("contract not found")
|
|
},
|
|
}
|
|
mockFolder := &mockContractFolderService{
|
|
listFn: func() ([]model.ContractFolder, error) { return nil, nil },
|
|
}
|
|
mockBatch := &mockContractBatchService{
|
|
listFn: func(folderID *uint) ([]model.ContractBatch, error) { return nil, nil },
|
|
}
|
|
|
|
h := handler.NewContractHandler(mockContract, mockFolder, mockBatch)
|
|
router := setupContractRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/contract/999", nil)
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusNotFound {
|
|
t.Errorf("expected status 404, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestContractCreateFolder_Success(t *testing.T) {
|
|
mockContract := &mockContractService{}
|
|
mockFolder := &mockContractFolderService{
|
|
createFn: func(name, description string) (*model.ContractFolder, error) {
|
|
return &model.ContractFolder{ID: 1, Name: name, Description: description}, nil
|
|
},
|
|
}
|
|
mockBatch := &mockContractBatchService{}
|
|
|
|
h := handler.NewContractHandler(mockContract, mockFolder, mockBatch)
|
|
router := setupContractRouter(h)
|
|
|
|
body := `{"name":"测试文件夹","description":"测试描述"}`
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("POST", "/api/contract/folders", nil)
|
|
req.Body = http.NoBody
|
|
_ = body // body is unused in this simple test; the handler uses ShouldBindJSON
|
|
router.ServeHTTP(w, req)
|
|
|
|
// Without valid JSON body, this should return 400
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("expected status 400 for missing body, got %d", w.Code)
|
|
}
|
|
}
|
|
|
|
func TestContractListFolders_Success(t *testing.T) {
|
|
mockContract := &mockContractService{}
|
|
mockFolder := &mockContractFolderService{
|
|
listFn: func() ([]model.ContractFolder, error) {
|
|
return []model.ContractFolder{
|
|
{ID: 1, Name: "文件夹1"},
|
|
{ID: 2, Name: "文件夹2"},
|
|
}, nil
|
|
},
|
|
}
|
|
mockBatch := &mockContractBatchService{}
|
|
|
|
h := handler.NewContractHandler(mockContract, mockFolder, mockBatch)
|
|
router := setupContractRouter(h)
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "/api/contract/folders", 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"])
|
|
}
|
|
}
|