package routes import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gin-gonic/gin" "gorm.io/driver/sqlite" "gorm.io/gorm" marketinghandler "wx_service/internal/marketing/handler" marketingmodel "wx_service/internal/marketing/model" marketingrepo "wx_service/internal/marketing/repository" marketingservice "wx_service/internal/marketing/service" middlewarepkg "wx_service/internal/middleware" "wx_service/internal/model" ) func setupMarketingRouter(t *testing.T, adminToken string) *gin.Engine { t.Helper() gin.SetMode(gin.TestMode) db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{}) if err != nil { t.Fatalf("open sqlite: %v", err) } if err := db.AutoMigrate(&marketingmodel.MarketingCategory{}, &marketingmodel.MarketingTemplate{}, &marketingmodel.MarketingDownload{}); err != nil { t.Fatalf("auto migrate: %v", err) } categoryRepo := marketingrepo.NewCategoryRepository(db) templateRepo := marketingrepo.NewTemplateRepository(db) downloadRepo := marketingrepo.NewDownloadRepository(db) categorySvc := marketingservice.NewCategoryService(categoryRepo) templateSvc := marketingservice.NewTemplateService(templateRepo) downloadSvc := marketingservice.NewDownloadService(downloadRepo, templateRepo) categoryHandler := marketinghandler.NewCategoryHandler(categorySvc) templateHandler := marketinghandler.NewTemplateHandler(templateSvc) downloadHandler := marketinghandler.NewDownloadHandler(downloadSvc) cat := &marketingmodel.MarketingCategory{ Name: "节日海报", SortOrder: 1, Status: 1, } if err := db.Create(cat).Error; err != nil { t.Fatalf("seed category: %v", err) } tpl := &marketingmodel.MarketingTemplate{ CategoryID: cat.ID, Title: "模板A", ImageURL: "https://example.com/a.jpg", ThumbnailURL: "https://example.com/a_thumb.jpg", Width: 1080, Height: 1920, SortOrder: 1, Status: 1, } if err := db.Create(tpl).Error; err != nil { t.Fatalf("seed template: %v", err) } router := gin.New() api := router.Group("/api/v1") protected := api.Group("") protected.Use(func(c *gin.Context) { c.Set(middlewarepkg.ContextCurrentUserKey, &model.User{ ID: 1, MiniProgramID: 1, }) c.Next() }) registerMarketingRoutes(api, protected, adminToken, categoryHandler, templateHandler, downloadHandler) return router } func TestMarketingRoutes_AdminTokenMiddleware(t *testing.T) { router := setupMarketingRouter(t, "test-token") reqWithoutToken := httptest.NewRequest(http.MethodGet, "/api/v1/admin/marketing/categories", nil) w1 := httptest.NewRecorder() router.ServeHTTP(w1, reqWithoutToken) if w1.Code != http.StatusUnauthorized { t.Fatalf("expected 401 without token, got %d", w1.Code) } reqWithToken := httptest.NewRequest(http.MethodGet, "/api/v1/admin/marketing/categories", nil) reqWithToken.Header.Set("X-Admin-Token", "test-token") w2 := httptest.NewRecorder() router.ServeHTTP(w2, reqWithToken) if w2.Code != http.StatusOK { t.Fatalf("expected 200 with token, got %d, body=%s", w2.Code, w2.Body.String()) } } func TestMarketingRoutes_ProtectedDownloadRoute(t *testing.T) { router := setupMarketingRouter(t, "test-token") payload := map[string]interface{}{ "template_id": 1, "logo_url": "https://example.com/logo.png", "logo_x": 0.2, "logo_y": 0.3, "logo_w": 0.4, "logo_h": 0.5, } body, _ := json.Marshal(payload) req := httptest.NewRequest(http.MethodPost, "/api/v1/marketing/downloads", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() router.ServeHTTP(w, req) if w.Code != http.StatusOK { t.Fatalf("expected 200, got %d, body=%s", w.Code, w.Body.String()) } }