package admin import ( "net/http" "net/http/httptest" "testing" "github.com/Wei-Shaw/sub2api/internal/service" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" ) func TestSoraHandler_ListGenerations(t *testing.T) { gin.SetMode(gin.TestMode) handler := &SoraHandler{} w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodGet, "/admin/sora/generations", nil) handler.ListGenerations(c) assert.Equal(t, http.StatusOK, w.Code) assert.Contains(t, w.Body.String(), "items") } func TestSoraHandler_ClearUserStorage_InvalidUserID(t *testing.T) { gin.SetMode(gin.TestMode) handler := &SoraHandler{} testCases := []struct { name string userID string expected int }{ {"empty string", "", http.StatusBadRequest}, {"non-numeric", "abc", http.StatusBadRequest}, {"float", "1.5", http.StatusBadRequest}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodDelete, "/admin/sora/users/"+tc.userID+"/storage", nil) c.Params = gin.Params{{Key: "id", Value: tc.userID}} handler.ClearUserStorage(c) assert.Equal(t, tc.expected, w.Code) }) } } func TestSoraSystemStatsResponse_Fields(t *testing.T) { resp := SoraSystemStatsResponse{ TotalUsers: 10, TotalGenerations: 100, TotalStorageBytes: 1024 * 1024 * 1024, ActiveGenerations: 5, ByStatus: map[string]int64{"completed": 80, "failed": 20}, ByModel: map[string]int64{"sora2": 50, "sora1": 50}, } assert.Equal(t, int64(10), resp.TotalUsers) assert.Equal(t, int64(100), resp.TotalGenerations) assert.Equal(t, int64(1024*1024*1024), resp.TotalStorageBytes) assert.Equal(t, int64(5), resp.ActiveGenerations) assert.Equal(t, int64(80), resp.ByStatus["completed"]) assert.Equal(t, int64(50), resp.ByModel["sora2"]) } func TestSoraUserStatsResponse_Fields(t *testing.T) { resp := SoraUserStatsResponse{ UserID: 1, Username: "testuser", Email: "test@example.com", QuotaBytes: 10 * 1024 * 1024 * 1024, UsedBytes: 1 * 1024 * 1024 * 1024, AvailableBytes: 9 * 1024 * 1024 * 1024, QuotaSource: "user", GenerationsCount: 10, ActiveCount: 2, TotalFileSizeBytes: 1 * 1024 * 1024 * 1024, } assert.Equal(t, int64(1), resp.UserID) assert.Equal(t, "testuser", resp.Username) assert.Equal(t, "test@example.com", resp.Email) assert.Equal(t, int64(10*1024*1024*1024), resp.QuotaBytes) assert.Equal(t, int64(1*1024*1024*1024), resp.UsedBytes) assert.Equal(t, "user", resp.QuotaSource) assert.Equal(t, int64(10), resp.GenerationsCount) assert.Equal(t, int64(2), resp.ActiveCount) } func TestSoraGenerationAdminResponse_Fields(t *testing.T) { completedAt := "2024-01-01T12:00:00Z" resp := SoraGenerationAdminResponse{ ID: 1, UserID: 100, Username: "testuser", Email: "test@example.com", Model: "sora2", Prompt: "A beautiful sunset", MediaType: "video", Status: "completed", StorageType: "s3", MediaURL: "https://example.com/video.mp4", FileSizeBytes: 1024 * 1024 * 10, ErrorMessage: "", CreatedAt: "2024-01-01T10:00:00Z", CompletedAt: &completedAt, } assert.Equal(t, int64(1), resp.ID) assert.Equal(t, int64(100), resp.UserID) assert.Equal(t, "testuser", resp.Username) assert.Equal(t, "sora2", resp.Model) assert.Equal(t, "video", resp.MediaType) assert.Equal(t, "completed", resp.Status) assert.Equal(t, "s3", resp.StorageType) assert.Equal(t, int64(1024*1024*10), resp.FileSizeBytes) assert.NotNil(t, resp.CompletedAt) } func TestSoraGenerationAdminResponse_NilCompletedAt(t *testing.T) { resp := SoraGenerationAdminResponse{ ID: 1, UserID: 100, Username: "testuser", Email: "test@example.com", Model: "sora2", Prompt: "A beautiful sunset", MediaType: "video", Status: "pending", StorageType: "upstream", CreatedAt: "2024-01-01T10:00:00Z", CompletedAt: nil, } assert.Equal(t, "pending", resp.Status) assert.Nil(t, resp.CompletedAt) } func TestNewSoraHandler(t *testing.T) { handler := NewSoraHandler(nil, nil, nil) assert.NotNil(t, handler) assert.Nil(t, handler.soraGenService) assert.Nil(t, handler.soraQuotaService) assert.Nil(t, handler.userRepo) } func TestUser_SoraFields(t *testing.T) { user := &service.User{ ID: 1, Email: "test@example.com", SoraStorageQuotaBytes: 10 * 1024 * 1024 * 1024, SoraStorageUsedBytes: 1 * 1024 * 1024 * 1024, } assert.Equal(t, int64(1), user.ID) assert.Equal(t, int64(10*1024*1024*1024), user.SoraStorageQuotaBytes) assert.Equal(t, int64(1*1024*1024*1024), user.SoraStorageUsedBytes) } func TestQuotaInfo_Fields(t *testing.T) { quota := &service.QuotaInfo{ QuotaBytes: 10 * 1024 * 1024 * 1024, UsedBytes: 1 * 1024 * 1024 * 1024, AvailableBytes: 9 * 1024 * 1024 * 1024, QuotaSource: "user", } assert.Equal(t, int64(10*1024*1024*1024), quota.QuotaBytes) assert.Equal(t, int64(1*1024*1024*1024), quota.UsedBytes) assert.Equal(t, "user", quota.QuotaSource) } func TestSoraSystemStatsResponse_JSON(t *testing.T) { resp := SoraSystemStatsResponse{ TotalUsers: 10, TotalGenerations: 100, TotalStorageBytes: 1024, ActiveGenerations: 5, ByStatus: map[string]int64{"completed": 80}, ByModel: map[string]int64{"sora2": 50}, } // Verify JSON tags by checking field values assert.Equal(t, int64(10), resp.TotalUsers) assert.Equal(t, int64(100), resp.TotalGenerations) assert.Equal(t, int64(1024), resp.TotalStorageBytes) assert.Equal(t, int64(5), resp.ActiveGenerations) } func TestSoraUserStatsResponse_JSON(t *testing.T) { resp := SoraUserStatsResponse{ UserID: 1, Username: "testuser", Email: "test@example.com", QuotaBytes: 1024, UsedBytes: 512, AvailableBytes: 512, QuotaSource: "user", GenerationsCount: 10, ActiveCount: 2, TotalFileSizeBytes: 1024, } // Verify all fields assert.Equal(t, int64(1), resp.UserID) assert.Equal(t, "testuser", resp.Username) assert.Equal(t, "test@example.com", resp.Email) assert.Equal(t, int64(1024), resp.QuotaBytes) assert.Equal(t, int64(512), resp.UsedBytes) assert.Equal(t, int64(512), resp.AvailableBytes) assert.Equal(t, "user", resp.QuotaSource) assert.Equal(t, int64(10), resp.GenerationsCount) assert.Equal(t, int64(2), resp.ActiveCount) assert.Equal(t, int64(1024), resp.TotalFileSizeBytes) } func TestSoraSystemStatsResponse_EmptyMaps(t *testing.T) { resp := SoraSystemStatsResponse{ TotalUsers: 0, TotalGenerations: 0, TotalStorageBytes: 0, ActiveGenerations: 0, ByStatus: map[string]int64{}, ByModel: map[string]int64{}, } assert.Equal(t, int64(0), resp.TotalUsers) assert.Equal(t, int64(0), resp.TotalGenerations) assert.Equal(t, int64(0), resp.TotalStorageBytes) assert.Equal(t, int64(0), resp.ActiveGenerations) assert.NotNil(t, resp.ByStatus) assert.NotNil(t, resp.ByModel) } func TestSoraUserStatsResponse_QuotaSources(t *testing.T) { sources := []string{"user", "group", "system", "unlimited"} for _, source := range sources { resp := SoraUserStatsResponse{ UserID: 1, QuotaSource: source, } assert.Equal(t, source, resp.QuotaSource) } } func TestSoraGenerationAdminResponse_Statuses(t *testing.T) { statuses := []string{"pending", "generating", "completed", "failed", "cancelled"} for _, status := range statuses { resp := SoraGenerationAdminResponse{ ID: 1, Status: status, } assert.Equal(t, status, resp.Status) } } func TestSoraGenerationAdminResponse_MediaTypes(t *testing.T) { mediaTypes := []string{"video", "image"} for _, mt := range mediaTypes { resp := SoraGenerationAdminResponse{ ID: 1, MediaType: mt, } assert.Equal(t, mt, resp.MediaType) } } func TestSoraGenerationAdminResponse_StorageTypes(t *testing.T) { storageTypes := []string{"s3", "upstream"} for _, st := range storageTypes { resp := SoraGenerationAdminResponse{ ID: 1, StorageType: st, } assert.Equal(t, st, resp.StorageType) } }