package handlers import ( "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "github.com/gin-gonic/gin" "github.com/google/uuid" "go.uber.org/zap" "veza-backend-api/internal/core/subscription" ) func TestNewSubscriptionHandler(t *testing.T) { logger := zap.NewNop() svc := subscription.NewService(nil, logger) handler := NewSubscriptionHandler(svc, logger) if handler == nil { t.Fatal("expected non-nil handler") } if handler.service == nil { t.Error("expected non-nil service") } if handler.logger == nil { t.Error("expected non-nil logger") } } func TestSubscriptionHandler_GetMySubscription_NoAuth(t *testing.T) { gin.SetMode(gin.TestMode) logger := zap.NewNop() svc := subscription.NewService(nil, logger) handler := NewSubscriptionHandler(svc, logger) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodGet, "/subscriptions/me", nil) handler.GetMySubscription(c) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } } func TestSubscriptionHandler_Subscribe_NoAuth(t *testing.T) { gin.SetMode(gin.TestMode) logger := zap.NewNop() svc := subscription.NewService(nil, logger) handler := NewSubscriptionHandler(svc, logger) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodPost, "/subscriptions/subscribe", strings.NewReader(`{}`)) c.Request.Header.Set("Content-Type", "application/json") handler.Subscribe(c) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } } func TestSubscriptionHandler_Subscribe_InvalidBody(t *testing.T) { gin.SetMode(gin.TestMode) logger := zap.NewNop() svc := subscription.NewService(nil, logger) handler := NewSubscriptionHandler(svc, logger) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Set("user_id", uuid.New()) c.Request = httptest.NewRequest(http.MethodPost, "/subscriptions/subscribe", strings.NewReader(`{}`)) c.Request.Header.Set("Content-Type", "application/json") handler.Subscribe(c) // Should get validation error since plan_id and billing_cycle are missing var resp map[string]interface{} if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatalf("failed to decode response: %v", err) } if resp["success"] != false { t.Error("expected success=false for invalid request") } } func TestSubscriptionHandler_CancelSubscription_NoAuth(t *testing.T) { gin.SetMode(gin.TestMode) logger := zap.NewNop() svc := subscription.NewService(nil, logger) handler := NewSubscriptionHandler(svc, logger) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodPost, "/subscriptions/cancel", nil) handler.CancelSubscription(c) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } } func TestSubscriptionHandler_GetPlan_InvalidID(t *testing.T) { gin.SetMode(gin.TestMode) logger := zap.NewNop() svc := subscription.NewService(nil, logger) handler := NewSubscriptionHandler(svc, logger) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Params = gin.Params{{Key: "id", Value: "not-a-uuid"}} c.Request = httptest.NewRequest(http.MethodGet, "/subscriptions/plans/not-a-uuid", nil) handler.GetPlan(c) var resp map[string]interface{} if err := json.NewDecoder(w.Body).Decode(&resp); err != nil { t.Fatalf("failed to decode response: %v", err) } if resp["success"] != false { t.Error("expected success=false for invalid plan ID") } } func TestSubscriptionHandler_ChangeBillingCycle_NoAuth(t *testing.T) { gin.SetMode(gin.TestMode) logger := zap.NewNop() svc := subscription.NewService(nil, logger) handler := NewSubscriptionHandler(svc, logger) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) c.Request = httptest.NewRequest(http.MethodPut, "/subscriptions/billing-cycle", strings.NewReader(`{"billing_cycle":"yearly"}`)) c.Request.Header.Set("Content-Type", "application/json") handler.ChangeBillingCycle(c) if w.Code != http.StatusUnauthorized { t.Errorf("expected 401, got %d", w.Code) } }