package controllers import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "net/url" "os" "strconv" "testing" "log" "github.com/gin-gonic/gin" "GoMembership/internal/config" "GoMembership/internal/database" "GoMembership/internal/models" "GoMembership/internal/repositories" "GoMembership/internal/services" "GoMembership/internal/utils" "GoMembership/pkg/logger" ) type TestCase interface { SetupContext() (*gin.Context, *httptest.ResponseRecorder) RunHandler(*gin.Context) ValidateResponse(*httptest.ResponseRecorder) error ValidateResult() error } const ( Host = "127.0.0.1" Port int = 2525 ) var ( Uc *UserController Mc *MembershipController Cc *ContactController ) func TestSuite(t *testing.T) { _ = deleteTestDB("test.db") if err := database.InitDB("test.db"); err != nil { log.Fatalf("Failed to create DB: %#v", err) } if err := os.Setenv("SMTP_HOST", Host); err != nil { log.Fatalf("Error setting environment variable: %v", err) } if err := os.Setenv("SMTP_PORT", strconv.Itoa(Port)); err != nil { log.Fatalf("Error setting environment variable: %v", err) } if err := os.Setenv("BASE_URL", "http://"+Host+":2525"); err != nil { log.Fatalf("Error setting environment variable: %v", err) } config.LoadConfig() utils.SMTPStart(Host, Port) emailService := services.NewEmailService(config.SMTP.Host, config.SMTP.Port, config.SMTP.User, config.SMTP.Password) var consentRepo repositories.ConsentRepositoryInterface = &repositories.ConsentRepository{} consentService := &services.ConsentService{Repo: consentRepo} var bankAccountRepo repositories.BankAccountRepositoryInterface = &repositories.BankAccountRepository{} bankAccountService := &services.BankAccountService{Repo: bankAccountRepo} var membershipRepo repositories.MembershipRepositoryInterface = &repositories.MembershipRepository{} var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{} membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo} var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{} userService := &services.UserService{Repo: userRepo} Uc = &UserController{Service: userService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService} Mc = &MembershipController{Service: *membershipService} Cc = &ContactController{EmailService: emailService} if err := initSubscriptionPlans(); err != nil { log.Fatalf("Failed to init Subscription plans: %#v", err) } // Run all tests // code := m.Run() t.Run("userController", func(t *testing.T) { TestUserController(t) }) t.Run("contactController", func(t *testing.T) { TestContactController(t) }) t.Run("membershipController", func(t *testing.T) { TestMembershipController(t) }) if err := utils.SMTPStop(); err != nil { log.Fatalf("Failed to stop SMTP Mockup Server: %#v", err) } if err := deleteTestDB("test.db"); err != nil { log.Fatalf("Failed to tear down DB: %#v", err) } } func initSubscriptionPlans() error { subscription := models.SubscriptionModel{ Name: "Basic", Details: "Test Plan", MonthlyFee: 2, HourlyRate: 3, } result := database.DB.Create(&subscription) if result.Error != nil { return result.Error } return nil } func GetMockedJSONContext(jsonStr []byte, url string) (*gin.Context, *httptest.ResponseRecorder) { gin.SetMode(gin.TestMode) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) var err error c.Request, err = http.NewRequest("POST", url, bytes.NewBuffer(jsonStr)) if err != nil { log.Fatalf("Failed to create new Request: %#v", err) } c.Request.Header.Set("Content-Type", "application/json") return c, w } func GetMockedFormContext(formData url.Values, url string) (*gin.Context, *httptest.ResponseRecorder) { gin.SetMode(gin.TestMode) w := httptest.NewRecorder() c, _ := gin.CreateTestContext(w) req, err := http.NewRequest("POST", url, bytes.NewBufferString(formData.Encode())) if err != nil { log.Fatalf("Failed to create new Request: %#v", err) } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") c.Request = req return c, w } func deleteTestDB(dbPath string) error { err := os.Remove(dbPath) if err != nil { return err } return nil } func runSingleTest(tc TestCase) error { c, w := tc.SetupContext() tc.RunHandler(c) if err := tc.ValidateResponse(w); err != nil { return err } return tc.ValidateResult() } func GenerateInputJSON(aStruct interface{}) string { // Marshal the object into JSON jsonBytes, err := json.Marshal(aStruct) if err != nil { logger.Error.Fatalf("Couldn't generate JSON: %#v\nERROR: %#v", aStruct, err) return "" } return string(jsonBytes) }