From 18414bbb952f49484b973662815effd6f6dc04d5 Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Mon, 5 Jun 2017 14:30:31 +0200 Subject: [PATCH] [TASK] implement release of goods + add tests --- config_example.conf | 2 +- http/bindapi.go | 3 ++ http/good_lock.go | 63 ++++++++++++++++++++++++++++++++++ http/good_lock_test.go | 45 ++++++++++++++++++++++++ test/testrest.go | 8 ++++- webroot/dummie_cart/index.html | 24 ++++++++++--- 6 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 http/good_lock.go create mode 100644 http/good_lock_test.go diff --git a/config_example.conf b/config_example.conf index f4976e8..a2e6eec 100644 --- a/config_example.conf +++ b/config_example.conf @@ -8,7 +8,7 @@ fouled_deleted = "0m" [database] type = "sqlite3" -# logging = true +#logging = true connection = "file::memory:?mode=memory&cache=shared" # For Master-Slave cluster # read_connection = "" diff --git a/http/bindapi.go b/http/bindapi.go index eca7ae2..75a91fb 100644 --- a/http/bindapi.go +++ b/http/bindapi.go @@ -17,4 +17,7 @@ func BindAPI(router *goji.Mux) { router.HandleFunc(pat.Get("/api/good/freshness/:goodid"), getGoodFreshness) router.HandleFunc(pat.Post("/api/good/:productid"), http.PermissionHandler(addGood, runtime.HasPermission, runtime.PermissionCreateGood)) router.HandleFunc(pat.Delete("/api/good/:goodid"), http.PermissionHandler(delGood, runtime.HasPermission, runtime.PermissionDeleteGood)) + + router.HandleFunc(pat.Post("/api/goods/locking"), lockGoods) + router.HandleFunc(pat.Delete("/api/goods/locking"), releaseGoods) } diff --git a/http/good_lock.go b/http/good_lock.go new file mode 100644 index 0000000..ce7c1a3 --- /dev/null +++ b/http/good_lock.go @@ -0,0 +1,63 @@ +package http + +import ( + "net/http" + + "github.com/genofire/hs_master-kss-monolith/lib/database" + lib "github.com/genofire/hs_master-kss-monolith/lib/http" + logger "github.com/genofire/hs_master-kss-monolith/lib/log" + "github.com/genofire/hs_master-kss-monolith/models" +) + +type LockGood struct { + ProductID int64 `json:"product_id"` + Count int64 `json:"count"` +} + +func lockGoods(w http.ResponseWriter, r *http.Request) { + log := logger.HTTP(r) + secret := r.Header.Get("secret") + log = log.WithField("lSecret", secret) + + tx := database.Write.Begin() + // TODO the logic + if tx.Error != nil { + tx.Rollback() + log.Warn("good not found") + http.Error(w, "the good was not found in database", http.StatusNotFound) + return + } + // TODO the logic + + lib.Write(w, map[string]int64{"count": 0}) + tx.Commit() + log.Info("done") + +} + +func releaseGoods(w http.ResponseWriter, r *http.Request) { + log := logger.HTTP(r) + secret := r.Header.Get("secret") + log = log.WithField("lSecret", secret) + + db := database.Write.Model(&models.Good{}).Where(&models.Good{LockedSecret: secret}).Updates(map[string]interface{}{"locked_secret": nil, "locked_at": nil}) + err := db.Error + result := db.RowsAffected + + if err != nil { + log.Warn("database error during release goods: ", err) + http.Error(w, "secret could not validate", http.StatusInternalServerError) + return + } + + if result <= 0 { + log.Warn("no goods found") + http.Error(w, "no goods found to release", http.StatusNotFound) + return + } + + log = log.WithField("count", result) + + lib.Write(w, map[string]int64{"count": result}) + log.Info("done") +} diff --git a/http/good_lock_test.go b/http/good_lock_test.go new file mode 100644 index 0000000..bdd8df2 --- /dev/null +++ b/http/good_lock_test.go @@ -0,0 +1,45 @@ +// Package that contains all api routes of this microservice +package http + +import ( + "net/http" + "testing" + "time" + + "github.com/genofire/hs_master-kss-monolith/lib/database" + "github.com/genofire/hs_master-kss-monolith/models" + "github.com/genofire/hs_master-kss-monolith/test" +) + +func TestReleaseGoods(t *testing.T) { + now := time.Now() + assertion, router := test.Init(t) + + database.Write.Create(&models.Good{ + ProductID: 3, + Comment: "blub", + LockedAt: &now, + LockedSecret: "hidden", + }) + + BindAPI(router) + session := test.NewSession(router) + + session.Header["secret"] = "a" + result, w := session.JSONRequest("DELETE", "/api/goods/locking", nil) + assertion.Equal(http.StatusNotFound, w.StatusCode) + + session.Header["secret"] = "hidden" + result, w = session.JSONRequest("DELETE", "/api/goods/locking", nil) + assertion.Equal(http.StatusOK, w.StatusCode) + resultMap := result.(map[string]interface{}) + count := resultMap["count"] + assertion.Equal(float64(1), count) + + database.Close() + result, w = session.JSONRequest("DELETE", "/api/goods/locking", nil) + assertion.Equal(http.StatusInternalServerError, w.StatusCode) + + test.Close() + +} diff --git a/test/testrest.go b/test/testrest.go index f00f327..707a837 100644 --- a/test/testrest.go +++ b/test/testrest.go @@ -78,11 +78,12 @@ type Request struct { req *http.Request cookies []*http.Cookie router *goji.Mux + Header map[string]string } // Function to create a NewSession with the easy manager func NewSession(router *goji.Mux) *Request { - return &Request{router: router} + return &Request{router: router, Header: make(map[string]string)} } // Function to send a request to the router and receive the api's answer @@ -90,6 +91,11 @@ func (r *Request) JSONRequest(method string, url string, body interface{}) (json jsonObj, _ := json.Marshal(body) req, _ := http.NewRequest(method, url, bytes.NewReader(jsonObj)) req.Header.Set("Content-Type", "application/json") + if len(r.Header) > 0 { + for k, h := range r.Header { + req.Header.Set(k, h) + } + } for _, c := range r.cookies { req.AddCookie(c) } diff --git a/webroot/dummie_cart/index.html b/webroot/dummie_cart/index.html index 37f9c50..6c5af42 100644 --- a/webroot/dummie_cart/index.html +++ b/webroot/dummie_cart/index.html @@ -72,8 +72,8 @@ 'microservice_dependencies': { 'products': 'http://localhost:8080/api-test/product/', 'productById': 'http://localhost:8080/api-test/product/%d/', - 'lockGoods': '/api/goods/lock/%s', - 'unlockGoods': '/api/goods/unlock/%s' + 'lockGoods': '/api/goods/locking', + 'unlockGoods': '/api/goods/locking' } }; @@ -148,9 +148,17 @@ $scope.add = function add() { $scope.goods.product_id = selectedProduct; - $scope.goods.secret = createUUID(); - $http.post(config.microservice_dependencies.lockGoods.replace('%s', $scope.goods.secret), [$scope.goods]).then(function(res) { + const secret = createUUID(); + $http({ + method: 'POST', + headers: { + 'secret': secret + }, + url: config.microservice_dependencies.lockGoods, + data: [$scope.goods] + }).then(function(res) { console.log('add', $scope.goods); + $scope.goods.secret = secret; $scope.cart.push($scope.goods); save(); $scope.goods = {count:1}; @@ -158,7 +166,13 @@ }; $scope.del = function del(entry) { - $http.delete(config.microservice_dependencies.unlockGoods.replace('%s', entry.secret)).then(function(res) { + $http({ + method: 'DELETE', + headers: { + 'secret': entry.secret + }, + url: config.microservice_dependencies.unlockGoods + }).then(function(res) { console.log('del', entry); $scope.cart = $scope.cart.filter((item) => item !== entry); save();