From 2406bf8d444bf442d6d3d5381db02ff8480c618c Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Thu, 24 Nov 2016 01:37:24 +0200 Subject: [PATCH] More API tests and removal of dead code --- api.go | 21 +++++++----------- api_test.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++------- db.go | 2 +- 3 files changed, 62 insertions(+), 22 deletions(-) diff --git a/api.go b/api.go index 2cec374..c5189cc 100644 --- a/api.go +++ b/api.go @@ -24,6 +24,9 @@ func (a authMiddleware) Serve(ctx *iris.Context) { ctx.Next() return } + } else { + ctx.JSON(iris.StatusBadRequest, iris.Map{"error": "bad data"}) + return } } // To protect against timed side channel (never gonna give you up) @@ -39,7 +42,7 @@ func webRegisterPost(ctx *iris.Context) { var regStatus int if err != nil { errstr := fmt.Sprintf("%v", err) - regJSON = iris.Map{"username": "", "password": "", "domain": "", "error": errstr} + regJSON = iris.Map{"error": errstr} regStatus = iris.StatusInternalServerError log.Debugf("Error in registration, [%v]", err) } else { @@ -60,18 +63,10 @@ func webUpdatePost(ctx *iris.Context) { // User auth done in middleware a := ACMETxt{} userStr := ctx.RequestHeader("X-API-User") - username, err := getValidUsername(userStr) - if err != nil { - log.Warningf("Error while getting username [%s]. This should never happen because of auth middlware.", userStr) - webUpdatePostError(ctx, err, iris.StatusUnauthorized) - return - } - if err := ctx.ReadJSON(&a); err != nil { - // Handle bad post data - log.Warningf("Could not unmarshal: [%v]", err) - webUpdatePostError(ctx, err, iris.StatusBadRequest) - return - } + // Already checked in auth middlware + username, _ := getValidUsername(userStr) + // Already checked in auth middleware + _ = ctx.ReadJSON(&a) a.Username = username // Do update if validSubdomain(a.Subdomain) && validTXT(a.Value) { diff --git a/api_test.go b/api_test.go index 260cb54..5219c1c 100644 --- a/api_test.go +++ b/api_test.go @@ -1,14 +1,16 @@ package main import ( + "errors" "github.com/gavv/httpexpect" "github.com/kataras/iris" "github.com/kataras/iris/httptest" "github.com/op/go-logging" + "gopkg.in/DATA-DOG/go-sqlmock.v1" "testing" ) -func SetupIris(t *testing.T, debug bool) *httpexpect.Expect { +func SetupIris(t *testing.T, debug bool, noauth bool) *httpexpect.Expect { iris.ResetDefault() var dbcfg = dbsettings{ Engine: "sqlite3", @@ -33,14 +35,18 @@ func SetupIris(t *testing.T, debug bool) *httpexpect.Expect { var ForceAuth = authMiddleware{} iris.Get("/register", webRegisterGet) iris.Post("/register", webRegisterPost) - iris.Post("/update", ForceAuth.Serve, webUpdatePost) + if noauth { + iris.Post("/update", webUpdatePost) + } else { + iris.Post("/update", ForceAuth.Serve, webUpdatePost) + } httptestcfg := httptest.DefaultConfiguration() httptestcfg.Debug = debug return httptest.New(iris.Default, t, httptestcfg) } func TestApiRegister(t *testing.T) { - e := SetupIris(t, false) + e := SetupIris(t, false, false) defer DB.DB.Close() e.GET("/register").Expect(). Status(iris.StatusCreated). @@ -60,8 +66,22 @@ func TestApiRegister(t *testing.T) { NotContainsKey("error") } +func TestApiRegisterWithMockDB(t *testing.T) { + e := SetupIris(t, false, false) + DB.DB.Close() + db, mock, _ := sqlmock.New() + DB.DB = db + defer DB.DB.Close() + mock.ExpectBegin() + mock.ExpectPrepare("INSERT INTO records").WillReturnError(errors.New("error")) + e.GET("/register").Expect(). + Status(iris.StatusInternalServerError). + JSON().Object(). + ContainsKey("error") +} + func TestApiUpdateWithoutCredentials(t *testing.T) { - e := SetupIris(t, false) + e := SetupIris(t, false, false) defer DB.DB.Close() e.POST("/update").Expect(). Status(iris.StatusUnauthorized). @@ -77,7 +97,7 @@ func TestApiUpdateWithCredentials(t *testing.T) { "subdomain": "", "txt": ""} - e := SetupIris(t, false) + e := SetupIris(t, false, false) defer DB.DB.Close() newUser, err := DB.Register() if err != nil { @@ -97,19 +117,43 @@ func TestApiUpdateWithCredentials(t *testing.T) { ContainsKey("txt"). NotContainsKey("error"). ValueEqual("txt", validTxtData) +} +func TestApiUpdateWithCredentialsMockDB(t *testing.T) { + validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + updateJSON := map[string]interface{}{ + "subdomain": "", + "txt": ""} + + // Valid data + updateJSON["subdomain"] = "a097455b-52cc-4569-90c8-7a4b97c6eba8" + updateJSON["txt"] = validTxtData + + e := SetupIris(t, false, true) + DB.DB.Close() + db, mock, _ := sqlmock.New() + DB.DB = db + defer DB.DB.Close() + mock.ExpectBegin() + mock.ExpectPrepare("UPDATE records").WillReturnError(errors.New("error")) + e.POST("/update"). + WithJSON(updateJSON). + Expect(). + Status(iris.StatusInternalServerError). + JSON().Object(). + ContainsKey("error") } func TestApiManyUpdateWithCredentials(t *testing.T) { // TODO: transfer to using httpexpect builder - // If test fails and more debuf info is needed, use SetupIris(t, true) + // If test fails and more debuf info is needed, use SetupIris(t, true, false) validTxtData := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" updateJSON := map[string]interface{}{ "subdomain": "", "txt": ""} - e := SetupIris(t, false) + e := SetupIris(t, true, false) defer DB.DB.Close() newUser, err := DB.Register() if err != nil { @@ -119,7 +163,7 @@ func TestApiManyUpdateWithCredentials(t *testing.T) { user string pass string subdomain string - txt string + txt interface{} status int }{ {"non-uuid-user", "tooshortpass", "non-uuid-subdomain", validTxtData, 401}, @@ -127,6 +171,7 @@ func TestApiManyUpdateWithCredentials(t *testing.T) { {"a097455b-52cc-4569-90c8-7a4b97c6eba8", "LongEnoughPassButNoUserExists___________", "bb97455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, {newUser.Username.String(), newUser.Password, "a097455b-52cc-4569-90c8-7a4b97c6eba8", validTxtData, 401}, {newUser.Username.String(), newUser.Password, newUser.Subdomain, "tooshortfortxt", 400}, + {newUser.Username.String(), newUser.Password, newUser.Subdomain, 1234567890, 400}, {newUser.Username.String(), newUser.Password, newUser.Subdomain, validTxtData, 200}, } { updateJSON = map[string]interface{}{ diff --git a/db.go b/db.go index bf85b56..e7b546d 100644 --- a/db.go +++ b/db.go @@ -68,7 +68,7 @@ func (d *database) Register() (ACMETxt, error) { } sm, err := d.DB.Prepare(regSQL) if err != nil { - return a, err + return a, errors.New("SQL error") } defer sm.Close() _, err = sm.Exec(a.Username.String(), passwordHash, a.Subdomain, timenow)