From cf5d94d55d0bb98c70e58893a59948d07e6065fd Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Mon, 5 Jun 2017 14:51:01 +0200 Subject: [PATCH] [TASK] implement lock of goods + add tests --- http/good_lock.go | 66 +++++++++++++++++++++++++++++++++++------- http/good_lock_test.go | 47 ++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 10 deletions(-) diff --git a/http/good_lock.go b/http/good_lock.go index ce7c1a3..334df63 100644 --- a/http/good_lock.go +++ b/http/good_lock.go @@ -11,25 +11,71 @@ import ( type LockGood struct { ProductID int64 `json:"product_id"` - Count int64 `json:"count"` + Count int `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) + if secret == "" { + log.Warn("no secred for locking given") + http.Error(w, "no secred for locking given", http.StatusBadRequest) return } - // TODO the logic - lib.Write(w, map[string]int64{"count": 0}) + log = log.WithField("lSecret", secret) + + var goods []*LockGood + + err := lib.Read(r, &goods) + + if err != nil { + log.Warn(err.Error()) + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if len(goods) <= 0 { + log.Warn("try to log nothing") + http.Error(w, "try to log nothing", http.StatusBadRequest) + return + } + + tx := database.Write.Begin() + count := int64(0) + + for _, good := range goods { + if good.ProductID <= 0 { + log.Warn("try to log nothing") + tx.Rollback() + http.Error(w, "try to log nothing", http.StatusBadRequest) + return + } + for i := 0; i < good.Count; i++ { + g := &models.Good{ProductID: good.ProductID} + db := g.FilterAvailable(tx).First(g) + if db.RecordNotFound() { + log.Warn("good not found") + tx.Rollback() + http.Error(w, "the good was not found in database", http.StatusNotFound) + return + } + g.Lock(secret) + + db = tx.Save(g) + + if db.Error != nil || db.RowsAffected != 1 { + http.Error(w, "the good was not found in database", http.StatusInternalServerError) + tx.Rollback() + log.Panic("more then one good locked: ", db.Error) + return + } + count += 1 + } + } + + lib.Write(w, map[string]int64{"count": count}) tx.Commit() log.Info("done") diff --git a/http/good_lock_test.go b/http/good_lock_test.go index bdd8df2..e881835 100644 --- a/http/good_lock_test.go +++ b/http/good_lock_test.go @@ -11,6 +11,53 @@ import ( "github.com/genofire/hs_master-kss-monolith/test" ) +func TestLockGoods(t *testing.T) { + assertion, router := test.Init(t) + good := &models.Good{ + ProductID: 3, + Comment: "blabla", + } + database.Write.Create(good) + + BindAPI(router) + session := test.NewSession(router) + + _, w := session.JSONRequest("POST", "/api/goods/locking", []interface{}{LockGood{ProductID: 3, Count: 1}}) + assertion.Equal(http.StatusBadRequest, w.StatusCode) + + session.Header["secret"] = "hiddenLockTest" + + _, w = session.JSONRequest("POST", "/api/goods/locking", 13) + assertion.Equal(http.StatusBadRequest, w.StatusCode) + + _, w = session.JSONRequest("POST", "/api/goods/locking", nil) + assertion.Equal(http.StatusBadRequest, w.StatusCode) + + _, w = session.JSONRequest("POST", "/api/goods/locking", []interface{}{LockGood{ProductID: 0, Count: 2}}) + assertion.Equal(http.StatusBadRequest, w.StatusCode) + + _, w = session.JSONRequest("POST", "/api/goods/locking", []interface{}{LockGood{ProductID: 3, Count: 2}}) + assertion.Equal(http.StatusNotFound, w.StatusCode) + + result, w := session.JSONRequest("POST", "/api/goods/locking", []interface{}{LockGood{ProductID: 3, Count: 1}}) + assertion.Equal(http.StatusOK, w.StatusCode) + resultMap := result.(map[string]interface{}) + count := resultMap["count"] + assertion.Equal(float64(1), count) + + _, w = session.JSONRequest("POST", "/api/goods/locking", []interface{}{LockGood{ProductID: 3, Count: 1}}) + assertion.Equal(http.StatusNotFound, w.StatusCode) + + database.Close() + + assertion.Panics(func() { + _, w = session.JSONRequest("POST", "/api/goods/locking", []interface{}{LockGood{ProductID: 3, Count: 1}}) + assertion.Equal(http.StatusInternalServerError, w.StatusCode) + }) + + test.Close() +} + func TestReleaseGoods(t *testing.T) { now := time.Now() assertion, router := test.Init(t)