|
- package controller
-
- import (
- "bytes"
- "encoding/json"
- "net/http"
- "net/http/httptest"
- "strconv"
- "testing"
-
- "github.com/QuantumNous/new-api/common"
- "github.com/QuantumNous/new-api/model"
- "github.com/glebarez/sqlite"
- "github.com/gin-gonic/gin"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "gorm.io/gorm"
- )
-
- func setupEmailQuotaRuleControllerDB(t *testing.T) *gorm.DB {
- t.Helper()
- db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
- require.NoError(t, err)
- sqlDB, _ := db.DB()
- sqlDB.SetMaxOpenConns(1)
-
- origDB := model.DB
- model.DB = db
- common.UsingSQLite = true
- common.RedisEnabled = false
-
- require.NoError(t, db.AutoMigrate(&model.EmailQuotaRule{}))
-
- t.Cleanup(func() {
- model.DB = origDB
- sqlDB.Close()
- })
- return db
- }
-
- func setupEmailQuotaRuleRouter() *gin.Engine {
- gin.SetMode(gin.TestMode)
- r := gin.New()
- g := r.Group("/api/email_quota_rule")
- {
- g.GET("/", GetAllEmailQuotaRules)
- g.POST("/", CreateEmailQuotaRule)
- g.PUT("/:id", UpdateEmailQuotaRule)
- g.DELETE("/:id", DeleteEmailQuotaRule)
- }
- return r
- }
-
- func TestGetAllEmailQuotaRules_Empty(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/api/email_quota_rule/", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, http.StatusOK, w.Code)
- var resp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
- assert.True(t, resp["success"].(bool))
- assert.Empty(t, resp["data"])
- }
-
- func TestCreateEmailQuotaRule_Success(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- body, _ := json.Marshal(map[string]interface{}{
- "email_suffix": "@test.com",
- "quota": 500000,
- "description": "Test company",
- })
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("POST", "/api/email_quota_rule/", bytes.NewReader(body))
- req.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w, req)
-
- assert.Equal(t, http.StatusOK, w.Code)
- var resp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
- assert.True(t, resp["success"].(bool))
-
- data := resp["data"].(map[string]interface{})
- assert.Equal(t, "@test.com", data["email_suffix"])
- assert.Equal(t, float64(500000), data["quota"])
- assert.Equal(t, true, data["enabled"])
- }
-
- func TestCreateEmailQuotaRule_Duplicate(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- body, _ := json.Marshal(map[string]interface{}{
- "email_suffix": "@dup.com",
- "quota": 100,
- })
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("POST", "/api/email_quota_rule/", bytes.NewReader(body))
- req.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w, req)
- var firstResp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &firstResp))
- assert.True(t, firstResp["success"].(bool))
-
- // Second create should fail
- w2 := httptest.NewRecorder()
- req2, _ := http.NewRequest("POST", "/api/email_quota_rule/", bytes.NewReader(body))
- req2.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w2, req2)
-
- var resp2 map[string]interface{}
- require.NoError(t, json.Unmarshal(w2.Body.Bytes(), &resp2))
- assert.False(t, resp2["success"].(bool))
- }
-
- func TestCreateEmailQuotaRule_MissingFields(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- body, _ := json.Marshal(map[string]interface{}{
- "description": "no suffix",
- })
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("POST", "/api/email_quota_rule/", bytes.NewReader(body))
- req.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w, req)
-
- var resp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
- assert.False(t, resp["success"].(bool))
- }
-
- func TestUpdateEmailQuotaRule_Success(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- // Create first
- rule := &model.EmailQuotaRule{EmailSuffix: "@up.com", Quota: 100, Enabled: true}
- require.NoError(t, rule.Insert())
-
- body, _ := json.Marshal(map[string]interface{}{
- "quota": 999,
- "description": "updated desc",
- })
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("PUT", "/api/email_quota_rule/"+itoa(rule.Id), bytes.NewReader(body))
- req.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w, req)
-
- var resp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
- assert.True(t, resp["success"].(bool))
-
- data := resp["data"].(map[string]interface{})
- assert.Equal(t, float64(999), data["quota"])
- assert.Equal(t, "updated desc", data["description"])
- }
-
- func TestUpdateEmailQuotaRule_ToggleEnabled(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- rule := &model.EmailQuotaRule{EmailSuffix: "@toggle.com", Quota: 500, Enabled: true}
- require.NoError(t, rule.Insert())
-
- body, _ := json.Marshal(map[string]interface{}{
- "enabled": false,
- })
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("PUT", "/api/email_quota_rule/"+itoa(rule.Id), bytes.NewReader(body))
- req.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w, req)
-
- var resp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
- assert.True(t, resp["success"].(bool))
-
- data := resp["data"].(map[string]interface{})
- assert.Equal(t, false, data["enabled"])
-
- // Cache should reflect disabled
- assert.Equal(t, int64(-1), model.MatchEmailQuotaRule("user@toggle.com"))
- }
-
- func TestDeleteEmailQuotaRule_Success(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- rule := &model.EmailQuotaRule{EmailSuffix: "@del.com", Quota: 100, Enabled: true}
- require.NoError(t, rule.Insert())
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("DELETE", "/api/email_quota_rule/"+itoa(rule.Id), nil)
- router.ServeHTTP(w, req)
-
- var resp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &resp))
- assert.True(t, resp["success"].(bool))
-
- // Verify deleted
- assert.Equal(t, int64(-1), model.MatchEmailQuotaRule("user@del.com"))
- }
-
- func TestCRUD_FullFlow(t *testing.T) {
- setupEmailQuotaRuleControllerDB(t)
- router := setupEmailQuotaRuleRouter()
-
- // 1. Create
- body, _ := json.Marshal(map[string]interface{}{
- "email_suffix": "@full.com",
- "quota": 1000,
- "description": "full flow test",
- })
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("POST", "/api/email_quota_rule/", bytes.NewReader(body))
- req.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w, req)
- var createResp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &createResp))
- assert.True(t, createResp["success"].(bool))
-
- // 2. List
- w = httptest.NewRecorder()
- req, _ = http.NewRequest("GET", "/api/email_quota_rule/", nil)
- router.ServeHTTP(w, req)
- var listResp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &listResp))
- data := listResp["data"].([]interface{})
- assert.Len(t, data, 1)
-
- // 3. Update
- ruleId := itoa(int(data[0].(map[string]interface{})["id"].(float64)))
- body, _ = json.Marshal(map[string]interface{}{"quota": 2000})
- w = httptest.NewRecorder()
- req, _ = http.NewRequest("PUT", "/api/email_quota_rule/"+ruleId, bytes.NewReader(body))
- req.Header.Set("Content-Type", "application/json")
- router.ServeHTTP(w, req)
- var updateResp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &updateResp))
- assert.True(t, updateResp["success"].(bool))
-
- // 4. Verify cache
- assert.Equal(t, int64(2000), model.MatchEmailQuotaRule("user@full.com"))
-
- // 5. Delete
- w = httptest.NewRecorder()
- req, _ = http.NewRequest("DELETE", "/api/email_quota_rule/"+ruleId, nil)
- router.ServeHTTP(w, req)
- var delResp map[string]interface{}
- require.NoError(t, json.Unmarshal(w.Body.Bytes(), &delResp))
- assert.True(t, delResp["success"].(bool))
-
- // 6. Verify cache cleared
- assert.Equal(t, int64(-1), model.MatchEmailQuotaRule("user@full.com"))
- }
-
- func itoa(i int) string {
- return strconv.Itoa(i)
- }
|