package controllers import ( "fmt" "net/http" "net/http/httptest" "testing" "GoMembership/internal/models" "github.com/gin-gonic/gin" ) type RegisterSubscriptionTest struct { WantDBData map[string]interface{} Input string Name string WantResponse int Assert bool } func TestMembershipController(t *testing.T) { tests := getSubscriptionData() for _, tt := range tests { t.Run(tt.Name, func(t *testing.T) { if err := runSingleTest(&tt); err != nil { t.Errorf("Test failed: %v", err.Error()) } }) } } func (rt *RegisterSubscriptionTest) SetupContext() (*gin.Context, *httptest.ResponseRecorder, *gin.Engine) { return GetMockedJSONContext([]byte(rt.Input), "api/subscription") } func (rt *RegisterSubscriptionTest) RunHandler(c *gin.Context, router *gin.Engine) { Mc.RegisterSubscription(c) } func (rt *RegisterSubscriptionTest) ValidateResponse(w *httptest.ResponseRecorder) error { if w.Code != rt.WantResponse { return fmt.Errorf("Didn't get the expected response code: got: %v; expected: %v", w.Code, rt.WantResponse) } return nil } func (rt *RegisterSubscriptionTest) ValidateResult() error { return validateSubscription(rt.Assert, rt.WantDBData) } func validateSubscription(assert bool, wantDBData map[string]interface{}) error { subscriptions, err := Mc.Service.GetSubscriptions(wantDBData) if err != nil { return fmt.Errorf("Error in database ops: %#v", err) } if assert != (len(*subscriptions) != 0) { return fmt.Errorf("Subscription entry query didn't met expectation: %v != %#v", assert, *subscriptions) } return nil } func getBaseSubscription() MembershipData { return MembershipData{ Model: models.SubscriptionModel{ Name: "Just a Subscription", Details: "A subscription detail", MonthlyFee: 12.0, HourlyRate: 14.0, }, } } func customizeSubscription(customize func(MembershipData) MembershipData) MembershipData { subscription := getBaseSubscription() return customize(subscription) } func getSubscriptionData() []RegisterSubscriptionTest { return []RegisterSubscriptionTest{ { Name: "No Details should fail", WantResponse: http.StatusNotAcceptable, WantDBData: map[string]interface{}{"name": "Just a Subscription"}, Assert: false, Input: GenerateInputJSON( customizeSubscription(func(subscription MembershipData) MembershipData { subscription.Model.Details = "" return subscription })), }, { Name: "No Model Name should fail", WantResponse: http.StatusNotAcceptable, WantDBData: map[string]interface{}{"name": ""}, Assert: false, Input: GenerateInputJSON( customizeSubscription(func(subscription MembershipData) MembershipData { subscription.Model.Name = "" return subscription })), }, { Name: "correct entry should pass", WantResponse: http.StatusCreated, WantDBData: map[string]interface{}{"name": "Just a Subscription"}, Assert: true, Input: GenerateInputJSON( customizeSubscription(func(subscription MembershipData) MembershipData { subscription.Model.Conditions = "Some Condition" subscription.Model.IncludedPerYear = 0 subscription.Model.IncludedPerMonth = 1 return subscription })), }, } }