Files
agent/backend/internal/logic/projects/handlers_test.go

97 lines
3.6 KiB
Go

package projects
import (
"bytes"
"encoding/json"
"mime/multipart"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/require"
"senlinai-agent/backend/internal/config"
"senlinai-agent/backend/internal/httpx"
"senlinai-agent/backend/internal/logic/files"
"senlinai-agent/backend/internal/models"
)
func TestCreateTaskHandlerPersistsTask(t *testing.T) {
router, project, _ := newProjectsHandlerTestRouter(t)
body, err := json.Marshal(gin.H{"title": "整理需求", "description": "形成任务清单", "dueAt": "2026-07-21T09:30:00Z"})
require.NoError(t, err)
req := httptest.NewRequest(http.MethodPost, "/api/projects/1/tasks", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer test-token")
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
require.Equal(t, http.StatusCreated, rec.Code)
var task models.SenlinAgentTask
require.NoError(t, models.DBService.Where("project_id = ? AND title = ?", project.ID, "整理需求").First(&task).Error)
require.Equal(t, "open", task.Status)
require.NotNil(t, task.DueAt)
}
func TestUploadSourceHandlerStoresFileAndSource(t *testing.T) {
router, project, storageDir := newProjectsHandlerTestRouter(t)
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
require.NoError(t, writer.WriteField("title", "客户资料.txt"))
fileWriter, err := writer.CreateFormFile("file", "客户资料.txt")
require.NoError(t, err)
_, err = fileWriter.Write([]byte("hello"))
require.NoError(t, err)
require.NoError(t, writer.Close())
req := httptest.NewRequest(http.MethodPost, "/api/projects/1/sources", body)
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", "Bearer test-token")
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
require.Equal(t, http.StatusCreated, rec.Code)
var source models.SenlinAgentSource
require.NoError(t, models.DBService.Where("project_id = ? AND kind = ?", project.ID, "file").First(&source).Error)
require.Equal(t, "客户资料.txt", source.Title)
require.NotEmpty(t, source.FilePath)
require.FileExists(t, filepath.Join(storageDir, source.FilePath))
}
func TestCreateCronPlanHandlerPersistsPlan(t *testing.T) {
router, project, _ := newProjectsHandlerTestRouter(t)
body, err := json.Marshal(gin.H{"title": "每日整理", "schedule": "0 9 * * *", "enabled": true, "nextRunAt": "2026-07-22T08:00:00Z"})
require.NoError(t, err)
req := httptest.NewRequest(http.MethodPost, "/api/projects/1/cron-plans", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer test-token")
rec := httptest.NewRecorder()
router.ServeHTTP(rec, req)
require.Equal(t, http.StatusCreated, rec.Code)
var plan models.SenlinAgentCronPlan
require.NoError(t, models.DBService.Where("project_id = ? AND title = ?", project.ID, "每日整理").First(&plan).Error)
require.Equal(t, "0 9 * * *", plan.Schedule)
require.True(t, plan.Enabled)
require.NotNil(t, plan.NextRunAt)
}
func newProjectsHandlerTestRouter(t *testing.T) (*gin.Engine, *models.SenlinAgentProject, string) {
t.Helper()
newTestDB(t)
require.NoError(t, models.DBService.Create(&models.SenlinAgentUser{Email: "david@example.com", DisplayName: "David", PasswordHash: "hash"}).Error)
service := NewService()
project, err := service.CreateProject(1, "Alpha", "")
require.NoError(t, err)
storageDir := t.TempDir()
router := httpx.NewProtectedRouter(
config.Config{Env: "test"},
func(token string) (uint, error) { return 1, nil },
NewHandler(service, files.NewService(storageDir)),
)
return router, project, storageDir
}