diff --git a/internal/api/application_test.go b/internal/api/application_test.go index 2dcb368..19d429d 100644 --- a/internal/api/application_test.go +++ b/internal/api/application_test.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "fmt" "io/ioutil" "log" "os" @@ -70,12 +71,12 @@ func TestApi_RgisterApplication(t *testing.T) { assert := assert.New(t) gin.SetMode(gin.TestMode) - testCases := make(map[int]tests.Request) - testCases[400] = tests.Request{Name: "Invalid Form Data", Method: "POST", Endpoint: "/application", Data: "k=1&v=abc"} - testCases[400] = tests.Request{Name: "Invalid JSON Data", Method: "POST", Endpoint: "/application", Data: `{"name": "test1", "strict_compatibility": "oh yes"}`, Headers: map[string]string{"Content-Type": "application/json"}} - testCases[200] = tests.Request{Name: "Valid JSON Data", Method: "POST", Endpoint: "/application", Data: `{"name": "test2", "strict_compatibility": true}`, Headers: map[string]string{"Content-Type": "application/json"}} + testCases := make([]tests.Request, 0) + testCases = append(testCases, tests.Request{Name: "Invalid Form Data", Method: "POST", Endpoint: "/application", Data: "k=1&v=abc", ShouldStatus: 400}) + testCases = append(testCases, tests.Request{Name: "Invalid JSON Data", Method: "POST", Endpoint: "/application", Data: `{"name": "test1", "strict_compatibility": "oh yes"}`, Headers: map[string]string{"Content-Type": "application/json"}, ShouldStatus: 400}) + testCases = append(testCases, tests.Request{Name: "Valid JSON Data", Method: "POST", Endpoint: "/application", Data: `{"name": "test2", "strict_compatibility": true}`, Headers: map[string]string{"Content-Type": "application/json"}, ShouldStatus: 200}) - for statusCode, req := range testCases { + for _, req := range testCases { var application model.Application w, c, err := req.GetRequest() if err != nil { @@ -86,7 +87,7 @@ func TestApi_RgisterApplication(t *testing.T) { TestApplicationHandler.CreateApplication(c) // Parse body only for successful requests - if statusCode >= 200 && statusCode < 300 { + if req.ShouldStatus >= 200 && req.ShouldStatus < 300 { body, err := ioutil.ReadAll(w.Body) assert.NoErrorf(err, "Can not read request body") if err != nil { @@ -101,7 +102,7 @@ func TestApi_RgisterApplication(t *testing.T) { SuccessAplications = append(SuccessAplications, application) } - assert.Equalf(w.Code, statusCode, "CreateApplication (Test case: \"%s\") should return status code %v but is %v.", req.Name, statusCode, w.Code) + assert.Equalf(w.Code, req.ShouldStatus, "CreateApplication (Test case: \"%s\") should return status code %v but is %v.", req.Name, req.ShouldStatus, w.Code) } } @@ -111,10 +112,10 @@ func TestApi_GetApplications(t *testing.T) { assert := assert.New(t) gin.SetMode(gin.TestMode) - testCases := make(map[int]tests.Request) - testCases[200] = tests.Request{Name: "Valid Request", Method: "GET", Endpoint: "/application"} + testCases := make([]tests.Request, 0) + testCases = append(testCases, tests.Request{Name: "Valid Request", Method: "GET", Endpoint: "/application", ShouldStatus: 200}) - for statusCode, req := range testCases { + for _, req := range testCases { w, c, err := req.GetRequest() if err != nil { t.Fatalf(err.Error()) @@ -124,7 +125,7 @@ func TestApi_GetApplications(t *testing.T) { TestApplicationHandler.GetApplications(c) // Parse body only for successful requests - if statusCode >= 200 && statusCode < 300 { + if req.ShouldStatus >= 200 && req.ShouldStatus < 300 { body, err := ioutil.ReadAll(w.Body) assert.NoErrorf(err, "Can not read request body") if err != nil { @@ -140,7 +141,7 @@ func TestApi_GetApplications(t *testing.T) { assert.Equalf(len(applications), len(SuccessAplications), "Created %d application(s) but got %d back", len(SuccessAplications), len(applications)) } - assert.Equalf(w.Code, statusCode, "GetApplications (Test case: \"%s\") should return status code %v but is %v.", req.Name, statusCode, w.Code) + assert.Equalf(w.Code, req.ShouldStatus, "GetApplications (Test case: \"%s\") should return status code %v but is %v.", req.Name, req.ShouldStatus, w.Code) } } @@ -159,6 +160,135 @@ func TestApi_GetApplicationsWithoutUser(t *testing.T) { } +func TestApi_GetApplicationErrors(t *testing.T) { + assert := assert.New(t) + gin.SetMode(gin.TestMode) + + // Arbitrary test cases + testCases := make(map[uint]tests.Request, 0) + testCases[0] = tests.Request{Name: "Requesting unknown application 0", Method: "GET", Endpoint: "/application/0", ShouldStatus: 404} + testCases[5555] = tests.Request{Name: "Requesting unknown application 5555", Method: "GET", Endpoint: "/application/5555", ShouldStatus: 404} + testCases[99999999999999999] = tests.Request{Name: "Requesting unknown application 99999999999999999", Method: "GET", Endpoint: "/application/99999999999999999", ShouldStatus: 404} + + for id, req := range testCases { + w, c, err := req.GetRequest() + if err != nil { + t.Fatalf(err.Error()) + } + + c.Set("user", TestUser) + c.Set("id", id) + TestApplicationHandler.GetApplication(c) + + assert.Equalf(w.Code, req.ShouldStatus, "GetApplication (Test case: \"%s\") should return status code %v but is %v.", req.Name, req.ShouldStatus, w.Code) + } +} + +func TestApi_GetApplication(t *testing.T) { + var application model.Application + + assert := assert.New(t) + gin.SetMode(gin.TestMode) + + // Previously generated applications + for _, app := range SuccessAplications { + req := tests.Request{Name: fmt.Sprintf("Requesting application %s (%d)", app.Name, app.ID), Method: "GET", Endpoint: fmt.Sprintf("/application/%d", app.ID), ShouldStatus: 200} + + w, c, err := req.GetRequest() + if err != nil { + t.Fatalf(err.Error()) + } + + c.Set("user", TestUser) + c.Set("id", app.ID) + TestApplicationHandler.GetApplication(c) + + // Parse body only for successful requests + if req.ShouldStatus >= 200 && req.ShouldStatus < 300 { + body, err := ioutil.ReadAll(w.Body) + assert.NoErrorf(err, "Can not read request body") + if err != nil { + continue + } + err = json.Unmarshal(body, &application) + assert.NoErrorf(err, "Can not unmarshal request body: %v", err) + if err != nil { + continue + } + + assert.Equalf(application.ID, app.ID, "Application ID should be %d but is %d", app.ID, application.ID) + assert.Equalf(application.Name, app.Name, "Application Name should be %s but is %s", app.Name, application.Name) + assert.Equalf(application.UserID, app.UserID, "Application user ID should be %d but is %d", app.UserID, application.UserID) + + } + + assert.Equalf(w.Code, req.ShouldStatus, "GetApplication (Test case: \"%s\") should return status code %v but is %v.", req.Name, req.ShouldStatus, w.Code) + } +} + +func TestApi_UpdateApplication(t *testing.T) { + assert := assert.New(t) + gin.SetMode(gin.TestMode) + + testCases := make(map[uint]tests.Request) + // Previously generated applications + for _, app := range SuccessAplications { + newName := app.Name + "-new_name" + updateApp := model.UpdateApplication{ + Name: &newName, + } + updateAppBytes, err := json.Marshal(updateApp) + assert.NoErrorf(err, "Error on marshaling updateApplication struct") + + // Valid + testCases[app.ID] = tests.Request{Name: fmt.Sprintf("Update application (valid) %s (%d)", app.Name, app.ID), Method: "PUT", Endpoint: fmt.Sprintf("/application/%d", app.ID), ShouldStatus: 200, Data: string(updateAppBytes), Headers: map[string]string{"Content-Type": "application/json"}} + // Invalid + testCases[app.ID] = tests.Request{Name: fmt.Sprintf("Update application (invalid) %s (%d)", app.Name, app.ID), Method: "PUT", Endpoint: fmt.Sprintf("/application/%d", app.ID), ShouldStatus: 200, Data: "{}", Headers: map[string]string{"Content-Type": "application/json"}} + } + // Arbitrary test cases + testCases[5555] = tests.Request{Name: "Update application 5555", Method: "PUT", Endpoint: "/application/5555", ShouldStatus: 404, Data: "random data"} + testCases[5556] = tests.Request{Name: "Update application 5556", Method: "PUT", Endpoint: "/application/5556", ShouldStatus: 404, Data: `{"new_name": "new name"}`, Headers: map[string]string{"Content-Type": "application/json"}} + + for id, req := range testCases { + w, c, err := req.GetRequest() + if err != nil { + t.Fatalf(err.Error()) + } + + c.Set("user", TestUser) + c.Set("id", id) + TestApplicationHandler.UpdateApplication(c) + + assert.Equalf(w.Code, req.ShouldStatus, "UpdateApplication (Test case: \"%s\") should return status code %v but is %v.", req.Name, req.ShouldStatus, w.Code) + } +} + +func TestApi_DeleteApplication(t *testing.T) { + assert := assert.New(t) + gin.SetMode(gin.TestMode) + + testCases := make(map[uint]tests.Request) + // Previously generated applications + for _, app := range SuccessAplications { + testCases[app.ID] = tests.Request{Name: fmt.Sprintf("Delete application %s (%d)", app.Name, app.ID), Method: "DELETE", Endpoint: fmt.Sprintf("/application/%d", app.ID), ShouldStatus: 200} + } + // Arbitrary test cases + testCases[5555] = tests.Request{Name: "Delete application 5555", Method: "DELETE", Endpoint: "/application/5555", ShouldStatus: 404} + + for id, req := range testCases { + w, c, err := req.GetRequest() + if err != nil { + t.Fatalf(err.Error()) + } + + c.Set("user", TestUser) + c.Set("id", id) + TestApplicationHandler.DeleteApplication(c) + + assert.Equalf(w.Code, req.ShouldStatus, "DeleteApplication (Test case: \"%s\") should return status code %v but is %v.", req.Name, req.ShouldStatus, w.Code) + } +} + // GetApplicationHandler creates and returns an application handler func getApplicationHandler(c *configuration.Matrix) (*ApplicationHandler, error) { db, err := mockups.GetEmptyDatabase() @@ -196,5 +326,5 @@ func validateAllApplications(apps []model.Application) bool { } func cleanUp() { - os.Remove("pushbits-test.db") + //os.Remove("pushbits-test.db") } diff --git a/tests/request.go b/tests/request.go index 43a9651..bb786af 100644 --- a/tests/request.go +++ b/tests/request.go @@ -11,11 +11,12 @@ import ( // Request holds information for a HTTP request type Request struct { - Name string - Method string - Endpoint string - Data interface{} - Headers map[string]string + Name string + Method string + Endpoint string + Data interface{} + Headers map[string]string + ShouldStatus int } // GetRequest returns a ResponseRecorder and gin context according to the data set in the Request.